Skip to content

Commit e02db62

Browse files
authored
Added more pdo tests to verify different error conditions (#984)
1 parent 9e90a42 commit e02db62

File tree

5 files changed

+499
-50
lines changed

5 files changed

+499
-50
lines changed
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
--TEST--
2+
GitHub Issue #35 binary encoding error when binding by name
3+
--DESCRIPTION--
4+
Based on pdo_035_binary_encoding_error_bound_by_name.phpt but this includes error checking for various encoding errors
5+
--SKIPIF--
6+
<?php require('skipif_mid-refactor.inc'); ?>
7+
--FILE--
8+
<?php
9+
10+
function bindTypeNoEncoding($conn, $sql, $input)
11+
{
12+
try {
13+
$value = 1;
14+
15+
$stmt = $conn->prepare($sql);
16+
$stmt->bindParam(1, $value, PDO::PARAM_INT, 0, PDO::SQLSRV_ENCODING_DEFAULT);
17+
$stmt->setAttribute(constant('PDO::SQLSRV_ATTR_ENCODING'), PDO::SQLSRV_ENCODING_BINARY);
18+
$stmt->bindParam(2, $input, PDO::PARAM_LOB);
19+
$stmt->execute();
20+
} catch (PDOException $e) {
21+
$error = '*An encoding was specified for parameter 1. Only PDO::PARAM_LOB and PDO::PARAM_STR can take an encoding option.';
22+
if (!fnmatch($error, $e->getMessage())) {
23+
echo "Error message unexpected in bindTypeNoEncoding\n";
24+
var_dump($e->getMessage());
25+
}
26+
}
27+
}
28+
29+
function bindDefaultEncoding($conn, $sql, $input)
30+
{
31+
try {
32+
$value = 1;
33+
34+
$stmt = $conn->prepare($sql);
35+
$stmt->bindParam(1, $value, PDO::PARAM_STR, 0, PDO::SQLSRV_ENCODING_DEFAULT);
36+
$stmt->setAttribute(constant('PDO::SQLSRV_ATTR_ENCODING'), PDO::SQLSRV_ENCODING_BINARY);
37+
$stmt->bindParam(2, $input, PDO::PARAM_LOB);
38+
$stmt->execute();
39+
} catch (PDOException $e) {
40+
$error = '*Invalid encoding specified for parameter 1.';
41+
if (!fnmatch($error, $e->getMessage())) {
42+
echo "Error message unexpected in bindDefaultEncoding\n";
43+
var_dump($e->getMessage());
44+
}
45+
}
46+
}
47+
48+
function insertData($conn, $sql, $input)
49+
{
50+
try {
51+
$value = 1;
52+
53+
$stmt = $conn->prepare($sql);
54+
$stmt->bindParam(1, $value);
55+
$stmt->setAttribute(constant('PDO::SQLSRV_ATTR_ENCODING'), PDO::SQLSRV_ENCODING_BINARY);
56+
$stmt->bindParam(2, $input, PDO::PARAM_LOB);
57+
$stmt->execute();
58+
} catch (PDOException $e) {
59+
echo "Error unexpected in insertData\n";
60+
var_dump($e->getMessage());
61+
}
62+
}
63+
64+
function invalidEncoding1($conn, $sql)
65+
{
66+
try {
67+
$stmt = $conn->prepare($sql);
68+
$stmt->bindColumn(1, $id, PDO::PARAM_INT, 0, PDO::SQLSRV_ENCODING_UTF8);
69+
$stmt->execute();
70+
$stmt->fetch(PDO::FETCH_BOUND);
71+
} catch (PDOException $e) {
72+
$error = '*An encoding was specified for column 1. Only PDO::PARAM_LOB and PDO::PARAM_STR column types can take an encoding option.';
73+
if (!fnmatch($error, $e->getMessage())) {
74+
echo "Error message unexpected in invalidEncoding1\n";
75+
var_dump($e->getMessage());
76+
}
77+
}
78+
}
79+
80+
function invalidEncoding2($conn, $sql)
81+
{
82+
try {
83+
$stmt = $conn->prepare($sql);
84+
$stmt->bindColumn('Value', $val1, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_DEFAULT);
85+
$stmt->execute();
86+
$stmt->fetch(PDO::FETCH_BOUND);
87+
} catch (PDOException $e) {
88+
$error = '*Invalid encoding specified for column 1.';
89+
if (!fnmatch($error, $e->getMessage())) {
90+
echo "Error message unexpected in invalidEncoding2\n";
91+
var_dump($e->getMessage());
92+
}
93+
}
94+
}
95+
96+
function invalidEncoding3($conn, $sql)
97+
{
98+
try {
99+
$stmt = $conn->prepare($sql);
100+
$stmt->bindColumn(1, $id, PDO::PARAM_STR, 0, "dummy");
101+
$stmt->execute();
102+
$stmt->fetch(PDO::FETCH_BOUND);
103+
} catch (PDOException $e) {
104+
$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.';
105+
if (!fnmatch($error, $e->getMessage())) {
106+
echo "Error message unexpected in invalidEncoding3\n";
107+
var_dump($e->getMessage());
108+
}
109+
}
110+
}
111+
112+
try {
113+
require_once( "MsCommon_mid-refactor.inc" );
114+
115+
// Connect
116+
$conn = connect();
117+
118+
// Create a table
119+
$tableName = "testTableIssue35";
120+
createTable($conn, $tableName, array("ID" => "int", "Value" => "varbinary(max)"));
121+
122+
// Insert data using bind parameters
123+
$sql = "INSERT INTO $tableName VALUES (?, ?)";
124+
$message = "This is to test github issue 35.";
125+
$value = base64_encode($message);
126+
127+
// Errors expected
128+
bindTypeNoEncoding($conn, $sql, $value);
129+
bindDefaultEncoding($conn, $sql, $value);
130+
131+
// No error expected
132+
insertData($conn, $sql, $value);
133+
134+
// Fetch data, but test several invalid encoding issues (errors expected)
135+
$sql = "SELECT * FROM $tableName";
136+
invalidEncoding1($conn, $sql);
137+
invalidEncoding2($conn, $sql);
138+
invalidEncoding3($conn, $sql);
139+
140+
// Now fetch it back
141+
$stmt = $conn->prepare("SELECT Value FROM $tableName");
142+
$stmt->bindColumn('Value', $val1, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY);
143+
$stmt->execute();
144+
$stmt->fetch(PDO::FETCH_BOUND);
145+
var_dump($val1 === $value);
146+
147+
// Close connection
148+
dropTable($conn, $tableName);
149+
unset($stmt);
150+
unset($conn);
151+
print "Done\n";
152+
} catch (PDOException $e) {
153+
var_dump($e->errorInfo);
154+
}
155+
?>
156+
--EXPECT--
157+
bool(true)
158+
Done
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
--TEST--
2+
Test fetchColumn twice in a row. Intentionally trigger various error messages.
3+
--DESCRIPTION--
4+
This is similar to sqlsrv_fetch_field_twice_data_types.phpt.
5+
--SKIPIF--
6+
<?php require('skipif_mid-refactor.inc'); ?>
7+
--FILE--
8+
<?php
9+
require_once("MsCommon_mid-refactor.inc");
10+
11+
function fetchBeforeExecute($conn, $tableName, $inputs)
12+
{
13+
try {
14+
$tsql = "SELECT * FROM $tableName";
15+
$stmt = $conn->prepare($tsql);
16+
$row = $stmt->fetch(PDO::FETCH_ASSOC);
17+
if ($row !== false) {
18+
echo "fetchBeforeExecute: fetch should have failed before execute!\n";
19+
}
20+
$stmt->execute();
21+
$row = $stmt->fetch(PDO::FETCH_NUM);
22+
23+
for ($i = 0; $i < count($inputs); $i++) {
24+
if ($row[$i] !== $inputs[$i]) {
25+
echo "fetchBeforeExecute: expected $inputs[$i] but got $row[$i]\n";
26+
}
27+
}
28+
29+
unset($stmt);
30+
} catch (PDOException $e) {
31+
var_dump($e->getMessage());
32+
}
33+
}
34+
35+
function fetchColumnTwice($conn, $tableName, $col, $input)
36+
{
37+
try {
38+
$tsql = "SELECT * FROM $tableName";
39+
$stmt = $conn->query($tsql);
40+
$result = $stmt->fetchColumn($col);
41+
if ($result !== $input) {
42+
echo "fetchColumnTwice (1): expected $input but got $result\n";
43+
}
44+
$result = $stmt->fetchColumn($col);
45+
if ($result !== false) {
46+
echo "fetchColumnTwice (2): expected the second fetchColumn to fail\n";
47+
}
48+
49+
// Re-run the query with fetch style
50+
$stmt = $conn->query($tsql, PDO::FETCH_COLUMN, $col);
51+
$result = $stmt->fetch();
52+
if ($result !== $input) {
53+
echo "fetchColumnTwice (3): expected $input but got $result\n";
54+
}
55+
$result = $stmt->fetch();
56+
if ($result !== false) {
57+
echo "fetchColumnTwice (4): expected the second fetch to fail\n";
58+
}
59+
$result = $stmt->fetchColumn($col);
60+
echo "fetchColumnTwice (5): expected fetchColumn to throw an exception\n";
61+
unset($stmt);
62+
} catch (PDOException $e) {
63+
$error = '*There are no more rows in the active result set. Since this result set is not scrollable, no more data may be retrieved.';
64+
65+
if (!fnmatch($error, $e->getMessage())) {
66+
echo "Error message unexpected in fetchColumnTwice\n";
67+
var_dump($e->getMessage());
68+
}
69+
}
70+
}
71+
72+
function fetchColumnOutOfBound1($conn, $tableName, $col)
73+
{
74+
try {
75+
$tsql = "SELECT * FROM $tableName";
76+
$stmt = $conn->query($tsql);
77+
$result = $stmt->fetchColumn($col);
78+
echo "fetchColumnOutOfBound1: expected fetchColumn to throw an exception\n";
79+
unset($stmt);
80+
} catch (PDOException $e) {
81+
$error1 = '*General error: Invalid column index';
82+
$error2 = '*An invalid column number was specified.';
83+
84+
// Different errors may be returned depending on running with run-tests.php or not
85+
if (fnmatch($error1, $e->getMessage()) || fnmatch($error2, $e->getMessage())) {
86+
;
87+
} else {
88+
echo "Error message unexpected in fetchColumnOutOfBound1\n";
89+
var_dump($e->getMessage());
90+
}
91+
}
92+
}
93+
94+
function fetchColumnOutOfBound2($conn, $tableName, $col)
95+
{
96+
try {
97+
$tsql = "SELECT * FROM $tableName";
98+
$stmt = $conn->query($tsql, PDO::FETCH_COLUMN, $col);
99+
$result = $stmt->fetch();
100+
unset($stmt);
101+
} catch (PDOException $e) {
102+
var_dump($e->getMessage());
103+
}
104+
}
105+
106+
try {
107+
$conn = connect();
108+
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
109+
110+
$tableName = 'pdoFetchColumnTwice';
111+
$colMeta = array(new ColumnMeta('int', 'c1_int'),
112+
new ColumnMeta('varchar(20)', 'c2_varchar'),
113+
new ColumnMeta('decimal(5, 3)', 'c3_decimal'),
114+
new ColumnMeta('datetime', 'c4_datetime'));
115+
createTable($conn, $tableName, $colMeta);
116+
117+
$inputs = array('968580013', 'dummy value', '3.438', ('1756-04-16 23:27:09.130'));
118+
$numCols = count($inputs);
119+
120+
$tsql = "INSERT INTO $tableName(c1_int, c2_varchar, c3_decimal, c4_datetime) VALUES (?,?,?,?)";
121+
$stmt = $conn->prepare($tsql);
122+
123+
for ($i = 0; $i < $numCols; $i++) {
124+
$stmt->bindParam($i + 1, $inputs[$i]);
125+
}
126+
$stmt->execute();
127+
unset($stmt);
128+
129+
fetchBeforeExecute($conn, $tableName, $inputs);
130+
for ($i = 0; $i < $numCols; $i++) {
131+
fetchColumnTwice($conn, $tableName, $i, $inputs[$i]);
132+
}
133+
134+
fetchColumnOutOfBound1($conn, $tableName, -1);
135+
136+
// Change to warning mode
137+
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
138+
fetchColumnOutOfBound2($conn, $tableName, $numCols + 1);
139+
140+
dropTable($conn, $tableName);
141+
unset($conn);
142+
echo "Done\n";
143+
} catch (PDOException $e) {
144+
var_dump($e);
145+
}
146+
?>
147+
--EXPECTREGEX--
148+
Warning: PDOStatement::fetch\(\): SQLSTATE\[HY000\]: General error: Invalid column index in .+(\/|\\)pdo_fetch_column_twice.php on line [0-9]+
149+
150+
Warning: PDOStatement::fetch\(\): SQLSTATE\[HY000\]: General error in .+(\/|\\)pdo_fetch_column_twice.php on line [0-9]+
151+
Done

test/functional/pdo_sqlsrv/pdo_output_decimal.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ try {
4242
$expected1 = "7.4";
4343
$expected2 = "7";
4444
if ($outValue1 == $expected1 && $outValue2 == $expected2) {
45-
echo "Test Successfully\n";
45+
echo "Test Successful\n";
4646
}
4747

4848
dropProc($conn, $proc_scale);
@@ -56,4 +56,4 @@ try {
5656
?>
5757

5858
--EXPECT--
59-
Test Successfully
59+
Test Successful

0 commit comments

Comments
 (0)