Skip to content

Commit

Permalink
Include sql_variant type for buffered queries
Browse files Browse the repository at this point in the history
  • Loading branch information
yitam committed Jan 20, 2020
1 parent 9c9c04a commit 6ce9901
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 20 deletions.
2 changes: 2 additions & 0 deletions source/shared/core_results.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( _Inout_ sqlsrv_stmt* stm
break;
case SQL_CHAR:
case SQL_VARCHAR:
case SQL_SS_VARIANT:
if ( meta[i].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) {
offset += sizeof( void* );
}
Expand Down Expand Up @@ -610,6 +611,7 @@ sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( _Inout_ sqlsrv_stmt* stm

case SQL_CHAR:
case SQL_VARCHAR:
case SQL_SS_VARIANT:
case SQL_LONGVARCHAR:
// If encoding is set to UTF-8, the following types are not necessarily column size.
// We need to call SQLGetData with c_type SQL_C_WCHAR and set the size accordingly.
Expand Down
18 changes: 10 additions & 8 deletions test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1707,19 +1707,21 @@ function CallProcEx($conn, $procName, $procPrefix, $procArgs, $procValues)
function CreateFunc($conn, $funcName, $funcArgs, $retType, $funcCode)
{
DropFunc($conn, $funcName);
$stmt = sqlsrv_query($conn, "CREATE FUNCTION [$funcName] ($funcArgs) RETURNS $retType AS BEGIN $funcCode END");
if ($stmt === false) {
FatalError("Failed to create test function");
try {
$stmt = $conn->query("CREATE FUNCTION [$funcName] ($funcArgs) RETURNS $retType AS BEGIN $funcCode END");
} catch (PDOException $e) {
echo "Failed to create test function\n";
var_dump($e);
}
sqlsrv_free_stmt($stmt);
unset($stmt);
}

function DropFunc($conn, $funcName)
{
$stmt = sqlsrv_query($conn, "DROP FUNCTION [$funcName]");
if ($stmt === false) {
} else {
sqlsrv_free_stmt($stmt);
try {
$conn->query("DROP FUNCTION [$funcName]");
} catch (PDOException $e) {
; // do nothing
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
--TEST--
GitHub issue 1079 - fetching sql_variant types using client buffers
--DESCRIPTION--
This test verifies that fetching sql_variant types using client buffers is supported.
--ENV--
PHPT_EXEC=true
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsSetup.inc");
require_once("MsCommon_mid-refactor.inc");

try {
$conn = connect();

$funcName = 'PDO1079';
dropFunc($conn, $funcName);

$tsql = "CREATE FUNCTION [$funcName](@OP1 sql_variant, @OP2 sql_variant) RETURNS sql_variant AS
BEGIN DECLARE @Result sql_variant SET @Result = CASE WHEN @OP1 >= @OP2 THEN @OP1 ELSE @OP2 END RETURN @Result END";

$conn->exec($tsql);

$tsql = "SELECT [dbo].[$funcName](5, 6) AS RESULT";
$stmt = $conn->prepare($tsql, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED));
$stmt->execute();

$metadata = $stmt->getColumnMeta(0);
var_dump($metadata);

dropFunc($conn, $funcName);

unset($stmt);
unset($conn);
} catch (PdoException $e) {
echo $e->getMessage() . PHP_EOL;
}

?>
--EXPECT--
array(8) {
["flags"]=>
int(0)
["sqlsrv:decl_type"]=>
string(11) "sql_variant"
["native_type"]=>
string(6) "string"
["table"]=>
string(0) ""
["pdo_type"]=>
int(2)
["name"]=>
string(6) "RESULT"
["len"]=>
int(10)
["precision"]=>
int(0)
}
13 changes: 11 additions & 2 deletions test/functional/pdo_sqlsrv/pdo_fetch_variants_diff_styles.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,15 @@ function doValuesMatched($value1, $value2, $row, $col)
}
}

function fetchColumns($conn, $tableName, $numRows, $numCols)
function fetchColumns($conn, $tableName, $numRows, $numCols, $buffered = false)
{
try {
// insert column data from a row of the original table
$stmtOriginal = $conn->prepare("SELECT * FROM $tableName WHERE c1_int = :row");
if ($buffered) {
$stmtOriginal = $conn->prepare("SELECT * FROM $tableName WHERE c1_int = :row", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED));
} else {
$stmtOriginal = $conn->prepare("SELECT * FROM $tableName WHERE c1_int = :row");
}

for ($i = 1; $i <= $numRows; $i++) {
$c1_int = $i;
Expand Down Expand Up @@ -263,6 +267,7 @@ try {

$numCols = fetchBoundMixed($conn, $tableName, $numRows);
fetchColumns($conn, $tableName, $numRows, $numCols);
fetchColumns($conn, $tableName, $numRows, $numCols, true);

dropTable($conn, $tableName);
unset($conn);
Expand All @@ -278,3 +283,7 @@ Insert all columns from row 1 into one column of type sql_variant
string(11) "sql_variant"
Insert all columns from row 2 into one column of type sql_variant
string(11) "sql_variant"
Insert all columns from row 1 into one column of type sql_variant
string(11) "sql_variant"
Insert all columns from row 2 into one column of type sql_variant
string(11) "sql_variant"
13 changes: 9 additions & 4 deletions test/functional/pdo_sqlsrv/pdo_simple_update_variants.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,15 @@ function updateFood($conn, $tableName, $id, $food, $category)
}
}

function fetchRows($conn, $tableName)
function fetchRows($conn, $tableName, $buffered = false)
{
$query = "SELECT * FROM $tableName ORDER BY id";
$stmt = $conn->query($query);
if ($buffered) {
$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED));
$stmt->execute();
} else {
$stmt = $conn->query($query);
}

$stmt->setFetchMode(PDO::FETCH_CLASS, 'Food');
while ($food = $stmt->fetch()) {
Expand Down Expand Up @@ -108,7 +113,7 @@ try {

updateID($conn, $tableName, 4, 'Milk', 'Diary Products');

fetchRows($conn, $tableName);
fetchRows($conn, $tableName, true);

updateFood($conn, $tableName, 4, 'Cheese', 'Diary Products');

Expand All @@ -118,7 +123,7 @@ try {
insertData($conn, $tableName, 6, 'Salmon', 'Fish');
insertData($conn, $tableName, 2, 'Broccoli', 'Vegetables');

fetchRows($conn, $tableName);
fetchRows($conn, $tableName, true);

dropTable($conn, $tableName);
unset($conn);
Expand Down
3 changes: 2 additions & 1 deletion test/functional/sqlsrv/sqlsrv_param_input_variants.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ function insertData($conn, $tableName, $index)
function fetchData($conn, $tableName, $numRows)
{
$select = "SELECT * FROM $tableName ORDER BY c1_int";
$stmt = sqlsrv_query($conn, $select);

$stmt = sqlsrv_query($conn, $select, array(), array("Scrollable"=>"buffered"));
$stmt2 = sqlsrv_query($conn, $select);

$metadata = sqlsrv_field_metadata($stmt);
Expand Down
2 changes: 1 addition & 1 deletion test/functional/sqlsrv/sqlsrv_simple_fetch_variants.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function Fetch($conn, $tableName, $numRows)
{
$select = "SELECT * FROM $tableName ORDER BY c1_int";
$stmt = sqlsrv_query($conn, $select);
$stmt2 = sqlsrv_query($conn, $select);
$stmt2 = sqlsrv_query($conn, $select, array(), array("Scrollable"=>"buffered"));
$stmt3 = sqlsrv_query($conn, $select);

$metadata = sqlsrv_field_metadata($stmt);
Expand Down
13 changes: 9 additions & 4 deletions test/functional/sqlsrv/sqlsrv_simple_update_variants.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,15 @@ function updateCountry($conn, $tableName, $id, $country, $continent)
}
}

function fetch($conn, $tableName)
function fetch($conn, $tableName, $buffered = false)
{
$select = "SELECT * FROM $tableName ORDER BY id";
$stmt = sqlsrv_query($conn, $select);

if ($buffered) {
$stmt = sqlsrv_query($conn, $select, array(), array("Scrollable"=>"buffered"));
} else {
$stmt = sqlsrv_query($conn, $select);
}

while ($country = sqlsrv_fetch_object($stmt, "Country")) {
echo "\nID: " . $country->id . " ";
Expand Down Expand Up @@ -125,13 +130,13 @@ try {
updateID($conn, $tableName, 4, 'Canada', 'North America');

// Read data
fetch($conn, $tableName);
fetch($conn, $tableName, true);

// Update country
updateCountry($conn, $tableName, 4, 'Mexico', 'North America');

// Read data
fetch($conn, $tableName);
fetch($conn, $tableName, true);

// Add two more countries
addCountry($conn, $tableName, 6, 'Brazil', 'South America');
Expand Down
62 changes: 62 additions & 0 deletions test/functional/sqlsrv/srv_1079_sql_variant_buffered_queries.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
--TEST--
GitHub issue 1079 - fetching sql_variant types using client buffers
--DESCRIPTION--
This test verifies that fetching sql_variant types using client buffers is supported.
--ENV--
PHPT_EXEC=true
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
--FILE--
<?php
require_once('MsCommon.inc');

$conn = AE\connect();

$funcName = 'SRV1079';
dropFunc($conn, $funcName);

$tsql = "CREATE FUNCTION [$funcName](@OP1 sql_variant, @OP2 sql_variant) RETURNS sql_variant AS
BEGIN DECLARE @Result sql_variant SET @Result = CASE WHEN @OP1 >= @OP2 THEN @OP1 ELSE @OP2 END RETURN @Result END";

$stmt = sqlsrv_query($conn, $tsql);
if (!$stmt) {
fatalError('Could not create function\n');
}

$tsql = "SELECT [dbo].[$funcName](5, 6) AS RESULT";
$stmt = sqlsrv_prepare($conn, $tsql, array(), array("Scrollable" => SQLSRV_CURSOR_CLIENT_BUFFERED, "ClientBufferMaxKBSize" => 1000));

if (!$stmt) {
fatalError('Could not prepare query\n');
}

$result = sqlsrv_execute($stmt);
if (!$result) {
fatalError('Executing the query failed\n');
}

foreach (sqlsrv_field_metadata($stmt) as $fieldMetadata) {
var_dump($fieldMetadata);
}

dropFunc($conn, $funcName);

sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);

?>
--EXPECT--
array(6) {
["Name"]=>
string(6) "RESULT"
["Type"]=>
int(-150)
["Size"]=>
int(10)
["Precision"]=>
NULL
["Scale"]=>
NULL
["Nullable"]=>
int(1)
}

0 comments on commit 6ce9901

Please sign in to comment.