-
Notifications
You must be signed in to change notification settings - Fork 375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactored SQLSRV tests to test AE with various data types #575
Conversation
test/functional/sqlsrv/MsCommon.inc
Outdated
function createProc($conn, $procName, $procArgs, $procCode) | ||
{ | ||
dropProc($conn, $procName); | ||
$stmt = sqlsrv_query($conn, "CREATE PROC [$procName] ($procArgs) AS BEGIN $procCode END"); | ||
if ($stmt === false) { | ||
fatalError("Failed to create test procedure"); | ||
fatalError("Failed to create test procedure", true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
default is already true, no need to put this in
test/functional/sqlsrv/MsCommon.inc
Outdated
@@ -509,7 +376,7 @@ function callProcEx($conn, $procName, $procPrefix, $procArgs, $procValues) | |||
{ | |||
$stmt = sqlsrv_query($conn, "{ $procPrefix CALL [$procName] ($procArgs)}", $procValues); | |||
if ($stmt === false) { | |||
fatalError("Failed to call test procedure"); | |||
fatalError("Failed to call test procedure", true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as line 355
test/functional/sqlsrv/MsHelper.inc
Outdated
!strcasecmp($this->dataType, "hierarchyid") || | ||
!strcasecmp($this->dataType, "geography") || | ||
!strcasecmp($this->dataType, "geometry") || | ||
!strcasecmp($this->dataType, "alias")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
money and smallmoney are also not supported, why comment out?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also it would look nicer to put all the unsupported types in an array and there an array_in function that you can use in php to find a match
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when we do not encrypt money or smallmoney one of the AE tests with money types fail...
that's why I changed the ColumnMeta to take an optional parameter to not to encrypt a particular column instead
test/functional/sqlsrv/MsHelper.inc
Outdated
$this->dataType = $dataType; | ||
$this->options = $options; | ||
|
||
// first asssumes the column is not encryptable | ||
$this->encryptable = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not put this in an else block instead of assuming?
test/functional/sqlsrv/MsHelper.inc
Outdated
*/ | ||
protected function checkIfUnsupported() | ||
{ | ||
$this->encryptable = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here, you can put this into an else block
test/functional/sqlsrv/MsHelper.inc
Outdated
@@ -325,6 +377,7 @@ function connect($options = array(), $disableCE = false) | |||
* @param object $conn : sqlsrv connection object | |||
* @param string $tbname : name of the table to be created | |||
* @param array $columnMetaArr : array of ColumnMeta objects, which contain metadata for one column | |||
* @return object sqlsrv statement |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe sqlsrv statement is a resource not an object, same with sqlsrv connection
$r = sqlsrv_execute($stmt); | ||
if ($stmt) { | ||
$r = sqlsrv_execute($stmt); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you're going to check $stmt, maybe output the error as well
test/functional/sqlsrv/MsHelper.inc
Outdated
@@ -370,32 +425,106 @@ function insertRow($conn, $tbname, $inputs, &$r = null, $api = INSERT_QUERY) | |||
$params = array(); | |||
foreach ($inputs as $key => $input) { | |||
if (is_object($input)) { | |||
array_push($params, $input->bindParamArr($inputs[$key])); | |||
array_push($params, $input->bindParamArr($input->value)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is very strange looking. If you're calling a member function from $input, the function will have access to everything in $input. Passing in $input->value is not necessary. Please change bindParamArr function accordingly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reverted the change now. Thanks!
test/functional/sqlsrv/MsHelper.inc
Outdated
*/ | ||
function executeQuery($conn, $sql, $conds = null, $values = null) | ||
{ | ||
// when AE is enabled, use sqlsrv_prepare() to handle fields with unlimited size |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how can you tell if a field has unlimited size from here? If AE is enabled, does it always use sqlsrv_prepare?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, I'll modify the comments accordingly
test/functional/sqlsrv/MsHelper.inc
Outdated
* all deterministic if AE is enabled | ||
* @param resource $conn : connection resource | ||
* @param string $tbname : name of the table to create | ||
* @return object sqlsrv statement |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sqlsrv statement is a resoure
test/functional/sqlsrv/MsHelper.inc
Outdated
* @param resource $conn : connection resource | ||
* @param string $tbname : name of the table to create | ||
* @param int $index : the index of a certain row of test data | ||
* @return object sqlsrv statement upon success or false otherwise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resource
test/functional/sqlsrv/MsHelper.inc
Outdated
|
||
$result = null; | ||
if (isColEncrypted()) { | ||
$stmt = insertRow($conn, $tbname, $inputArray, $result, INSERT_PREPARE_PARAMS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
INSERT_PREPARE_PARAMS is redundant since in insertRow, isColEncrypted() and INSERT_PREPARE_PARAMS go to the same path (line 435)
test/functional/sqlsrv/MsHelper.inc
Outdated
* literal or a BindParamOption object | ||
* @param bool $r : true if the row was successfully inserted, otherwise false. Default value is null to make this parameter optional. | ||
* $param string $api : SQLSRV API used for executing the insert query | ||
* accepted values: INSERT_QUERY, INSERT_PREPARE, INSERT_QUERY_PARAMS, INSERT_PREPARE_PARAMS | ||
* accepted values: INSERT_QUERY, INSERT_PREPARE, INSERT_QUERY_PARAMS, INSERT_PREPARE_PARAMS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since you've already defined these constants, they are no longer string, use long
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed it to int
// this might be an input to a decimal, a numeric or a binary field | ||
if (isBinary($col)) { | ||
$value = "0x" . $value; // annotate the input string as a hex string | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can't you call insertRow after you've modified the binary data?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no I can't because binary data needs special handling which the generic function insertRow not supposed to know
test/functional/sqlsrv/MsHelper.inc
Outdated
// get array of input values | ||
$inputArray = getInsertArray($rowIndex); | ||
if (empty($inputArray)) { | ||
fatalError("getInsertData: failed to retrieve data at row $rowIndex and column $colIndex.\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get rid of "and column $colIndex" since the error comes from only $rowIndex
test/functional/sqlsrv/MsHelper.inc
Outdated
@@ -449,7 +773,7 @@ function getSqlType($k) | |||
return ("udt"); | |||
} | |||
|
|||
function getDriverType($k, $dataSize) | |||
function getDriverType($k, $dataSize = 512) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where does 512 come from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was for convenience, but I only need it for one test, so I'll move this constant to that test instead.
insertRows($conn1, $tableName, $noRows); | ||
// Insert a couple of random rows | ||
AE\createTestTable($conn1, $tableName); | ||
AE\insertTestRows($conn1, $tableName, 2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why change $noRows from 5 to 2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just thought the essence of the test is not really the data. Anyway, I've reverted the change.
$conn2 = connect(); | ||
$stmt2 = selectFromTable($conn2, $tableName); | ||
$conn2 = AE\connect(); | ||
$stmt2 = sqlsrv_query($conn2, "SELECT * FROM [$tableName]"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why can't you call selectFromTable?
|
||
trace("Executing SELECT query on $tableName ..."); | ||
$stmt1 = selectFromTable($conn1, $tableName); | ||
$stmt1 = sqlsrv_query($conn1, "SELECT * FROM $tableName"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not use createTable and selectFromTable?
|
||
createTable($conn1, $tableName); | ||
// just create an empty table | ||
$stmt1 = sqlsrv_query($conn1, "CREATE TABLE $tableName (dummyColumn int)"); | ||
|
||
trace("Executing SELECT query on $tableName ..."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought we were going to get rid of trace
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't mind keeping them around. Some tests have useful trace statements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But we never turn tracemode on.. If you think the output is useful, then use echo or print
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally do when I need to debug what goes wrong. If I use echo/print if will affect the expected output, which is often unnecessary.
$rows = rowCount($stmt1); | ||
; | ||
sqlsrv_free_stmt($stmt1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please dropTable at the end of the test
$cond = "(c1_int = $keyValue)"; | ||
|
||
$stmt3 = selectFromTableEx($conn1, $tableName, $cond); | ||
$cond = "(c1_int = ?)"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it a good idea to change the test to use a placeholder completely? Now even if isColEnc() is false, the test still uses sqlsrv_prepare with placeholder to run the query, whereas before is used to use sqlsrv_query on a direct query. When refactoring tests, we want to keep the behavior of the original test as intact as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided to put the logic in AE\executeQuery() instead so that each placeholder will be replaced with literal value if not encrypted
createTableEx($conn1, $tableName, $dataType); | ||
|
||
$columns = array(new AE\ColumnMeta('int', 'c1'), | ||
new AE\ColumnMeta('int', 'c2')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where is createTable?
} else { // should check data even if $fld is null | ||
$data = getInsertData($startRow + $i, $col, $skipCount); | ||
if (!CheckData($col, $fld, $data)) { | ||
$data = AE\getInsertData($startRow + $i, $col); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how come you getInsertData before checking if $col isUpdatable?
Can you also explain what $skipCount does and why you got rid of it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only the timestamp column (column 27) is updatable, and the original way to look for insert data is to skip this column. I'll explain more if this is unclear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK I'm beginning to understand what $skipCount is for now. But I still don't understand why you have getInsertData in line 47. There is an identical line in line 50, and $data is only used inside the isUpdatable if block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it was an oversight. Thanks!
if (sqlsrv_next_result($stmt1) || | ||
sqlsrv_next_result($stmt2)) { | ||
if ($r1 = sqlsrv_next_result($stmt1) || | ||
$r2 = sqlsrv_next_result($stmt2)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do you need to introduce $r1 and $r2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was for debugging when I thought I discovered a bug... forgot to remove them afterwards ;)
AE\insertRow($conn1, | ||
$tableName, | ||
array("c1"=>$k, "c2"=>array($data, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR), $phpDriverType)), | ||
$res, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you just put null here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just tried to be faithful to the original test, in which it called a function insertRowEx() that does the following:
$stmt = sqlsrv_query($conn, "INSERT INTO [$tableName] ($dataCols) VALUES ($dataValues)", $dataOptions);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?? I was talking about $res
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope... I will get the error Fatal error: Uncaught Error: Cannot pass parameter 4 by reference
|
||
sqlsrv_close($conn1); | ||
|
||
endTest($testName); | ||
} | ||
|
||
function CreateQueryTable($conn, $table, $dataType, $dataCols, $dataValues, $dataOptions, $execMode) | ||
function insertQueryTable($conn, $tableName, $params, $execMode) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you not use insertRow for this function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no because it's specific to this test, in which they set the option SendStreamParamsAtExec
on and off for testing
break; | ||
} | ||
if ($data != null) { | ||
$sqlType = GetSqlType($k); | ||
$sqlType = getSqlType($k); | ||
$driverType = getDriverType($k); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the name of this function is very misleading. I thought getDriverType gets the PHP zend type... can you change the name of this to getSqlsrvSqltype() or something more clear?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that it's confusing, but that was one of the common functions originally in MsCommon... I'll see how many tests are affected by the renaming.
@@ -74,40 +74,50 @@ function ProcQuery($minType, $maxType) | |||
endTest($testName); | |||
} | |||
|
|||
function ExecProcQuery($conn, $procName, $dataType, $inData1, $inData2, $outData) | |||
function execprocQuery($conn, $procName, $type, $dataType, $inData1, $inData2, $outData) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
execProcQuery
{ | ||
include 'MsSetup.inc'; | ||
// include 'MsSetup.inc'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
delete this line
$s = sqlsrv_query($conn1, "DROP TABLE test_bq"); | ||
$s = sqlsrv_query($conn1, "CREATE TABLE test_bq (id INT IDENTITY NOT NULL, test_varchar_max varchar(max))"); | ||
$tableName = "test_bq"; | ||
dropTable($conn1, $tableName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think createTable already drop the table before creating the table, so this line is not necessary.
test/functional/sqlsrv/MsHelper.inc
Outdated
$this->dataType = $dataType; | ||
$this->options = $options; | ||
|
||
// first asssumes the column is not encryptable | ||
// $this->encryptable = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please get rid of comments
test/functional/sqlsrv/MsHelper.inc
Outdated
// when AE is enabled, use sqlsrv_prepare() to handle fields with unlimited size | ||
if (!isColEncrypted() && (is_null($conds) || empty($values))) { | ||
if (!isColEncrypted()) { | ||
if (!empty($values)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add a comment saying this if block is for replacing '?' placeholders with values
Mainly the tests using a test table with 28 data types
This change is