added error handling for emulate prepared statement with inout parameters

This commit is contained in:
v-kaywon 2017-04-21 13:04:24 -07:00
parent fa38f7d61c
commit 2aec3b4a95
5 changed files with 121 additions and 1 deletions

View file

@ -1115,6 +1115,10 @@ int pdo_sqlsrv_stmt_param_hook(pdo_stmt_t *stmt,
// since the param isn't reliable, we don't do anything here
case PDO_PARAM_EVT_ALLOC:
if ( stmt->supports_placeholders == PDO_PLACEHOLDER_NONE && (param->param_type & PDO_PARAM_INPUT_OUTPUT )) {
sqlsrv_stmt* driver_stmt = reinterpret_cast<sqlsrv_stmt*>( stmt->driver_data );
THROW_PDO_ERROR( driver_stmt, PDO_SQLSRV_ERROR_EMULATE_INOUT_UNSUPPORTED );
}
break;
case PDO_PARAM_EVT_FREE:
break;

View file

@ -373,6 +373,10 @@ pdo_error PDO_ERRORS[] = {
SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED,
{ IMSSP, (SQLCHAR*) "Memory limit of %1!d! KB exceeded for buffered query", -71, true }
},
{
PDO_SQLSRV_ERROR_EMULATE_INOUT_UNSUPPORTED,
{ IMSSP, (SQLCHAR*) "Statement with emulate prepare on does not support output or input_output parameters.", -72, false }
},
{ UINT_MAX, {} }
};

View file

@ -389,7 +389,7 @@ enum PDO_ERROR_CODES {
PDO_SQLSRV_ERROR_INVALID_COLUMN_INDEX,
PDO_SQLSRV_ERROR_INVALID_OUTPUT_PARAM_TYPE,
PDO_SQLSRV_ERROR_INVALID_CURSOR_WITH_SCROLL_TYPE,
PDO_SQLSRV_ERROR_EMULATE_INOUT_UNSUPPORTED,
};
extern pdo_error PDO_ERRORS[];

View file

@ -0,0 +1,30 @@
--TEST--
uses an input/output parameter with emulate prepare
--SKIPIF--
--FILE--
<?php
require_once("autonomous_setup.php");
$database = 'tempdb';
$dsn = "sqlsrv:Server=$serverName ; Database = $database";
try {
$dbh = new PDO($dsn, $username, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->query("IF OBJECT_ID('sp_ReverseString', 'P') IS NOT NULL DROP PROCEDURE sp_ReverseString");
$dbh->query("CREATE PROCEDURE sp_ReverseString @String as VARCHAR(2048) OUTPUT as SELECT @String = REVERSE(@String)");
$stmt = $dbh->prepare("EXEC sp_ReverseString ?", array(PDO::ATTR_EMULATE_PREPARES => true));
$string = "123456789";
$stmt->bindParam(1, $string, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 2048);
$stmt->execute();
print "Result: ".$string;
//free the statement and connection
$stmt = null;
$dbh = null;
}
catch(PDOException $e) {
print("Error: " . $e->getMessage() . "\n");
}
?>
--EXPECT--
Error: SQLSTATE[IMSSP]: Statement with emulate prepare on does not support output or input_output parameters.

View file

@ -0,0 +1,82 @@
--TEST--
Test emulate prepare with mix bound param encodings and positional placeholders (i.e., using '?' as placeholders)
--SKIPIF--
--FILE--
<?php
require_once("autonomous_setup.php");
$connection_options['pdo'] = array();
$connection_options['pdo'][PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
$database = "tempdb";
$cnn = new PDO("sqlsrv:Server=$serverName;Database=$database", $username, $password, $connection_options['pdo']);
// Drop
try {
$pdo_options = array();
$pdo_options[PDO::ATTR_EMULATE_PREPARES] = TRUE;
$pdo_options[PDO::SQLSRV_ATTR_DIRECT_QUERY] = TRUE;
$pdo_options[PDO::ATTR_CURSOR] = PDO::CURSOR_SCROLL;
$pdo_options[PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE] = PDO::SQLSRV_CURSOR_BUFFERED;
$st = $cnn->prepare('DROP TABLE WATCHDOG', $pdo_options);
$st->execute();
}
catch(\Exception $e) {}
$tablescript = <<<EOF
CREATE TABLE [dbo].[watchdog](
[system_encoding] [nvarchar](128),
[utf8_encoding] [nvarchar](128),
[binary_encoding] [varbinary](max))
EOF;
// Recreate
$st = $cnn->prepare($tablescript, $pdo_options);
$st->execute();
$query = <<<EOF
INSERT INTO [watchdog] ([system_encoding], [utf8_encoding], [binary_encoding]) VALUES
(?, ?, ?)
EOF;
/** @var MyStatement */
$st = $cnn->prepare($query, $pdo_options);
$system_param = 'system encoded string';
$utf8_param = '가각ácasa';
$binary_param = fopen('php://memory', 'a');
fwrite($binary_param, 'asdgasdgasdgsadg');
rewind($binary_param);
$st->bindParam(1, $system_param, PDO::PARAM_STR);
$st->bindParam(2, $utf8_param, PDO::PARAM_STR, 0, PDO::SQLSRV_ENCODING_UTF8);
$st->bindParam(3, $binary_param, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY);
$st->execute();
$st = $cnn->query("SELECT * FROM [watchdog]");
var_dump($st->fetchAll());
$st = NULL;
$cnn = NULL;
?>
--EXPECT--
array(1) {
[0]=>
array(6) {
["system_encoding"]=>
string(21) "system encoded string"
[0]=>
string(21) "system encoded string"
["utf8_encoding"]=>
string(12) "가각ácasa"
[1]=>
string(12) "가각ácasa"
["binary_encoding"]=>
string(16) "asdgasdgasdgsadg"
[2]=>
string(16) "asdgasdgasdgsadg"
}
}