Skip to content

Added more pdo tests to verify different error conditions #984

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
--TEST--
GitHub Issue #35 binary encoding error when binding by name
--DESCRIPTION--
Based on pdo_035_binary_encoding_error_bound_by_name.phpt but this includes error checking for various encoding errors
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php

function bindTypeNoEncoding($conn, $sql, $input)
{
try {
$value = 1;

$stmt = $conn->prepare($sql);
$stmt->bindParam(1, $value, PDO::PARAM_INT, 0, PDO::SQLSRV_ENCODING_DEFAULT);
$stmt->setAttribute(constant('PDO::SQLSRV_ATTR_ENCODING'), PDO::SQLSRV_ENCODING_BINARY);
$stmt->bindParam(2, $input, PDO::PARAM_LOB);
$stmt->execute();
} catch (PDOException $e) {
$error = '*An encoding was specified for parameter 1. Only PDO::PARAM_LOB and PDO::PARAM_STR can take an encoding option.';
if (!fnmatch($error, $e->getMessage())) {
echo "Error message unexpected in bindTypeNoEncoding\n";
var_dump($e->getMessage());
}
}
}

function bindDefaultEncoding($conn, $sql, $input)
{
try {
$value = 1;

$stmt = $conn->prepare($sql);
$stmt->bindParam(1, $value, PDO::PARAM_STR, 0, PDO::SQLSRV_ENCODING_DEFAULT);
$stmt->setAttribute(constant('PDO::SQLSRV_ATTR_ENCODING'), PDO::SQLSRV_ENCODING_BINARY);
$stmt->bindParam(2, $input, PDO::PARAM_LOB);
$stmt->execute();
} catch (PDOException $e) {
$error = '*Invalid encoding specified for parameter 1.';
if (!fnmatch($error, $e->getMessage())) {
echo "Error message unexpected in bindDefaultEncoding\n";
var_dump($e->getMessage());
}
}
}

function insertData($conn, $sql, $input)
{
try {
$value = 1;

$stmt = $conn->prepare($sql);
$stmt->bindParam(1, $value);
$stmt->setAttribute(constant('PDO::SQLSRV_ATTR_ENCODING'), PDO::SQLSRV_ENCODING_BINARY);
$stmt->bindParam(2, $input, PDO::PARAM_LOB);
$stmt->execute();
} catch (PDOException $e) {
echo "Error unexpected in insertData\n";
var_dump($e->getMessage());
}
}

function invalidEncoding1($conn, $sql)
{
try {
$stmt = $conn->prepare($sql);
$stmt->bindColumn(1, $id, PDO::PARAM_INT, 0, PDO::SQLSRV_ENCODING_UTF8);
$stmt->execute();
$stmt->fetch(PDO::FETCH_BOUND);
} catch (PDOException $e) {
$error = '*An encoding was specified for column 1. Only PDO::PARAM_LOB and PDO::PARAM_STR column types can take an encoding option.';
if (!fnmatch($error, $e->getMessage())) {
echo "Error message unexpected in invalidEncoding1\n";
var_dump($e->getMessage());
}
}
}

function invalidEncoding2($conn, $sql)
{
try {
$stmt = $conn->prepare($sql);
$stmt->bindColumn('Value', $val1, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_DEFAULT);
$stmt->execute();
$stmt->fetch(PDO::FETCH_BOUND);
} catch (PDOException $e) {
$error = '*Invalid encoding specified for column 1.';
if (!fnmatch($error, $e->getMessage())) {
echo "Error message unexpected in invalidEncoding2\n";
var_dump($e->getMessage());
}
}
}

function invalidEncoding3($conn, $sql)
{
try {
$stmt = $conn->prepare($sql);
$stmt->bindColumn(1, $id, PDO::PARAM_STR, 0, "dummy");
$stmt->execute();
$stmt->fetch(PDO::FETCH_BOUND);
} catch (PDOException $e) {
$error = '*An invalid type or value was given as bound column driver data for column 1. Only encoding constants such as PDO::SQLSRV_ENCODING_UTF8 may be used as bound column driver data.';
if (!fnmatch($error, $e->getMessage())) {
echo "Error message unexpected in invalidEncoding3\n";
var_dump($e->getMessage());
}
}
}

try {
require_once( "MsCommon_mid-refactor.inc" );

// Connect
$conn = connect();

// Create a table
$tableName = "testTableIssue35";
createTable($conn, $tableName, array("ID" => "int", "Value" => "varbinary(max)"));

// Insert data using bind parameters
$sql = "INSERT INTO $tableName VALUES (?, ?)";
$message = "This is to test github issue 35.";
$value = base64_encode($message);

// Errors expected
bindTypeNoEncoding($conn, $sql, $value);
bindDefaultEncoding($conn, $sql, $value);

// No error expected
insertData($conn, $sql, $value);

// Fetch data, but test several invalid encoding issues (errors expected)
$sql = "SELECT * FROM $tableName";
invalidEncoding1($conn, $sql);
invalidEncoding2($conn, $sql);
invalidEncoding3($conn, $sql);

// Now fetch it back
$stmt = $conn->prepare("SELECT Value FROM $tableName");
$stmt->bindColumn('Value', $val1, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY);
$stmt->execute();
$stmt->fetch(PDO::FETCH_BOUND);
var_dump($val1 === $value);

// Close connection
dropTable($conn, $tableName);
unset($stmt);
unset($conn);
print "Done\n";
} catch (PDOException $e) {
var_dump($e->errorInfo);
}
?>
--EXPECT--
bool(true)
Done
151 changes: 151 additions & 0 deletions test/functional/pdo_sqlsrv/pdo_fetch_column_twice.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
--TEST--
Test fetchColumn twice in a row. Intentionally trigger various error messages.
--DESCRIPTION--
This is similar to sqlsrv_fetch_field_twice_data_types.phpt.
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");

function fetchBeforeExecute($conn, $tableName, $inputs)
{
try {
$tsql = "SELECT * FROM $tableName";
$stmt = $conn->prepare($tsql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row !== false) {
echo "fetchBeforeExecute: fetch should have failed before execute!\n";
}
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_NUM);

for ($i = 0; $i < count($inputs); $i++) {
if ($row[$i] !== $inputs[$i]) {
echo "fetchBeforeExecute: expected $inputs[$i] but got $row[$i]\n";
}
}

unset($stmt);
} catch (PDOException $e) {
var_dump($e->getMessage());
}
}

function fetchColumnTwice($conn, $tableName, $col, $input)
{
try {
$tsql = "SELECT * FROM $tableName";
$stmt = $conn->query($tsql);
$result = $stmt->fetchColumn($col);
if ($result !== $input) {
echo "fetchColumnTwice (1): expected $input but got $result\n";
}
$result = $stmt->fetchColumn($col);
if ($result !== false) {
echo "fetchColumnTwice (2): expected the second fetchColumn to fail\n";
}

// Re-run the query with fetch style
$stmt = $conn->query($tsql, PDO::FETCH_COLUMN, $col);
$result = $stmt->fetch();
if ($result !== $input) {
echo "fetchColumnTwice (3): expected $input but got $result\n";
}
$result = $stmt->fetch();
if ($result !== false) {
echo "fetchColumnTwice (4): expected the second fetch to fail\n";
}
$result = $stmt->fetchColumn($col);
echo "fetchColumnTwice (5): expected fetchColumn to throw an exception\n";
unset($stmt);
} catch (PDOException $e) {
$error = '*There are no more rows in the active result set. Since this result set is not scrollable, no more data may be retrieved.';

if (!fnmatch($error, $e->getMessage())) {
echo "Error message unexpected in fetchColumnTwice\n";
var_dump($e->getMessage());
}
}
}

function fetchColumnOutOfBound1($conn, $tableName, $col)
{
try {
$tsql = "SELECT * FROM $tableName";
$stmt = $conn->query($tsql);
$result = $stmt->fetchColumn($col);
echo "fetchColumnOutOfBound1: expected fetchColumn to throw an exception\n";
unset($stmt);
} catch (PDOException $e) {
$error1 = '*General error: Invalid column index';
$error2 = '*An invalid column number was specified.';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So either error might be returned?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, different error is returned depends on running with run-tests.php or not


// Different errors may be returned depending on running with run-tests.php or not
if (fnmatch($error1, $e->getMessage()) || fnmatch($error2, $e->getMessage())) {
;
} else {
echo "Error message unexpected in fetchColumnOutOfBound1\n";
var_dump($e->getMessage());
}
}
}

function fetchColumnOutOfBound2($conn, $tableName, $col)
{
try {
$tsql = "SELECT * FROM $tableName";
$stmt = $conn->query($tsql, PDO::FETCH_COLUMN, $col);
$result = $stmt->fetch();
unset($stmt);
} catch (PDOException $e) {
var_dump($e->getMessage());
}
}

try {
$conn = connect();
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$tableName = 'pdoFetchColumnTwice';
$colMeta = array(new ColumnMeta('int', 'c1_int'),
new ColumnMeta('varchar(20)', 'c2_varchar'),
new ColumnMeta('decimal(5, 3)', 'c3_decimal'),
new ColumnMeta('datetime', 'c4_datetime'));
createTable($conn, $tableName, $colMeta);

$inputs = array('968580013', 'dummy value', '3.438', ('1756-04-16 23:27:09.130'));
$numCols = count($inputs);

$tsql = "INSERT INTO $tableName(c1_int, c2_varchar, c3_decimal, c4_datetime) VALUES (?,?,?,?)";
$stmt = $conn->prepare($tsql);

for ($i = 0; $i < $numCols; $i++) {
$stmt->bindParam($i + 1, $inputs[$i]);
}
$stmt->execute();
unset($stmt);

fetchBeforeExecute($conn, $tableName, $inputs);
for ($i = 0; $i < $numCols; $i++) {
fetchColumnTwice($conn, $tableName, $i, $inputs[$i]);
}

fetchColumnOutOfBound1($conn, $tableName, -1);

// Change to warning mode
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
fetchColumnOutOfBound2($conn, $tableName, $numCols + 1);

dropTable($conn, $tableName);
unset($conn);
echo "Done\n";
} catch (PDOException $e) {
var_dump($e);
}
?>
--EXPECTREGEX--
Warning: PDOStatement::fetch\(\): SQLSTATE\[HY000\]: General error: Invalid column index in .+(\/|\\)pdo_fetch_column_twice.php on line [0-9]+

Warning: PDOStatement::fetch\(\): SQLSTATE\[HY000\]: General error in .+(\/|\\)pdo_fetch_column_twice.php on line [0-9]+
Done
4 changes: 2 additions & 2 deletions test/functional/pdo_sqlsrv/pdo_output_decimal.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ try {
$expected1 = "7.4";
$expected2 = "7";
if ($outValue1 == $expected1 && $outValue2 == $expected2) {
echo "Test Successfully\n";
echo "Test Successful\n";
}

dropProc($conn, $proc_scale);
Expand All @@ -56,4 +56,4 @@ try {
?>

--EXPECT--
Test Successfully
Test Successful
Loading