-
Notifications
You must be signed in to change notification settings - Fork 374
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PDO::ATTR_EMULATE_PREPARES at the connection level (#1324)
- Loading branch information
Showing
8 changed files
with
243 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 21 additions & 26 deletions
47
test/functional/pdo_sqlsrv/pdoStatement_bindParam_output_emulate_prepare.phpt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,44 @@ | ||
--TEST-- | ||
Tests error returned when binding output parameter with emulate prepare | ||
--DESCRIPTION-- | ||
The test shows that the option sets in prepared statements overrides the | ||
connection setting of PDO::ATTR_EMULATE_PREPARES | ||
--SKIPIF-- | ||
<?php require_once('skipif_mid-refactor.inc'); ?> | ||
<?php require('skipif_azure_dw.inc'); ?> | ||
--FILE-- | ||
<?php | ||
require_once("MsCommon_mid-refactor.inc"); | ||
require_once("MsSetup.inc"); | ||
|
||
try { | ||
$conn = connect(); | ||
// Do not connect with AE enabled because otherwise this would have thrown a different exception | ||
$conn = new PDO("sqlsrv:server=$server; Database = $databaseName;", $uid, $pwd); | ||
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | ||
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); | ||
|
||
$count = 0; | ||
|
||
$query = "select ? = count(* ) from cd_info"; | ||
$stmt = $conn->prepare($query, array(PDO::ATTR_EMULATE_PREPARES => true)); | ||
$stmt->bindParam(1, $count, PDO::PARAM_STR, 10); | ||
$stmt->execute(); | ||
echo "Result: ".$count."\n"; | ||
|
||
$query = "select bigint_type, int_type, money_type from [test_types] where int_type < 0"; | ||
$stmt1 = $conn->prepare($query); | ||
$stmt1->execute(); | ||
$row = $stmt1->fetch(PDO::FETCH_ASSOC); | ||
print_r($row); | ||
$stmt = $conn->prepare($query); | ||
} catch (PDOException $e) { | ||
print("Error: " . $e->getMessage() . "\n"); | ||
} | ||
|
||
try { | ||
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); | ||
|
||
$int = 0; | ||
$bigint = 100; | ||
$query = "select ? = bigint_type, ? = int_type, ? = money_type from [test_types] where int_type < 0"; | ||
$stmt2 = $conn->prepare($query, array(PDO::ATTR_EMULATE_PREPARES => true)); | ||
$stmt2->bindparam(1, $bigint, PDO::PARAM_STR, 256); | ||
$stmt2->bindParam(2, $int, PDO::PARAM_INT, 4); | ||
$stmt2->bindParam(3, $money, PDO::PARAM_STR, 1024); | ||
$stmt2->execute(); | ||
echo "Big integer: ".$bigint."\n"; | ||
echo "Integer: ".$int."\n"; | ||
echo "Money: ".$money."\n"; | ||
|
||
//free the statement and connection | ||
unset($stmt); | ||
unset($stmt1); | ||
unset($stmt2); | ||
unset($conn); | ||
$stmt = $conn->prepare($query, array(PDO::ATTR_EMULATE_PREPARES => true)); | ||
} catch (PDOException $e) { | ||
print("Error: " . $e->getMessage() . "\n"); | ||
} | ||
|
||
// free the statement and connection | ||
unset($stmt); | ||
unset($conn); | ||
?> | ||
--EXPECT-- | ||
Error: SQLSTATE[IMSSP]: Statement with emulate prepare on does not support output or input_output parameters. | ||
Error: SQLSTATE[IMSSP]: Statement with emulate prepare on does not support output or input_output parameters. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
test/functional/pdo_sqlsrv/pdo_1320_pdo_emulate_prepare.phpt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
--TEST-- | ||
GitHub issue 1320 - support PDO::ATTR_EMULATE_PREPARES at the connection level | ||
--DESCRIPTION-- | ||
Supports PDO::ATTR_EMULATE_PREPARES at the connection level but setting it to true with column | ||
encryption enabled will fail with an exception. Also, the options in the prepared statement will | ||
override the connection setting. | ||
--ENV-- | ||
PHPT_EXEC=true | ||
--SKIPIF-- | ||
<?php require('skipif_mid-refactor.inc'); ?> | ||
--FILE-- | ||
<?php | ||
require_once("MsSetup.inc"); | ||
require_once("MsCommon_mid-refactor.inc"); | ||
|
||
try { | ||
// Connection with column encryption enabled | ||
$connectionInfo = "ColumnEncryption = Enabled;"; | ||
$conn = new PDO("sqlsrv:server = $server; database=$databaseName; $connectionInfo", $uid, $pwd); | ||
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | ||
|
||
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); | ||
echo "setAttribute should have failed because column encryption is enabled.\n\n"; | ||
} catch (PDOException $e) { | ||
echo $e->getMessage() . "\n"; | ||
} | ||
|
||
unset($conn); | ||
|
||
try { | ||
// Connection with column encryption enabled | ||
$options = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => true); | ||
$connectionInfo = "ColumnEncryption = Enabled;"; | ||
$conn = new PDO("sqlsrv:server = $server; database=$databaseName; $connectionInfo", $uid, $pwd, $options); | ||
} catch (PDOException $e) { | ||
echo $e->getMessage() . "\n"; | ||
} | ||
|
||
unset($conn); | ||
|
||
try { | ||
// Connection with column encryption enabled - PDO::ATTR_EMULATE_PREPARES is false by default | ||
$connectionInfo = "ColumnEncryption = Enabled;"; | ||
$conn = new PDO("sqlsrv:server = $server; database=$databaseName; $connectionInfo", $uid, $pwd); | ||
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | ||
|
||
echo "Connected successfully with column encryption enabled.\n"; | ||
$enabled = $conn->getAttribute(PDO::ATTR_EMULATE_PREPARES); | ||
echo "By default, the emulation of prepared statements is:\n"; | ||
var_dump($enabled); | ||
} catch (PDOException $e) { | ||
echo $e->getMessage() . "\n"; | ||
} | ||
|
||
?> | ||
|
||
--EXPECT-- | ||
SQLSTATE[IMSSP]: Parameterized statement with attribute PDO::ATTR_EMULATE_PREPARES is not supported in a Column Encryption enabled Connection. | ||
SQLSTATE[IMSSP]: Parameterized statement with attribute PDO::ATTR_EMULATE_PREPARES is not supported in a Column Encryption enabled Connection. | ||
Connected successfully with column encryption enabled. | ||
By default, the emulation of prepared statements is: | ||
bool(false) |
137 changes: 137 additions & 0 deletions
137
test/functional/pdo_sqlsrv/pdo_prepare_emulatePrepare_unicode2.phpt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
--TEST-- | ||
Prepare with emulate prepare and binding uft8 characters | ||
--DESCRIPTION-- | ||
This is the same as pdo_prepare_emulatePrepare_unicode.phpt except that | ||
PDO::ATTR_EMULATE_PREPARES at the connection level | ||
--SKIPIF-- | ||
<?php require('skipif_mid-refactor.inc'); ?> | ||
--FILE-- | ||
<?php | ||
require_once('MsCommon_mid-refactor.inc'); | ||
|
||
function prepareStmt($conn, $query, $prepareOptions = array(), $dataType = PDO::PARAM_STR, $length = 0, $driverOptions = null) | ||
{ | ||
$name = "가각"; | ||
if (!isColEncrypted()) { | ||
$stmt = $conn->prepare($query, $prepareOptions); | ||
$stmt->bindParam(':name', $name, $dataType, $length, $driverOptions); | ||
} else { | ||
$status = 1; | ||
$stmt = $conn->prepare($query, $prepareOptions); | ||
$stmt->bindParam(':name', $name, $dataType, $length, $driverOptions); | ||
$stmt->bindParam(':status', $status); | ||
} | ||
$stmt->execute(); | ||
return $stmt; | ||
} | ||
|
||
try { | ||
$conn = connect("", array(), PDO::ERRMODE_SILENT); | ||
|
||
$tableName = "users"; | ||
createTable($conn, $tableName, array("name" => "nvarchar(max)", "status" => "int", "age" => "int")); | ||
|
||
if (!isColEncrypted()) { | ||
$conn->exec("INSERT INTO [$tableName] (name, status, age) VALUES (N'Belle', 1, 34)"); | ||
$conn->exec("INSERT INTO [$tableName] (name, status, age) VALUES (N'Абрам', 1, 40)"); | ||
$conn->exec("INSERT INTO [$tableName] (name, status, age) VALUES (N'가각', 1, 30)"); | ||
$query = "SELECT * FROM [$tableName] WHERE name = :name AND status = 1"; | ||
} else { | ||
insertRow($conn, $tableName, array("name" => "Belle", "status" => 1, "age" => 34)); | ||
insertRow($conn, $tableName, array("name" => "Абрам", "status" => 1, "age" => 40)); | ||
insertRow($conn, $tableName, array("name" => "가각", "status" => 1, "age" => 30)); | ||
$query = "SELECT * FROM [$tableName] WHERE name = :name AND status = :status"; | ||
} | ||
|
||
//without emulate prepare | ||
print_r("Prepare without emulate prepare:\n"); | ||
$stmt = prepareStmt($conn, $query, array(), PDO::PARAM_STR, 0, PDO::SQLSRV_ENCODING_UTF8); | ||
$row = $stmt->fetch(PDO::FETCH_ASSOC); | ||
print_r($row); | ||
|
||
if (!isAEConnected()) { | ||
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); | ||
} else { | ||
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); | ||
} | ||
|
||
//with emulate prepare and no bind param options | ||
print_r("Prepare with emulate prepare and no bindParam options:\n"); | ||
// This test only makes sense without AE because the default encoding is PDO::SQLSRV_ENCODING_UTF8 | ||
if (!isAEConnected()) { | ||
$stmt = prepareStmt($conn, $query, array()); | ||
$row = $stmt->fetch(PDO::FETCH_ASSOC); | ||
if ($stmt->rowCount() != 0) { | ||
print_r("Do not expect results for this query!\n"); | ||
print_r($row); | ||
} | ||
} | ||
|
||
//with emulate prepare and SQLSRV_ENCODING_UTF8 | ||
print_r("Prepare with emulate prepare and SQLSRV_ENCODING_UTF8:\n"); | ||
$stmt = prepareStmt($conn, $query, array(), PDO::PARAM_STR, 0, PDO::SQLSRV_ENCODING_UTF8); | ||
$row = $stmt->fetch(PDO::FETCH_ASSOC); | ||
print_r($row); | ||
|
||
//with emulate prepare and SQLSRV_ENCODING_SYSTEM | ||
print_r("Prepare with emulate prepare and and SQLSRV_ENCODING_SYSTEM:\n"); | ||
$stmt = prepareStmt($conn, $query, array(), PDO::PARAM_STR, 0, PDO::SQLSRV_ENCODING_SYSTEM); | ||
$row = $stmt->fetch(PDO::FETCH_ASSOC); | ||
|
||
// The combination of Column Encryption and Unix platforms support SQLSRV_ENCODING_SYSTEM because: | ||
// With Column Encryption enabled, binding parameters uses exact datatypes as the column definition | ||
// the default encoding in Linux and Mac is UTF8 | ||
$success = true; | ||
if (!(strtoupper( substr( php_uname( 's' ),0,3 ) ) === 'WIN') && isAEConnected()) { | ||
if ($row['name'] != "가각" || $row['status'] != 1 || $row['age'] != 30) { | ||
print_r("Incorrect results retrieved.\n"); | ||
$success = false; | ||
} | ||
} else { | ||
// the default encoding in Windows is non-UTF8, thus binding UTF8 parameters does not work | ||
if ($stmt->rowCount() != 0) { | ||
print_r("Binding UTF8 data when encoding is SQLSRV_ENCODING_SYSTEM should not work.\n"); | ||
$success = false; | ||
} | ||
} | ||
if ($success) { | ||
print_r("Binding UTF8 data with SQLSRV_ENCODING_SYSTEM is tested successfully.\n"); | ||
} | ||
|
||
//with emulate prepare and encoding SQLSRV_ENCODING_BINARY | ||
print_r("Prepare with emulate prepare and encoding SQLSRV_ENCODING_BINARY:\n"); | ||
$stmt = prepareStmt($conn, $query, array(), PDO::PARAM_STR, 0, PDO::SQLSRV_ENCODING_BINARY); | ||
$row = $stmt->fetch(PDO::FETCH_ASSOC); | ||
print_r($row); | ||
if ($stmt->rowCount() == 0) { | ||
print_r("No results for this query\n"); | ||
} | ||
|
||
dropTable($conn, $tableName); | ||
unset($stmt); | ||
unset($conn); | ||
} catch (PDOException $e) { | ||
var_dump($e->errorInfo); | ||
} | ||
?> | ||
|
||
--EXPECT-- | ||
Prepare without emulate prepare: | ||
Array | ||
( | ||
[name] => 가각 | ||
[status] => 1 | ||
[age] => 30 | ||
) | ||
Prepare with emulate prepare and no bindParam options: | ||
Prepare with emulate prepare and SQLSRV_ENCODING_UTF8: | ||
Array | ||
( | ||
[name] => 가각 | ||
[status] => 1 | ||
[age] => 30 | ||
) | ||
Prepare with emulate prepare and and SQLSRV_ENCODING_SYSTEM: | ||
Binding UTF8 data with SQLSRV_ENCODING_SYSTEM is tested successfully. | ||
Prepare with emulate prepare and encoding SQLSRV_ENCODING_BINARY: | ||
No results for this query |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters