diff --git a/source/pdo_sqlsrv/pdo_stmt.cpp b/source/pdo_sqlsrv/pdo_stmt.cpp index 6adfbd0c2..2506960bf 100644 --- a/source/pdo_sqlsrv/pdo_stmt.cpp +++ b/source/pdo_sqlsrv/pdo_stmt.cpp @@ -721,12 +721,10 @@ int pdo_sqlsrv_stmt_get_col_data(pdo_stmt_t *stmt, int colno, sqlsrv_phptype sqlsrv_php_type; SQLSRV_ASSERT( colno >= 0 && colno < static_cast( driver_stmt->current_meta_data.size()), "Invalid column number in pdo_sqlsrv_stmt_get_col_data" ); - sqlsrv_php_type = driver_stmt->sql_type_to_php_type( static_cast( driver_stmt->current_meta_data[ colno ]->field_type ), - static_cast( driver_stmt->current_meta_data[ colno ]->field_size ), - true ); // set the encoding if the user specified one via bindColumn, otherwise use the statement's encoding - sqlsrv_php_type.typeinfo.encoding = driver_stmt->encoding(); + sqlsrv_php_type = driver_stmt->sql_type_to_php_type( static_cast( driver_stmt->current_meta_data[colno]->field_type ), + static_cast( driver_stmt->current_meta_data[colno]->field_size ), true ); // if a column is bound to a type different than the column type, figure out a way to convert it to the // type they want @@ -1306,6 +1304,8 @@ sqlsrv_phptype pdo_sqlsrv_stmt::sql_type_to_php_type( SQLINTEGER sql_type, SQLUI "Invalid encoding on the connection. Must not be invalid or default." ); } + sqlsrv_phptype.typeinfo.encoding = local_encoding; + switch( sql_type ) { case SQL_BIT: case SQL_INTEGER: @@ -1316,7 +1316,6 @@ sqlsrv_phptype pdo_sqlsrv_stmt::sql_type_to_php_type( SQLINTEGER sql_type, SQLUI } else { sqlsrv_phptype.typeinfo.type = SQLSRV_PHPTYPE_STRING; - sqlsrv_phptype.typeinfo.encoding = local_encoding; } break; case SQL_FLOAT: @@ -1326,7 +1325,6 @@ sqlsrv_phptype pdo_sqlsrv_stmt::sql_type_to_php_type( SQLINTEGER sql_type, SQLUI } else { sqlsrv_phptype.typeinfo.type = SQLSRV_PHPTYPE_STRING; - sqlsrv_phptype.typeinfo.encoding = local_encoding; } break; case SQL_BIGINT: @@ -1345,7 +1343,6 @@ sqlsrv_phptype pdo_sqlsrv_stmt::sql_type_to_php_type( SQLINTEGER sql_type, SQLUI case SQL_WLONGVARCHAR: case SQL_SS_XML: sqlsrv_phptype.typeinfo.type = SQLSRV_PHPTYPE_STRING; - sqlsrv_phptype.typeinfo.encoding = local_encoding; break; case SQL_BINARY: case SQL_LONGVARBINARY: diff --git a/test/pdo_sqlsrv/pdo_270_fetch_binary.phpt b/test/pdo_sqlsrv/pdo_270_fetch_binary.phpt new file mode 100644 index 000000000..5edebcce3 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_270_fetch_binary.phpt @@ -0,0 +1,92 @@ +--TEST-- +Test fetch from binary, varbinary, varbinary(max), image columns, without setting binary encoding. +--DESCRIPTION-- +Verifies GitHub issue 270 is fixed, users could not retrieve the data as inserted in binary columns without setting the binary encoding either on stmt or using bindCoulmn encoding. +This test verifies that the data inserted in binary columns can be retrieved using fetch, fetchColumn, fetchObject, and fetchAll functions. + +--FILE-- +exec($sql); + +$icon = base64_decode("This is some text to test retrieving from binary type columns"); + +// Insert data using bind parameters +$sql = "INSERT INTO $tableName($columns[0], $columns[1], $columns[2], $columns[3]) VALUES(?, ?, ?, ?)"; +$stmt = $conn->prepare($sql); +$stmt->bindParam(1, $icon, PDO::PARAM_LOB, null, PDO::SQLSRV_ENCODING_BINARY); +$stmt->bindParam(2, $icon, PDO::PARAM_LOB, null, PDO::SQLSRV_ENCODING_BINARY); +$stmt->bindParam(3, $icon, PDO::PARAM_LOB, null, PDO::SQLSRV_ENCODING_BINARY); +$stmt->bindParam(4, $icon, PDO::PARAM_LOB, null, PDO::SQLSRV_ENCODING_BINARY); +$stmt->execute(); + +// loop through each column in the table +foreach ($columns as $col){ + test_fetch($conn, $tableName, $col, $icon); +} +// DROP table +$conn->query("DROP TABLE $tableName") ?: die(); + +//free statement and connection +$stmt = null; +$conn = null; + +print_r("Test finished successfully"); + +//calls various fetch methods +function test_fetch($conn, $tableName, $columnName, $input){ + + $len = strlen($input); + $result = ""; + $sql = "SELECT $columnName from $tableName"; + + $stmt = $conn->query($sql); + $stmt->bindColumn(1, $result, PDO::PARAM_LOB); + $stmt->fetch(PDO::FETCH_BOUND); + //binary is fixed size, to evaluate output, compare it using strncmp + if( strncmp($result, $input, $len) !== 0){ + print_r("\nRetrieving using bindColumn failed"); + } + + $result = ""; + $stmt = $conn->query($sql); + $stmt->bindColumn(1, $result, PDO::PARAM_LOB, 0 , PDO::SQLSRV_ENCODING_BINARY); + $stmt->fetch(PDO::FETCH_BOUND); + if( strncmp($result, $input, $len) !== 0){ + print_r("\nRetrieving using bindColumn with encoding set failed"); + } + + $result = ""; + $stmt = $conn->query($sql); + $result = $stmt->fetchColumn(); + if( strncmp($result, $input, $len) !== 0){ + print_r("\nRetrieving using fetchColumn failed"); + } + + $result = ""; + $stmt = $conn->query($sql); + $result = $stmt->fetchObject(); + if( strncmp($result->$columnName, $input, $len) !== 0){ + print_r("\nRetrieving using fetchObject failed"); + } + + $result = ""; + $stmt = $conn->query($sql); + $result = $stmt->fetchAll( PDO::FETCH_COLUMN ); + if( strncmp($result[0], $input, $len) !== 0){ + print_r("\nRetrieving using fetchAll failed"); + } +} + +?> +--EXPECT-- +Test finished successfully