From a0e886273f50a50a73599b79086e13922a4ff047 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Wed, 11 Oct 2017 18:03:14 -0700 Subject: [PATCH 01/27] convert long output param to string, then convert back to long if less than max int --- source/shared/core_sqlsrv.h | 8 +- source/shared/core_stmt.cpp | 27 +++++- .../pdo_sqlsrv/pdo_bigint_outparam.phpt | 82 +++++++++++++++++++ .../pdo_sqlsrv/pdo_bool_outparam.phpt | 82 +++++++++++++++++++ .../sqlsrv/sqlsrv_bigint_outparam.phpt | 79 ++++++++++++++++++ .../sqlsrv/sqlsrv_bool_outparam.phpt | 79 ++++++++++++++++++ 6 files changed, 351 insertions(+), 6 deletions(-) create mode 100644 test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt create mode 100644 test/functional/pdo_sqlsrv/pdo_bool_outparam.phpt create mode 100644 test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt create mode 100644 test/functional/sqlsrv/sqlsrv_bool_outparam.phpt diff --git a/source/shared/core_sqlsrv.h b/source/shared/core_sqlsrv.h index 0c909b44..5e50564d 100644 --- a/source/shared/core_sqlsrv.h +++ b/source/shared/core_sqlsrv.h @@ -1322,10 +1322,11 @@ struct sqlsrv_output_param { SQLUSMALLINT param_num; // used to index into the ind_or_len of the statement SQLLEN original_buffer_len; // used to make sure the returned length didn't overflow the buffer bool is_bool; + bool is_long; // string output param constructor - sqlsrv_output_param( _In_ zval* p_z, _In_ SQLSRV_ENCODING enc, _In_ int num, _In_ SQLUINTEGER buffer_len ) : - param_z( p_z ), encoding( enc ), param_num( num ), original_buffer_len( buffer_len ), is_bool( false ) + sqlsrv_output_param( _In_ zval* p_z, _In_ SQLSRV_ENCODING enc, _In_ int num, _In_ SQLUINTEGER buffer_len, _In_ bool is_long ) : + param_z( p_z ), encoding( enc ), param_num( num ), original_buffer_len( buffer_len ), is_bool( false ), is_long( is_long ) { } @@ -1335,7 +1336,8 @@ struct sqlsrv_output_param { encoding( SQLSRV_ENCODING_INVALID ), param_num( num ), original_buffer_len( -1 ), - is_bool( is_bool ) + is_bool( is_bool ), + is_long( false ) { } }; diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index 29255029..84f36b4e 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -373,6 +373,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ } bool zval_was_null = ( Z_TYPE_P( param_z ) == IS_NULL ); bool zval_was_bool = ( Z_TYPE_P( param_z ) == IS_TRUE || Z_TYPE_P( param_z ) == IS_FALSE ); + bool zval_was_long = ( Z_TYPE_P( param_z ) == IS_LONG && php_out_type == SQLSRV_PHPTYPE_INT ); // if the user asks for for a specific type for input and output, make sure the data type we send matches the data we // type we expect back, since we can only send and receive the same type. Anything can be converted to a string, so // we always let that match if they want a string back. @@ -383,7 +384,13 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ if( zval_was_null || zval_was_bool ) { convert_to_long( param_z ); } - match = Z_TYPE_P( param_z ) == IS_LONG; + if( zval_was_long ){ + convert_to_string( param_z ); + match = Z_TYPE_P( param_z ) == IS_STRING; + } + else { + match = Z_TYPE_P(param_z) == IS_LONG; + } break; case SQLSRV_PHPTYPE_FLOAT: if( zval_was_null ) { @@ -415,7 +422,12 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ if( direction == SQL_PARAM_OUTPUT ) { switch( php_out_type ) { case SQLSRV_PHPTYPE_INT: - convert_to_long( param_z ); + if( zval_was_long ){ + convert_to_string( param_z ); + } + else { + convert_to_long( param_z ); + } break; case SQLSRV_PHPTYPE_FLOAT: convert_to_double( param_z ); @@ -551,7 +563,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ buffer, buffer_len TSRMLS_CC ); // save the parameter to be adjusted and/or converted after the results are processed - sqlsrv_output_param output_param( param_ref, encoding, param_num, static_cast( buffer_len )); + sqlsrv_output_param output_param( param_ref, encoding, param_num, static_cast( buffer_len ), zval_was_long ); save_output_param_for_later( stmt, output_param TSRMLS_CC ); @@ -2127,6 +2139,15 @@ void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) else { core::sqlsrv_zval_stringl(value_z, str, str_len); } + if ( output_param->is_long ) { + zval* value_z_temp = ( zval * )sqlsrv_malloc( sizeof( zval )); + ZVAL_COPY( value_z_temp, value_z ); + convert_to_double( value_z_temp ); + if ( Z_DVAL_P( value_z_temp ) > INT_MIN && Z_DVAL_P( value_z_temp ) < INT_MAX ) { + convert_to_long( value_z ); + } + sqlsrv_free( value_z_temp ); + } } break; case IS_LONG: diff --git a/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt b/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt new file mode 100644 index 00000000..5b47022f --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt @@ -0,0 +1,82 @@ +--TEST-- +Test for binding bigint output and inout parameters +--SKIPIF-- + +--FILE-- + "bigint")); + +// Create a Store Procedure +$spname = "selectBigint"; +$spSql = "CREATE PROCEDURE $spname (@c1_bigint bigint OUTPUT) AS + SELECT @c1_bigint = c1_bigint FROM $tbname"; +$conn->query($spSql); + +// Insert a large bigint +insertRow($conn, $tbname, array("c1_bigint" => 922337203685479936)); + +// Call store procedure with output +$outSql = "{CALL $spname (?)}"; +$bigintOut = 0; +$stmt = $conn->prepare($outSql); +$stmt->bindParam(1, $bigintOut, PDO::PARAM_INT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE); +$stmt->execute(); +printf("Large bigint output:\n" ); +var_dump($bigintOut); +printf("\n"); + +// Call store procedure with inout +$bigintOut = 0; +$stmt = $conn->prepare($outSql); +$stmt->bindParam(1, $bigintOut, PDO::PARAM_INT | PDO::PARAM_INPUT_OUTPUT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE); +$stmt->execute(); +printf("Large bigint inout:\n" ); +var_dump($bigintOut); +printf("\n"); + +$conn->exec("TRUNCATE TABLE $tbname"); + +// Insert a small bigint +insertRow($conn, $tbname, array("c1_bigint" => 922337203)); + +// Call store procedure with output +$bigintOut = 0; +$stmt = $conn->prepare($outSql); +$stmt->bindParam(1, $bigintOut, PDO::PARAM_INT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE); +$stmt->execute(); +printf("Small bigint output:\n" ); +var_dump($bigintOut); +printf("\n"); + +// Call store procedure with inout +$bigintOut = 0; +$stmt = $conn->prepare($outSql); +$stmt->bindParam(1, $bigintOut, PDO::PARAM_INT | PDO::PARAM_INPUT_OUTPUT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE); +$stmt->execute(); +printf("Small bigint inout:\n" ); +var_dump($bigintOut); +printf("\n"); + +dropProc($conn, $spname); +dropTable($conn, $tbname); +unset($stmt); +unset($conn); +?> +--EXPECT-- +Large bigint output: +string(18) "922337203685479936" + +Large bigint inout: +string(18) "922337203685479936" + +Small bigint output: +int(922337203) + +Small bigint inout: +int(922337203) diff --git a/test/functional/pdo_sqlsrv/pdo_bool_outparam.phpt b/test/functional/pdo_sqlsrv/pdo_bool_outparam.phpt new file mode 100644 index 00000000..b2eb8781 --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_bool_outparam.phpt @@ -0,0 +1,82 @@ +--TEST-- +Test for binding boolean output and inout parameters +--SKIPIF-- + +--FILE-- + "int")); + +// Create a Store Procedure +$spname = "selectBool"; +$spSql = "CREATE PROCEDURE $spname (@c1_bool int OUTPUT) AS + SELECT @c1_bool = c1_bool FROM $tbname"; +$conn->query($spSql); + +// Insert 1 +insertRow($conn, $tbname, array("c1_bool" => 1)); + +// Call store procedure with output +$outSql = "{CALL $spname (?)}"; +$boolOut = false; +$stmt = $conn->prepare($outSql); +$stmt->bindParam(1, $boolOut, PDO::PARAM_INT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE); +$stmt->execute(); +printf("True bool output:\n" ); +var_dump($boolOut); +printf("\n"); + +// Call store procedure with inout +$boolOut = false; +$stmt = $conn->prepare($outSql); +$stmt->bindParam(1, $boolOut, PDO::PARAM_INT | PDO::PARAM_INPUT_OUTPUT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE); +$stmt->execute(); +printf("True bool inout:\n" ); +var_dump($boolOut); +printf("\n"); + +$conn->exec("TRUNCATE TABLE $tbname"); + +// Insert 0 +insertRow($conn, $tbname, array("c1_bool" => 0)); + +// Call store procedure with output +$boolOut = true; +$stmt = $conn->prepare($outSql); +$stmt->bindParam(1, $boolOut, PDO::PARAM_INT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE); +$stmt->execute(); +printf("True bool output:\n" ); +var_dump($boolOut); +printf("\n"); + +// Call store procedure with inout +$boolOut = true; +$stmt = $conn->prepare($outSql); +$stmt->bindParam(1, $boolOut, PDO::PARAM_INT | PDO::PARAM_INPUT_OUTPUT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE); +$stmt->execute(); +printf("True bool inout:\n" ); +var_dump($boolOut); +printf("\n"); + +dropProc($conn, $spname); +dropTable($conn, $tbname); +unset($stmt); +unset($conn); +?> +--EXPECT-- +True bool output: +int(1) + +True bool inout: +int(1) + +True bool output: +int(0) + +True bool inout: +int(0) diff --git a/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt b/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt new file mode 100644 index 00000000..e0073a1f --- /dev/null +++ b/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt @@ -0,0 +1,79 @@ +--TEST-- +Test for binding bigint output and inout parameters +--SKIPIF-- + +--FILE-- + 922337203685479936)); + +// Call store procedure with SQLSRV_PARAM_OUT +$outSql = "{CALL $spname (?)}"; +$bigintOut = 0; +$stmt = sqlsrv_prepare($conn, $outSql, array(array(&$bigintOut, SQLSRV_PARAM_OUT))); +sqlsrv_execute($stmt); +printf("Large bigint output:\n"); +var_dump($bigintOut); +printf("\n"); + +// Call store procedure with SQLSRV_PARAM_INOUT +$bigintOut = 0; +$stmt = sqlsrv_prepare($conn, $outSql, array(array(&$bigintOut, SQLSRV_PARAM_INOUT))); +sqlsrv_execute($stmt); +printf("Large bigint inout:\n"); +var_dump($bigintOut); +printf("\n"); +sqlsrv_query($conn, "TRUNCATE TABLE $tbname"); + +// Insert a small bigint +AE\insertRow($conn, $tbname, array("c1_bigint" => 922337203)); + +// Call store procedure with SQLSRV_PARAM_OUT +$bigintOut = 0; +$stmt = sqlsrv_prepare($conn, $outSql, array(array(&$bigintOut, SQLSRV_PARAM_OUT))); +sqlsrv_execute($stmt); +printf("Small bigint output:\n"); +var_dump($bigintOut); +printf("\n"); + +// Call store procedure with SQLSRV_PARAM_INOUT +$bigintOut = 0; +$stmt = sqlsrv_prepare($conn, $outSql, array(array(&$bigintOut, SQLSRV_PARAM_INOUT))); +sqlsrv_execute($stmt); +printf("Small bigint inout:\n"); +var_dump($bigintOut); +printf("\n"); + +dropProc($conn, $spname); +dropTable($conn, $tbname); +sqlsrv_free_stmt($stmt); +sqlsrv_close($conn); + +?> +--EXPECT-- +Large bigint output: +string(18) "922337203685479936" + +Large bigint inout: +string(18) "922337203685479936" + +Small bigint output: +int(922337203) + +Small bigint inout: +int(922337203) diff --git a/test/functional/sqlsrv/sqlsrv_bool_outparam.phpt b/test/functional/sqlsrv/sqlsrv_bool_outparam.phpt new file mode 100644 index 00000000..99668467 --- /dev/null +++ b/test/functional/sqlsrv/sqlsrv_bool_outparam.phpt @@ -0,0 +1,79 @@ +--TEST-- +Test for binding boolean output and inout parameters +--SKIPIF-- + +--FILE-- + 1)); + +// Call store procedure with SQLSRV_PARAM_OUT +$outSql = "{CALL $spname (?)}"; +$boolOut = false; +$stmt = sqlsrv_prepare($conn, $outSql, array(array(&$boolOut, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_INT))); +sqlsrv_execute($stmt); +printf("True bool output:\n"); +var_dump($boolOut); +printf("\n"); + +// Call store procedure with SQLSRV_PARAM_INOUT +$boolOut = false; +$stmt = sqlsrv_prepare($conn, $outSql, array(array(&$boolOut, SQLSRV_PARAM_INOUT, SQLSRV_PHPTYPE_INT))); +sqlsrv_execute($stmt); +printf("True bool inout:\n"); +var_dump($boolOut); +printf("\n"); +sqlsrv_query($conn, "TRUNCATE TABLE $tbname"); + +// Insert 0 +AE\insertRow($conn, $tbname, array("c1_bool" => 0)); + +// Call store procedure with SQLSRV_PARAM_OUT +$boolOut = true; +$stmt = sqlsrv_prepare($conn, $outSql, array(array(&$boolOut, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_INT))); +sqlsrv_execute($stmt); +printf("False bool output:\n"); +var_dump($boolOut); +printf("\n"); + +// Call store procedure with SQLSRV_PARAM_INOUT +$boolOut = true; +$stmt = sqlsrv_prepare($conn, $outSql, array(array(&$boolOut, SQLSRV_PARAM_INOUT, SQLSRV_PHPTYPE_INT))); +sqlsrv_execute($stmt); +printf("False bool inout:\n"); +var_dump($boolOut); +printf("\n"); + +dropProc($conn, $spname); +dropTable($conn, $tbname); +sqlsrv_free_stmt($stmt); +sqlsrv_close($conn); + +?> +--EXPECT-- +True bool output: +bool(true) + +True bool inout: +bool(true) + +False bool output: +bool(false) + +False bool inout: +bool(false) From c30f2d6100f278d354c0fcf5cbdf18bf8f35f864 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Thu, 12 Oct 2017 11:33:45 -0700 Subject: [PATCH 02/27] change encoding to SYSTEM when converting int to string for inout and output param --- source/shared/core_sqlsrv.h | 2 +- source/shared/core_stmt.cpp | 6 ++++-- test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt | 12 ++++++------ test/functional/pdo_sqlsrv/pdo_bool_outparam.phpt | 8 ++++---- test/functional/sqlsrv/MsHelper.inc | 1 + test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt | 12 ++++++------ test/functional/sqlsrv/sqlsrv_bool_outparam.phpt | 8 ++++---- 7 files changed, 26 insertions(+), 23 deletions(-) diff --git a/source/shared/core_sqlsrv.h b/source/shared/core_sqlsrv.h index 5e50564d..16ca5711 100644 --- a/source/shared/core_sqlsrv.h +++ b/source/shared/core_sqlsrv.h @@ -1433,7 +1433,7 @@ typedef sqlsrv_stmt* (*driver_stmt_factory)( sqlsrv_conn* conn, SQLHANDLE h, err sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stmt_factory stmt_factory, _In_opt_ HashTable* options_ht, _In_opt_ const stmt_option valid_stmt_opts[], _In_ error_callback const err, _In_opt_ void* driver TSRMLS_DC ); void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_num, _In_ SQLSMALLINT direction, _Inout_ zval* param_z, - _In_ SQLSRV_PHPTYPE php_out_type, _In_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, + _In_ SQLSRV_PHPTYPE php_out_type, _Inout_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, _Inout_ SQLSMALLINT decimal_digits TSRMLS_DC ); SQLRETURN core_sqlsrv_execute( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_reads_bytes_(sql_len) const char* sql = NULL, _In_ int sql_len = 0 ); field_meta_data* core_sqlsrv_field_metadata( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno TSRMLS_DC ); diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index 84f36b4e..f0823aa8 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -342,7 +342,7 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stm // The sql type is given as a hint if the driver provides it. void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_num, _In_ SQLSMALLINT direction, _Inout_ zval* param_z, - _In_ SQLSRV_PHPTYPE php_out_type, _In_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, + _In_ SQLSRV_PHPTYPE php_out_type, _Inout_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, _Inout_ SQLSMALLINT decimal_digits TSRMLS_DC ) { SQLSMALLINT c_type; @@ -373,7 +373,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ } bool zval_was_null = ( Z_TYPE_P( param_z ) == IS_NULL ); bool zval_was_bool = ( Z_TYPE_P( param_z ) == IS_TRUE || Z_TYPE_P( param_z ) == IS_FALSE ); - bool zval_was_long = ( Z_TYPE_P( param_z ) == IS_LONG && php_out_type == SQLSRV_PHPTYPE_INT ); + bool zval_was_long = ( Z_TYPE_P( param_z ) == IS_LONG && php_out_type == SQLSRV_PHPTYPE_INT && (sql_type == SQL_BIGINT || sql_type == SQL_UNKNOWN_TYPE )); // if the user asks for for a specific type for input and output, make sure the data type we send matches the data we // type we expect back, since we can only send and receive the same type. Anything can be converted to a string, so // we always let that match if they want a string back. @@ -386,6 +386,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ } if( zval_was_long ){ convert_to_string( param_z ); + encoding = SQLSRV_ENCODING_SYSTEM; match = Z_TYPE_P( param_z ) == IS_STRING; } else { @@ -424,6 +425,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ case SQLSRV_PHPTYPE_INT: if( zval_was_long ){ convert_to_string( param_z ); + encoding = SQLSRV_ENCODING_SYSTEM; } else { convert_to_long( param_z ); diff --git a/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt b/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt index 5b47022f..740291f7 100644 --- a/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt +++ b/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt @@ -69,14 +69,14 @@ unset($stmt); unset($conn); ?> --EXPECT-- -Large bigint output: +Large bigint output: string(18) "922337203685479936" -Large bigint inout: +Large bigint inout: string(18) "922337203685479936" -Small bigint output: -int(922337203) - -Small bigint inout: +Small bigint output: +int(922337203) + +Small bigint inout: int(922337203) diff --git a/test/functional/pdo_sqlsrv/pdo_bool_outparam.phpt b/test/functional/pdo_sqlsrv/pdo_bool_outparam.phpt index b2eb8781..b1df6b9d 100644 --- a/test/functional/pdo_sqlsrv/pdo_bool_outparam.phpt +++ b/test/functional/pdo_sqlsrv/pdo_bool_outparam.phpt @@ -69,14 +69,14 @@ unset($stmt); unset($conn); ?> --EXPECT-- -True bool output: +True bool output: int(1) -True bool inout: +True bool inout: int(1) -True bool output: +True bool output: int(0) -True bool inout: +True bool inout: int(0) diff --git a/test/functional/sqlsrv/MsHelper.inc b/test/functional/sqlsrv/MsHelper.inc index c6fa7173..7cf5f3f8 100644 --- a/test/functional/sqlsrv/MsHelper.inc +++ b/test/functional/sqlsrv/MsHelper.inc @@ -328,6 +328,7 @@ function connect($options = array(), $disableCE = false) */ function createTable($conn, $tbname, $columnMetaArr) { + require_once("MsCommon.inc"); dropTable($conn, $tbname); $colDef = ""; foreach ($columnMetaArr as $meta) { diff --git a/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt b/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt index e0073a1f..fd2023a2 100644 --- a/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt +++ b/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt @@ -66,14 +66,14 @@ sqlsrv_close($conn); ?> --EXPECT-- -Large bigint output: +Large bigint output: string(18) "922337203685479936" -Large bigint inout: +Large bigint inout: string(18) "922337203685479936" -Small bigint output: -int(922337203) - -Small bigint inout: +Small bigint output: +int(922337203) + +Small bigint inout: int(922337203) diff --git a/test/functional/sqlsrv/sqlsrv_bool_outparam.phpt b/test/functional/sqlsrv/sqlsrv_bool_outparam.phpt index 99668467..a07aa91c 100644 --- a/test/functional/sqlsrv/sqlsrv_bool_outparam.phpt +++ b/test/functional/sqlsrv/sqlsrv_bool_outparam.phpt @@ -66,14 +66,14 @@ sqlsrv_close($conn); ?> --EXPECT-- -True bool output: +True bool output: bool(true) -True bool inout: +True bool inout: bool(true) -False bool output: +False bool output: bool(false) -False bool inout: +False bool inout: bool(false) From 628e04e402aeb389227a7f64ed7b270b1061912f Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Thu, 12 Oct 2017 12:20:30 -0700 Subject: [PATCH 03/27] fix spacing in expected output in pdo_bigint_outparam.phpt and sqlsrv_bigint_outparam.phpt --- test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt | 2 +- test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt b/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt index 740291f7..aef8f830 100644 --- a/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt +++ b/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt @@ -77,6 +77,6 @@ string(18) "922337203685479936" Small bigint output: int(922337203) - + Small bigint inout: int(922337203) diff --git a/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt b/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt index fd2023a2..b25ed185 100644 --- a/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt +++ b/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt @@ -74,6 +74,6 @@ string(18) "922337203685479936" Small bigint output: int(922337203) - + Small bigint inout: int(922337203) From b5a0d1f8598065b53fa8e153b4399b5ac1c21820 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Fri, 13 Oct 2017 15:50:50 -0700 Subject: [PATCH 04/27] cosmetic changes --- source/shared/core_stmt.cpp | 4 ++-- test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt | 10 +++++----- test/functional/pdo_sqlsrv/pdo_bool_outparam.phpt | 10 +++++----- test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt | 12 ++++++------ test/functional/sqlsrv/sqlsrv_bool_outparam.phpt | 10 +++++----- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index f0823aa8..dd2d22bf 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -386,7 +386,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ } if( zval_was_long ){ convert_to_string( param_z ); - encoding = SQLSRV_ENCODING_SYSTEM; + encoding = SQLSRV_ENCODING_SYSTEM; match = Z_TYPE_P( param_z ) == IS_STRING; } else { @@ -565,7 +565,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ buffer, buffer_len TSRMLS_CC ); // save the parameter to be adjusted and/or converted after the results are processed - sqlsrv_output_param output_param( param_ref, encoding, param_num, static_cast( buffer_len ), zval_was_long ); + sqlsrv_output_param output_param( param_ref, encoding, param_num, static_cast( buffer_len ), zval_was_long ); save_output_param_for_later( stmt, output_param TSRMLS_CC ); diff --git a/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt b/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt index aef8f830..0e232694 100644 --- a/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt +++ b/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt @@ -12,7 +12,7 @@ $conn = connect(); $tbname = "bigint_table"; createTable($conn, $tbname, array("c1_bigint" => "bigint")); -// Create a Store Procedure +// Create a Stored Procedure $spname = "selectBigint"; $spSql = "CREATE PROCEDURE $spname (@c1_bigint bigint OUTPUT) AS SELECT @c1_bigint = c1_bigint FROM $tbname"; @@ -21,7 +21,7 @@ $conn->query($spSql); // Insert a large bigint insertRow($conn, $tbname, array("c1_bigint" => 922337203685479936)); -// Call store procedure with output +// Call stored procedure with output $outSql = "{CALL $spname (?)}"; $bigintOut = 0; $stmt = $conn->prepare($outSql); @@ -31,7 +31,7 @@ printf("Large bigint output:\n" ); var_dump($bigintOut); printf("\n"); -// Call store procedure with inout +// Call stored procedure with inout $bigintOut = 0; $stmt = $conn->prepare($outSql); $stmt->bindParam(1, $bigintOut, PDO::PARAM_INT | PDO::PARAM_INPUT_OUTPUT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE); @@ -45,7 +45,7 @@ $conn->exec("TRUNCATE TABLE $tbname"); // Insert a small bigint insertRow($conn, $tbname, array("c1_bigint" => 922337203)); -// Call store procedure with output +// Call stored procedure with output $bigintOut = 0; $stmt = $conn->prepare($outSql); $stmt->bindParam(1, $bigintOut, PDO::PARAM_INT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE); @@ -54,7 +54,7 @@ printf("Small bigint output:\n" ); var_dump($bigintOut); printf("\n"); -// Call store procedure with inout +// Call stored procedure with inout $bigintOut = 0; $stmt = $conn->prepare($outSql); $stmt->bindParam(1, $bigintOut, PDO::PARAM_INT | PDO::PARAM_INPUT_OUTPUT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE); diff --git a/test/functional/pdo_sqlsrv/pdo_bool_outparam.phpt b/test/functional/pdo_sqlsrv/pdo_bool_outparam.phpt index b1df6b9d..2048e496 100644 --- a/test/functional/pdo_sqlsrv/pdo_bool_outparam.phpt +++ b/test/functional/pdo_sqlsrv/pdo_bool_outparam.phpt @@ -12,7 +12,7 @@ $conn = connect(); $tbname = "bool_table"; createTable($conn, $tbname, array("c1_bool" => "int")); -// Create a Store Procedure +// Create a Stored Procedure $spname = "selectBool"; $spSql = "CREATE PROCEDURE $spname (@c1_bool int OUTPUT) AS SELECT @c1_bool = c1_bool FROM $tbname"; @@ -21,7 +21,7 @@ $conn->query($spSql); // Insert 1 insertRow($conn, $tbname, array("c1_bool" => 1)); -// Call store procedure with output +// Call stored procedure with output $outSql = "{CALL $spname (?)}"; $boolOut = false; $stmt = $conn->prepare($outSql); @@ -31,7 +31,7 @@ printf("True bool output:\n" ); var_dump($boolOut); printf("\n"); -// Call store procedure with inout +// Call stored procedure with inout $boolOut = false; $stmt = $conn->prepare($outSql); $stmt->bindParam(1, $boolOut, PDO::PARAM_INT | PDO::PARAM_INPUT_OUTPUT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE); @@ -45,7 +45,7 @@ $conn->exec("TRUNCATE TABLE $tbname"); // Insert 0 insertRow($conn, $tbname, array("c1_bool" => 0)); -// Call store procedure with output +// Call stored procedure with output $boolOut = true; $stmt = $conn->prepare($outSql); $stmt->bindParam(1, $boolOut, PDO::PARAM_INT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE); @@ -54,7 +54,7 @@ printf("True bool output:\n" ); var_dump($boolOut); printf("\n"); -// Call store procedure with inout +// Call stored procedure with inout $boolOut = true; $stmt = $conn->prepare($outSql); $stmt->bindParam(1, $boolOut, PDO::PARAM_INT | PDO::PARAM_INPUT_OUTPUT, PDO::SQLSRV_PARAM_OUT_DEFAULT_SIZE); diff --git a/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt b/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt index b25ed185..a3aaf8a3 100644 --- a/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt +++ b/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt @@ -13,16 +13,16 @@ $tbname = "bigint_table"; AE\createTable($conn, $tbname, array(new AE\ColumnMeta("bigint", "c1_bigint"))); -// Create a Store Procedure with output +// Create a Stored Procedure with output $spname = "selectBigint"; $spSql = "CREATE PROCEDURE $spname (@c1_bigint bigint OUTPUT) AS SELECT @c1_bigint = c1_bigint FROM $tbname"; sqlsrv_query( $conn, $spSql ); // Insert a large bigint -AE\insertRow($conn, $tbname, array("c1_bigint" => 922337203685479936)); +AE\insertRow($conn, $tbname, array("c1_bigint" => 922,337,203,685,479,936)); -// Call store procedure with SQLSRV_PARAM_OUT +// Call stored procedure with SQLSRV_PARAM_OUT $outSql = "{CALL $spname (?)}"; $bigintOut = 0; $stmt = sqlsrv_prepare($conn, $outSql, array(array(&$bigintOut, SQLSRV_PARAM_OUT))); @@ -31,7 +31,7 @@ printf("Large bigint output:\n"); var_dump($bigintOut); printf("\n"); -// Call store procedure with SQLSRV_PARAM_INOUT +// Call stored procedure with SQLSRV_PARAM_INOUT $bigintOut = 0; $stmt = sqlsrv_prepare($conn, $outSql, array(array(&$bigintOut, SQLSRV_PARAM_INOUT))); sqlsrv_execute($stmt); @@ -43,7 +43,7 @@ sqlsrv_query($conn, "TRUNCATE TABLE $tbname"); // Insert a small bigint AE\insertRow($conn, $tbname, array("c1_bigint" => 922337203)); -// Call store procedure with SQLSRV_PARAM_OUT +// Call stored procedure with SQLSRV_PARAM_OUT $bigintOut = 0; $stmt = sqlsrv_prepare($conn, $outSql, array(array(&$bigintOut, SQLSRV_PARAM_OUT))); sqlsrv_execute($stmt); @@ -51,7 +51,7 @@ printf("Small bigint output:\n"); var_dump($bigintOut); printf("\n"); -// Call store procedure with SQLSRV_PARAM_INOUT +// Call stored procedure with SQLSRV_PARAM_INOUT $bigintOut = 0; $stmt = sqlsrv_prepare($conn, $outSql, array(array(&$bigintOut, SQLSRV_PARAM_INOUT))); sqlsrv_execute($stmt); diff --git a/test/functional/sqlsrv/sqlsrv_bool_outparam.phpt b/test/functional/sqlsrv/sqlsrv_bool_outparam.phpt index a07aa91c..45ba3fed 100644 --- a/test/functional/sqlsrv/sqlsrv_bool_outparam.phpt +++ b/test/functional/sqlsrv/sqlsrv_bool_outparam.phpt @@ -13,7 +13,7 @@ $tbname = "bool_table"; AE\createTable($conn, $tbname, array(new AE\ColumnMeta("int", "c1_bool"))); -// Create a Store Procedure with output +// Create a Stored Procedure with output $spname = "selectBool"; $spSql = "CREATE PROCEDURE $spname (@c1_bool int OUTPUT) AS SELECT @c1_bool = c1_bool FROM $tbname"; @@ -22,7 +22,7 @@ sqlsrv_query( $conn, $spSql ); // Insert 1 AE\insertRow($conn, $tbname, array("c1_bool" => 1)); -// Call store procedure with SQLSRV_PARAM_OUT +// Call stored procedure with SQLSRV_PARAM_OUT $outSql = "{CALL $spname (?)}"; $boolOut = false; $stmt = sqlsrv_prepare($conn, $outSql, array(array(&$boolOut, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_INT))); @@ -31,7 +31,7 @@ printf("True bool output:\n"); var_dump($boolOut); printf("\n"); -// Call store procedure with SQLSRV_PARAM_INOUT +// Call stored procedure with SQLSRV_PARAM_INOUT $boolOut = false; $stmt = sqlsrv_prepare($conn, $outSql, array(array(&$boolOut, SQLSRV_PARAM_INOUT, SQLSRV_PHPTYPE_INT))); sqlsrv_execute($stmt); @@ -43,7 +43,7 @@ sqlsrv_query($conn, "TRUNCATE TABLE $tbname"); // Insert 0 AE\insertRow($conn, $tbname, array("c1_bool" => 0)); -// Call store procedure with SQLSRV_PARAM_OUT +// Call stored procedure with SQLSRV_PARAM_OUT $boolOut = true; $stmt = sqlsrv_prepare($conn, $outSql, array(array(&$boolOut, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_INT))); sqlsrv_execute($stmt); @@ -51,7 +51,7 @@ printf("False bool output:\n"); var_dump($boolOut); printf("\n"); -// Call store procedure with SQLSRV_PARAM_INOUT +// Call stored procedure with SQLSRV_PARAM_INOUT $boolOut = true; $stmt = sqlsrv_prepare($conn, $outSql, array(array(&$boolOut, SQLSRV_PARAM_INOUT, SQLSRV_PHPTYPE_INT))); sqlsrv_execute($stmt); From 83ca7b498b2bbaccc93df040cab9708139173e70 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Fri, 13 Oct 2017 16:00:57 -0700 Subject: [PATCH 05/27] add comment do pdo_bigint_outparam.phpt and sqlsrv_bitint_outparam.phpt --- test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt | 2 +- test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt b/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt index 0e232694..15234ff5 100644 --- a/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt +++ b/test/functional/pdo_sqlsrv/pdo_bigint_outparam.phpt @@ -42,7 +42,7 @@ printf("\n"); $conn->exec("TRUNCATE TABLE $tbname"); -// Insert a small bigint +// Insert a random small value truncated from the bigint input insertRow($conn, $tbname, array("c1_bigint" => 922337203)); // Call stored procedure with output diff --git a/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt b/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt index a3aaf8a3..4056e868 100644 --- a/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt +++ b/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt @@ -40,7 +40,7 @@ var_dump($bigintOut); printf("\n"); sqlsrv_query($conn, "TRUNCATE TABLE $tbname"); -// Insert a small bigint +// Insert a random small value truncated from the bigint input AE\insertRow($conn, $tbname, array("c1_bigint" => 922337203)); // Call stored procedure with SQLSRV_PARAM_OUT From e190bca4ddecf0f70356d0097d02cfe5b7237cc6 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Mon, 16 Oct 2017 09:42:06 -0700 Subject: [PATCH 06/27] fix bigint input in sqlsrv_bigint_outparam.phpt --- test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt b/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt index 4056e868..f305ecee 100644 --- a/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt +++ b/test/functional/sqlsrv/sqlsrv_bigint_outparam.phpt @@ -20,7 +20,7 @@ $spSql = "CREATE PROCEDURE $spname (@c1_bigint bigint OUTPUT) AS sqlsrv_query( $conn, $spSql ); // Insert a large bigint -AE\insertRow($conn, $tbname, array("c1_bigint" => 922,337,203,685,479,936)); +AE\insertRow($conn, $tbname, array("c1_bigint" => 922337203685479936)); // Call stored procedure with SQLSRV_PARAM_OUT $outSql = "{CALL $spname (?)}"; From 9b12fe39fdaf7138db70e4273ea637c34943c608 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Tue, 17 Oct 2017 11:28:53 -0700 Subject: [PATCH 07/27] detect Appveyor problem --- appveyor.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index b4eb35d3..8ff16877 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,6 +18,15 @@ environment: PHP_DEPSVER: 7.0 PHP_SDK: c:\projects\php matrix: + - BUILD_PLATFORM: x64 + TEST_PHP_SQL_SERVER: (local)\SQL2016 + SQL_INSTANCE: SQL2016 + PHP_VC: 14 + PHP_MAJOR_VER: 7.1 + PHP_MINOR_VER: latest + PHP_SDK_DIR: c:\projects\php\x64 + PHP_INSTALL_DIR: c:\projects\php\x64\bin + platform: x64 - BUILD_PLATFORM: x64 TEST_PHP_SQL_SERVER: (local)\SQL2012SP1 SQL_INSTANCE: SQL2012SP1 @@ -37,15 +46,6 @@ environment: PHP_SDK_DIR: c:\projects\php\x86 PHP_INSTALL_DIR: c:\projects\php\x86\bin platform: x86 - - BUILD_PLATFORM: x64 - TEST_PHP_SQL_SERVER: (local)\SQL2016 - SQL_INSTANCE: SQL2016 - PHP_VC: 14 - PHP_MAJOR_VER: 7.1 - PHP_MINOR_VER: latest - PHP_SDK_DIR: c:\projects\php\x64 - PHP_INSTALL_DIR: c:\projects\php\x64\bin - platform: x64 - BUILD_PLATFORM: x86 TEST_PHP_SQL_SERVER: (local)\SQL2008R2SP2 SQL_INSTANCE: SQL2008R2SP2 @@ -191,7 +191,7 @@ test_script: - ps: foreach($file in $difffiles){ls $file; more $file} - ps: foreach($file in $outfiles){ls $file; more $file} - cd %PHP_INSTALL_DIR% - - OpenCppCoverage.exe --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\pdo_sqlsrv --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\sqlsrv --modules *sqlsrv*.dll --export_type=cobertura:.\coverage.xml --cover_children --quiet --optimized_build -- .\php.exe .\run-tests.php -P %APPVEYOR_BUILD_FOLDER%\test\functional\ + - OpenCppCoverage.exe --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\pdo_sqlsrv --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\sqlsrv --modules *sqlsrv*.dll --export_type=cobertura:.\coverage.xml --cover_children --optimized_build -- .\php.exe .\run-tests.php -P %APPVEYOR_BUILD_FOLDER%\test\functional\ - ls - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\cleanup_dbs.py -dbname %SQLSRV_DBNAME% - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\cleanup_dbs.py -dbname %PDOSQLSRV_DBNAME% From e3651e56c4b0317e99adb8e35a885f07a30db0b5 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Tue, 17 Oct 2017 12:33:13 -0700 Subject: [PATCH 08/27] detect appveyor problem --- appveyor.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 8ff16877..82be746b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,15 +18,6 @@ environment: PHP_DEPSVER: 7.0 PHP_SDK: c:\projects\php matrix: - - BUILD_PLATFORM: x64 - TEST_PHP_SQL_SERVER: (local)\SQL2016 - SQL_INSTANCE: SQL2016 - PHP_VC: 14 - PHP_MAJOR_VER: 7.1 - PHP_MINOR_VER: latest - PHP_SDK_DIR: c:\projects\php\x64 - PHP_INSTALL_DIR: c:\projects\php\x64\bin - platform: x64 - BUILD_PLATFORM: x64 TEST_PHP_SQL_SERVER: (local)\SQL2012SP1 SQL_INSTANCE: SQL2012SP1 @@ -192,6 +183,15 @@ test_script: - ps: foreach($file in $outfiles){ls $file; more $file} - cd %PHP_INSTALL_DIR% - OpenCppCoverage.exe --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\pdo_sqlsrv --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\sqlsrv --modules *sqlsrv*.dll --export_type=cobertura:.\coverage.xml --cover_children --optimized_build -- .\php.exe .\run-tests.php -P %APPVEYOR_BUILD_FOLDER%\test\functional\ + - cd %APPVEYOR_BUILD_FOLDER%\test\functional\ + - ps: $difffiles = Get-ChildItem sqlsrv\*.diff + - ps: $outfiles = Get-ChildItem sqlsrv\*.out + - ps: foreach($file in $difffiles){ls $file; more $file} + - ps: foreach($file in $outfiles){ls $file; more $file} + - ps: $difffiles = Get-ChildItem pdo_sqlsrv\*.diff + - ps: $outfiles = Get-ChildItem pdo_sqlsrv\*.out + - ps: foreach($file in $difffiles){ls $file; more $file} + - ps: foreach($file in $outfiles){ls $file; more $file} - ls - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\cleanup_dbs.py -dbname %SQLSRV_DBNAME% - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\cleanup_dbs.py -dbname %PDOSQLSRV_DBNAME% From a195e850499bca08bda316f6dacfa5d5d4b38a98 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Tue, 17 Oct 2017 14:03:13 -0700 Subject: [PATCH 09/27] detect appveyor problem --- appveyor.yml | 46 ++++++++-------------------------------------- 1 file changed, 8 insertions(+), 38 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 82be746b..e6bc544c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,34 +19,14 @@ environment: PHP_SDK: c:\projects\php matrix: - BUILD_PLATFORM: x64 - TEST_PHP_SQL_SERVER: (local)\SQL2012SP1 - SQL_INSTANCE: SQL2012SP1 - PHP_VC: 14 - PHP_MAJOR_VER: 7.0 - PHP_MINOR_VER: latest - PHP_SDK_DIR: c:\projects\php\x64 - PHP_INSTALL_DIR: c:\projects\php\x64\bin - PHP_ZTS: --disable-zts - platform: x64 - - BUILD_PLATFORM: x86 - TEST_PHP_SQL_SERVER: (local)\SQL2014 - SQL_INSTANCE: SQL2014 - PHP_VC: 14 - PHP_MAJOR_VER: 7.0 - PHP_MINOR_VER: latest - PHP_SDK_DIR: c:\projects\php\x86 - PHP_INSTALL_DIR: c:\projects\php\x86\bin - platform: x86 - - BUILD_PLATFORM: x86 - TEST_PHP_SQL_SERVER: (local)\SQL2008R2SP2 - SQL_INSTANCE: SQL2008R2SP2 + TEST_PHP_SQL_SERVER: (local)\SQL2016 + SQL_INSTANCE: SQL2016 PHP_VC: 14 PHP_MAJOR_VER: 7.1 - PHP_MINOR_VER: latest - PHP_SDK_DIR: c:\projects\php\x86 - PHP_INSTALL_DIR: c:\projects\php\x86\bin - PHP_ZTS: --disable-zts - platform: x86 + PHP_MINOR_VER: latest + PHP_SDK_DIR: c:\projects\php\x64 + PHP_INSTALL_DIR: c:\projects\php\x64\bin + platform: x64 # PHP_MAJOR_VER is PHP major version to build (7.0, 7.1) # PHP_MINOR_VER is PHP point release number (or latest for latest release) @@ -167,7 +147,8 @@ test_script: - copy %APPVEYOR_BUILD_FOLDER%\test\functional\setup\*.dll %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv\ - copy %APPVEYOR_BUILD_FOLDER%\test\functional\setup\*.dll %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv\ - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\run_ksp.py -server %TEST_PHP_SQL_SERVER% -dbname %SQLSRV_DBNAME% -uid %TEST_PHP_SQL_UID% -pwd %TEST_PHP_SQL_PWD% - - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\run_ksp.py -server %TEST_PHP_SQL_SERVER% -dbname %PDOSQLSRV_DBNAME% -uid %TEST_PHP_SQL_UID% -pwd %TEST_PHP_SQL_PWD% + - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\run_ksp.py -server %TEST_PHP_SQL_SERVER% -dbname %PDOSQLSRV_DBNAME% -uid %TEST_PHP_SQL_UID% -pwd %TEST_PHP_SQL_PWD% + - OpenCppCoverage.exe --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\pdo_sqlsrv --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\sqlsrv --modules *sqlsrv*.dll --export_type=cobertura:.\coverage.xml --cover_children --optimized_build -- .\php.exe .\run-tests.php -P %APPVEYOR_BUILD_FOLDER%\test\functional\ - php run-tests.php -p php.exe %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv\*.phpt > %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv.log 2>&1 - type %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv.log - php run-tests.php -p php.exe %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv\*.phpt > %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv.log 2>&1 @@ -181,17 +162,6 @@ test_script: - ps: $outfiles = Get-ChildItem pdo_sqlsrv\*.out - ps: foreach($file in $difffiles){ls $file; more $file} - ps: foreach($file in $outfiles){ls $file; more $file} - - cd %PHP_INSTALL_DIR% - - OpenCppCoverage.exe --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\pdo_sqlsrv --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\sqlsrv --modules *sqlsrv*.dll --export_type=cobertura:.\coverage.xml --cover_children --optimized_build -- .\php.exe .\run-tests.php -P %APPVEYOR_BUILD_FOLDER%\test\functional\ - - cd %APPVEYOR_BUILD_FOLDER%\test\functional\ - - ps: $difffiles = Get-ChildItem sqlsrv\*.diff - - ps: $outfiles = Get-ChildItem sqlsrv\*.out - - ps: foreach($file in $difffiles){ls $file; more $file} - - ps: foreach($file in $outfiles){ls $file; more $file} - - ps: $difffiles = Get-ChildItem pdo_sqlsrv\*.diff - - ps: $outfiles = Get-ChildItem pdo_sqlsrv\*.out - - ps: foreach($file in $difffiles){ls $file; more $file} - - ps: foreach($file in $outfiles){ls $file; more $file} - ls - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\cleanup_dbs.py -dbname %SQLSRV_DBNAME% - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\cleanup_dbs.py -dbname %PDOSQLSRV_DBNAME% From acee5c46868c1d9bc03e52ffb470ddf81afc7a78 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Tue, 17 Oct 2017 14:50:33 -0700 Subject: [PATCH 10/27] detect appveyor problem --- test/functional/pdo_sqlsrv/PDO100_InsertNulls.phpt | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/functional/pdo_sqlsrv/PDO100_InsertNulls.phpt b/test/functional/pdo_sqlsrv/PDO100_InsertNulls.phpt index 0f3b1a52..227c5293 100644 --- a/test/functional/pdo_sqlsrv/PDO100_InsertNulls.phpt +++ b/test/functional/pdo_sqlsrv/PDO100_InsertNulls.phpt @@ -102,12 +102,9 @@ function Repro() if ($failed) FatalError("Possible Regression: Could not insert NULL"); - - EndTest($testName); } Repro(); ?> --EXPECT-- -Test "PDO - Insert Nulls" completed successfully. From 8397f7b8bfb534734dfa903677752316c2efcba2 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Tue, 17 Oct 2017 15:13:29 -0700 Subject: [PATCH 11/27] detect appveyor problem --- source/shared/core_sqlsrv.h | 10 ++++------ source/shared/core_stmt.cpp | 31 ++++--------------------------- 2 files changed, 8 insertions(+), 33 deletions(-) diff --git a/source/shared/core_sqlsrv.h b/source/shared/core_sqlsrv.h index 16ca5711..0c909b44 100644 --- a/source/shared/core_sqlsrv.h +++ b/source/shared/core_sqlsrv.h @@ -1322,11 +1322,10 @@ struct sqlsrv_output_param { SQLUSMALLINT param_num; // used to index into the ind_or_len of the statement SQLLEN original_buffer_len; // used to make sure the returned length didn't overflow the buffer bool is_bool; - bool is_long; // string output param constructor - sqlsrv_output_param( _In_ zval* p_z, _In_ SQLSRV_ENCODING enc, _In_ int num, _In_ SQLUINTEGER buffer_len, _In_ bool is_long ) : - param_z( p_z ), encoding( enc ), param_num( num ), original_buffer_len( buffer_len ), is_bool( false ), is_long( is_long ) + sqlsrv_output_param( _In_ zval* p_z, _In_ SQLSRV_ENCODING enc, _In_ int num, _In_ SQLUINTEGER buffer_len ) : + param_z( p_z ), encoding( enc ), param_num( num ), original_buffer_len( buffer_len ), is_bool( false ) { } @@ -1336,8 +1335,7 @@ struct sqlsrv_output_param { encoding( SQLSRV_ENCODING_INVALID ), param_num( num ), original_buffer_len( -1 ), - is_bool( is_bool ), - is_long( false ) + is_bool( is_bool ) { } }; @@ -1433,7 +1431,7 @@ typedef sqlsrv_stmt* (*driver_stmt_factory)( sqlsrv_conn* conn, SQLHANDLE h, err sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stmt_factory stmt_factory, _In_opt_ HashTable* options_ht, _In_opt_ const stmt_option valid_stmt_opts[], _In_ error_callback const err, _In_opt_ void* driver TSRMLS_DC ); void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_num, _In_ SQLSMALLINT direction, _Inout_ zval* param_z, - _In_ SQLSRV_PHPTYPE php_out_type, _Inout_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, + _In_ SQLSRV_PHPTYPE php_out_type, _In_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, _Inout_ SQLSMALLINT decimal_digits TSRMLS_DC ); SQLRETURN core_sqlsrv_execute( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_reads_bytes_(sql_len) const char* sql = NULL, _In_ int sql_len = 0 ); field_meta_data* core_sqlsrv_field_metadata( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno TSRMLS_DC ); diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index dd2d22bf..29255029 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -342,7 +342,7 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stm // The sql type is given as a hint if the driver provides it. void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_num, _In_ SQLSMALLINT direction, _Inout_ zval* param_z, - _In_ SQLSRV_PHPTYPE php_out_type, _Inout_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, + _In_ SQLSRV_PHPTYPE php_out_type, _In_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, _Inout_ SQLSMALLINT decimal_digits TSRMLS_DC ) { SQLSMALLINT c_type; @@ -373,7 +373,6 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ } bool zval_was_null = ( Z_TYPE_P( param_z ) == IS_NULL ); bool zval_was_bool = ( Z_TYPE_P( param_z ) == IS_TRUE || Z_TYPE_P( param_z ) == IS_FALSE ); - bool zval_was_long = ( Z_TYPE_P( param_z ) == IS_LONG && php_out_type == SQLSRV_PHPTYPE_INT && (sql_type == SQL_BIGINT || sql_type == SQL_UNKNOWN_TYPE )); // if the user asks for for a specific type for input and output, make sure the data type we send matches the data we // type we expect back, since we can only send and receive the same type. Anything can be converted to a string, so // we always let that match if they want a string back. @@ -384,14 +383,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ if( zval_was_null || zval_was_bool ) { convert_to_long( param_z ); } - if( zval_was_long ){ - convert_to_string( param_z ); - encoding = SQLSRV_ENCODING_SYSTEM; - match = Z_TYPE_P( param_z ) == IS_STRING; - } - else { - match = Z_TYPE_P(param_z) == IS_LONG; - } + match = Z_TYPE_P( param_z ) == IS_LONG; break; case SQLSRV_PHPTYPE_FLOAT: if( zval_was_null ) { @@ -423,13 +415,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ if( direction == SQL_PARAM_OUTPUT ) { switch( php_out_type ) { case SQLSRV_PHPTYPE_INT: - if( zval_was_long ){ - convert_to_string( param_z ); - encoding = SQLSRV_ENCODING_SYSTEM; - } - else { - convert_to_long( param_z ); - } + convert_to_long( param_z ); break; case SQLSRV_PHPTYPE_FLOAT: convert_to_double( param_z ); @@ -565,7 +551,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ buffer, buffer_len TSRMLS_CC ); // save the parameter to be adjusted and/or converted after the results are processed - sqlsrv_output_param output_param( param_ref, encoding, param_num, static_cast( buffer_len ), zval_was_long ); + sqlsrv_output_param output_param( param_ref, encoding, param_num, static_cast( buffer_len )); save_output_param_for_later( stmt, output_param TSRMLS_CC ); @@ -2141,15 +2127,6 @@ void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) else { core::sqlsrv_zval_stringl(value_z, str, str_len); } - if ( output_param->is_long ) { - zval* value_z_temp = ( zval * )sqlsrv_malloc( sizeof( zval )); - ZVAL_COPY( value_z_temp, value_z ); - convert_to_double( value_z_temp ); - if ( Z_DVAL_P( value_z_temp ) > INT_MIN && Z_DVAL_P( value_z_temp ) < INT_MAX ) { - convert_to_long( value_z ); - } - sqlsrv_free( value_z_temp ); - } } break; case IS_LONG: From 98edd5df85c82f88f038fb230cdbb714dd86fb77 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Tue, 17 Oct 2017 15:22:00 -0700 Subject: [PATCH 12/27] detect appveyor problem --- source/shared/core_stmt.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index 29255029..982a64b4 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -373,6 +373,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ } bool zval_was_null = ( Z_TYPE_P( param_z ) == IS_NULL ); bool zval_was_bool = ( Z_TYPE_P( param_z ) == IS_TRUE || Z_TYPE_P( param_z ) == IS_FALSE ); + bool zval_was_long = ( Z_TYPE_P( param_z ) == IS_LONG && php_out_type == SQLSRV_PHPTYPE_INT && (sql_type == SQL_BIGINT || sql_type == SQL_UNKNOWN_TYPE )); // if the user asks for for a specific type for input and output, make sure the data type we send matches the data we // type we expect back, since we can only send and receive the same type. Anything can be converted to a string, so // we always let that match if they want a string back. From 3e247c6a253a96977ff0f8b6f3906c7157e01657 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Tue, 17 Oct 2017 15:30:27 -0700 Subject: [PATCH 13/27] detect appveyor problem --- source/shared/core_stmt.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index 982a64b4..285764b1 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -384,7 +384,14 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ if( zval_was_null || zval_was_bool ) { convert_to_long( param_z ); } - match = Z_TYPE_P( param_z ) == IS_LONG; + if( zval_was_long ){ + convert_to_string( param_z ); + encoding = SQLSRV_ENCODING_SYSTEM; + match = Z_TYPE_P( param_z ) == IS_STRING; + } + else { + match = Z_TYPE_P(param_z) == IS_LONG; + } break; case SQLSRV_PHPTYPE_FLOAT: if( zval_was_null ) { From 597d54476ec9be5684fd718f4b723e1e1686c4c4 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Tue, 17 Oct 2017 15:37:59 -0700 Subject: [PATCH 14/27] detect appveyor problem --- source/shared/core_sqlsrv.h | 10 ++++++---- source/shared/core_stmt.cpp | 30 +++++++++++++++++++----------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/source/shared/core_sqlsrv.h b/source/shared/core_sqlsrv.h index 0c909b44..16ca5711 100644 --- a/source/shared/core_sqlsrv.h +++ b/source/shared/core_sqlsrv.h @@ -1322,10 +1322,11 @@ struct sqlsrv_output_param { SQLUSMALLINT param_num; // used to index into the ind_or_len of the statement SQLLEN original_buffer_len; // used to make sure the returned length didn't overflow the buffer bool is_bool; + bool is_long; // string output param constructor - sqlsrv_output_param( _In_ zval* p_z, _In_ SQLSRV_ENCODING enc, _In_ int num, _In_ SQLUINTEGER buffer_len ) : - param_z( p_z ), encoding( enc ), param_num( num ), original_buffer_len( buffer_len ), is_bool( false ) + sqlsrv_output_param( _In_ zval* p_z, _In_ SQLSRV_ENCODING enc, _In_ int num, _In_ SQLUINTEGER buffer_len, _In_ bool is_long ) : + param_z( p_z ), encoding( enc ), param_num( num ), original_buffer_len( buffer_len ), is_bool( false ), is_long( is_long ) { } @@ -1335,7 +1336,8 @@ struct sqlsrv_output_param { encoding( SQLSRV_ENCODING_INVALID ), param_num( num ), original_buffer_len( -1 ), - is_bool( is_bool ) + is_bool( is_bool ), + is_long( false ) { } }; @@ -1431,7 +1433,7 @@ typedef sqlsrv_stmt* (*driver_stmt_factory)( sqlsrv_conn* conn, SQLHANDLE h, err sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stmt_factory stmt_factory, _In_opt_ HashTable* options_ht, _In_opt_ const stmt_option valid_stmt_opts[], _In_ error_callback const err, _In_opt_ void* driver TSRMLS_DC ); void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_num, _In_ SQLSMALLINT direction, _Inout_ zval* param_z, - _In_ SQLSRV_PHPTYPE php_out_type, _In_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, + _In_ SQLSRV_PHPTYPE php_out_type, _Inout_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, _Inout_ SQLSMALLINT decimal_digits TSRMLS_DC ); SQLRETURN core_sqlsrv_execute( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_reads_bytes_(sql_len) const char* sql = NULL, _In_ int sql_len = 0 ); field_meta_data* core_sqlsrv_field_metadata( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno TSRMLS_DC ); diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index 285764b1..23062b8e 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -342,7 +342,7 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stm // The sql type is given as a hint if the driver provides it. void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_num, _In_ SQLSMALLINT direction, _Inout_ zval* param_z, - _In_ SQLSRV_PHPTYPE php_out_type, _In_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, + _In_ SQLSRV_PHPTYPE php_out_type, _Inout_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, _Inout_ SQLSMALLINT decimal_digits TSRMLS_DC ) { SQLSMALLINT c_type; @@ -384,14 +384,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ if( zval_was_null || zval_was_bool ) { convert_to_long( param_z ); } - if( zval_was_long ){ - convert_to_string( param_z ); - encoding = SQLSRV_ENCODING_SYSTEM; - match = Z_TYPE_P( param_z ) == IS_STRING; - } - else { - match = Z_TYPE_P(param_z) == IS_LONG; - } + match = Z_TYPE_P( param_z ) == IS_LONG; break; case SQLSRV_PHPTYPE_FLOAT: if( zval_was_null ) { @@ -423,7 +416,13 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ if( direction == SQL_PARAM_OUTPUT ) { switch( php_out_type ) { case SQLSRV_PHPTYPE_INT: - convert_to_long( param_z ); + if( zval_was_long ){ + convert_to_string( param_z ); + encoding = SQLSRV_ENCODING_SYSTEM; + } + else { + convert_to_long( param_z ); + } break; case SQLSRV_PHPTYPE_FLOAT: convert_to_double( param_z ); @@ -559,7 +558,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ buffer, buffer_len TSRMLS_CC ); // save the parameter to be adjusted and/or converted after the results are processed - sqlsrv_output_param output_param( param_ref, encoding, param_num, static_cast( buffer_len )); + sqlsrv_output_param output_param( param_ref, encoding, param_num, static_cast( buffer_len ), zval_was_long ); save_output_param_for_later( stmt, output_param TSRMLS_CC ); @@ -2135,6 +2134,15 @@ void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) else { core::sqlsrv_zval_stringl(value_z, str, str_len); } + if ( output_param->is_long ) { + zval* value_z_temp = ( zval * )sqlsrv_malloc( sizeof( zval )); + ZVAL_COPY( value_z_temp, value_z ); + convert_to_double( value_z_temp ); + if ( Z_DVAL_P( value_z_temp ) > INT_MIN && Z_DVAL_P( value_z_temp ) < INT_MAX ) { + convert_to_long( value_z ); + } + sqlsrv_free( value_z_temp ); + } } break; case IS_LONG: From 6b223a77c9a5865e1f67324b6af4d0412792b1d6 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Tue, 17 Oct 2017 15:44:52 -0700 Subject: [PATCH 15/27] detect appveyor problem --- source/shared/core_stmt.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index 23062b8e..ef691aa0 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -384,7 +384,12 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ if( zval_was_null || zval_was_bool ) { convert_to_long( param_z ); } - match = Z_TYPE_P( param_z ) == IS_LONG; + if( zval_was_long ){ + convert_to_string( param_z ); + } + else { + match = Z_TYPE_P(param_z) == IS_LONG; + } break; case SQLSRV_PHPTYPE_FLOAT: if( zval_was_null ) { From 9e847c1ca893b47c8d69490eedf814f38229c717 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Tue, 17 Oct 2017 15:51:41 -0700 Subject: [PATCH 16/27] detect appveyor problem --- source/shared/core_stmt.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index ef691aa0..f0e022e1 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -386,6 +386,8 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ } if( zval_was_long ){ convert_to_string( param_z ); + + match = Z_TYPE_P( param_z ) == IS_STRING; } else { match = Z_TYPE_P(param_z) == IS_LONG; From f67240e566e7aaa939e789ccde4fca5884e928ee Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Tue, 17 Oct 2017 16:02:12 -0700 Subject: [PATCH 17/27] change encoding to converting from long to string to UTF8 --- source/shared/core_stmt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index f0e022e1..e0e35440 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -386,7 +386,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ } if( zval_was_long ){ convert_to_string( param_z ); - + encoding = SQLSRV_ENCODING_UTF8; match = Z_TYPE_P( param_z ) == IS_STRING; } else { From d7212e60cb9faec9a2a6502b278395687179c2b6 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Tue, 17 Oct 2017 16:11:05 -0700 Subject: [PATCH 18/27] change output biging to encoding utf8 --- source/shared/core_stmt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index e0e35440..a1016644 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -425,7 +425,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ case SQLSRV_PHPTYPE_INT: if( zval_was_long ){ convert_to_string( param_z ); - encoding = SQLSRV_ENCODING_SYSTEM; + encoding = SQLSRV_ENCODING_UTF8; } else { convert_to_long( param_z ); From a5125dff54a62aab72b1d19424ea2eb7625da091 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Tue, 17 Oct 2017 16:13:42 -0700 Subject: [PATCH 19/27] undo changes in appveyor.yml --- appveyor.yml | 6 +----- test/functional/pdo_sqlsrv/PDO100_InsertNulls.phpt | 3 +++ 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index e6bc544c..c2f15f61 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -148,11 +148,7 @@ test_script: - copy %APPVEYOR_BUILD_FOLDER%\test\functional\setup\*.dll %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv\ - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\run_ksp.py -server %TEST_PHP_SQL_SERVER% -dbname %SQLSRV_DBNAME% -uid %TEST_PHP_SQL_UID% -pwd %TEST_PHP_SQL_PWD% - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\run_ksp.py -server %TEST_PHP_SQL_SERVER% -dbname %PDOSQLSRV_DBNAME% -uid %TEST_PHP_SQL_UID% -pwd %TEST_PHP_SQL_PWD% - - OpenCppCoverage.exe --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\pdo_sqlsrv --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\sqlsrv --modules *sqlsrv*.dll --export_type=cobertura:.\coverage.xml --cover_children --optimized_build -- .\php.exe .\run-tests.php -P %APPVEYOR_BUILD_FOLDER%\test\functional\ - - php run-tests.php -p php.exe %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv\*.phpt > %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv.log 2>&1 - - type %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv.log - - php run-tests.php -p php.exe %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv\*.phpt > %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv.log 2>&1 - - type %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv.log + - OpenCppCoverage.exe --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\pdo_sqlsrv --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\sqlsrv --modules *sqlsrv*.dll --export_type=cobertura:.\coverage.xml --cover_children --quiet --optimized_build -- .\php.exe .\run-tests.php -P %APPVEYOR_BUILD_FOLDER%\test\functional\ - cd %APPVEYOR_BUILD_FOLDER%\test\functional\ - ps: $difffiles = Get-ChildItem sqlsrv\*.diff - ps: $outfiles = Get-ChildItem sqlsrv\*.out diff --git a/test/functional/pdo_sqlsrv/PDO100_InsertNulls.phpt b/test/functional/pdo_sqlsrv/PDO100_InsertNulls.phpt index 227c5293..0f3b1a52 100644 --- a/test/functional/pdo_sqlsrv/PDO100_InsertNulls.phpt +++ b/test/functional/pdo_sqlsrv/PDO100_InsertNulls.phpt @@ -102,9 +102,12 @@ function Repro() if ($failed) FatalError("Possible Regression: Could not insert NULL"); + + EndTest($testName); } Repro(); ?> --EXPECT-- +Test "PDO - Insert Nulls" completed successfully. From 68df220418e6415d65f781784f031ac501109b8c Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Tue, 17 Oct 2017 16:17:01 -0700 Subject: [PATCH 20/27] undo changes in appveyor.yml --- appveyor.yml | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index c2f15f61..b4eb35d3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,6 +18,25 @@ environment: PHP_DEPSVER: 7.0 PHP_SDK: c:\projects\php matrix: + - BUILD_PLATFORM: x64 + TEST_PHP_SQL_SERVER: (local)\SQL2012SP1 + SQL_INSTANCE: SQL2012SP1 + PHP_VC: 14 + PHP_MAJOR_VER: 7.0 + PHP_MINOR_VER: latest + PHP_SDK_DIR: c:\projects\php\x64 + PHP_INSTALL_DIR: c:\projects\php\x64\bin + PHP_ZTS: --disable-zts + platform: x64 + - BUILD_PLATFORM: x86 + TEST_PHP_SQL_SERVER: (local)\SQL2014 + SQL_INSTANCE: SQL2014 + PHP_VC: 14 + PHP_MAJOR_VER: 7.0 + PHP_MINOR_VER: latest + PHP_SDK_DIR: c:\projects\php\x86 + PHP_INSTALL_DIR: c:\projects\php\x86\bin + platform: x86 - BUILD_PLATFORM: x64 TEST_PHP_SQL_SERVER: (local)\SQL2016 SQL_INSTANCE: SQL2016 @@ -27,6 +46,16 @@ environment: PHP_SDK_DIR: c:\projects\php\x64 PHP_INSTALL_DIR: c:\projects\php\x64\bin platform: x64 + - BUILD_PLATFORM: x86 + TEST_PHP_SQL_SERVER: (local)\SQL2008R2SP2 + SQL_INSTANCE: SQL2008R2SP2 + PHP_VC: 14 + PHP_MAJOR_VER: 7.1 + PHP_MINOR_VER: latest + PHP_SDK_DIR: c:\projects\php\x86 + PHP_INSTALL_DIR: c:\projects\php\x86\bin + PHP_ZTS: --disable-zts + platform: x86 # PHP_MAJOR_VER is PHP major version to build (7.0, 7.1) # PHP_MINOR_VER is PHP point release number (or latest for latest release) @@ -147,8 +176,11 @@ test_script: - copy %APPVEYOR_BUILD_FOLDER%\test\functional\setup\*.dll %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv\ - copy %APPVEYOR_BUILD_FOLDER%\test\functional\setup\*.dll %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv\ - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\run_ksp.py -server %TEST_PHP_SQL_SERVER% -dbname %SQLSRV_DBNAME% -uid %TEST_PHP_SQL_UID% -pwd %TEST_PHP_SQL_PWD% - - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\run_ksp.py -server %TEST_PHP_SQL_SERVER% -dbname %PDOSQLSRV_DBNAME% -uid %TEST_PHP_SQL_UID% -pwd %TEST_PHP_SQL_PWD% - - OpenCppCoverage.exe --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\pdo_sqlsrv --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\sqlsrv --modules *sqlsrv*.dll --export_type=cobertura:.\coverage.xml --cover_children --quiet --optimized_build -- .\php.exe .\run-tests.php -P %APPVEYOR_BUILD_FOLDER%\test\functional\ + - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\run_ksp.py -server %TEST_PHP_SQL_SERVER% -dbname %PDOSQLSRV_DBNAME% -uid %TEST_PHP_SQL_UID% -pwd %TEST_PHP_SQL_PWD% + - php run-tests.php -p php.exe %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv\*.phpt > %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv.log 2>&1 + - type %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv.log + - php run-tests.php -p php.exe %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv\*.phpt > %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv.log 2>&1 + - type %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv.log - cd %APPVEYOR_BUILD_FOLDER%\test\functional\ - ps: $difffiles = Get-ChildItem sqlsrv\*.diff - ps: $outfiles = Get-ChildItem sqlsrv\*.out @@ -158,6 +190,8 @@ test_script: - ps: $outfiles = Get-ChildItem pdo_sqlsrv\*.out - ps: foreach($file in $difffiles){ls $file; more $file} - ps: foreach($file in $outfiles){ls $file; more $file} + - cd %PHP_INSTALL_DIR% + - OpenCppCoverage.exe --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\pdo_sqlsrv --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\sqlsrv --modules *sqlsrv*.dll --export_type=cobertura:.\coverage.xml --cover_children --quiet --optimized_build -- .\php.exe .\run-tests.php -P %APPVEYOR_BUILD_FOLDER%\test\functional\ - ls - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\cleanup_dbs.py -dbname %SQLSRV_DBNAME% - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\cleanup_dbs.py -dbname %PDOSQLSRV_DBNAME% From 3f171471c09b159bee9aa8e80a6eea0724fbf310 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Wed, 18 Oct 2017 09:31:46 -0700 Subject: [PATCH 21/27] add contrinue_after_cpp_exception option to OpenCppCoverage --- appveyor.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index b4eb35d3..0b449210 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,6 +18,15 @@ environment: PHP_DEPSVER: 7.0 PHP_SDK: c:\projects\php matrix: + - BUILD_PLATFORM: x64 + TEST_PHP_SQL_SERVER: (local)\SQL2016 + SQL_INSTANCE: SQL2016 + PHP_VC: 14 + PHP_MAJOR_VER: 7.1 + PHP_MINOR_VER: latest + PHP_SDK_DIR: c:\projects\php\x64 + PHP_INSTALL_DIR: c:\projects\php\x64\bin + platform: x64 - BUILD_PLATFORM: x64 TEST_PHP_SQL_SERVER: (local)\SQL2012SP1 SQL_INSTANCE: SQL2012SP1 @@ -37,15 +46,6 @@ environment: PHP_SDK_DIR: c:\projects\php\x86 PHP_INSTALL_DIR: c:\projects\php\x86\bin platform: x86 - - BUILD_PLATFORM: x64 - TEST_PHP_SQL_SERVER: (local)\SQL2016 - SQL_INSTANCE: SQL2016 - PHP_VC: 14 - PHP_MAJOR_VER: 7.1 - PHP_MINOR_VER: latest - PHP_SDK_DIR: c:\projects\php\x64 - PHP_INSTALL_DIR: c:\projects\php\x64\bin - platform: x64 - BUILD_PLATFORM: x86 TEST_PHP_SQL_SERVER: (local)\SQL2008R2SP2 SQL_INSTANCE: SQL2008R2SP2 @@ -191,7 +191,7 @@ test_script: - ps: foreach($file in $difffiles){ls $file; more $file} - ps: foreach($file in $outfiles){ls $file; more $file} - cd %PHP_INSTALL_DIR% - - OpenCppCoverage.exe --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\pdo_sqlsrv --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\sqlsrv --modules *sqlsrv*.dll --export_type=cobertura:.\coverage.xml --cover_children --quiet --optimized_build -- .\php.exe .\run-tests.php -P %APPVEYOR_BUILD_FOLDER%\test\functional\ + - OpenCppCoverage.exe --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\pdo_sqlsrv --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\sqlsrv --modules *sqlsrv*.dll --export_type=cobertura:.\coverage.xml --cover_children --quiet --continue_after_cpp_exception --optimized_build -- .\php.exe .\run-tests.php -P %APPVEYOR_BUILD_FOLDER%\test\functional\ - ls - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\cleanup_dbs.py -dbname %SQLSRV_DBNAME% - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\cleanup_dbs.py -dbname %PDOSQLSRV_DBNAME% From b73539c311b823105be531d7335b0886720b2781 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Wed, 18 Oct 2017 11:17:55 -0700 Subject: [PATCH 22/27] remove setting encoding in core_stmt.cpp --- source/shared/core_stmt.cpp | 101 ++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 51 deletions(-) diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index a1016644..eff54123 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -386,11 +386,10 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ } if( zval_was_long ){ convert_to_string( param_z ); - encoding = SQLSRV_ENCODING_UTF8; match = Z_TYPE_P( param_z ) == IS_STRING; } else { - match = Z_TYPE_P(param_z) == IS_LONG; + match = Z_TYPE_P( param_z ) == IS_LONG; } break; case SQLSRV_PHPTYPE_FLOAT: @@ -425,7 +424,6 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ case SQLSRV_PHPTYPE_INT: if( zval_was_long ){ convert_to_string( param_z ); - encoding = SQLSRV_ENCODING_UTF8; } else { convert_to_long( param_z ); @@ -2093,54 +2091,6 @@ void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) ZVAL_NULL( value_z ); continue; } - - // if there was more to output than buffer size to hold it, then throw a truncation error - int null_size = 0; - switch( output_param->encoding ) { - case SQLSRV_ENCODING_UTF8: - null_size = sizeof( SQLWCHAR ); // string isn't yet converted to UTF-8, still UTF-16 - break; - case SQLSRV_ENCODING_SYSTEM: - null_size = 1; - break; - case SQLSRV_ENCODING_BINARY: - null_size = 0; - break; - default: - SQLSRV_ASSERT( false, "Invalid encoding in output_param structure." ); - break; - } - CHECK_CUSTOM_ERROR( str_len > ( output_param->original_buffer_len - null_size ), stmt, - SQLSRV_ERROR_OUTPUT_PARAM_TRUNCATED, output_param->param_num + 1 ) { - throw core::CoreException(); - } - - // For ODBC 11+ see https://msdn.microsoft.com/en-us/library/jj219209.aspx - // A length value of SQL_NO_TOTAL for SQLBindParameter indicates that the buffer contains up to - // output_param->original_buffer_len data and is NULL terminated. - // The IF statement can be true when using connection pooling with unixODBC 2.3.4. - if ( str_len == SQL_NO_TOTAL ) - { - str_len = output_param->original_buffer_len - null_size; - } - - // if it's not in the 8 bit encodings, then it's in UTF-16 - if( output_param->encoding != SQLSRV_ENCODING_CHAR && output_param->encoding != SQLSRV_ENCODING_BINARY ) { - bool converted = convert_zval_string_from_utf16(output_param->encoding, value_z, str_len); - CHECK_CUSTOM_ERROR( !converted, stmt, SQLSRV_ERROR_OUTPUT_PARAM_ENCODING_TRANSLATE, get_last_error_message()) { - throw core::CoreException(); - } - } - else if( output_param->encoding == SQLSRV_ENCODING_BINARY && str_len < output_param->original_buffer_len ) { - // ODBC doesn't null terminate binary encodings, but PHP complains if a string isn't null terminated - // so we do that here if the length of the returned data is less than the original allocation. The - // original allocation null terminates the buffer already. - str[ str_len ] = '\0'; - core::sqlsrv_zval_stringl(value_z, str, str_len); - } - else { - core::sqlsrv_zval_stringl(value_z, str, str_len); - } if ( output_param->is_long ) { zval* value_z_temp = ( zval * )sqlsrv_malloc( sizeof( zval )); ZVAL_COPY( value_z_temp, value_z ); @@ -2150,6 +2100,55 @@ void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) } sqlsrv_free( value_z_temp ); } + else { + // if there was more to output than buffer size to hold it, then throw a truncation error + int null_size = 0; + switch ( output_param->encoding ) { + case SQLSRV_ENCODING_UTF8: + null_size = sizeof( SQLWCHAR ); // string isn't yet converted to UTF-8, still UTF-16 + break; + case SQLSRV_ENCODING_SYSTEM: + null_size = 1; + break; + case SQLSRV_ENCODING_BINARY: + null_size = 0; + break; + default: + SQLSRV_ASSERT( false, "Invalid encoding in output_param structure." ); + break; + } + CHECK_CUSTOM_ERROR( str_len > ( output_param->original_buffer_len - null_size ), stmt, + SQLSRV_ERROR_OUTPUT_PARAM_TRUNCATED, output_param->param_num + 1 ) { + throw core::CoreException(); + } + + // For ODBC 11+ see https://msdn.microsoft.com/en-us/library/jj219209.aspx + // A length value of SQL_NO_TOTAL for SQLBindParameter indicates that the buffer contains up to + // output_param->original_buffer_len data and is NULL terminated. + // The IF statement can be true when using connection pooling with unixODBC 2.3.4. + if ( str_len == SQL_NO_TOTAL ) + { + str_len = output_param->original_buffer_len - null_size; + } + + // if it's not in the 8 bit encodings, then it's in UTF-16 + if ( output_param->encoding != SQLSRV_ENCODING_CHAR && output_param->encoding != SQLSRV_ENCODING_BINARY ) { + bool converted = convert_zval_string_from_utf16( output_param->encoding, value_z, str_len ); + CHECK_CUSTOM_ERROR( !converted, stmt, SQLSRV_ERROR_OUTPUT_PARAM_ENCODING_TRANSLATE, get_last_error_message() ) { + throw core::CoreException(); + } + } + else if ( output_param->encoding == SQLSRV_ENCODING_BINARY && str_len < output_param->original_buffer_len ) { + // ODBC doesn't null terminate binary encodings, but PHP complains if a string isn't null terminated + // so we do that here if the length of the returned data is less than the original allocation. The + // original allocation null terminates the buffer already. + str[str_len] = '\0'; + core::sqlsrv_zval_stringl( value_z, str, str_len ); + } + else { + core::sqlsrv_zval_stringl( value_z, str, str_len ); + } + } } break; case IS_LONG: From f4c736a073b9612c1e567bfdf844f7d15c1972d8 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Wed, 18 Oct 2017 12:17:52 -0700 Subject: [PATCH 23/27] only change encoding if it is invalid --- appveyor.yml | 4 +- source/shared/core_stmt.cpp | 101 +++++++++++++++++++----------------- 2 files changed, 54 insertions(+), 51 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 0b449210..10ce9d8d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -177,6 +177,7 @@ test_script: - copy %APPVEYOR_BUILD_FOLDER%\test\functional\setup\*.dll %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv\ - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\run_ksp.py -server %TEST_PHP_SQL_SERVER% -dbname %SQLSRV_DBNAME% -uid %TEST_PHP_SQL_UID% -pwd %TEST_PHP_SQL_PWD% - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\run_ksp.py -server %TEST_PHP_SQL_SERVER% -dbname %PDOSQLSRV_DBNAME% -uid %TEST_PHP_SQL_UID% -pwd %TEST_PHP_SQL_PWD% + - OpenCppCoverage.exe --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\pdo_sqlsrv --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\sqlsrv --modules *sqlsrv*.dll --export_type=cobertura:.\coverage.xml --cover_children --quiet --continue_after_cpp_exception --optimized_build -- .\php.exe .\run-tests.php -P %APPVEYOR_BUILD_FOLDER%\test\functional\ - php run-tests.php -p php.exe %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv\*.phpt > %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv.log 2>&1 - type %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv.log - php run-tests.php -p php.exe %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv\*.phpt > %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv.log 2>&1 @@ -190,8 +191,7 @@ test_script: - ps: $outfiles = Get-ChildItem pdo_sqlsrv\*.out - ps: foreach($file in $difffiles){ls $file; more $file} - ps: foreach($file in $outfiles){ls $file; more $file} - - cd %PHP_INSTALL_DIR% - - OpenCppCoverage.exe --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\pdo_sqlsrv --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\sqlsrv --modules *sqlsrv*.dll --export_type=cobertura:.\coverage.xml --cover_children --quiet --continue_after_cpp_exception --optimized_build -- .\php.exe .\run-tests.php -P %APPVEYOR_BUILD_FOLDER%\test\functional\ + - cd %PHP_INSTALL_DIR% - ls - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\cleanup_dbs.py -dbname %SQLSRV_DBNAME% - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\cleanup_dbs.py -dbname %PDOSQLSRV_DBNAME% diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index eff54123..3e532456 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -386,6 +386,8 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ } if( zval_was_long ){ convert_to_string( param_z ); + if ( encoding != SQLSRV_ENCODING_SYSTEM && encoding != SQLSRV_ENCODING_UTF8 && encoding != SQLSRV_ENCODING_BINARY ) + encoding = SQLSRV_ENCODING_UTF8; match = Z_TYPE_P( param_z ) == IS_STRING; } else { @@ -424,6 +426,8 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ case SQLSRV_PHPTYPE_INT: if( zval_was_long ){ convert_to_string( param_z ); + if ( encoding != SQLSRV_ENCODING_SYSTEM && encoding != SQLSRV_ENCODING_UTF8 && encoding != SQLSRV_ENCODING_BINARY ) + encoding = SQLSRV_ENCODING_UTF8; } else { convert_to_long( param_z ); @@ -2091,6 +2095,54 @@ void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) ZVAL_NULL( value_z ); continue; } + + // if there was more to output than buffer size to hold it, then throw a truncation error + int null_size = 0; + switch( output_param->encoding ) { + case SQLSRV_ENCODING_UTF8: + null_size = sizeof( SQLWCHAR ); // string isn't yet converted to UTF-8, still UTF-16 + break; + case SQLSRV_ENCODING_SYSTEM: + null_size = 1; + break; + case SQLSRV_ENCODING_BINARY: + null_size = 0; + break; + default: + SQLSRV_ASSERT( false, "Invalid encoding in output_param structure." ); + break; + } + CHECK_CUSTOM_ERROR( str_len > ( output_param->original_buffer_len - null_size ), stmt, + SQLSRV_ERROR_OUTPUT_PARAM_TRUNCATED, output_param->param_num + 1 ) { + throw core::CoreException(); + } + + // For ODBC 11+ see https://msdn.microsoft.com/en-us/library/jj219209.aspx + // A length value of SQL_NO_TOTAL for SQLBindParameter indicates that the buffer contains up to + // output_param->original_buffer_len data and is NULL terminated. + // The IF statement can be true when using connection pooling with unixODBC 2.3.4. + if ( str_len == SQL_NO_TOTAL ) + { + str_len = output_param->original_buffer_len - null_size; + } + + // if it's not in the 8 bit encodings, then it's in UTF-16 + if( output_param->encoding != SQLSRV_ENCODING_CHAR && output_param->encoding != SQLSRV_ENCODING_BINARY ) { + bool converted = convert_zval_string_from_utf16(output_param->encoding, value_z, str_len); + CHECK_CUSTOM_ERROR( !converted, stmt, SQLSRV_ERROR_OUTPUT_PARAM_ENCODING_TRANSLATE, get_last_error_message()) { + throw core::CoreException(); + } + } + else if( output_param->encoding == SQLSRV_ENCODING_BINARY && str_len < output_param->original_buffer_len ) { + // ODBC doesn't null terminate binary encodings, but PHP complains if a string isn't null terminated + // so we do that here if the length of the returned data is less than the original allocation. The + // original allocation null terminates the buffer already. + str[ str_len ] = '\0'; + core::sqlsrv_zval_stringl(value_z, str, str_len); + } + else { + core::sqlsrv_zval_stringl(value_z, str, str_len); + } if ( output_param->is_long ) { zval* value_z_temp = ( zval * )sqlsrv_malloc( sizeof( zval )); ZVAL_COPY( value_z_temp, value_z ); @@ -2100,55 +2152,6 @@ void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) } sqlsrv_free( value_z_temp ); } - else { - // if there was more to output than buffer size to hold it, then throw a truncation error - int null_size = 0; - switch ( output_param->encoding ) { - case SQLSRV_ENCODING_UTF8: - null_size = sizeof( SQLWCHAR ); // string isn't yet converted to UTF-8, still UTF-16 - break; - case SQLSRV_ENCODING_SYSTEM: - null_size = 1; - break; - case SQLSRV_ENCODING_BINARY: - null_size = 0; - break; - default: - SQLSRV_ASSERT( false, "Invalid encoding in output_param structure." ); - break; - } - CHECK_CUSTOM_ERROR( str_len > ( output_param->original_buffer_len - null_size ), stmt, - SQLSRV_ERROR_OUTPUT_PARAM_TRUNCATED, output_param->param_num + 1 ) { - throw core::CoreException(); - } - - // For ODBC 11+ see https://msdn.microsoft.com/en-us/library/jj219209.aspx - // A length value of SQL_NO_TOTAL for SQLBindParameter indicates that the buffer contains up to - // output_param->original_buffer_len data and is NULL terminated. - // The IF statement can be true when using connection pooling with unixODBC 2.3.4. - if ( str_len == SQL_NO_TOTAL ) - { - str_len = output_param->original_buffer_len - null_size; - } - - // if it's not in the 8 bit encodings, then it's in UTF-16 - if ( output_param->encoding != SQLSRV_ENCODING_CHAR && output_param->encoding != SQLSRV_ENCODING_BINARY ) { - bool converted = convert_zval_string_from_utf16( output_param->encoding, value_z, str_len ); - CHECK_CUSTOM_ERROR( !converted, stmt, SQLSRV_ERROR_OUTPUT_PARAM_ENCODING_TRANSLATE, get_last_error_message() ) { - throw core::CoreException(); - } - } - else if ( output_param->encoding == SQLSRV_ENCODING_BINARY && str_len < output_param->original_buffer_len ) { - // ODBC doesn't null terminate binary encodings, but PHP complains if a string isn't null terminated - // so we do that here if the length of the returned data is less than the original allocation. The - // original allocation null terminates the buffer already. - str[str_len] = '\0'; - core::sqlsrv_zval_stringl( value_z, str, str_len ); - } - else { - core::sqlsrv_zval_stringl( value_z, str, str_len ); - } - } } break; case IS_LONG: From f2f3bc1ff5905b0735c9d9b330a57eb6c9d54fe8 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Wed, 18 Oct 2017 13:08:07 -0700 Subject: [PATCH 24/27] change encoding --- source/shared/core_stmt.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index 3e532456..848faacf 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -386,8 +386,12 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ } if( zval_was_long ){ convert_to_string( param_z ); - if ( encoding != SQLSRV_ENCODING_SYSTEM && encoding != SQLSRV_ENCODING_UTF8 && encoding != SQLSRV_ENCODING_BINARY ) - encoding = SQLSRV_ENCODING_UTF8; + if (encoding != SQLSRV_ENCODING_SYSTEM && encoding != SQLSRV_ENCODING_UTF8 && encoding != SQLSRV_ENCODING_BINARY) { + encoding = stmt->encoding(); + if (encoding == SQLSRV_ENCODING_DEFAULT) { + encoding = stmt->conn->encoding(); + } + } match = Z_TYPE_P( param_z ) == IS_STRING; } else { @@ -426,8 +430,12 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ case SQLSRV_PHPTYPE_INT: if( zval_was_long ){ convert_to_string( param_z ); - if ( encoding != SQLSRV_ENCODING_SYSTEM && encoding != SQLSRV_ENCODING_UTF8 && encoding != SQLSRV_ENCODING_BINARY ) - encoding = SQLSRV_ENCODING_UTF8; + if (encoding != SQLSRV_ENCODING_SYSTEM && encoding != SQLSRV_ENCODING_UTF8 && encoding != SQLSRV_ENCODING_BINARY) { + encoding = stmt->encoding(); + if (encoding == SQLSRV_ENCODING_DEFAULT) { + encoding = stmt->conn->encoding(); + } + } } else { convert_to_long( param_z ); From 02b3d6df282bfc006644b754b9973074744604d6 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Wed, 18 Oct 2017 13:41:13 -0700 Subject: [PATCH 25/27] change appveyor SQL2016 to run on x86 platform --- appveyor.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 10ce9d8d..1c9d3ad9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,15 +18,15 @@ environment: PHP_DEPSVER: 7.0 PHP_SDK: c:\projects\php matrix: - - BUILD_PLATFORM: x64 + - BUILD_PLATFORM: x86 TEST_PHP_SQL_SERVER: (local)\SQL2016 SQL_INSTANCE: SQL2016 PHP_VC: 14 PHP_MAJOR_VER: 7.1 PHP_MINOR_VER: latest - PHP_SDK_DIR: c:\projects\php\x64 - PHP_INSTALL_DIR: c:\projects\php\x64\bin - platform: x64 + PHP_SDK_DIR: c:\projects\php\x86 + PHP_INSTALL_DIR: c:\projects\php\x86\bin + platform: x86 - BUILD_PLATFORM: x64 TEST_PHP_SQL_SERVER: (local)\SQL2012SP1 SQL_INSTANCE: SQL2012SP1 From 78da8356394f3defc15f2ef433cb916ed8e7f3f7 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Wed, 18 Oct 2017 14:20:16 -0700 Subject: [PATCH 26/27] move opencppcoverage.exe down in appveyor.xml --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 1c9d3ad9..e7d4af30 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -177,7 +177,6 @@ test_script: - copy %APPVEYOR_BUILD_FOLDER%\test\functional\setup\*.dll %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv\ - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\run_ksp.py -server %TEST_PHP_SQL_SERVER% -dbname %SQLSRV_DBNAME% -uid %TEST_PHP_SQL_UID% -pwd %TEST_PHP_SQL_PWD% - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\run_ksp.py -server %TEST_PHP_SQL_SERVER% -dbname %PDOSQLSRV_DBNAME% -uid %TEST_PHP_SQL_UID% -pwd %TEST_PHP_SQL_PWD% - - OpenCppCoverage.exe --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\pdo_sqlsrv --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\sqlsrv --modules *sqlsrv*.dll --export_type=cobertura:.\coverage.xml --cover_children --quiet --continue_after_cpp_exception --optimized_build -- .\php.exe .\run-tests.php -P %APPVEYOR_BUILD_FOLDER%\test\functional\ - php run-tests.php -p php.exe %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv\*.phpt > %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv.log 2>&1 - type %APPVEYOR_BUILD_FOLDER%\test\functional\sqlsrv.log - php run-tests.php -p php.exe %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv\*.phpt > %APPVEYOR_BUILD_FOLDER%\test\functional\pdo_sqlsrv.log 2>&1 @@ -192,6 +191,7 @@ test_script: - ps: foreach($file in $difffiles){ls $file; more $file} - ps: foreach($file in $outfiles){ls $file; more $file} - cd %PHP_INSTALL_DIR% + - OpenCppCoverage.exe --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\pdo_sqlsrv --sources %PHP_SDK_DIR%\php-%PHP_VERSION%-src\ext\sqlsrv --modules *sqlsrv*.dll --export_type=cobertura:.\coverage.xml --cover_children --quiet --continue_after_cpp_exception --optimized_build -- .\php.exe .\run-tests.php -P %APPVEYOR_BUILD_FOLDER%\test\functional\ - ls - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\cleanup_dbs.py -dbname %SQLSRV_DBNAME% - python %APPVEYOR_BUILD_FOLDER%\test\functional\setup\cleanup_dbs.py -dbname %PDOSQLSRV_DBNAME% From 6a4f625e563b2a6188127c955151ec2de2a49364 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Wed, 18 Oct 2017 15:40:58 -0700 Subject: [PATCH 27/27] change encoding --- source/shared/core_stmt.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index 848faacf..957389e4 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -386,11 +386,8 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ } if( zval_was_long ){ convert_to_string( param_z ); - if (encoding != SQLSRV_ENCODING_SYSTEM && encoding != SQLSRV_ENCODING_UTF8 && encoding != SQLSRV_ENCODING_BINARY) { - encoding = stmt->encoding(); - if (encoding == SQLSRV_ENCODING_DEFAULT) { - encoding = stmt->conn->encoding(); - } + if ( encoding != SQLSRV_ENCODING_SYSTEM && encoding != SQLSRV_ENCODING_UTF8 && encoding != SQLSRV_ENCODING_BINARY ) { + encoding = SQLSRV_ENCODING_SYSTEM; } match = Z_TYPE_P( param_z ) == IS_STRING; } @@ -430,11 +427,8 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ case SQLSRV_PHPTYPE_INT: if( zval_was_long ){ convert_to_string( param_z ); - if (encoding != SQLSRV_ENCODING_SYSTEM && encoding != SQLSRV_ENCODING_UTF8 && encoding != SQLSRV_ENCODING_BINARY) { - encoding = stmt->encoding(); - if (encoding == SQLSRV_ENCODING_DEFAULT) { - encoding = stmt->conn->encoding(); - } + if ( encoding != SQLSRV_ENCODING_SYSTEM && encoding != SQLSRV_ENCODING_UTF8 && encoding != SQLSRV_ENCODING_BINARY ) { + encoding = SQLSRV_ENCODING_SYSTEM; } } else {