Skip to content

Commit

Permalink
Merge 3984d47 into e2c1597
Browse files Browse the repository at this point in the history
  • Loading branch information
absci authored Sep 7, 2022
2 parents e2c1597 + 3984d47 commit 6828586
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 14 deletions.
1 change: 1 addition & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ variables:

trigger:
- dev
- fix/*

pr:
- dev
Expand Down
28 changes: 14 additions & 14 deletions source/shared/core_stmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,10 +414,22 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_
}

// If Always Encrypted is enabled, transfer the known param meta data if applicable, which might alter param_z for decimal types
if (stmt->conn->ce_option.enabled) {
if (param_ptr->sql_data_type == SQL_UNKNOWN_TYPE || param_ptr->column_size == SQLSRV_UNKNOWN_SIZE) {
if (stmt->conn->ce_option.enabled
&& (param_ptr->sql_data_type == SQL_UNKNOWN_TYPE || param_ptr->column_size == SQLSRV_UNKNOWN_SIZE)) {
// meta data parameters are always sorted based on parameter number
param_ptr->copy_param_meta_ae(param_z, stmt->params_container.params_meta_ae[param_num]);
}
else {
if (Z_TYPE_P(param_z) == IS_STRING && column_size == SQLSRV_UNKNOWN_SIZE) {
size_t char_size = (encoding == SQLSRV_ENCODING_UTF8) ? sizeof(SQLWCHAR) : sizeof(char);
SQLULEN byte_len = Z_STRLEN_P(param_z) * char_size;

if (byte_len > SQL_SERVER_MAX_FIELD_SIZE) {
param_ptr->column_size = SQL_SERVER_MAX_TYPE_SIZE;
}
else {
param_ptr->column_size = SQL_SERVER_MAX_FIELD_SIZE / char_size;
}
}
}

Expand Down Expand Up @@ -2272,18 +2284,6 @@ bool sqlsrv_param::derive_string_types_sizes(_In_ zval* param_z)
break;
}

// Derive the column size also only if it is unknown
if (column_size == SQLSRV_UNKNOWN_SIZE) {
size_t char_size = (encoding == SQLSRV_ENCODING_UTF8) ? sizeof(SQLWCHAR) : sizeof(char);
SQLULEN byte_len = Z_STRLEN_P(param_z) * char_size;

if (byte_len > SQL_SERVER_MAX_FIELD_SIZE) {
column_size = SQL_SERVER_MAX_TYPE_SIZE;
} else {
column_size = SQL_SERVER_MAX_FIELD_SIZE / char_size;
}
}

return is_numeric;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
--TEST--
GitHub issue 1391 - string truncation error when binding some parameters as longer strings the second time
--DESCRIPTION--
The test shows the same parameters, though bound as short strings in the first insertion, can be bound as longer strings in the subsequent insertions.
--ENV--
PHPT_EXEC=true
--SKIPIF--
<?php require('skipif.inc'); ?>
--FILE--
<?php

require_once("MsSetup.inc");

function dropTable($conn, $tableName)
{
$drop = "IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'" . $tableName . "') AND type in (N'U')) DROP TABLE $tableName";
$conn->exec($drop);
}

try {
$conn = new PDO("sqlsrv:server=$server; Database = $databaseName;", $uid, $pwd);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

dropTable($conn, 'long_strings');

$tsql = <<<CREATESQL
CREATE TABLE long_strings (
id bigint IDENTITY(1,1) NOT NULL,
four_thousand varchar(4002) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
var_max varchar(max) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
nvar_max varchar(max) NOT NULL,
CONSTRAINT PK__long_strings__1391E83F512B1391 PRIMARY KEY (id))
CREATESQL;

$conn->exec($tsql);

$tsql = <<<INSERTSQL
INSERT INTO long_strings (four_thousand, var_max, nvar_max) VALUES (?, ?, ?)
INSERTSQL;

$stmt = $conn->prepare($tsql);

// Bind and execute short string values first
$fourThousand = '4';
$varMax = 'v';
$nvarMax = 'n';
$stmt->bindParam(1, $fourThousand);
$stmt->bindParam(2, $varMax);
$stmt->bindParam(3, $nvarMax);
$stmt->execute();

// Bind and execute long string values second, on same $stmt
$fourThousand = str_repeat('4', 4001);
$varMax = str_repeat('v', 4001);
$nvarMax = str_repeat('n', 4001);
$stmt->bindParam(1, $fourThousand);
$stmt->bindParam(2, $varMax);
$stmt->bindParam(3, $nvarMax);
$stmt->execute();

// fetch the data
$stmt = $conn->prepare("SELECT COUNT(*) FROM long_strings");
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_NUM);
echo $row[0]."\n";

dropTable($conn, 'long_strings');

echo "Done\n";
} catch (PdoException $e) {
echo $e->getMessage();
}

?>
--EXPECT--
2
Done

0 comments on commit 6828586

Please sign in to comment.