diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b78e5999..0db098013 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,37 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) +## Windows/Linux/MAC 4.1.7-preview - 2017-03-07 +Updated PECL release packages. Here is the list of updates: +### Added +- The early technical preview (ETP) for SQLSRV and PDO_SQLSRV drivers for MAC with basic functionalities is now available. Both drivers has been built and tested on MAC OS version El Capitan (OS X 10.11). + +### Fixed +#### SQLSRV and PDO_SQLSRV +- Fixed null returned when an empty string is set to an output parameter ([issue #308](https://github.com/Microsoft/msphpsql/issues/308)). +- Fixed memory leaks in buffered result sets. +- Fixed clang compile errors. + +#### SQLSRV only +- Fixed debug abort error when building the driver in debug mode with PHP 7.1. +- Fixed string truncation when binding varchar(max), nvarchar(max), varbinary(max), and xml types ([issue #231](https://github.com/Microsoft/msphpsql/issues/231)). +- Fixed fatal error when fetching empty nvarchar ([issue #69](https://github.com/Microsoft/msphpsql/issues/69)). +- Fixed fatal error when calling sqlsrv_fetch() with an out of bound offset for SQLSRV_SCROLL_ABSOLUTE ([issue #223](https://github.com/Microsoft/msphpsql/issues/223)). + +#### PDO_SQLSRV only +- Fixed wrong value returned when fetching varbinary value on Linux ([issue #270](https://github.com/Microsoft/msphpsql/issues/270)). +- Fixed binary data not returned when the column is bound by name ([issue #35](https://github.com/Microsoft/msphpsql/issues/35)). +- Fixed exception thrown on closeCursor() when the statement has not been executed ([issue #267](https://github.com/Microsoft/msphpsql/issues/267)). + +### Known Issues +- User defined data types and SQL_VARIANT ([issue #127](https://github.com/Microsoft/msphpsql/issues/127)). +- Binary column binding with emulate prepare ([issue #140](https://github.com/Microsoft/msphpsql/issues/140)). +- Segmentation fault may result when an unsupported attribute is used for connection. + +#### MAC only +- If loading both sqlsrv and pdo_sqlsrv, the order matters (even when dynamically). For PDO_SQLSRV scripts, load pdo_sqlsrv.so first. For SQLSRV scripts, load sqlsrv.so first. +- Connection pooling not working. + ## Windows/Linux 4.1.6 - 2017-02-03 Updated PECL release packages. Here is the list of updates: ### Added @@ -61,7 +92,7 @@ Linux drivers compiled with PHP 7.0.13 are available for Ubuntu 15.04, Ubuntu 16 ### Changed - Code structure is updated to facilitate the development; shared codes between both drivers are moved to "shared" folder to avoid code duplication issues in development. To build the driver from source, use "packagize" script as follows: - - if you are using the phpize, clone or download the source, run the script within the source directory and then run phpize. + - if you are using the phpize, clone or download the “source”, run the script within the “source” directory and then run phpize. - if you are building the driver from source using PHP source, give the path to the PHP source to the script. ### Fixed diff --git a/README.md b/README.md index 48529b131..f9d15705c 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,14 @@ This release contains the SQLSRV and PDO_SQLSRV drivers for PHP 7 with improveme SQL Server Team -##Take our survey + +## Take our survey Thank you for taking time to take our Febraury survey. Let us know how we are doing and how you use PHP by taking our March pulse survey: - -###Status of Most Recent Builds +### Status of Most Recent Builds | AppVeyor (Windows) |Travis CI (Linux) | Coverage Status |-------------------------|--------------------------| ------------------ | [![av-image][]][av-site]| [![tv-image][]][tv-site] |[![Coverage Status][]][coveralls-site] @@ -27,16 +27,17 @@ Thank you for taking time to take our Febraury survey. Let us know how we are do [Coverage Status]: https://coveralls.io/repos/github/Microsoft/msphpsql/badge.svg?branch=dev [coveralls-site]: https://coveralls.io/github/Microsoft/msphpsql?branch=dev -##Get Started +## Get Started * [**Ubuntu + SQL Server + PHP 7**](https://www.microsoft.com/en-us/sql-server/developer-get-started/php-ubuntu) * [**RedHat + SQL Server + PHP 7**](https://www.microsoft.com/en-us/sql-server/developer-get-started/php-rhel) * [**Windows + SQL Server + PHP 7**](https://www.microsoft.com/en-us/sql-server/developer-get-started/php-windows) * [**Docker**](https://hub.docker.com/r/lbosqmsft/mssql-php-msphpsql/) -##Announcements -**December 19, 2016**: We are delighted announce that production release for PHP Linux Driver for SQL Server is available. PECL packages (4.0.8) are updated with the latest changes, and Linux binaries (4.0.8) compiled with PHP 7.0.14 are available for Ubuntu 15.04, Ubuntu 16.04, and RedHat 7.2. For complete list of changes please visit [CHANGELOG](https://github.com/Microsoft/msphpsql/blob/dev/CHANGELOG.md) file. +## Announcements + +**March 7, 2017**: We are trilled to announce that the early technical preview for SQLSRV and PDO_SQLSRV drivers is now available, both drivers have been built and tested on El Capitan (OS X 10.11). For complete list of changes please visit [4.1.7-preview release notes](https://github.com/Microsoft/msphpsql/releases/tag/v4.1.7-preview). Please visit the [blog][blog] for more announcements. @@ -45,11 +46,11 @@ Thank you for taking time to take our Febraury survey. Let us know how we are do Note: if you prefer, you can use the pre-compiled binary found [HERE](https://github.com/Azure/msphpsql/releases) -####Prerequisites +#### Prerequisites You must first be able to build PHP 7 without including these extensions. For help with doing this, see the [official PHP website][phpbuild] for building your own PHP on Windows. -####Compile the drivers +#### Compile the drivers 1. Copy the sqlsrv and/or pdo_sqlsrv source code directory from this repository into the ext subdirectory. @@ -67,12 +68,12 @@ This software has been compiled and tested under PHP 7.0.8 using the Visual C++ ## Install (Windows) -####Prerequisites +#### Prerequisites - A Web server such as Internet Information Services (IIS) is required. Your Web server must be configured to run PHP - [Microsoft ODBC Driver 11][odbc11] or [Microsoft ODBC Driver 13][odbc13] -####Enable the drivers +#### Enable the drivers 1. Make sure that the driver is in your PHP extension directory (you can simply copy it there if you did not use nmake install). @@ -80,10 +81,10 @@ This software has been compiled and tested under PHP 7.0.8 using the Visual C++ 3. Restart the Web server. -## Install (Linux) -Following instructions shows how to install PHP 7.x, Microsoft ODBC driver, apache, and Microsoft PHP drivers on Ubuntu 15, 16 and RedHat 7. To see how to get PHP SQLSRV drivers running on Debian, please visit [Wiki](https://github.com/Microsoft/msphpsql/wiki/Dockerfile-for-getting-pdo_sqlsrv-for-PHP-7.0-on-Debian-in-3-ways). Note that Debian is not officially supported and this instruction hasn't been tested in our test lab. +## Install (UNIX) +Following instructions shows how to install PHP 7.x, Microsoft ODBC driver, apache, and Microsoft PHP drivers on Ubuntu 15, 16, RedHat 7 and Mac OS X. To see how to get PHP SQLSRV drivers running on Debian, please visit [Wiki](https://github.com/Microsoft/msphpsql/wiki/Dockerfile-for-getting-pdo_sqlsrv-for-PHP-7.0-on-Debian-in-3-ways). Note that Debian is not officially supported and this instruction hasn't been tested in our test lab. -### Step 1: Install PHP (unless already installed) +### Step 1: Install PHP7 (unless already installed) #### PHP 7.0 @@ -113,6 +114,17 @@ Following instructions shows how to install PHP 7.x, Microsoft ODBC driver, apac yum update yum install php php-pdo php-xml php-pear php-devel re2c gcc-c++ gcc +**Mac OS X** + + /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" + brew tap + brew tap homebrew/dupes + brew tap homebrew/versions + brew tap homebrew/homebrew-php + brew install php70 --with-pear --with-httpd24 --with-cgi + echo 'export PATH="/usr/local/sbin:$PATH"' >> ~/.bash_profile + echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile +*Note: Restart the terminal if PHP(`php -v`) is not updated. #### PHP 7.1 @@ -123,7 +135,7 @@ Following instructions shows how to install PHP 7.x, Microsoft ODBC driver, apac sudo su add-apt-repository ppa:ondrej/php apt-get update - apt-get -y install php7.1 mcrypt php7.1-mcrypt php-mbstring php-pear php7.1-dev + apt-get -y install php7.1 mcrypt php7.1-mcrypt php-mbstring php-pear php7.1-dev php7.1-xml **RedHat 7** @@ -135,6 +147,19 @@ Following instructions shows how to install PHP 7.x, Microsoft ODBC driver, apac yum-config-manager --enable remi-php71 yum update yum install php php-pdo php-xml php-pear php-devel + +**Mac OS X** + + /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" + brew tap + brew tap homebrew/dupes + brew tap homebrew/versions + brew tap homebrew/homebrew-php + brew install php71 --with-pear --with-httpd24 --with-cgi + echo 'export PATH="/usr/local/sbin:$PATH"' >> ~/.bash_profile + echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile +*Note: Restart the terminal if PHP(`php -v`) is not updated. + ### Step 2: Install pre-requisites @@ -178,15 +203,21 @@ Following instructions shows how to install PHP 7.x, Microsoft ODBC driver, apac echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc source ~/.bashrc + +**Mac OS X** + brew tap microsoft/msodbcsql https://github.com/Microsoft/homebrew-msodbcsql + brew update + brew install unixodbc + brew install msodbcsql + brew install llvm --with-clang --with-clang-extra-tools + brew install autoconf - - -*Note: On Ubuntu, you need to make sure you install PHP 7 before you proceed to step 2. The Microsoft PHP Drivers for SQL Server will only work for PHP 7+. +*Note: You need to make sure you install PHP 7 before you proceed to step 3. The Microsoft PHP Drivers for SQL Server will only work for PHP 7+. ### Step 3: Install Apache -####PHP 7.0 +#### PHP 7.0 **Ubuntu** @@ -197,65 +228,36 @@ Following instructions shows how to install PHP 7.x, Microsoft ODBC driver, apac sudo yum install httpd -####PHP 7.1 +**Mac OS X** + + (echo ""; echo "SetHandler application/x-httpd-php"; echo "";) >> /usr/local/etc/apache2/2.4/httpd.conf + +#### PHP 7.1 **Ubuntu** - sudo apt-get install libapache2-mod-php7.1 - sudo apt-get install apache2 + sudo apt-get install libapache2-mod-php7.1 + sudo apt-get install apache2 **RedHat** sudo yum install httpd + +**Mac OS X** + + (echo ""; echo "SetHandler application/x-httpd-php"; echo "";) >> /usr/local/etc/apache2/2.4/httpd.conf ### Step 4: Install the Microsoft PHP Drivers for SQL Server + sudo pear config-set php_ini `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"` system sudo pecl install sqlsrv sudo pecl install pdo_sqlsrv -*Note: it installs the stable version, for specific version you should set the version. For example, `sudo pecl install sqlsrv-4.0.8` - - -### Step 5: Add the Microsoft PHP Drivers for SQL Server to php.ini - - -####PHP 7.0 - -**Ubuntu** +*Note: it installs the stable version, for specific version you should set the version. For example, do `sudo pecl search sqlsrv` to search for the latest releases and `sudo pecl install sqlsrv-[version]` to install a specific version. +Drivers are Mac-compatible starting from 4.1.7preview release. . - echo "extension=/usr/lib/php/20151012/sqlsrv.so" >> /etc/php/7.0/apache2/php.ini - echo "extension=/usr/lib/php/20151012/pdo_sqlsrv.so" >> /etc/php/7.0/apache2/php.ini - echo "extension=/usr/lib/php/20151012/sqlsrv.so" >> /etc/php/7.0/cli/php.ini - echo "extension=/usr/lib/php/20151012/pdo_sqlsrv.so" >> /etc/php/7.0/cli/php.ini - - -**RedHat** - - echo "extension= /usr/lib64/php/modules/sqlsrv.so" > /etc/php.d/sqlsrv.ini - echo "extension= /usr/lib64/php/modules/pdo_sqlsrv.so" > /etc/php.d/pdo_sqlsrv.ini - - -####PHP 7.1 - - -**Ubuntu 16.04** - - echo "extension=/usr/lib/php/20160303/sqlsrv.so" >> /etc/php/7.1/apache2/php.ini - echo "extension=/usr/lib/php/20160303/pdo_sqlsrv.so" >> /etc/php/7.1/apache2/php.ini - echo "extension=/usr/lib/php/20160303/sqlsrv.so" >> /etc/php/7.1/cli/php.ini - echo "extension=/usr/lib/php/20160303/pdo_sqlsrv.so" >> /etc/php/7.1/cli/php.ini - - - -**RedHat** - - echo "extension= /usr/lib64/php/modules/sqlsrv.so" > /etc/php.d/sqlsrv.ini - echo "extension= /usr/lib64/php/modules/pdo_sqlsrv.so" > /etc/php.d/pdo_sqlsrv.ini - - - -### Step 6: Restart Apache to load the new php.ini file +### Step 5: Restart Apache to load the new php.ini file **Ubuntu** @@ -264,9 +266,15 @@ Following instructions shows how to install PHP 7.x, Microsoft ODBC driver, apac **RedHat** sudo apachectl restart + +**Mac OS X** + + sudo apachectl restart + +*Note to RedHat users: SELinux is installed by default and runs in Enforcing mode. To allow Apache to connect to database through SELinux, do this `sudo setsebool -P httpd_can_network_connect_db 1` -### Step 7: Create your sample app -Navigate to `/var/www/html` and create a new file called testsql.php. Copy and paste the following code in tetsql.php and change the servername, username, password and databasename. +### Step 6: Create your sample app +Navigate to `/var/www/html` (`/usr/local/var/www/htdocs` on Mac) and create a new file called testsql.php. Copy and paste the following code in tetsql.php and change the servername, username, password and databasename. -### Step 8: Run your sample app +### Step 7: Run your sample app -Go to your browser and type in http://localhost/testsql.php +Go to your browser and type in http://localhost/testsql.php (http://localhost:8080/testsql.php on Mac) You should be able to connect to your SQL Server/Azure SQL Database. The drivers are distributed as shared binary extensions for PHP. They are available in thread safe (*_ts.so) and-non thread safe (*_nts.so) versions. The source code for the drivers is also available, and you can choose whether to compile them as thread safe or non-thread safe versions. The thread safety configuration of your web server will determine which version you need. @@ -331,11 +339,29 @@ For samples, please see the sample folder. For setup instructions, see [here] [ - Binary column binding with emulate prepare ([issue#140](https://github.com/Microsoft/msphpsql/issues/140) ) - Linux - The following features are not supported with connection pooling: + - PDO is only supported with unixODBC 2.3.1. - Unicode connection strings - sqlsrv_server_info and sqlsrv_client_info return false - In certain scenarios a generic error message maybe returned instead of a specific error when pooling is disabled - When retrieving data from columns with a data type of XML, varchar(max), nvarchar(max), or varbinary(max) no data maybe returned or the data maybe truncated depending on the length of the data in the source table. +## Version number +Version number of PHP drivers follow the [semantic versioning](http://semver.org/): + +Given a version number MAJOR.MINOR.PATCH, + + - MAJOR version is incremented when an incompatible API changes is made, + - MINOR version is incremented when a functionality in a backwards-compatible manner is added, and + - PATCH version is incremented when backwards-compatible bug fixes are made. + +version number MAY have trailing pre-release version to indicate the stability, and/or build meta data. + +- Pre-release version is denoted by hyphen followed by `preview` or `rc` keyword and may be followed by a series of dot separated identifiers. Production quality releases do not contain the pre-release version. `preview` has lower precedence than `rc`. Example of precedence: *preview < preview.1 < rc < rc.1*. +*Note that PECL package version does not have the hyphen before pre-release version, due to restrictions in PECL. Example of PECL package version: 1.2.3preview* +- Build metadata MAY be denoted by a plus sign followed by 4 digits, such as `1.2.3-preview+5678` or `1.2.3+5678`. Build meta data does NOT figure into the precedence order. + + + ## Future Plans - Expand SQL 16 Feature Support (example: Always Encrypted). - Build Verification/Fundamental Tests. diff --git a/appveyor.yml b/appveyor.yml index f45dc84d4..98edf7508 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -165,7 +165,11 @@ test_script: after_test: - cd %APPVEYOR_BUILD_FOLDER%\test\ - - python output.py + - python output.py + - ps: $files = Get-ChildItem sqlsrv\*.diff + - ps: foreach($file in $files){ls $file; more $file; more "$file.out"} + - ps: $files = Get-ChildItem pdo_sqlsrv\*.diff + - ps: foreach($file in $files){ls $file; more $file; more "$file.out"} - ps: (new-object net.webclient).UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\nativeresult1.xml)) - ps: (new-object net.webclient).UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\nativeresult2.xml)) - ps: >- diff --git a/source/pdo_sqlsrv/config.m4 b/source/pdo_sqlsrv/config.m4 index 411d405a1..2b310f920 100644 --- a/source/pdo_sqlsrv/config.m4 +++ b/source/pdo_sqlsrv/config.m4 @@ -1,68 +1,68 @@ -PHP_ARG_WITH(pdo_sqlsrv, for pdo_sqlsrv support, -[ --with-pdo_sqlsrv Include pdo_sqlsrv support]) - -if test "$PHP_PDO_SQLSRV" != "no"; then - if test "$PHP_PDO" = "no" && test "$ext_shared" = "no"; then - AC_MSG_ERROR([PDO is not enabled! Add --enable-pdo to your configure line.]) - fi - - ifdef([PHP_CHECK_PDO_INCLUDES], - [ - PHP_CHECK_PDO_INCLUDES - ],[ - AC_MSG_CHECKING([for PDO includes]) - if test -f $abs_srcdir/include/php/ext/pdo/php_pdo_driver.h; then - pdo_cv_inc_path=$abs_srcdir/ext - elif test -f $abs_srcdir/ext/pdo/php_pdo_driver.h; then - pdo_cv_inc_path=$abs_srcdir/ext - elif test -f $phpincludedir/ext/pdo/php_pdo_driver.h; then - pdo_cv_inc_path=$phpincludedir/ext - else - AC_MSG_ERROR([Cannot find php_pdo_driver.h.]) - fi - AC_MSG_RESULT($pdo_cv_inc_path) - ]) - - pdo_sqlsrv_src_class="\ - pdo_dbh.cpp \ - pdo_parser.cpp \ - pdo_util.cpp \ - pdo_init.cpp \ - pdo_stmt.cpp \ - " - - shared_src_class="\ - shared/core_conn.cpp \ - shared/core_results.cpp \ - shared/core_stream.cpp \ - shared/core_init.cpp \ - shared/core_stmt.cpp \ - shared/core_util.cpp \ - shared/FormattedPrint.cpp \ - shared/localizationimpl.cpp \ - shared/StringFunctions.cpp \ - " - AC_MSG_CHECKING([for PDO_SQLSRV headers]) - if test -f $srcdir/ext/pdo_sqlsrv/shared/core_sqlsrv.h; then - pdo_sqlsrv_inc_path=$srcdir/ext/pdo_sqlsrv/shared/ - elif test -f $srcdir/shared/core_sqlsrv.h; then - pdo_sqlsrv_inc_path=$srcdir/shared/ - else - AC_MSG_ERROR([Cannot find PDO_SQLSRV headers]) - fi - AC_MSG_RESULT($pdo_sqlsrv_inc_path) - - - CXXFLAGS="$CXXFLAGS -std=c++11" - PHP_REQUIRE_CXX() - PHP_ADD_LIBRARY(stdc++, 1, PDO_SQLSRV_SHARED_LIBADD) - PHP_ADD_LIBRARY(odbc, 1, PDO_SQLSRV_SHARED_LIBADD) - PHP_ADD_LIBRARY(odbcinst, 1, PDO_SQLSRV_SHARED_LIBADD) - AC_DEFINE(HAVE_PDO_SQLSRV, 1, [ ]) - PHP_ADD_INCLUDE([$pdo_sqlsrv_inc_path]) - PHP_NEW_EXTENSION(pdo_sqlsrv, $pdo_sqlsrv_src_class $shared_src_class, $ext_shared,,-I$pdo_cv_inc_path -std=c++11) - PHP_SUBST(PDO_SQLSRV_SHARED_LIBADD) - PHP_ADD_EXTENSION_DEP(pdo_sqlsrv, pdo) - PHP_ADD_BUILD_DIR([$ext_builddir/shared], 1) -fi - +PHP_ARG_WITH(pdo_sqlsrv, for pdo_sqlsrv support, +[ --with-pdo_sqlsrv Include pdo_sqlsrv support]) + +if test "$PHP_PDO_SQLSRV" != "no"; then + if test "$PHP_PDO" = "no" && test "$ext_shared" = "no"; then + AC_MSG_ERROR([PDO is not enabled! Add --enable-pdo to your configure line.]) + fi + + ifdef([PHP_CHECK_PDO_INCLUDES], + [ + PHP_CHECK_PDO_INCLUDES + ],[ + AC_MSG_CHECKING([for PDO includes]) + if test -f $abs_srcdir/include/php/ext/pdo/php_pdo_driver.h; then + pdo_cv_inc_path=$abs_srcdir/ext + elif test -f $abs_srcdir/ext/pdo/php_pdo_driver.h; then + pdo_cv_inc_path=$abs_srcdir/ext + elif test -f $phpincludedir/ext/pdo/php_pdo_driver.h; then + pdo_cv_inc_path=$phpincludedir/ext + else + AC_MSG_ERROR([Cannot find php_pdo_driver.h.]) + fi + AC_MSG_RESULT($pdo_cv_inc_path) + ]) + + pdo_sqlsrv_src_class="\ + pdo_dbh.cpp \ + pdo_parser.cpp \ + pdo_util.cpp \ + pdo_init.cpp \ + pdo_stmt.cpp \ + " + + shared_src_class="\ + shared/core_conn.cpp \ + shared/core_results.cpp \ + shared/core_stream.cpp \ + shared/core_init.cpp \ + shared/core_stmt.cpp \ + shared/core_util.cpp \ + shared/FormattedPrint.cpp \ + shared/localizationimpl.cpp \ + shared/StringFunctions.cpp \ + " + AC_MSG_CHECKING([for PDO_SQLSRV headers]) + if test -f $srcdir/ext/pdo_sqlsrv/shared/core_sqlsrv.h; then + pdo_sqlsrv_inc_path=$srcdir/ext/pdo_sqlsrv/shared/ + elif test -f $srcdir/shared/core_sqlsrv.h; then + pdo_sqlsrv_inc_path=$srcdir/shared/ + else + AC_MSG_ERROR([Cannot find PDO_SQLSRV headers]) + fi + AC_MSG_RESULT($pdo_sqlsrv_inc_path) + + + CXXFLAGS="$CXXFLAGS -std=c++11" + PHP_REQUIRE_CXX() + PHP_ADD_LIBRARY(stdc++, 1, PDO_SQLSRV_SHARED_LIBADD) + PHP_ADD_LIBRARY(odbc, 1, PDO_SQLSRV_SHARED_LIBADD) + PHP_ADD_LIBRARY(odbcinst, 1, PDO_SQLSRV_SHARED_LIBADD) + AC_DEFINE(HAVE_PDO_SQLSRV, 1, [ ]) + PHP_ADD_INCLUDE([$pdo_sqlsrv_inc_path]) + PHP_NEW_EXTENSION(pdo_sqlsrv, $pdo_sqlsrv_src_class $shared_src_class, $ext_shared,,-I$pdo_cv_inc_path -std=c++11) + PHP_SUBST(PDO_SQLSRV_SHARED_LIBADD) + PHP_ADD_EXTENSION_DEP(pdo_sqlsrv, pdo) + PHP_ADD_BUILD_DIR([$ext_builddir/shared], 1) +fi + diff --git a/source/pdo_sqlsrv/pdo_stmt.cpp b/source/pdo_sqlsrv/pdo_stmt.cpp index ff92c6d47..2506960bf 100644 --- a/source/pdo_sqlsrv/pdo_stmt.cpp +++ b/source/pdo_sqlsrv/pdo_stmt.cpp @@ -393,17 +393,20 @@ int pdo_sqlsrv_stmt_close_cursor(pdo_stmt_t *stmt TSRMLS_DC) try { - SQLSRV_ASSERT( stmt != NULL, "pdo_sqlsrv_stmt_next_rowset: pdo_stmt object was null" ); + SQLSRV_ASSERT( stmt != NULL, "pdo_sqlsrv_stmt_close_cursor: pdo_stmt object was null" ); sqlsrv_stmt* driver_stmt = reinterpret_cast( stmt->driver_data ); - SQLSRV_ASSERT( driver_stmt != NULL, "pdo_sqlsrv_stmt_next_rowset: driver_data object was null" ); + SQLSRV_ASSERT( driver_stmt != NULL, "pdo_sqlsrv_stmt_close_cursor: driver_data object was null" ); // to "close the cursor" means we make the statement ready for execution again. To do this, we // skip all the result sets on the current statement. - while( driver_stmt->past_next_result_end == false ) { - - core_sqlsrv_next_result( driver_stmt TSRMLS_CC ); + // If the statement has not been executed there are no next results to iterate over. + if ( driver_stmt->executed == true ) + { + while( driver_stmt->past_next_result_end == false ) { + core_sqlsrv_next_result( driver_stmt TSRMLS_CC ); + } } } catch( core::CoreException& ) { @@ -412,7 +415,7 @@ int pdo_sqlsrv_stmt_close_cursor(pdo_stmt_t *stmt TSRMLS_DC) } catch( ... ) { - DIE( "pdo_sqlsrv_stmt_next_rowset: Unknown exception occurred while advanding to the next result set." ); + DIE( "pdo_sqlsrv_stmt_close_cursor: Unknown exception occurred while advancing to the next result set." ); } return 1; @@ -718,12 +721,10 @@ int pdo_sqlsrv_stmt_get_col_data(pdo_stmt_t *stmt, int colno, sqlsrv_phptype sqlsrv_php_type; SQLSRV_ASSERT( colno >= 0 && colno < static_cast( driver_stmt->current_meta_data.size()), "Invalid column number in pdo_sqlsrv_stmt_get_col_data" ); - sqlsrv_php_type = driver_stmt->sql_type_to_php_type( static_cast( driver_stmt->current_meta_data[ colno ]->field_type ), - static_cast( driver_stmt->current_meta_data[ colno ]->field_size ), - true ); // set the encoding if the user specified one via bindColumn, otherwise use the statement's encoding - sqlsrv_php_type.typeinfo.encoding = driver_stmt->encoding(); + sqlsrv_php_type = driver_stmt->sql_type_to_php_type( static_cast( driver_stmt->current_meta_data[colno]->field_type ), + static_cast( driver_stmt->current_meta_data[colno]->field_size ), true ); // if a column is bound to a type different than the column type, figure out a way to convert it to the // type they want @@ -735,6 +736,10 @@ int pdo_sqlsrv_stmt_get_col_data(pdo_stmt_t *stmt, int colno, pdo_bound_param_data* bind_data = NULL; bind_data = reinterpret_cast(zend_hash_index_find_ptr(stmt->bound_columns, colno)); + if (bind_data == NULL) { + // can't find by index then try searching by name + bind_data = reinterpret_cast(zend_hash_find_ptr(stmt->bound_columns, stmt->columns[colno].name)); + } if( bind_data != NULL && !Z_ISUNDEF(bind_data->driver_params) ) { @@ -1299,6 +1304,8 @@ sqlsrv_phptype pdo_sqlsrv_stmt::sql_type_to_php_type( SQLINTEGER sql_type, SQLUI "Invalid encoding on the connection. Must not be invalid or default." ); } + sqlsrv_phptype.typeinfo.encoding = local_encoding; + switch( sql_type ) { case SQL_BIT: case SQL_INTEGER: @@ -1309,7 +1316,6 @@ sqlsrv_phptype pdo_sqlsrv_stmt::sql_type_to_php_type( SQLINTEGER sql_type, SQLUI } else { sqlsrv_phptype.typeinfo.type = SQLSRV_PHPTYPE_STRING; - sqlsrv_phptype.typeinfo.encoding = local_encoding; } break; case SQL_FLOAT: @@ -1319,7 +1325,6 @@ sqlsrv_phptype pdo_sqlsrv_stmt::sql_type_to_php_type( SQLINTEGER sql_type, SQLUI } else { sqlsrv_phptype.typeinfo.type = SQLSRV_PHPTYPE_STRING; - sqlsrv_phptype.typeinfo.encoding = local_encoding; } break; case SQL_BIGINT: @@ -1338,7 +1343,6 @@ sqlsrv_phptype pdo_sqlsrv_stmt::sql_type_to_php_type( SQLINTEGER sql_type, SQLUI case SQL_WLONGVARCHAR: case SQL_SS_XML: sqlsrv_phptype.typeinfo.type = SQLSRV_PHPTYPE_STRING; - sqlsrv_phptype.typeinfo.encoding = local_encoding; break; case SQL_BINARY: case SQL_LONGVARBINARY: diff --git a/source/pdo_sqlsrv/template.rc b/source/pdo_sqlsrv/template.rc index d36cd82fb..285762db5 100644 --- a/source/pdo_sqlsrv/template.rc +++ b/source/pdo_sqlsrv/template.rc @@ -43,8 +43,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US //Version VS_VERSION_INFO VERSIONINFO - FILEVERSION SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_RELEASE, SQLVERSION_BUILD - PRODUCTVERSION SQLVERSION_MAJOR,SQLVERSION_MINOR,SQLVERSION_RELEASE,0 + FILEVERSION SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_PATCH, SQLVERSION_BUILD + PRODUCTVERSION SQLVERSION_MAJOR,SQLVERSION_MINOR,SQLVERSION_PATCH,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS VS_FF_DEBUG @@ -62,12 +62,12 @@ BEGIN VALUE "Comments", "This product includes PHP software that is freely available from http://www.php.net/software/. Copyright © 2001-2016 The PHP Group. All rights reserved.\0" VALUE "CompanyName", "Microsoft Corp.\0" VALUE "FileDescription", "Microsoft Drivers for PHP for SQL Server (PDO Driver)\0" - VALUE "FileVersion", STRVER4(SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_RELEASE, SQLVERSION_BUILD) + VALUE "FileVersion", STRVER4(SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_PATCH, SQLVERSION_BUILD) VALUE "InternalName", FILE_NAME "\0" VALUE "LegalCopyright", "Copyright Microsoft Corporation.\0" VALUE "OriginalFilename", FILE_NAME "\0" VALUE "ProductName", "Microsoft Drivers for PHP for SQL Server\0" - VALUE "ProductVersion", STRVER3(SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_RELEASE) + VALUE "ProductVersion", STRVER3(SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_PATCH) VALUE "URL", "http://www.microsoft.com\0" END END diff --git a/source/shared/core_results.cpp b/source/shared/core_results.cpp index 1f1593a2a..fd7209610 100644 --- a/source/shared/core_results.cpp +++ b/source/shared/core_results.cpp @@ -25,7 +25,6 @@ #ifndef _WIN32 #include -#include #endif // !_WIN32 @@ -210,21 +209,20 @@ SQLRETURN number_to_string( Number* number_data, _Out_ void* buffer, SQLLEN buff if ( std::is_same::value ) { - std::basic_string str; - char *str_num_ptr = &str_num[0], *str_num_end = &str_num[0] + str_num.size(); - for ( const auto &mb : str_num ) + std::basic_string str; + + for (const auto &mb : str_num ) { - char16_t ch16; - std::mbstate_t mbs = std::mbstate_t(); - - int len = mbrtoc16( &ch16, &mb, str_num_end - str_num_ptr, &mbs ); - if ( len > 0 || len == -3 ) + size_t cch = SystemLocale::NextChar( CP_ACP, &mb ) - &mb; + if ( cch > 0 ) { - str.push_back( ch16 ); - if ( len > 0 ) + WCHAR ch16; + DWORD rc; + size_t cchActual = SystemLocale::ToUtf16( CP_ACP, &mb, cch, &ch16, 1, &rc); + if (cchActual > 0) { - str_num_ptr += len; + str.push_back ( ch16 ); } } } @@ -238,6 +236,39 @@ SQLRETURN number_to_string( Number* number_data, _Out_ void* buffer, SQLLEN buff } +#ifndef _WIN32 + + +std::string getUTF8StringFromString( const SQLWCHAR* source ) +{ + // convert to regular character string first + char c_str[4] = ""; + mbstate_t mbs; + + SQLLEN i = 0; + std::string str; + while ( source[i] ) + { + memset( c_str, 0, sizeof( c_str ) ); + DWORD rc; + int cch = 0; + errno_t err = mplat_wctomb_s( &cch, c_str, sizeof( c_str ), source[i++] ); + if ( cch > 0 && err == ERROR_SUCCESS ) + { + str.append( std::string( c_str, cch ) ); + } + } + return str; +} + + +std::string getUTF8StringFromString( const char* source ) +{ + return std::string( source ); +} + +#endif // !_WIN32 + template SQLRETURN string_to_number( Char* string_data, SQLLEN str_len, _Out_ void* buffer, SQLLEN buffer_length, _Out_ SQLLEN* out_buffer_length, sqlsrv_error_auto_ptr& last_error ) @@ -259,32 +290,13 @@ SQLRETURN string_to_number( Char* string_data, SQLLEN str_len, _Out_ void* buffe *out_buffer_length = sizeof( Number ); #else - std::string str; - if ( std::is_same::value ) - { - // convert to regular character string first - char c_str[3] = ""; - mbstate_t mbs; - - SQLLEN i = 0; - while ( string_data[i] ) - { - memset( &mbs, 0, sizeof( mbs )); //set shift state to the initial state - memset( c_str, 0, sizeof( c_str )); - int len = c16rtomb( c_str, string_data[i++], &mbs ); // treat string_data as a char16_t string - str.append(std::string( c_str, len )); - } - } - else - { - str.append( std::string(( char * )string_data )); - } + std::string str = getUTF8StringFromString( string_data ); std::istringstream is( str ); std::locale loc; // default locale should match system is.imbue( loc ); - auto& facet = std::use_facet>( is.getloc()); + auto& facet = std::use_facet>( is.getloc() ); std::istreambuf_iterator beg( is ), end; std::ios_base::iostate err = std::ios_base::goodbit; @@ -428,15 +440,11 @@ sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( sqlsrv_stmt* stmt TSRMLS sqlsrv_result_set( stmt ), cache(NULL), col_count(0), - meta(NULL), current(0), last_field_index(-1), read_so_far(0), temp_length(0) { - // 10 is an arbitrary number for now for the initial size of the cache - ALLOC_HASHTABLE( cache ); - core::sqlsrv_zend_hash_init( *stmt, cache, 10 /* # of buckets */, cache_row_dtor /*dtor*/, 0 /*persistent*/ TSRMLS_CC ); col_count = core::SQLNumResultCols( stmt TSRMLS_CC ); // there is no result set to buffer if( col_count == 0 ) { @@ -650,87 +658,104 @@ sqlsrv_buffered_result_set::sqlsrv_buffered_result_set( sqlsrv_stmt* stmt TSRMLS // (offset from the above loop has the size of the row buffer necessary) zend_long mem_used = 0; size_t row_count = 0; + // 10 is an arbitrary number for now for the initial size of the cache + ALLOC_HASHTABLE( cache ); + core::sqlsrv_zend_hash_init( *stmt, cache, 10 /* # of buckets */, cache_row_dtor /*dtor*/, 0 /*persistent*/ TSRMLS_CC ); - while( core::SQLFetchScroll( stmt, SQL_FETCH_NEXT, 0 TSRMLS_CC ) != SQL_NO_DATA ) { - - // allocate the row buffer - unsigned char* row = static_cast( sqlsrv_malloc( offset )); - memset( row, 0, offset ); - - // read the fields into the row buffer - for( SQLSMALLINT i = 0; i < col_count; ++i ) { - - SQLLEN out_buffer_temp = SQL_NULL_DATA; - SQLPOINTER buffer; - SQLLEN* out_buffer_length = &out_buffer_temp; - - switch( meta[i].c_type ) { - - case SQL_C_CHAR: - case SQL_C_WCHAR: - case SQL_C_BINARY: - if( meta[i].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) { - - out_buffer_length = &out_buffer_temp; - SQLPOINTER* lob_addr = reinterpret_cast( &row[ meta[i].offset ] ); - *lob_addr = read_lob_field( stmt, i, meta[i], mem_used TSRMLS_CC ); - // a NULL pointer means NULL field - if( *lob_addr == NULL ) { - *out_buffer_length = SQL_NULL_DATA; + try { + while( core::SQLFetchScroll( stmt, SQL_FETCH_NEXT, 0 TSRMLS_CC ) != SQL_NO_DATA ) { + + // allocate the row buffer + sqlsrv_malloc_auto_ptr rowAuto; + rowAuto = static_cast( sqlsrv_malloc( offset )); + unsigned char* row = rowAuto.get(); + memset( row, 0, offset ); + + // read the fields into the row buffer + for( SQLSMALLINT i = 0; i < col_count; ++i ) { + + SQLLEN out_buffer_temp = SQL_NULL_DATA; + SQLPOINTER buffer; + SQLLEN* out_buffer_length = &out_buffer_temp; + + switch( meta[i].c_type ) { + + case SQL_C_CHAR: + case SQL_C_WCHAR: + case SQL_C_BINARY: + if( meta[i].length == sqlsrv_buffered_result_set::meta_data::SIZE_UNKNOWN ) { + + out_buffer_length = &out_buffer_temp; + SQLPOINTER* lob_addr = reinterpret_cast( &row[ meta[i].offset ] ); + *lob_addr = read_lob_field( stmt, i, meta[i], mem_used TSRMLS_CC ); + // a NULL pointer means NULL field + if( *lob_addr == NULL ) { + *out_buffer_length = SQL_NULL_DATA; + } + else { + *out_buffer_length = **reinterpret_cast( lob_addr ); + mem_used += *out_buffer_length; + } } else { - *out_buffer_length = **reinterpret_cast( lob_addr ); - mem_used += *out_buffer_length; - } - } - else { - - mem_used += meta[i].length; - CHECK_CUSTOM_ERROR( mem_used > stmt->buffered_query_limit * 1024, stmt, - SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED, stmt->buffered_query_limit ) { - throw core::CoreException(); - } + mem_used += meta[i].length; + CHECK_CUSTOM_ERROR( mem_used > stmt->buffered_query_limit * 1024, stmt, + SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED, stmt->buffered_query_limit ) { - buffer = row + meta[i].offset + sizeof( SQLULEN ); - out_buffer_length = reinterpret_cast( row + meta[i].offset ); - core::SQLGetData( stmt, i + 1, meta[i].c_type, buffer, meta[i].length, out_buffer_length, - false TSRMLS_CC ); - } - break; + throw core::CoreException(); + } - case SQL_C_LONG: - case SQL_C_DOUBLE: - { - mem_used += meta[i].length; - CHECK_CUSTOM_ERROR( mem_used > stmt->buffered_query_limit * 1024, stmt, - SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED, stmt->buffered_query_limit ) { + buffer = row + meta[i].offset + sizeof( SQLULEN ); + out_buffer_length = reinterpret_cast( row + meta[i].offset ); + core::SQLGetData( stmt, i + 1, meta[i].c_type, buffer, meta[i].length, out_buffer_length, + false TSRMLS_CC ); + } + break; - throw core::CoreException(); + case SQL_C_LONG: + case SQL_C_DOUBLE: + { + mem_used += meta[i].length; + CHECK_CUSTOM_ERROR( mem_used > stmt->buffered_query_limit * 1024, stmt, + SQLSRV_ERROR_BUFFER_LIMIT_EXCEEDED, stmt->buffered_query_limit ) { + + throw core::CoreException(); + } + buffer = row + meta[i].offset; + out_buffer_length = &out_buffer_temp; + core::SQLGetData( stmt, i + 1, meta[i].c_type, buffer, meta[i].length, out_buffer_length, + false TSRMLS_CC ); } - buffer = row + meta[i].offset; - out_buffer_length = &out_buffer_temp; - core::SQLGetData( stmt, i + 1, meta[i].c_type, buffer, meta[i].length, out_buffer_length, - false TSRMLS_CC ); - } - break; + break; - default: - SQLSRV_ASSERT( false, "Unknown C type" ); - break; - } + default: + SQLSRV_ASSERT( false, "Unknown C type" ); + break; + } - row_count++; - if( *out_buffer_length == SQL_NULL_DATA ) { - set_bit( row, i ); + row_count++; + if( *out_buffer_length == SQL_NULL_DATA ) { + set_bit( row, i ); + } } - } - SQLSRV_ASSERT( row_count < INT_MAX, "Hard maximum of 2 billion rows exceeded in a buffered query" ); - - // add it to the cache - row_dtor_closure cl( this, row ); - sqlsrv_zend_hash_next_index_insert_mem( *stmt, cache, &cl, sizeof(row_dtor_closure) TSRMLS_CC ); + SQLSRV_ASSERT( row_count < INT_MAX, "Hard maximum of 2 billion rows exceeded in a buffered query" ); + + // add it to the cache + row_dtor_closure cl( this, row ); + sqlsrv_zend_hash_next_index_insert_mem( *stmt, cache, &cl, sizeof(row_dtor_closure) TSRMLS_CC ); + rowAuto.transferred(); + } + } + catch( core::CoreException& ) { + // free the rows + if( cache ) { + zend_hash_destroy( cache ); + FREE_HASHTABLE( cache ); + cache = NULL; + } + throw; } } @@ -743,12 +768,6 @@ sqlsrv_buffered_result_set::~sqlsrv_buffered_result_set( void ) FREE_HASHTABLE( cache ); cache = NULL; } - - // free the meta data - if( meta ) { - efree( meta ); - meta = NULL; - } } SQLRETURN sqlsrv_buffered_result_set::fetch( SQLSMALLINT orientation, SQLLEN offset TSRMLS_DC ) @@ -1351,6 +1370,11 @@ SQLRETURN sqlsrv_buffered_result_set::wide_to_system_string( SQLSMALLINT field_i field_data = &row[ meta[ field_index ].offset ] + sizeof( SQLULEN ) + read_so_far; } + if ( field_len == 0 ) { // empty string, no need for conversion + *out_buffer_length = 0; + return SQL_SUCCESS; + } + // allocate enough to handle WC -> DBCS conversion if it happens temp_string = reinterpret_cast( sqlsrv_malloc( field_len, sizeof(char), sizeof(char))); diff --git a/source/shared/core_sqlsrv.h b/source/shared/core_sqlsrv.h index 9b6c2d2de..55c0678b9 100644 --- a/source/shared/core_sqlsrv.h +++ b/source/shared/core_sqlsrv.h @@ -131,6 +131,11 @@ OACR_WARNING_POP #include #endif // _WIN32 +#if !defined(SQL_GUID) +// imported from sqlext.h +#define SQL_GUID (-11) +#endif + #if !defined(WC_ERR_INVALID_CHARS) // imported from winnls.h as it isn't included by 5.3.0 #define WC_ERR_INVALID_CHARS 0x00000080 // error for invalid chars @@ -1479,7 +1484,7 @@ struct sqlsrv_buffered_result_set : public sqlsrv_result_set { HashTable* cache; // rows of data kept in index based hash table SQLSMALLINT col_count; // number of columns in the current result set - meta_data* meta; // metadata for fields in the cache + sqlsrv_malloc_auto_ptr meta; // metadata for fields in the cache SQLLEN current; // 1 based, 0 means before first row sqlsrv_error_auto_ptr last_error; // if an error occurred, it is kept here SQLUSMALLINT last_field_index; // the last field data retrieved from diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index faa0c5235..9dd505ec6 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -208,7 +208,11 @@ void sqlsrv_stmt::new_result_set( TSRMLS_D ) // create a new result set if( cursor_type == SQLSRV_CURSOR_BUFFERED ) { - current_results = new (sqlsrv_malloc( sizeof( sqlsrv_buffered_result_set ))) sqlsrv_buffered_result_set( this TSRMLS_CC ); + sqlsrv_malloc_auto_ptr result; + result = reinterpret_cast ( sqlsrv_malloc( sizeof( sqlsrv_buffered_result_set ) ) ); + new ( result.get() ) sqlsrv_buffered_result_set( this TSRMLS_CC ); + current_results = result.get(); + result.transferred(); } else { current_results = new (sqlsrv_malloc( sizeof( sqlsrv_odbc_result_set ))) sqlsrv_odbc_result_set( this ); @@ -776,6 +780,7 @@ bool core_sqlsrv_fetch( sqlsrv_stmt* stmt, SQLSMALLINT fetch_orientation, SQLULE if( stmt->cursor_type == SQL_CURSOR_FORWARD_ONLY ) { stmt->past_fetch_end = true; } + stmt->fetch_called = false; // reset this flag return false; } @@ -2002,7 +2007,11 @@ void finalize_output_parameters( sqlsrv_stmt* stmt TSRMLS_DC ) // adjust the length of the string to the value returned by SQLBindParameter in the ind_ptr parameter char* str = Z_STRVAL_P( value_z ); SQLLEN str_len = stmt->param_ind_ptrs[ output_param->param_num ]; - if( str_len == SQL_NULL_DATA || str_len == 0 ) { + if( str_len == 0 ) { + core::sqlsrv_zval_stringl( value_z, "", 0 ); + continue; + } + if( str_len == SQL_NULL_DATA ) { zend_string_release( Z_STR_P( value_z )); ZVAL_NULL( value_z ); continue; @@ -2029,6 +2038,15 @@ void finalize_output_parameters( sqlsrv_stmt* stmt TSRMLS_DC ) 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); @@ -2410,16 +2428,20 @@ void resize_output_buffer_if_necessary( sqlsrv_stmt* stmt, zval* param_z, SQLULE // calculate the size of each 'element' represented by column_size. WCHAR is of course 2, // as is a n(var)char/ntext field being returned as a binary field. - elem_size = (c_type == SQL_C_WCHAR || (c_type == SQL_C_BINARY && (sql_type == SQL_WCHAR || sql_type == SQL_WVARCHAR))) ? 2 : 1; + elem_size = (c_type == SQL_C_WCHAR || (c_type == SQL_C_BINARY && (sql_type == SQL_WCHAR || sql_type == SQL_WVARCHAR || sql_type == SQL_WLONGVARCHAR ))) ? 2 : 1; // account for the NULL terminator returned by ODBC and needed by Zend to avoid a "String not null terminated" debug warning - expected_len = column_size * elem_size + elem_size; + SQLULEN field_size = column_size; + if (column_size == SQL_SS_LENGTH_UNLIMITED) { + field_size = SQL_SERVER_MAX_FIELD_SIZE / elem_size; + } + expected_len = field_size * elem_size + elem_size; // binary fields aren't null terminated, so we need to account for that in our buffer length calcuations buffer_null_extra = (c_type == SQL_C_BINARY) ? elem_size : 0; // this is the size of the string for Zend and for the StrLen parameter to SQLBindParameter - without_null_len = column_size * elem_size; + without_null_len = field_size * elem_size; // increment to include the null terminator since the Zend length doesn't include the null terminator buffer_len += elem_size; diff --git a/source/shared/localization.hpp b/source/shared/localization.hpp index a73078897..18e30b271 100644 --- a/source/shared/localization.hpp +++ b/source/shared/localization.hpp @@ -25,13 +25,10 @@ #include "typedefs_for_linux.h" #ifdef MPLAT_UNIX -namespace std -{ - // Forward reference - class locale; -} +#include #endif + #define CP_UTF8 65001 #define CP_UTF16 1200 #define CP_UTF32 12000 diff --git a/source/shared/localizationimpl.cpp b/source/shared/localizationimpl.cpp index eb66d34a5..bff427211 100644 --- a/source/shared/localizationimpl.cpp +++ b/source/shared/localizationimpl.cpp @@ -311,7 +311,7 @@ const SystemLocale & SystemLocale::Singleton() #if !defined(__GNUC__) || defined(NO_THREADSAFE_STATICS) #error "Relying on GCC's threadsafe initialization of local statics." #endif - static const SystemLocale s_Default( "en_US.utf8" ); + static const SystemLocale s_Default( "en_US.utf-8" ); return s_Default; } diff --git a/source/shared/msodbcsql.h b/source/shared/msodbcsql.h index 278a86175..98b23f191 100644 --- a/source/shared/msodbcsql.h +++ b/source/shared/msodbcsql.h @@ -1,426 +1,426 @@ -#ifndef __msodbcsql_h__ -#define __msodbcsql_h__ - -//--------------------------------------------------------------------------------------------------------------------------------- -// File: msodbcsql.h -// -// Contents: Routines that use statement handles -// -// Contents: This SDK is not supported under any Microsoft standard support -// program or service. The information is provided AS IS without -// warranty of any kind. Microsoft disclaims all implied -// warranties including, without limitation, any implied -// warranties of merchantability or of fitness for a particular -// purpose. The entire risk arising out of the use of this SDK -// remains with you. In no event shall Microsoft, its authors, or -// anyone else involved in the creation, production, or delivery -// of this SDK be liable for any damages whatsoever (including, -// without limitation, damages for loss of business profits, -// business interruption, loss of business information, or other -// pecuniary loss) arising out of the use of or inability to use -// this SDK, even if Microsoft has been advised of the possibility -// of such damages. -// Microsoft Drivers 4.1 for PHP for SQL Server -// Copyright(c) Microsoft Corporation -// All rights reserved. -// MIT License -// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""), -// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : -// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//--------------------------------------------------------------------------------------------------------------------------------- - - -#if !defined(SQLODBC_VER) -#define SQLODBC_VER 1100 -#endif - -#if SQLODBC_VER >= 1300 - -#define SQLODBC_PRODUCT_NAME_FULL_VER_ANSI "Microsoft ODBC Driver 13 for SQL Server" -#define SQLODBC_PRODUCT_NAME_FULL_ANSI "Microsoft ODBC Driver for SQL Server" -#define SQLODBC_PRODUCT_NAME_SHORT_VER_ANSI "ODBC Driver 13 for SQL Server" -#define SQLODBC_PRODUCT_NAME_SHORT_ANSI "ODBC Driver for SQL Server" - -#endif /* SQLODBC_VER >= 1300 */ - -#define SQLODBC_PRODUCT_NAME_FULL_VER SQLODBC_PRODUCT_NAME_FULL_VER_ANSI -#define SQLODBC_PRODUCT_NAME_FULL SQLODBC_PRODUCT_NAME_FULL_ANSI -#define SQLODBC_PRODUCT_NAME_SHORT_VER SQLODBC_PRODUCT_NAME_SHORT_VER_ANSI -#define SQLODBC_PRODUCT_NAME_SHORT SQLODBC_PRODUCT_NAME_SHORT_ANSI - -#define SQLODBC_DRIVER_NAME SQLODBC_PRODUCT_NAME_SHORT_VER - -/* max SQL Server identifier length */ -#define SQL_MAX_SQLSERVERNAME 128 - -/* - * SQLSetConnectAttr driver specific defines. - * Microsoft has 1200 thru 1249 reserved for Microsoft ODBC Driver for SQL Server usage. - * Connection attributes - */ -#define SQL_COPT_SS_BASE 1200 -#define SQL_COPT_SS_INTEGRATED_SECURITY (SQL_COPT_SS_BASE+3) /* Force integrated security on login */ -#define SQL_COPT_SS_TRANSLATE (SQL_COPT_SS_BASE+20) /* Perform code page translation */ -#define SQL_COPT_SS_ENCRYPT (SQL_COPT_SS_BASE+23) /* Allow strong encryption for data */ -#define SQL_COPT_SS_MARS_ENABLED (SQL_COPT_SS_BASE+24) /* Multiple active result set per connection */ -#define SQL_COPT_SS_TXN_ISOLATION (SQL_COPT_SS_BASE+27) /* Used to set/get any driver-specific or ODBC-defined TXN iso level */ -#define SQL_COPT_SS_TRUST_SERVER_CERTIFICATE (SQL_COPT_SS_BASE+28) /* Trust server certificate */ -/* - * SQLSetStmtAttr Microsoft ODBC Driver for SQL Server specific defines. - * Statement attributes - */ -#define SQL_SOPT_SS_BASE 1225 -#define SQL_SOPT_SS_TEXTPTR_LOGGING (SQL_SOPT_SS_BASE+0) /* Text pointer logging */ -#define SQL_SOPT_SS_NOBROWSETABLE (SQL_SOPT_SS_BASE+3) /* Set NOBROWSETABLE option */ -#define SQL_SOPT_SS_COLUMN_ENCRYPTION (SQL_SOPT_SS_BASE+13)/* Sets the column encryption mode */ -/* Define old names */ -#define SQL_TEXTPTR_LOGGING SQL_SOPT_SS_TEXTPTR_LOGGING -#define SQL_COPT_SS_BASE_EX 1240 -#define SQL_COPT_SS_WARN_ON_CP_ERROR (SQL_COPT_SS_BASE_EX+3) /* Issues warning when data from the server had a loss during code page conversion. */ -#define SQL_COPT_SS_CONNECTION_DEAD (SQL_COPT_SS_BASE_EX+4) /* dbdead SQLGetConnectOption only. It will try to ping the server. Expensive connection check */ -#define SQL_COPT_SS_APPLICATION_INTENT (SQL_COPT_SS_BASE_EX+7) /* Application Intent */ -#define SQL_COPT_SS_MULTISUBNET_FAILOVER (SQL_COPT_SS_BASE_EX+8) /* Multi-subnet Failover */ -#define SQL_COPT_SS_TNIR (SQL_COPT_SS_BASE_EX+9) /* Transparent Network IP Resolution */ -#define SQL_COPT_SS_COLUMN_ENCRYPTION (SQL_COPT_SS_BASE_EX+10) /* Always Encrypted Enabled or Disabled */ -#define SQL_COPT_SS_AEKEYSTOREPROVIDER (SQL_COPT_SS_BASE_EX+11) /* Load a keystore provider or read the list of loaded keystore providers */ -#define SQL_COPT_SS_AEKEYSTOREDATA (SQL_COPT_SS_BASE_EX+12) /* Communicate with a loaded keystore provider */ -#define SQL_COPT_SS_AETRUSTEDCMKPATHS (SQL_COPT_SS_BASE_EX+13) /* List of trusted CMK paths */ -#define SQL_COPT_SS_AECEKCACHETTL (SQL_COPT_SS_BASE_EX+14)// Symmetric Key Cache TTL -/* - * SQLColAttributes driver specific defines. - * SQLSetDescField/SQLGetDescField driver specific defines. - * Microsoft has 1200 thru 1249 reserved for Microsoft ODBC Driver for SQL Server usage. - */ -#define SQL_CA_SS_BASE 1200 -#define SQL_CA_SS_COLUMN_SSTYPE (SQL_CA_SS_BASE+0) /* dbcoltype/dbalttype */ -#define SQL_CA_SS_COLUMN_UTYPE (SQL_CA_SS_BASE+1) /* dbcolutype/dbaltutype */ -#define SQL_CA_SS_NUM_ORDERS (SQL_CA_SS_BASE+2) /* dbnumorders */ -#define SQL_CA_SS_COLUMN_ORDER (SQL_CA_SS_BASE+3) /* dbordercol */ -#define SQL_CA_SS_COLUMN_VARYLEN (SQL_CA_SS_BASE+4) /* dbvarylen */ -#define SQL_CA_SS_NUM_COMPUTES (SQL_CA_SS_BASE+5) /* dbnumcompute */ -#define SQL_CA_SS_COMPUTE_ID (SQL_CA_SS_BASE+6) /* dbnextrow status return */ -#define SQL_CA_SS_COMPUTE_BYLIST (SQL_CA_SS_BASE+7) /* dbbylist */ -#define SQL_CA_SS_COLUMN_ID (SQL_CA_SS_BASE+8) /* dbaltcolid */ -#define SQL_CA_SS_COLUMN_OP (SQL_CA_SS_BASE+9) /* dbaltop */ -#define SQL_CA_SS_COLUMN_SIZE (SQL_CA_SS_BASE+10) /* dbcollen */ -#define SQL_CA_SS_COLUMN_HIDDEN (SQL_CA_SS_BASE+11) /* Column is hidden (FOR BROWSE) */ -#define SQL_CA_SS_COLUMN_KEY (SQL_CA_SS_BASE+12) /* Column is key column (FOR BROWSE) */ -#define SQL_CA_SS_COLUMN_COLLATION (SQL_CA_SS_BASE+14) /* Column collation (only for chars) */ -#define SQL_CA_SS_VARIANT_TYPE (SQL_CA_SS_BASE+15) -#define SQL_CA_SS_VARIANT_SQL_TYPE (SQL_CA_SS_BASE+16) -#define SQL_CA_SS_VARIANT_SERVER_TYPE (SQL_CA_SS_BASE+17) - -/* XML, CLR UDT, and table valued parameter related metadata */ -#define SQL_CA_SS_UDT_CATALOG_NAME (SQL_CA_SS_BASE+18) /* UDT catalog name */ -#define SQL_CA_SS_UDT_SCHEMA_NAME (SQL_CA_SS_BASE+19) /* UDT schema name */ -#define SQL_CA_SS_UDT_TYPE_NAME (SQL_CA_SS_BASE+20) /* UDT type name */ -#define SQL_CA_SS_XML_SCHEMACOLLECTION_CATALOG_NAME (SQL_CA_SS_BASE+22) /* Name of the catalog that contains XML Schema collection */ -#define SQL_CA_SS_XML_SCHEMACOLLECTION_SCHEMA_NAME (SQL_CA_SS_BASE+23) /* Name of the schema that contains XML Schema collection */ -#define SQL_CA_SS_XML_SCHEMACOLLECTION_NAME (SQL_CA_SS_BASE+24) /* Name of the XML Schema collection */ -#define SQL_CA_SS_CATALOG_NAME (SQL_CA_SS_BASE+25) /* Catalog name */ -#define SQL_CA_SS_SCHEMA_NAME (SQL_CA_SS_BASE+26) /* Schema name */ -#define SQL_CA_SS_TYPE_NAME (SQL_CA_SS_BASE+27) /* Type name */ - -/* table valued parameter related metadata */ -#define SQL_CA_SS_COLUMN_COMPUTED (SQL_CA_SS_BASE+29) /* column is computed */ -#define SQL_CA_SS_COLUMN_IN_UNIQUE_KEY (SQL_CA_SS_BASE+30) /* column is part of a unique key */ -#define SQL_CA_SS_COLUMN_SORT_ORDER (SQL_CA_SS_BASE+31) /* column sort order */ -#define SQL_CA_SS_COLUMN_SORT_ORDINAL (SQL_CA_SS_BASE+32) /* column sort ordinal */ -#define SQL_CA_SS_COLUMN_HAS_DEFAULT_VALUE (SQL_CA_SS_BASE+33) /* column has default value for all rows of the table valued parameter */ - -/* sparse column related metadata */ -#define SQL_CA_SS_IS_COLUMN_SET (SQL_CA_SS_BASE+34) /* column is a column-set column for sparse columns */ - -/* Legacy datetime related metadata */ -#define SQL_CA_SS_SERVER_TYPE (SQL_CA_SS_BASE+35) /* column type to send on the wire for datetime types */ - -/* force column encryption */ -#define SQL_CA_SS_FORCE_ENCRYPT (SQL_CA_SS_BASE+36) /* indicate mandatory encryption for this parameter */ - -/* Defines for use with SQL_COPT_SS_INTEGRATED_SECURITY - Pre-Connect Option only */ -#define SQL_IS_OFF 0L /* Integrated security isn't used */ -#define SQL_IS_ON 1L /* Integrated security is used */ -#define SQL_IS_DEFAULT SQL_IS_OFF -/* Defines for use with SQL_COPT_SS_TRANSLATE */ -#define SQL_XL_OFF 0L /* Code page translation is not performed */ -#define SQL_XL_ON 1L /* Code page translation is performed */ -#define SQL_XL_DEFAULT SQL_XL_ON -/* Defines for use with SQL_SOPT_SS_TEXTPTR_LOGGING */ -#define SQL_TL_OFF 0L /* No logging on text pointer ops */ -#define SQL_TL_ON 1L /* Logging occurs on text pointer ops */ -#define SQL_TL_DEFAULT SQL_TL_ON -/* Defines for use with SQL_SOPT_SS_NOBROWSETABLE */ -#define SQL_NB_OFF 0L /* NO_BROWSETABLE is off */ -#define SQL_NB_ON 1L /* NO_BROWSETABLE is on */ -#define SQL_NB_DEFAULT SQL_NB_OFF -/* Defines for use with SQL_SOPT_SS_COLUMN_ENCRYPTION */ -#define SQL_CE_DISABLED 0L /* Disabled */ -#define SQL_CE_RESULTSETONLY 1L /* Decryption Only (resultsets and return values) */ -#define SQL_CE_ENABLED 3L /* Enabled (both encryption and decryption) */ - -/* SQL_COPT_SS_ENCRYPT */ -#define SQL_EN_OFF 0L -#define SQL_EN_ON 1L -/* SQL_COPT_SS_TRUST_SERVER_CERTIFICATE */ -#define SQL_TRUST_SERVER_CERTIFICATE_NO 0L -#define SQL_TRUST_SERVER_CERTIFICATE_YES 1L -/* SQL_COPT_SS_WARN_ON_CP_ERROR */ -#define SQL_WARN_NO 0L -#define SQL_WARN_YES 1L -/* SQL_COPT_SS_MARS_ENABLED */ -#define SQL_MARS_ENABLED_NO 0L -#define SQL_MARS_ENABLED_YES 1L -/* SQL_TXN_ISOLATION_OPTION bitmasks */ -#define SQL_TXN_SS_SNAPSHOT 0x00000020L -/* SQL_COPT_SS_COLUMN_ENCRYPTION */ -#define SQL_COLUMN_ENCRYPTION_DISABLE 0L -#define SQL_COLUMN_ENCRYPTION_ENABLE 1L -#define SQL_COLUMN_ENCRYPTION_DEFAULT SQL_COLUMN_ENCRYPTION_DISABLE -// Defines for use with SQL_COPT_SS_AECEKCACHETTL -#define SQL_AECEKCACHETTL_DEFAULT 7200L // TTL value in seconds (2 hours) - -/* The following are defines for SQL_CA_SS_COLUMN_SORT_ORDER */ -#define SQL_SS_ORDER_UNSPECIFIED 0L -#define SQL_SS_DESCENDING_ORDER 1L -#define SQL_SS_ASCENDING_ORDER 2L -#define SQL_SS_ORDER_DEFAULT SQL_SS_ORDER_UNSPECIFIED - -/* - * Driver specific SQL data type defines. - * Microsoft has -150 thru -199 reserved for Microsoft ODBC Driver for SQL Server usage. - */ -#define SQL_SS_VARIANT (-150) -#define SQL_SS_UDT (-151) -#define SQL_SS_XML (-152) -#define SQL_SS_TABLE (-153) -#define SQL_SS_TIME2 (-154) -#define SQL_SS_TIMESTAMPOFFSET (-155) - -/* Local types to be used with SQL_CA_SS_SERVER_TYPE */ -#define SQL_SS_TYPE_DEFAULT 0L -#define SQL_SS_TYPE_SMALLDATETIME 1L -#define SQL_SS_TYPE_DATETIME 2L - -/* Extended C Types range 4000 and above. Range of -100 thru 200 is reserved by Driver Manager. */ -#define SQL_C_TYPES_EXTENDED 0x04000L - -/* - * SQL_SS_LENGTH_UNLIMITED is used to describe the max length of - * VARCHAR(max), VARBINARY(max), NVARCHAR(max), and XML columns - */ -#define SQL_SS_LENGTH_UNLIMITED 0 - -/* - * User Data Type definitions. - * Returned by SQLColAttributes/SQL_CA_SS_COLUMN_UTYPE. - */ -#define SQLudtBINARY 3 -#define SQLudtBIT 16 -#define SQLudtBITN 0 -#define SQLudtCHAR 1 -#define SQLudtDATETIM4 22 -#define SQLudtDATETIME 12 -#define SQLudtDATETIMN 15 -#define SQLudtDECML 24 -#define SQLudtDECMLN 26 -#define SQLudtFLT4 23 -#define SQLudtFLT8 8 -#define SQLudtFLTN 14 -#define SQLudtIMAGE 20 -#define SQLudtINT1 5 -#define SQLudtINT2 6 -#define SQLudtINT4 7 -#define SQLudtINTN 13 -#define SQLudtMONEY 11 -#define SQLudtMONEY4 21 -#define SQLudtMONEYN 17 -#define SQLudtNUM 10 -#define SQLudtNUMN 25 -#define SQLudtSYSNAME 18 -#define SQLudtTEXT 19 -#define SQLudtTIMESTAMP 80 -#define SQLudtUNIQUEIDENTIFIER 0 -#define SQLudtVARBINARY 4 -#define SQLudtVARCHAR 2 -#define MIN_USER_DATATYPE 256 -/* - * Aggregate operator types. - * Returned by SQLColAttributes/SQL_CA_SS_COLUMN_OP. - */ -#define SQLAOPSTDEV 0x30 /* Standard deviation */ -#define SQLAOPSTDEVP 0x31 /* Standard deviation population */ -#define SQLAOPVAR 0x32 /* Variance */ -#define SQLAOPVARP 0x33 /* Variance population */ -#define SQLAOPCNT 0x4b /* Count */ -#define SQLAOPSUM 0x4d /* Sum */ -#define SQLAOPAVG 0x4f /* Average */ -#define SQLAOPMIN 0x51 /* Min */ -#define SQLAOPMAX 0x52 /* Max */ -#define SQLAOPANY 0x53 /* Any */ -#define SQLAOPNOOP 0x56 /* None */ -/* - * SQLGetDiagField driver specific defines. - * Microsoft has -1150 thru -1199 reserved for Microsoft ODBC Driver for SQL Server usage. - */ -#define SQL_DIAG_SS_BASE (-1150) -#define SQL_DIAG_SS_MSGSTATE (SQL_DIAG_SS_BASE) -#define SQL_DIAG_SS_SEVERITY (SQL_DIAG_SS_BASE-1) -#define SQL_DIAG_SS_SRVNAME (SQL_DIAG_SS_BASE-2) -#define SQL_DIAG_SS_PROCNAME (SQL_DIAG_SS_BASE-3) -#define SQL_DIAG_SS_LINE (SQL_DIAG_SS_BASE-4) -/* - * SQLGetDiagField/SQL_DIAG_DYNAMIC_FUNCTION_CODE driver specific defines. - * Microsoft has -200 thru -299 reserved for Microsoft ODBC Driver for SQL Server usage. - */ -#define SQL_DIAG_DFC_SS_BASE (-200) -#define SQL_DIAG_DFC_SS_ALTER_DATABASE (SQL_DIAG_DFC_SS_BASE-0) -#define SQL_DIAG_DFC_SS_CHECKPOINT (SQL_DIAG_DFC_SS_BASE-1) -#define SQL_DIAG_DFC_SS_CONDITION (SQL_DIAG_DFC_SS_BASE-2) -#define SQL_DIAG_DFC_SS_CREATE_DATABASE (SQL_DIAG_DFC_SS_BASE-3) -#define SQL_DIAG_DFC_SS_CREATE_DEFAULT (SQL_DIAG_DFC_SS_BASE-4) -#define SQL_DIAG_DFC_SS_CREATE_PROCEDURE (SQL_DIAG_DFC_SS_BASE-5) -#define SQL_DIAG_DFC_SS_CREATE_RULE (SQL_DIAG_DFC_SS_BASE-6) -#define SQL_DIAG_DFC_SS_CREATE_TRIGGER (SQL_DIAG_DFC_SS_BASE-7) -#define SQL_DIAG_DFC_SS_CURSOR_DECLARE (SQL_DIAG_DFC_SS_BASE-8) -#define SQL_DIAG_DFC_SS_CURSOR_OPEN (SQL_DIAG_DFC_SS_BASE-9) -#define SQL_DIAG_DFC_SS_CURSOR_FETCH (SQL_DIAG_DFC_SS_BASE-10) -#define SQL_DIAG_DFC_SS_CURSOR_CLOSE (SQL_DIAG_DFC_SS_BASE-11) -#define SQL_DIAG_DFC_SS_DEALLOCATE_CURSOR (SQL_DIAG_DFC_SS_BASE-12) -#define SQL_DIAG_DFC_SS_DBCC (SQL_DIAG_DFC_SS_BASE-13) -#define SQL_DIAG_DFC_SS_DISK (SQL_DIAG_DFC_SS_BASE-14) -#define SQL_DIAG_DFC_SS_DROP_DATABASE (SQL_DIAG_DFC_SS_BASE-15) -#define SQL_DIAG_DFC_SS_DROP_DEFAULT (SQL_DIAG_DFC_SS_BASE-16) -#define SQL_DIAG_DFC_SS_DROP_PROCEDURE (SQL_DIAG_DFC_SS_BASE-17) -#define SQL_DIAG_DFC_SS_DROP_RULE (SQL_DIAG_DFC_SS_BASE-18) -#define SQL_DIAG_DFC_SS_DROP_TRIGGER (SQL_DIAG_DFC_SS_BASE-19) -#define SQL_DIAG_DFC_SS_DUMP_DATABASE (SQL_DIAG_DFC_SS_BASE-20) -#define SQL_DIAG_DFC_SS_BACKUP_DATABASE (SQL_DIAG_DFC_SS_BASE-20) -#define SQL_DIAG_DFC_SS_DUMP_TABLE (SQL_DIAG_DFC_SS_BASE-21) -#define SQL_DIAG_DFC_SS_DUMP_TRANSACTION (SQL_DIAG_DFC_SS_BASE-22) -#define SQL_DIAG_DFC_SS_BACKUP_TRANSACTION (SQL_DIAG_DFC_SS_BASE-22) -#define SQL_DIAG_DFC_SS_GOTO (SQL_DIAG_DFC_SS_BASE-23) -#define SQL_DIAG_DFC_SS_INSERT_BULK (SQL_DIAG_DFC_SS_BASE-24) -#define SQL_DIAG_DFC_SS_KILL (SQL_DIAG_DFC_SS_BASE-25) -#define SQL_DIAG_DFC_SS_LOAD_DATABASE (SQL_DIAG_DFC_SS_BASE-26) -#define SQL_DIAG_DFC_SS_RESTORE_DATABASE (SQL_DIAG_DFC_SS_BASE-26) -#define SQL_DIAG_DFC_SS_LOAD_HEADERONLY (SQL_DIAG_DFC_SS_BASE-27) -#define SQL_DIAG_DFC_SS_RESTORE_HEADERONLY (SQL_DIAG_DFC_SS_BASE-27) -#define SQL_DIAG_DFC_SS_LOAD_TABLE (SQL_DIAG_DFC_SS_BASE-28) -#define SQL_DIAG_DFC_SS_LOAD_TRANSACTION (SQL_DIAG_DFC_SS_BASE-29) -#define SQL_DIAG_DFC_SS_RESTORE_TRANSACTION (SQL_DIAG_DFC_SS_BASE-29) -#define SQL_DIAG_DFC_SS_PRINT (SQL_DIAG_DFC_SS_BASE-30) -#define SQL_DIAG_DFC_SS_RAISERROR (SQL_DIAG_DFC_SS_BASE-31) -#define SQL_DIAG_DFC_SS_READTEXT (SQL_DIAG_DFC_SS_BASE-32) -#define SQL_DIAG_DFC_SS_RECONFIGURE (SQL_DIAG_DFC_SS_BASE-33) -#define SQL_DIAG_DFC_SS_RETURN (SQL_DIAG_DFC_SS_BASE-34) -#define SQL_DIAG_DFC_SS_SELECT_INTO (SQL_DIAG_DFC_SS_BASE-35) -#define SQL_DIAG_DFC_SS_SET (SQL_DIAG_DFC_SS_BASE-36) -#define SQL_DIAG_DFC_SS_SET_IDENTITY_INSERT (SQL_DIAG_DFC_SS_BASE-37) -#define SQL_DIAG_DFC_SS_SET_ROW_COUNT (SQL_DIAG_DFC_SS_BASE-38) -#define SQL_DIAG_DFC_SS_SET_STATISTICS (SQL_DIAG_DFC_SS_BASE-39) -#define SQL_DIAG_DFC_SS_SET_TEXTSIZE (SQL_DIAG_DFC_SS_BASE-40) -#define SQL_DIAG_DFC_SS_SETUSER (SQL_DIAG_DFC_SS_BASE-41) -#define SQL_DIAG_DFC_SS_SHUTDOWN (SQL_DIAG_DFC_SS_BASE-42) -#define SQL_DIAG_DFC_SS_TRANS_BEGIN (SQL_DIAG_DFC_SS_BASE-43) -#define SQL_DIAG_DFC_SS_TRANS_COMMIT (SQL_DIAG_DFC_SS_BASE-44) -#define SQL_DIAG_DFC_SS_TRANS_PREPARE (SQL_DIAG_DFC_SS_BASE-45) -#define SQL_DIAG_DFC_SS_TRANS_ROLLBACK (SQL_DIAG_DFC_SS_BASE-46) -#define SQL_DIAG_DFC_SS_TRANS_SAVE (SQL_DIAG_DFC_SS_BASE-47) -#define SQL_DIAG_DFC_SS_TRUNCATE_TABLE (SQL_DIAG_DFC_SS_BASE-48) -#define SQL_DIAG_DFC_SS_UPDATE_STATISTICS (SQL_DIAG_DFC_SS_BASE-49) -#define SQL_DIAG_DFC_SS_UPDATETEXT (SQL_DIAG_DFC_SS_BASE-50) -#define SQL_DIAG_DFC_SS_USE (SQL_DIAG_DFC_SS_BASE-51) -#define SQL_DIAG_DFC_SS_WAITFOR (SQL_DIAG_DFC_SS_BASE-52) -#define SQL_DIAG_DFC_SS_WRITETEXT (SQL_DIAG_DFC_SS_BASE-53) -#define SQL_DIAG_DFC_SS_DENY (SQL_DIAG_DFC_SS_BASE-54) -#define SQL_DIAG_DFC_SS_SET_XCTLVL (SQL_DIAG_DFC_SS_BASE-55) -#define SQL_DIAG_DFC_SS_MERGE (SQL_DIAG_DFC_SS_BASE-56) - -/* Severity codes for SQL_DIAG_SS_SEVERITY */ -#define EX_ANY 0 -#define EX_INFO 10 -#define EX_MAXISEVERITY EX_INFO -#define EX_MISSING 11 -#define EX_TYPE 12 -#define EX_DEADLOCK 13 -#define EX_PERMIT 14 -#define EX_SYNTAX 15 -#define EX_USER 16 -#define EX_RESOURCE 17 -#define EX_INTOK 18 -#define MAXUSEVERITY EX_INTOK -#define EX_LIMIT 19 -#define EX_CMDFATAL 20 -#define MINFATALERR EX_CMDFATAL -#define EX_DBFATAL 21 -#define EX_TABCORRUPT 22 -#define EX_DBCORRUPT 23 -#define EX_HARDWARE 24 -#define EX_CONTROL 25 - -/* Keystore Provider interface definition */ - -typedef void errFunc(void *ctx, const wchar_t *msg, ...); - -#define IDS_MSG(x) ((const wchar_t*)(x)) - -typedef struct AEKeystoreProvider -{ - wchar_t *Name; - int (*Init)(void *ctx, errFunc *onError); - int (*Read)(void *ctx, errFunc *onError, void *data, unsigned int *len); - int (*Write)(void *ctx, errFunc *onError, void *data, unsigned int len); - int (*DecryptCEK)( - void *ctx, - errFunc *onError, - const wchar_t *keyPath, - const wchar_t *alg, - unsigned char *ecek, - unsigned short ecek_len, - unsigned char **cek_out, - unsigned short *cek_len); - void (*Free)(); -} AEKEYSTOREPROVIDER; - -/* Data is defined to be past the end of the structure header. - This is accepted by MSVC, GCC, and C99 standard but former emits - unnecessary warning, hence it has to be disabled. -*/ -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable:4200) -#endif - -typedef struct AEKeystoreData -{ - wchar_t *Name; - unsigned int dataSize; - char Data[]; -} AEKEYSTOREPROVIDERDATA; - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - -/* The following constants are for the Azure Key Vault configuration interface */ -#define AKV_CONFIG_FLAGS 0 - #define AKVCFG_USECLIENTID 0x00000001 - #define AKVCFG_AUTORENEW 0x00000002 - -#define AKV_CONFIG_CLIENTID 1 -#define AKV_CONFIG_CLIENTKEY 2 - -#define AKV_CONFIG_ACCESSTOKEN 3 -#define AKV_CONFIG_TOKENEXPIRY 4 - -#define AKV_CONFIG_MAXRETRIES 5 -#define AKV_CONFIG_RETRYTIMEOUT 6 -#define AKV_CONFIG_RETRYWAIT 7 - -#endif /* __msodbcsql_h__ */ - +#ifndef __msodbcsql_h__ +#define __msodbcsql_h__ + +//--------------------------------------------------------------------------------------------------------------------------------- +// File: msodbcsql.h +// +// Contents: Routines that use statement handles +// +// Contents: This SDK is not supported under any Microsoft standard support +// program or service. The information is provided AS IS without +// warranty of any kind. Microsoft disclaims all implied +// warranties including, without limitation, any implied +// warranties of merchantability or of fitness for a particular +// purpose. The entire risk arising out of the use of this SDK +// remains with you. In no event shall Microsoft, its authors, or +// anyone else involved in the creation, production, or delivery +// of this SDK be liable for any damages whatsoever (including, +// without limitation, damages for loss of business profits, +// business interruption, loss of business information, or other +// pecuniary loss) arising out of the use of or inability to use +// this SDK, even if Microsoft has been advised of the possibility +// of such damages. +// Microsoft Drivers 4.1 for PHP for SQL Server +// Copyright(c) Microsoft Corporation +// All rights reserved. +// MIT License +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""), +// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//--------------------------------------------------------------------------------------------------------------------------------- + + +#if !defined(SQLODBC_VER) +#define SQLODBC_VER 1100 +#endif + +#if SQLODBC_VER >= 1300 + +#define SQLODBC_PRODUCT_NAME_FULL_VER_ANSI "Microsoft ODBC Driver 13 for SQL Server" +#define SQLODBC_PRODUCT_NAME_FULL_ANSI "Microsoft ODBC Driver for SQL Server" +#define SQLODBC_PRODUCT_NAME_SHORT_VER_ANSI "ODBC Driver 13 for SQL Server" +#define SQLODBC_PRODUCT_NAME_SHORT_ANSI "ODBC Driver for SQL Server" + +#endif /* SQLODBC_VER >= 1300 */ + +#define SQLODBC_PRODUCT_NAME_FULL_VER SQLODBC_PRODUCT_NAME_FULL_VER_ANSI +#define SQLODBC_PRODUCT_NAME_FULL SQLODBC_PRODUCT_NAME_FULL_ANSI +#define SQLODBC_PRODUCT_NAME_SHORT_VER SQLODBC_PRODUCT_NAME_SHORT_VER_ANSI +#define SQLODBC_PRODUCT_NAME_SHORT SQLODBC_PRODUCT_NAME_SHORT_ANSI + +#define SQLODBC_DRIVER_NAME SQLODBC_PRODUCT_NAME_SHORT_VER + +/* max SQL Server identifier length */ +#define SQL_MAX_SQLSERVERNAME 128 + +/* + * SQLSetConnectAttr driver specific defines. + * Microsoft has 1200 thru 1249 reserved for Microsoft ODBC Driver for SQL Server usage. + * Connection attributes + */ +#define SQL_COPT_SS_BASE 1200 +#define SQL_COPT_SS_INTEGRATED_SECURITY (SQL_COPT_SS_BASE+3) /* Force integrated security on login */ +#define SQL_COPT_SS_TRANSLATE (SQL_COPT_SS_BASE+20) /* Perform code page translation */ +#define SQL_COPT_SS_ENCRYPT (SQL_COPT_SS_BASE+23) /* Allow strong encryption for data */ +#define SQL_COPT_SS_MARS_ENABLED (SQL_COPT_SS_BASE+24) /* Multiple active result set per connection */ +#define SQL_COPT_SS_TXN_ISOLATION (SQL_COPT_SS_BASE+27) /* Used to set/get any driver-specific or ODBC-defined TXN iso level */ +#define SQL_COPT_SS_TRUST_SERVER_CERTIFICATE (SQL_COPT_SS_BASE+28) /* Trust server certificate */ +/* + * SQLSetStmtAttr Microsoft ODBC Driver for SQL Server specific defines. + * Statement attributes + */ +#define SQL_SOPT_SS_BASE 1225 +#define SQL_SOPT_SS_TEXTPTR_LOGGING (SQL_SOPT_SS_BASE+0) /* Text pointer logging */ +#define SQL_SOPT_SS_NOBROWSETABLE (SQL_SOPT_SS_BASE+3) /* Set NOBROWSETABLE option */ +#define SQL_SOPT_SS_COLUMN_ENCRYPTION (SQL_SOPT_SS_BASE+13)/* Sets the column encryption mode */ +/* Define old names */ +#define SQL_TEXTPTR_LOGGING SQL_SOPT_SS_TEXTPTR_LOGGING +#define SQL_COPT_SS_BASE_EX 1240 +#define SQL_COPT_SS_WARN_ON_CP_ERROR (SQL_COPT_SS_BASE_EX+3) /* Issues warning when data from the server had a loss during code page conversion. */ +#define SQL_COPT_SS_CONNECTION_DEAD (SQL_COPT_SS_BASE_EX+4) /* dbdead SQLGetConnectOption only. It will try to ping the server. Expensive connection check */ +#define SQL_COPT_SS_APPLICATION_INTENT (SQL_COPT_SS_BASE_EX+7) /* Application Intent */ +#define SQL_COPT_SS_MULTISUBNET_FAILOVER (SQL_COPT_SS_BASE_EX+8) /* Multi-subnet Failover */ +#define SQL_COPT_SS_TNIR (SQL_COPT_SS_BASE_EX+9) /* Transparent Network IP Resolution */ +#define SQL_COPT_SS_COLUMN_ENCRYPTION (SQL_COPT_SS_BASE_EX+10) /* Always Encrypted Enabled or Disabled */ +#define SQL_COPT_SS_AEKEYSTOREPROVIDER (SQL_COPT_SS_BASE_EX+11) /* Load a keystore provider or read the list of loaded keystore providers */ +#define SQL_COPT_SS_AEKEYSTOREDATA (SQL_COPT_SS_BASE_EX+12) /* Communicate with a loaded keystore provider */ +#define SQL_COPT_SS_AETRUSTEDCMKPATHS (SQL_COPT_SS_BASE_EX+13) /* List of trusted CMK paths */ +#define SQL_COPT_SS_AECEKCACHETTL (SQL_COPT_SS_BASE_EX+14)// Symmetric Key Cache TTL +/* + * SQLColAttributes driver specific defines. + * SQLSetDescField/SQLGetDescField driver specific defines. + * Microsoft has 1200 thru 1249 reserved for Microsoft ODBC Driver for SQL Server usage. + */ +#define SQL_CA_SS_BASE 1200 +#define SQL_CA_SS_COLUMN_SSTYPE (SQL_CA_SS_BASE+0) /* dbcoltype/dbalttype */ +#define SQL_CA_SS_COLUMN_UTYPE (SQL_CA_SS_BASE+1) /* dbcolutype/dbaltutype */ +#define SQL_CA_SS_NUM_ORDERS (SQL_CA_SS_BASE+2) /* dbnumorders */ +#define SQL_CA_SS_COLUMN_ORDER (SQL_CA_SS_BASE+3) /* dbordercol */ +#define SQL_CA_SS_COLUMN_VARYLEN (SQL_CA_SS_BASE+4) /* dbvarylen */ +#define SQL_CA_SS_NUM_COMPUTES (SQL_CA_SS_BASE+5) /* dbnumcompute */ +#define SQL_CA_SS_COMPUTE_ID (SQL_CA_SS_BASE+6) /* dbnextrow status return */ +#define SQL_CA_SS_COMPUTE_BYLIST (SQL_CA_SS_BASE+7) /* dbbylist */ +#define SQL_CA_SS_COLUMN_ID (SQL_CA_SS_BASE+8) /* dbaltcolid */ +#define SQL_CA_SS_COLUMN_OP (SQL_CA_SS_BASE+9) /* dbaltop */ +#define SQL_CA_SS_COLUMN_SIZE (SQL_CA_SS_BASE+10) /* dbcollen */ +#define SQL_CA_SS_COLUMN_HIDDEN (SQL_CA_SS_BASE+11) /* Column is hidden (FOR BROWSE) */ +#define SQL_CA_SS_COLUMN_KEY (SQL_CA_SS_BASE+12) /* Column is key column (FOR BROWSE) */ +#define SQL_CA_SS_COLUMN_COLLATION (SQL_CA_SS_BASE+14) /* Column collation (only for chars) */ +#define SQL_CA_SS_VARIANT_TYPE (SQL_CA_SS_BASE+15) +#define SQL_CA_SS_VARIANT_SQL_TYPE (SQL_CA_SS_BASE+16) +#define SQL_CA_SS_VARIANT_SERVER_TYPE (SQL_CA_SS_BASE+17) + +/* XML, CLR UDT, and table valued parameter related metadata */ +#define SQL_CA_SS_UDT_CATALOG_NAME (SQL_CA_SS_BASE+18) /* UDT catalog name */ +#define SQL_CA_SS_UDT_SCHEMA_NAME (SQL_CA_SS_BASE+19) /* UDT schema name */ +#define SQL_CA_SS_UDT_TYPE_NAME (SQL_CA_SS_BASE+20) /* UDT type name */ +#define SQL_CA_SS_XML_SCHEMACOLLECTION_CATALOG_NAME (SQL_CA_SS_BASE+22) /* Name of the catalog that contains XML Schema collection */ +#define SQL_CA_SS_XML_SCHEMACOLLECTION_SCHEMA_NAME (SQL_CA_SS_BASE+23) /* Name of the schema that contains XML Schema collection */ +#define SQL_CA_SS_XML_SCHEMACOLLECTION_NAME (SQL_CA_SS_BASE+24) /* Name of the XML Schema collection */ +#define SQL_CA_SS_CATALOG_NAME (SQL_CA_SS_BASE+25) /* Catalog name */ +#define SQL_CA_SS_SCHEMA_NAME (SQL_CA_SS_BASE+26) /* Schema name */ +#define SQL_CA_SS_TYPE_NAME (SQL_CA_SS_BASE+27) /* Type name */ + +/* table valued parameter related metadata */ +#define SQL_CA_SS_COLUMN_COMPUTED (SQL_CA_SS_BASE+29) /* column is computed */ +#define SQL_CA_SS_COLUMN_IN_UNIQUE_KEY (SQL_CA_SS_BASE+30) /* column is part of a unique key */ +#define SQL_CA_SS_COLUMN_SORT_ORDER (SQL_CA_SS_BASE+31) /* column sort order */ +#define SQL_CA_SS_COLUMN_SORT_ORDINAL (SQL_CA_SS_BASE+32) /* column sort ordinal */ +#define SQL_CA_SS_COLUMN_HAS_DEFAULT_VALUE (SQL_CA_SS_BASE+33) /* column has default value for all rows of the table valued parameter */ + +/* sparse column related metadata */ +#define SQL_CA_SS_IS_COLUMN_SET (SQL_CA_SS_BASE+34) /* column is a column-set column for sparse columns */ + +/* Legacy datetime related metadata */ +#define SQL_CA_SS_SERVER_TYPE (SQL_CA_SS_BASE+35) /* column type to send on the wire for datetime types */ + +/* force column encryption */ +#define SQL_CA_SS_FORCE_ENCRYPT (SQL_CA_SS_BASE+36) /* indicate mandatory encryption for this parameter */ + +/* Defines for use with SQL_COPT_SS_INTEGRATED_SECURITY - Pre-Connect Option only */ +#define SQL_IS_OFF 0L /* Integrated security isn't used */ +#define SQL_IS_ON 1L /* Integrated security is used */ +#define SQL_IS_DEFAULT SQL_IS_OFF +/* Defines for use with SQL_COPT_SS_TRANSLATE */ +#define SQL_XL_OFF 0L /* Code page translation is not performed */ +#define SQL_XL_ON 1L /* Code page translation is performed */ +#define SQL_XL_DEFAULT SQL_XL_ON +/* Defines for use with SQL_SOPT_SS_TEXTPTR_LOGGING */ +#define SQL_TL_OFF 0L /* No logging on text pointer ops */ +#define SQL_TL_ON 1L /* Logging occurs on text pointer ops */ +#define SQL_TL_DEFAULT SQL_TL_ON +/* Defines for use with SQL_SOPT_SS_NOBROWSETABLE */ +#define SQL_NB_OFF 0L /* NO_BROWSETABLE is off */ +#define SQL_NB_ON 1L /* NO_BROWSETABLE is on */ +#define SQL_NB_DEFAULT SQL_NB_OFF +/* Defines for use with SQL_SOPT_SS_COLUMN_ENCRYPTION */ +#define SQL_CE_DISABLED 0L /* Disabled */ +#define SQL_CE_RESULTSETONLY 1L /* Decryption Only (resultsets and return values) */ +#define SQL_CE_ENABLED 3L /* Enabled (both encryption and decryption) */ + +/* SQL_COPT_SS_ENCRYPT */ +#define SQL_EN_OFF 0L +#define SQL_EN_ON 1L +/* SQL_COPT_SS_TRUST_SERVER_CERTIFICATE */ +#define SQL_TRUST_SERVER_CERTIFICATE_NO 0L +#define SQL_TRUST_SERVER_CERTIFICATE_YES 1L +/* SQL_COPT_SS_WARN_ON_CP_ERROR */ +#define SQL_WARN_NO 0L +#define SQL_WARN_YES 1L +/* SQL_COPT_SS_MARS_ENABLED */ +#define SQL_MARS_ENABLED_NO 0L +#define SQL_MARS_ENABLED_YES 1L +/* SQL_TXN_ISOLATION_OPTION bitmasks */ +#define SQL_TXN_SS_SNAPSHOT 0x00000020L +/* SQL_COPT_SS_COLUMN_ENCRYPTION */ +#define SQL_COLUMN_ENCRYPTION_DISABLE 0L +#define SQL_COLUMN_ENCRYPTION_ENABLE 1L +#define SQL_COLUMN_ENCRYPTION_DEFAULT SQL_COLUMN_ENCRYPTION_DISABLE +// Defines for use with SQL_COPT_SS_AECEKCACHETTL +#define SQL_AECEKCACHETTL_DEFAULT 7200L // TTL value in seconds (2 hours) + +/* The following are defines for SQL_CA_SS_COLUMN_SORT_ORDER */ +#define SQL_SS_ORDER_UNSPECIFIED 0L +#define SQL_SS_DESCENDING_ORDER 1L +#define SQL_SS_ASCENDING_ORDER 2L +#define SQL_SS_ORDER_DEFAULT SQL_SS_ORDER_UNSPECIFIED + +/* + * Driver specific SQL data type defines. + * Microsoft has -150 thru -199 reserved for Microsoft ODBC Driver for SQL Server usage. + */ +#define SQL_SS_VARIANT (-150) +#define SQL_SS_UDT (-151) +#define SQL_SS_XML (-152) +#define SQL_SS_TABLE (-153) +#define SQL_SS_TIME2 (-154) +#define SQL_SS_TIMESTAMPOFFSET (-155) + +/* Local types to be used with SQL_CA_SS_SERVER_TYPE */ +#define SQL_SS_TYPE_DEFAULT 0L +#define SQL_SS_TYPE_SMALLDATETIME 1L +#define SQL_SS_TYPE_DATETIME 2L + +/* Extended C Types range 4000 and above. Range of -100 thru 200 is reserved by Driver Manager. */ +#define SQL_C_TYPES_EXTENDED 0x04000L + +/* + * SQL_SS_LENGTH_UNLIMITED is used to describe the max length of + * VARCHAR(max), VARBINARY(max), NVARCHAR(max), and XML columns + */ +#define SQL_SS_LENGTH_UNLIMITED 0 + +/* + * User Data Type definitions. + * Returned by SQLColAttributes/SQL_CA_SS_COLUMN_UTYPE. + */ +#define SQLudtBINARY 3 +#define SQLudtBIT 16 +#define SQLudtBITN 0 +#define SQLudtCHAR 1 +#define SQLudtDATETIM4 22 +#define SQLudtDATETIME 12 +#define SQLudtDATETIMN 15 +#define SQLudtDECML 24 +#define SQLudtDECMLN 26 +#define SQLudtFLT4 23 +#define SQLudtFLT8 8 +#define SQLudtFLTN 14 +#define SQLudtIMAGE 20 +#define SQLudtINT1 5 +#define SQLudtINT2 6 +#define SQLudtINT4 7 +#define SQLudtINTN 13 +#define SQLudtMONEY 11 +#define SQLudtMONEY4 21 +#define SQLudtMONEYN 17 +#define SQLudtNUM 10 +#define SQLudtNUMN 25 +#define SQLudtSYSNAME 18 +#define SQLudtTEXT 19 +#define SQLudtTIMESTAMP 80 +#define SQLudtUNIQUEIDENTIFIER 0 +#define SQLudtVARBINARY 4 +#define SQLudtVARCHAR 2 +#define MIN_USER_DATATYPE 256 +/* + * Aggregate operator types. + * Returned by SQLColAttributes/SQL_CA_SS_COLUMN_OP. + */ +#define SQLAOPSTDEV 0x30 /* Standard deviation */ +#define SQLAOPSTDEVP 0x31 /* Standard deviation population */ +#define SQLAOPVAR 0x32 /* Variance */ +#define SQLAOPVARP 0x33 /* Variance population */ +#define SQLAOPCNT 0x4b /* Count */ +#define SQLAOPSUM 0x4d /* Sum */ +#define SQLAOPAVG 0x4f /* Average */ +#define SQLAOPMIN 0x51 /* Min */ +#define SQLAOPMAX 0x52 /* Max */ +#define SQLAOPANY 0x53 /* Any */ +#define SQLAOPNOOP 0x56 /* None */ +/* + * SQLGetDiagField driver specific defines. + * Microsoft has -1150 thru -1199 reserved for Microsoft ODBC Driver for SQL Server usage. + */ +#define SQL_DIAG_SS_BASE (-1150) +#define SQL_DIAG_SS_MSGSTATE (SQL_DIAG_SS_BASE) +#define SQL_DIAG_SS_SEVERITY (SQL_DIAG_SS_BASE-1) +#define SQL_DIAG_SS_SRVNAME (SQL_DIAG_SS_BASE-2) +#define SQL_DIAG_SS_PROCNAME (SQL_DIAG_SS_BASE-3) +#define SQL_DIAG_SS_LINE (SQL_DIAG_SS_BASE-4) +/* + * SQLGetDiagField/SQL_DIAG_DYNAMIC_FUNCTION_CODE driver specific defines. + * Microsoft has -200 thru -299 reserved for Microsoft ODBC Driver for SQL Server usage. + */ +#define SQL_DIAG_DFC_SS_BASE (-200) +#define SQL_DIAG_DFC_SS_ALTER_DATABASE (SQL_DIAG_DFC_SS_BASE-0) +#define SQL_DIAG_DFC_SS_CHECKPOINT (SQL_DIAG_DFC_SS_BASE-1) +#define SQL_DIAG_DFC_SS_CONDITION (SQL_DIAG_DFC_SS_BASE-2) +#define SQL_DIAG_DFC_SS_CREATE_DATABASE (SQL_DIAG_DFC_SS_BASE-3) +#define SQL_DIAG_DFC_SS_CREATE_DEFAULT (SQL_DIAG_DFC_SS_BASE-4) +#define SQL_DIAG_DFC_SS_CREATE_PROCEDURE (SQL_DIAG_DFC_SS_BASE-5) +#define SQL_DIAG_DFC_SS_CREATE_RULE (SQL_DIAG_DFC_SS_BASE-6) +#define SQL_DIAG_DFC_SS_CREATE_TRIGGER (SQL_DIAG_DFC_SS_BASE-7) +#define SQL_DIAG_DFC_SS_CURSOR_DECLARE (SQL_DIAG_DFC_SS_BASE-8) +#define SQL_DIAG_DFC_SS_CURSOR_OPEN (SQL_DIAG_DFC_SS_BASE-9) +#define SQL_DIAG_DFC_SS_CURSOR_FETCH (SQL_DIAG_DFC_SS_BASE-10) +#define SQL_DIAG_DFC_SS_CURSOR_CLOSE (SQL_DIAG_DFC_SS_BASE-11) +#define SQL_DIAG_DFC_SS_DEALLOCATE_CURSOR (SQL_DIAG_DFC_SS_BASE-12) +#define SQL_DIAG_DFC_SS_DBCC (SQL_DIAG_DFC_SS_BASE-13) +#define SQL_DIAG_DFC_SS_DISK (SQL_DIAG_DFC_SS_BASE-14) +#define SQL_DIAG_DFC_SS_DROP_DATABASE (SQL_DIAG_DFC_SS_BASE-15) +#define SQL_DIAG_DFC_SS_DROP_DEFAULT (SQL_DIAG_DFC_SS_BASE-16) +#define SQL_DIAG_DFC_SS_DROP_PROCEDURE (SQL_DIAG_DFC_SS_BASE-17) +#define SQL_DIAG_DFC_SS_DROP_RULE (SQL_DIAG_DFC_SS_BASE-18) +#define SQL_DIAG_DFC_SS_DROP_TRIGGER (SQL_DIAG_DFC_SS_BASE-19) +#define SQL_DIAG_DFC_SS_DUMP_DATABASE (SQL_DIAG_DFC_SS_BASE-20) +#define SQL_DIAG_DFC_SS_BACKUP_DATABASE (SQL_DIAG_DFC_SS_BASE-20) +#define SQL_DIAG_DFC_SS_DUMP_TABLE (SQL_DIAG_DFC_SS_BASE-21) +#define SQL_DIAG_DFC_SS_DUMP_TRANSACTION (SQL_DIAG_DFC_SS_BASE-22) +#define SQL_DIAG_DFC_SS_BACKUP_TRANSACTION (SQL_DIAG_DFC_SS_BASE-22) +#define SQL_DIAG_DFC_SS_GOTO (SQL_DIAG_DFC_SS_BASE-23) +#define SQL_DIAG_DFC_SS_INSERT_BULK (SQL_DIAG_DFC_SS_BASE-24) +#define SQL_DIAG_DFC_SS_KILL (SQL_DIAG_DFC_SS_BASE-25) +#define SQL_DIAG_DFC_SS_LOAD_DATABASE (SQL_DIAG_DFC_SS_BASE-26) +#define SQL_DIAG_DFC_SS_RESTORE_DATABASE (SQL_DIAG_DFC_SS_BASE-26) +#define SQL_DIAG_DFC_SS_LOAD_HEADERONLY (SQL_DIAG_DFC_SS_BASE-27) +#define SQL_DIAG_DFC_SS_RESTORE_HEADERONLY (SQL_DIAG_DFC_SS_BASE-27) +#define SQL_DIAG_DFC_SS_LOAD_TABLE (SQL_DIAG_DFC_SS_BASE-28) +#define SQL_DIAG_DFC_SS_LOAD_TRANSACTION (SQL_DIAG_DFC_SS_BASE-29) +#define SQL_DIAG_DFC_SS_RESTORE_TRANSACTION (SQL_DIAG_DFC_SS_BASE-29) +#define SQL_DIAG_DFC_SS_PRINT (SQL_DIAG_DFC_SS_BASE-30) +#define SQL_DIAG_DFC_SS_RAISERROR (SQL_DIAG_DFC_SS_BASE-31) +#define SQL_DIAG_DFC_SS_READTEXT (SQL_DIAG_DFC_SS_BASE-32) +#define SQL_DIAG_DFC_SS_RECONFIGURE (SQL_DIAG_DFC_SS_BASE-33) +#define SQL_DIAG_DFC_SS_RETURN (SQL_DIAG_DFC_SS_BASE-34) +#define SQL_DIAG_DFC_SS_SELECT_INTO (SQL_DIAG_DFC_SS_BASE-35) +#define SQL_DIAG_DFC_SS_SET (SQL_DIAG_DFC_SS_BASE-36) +#define SQL_DIAG_DFC_SS_SET_IDENTITY_INSERT (SQL_DIAG_DFC_SS_BASE-37) +#define SQL_DIAG_DFC_SS_SET_ROW_COUNT (SQL_DIAG_DFC_SS_BASE-38) +#define SQL_DIAG_DFC_SS_SET_STATISTICS (SQL_DIAG_DFC_SS_BASE-39) +#define SQL_DIAG_DFC_SS_SET_TEXTSIZE (SQL_DIAG_DFC_SS_BASE-40) +#define SQL_DIAG_DFC_SS_SETUSER (SQL_DIAG_DFC_SS_BASE-41) +#define SQL_DIAG_DFC_SS_SHUTDOWN (SQL_DIAG_DFC_SS_BASE-42) +#define SQL_DIAG_DFC_SS_TRANS_BEGIN (SQL_DIAG_DFC_SS_BASE-43) +#define SQL_DIAG_DFC_SS_TRANS_COMMIT (SQL_DIAG_DFC_SS_BASE-44) +#define SQL_DIAG_DFC_SS_TRANS_PREPARE (SQL_DIAG_DFC_SS_BASE-45) +#define SQL_DIAG_DFC_SS_TRANS_ROLLBACK (SQL_DIAG_DFC_SS_BASE-46) +#define SQL_DIAG_DFC_SS_TRANS_SAVE (SQL_DIAG_DFC_SS_BASE-47) +#define SQL_DIAG_DFC_SS_TRUNCATE_TABLE (SQL_DIAG_DFC_SS_BASE-48) +#define SQL_DIAG_DFC_SS_UPDATE_STATISTICS (SQL_DIAG_DFC_SS_BASE-49) +#define SQL_DIAG_DFC_SS_UPDATETEXT (SQL_DIAG_DFC_SS_BASE-50) +#define SQL_DIAG_DFC_SS_USE (SQL_DIAG_DFC_SS_BASE-51) +#define SQL_DIAG_DFC_SS_WAITFOR (SQL_DIAG_DFC_SS_BASE-52) +#define SQL_DIAG_DFC_SS_WRITETEXT (SQL_DIAG_DFC_SS_BASE-53) +#define SQL_DIAG_DFC_SS_DENY (SQL_DIAG_DFC_SS_BASE-54) +#define SQL_DIAG_DFC_SS_SET_XCTLVL (SQL_DIAG_DFC_SS_BASE-55) +#define SQL_DIAG_DFC_SS_MERGE (SQL_DIAG_DFC_SS_BASE-56) + +/* Severity codes for SQL_DIAG_SS_SEVERITY */ +#define EX_ANY 0 +#define EX_INFO 10 +#define EX_MAXISEVERITY EX_INFO +#define EX_MISSING 11 +#define EX_TYPE 12 +#define EX_DEADLOCK 13 +#define EX_PERMIT 14 +#define EX_SYNTAX 15 +#define EX_USER 16 +#define EX_RESOURCE 17 +#define EX_INTOK 18 +#define MAXUSEVERITY EX_INTOK +#define EX_LIMIT 19 +#define EX_CMDFATAL 20 +#define MINFATALERR EX_CMDFATAL +#define EX_DBFATAL 21 +#define EX_TABCORRUPT 22 +#define EX_DBCORRUPT 23 +#define EX_HARDWARE 24 +#define EX_CONTROL 25 + +/* Keystore Provider interface definition */ + +typedef void errFunc(void *ctx, const wchar_t *msg, ...); + +#define IDS_MSG(x) ((const wchar_t*)(x)) + +typedef struct AEKeystoreProvider +{ + wchar_t *Name; + int (*Init)(void *ctx, errFunc *onError); + int (*Read)(void *ctx, errFunc *onError, void *data, unsigned int *len); + int (*Write)(void *ctx, errFunc *onError, void *data, unsigned int len); + int (*DecryptCEK)( + void *ctx, + errFunc *onError, + const wchar_t *keyPath, + const wchar_t *alg, + unsigned char *ecek, + unsigned short ecek_len, + unsigned char **cek_out, + unsigned short *cek_len); + void (*Free)(); +} AEKEYSTOREPROVIDER; + +/* Data is defined to be past the end of the structure header. + This is accepted by MSVC, GCC, and C99 standard but former emits + unnecessary warning, hence it has to be disabled. +*/ +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4200) +#endif + +typedef struct AEKeystoreData +{ + wchar_t *Name; + unsigned int dataSize; + char Data[]; +} AEKEYSTOREPROVIDERDATA; + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +/* The following constants are for the Azure Key Vault configuration interface */ +#define AKV_CONFIG_FLAGS 0 + #define AKVCFG_USECLIENTID 0x00000001 + #define AKVCFG_AUTORENEW 0x00000002 + +#define AKV_CONFIG_CLIENTID 1 +#define AKV_CONFIG_CLIENTKEY 2 + +#define AKV_CONFIG_ACCESSTOKEN 3 +#define AKV_CONFIG_TOKENEXPIRY 4 + +#define AKV_CONFIG_MAXRETRIES 5 +#define AKV_CONFIG_RETRYTIMEOUT 6 +#define AKV_CONFIG_RETRYWAIT 7 + +#endif /* __msodbcsql_h__ */ + diff --git a/source/shared/typedefs_for_linux.h b/source/shared/typedefs_for_linux.h index 45798b863..15113d85b 100644 --- a/source/shared/typedefs_for_linux.h +++ b/source/shared/typedefs_for_linux.h @@ -95,9 +95,6 @@ typedef struct _SYSTEMTIME { typedef HINSTANCE HMODULE; /* HMODULEs can be used in place of HINSTANCEs */ -//From sqlext.h -#define SQL_GUID (-11) - size_t mplat_wcslen( const WCHAR * ); #endif // __linux_typedefs__ diff --git a/source/shared/version.h b/source/shared/version.h index c6c5a0c91..88c0c15a9 100644 --- a/source/shared/version.h +++ b/source/shared/version.h @@ -24,14 +24,28 @@ #define SQLVERSION_MAJOR 4 #define SQLVERSION_MINOR 1 -#define SQLVERSION_RELEASE 6 +#define SQLVERSION_PATCH 7 #define SQLVERSION_BUILD 0 -#define VER_FILEVERSION_STR STRINGIFY( SQLVERSION_MAJOR ) "." STRINGIFY( SQLVERSION_MINOR ) "." STRINGIFY( SQLVERSION_RELEASE ) "." STRINGIFY( SQLVERSION_BUILD ) -#define _FILEVERSION SQLVERSION_MAJOR,SQLVERSION_MINOR,SQLVERSION_RELEASE,SQLVERSION_BUILD -#define PHP_SQLSRV_VERSION STRINGIFY( SQLVERSION_MAJOR ) "." STRINGIFY( SQLVERSION_MINOR ) "." STRINGIFY( SQLVERSION_RELEASE ) -#define PHP_PDO_SQLSRV_VERSION PHP_SQLSRV_VERSION +// Semantic versioning pre-release, for stable releases should be empty +#define SEMVER_PRERELEASE "preview" +// Semantic versioning build metadata +#define SEMVER_BUILDMETA -#endif // VERSION_H +#if SQLVERSION_BUILD > 0 +#undef SEMVER_BUILDMETA +#define SEMVER_BUILDMETA "+" STRINGIFY( SQLVERSION_BUILD ) +#endif + +// Main version +#define VER_APIVERSION_STR STRINGIFY( SQLVERSION_MAJOR ) "." STRINGIFY( SQLVERSION_MINOR ) "." STRINGIFY( SQLVERSION_PATCH ) +// Remove "-" if SEMVER_PRERELEASE is empty (for stable releases) +#define VER_FILEVERSION_STR VER_APIVERSION_STR "-" SEMVER_PRERELEASE SEMVER_BUILDMETA +#define _FILEVERSION SQLVERSION_MAJOR,SQLVERSION_MINOR,SQLVERSION_PATCH,SQLVERSION_BUILD +// PECL package version macros (can't have '-' or '+') +#define PHP_SQLSRV_VERSION VER_APIVERSION_STR SEMVER_PRERELEASE +#define PHP_PDO_SQLSRV_VERSION PHP_SQLSRV_VERSION + +#endif // VERSION_H diff --git a/source/sqlsrv/conn.cpp b/source/sqlsrv/conn.cpp index 59a2479f5..51096cfbf 100644 --- a/source/sqlsrv/conn.cpp +++ b/source/sqlsrv/conn.cpp @@ -143,7 +143,7 @@ int get_stmt_option_key( zend_string* key, size_t key_len TSRMLS_DC ); // constants for parameters used by process_params function(s) int ss_sqlsrv_conn::descriptor; -char* ss_sqlsrv_conn::resource_name = static_cast("ss_sqlsrv_conn"); +const char* ss_sqlsrv_conn::resource_name = "ss_sqlsrv_conn"; // connection specific parameter proccessing. Use the generic function specialised to return a connection // resource. diff --git a/source/sqlsrv/init.cpp b/source/sqlsrv/init.cpp index 5f047f4b4..65f91860a 100644 --- a/source/sqlsrv/init.cpp +++ b/source/sqlsrv/init.cpp @@ -82,7 +82,7 @@ ZEND_BEGIN_ARG_INFO_EX( sqlsrv_connect_arginfo, 0, 0, 1 ) ZEND_ARG_ARRAY_INFO( 0, connection_info, 0 ) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX( sqlsrv_errors_arginfo, 0, 1, 0 ) +ZEND_BEGIN_ARG_INFO_EX( sqlsrv_errors_arginfo, 0, 0, 0 ) ZEND_ARG_INFO( 0, errors_and_or_warnings ) ZEND_END_ARG_INFO() @@ -94,14 +94,14 @@ ZEND_BEGIN_ARG_INFO_EX( sqlsrv_fetch_arginfo, 0, 0, 1 ) ZEND_ARG_INFO( 0, stmt ) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX( sqlsrv_fetch_array_arginfo, 0, 1, 1 ) +ZEND_BEGIN_ARG_INFO_EX( sqlsrv_fetch_array_arginfo, 0, 0, 1 ) ZEND_ARG_INFO( 0, stmt ) ZEND_ARG_INFO( 0, fetch_type ) ZEND_ARG_INFO( 0, row ) ZEND_ARG_INFO( 0, offset ) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX( sqlsrv_fetch_object_arginfo, 0, 1, 1 ) +ZEND_BEGIN_ARG_INFO_EX( sqlsrv_fetch_object_arginfo, 0, 0, 1 ) ZEND_ARG_INFO( 0, stmt ) ZEND_ARG_INFO( 0, class_name ) ZEND_ARG_INFO( 0, ctor_params ) @@ -109,7 +109,7 @@ ZEND_BEGIN_ARG_INFO_EX( sqlsrv_fetch_object_arginfo, 0, 1, 1 ) ZEND_ARG_INFO( 0, offset ) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX( sqlsrv_field_metadata_arginfo, 0, 1, 1 ) +ZEND_BEGIN_ARG_INFO_EX( sqlsrv_field_metadata_arginfo, 0, 0, 1 ) ZEND_ARG_INFO( 0, stmt ) ZEND_END_ARG_INFO() @@ -121,7 +121,7 @@ ZEND_BEGIN_ARG_INFO_EX( sqlsrv_get_config_arginfo, 0, 0, 1 ) ZEND_ARG_INFO( 0, setting ) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX( sqlsrv_get_field_arginfo, 0, 1, 2 ) +ZEND_BEGIN_ARG_INFO_EX( sqlsrv_get_field_arginfo, 0, 0, 2 ) ZEND_ARG_INFO( 0, stmt ) ZEND_ARG_INFO( 0, field_index ) ZEND_ARG_INFO( 0, get_as_type ) @@ -143,14 +143,14 @@ ZEND_BEGIN_ARG_INFO( sqlsrv_num_rows_arginfo, 0 ) ZEND_ARG_INFO( 0, stmt ) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX( sqlsrv_prepare_arginfo, 0, 1, 2 ) +ZEND_BEGIN_ARG_INFO_EX( sqlsrv_prepare_arginfo, 0, 0, 2 ) ZEND_ARG_INFO( 0, conn ) ZEND_ARG_INFO( 0, tsql ) ZEND_ARG_INFO( 0, params ) ZEND_ARG_INFO( 0, options ) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX( sqlsrv_query_arginfo, 0, 1, 2 ) +ZEND_BEGIN_ARG_INFO_EX( sqlsrv_query_arginfo, 0, 0, 2 ) ZEND_ARG_INFO( 0, conn ) ZEND_ARG_INFO( 0, tsql ) ZEND_ARG_INFO( 0, params ) diff --git a/source/sqlsrv/php_sqlsrv.h b/source/sqlsrv/php_sqlsrv.h index 043a108bb..71328a19b 100644 --- a/source/sqlsrv/php_sqlsrv.h +++ b/source/sqlsrv/php_sqlsrv.h @@ -134,7 +134,7 @@ struct ss_sqlsrv_conn : sqlsrv_conn bool in_transaction; // flag set when inside a transaction and used for checking validity of tran API calls // static variables used in process_params - static char* resource_name; // char because const char forces casting all over the place. Just easier to leave it char here. + static const char* resource_name; static int descriptor; // initialize with default values @@ -184,7 +184,7 @@ struct ss_sqlsrv_stmt : public sqlsrv_stmt { int fetch_fields_count; // static variables used in process_params - static char* resource_name; // char because const char forces casting all over the place in ODBC functions + static const char* resource_name; static int descriptor; }; @@ -490,7 +490,7 @@ namespace ss { } }; - inline void zend_register_resource(_Out_ zval& rsrc_result, void* rsrc_pointer, int rsrc_type, char* rsrc_name TSRMLS_DC) + inline void zend_register_resource(_Out_ zval& rsrc_result, void* rsrc_pointer, int rsrc_type, const char* rsrc_name TSRMLS_DC) { int zr = (NULL != (Z_RES(rsrc_result) = ::zend_register_resource(rsrc_pointer, rsrc_type)) ? SUCCESS : FAILURE); CHECK_CUSTOM_ERROR(( zr == FAILURE ), reinterpret_cast( rsrc_pointer ), SS_SQLSRV_ERROR_REGISTER_RESOURCE, diff --git a/source/sqlsrv/stmt.cpp b/source/sqlsrv/stmt.cpp index 7834aa831..d962d6d19 100644 --- a/source/sqlsrv/stmt.cpp +++ b/source/sqlsrv/stmt.cpp @@ -28,7 +28,7 @@ // // our resource descriptor assigned in minit int ss_sqlsrv_stmt::descriptor = 0; -char* ss_sqlsrv_stmt::resource_name = static_cast("ss_sqlsrv_stmt"); // not const for a reason. see sqlsrv_stmt in php_sqlsrv.h +const char* ss_sqlsrv_stmt::resource_name = "ss_sqlsrv_stmt"; namespace { @@ -2028,11 +2028,10 @@ void parse_param_array( ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array, zend_ul decimal_digits = 0; } - // if the user for some reason provides an output parameter with a null phptype and a specified + // if the user for some reason provides an inout / output parameter with a null phptype and a specified // sql server type, infer the php type from the sql server type. - if( direction == SQL_PARAM_OUTPUT && php_type_param_was_null && !sql_type_param_was_null ) { + if( direction != SQL_PARAM_INPUT && php_type_param_was_null && !sql_type_param_was_null ) { - int encoding; sqlsrv_phptype sqlsrv_phptype; sqlsrv_phptype = determine_sqlsrv_php_type( stmt, sql_type, (SQLUINTEGER)column_size, true ); @@ -2043,7 +2042,7 @@ void parse_param_array( ss_sqlsrv_stmt* stmt, _Inout_ zval* param_array, zend_ul "validated sql type and column_size" ); php_out_type = static_cast( sqlsrv_phptype.typeinfo.type ); - encoding = sqlsrv_phptype.typeinfo.encoding; + encoding = static_cast( sqlsrv_phptype.typeinfo.encoding ); } // verify that the parameter is a valid output param type diff --git a/source/sqlsrv/template.rc b/source/sqlsrv/template.rc index 5d148c59c..0e20602d6 100644 --- a/source/sqlsrv/template.rc +++ b/source/sqlsrv/template.rc @@ -43,8 +43,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US //Version VS_VERSION_INFO VERSIONINFO - FILEVERSION SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_RELEASE, SQLVERSION_BUILD - PRODUCTVERSION SQLVERSION_MAJOR,SQLVERSION_MINOR,SQLVERSION_RELEASE,0 + FILEVERSION SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_PATCH, SQLVERSION_BUILD + PRODUCTVERSION SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_PATCH,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS VS_FF_DEBUG @@ -62,12 +62,12 @@ BEGIN VALUE "Comments", "This product includes PHP software that is freely available from http://www.php.net/software/. Copyright © 2001-2016 The PHP Group. All rights reserved.\0" VALUE "CompanyName", "Microsoft Corp.\0" VALUE "FileDescription", "Microsoft Drivers for PHP for SQL Server\0" - VALUE "FileVersion", STRVER4(SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_RELEASE, SQLVERSION_BUILD) + VALUE "FileVersion", STRVER4(SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_PATCH, SQLVERSION_BUILD) VALUE "InternalName", FILE_NAME "\0" VALUE "LegalCopyright", "Copyright Microsoft Corporation.\0" VALUE "OriginalFilename", FILE_NAME "\0" VALUE "ProductName", "Microsoft Drivers for PHP for SQL Server\0" - VALUE "ProductVersion", STRVER3(SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_RELEASE) + VALUE "ProductVersion", STRVER3(SQLVERSION_MAJOR,SQLVERSION_MINOR, SQLVERSION_PATCH) VALUE "URL", "http://www.microsoft.com\0" END END diff --git a/test/pdo_sqlsrv/pdo_002_connect_app.phpt b/test/pdo_sqlsrv/pdo_002_connect_app.phpt index fa94dcaef..717a50201 100644 --- a/test/pdo_sqlsrv/pdo_002_connect_app.phpt +++ b/test/pdo_sqlsrv/pdo_002_connect_app.phpt @@ -1,34 +1,34 @@ ---TEST-- -Connection option APP name unicode ---SKIPIF-- ---FILE-- -query($query); -while ( $row = $stmt->fetch(PDO::FETCH_NUM) ){ - echo $row[0]."\n"; -} - -$stmt = $conn->query($query); -while ( $row = $stmt->fetch(PDO::FETCH_ASSOC) ){ - echo $row['']."\n"; -} - -// Free the connection -$conn=null; -echo "Done" -?> - ---EXPECTREGEX-- -APP_PoP_银河 -APP_PoP_银河 -Done +--TEST-- +Connection option APP name unicode +--SKIPIF-- +--FILE-- +query($query); +while ( $row = $stmt->fetch(PDO::FETCH_NUM) ){ + echo $row[0]."\n"; +} + +$stmt = $conn->query($query); +while ( $row = $stmt->fetch(PDO::FETCH_ASSOC) ){ + echo $row['']."\n"; +} + +// Free the connection +$conn=null; +echo "Done" +?> + +--EXPECTREGEX-- +APP_PoP_银河 +APP_PoP_银河 +Done diff --git a/test/pdo_sqlsrv/pdo_011_quote.phpt b/test/pdo_sqlsrv/pdo_011_quote.phpt index 46cd9b28d..04d791fd3 100644 --- a/test/pdo_sqlsrv/pdo_011_quote.phpt +++ b/test/pdo_sqlsrv/pdo_011_quote.phpt @@ -1,55 +1,55 @@ ---TEST-- -Insert with quoted parameters ---SKIPIF-- - ---FILE-- -quote( $param ); - -// CREATE database -$conn->query("CREATE DATABASE ". $dbName) ?: die(); - -// Create table -$query = "CREATE TABLE ".$tableName." (col1 VARCHAR(10), col2 VARCHAR(20))"; -$stmt = $conn->query($query); -if( $stmt === false ) { die(); } - -// Inserd data -$query = "INSERT INTO $tableName VALUES( ?, '1' )"; -$stmt = $conn->prepare( $query ); -$stmt->execute(array($param)); - -// Inserd data -$query = "INSERT INTO $tableName VALUES( ?, ? )"; -$stmt = $conn->prepare( $query ); -$stmt->execute(array($param, $param2)); - -// Query -$query = "SELECT * FROM $tableName"; -$stmt = $conn->query($query); -while ( $row = $stmt->fetch( PDO::FETCH_ASSOC ) ){ - print_r( $row['col1'] ." was inserted\n" ); -} - -// Revert the inserts -$query = "delete from $tableName where col1 = ?"; -$stmt = $conn->prepare( $query ); -$stmt->execute(array($param)); - -// DROP database -$conn->query("DROP DATABASE ". $dbName) ?: die(); - -//free the statement and connection -$stmt=null; -$conn=null; -?> ---EXPECT-- -a ' g was inserted -a ' g was inserted - +--TEST-- +Insert with quoted parameters +--SKIPIF-- + +--FILE-- +quote( $param ); + +// CREATE database +$conn->query("CREATE DATABASE ". $dbName) ?: die(); + +// Create table +$query = "CREATE TABLE ".$tableName." (col1 VARCHAR(10), col2 VARCHAR(20))"; +$stmt = $conn->query($query); +if( $stmt === false ) { die(); } + +// Inserd data +$query = "INSERT INTO $tableName VALUES( ?, '1' )"; +$stmt = $conn->prepare( $query ); +$stmt->execute(array($param)); + +// Inserd data +$query = "INSERT INTO $tableName VALUES( ?, ? )"; +$stmt = $conn->prepare( $query ); +$stmt->execute(array($param, $param2)); + +// Query +$query = "SELECT * FROM $tableName"; +$stmt = $conn->query($query); +while ( $row = $stmt->fetch( PDO::FETCH_ASSOC ) ){ + print_r( $row['col1'] ." was inserted\n" ); +} + +// Revert the inserts +$query = "delete from $tableName where col1 = ?"; +$stmt = $conn->prepare( $query ); +$stmt->execute(array($param)); + +// DROP database +$conn->query("DROP DATABASE ". $dbName) ?: die(); + +//free the statement and connection +$stmt=null; +$conn=null; +?> +--EXPECT-- +a ' g was inserted +a ' g was inserted + diff --git a/test/pdo_sqlsrv/pdo_013_row_count.phpt b/test/pdo_sqlsrv/pdo_013_row_count.phpt index fb27996c7..1aad0a2cb 100644 --- a/test/pdo_sqlsrv/pdo_013_row_count.phpt +++ b/test/pdo_sqlsrv/pdo_013_row_count.phpt @@ -1,60 +1,60 @@ ---TEST-- -Number of rows in a result set ---SKIPIF-- ---FILE-- -query("CREATE DATABASE ". $dbName) ?: die(); - -// Create table -$stmt = $conn->query("CREATE TABLE ".$tableName." (c1 VARCHAR(32))"); -$stmt=null; - -// Insert data -$query = "INSERT INTO ".$tableName." VALUES ('Salmon'),('Butterfish'),('Cod'),('NULL'),('Crab')"; -$stmt = $conn->query($query); -$res[] = $stmt->rowCount(); - -// Update data -$query = "UPDATE ".$tableName." SET c1='Salmon' WHERE c1='Cod'"; -$stmt = $conn->query($query); -$res[] = $stmt->rowCount(); - -// Update data -$query = "UPDATE ".$tableName." SET c1='Salmon' WHERE c1='NULL'"; -$stmt = $conn->query($query); -$res[] = $stmt->rowCount(); - -// Update data -$query = "UPDATE ".$tableName." SET c1='Salmon' WHERE c1='NO_NAME'"; -$stmt = $conn->query($query); -$res[] = $stmt->rowCount(); - -// Update data -$query = "UPDATE ".$tableName." SET c1='N/A'"; -$stmt = $conn->query($query); -$res[] = $stmt->rowCount(); - -print_r($res); - -// DROP database -$conn->query("DROP DATABASE ". $dbName) ?: die(); - -$stmt=null; -$conn=null; -print "Done" -?> ---EXPECT-- -Array -( - [0] => 5 - [1] => 1 - [2] => 1 - [3] => 0 - [4] => 5 -) -Done +--TEST-- +Number of rows in a result set +--SKIPIF-- +--FILE-- +query("CREATE DATABASE ". $dbName) ?: die(); + +// Create table +$stmt = $conn->query("CREATE TABLE ".$tableName." (c1 VARCHAR(32))"); +$stmt=null; + +// Insert data +$query = "INSERT INTO ".$tableName." VALUES ('Salmon'),('Butterfish'),('Cod'),('NULL'),('Crab')"; +$stmt = $conn->query($query); +$res[] = $stmt->rowCount(); + +// Update data +$query = "UPDATE ".$tableName." SET c1='Salmon' WHERE c1='Cod'"; +$stmt = $conn->query($query); +$res[] = $stmt->rowCount(); + +// Update data +$query = "UPDATE ".$tableName." SET c1='Salmon' WHERE c1='NULL'"; +$stmt = $conn->query($query); +$res[] = $stmt->rowCount(); + +// Update data +$query = "UPDATE ".$tableName." SET c1='Salmon' WHERE c1='NO_NAME'"; +$stmt = $conn->query($query); +$res[] = $stmt->rowCount(); + +// Update data +$query = "UPDATE ".$tableName." SET c1='N/A'"; +$stmt = $conn->query($query); +$res[] = $stmt->rowCount(); + +print_r($res); + +// DROP database +$conn->query("DROP DATABASE ". $dbName) ?: die(); + +$stmt=null; +$conn=null; +print "Done" +?> +--EXPECT-- +Array +( + [0] => 5 + [1] => 1 + [2] => 1 + [3] => 0 + [4] => 5 +) +Done diff --git a/test/pdo_sqlsrv/pdo_023.phpt b/test/pdo_sqlsrv/pdo_023.phpt index c9d634dbc..5c213705e 100644 --- a/test/pdo_sqlsrv/pdo_023.phpt +++ b/test/pdo_sqlsrv/pdo_023.phpt @@ -3,7 +3,6 @@ Bind values with PDO::PARAM_BOOL, enable/disable fetch numeric type attribute --SKIPIF-- --FILE-- query($sql); + + // Insert data using bind parameters + $sql = "INSERT INTO $tableName VALUES (?)"; + $stmt = $conn->prepare($sql); + $message = "This is to test github issue 35."; + $value = base64_encode($message); + + $stmt->setAttribute(constant('PDO::SQLSRV_ATTR_ENCODING'), PDO::SQLSRV_ENCODING_BINARY); + $stmt->bindParam(1, $value, PDO::PARAM_LOB); + $result = $stmt->execute(); + + // fetch it back + $stmt = $conn->prepare("SELECT Value FROM $tableName"); + $stmt->bindColumn('Value', $val1, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY); + $stmt->execute(); + $stmt->fetch(PDO::FETCH_BOUND); + var_dump($val1 === $value); + + $stmt = $conn->query("DROP TABLE $tableName"); + + // Close connection + $stmt = null; + $conn = null; +} + +test(); +print "Done"; +?> +--EXPECT-- +bool(true) +Done + diff --git a/test/pdo_sqlsrv/pdo_069_fetch_empty_nvarchar_buffered.phpt b/test/pdo_sqlsrv/pdo_069_fetch_empty_nvarchar_buffered.phpt new file mode 100644 index 000000000..b650dc548 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_069_fetch_empty_nvarchar_buffered.phpt @@ -0,0 +1,38 @@ +--TEST-- +GitHub issue #69 - fetching an empty nvarchar using client buffer +--SKIPIF-- +--FILE-- +setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); + +$sql = "EXEC dbo.sp_executesql +N'DECLARE @x nvarchar(max) +SET @x = '''' -- empty string +SELECT @x AS [Empty_Nvarchar_Max]'"; + +$stmt = $conn->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); + +$return = $stmt->fetchAll( PDO::FETCH_ASSOC ); +print_r($return); + +// Free the statement and connection resources. +$stmt = null; +$conn = null; + +print "Done"; +?> +--EXPECT-- +Array +( + [0] => Array + ( + [Empty_Nvarchar_Max] => + ) + +) +Done \ No newline at end of file diff --git a/test/pdo_sqlsrv/pdo_267_closeCursor.phpt b/test/pdo_sqlsrv/pdo_267_closeCursor.phpt new file mode 100644 index 000000000..b49bdf20f --- /dev/null +++ b/test/pdo_sqlsrv/pdo_267_closeCursor.phpt @@ -0,0 +1,70 @@ +--TEST-- +Test closeCursor with a stmt before/after execute and fetch. +--SKIPIF-- +--FILE-- +setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); + + // prepare a stmt but don't execute, then closeCursor. + $stmt = $conn->prepare("select 123 as 'IntCol'"); + $ret = $stmt->closeCursor(); + var_dump($ret); + $ret = $stmt->closeCursor(); + var_dump($ret); + + // prepare a stmt and execute, then closeCursor. + $stmt = $conn->prepare("select 123 as 'IntCol'"); + $stmt->execute(); + $ret = $stmt->closeCursor(); + var_dump($ret); + $ret = $stmt->closeCursor(); + var_dump($ret); + + + // use two stmt, execute, and fetch, then closeCursor. + // use one with client side buffering. + $stmt1 = $conn->query("select 123 as 'IntCol'"); + $stmt2 = $conn->prepare("select 'abc' as 'Charcol'", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); + $result = $stmt1->fetch(PDO::FETCH_NUM); + print_r($result[0]); + echo "\n"; + $ret = $stmt1->closeCursor(); + var_dump($ret); + $stmt2->execute(); + $result = $stmt2->fetch(PDO::FETCH_NUM); + print_r($result[0]); + echo "\n"; + $ret = $stmt2->closeCursor(); + var_dump($ret); + + $stmt1 = null; + $stmt2 = null; + $stmt = null; + $conn = null; + +} + +catch( PDOException $e ) { + var_dump($e); + exit; +} + +print "Done"; +?> + +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +123 +bool(true) +abc +bool(true) +Done \ No newline at end of file diff --git a/test/pdo_sqlsrv/pdo_270_fetch_binary.phpt b/test/pdo_sqlsrv/pdo_270_fetch_binary.phpt new file mode 100644 index 000000000..5edebcce3 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_270_fetch_binary.phpt @@ -0,0 +1,92 @@ +--TEST-- +Test fetch from binary, varbinary, varbinary(max), image columns, without setting binary encoding. +--DESCRIPTION-- +Verifies GitHub issue 270 is fixed, users could not retrieve the data as inserted in binary columns without setting the binary encoding either on stmt or using bindCoulmn encoding. +This test verifies that the data inserted in binary columns can be retrieved using fetch, fetchColumn, fetchObject, and fetchAll functions. + +--FILE-- +exec($sql); + +$icon = base64_decode("This is some text to test retrieving from binary type columns"); + +// Insert data using bind parameters +$sql = "INSERT INTO $tableName($columns[0], $columns[1], $columns[2], $columns[3]) VALUES(?, ?, ?, ?)"; +$stmt = $conn->prepare($sql); +$stmt->bindParam(1, $icon, PDO::PARAM_LOB, null, PDO::SQLSRV_ENCODING_BINARY); +$stmt->bindParam(2, $icon, PDO::PARAM_LOB, null, PDO::SQLSRV_ENCODING_BINARY); +$stmt->bindParam(3, $icon, PDO::PARAM_LOB, null, PDO::SQLSRV_ENCODING_BINARY); +$stmt->bindParam(4, $icon, PDO::PARAM_LOB, null, PDO::SQLSRV_ENCODING_BINARY); +$stmt->execute(); + +// loop through each column in the table +foreach ($columns as $col){ + test_fetch($conn, $tableName, $col, $icon); +} +// DROP table +$conn->query("DROP TABLE $tableName") ?: die(); + +//free statement and connection +$stmt = null; +$conn = null; + +print_r("Test finished successfully"); + +//calls various fetch methods +function test_fetch($conn, $tableName, $columnName, $input){ + + $len = strlen($input); + $result = ""; + $sql = "SELECT $columnName from $tableName"; + + $stmt = $conn->query($sql); + $stmt->bindColumn(1, $result, PDO::PARAM_LOB); + $stmt->fetch(PDO::FETCH_BOUND); + //binary is fixed size, to evaluate output, compare it using strncmp + if( strncmp($result, $input, $len) !== 0){ + print_r("\nRetrieving using bindColumn failed"); + } + + $result = ""; + $stmt = $conn->query($sql); + $stmt->bindColumn(1, $result, PDO::PARAM_LOB, 0 , PDO::SQLSRV_ENCODING_BINARY); + $stmt->fetch(PDO::FETCH_BOUND); + if( strncmp($result, $input, $len) !== 0){ + print_r("\nRetrieving using bindColumn with encoding set failed"); + } + + $result = ""; + $stmt = $conn->query($sql); + $result = $stmt->fetchColumn(); + if( strncmp($result, $input, $len) !== 0){ + print_r("\nRetrieving using fetchColumn failed"); + } + + $result = ""; + $stmt = $conn->query($sql); + $result = $stmt->fetchObject(); + if( strncmp($result->$columnName, $input, $len) !== 0){ + print_r("\nRetrieving using fetchObject failed"); + } + + $result = ""; + $stmt = $conn->query($sql); + $result = $stmt->fetchAll( PDO::FETCH_COLUMN ); + if( strncmp($result[0], $input, $len) !== 0){ + print_r("\nRetrieving using fetchAll failed"); + } +} + +?> +--EXPECT-- +Test finished successfully diff --git a/test/pdo_sqlsrv/pdo_308_empty_output_param.phpt b/test/pdo_sqlsrv/pdo_308_empty_output_param.phpt new file mode 100644 index 000000000..80984d186 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_308_empty_output_param.phpt @@ -0,0 +1,48 @@ +--TEST-- +GitHub issue #308 - empty string set to output parameter on stored procedure +--DESCRIPTION-- +Verifies GitHub issue 308 is fixed, empty string returned as output parameter will remain an empty string. +--SKIPIF-- +--FILE-- +setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); + +$procName = GetTempProcName(); + +$sql = "CREATE PROCEDURE $procName @TEST VARCHAR(200)='' OUTPUT +AS BEGIN +SET NOCOUNT ON; +SET @TEST=''; +SELECT HELLO_WORLD_COLUMN='THIS IS A COLUMN IN A SINGLE DATASET'; +END"; +$stmt = $conn->exec($sql); + +$sql = "EXEC $procName @Test = :Test"; +$stmt = $conn->prepare($sql); +$out = ''; +$stmt->bindParam(':Test', $out, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 200); +$stmt->execute(); + +$result = $stmt->fetchAll(); +$stmt->closeCursor(); + +echo "OUT value: "; +var_dump($out); + +// Free the statement and connection resources. +$stmt = null; +$conn = null; + +print "Done"; +?> +--EXPECT-- +OUT value: string(0) "" +Done \ No newline at end of file diff --git a/test/pdo_sqlsrv/pdo_connection_quote.phpt b/test/pdo_sqlsrv/pdo_connection_quote.phpt new file mode 100644 index 000000000..b05d6a322 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_connection_quote.phpt @@ -0,0 +1,74 @@ +--TEST-- +testing the quote method with different inputs and then test with a empty query +--SKIPIF-- + +--FILE-- +quote("1'2'3'4'5'6'7'8", PDO::PARAM_INT); + var_dump($output1); + + $output2 = $conn->quote("{ABCD}'{EFGH}", PDO::PARAM_STR); + var_dump($output2); + + $output3 = $conn->quote("The quick brown fox jumps over the lazy dog0123456789"); + var_dump($output3); + + $stmt = $conn->query(""); + if ($stmt != false) + { + echo("Empty query was expected to fail!\n"); + } + + $stmt1 = $conn->prepare($output2); + $result = $stmt1->execute(); + if ($result != false) + { + echo("This query was expected to fail!\n"); + } + $stmt1 = null; + + $stmt2 = $conn->query($output3); + if ($stmt2 != false) + { + echo("This query was expected to fail!\n"); + } + + $conn = null; +} + +function Repro() +{ + StartTest("pdo_connection_quote"); + try + { + Quote(); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("pdo_connection_quote"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'pdo_connection_quote' test... +string(24) "'1''2''3''4''5''6''7''8'" +string(16) "'{ABCD}''{EFGH}'" +string(118) "'The quick brown fox jumps over the lazy dog0123456789'" + +Done +...Test 'pdo_connection_quote' completed successfully. diff --git a/test/pdo_sqlsrv/pdo_fetch_bindcolumn_fetchmode.phpt b/test/pdo_sqlsrv/pdo_fetch_bindcolumn_fetchmode.phpt new file mode 100644 index 000000000..e1d07324a --- /dev/null +++ b/test/pdo_sqlsrv/pdo_fetch_bindcolumn_fetchmode.phpt @@ -0,0 +1,128 @@ +--TEST-- +fetch columns using fetch mode and different ways of binding columns +--SKIPIF-- + +--FILE-- +exec("CREATE TABLE $tableName ([c1_int] int, [c2_tinyint] tinyint, [c3_smallint] smallint, [c4_bigint] bigint, [c5_bit] bit, [c6_float] float, [c7_real] real, [c8_decimal] decimal(28,4), [c9_numeric] numeric(32,4), [c10_money] money, [c11_smallmoney] smallmoney, [c12_char] char(512), [c13_varchar] varchar(512), [c14_varchar_max] varchar(max), [c15_nchar] nchar(512), [c16_nvarchar] nvarchar(512), [c17_nvarchar_max] nvarchar(max), [c18_text] text, [c19_ntext] ntext, [c20_binary] binary(512), [c21_varbinary] varbinary(512), [c22_varbinary_max] varbinary(max), [c23_image] image, [c24_uniqueidentifier] uniqueidentifier, [c25_datetime] datetime, [c26_smalldatetime] smalldatetime, [c27_timestamp] timestamp, [c28_xml] xml, [c29_time] time, [c30_date] date, [c31_datetime2] datetime2, [c32_datetimeoffset] datetimeoffset)"); + + $numRows = 0; + $query = GetQuery($tableName, ++$numRows); + $stmt = $conn->query($query); + + $query = GetQuery($tableName, ++$numRows); + $stmt = $conn->query($query); + + $cols = array_fill(0, 32, null); + $stmt = $conn->prepare("SELECT * FROM $tableName ORDER BY c27_timestamp"); + $result = $stmt->execute(); + $stmt->bindColumn('c1_int', $cols[0]); + $stmt->bindColumn('c2_tinyint', $cols[1]); + $stmt->bindColumn(3, $cols[2]); + $stmt->bindColumn(4, $cols[3]); + $stmt->bindColumn(5, $cols[4]); + $stmt->bindColumn(6, $cols[5]); + $stmt->bindColumn(7, $cols[6]); + $stmt->bindColumn(8, $cols[7]); + $stmt->bindColumn('c9_numeric', $cols[8]); + $stmt->bindColumn('c10_money', $cols[9]); + $stmt->bindColumn('c11_smallmoney', $cols[10]); + $stmt->bindColumn('c12_char', $cols[11]); + $stmt->bindColumn(13, $cols[12]); + $stmt->bindColumn('c14_varchar_max', $cols[13]); + $stmt->bindColumn(15, $cols[14]); + $stmt->bindColumn('c16_nvarchar', $cols[15]); + $stmt->bindColumn(17, $cols[16]); + $stmt->bindColumn(18, $cols[17]); + $stmt->bindColumn(19, $cols[18]); + $stmt->bindColumn('c20_binary', $cols[19]); + $stmt->bindColumn(21, $cols[20]); + $stmt->bindColumn('c22_varbinary_max', $cols[21]); + $stmt->bindColumn(23, $cols[22]); + $stmt->bindColumn(24, $cols[23]); + $stmt->bindColumn(25, $cols[24]); + $stmt->bindColumn(26, $cols[25]); + $stmt->bindColumn('c27_timestamp', $cols[26]); + $stmt->bindColumn('c28_xml', $cols[27]); + $stmt->bindColumn(29, $cols[28]); + $stmt->bindColumn(30, $cols[29]); + $stmt->bindColumn(31, $cols[30]); + $stmt->bindColumn('c32_datetimeoffset', $cols[31]); + + $numFields = $stmt->columnCount(); + + $i = 0; + while ($row = $stmt->fetch(PDO::FETCH_BOUND)) + { + echo "Comparing data in row " . ++$i . "\n"; + $query = GetQuery($tableName, $i); + $dataArray = InsertDataToArray($stmt, $query, $numFields, $i); + $j = 0; + foreach ($cols as $value) + { + CompareData($stmt, $i, $j, $value, $dataArray[$j]); + $j++; + } + } + $stmt = null; + $conn = null; +} + +function GetQuery($tableName, $index) +{ + $query = ""; + switch ($index) + { + case 1: + $query = "INSERT INTO $tableName ([c1_int], [c2_tinyint], [c3_smallint], [c4_bigint], [c5_bit], [c6_float], [c7_real], [c8_decimal], [c9_numeric], [c10_money], [c11_smallmoney], [c12_char], [c13_varchar], [c14_varchar_max], [c15_nchar], [c16_nvarchar], [c17_nvarchar_max], [c18_text], [c19_ntext], [c20_binary], [c21_varbinary], [c22_varbinary_max], [c23_image], [c24_uniqueidentifier], [c25_datetime], [c26_smalldatetime], [c28_xml], [c29_time], [c30_date], [c31_datetime2], [c32_datetimeoffset]) VALUES ((1448461366), (110), (-28270), (804279686), (0), (0), (null), (-100000000000000000000000), (0.6685), (0.2997), (0.5352), ('äðubý/ö*bUah¢AoÖrZÃ_oßoüöÐ>ßÄßUAüîÖh_u*uh.uå:,öî@UCO,<¢<:Ö@>+ß,ªåÜbrª¢öãäo,ü£/b,|ýãý~öߣîUö_¢ªðu.+ýÃhAaäzvzrb£ßAÃhö,ö.aöü/Z+Ã.uvUo~v:+u_ýý©z¢ª|U/îã<©|vý+bÐÄЩoðbbüðb_~*î..üÐÃz,äAðß~Ö¢Äå~ð.£_ßzãÖv~¢£Oå*@|UozU©Ð+ãÄÐ,*Z/vA>ªOÄ,¢bhý/ÖÖuäAoü.a@@ßaðvbaߣ@v,ub+Oä@oBBÖöAüßö|Ö~hhvbuäo/<Ã+£¢Ã¢ß>'), ('Z:Uî/ÜãýüÄzãüvä/Ühý£||ãoå,ªÜ©uÖ_.>ßýbåää|üð/ý.BO:ZCu©ß<£ªãÄ@ýß©vöß:>:ä+åvCBª£.o>Z/*,B_å~AO,rO+åÖZ£>rö¢Ð~ðuö_Ðä'), ('ur|hÄðu*Zýðü_ÃÄÖ:ä~*äorO|üh*vaªOðäv¢<|OouÃbä.ßoßU.zZ>,ýra¢boýv|_Ää+ÐaOöC@h_::zBýßOCÐüß+Üu£/üö+.oßã.~|AbOÐåî@Z.buu£,CªãîvUbv,ÖüOoÖ,£ªî@/ÜBðaBåã<ß~OÖZüZ|ýöhz<ÜÄ:ÖÃÐÜðÜ<*Äu¢a©ßß..¢:ß|rîr:ߣ©Üröa.>U.hb|bCäbb+ZîoCÐðäzðå_ß_*CCß~>vªªo~/v*b.©Äoßãhî>_AZbÃ>¢ÐªªÐ/ðzv|ßÖÄЪÄ<~ßðUO+ýÄOr£v_rrðC|äß©¢£<+/¢Ab:Oîß~ÄZÖU/+¢å_uZAÖ*ªã~OÐîßüo<åÜÖü£ÖAÐ:ü>ðOåh@rÜb.oz©v/UäýoðÜÖCZ+©ª©Ußr|~ÜãéÄAuÃAîÖZ~B>_,åA~_OÖßî@<ð|@vr¢Ðå/ÖªhöðUÖä,ýß|BCåðoýb~BîÜO~zh@£|ÃãrbßßÐb£Z:î/îÐðß:£+A¢ÃZzãßü,¢Buußzö+azbOB*Ühr<ä<©>ÄäZ@boîÖöüÜÃaOr©ªªß|ßC~oðvîoC+ü@ÐC.,özUß:v+B//*ªð_åUÃBÃ~ZC~ÜUÖ£~avöåÜãÐZ+ýC_Ö>Ö@özU~>Äã£:ßBßÐ<_Ä¢ÜBh<:ãbߪîÃühãß,bßö>bBZ:Z:öÖð|å:/ðü,ªA@>oÜîßhÃZýZ/££ªr|ÃßÄOýåzåAAu|uä/ßAzZ¢oö<>îuär+Zªåä@ªãåäÜîCbC䣢*CåUBãªãZåÐzCßZÖü_ßO|bÖ:|U.ãC~abÐBU|ãð£aÖÜ_/äCO>öªÜäÄðv|Bã*>ðZÃÐ*ÐåÖB|öãöåhÄã,_ÃvÃ/ßß/ß/£o~hÃÄAÜ©aZ.AÃåÃzýå/aoîÐhäb_îýÃðð䣪¢Cb¢Ar:Ðh<å,|b©©CßZªz@,@УBbäbaöåÜÜ*ruü£OÜÄO/üð@îv~Ã|bvCÐ|î,B.åB<ö@Üvz<îã©.|ßrBÖЪh~>*.ã@©¢£*ª_ßî¢Ð>ªvª,~Öß@@Oß*BOOöA_¢AªðßäªåaB~ÖABhbääbCÃ_Ü¢A>>vª¢,zBBahåÃ>ÐÜÃÖÐðÜhÄrb*zåðãbUýåZ,*v,ÄU£öbýoO,**ýßbÃv+Üb|Zb:OUöîåßO*:/,'), (null), (null), (N'råhð_~ãZOZ¢öªUÄb£ß:ÄCBv.raî~.bahohåÃhhð¢.©ÐªouÖOÄZ,äÃ>@BªÖÄ_©UåhZ>ß:,Að>åßZ<,ÃuýUÄåC©h:©£Üb.:.öoÜ~ZÃ/ZßÃ,îýärbÐð@Ðvö,ÖåhÃß.||üîrÖÜo~:~boåÄCýÜaBh¢zýb+ð_üoZbOaÄý<©u|ߣ*+å+©ÄUðU@Ä<îð©~,uC¢ð|ãö~a.oo£u©ðr@CBÄÃuZAðß*ÄCßzîZa/oÐÜ_öß©zbܪvA|Ä.|<©_î*å¢AªäåªäU*uUÖ<ÖªoðaðrUz@Zo/,Ü/£<@ßão>*ðÜÄu@vAßßu©özÐ@ýh¢z_ZÄ@*OÐßCðö@ÃräüArz>h©~vbåªbã<ÄvßoåvAß+v>vÐÜßrU/ÐhßßðÐãbÐBhr~üîÐýhÃÖªã:zvývz©r@ßBåö+o~ãrz+îbr>bü<**ÃCbÖbu_aBZßß@ª*CÃa_~.Z£Ü©B|h.öä||ðÃ_îu/@,ð~ö/A+¢ÐZO*_ö|bÖÄrUãß_ãbäBÖߢörßÄ~AîÃ*£Öð/CÖ_a¢+¢ßOAoê.Öå~ðªßB*ý_ã+_ob,~@î+/b_ã>,OãÖo¢Aý£rüåÖCzü>_,Ä+Ü/~ªÃB|hu|ðz:Z+,*~£zÖöOãý.AðBCî@_h©>U@hÄOz.©A~zßü~oöÐ.¢ßUÖ¢vb£AC£.ÜZ£ähß/öh/|_ß.buö_öößh@ãU>åä£|ZvA£ßaOC:+@ßUOvÄöurãÃ@oâ¢ßߢ£ð~Z~hv@o~bbãbª:ýîz~_|£©ßåßC*aru,@ß/ö@©barÜ©hÜã/~U£Ð>uv|zÜý@AA+_B+<Üo/ÖoaAöÃäb¢ZzB>O.Öo@O©ÜZZ./Ãa¢bßîb@ð@a<:v~ÄUoÃOð_oC*rü~@£:墪vÃuýã.Uª~Ã.vÄuªö@hªu>hã>Ð~ðvzZö*ü>Ðb>Ðý|hZZ.BhãÐvU<ߪz¢v/äUÄ:hÜã<ÖãbÖýbãhÖ©ä:££>vBîü¢ovZhOã:öC.©ÄUÖ:h/@>za:Är+uzã+ßå|ß,ð~ãª>AaÄ@B¢,£Ð|ü@:ý£ªÄ|Bßö_ª~Z@BðäãäZãA/Cr~_<ßîÃÃÃ/_*zÜö@ß+üzrýB_ÜB¢ã|a>ýåOÐAb>ßêĢabß,B<ü¢OÜ'), (0xF502D70F2F74A32894021775707AEE3D8601A0E601FF565636A220DBFE213F3B143FA70B33712EC31501D0202A6125E5EA13FCD7F33991F6AC80D88D53C82A73C3DB6130D3E20914D2DDD1002E352BD57D3AF1EA246748DBADB05FB398A16F4DD75D5D4F00F4120709E704166891C77755030F18D63F4F5C9386822283567B316D8328D0D8DCD58828E9E13C6232731CE9E85D95915676980E01BB7A), (0xB36CD3A8E468F69E792D86F0ED5E12F9611266399BF8E6A0160D90C2D6205B1638642DD08F898EB3F249E4670A66883AFB075A670CB6E9BA853292D7D834C758D270B889304269D884B24751147E95B08456C6CFC6F40A817B734A5CF7B6DBBD818C959AADFF09B99D82E2596F97A6079CE153816DF892DE65370DBDF80DE0CDD689D087E9FB03844C0D314311B012E3CC43BF15635A4F88FAB63475F14CC090A11583E5C61E1DA1DECE3460C64ECDB4252AF0B54DCB697C39488D33C68D93004CA1A2FC2D2C1DAD251E379525EFC1ACE98050C75B0B42D6AB06AB7E91EADA503B331325ABD186F80C42902F94D4564986E14A463DCBA5415ECC5026809E1C3A43E65AF1DC9C0017F957BA187B1341D6AF61F8AFA09412), (0xC6DF805F786E2655EBAD7A656DE9E1324CE6118CC54A8A79771EA66D99AFD4EA630AD621979ADE4CF22528945C4AF40FCE6E482B5E010C7B5406E85AC8B9BC3CD98F016313BF9AB208C49A9F22F61D2C2A979E2A67A88C61FD5ACC91B184843969ECBBCC4890FB0ED3952399666D585EE8BC2F301A91D43003A066B9F3090083406136363A50E3999B9056D184F2FB90016EA8F554531ED7178AC9A82A421BCA95A0590536222398D896958A3A03AC10A5D5B784610B2EEC435E1FAF863B6E58758C3BE399F559DF4A0F1CBEBD949C13DEB903548A96688A716CC1D70273119D283C15AEC7C877AF7BD83A52EE702EAEC20BD1CD3719CEDE24B1722C3382DCD6FD7F95817FEE4B154254D8B25C169B003D1315F7A244650E6E368A16564A7BF9FC63546EDAAD2FD4C0BB8BE3401B820D1571EE206DE534B9198713496335BFF7D9DFB6F8C12C2590E44036E6B882CD52B37C00E45B5A8C172E9A55539AE6708AFC93096165894BE94B5E3C2CAE4E0196BAC095E735DA9B7E529FC927D7D2F6FDD0ABEA24786BED29301699FD1E6068E099BE98D950885521F88B0EC6C0241278673E5B0263DC1D4ED26BB71E409E60F236E88E), (0x94ADDFCEF48E90FEED2E4587B4401554C9C0B58BC1F60BDC5FAC801266895C178DCFCFF21C6CC699418336F7775A9C43B83D7D1E3BF6AC9EA2036E480D7E9864D12EF9E57123385DF91C4A3DBF1464050F3D5A280B3EDB9722315018FD7E8BC2EBD2254960B7D2940420241EAB6EDE8E9F6938D0236F59935262C23FD320607B918752EDEE1BA5586AC524EA1ABCEBB452C1799346BA9F7B7992F6FDF592C1E4C0A98D231CF19F84C4DF665E4B6E7995770DED11A7CC34D6E8D6745C24A863D7033F29702FC7976022F4CF665440300A196085E7A4B03DF475B73B457D425F1C7C8E5A0B440866B0768CEEB2FCCD82A7A66A43C4227B32530235FB778C51E3DF95B3EAC5E624C510F9D57117C18AF7A735939F12FF9BF9005B06080E0DEE2324A90F1D49E3BCC181A432CA4C0A1A92773E5342F8B2D0DFF9B9E96ADF1BB6030BB14C6EB26DA0CE5D50F7DCCD55A66C580B04ABE0CDD82B7FE6BF2297ADBA64DF606C88180D8069E505620B6FB4D1D345BF1DFEA213A4E6993B8C091C9E37B09592FD6CE91E534B8B9BC6DB6BCCBCCA15ECDCD78FBCC1CCBC85EFDD80764C47CEB176DCB764EA276BD272064DC97BCC7EC2F330C25F21D8D030B0632E76CA154F7E0CBA56E012B101B46BBC4ABB7FF20A225EBD821B846E909D0B), ('00000000-0000-0000-0000-000000000000'), ('2819-01-08 00:12:52.445'), ('2079-06-06 23:59:00'), ('10/31/2016 11:46:25 AMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/0110/31/2016 11:46:25 AMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/01'), ('03:46:33.6181920'), ('2148-04-25'), ('0269-03-15 01:59:43.6050438'), ('0001-01-01 12:00:00.0000000+00:00'))"; + break; + case 2: + $query = "INSERT INTO $tableName ([c1_int], [c2_tinyint], [c3_smallint], [c4_bigint], [c5_bit], [c6_float], [c7_real], [c8_decimal], [c9_numeric], [c10_money], [c11_smallmoney], [c12_char], [c13_varchar], [c14_varchar_max], [c15_nchar], [c16_nvarchar], [c17_nvarchar_max], [c18_text], [c19_ntext], [c20_binary], [c21_varbinary], [c22_varbinary_max], [c23_image], [c24_uniqueidentifier], [c25_datetime], [c26_smalldatetime], [c28_xml], [c29_time], [c30_date], [c31_datetime2], [c32_datetimeoffset]) VALUES ((1824541628), (28), (32767), (-5982062), (0), (2.3), (-3.4E+38), (0.4893), (0.9114), (0.7207), (0.4408), ('£åîýÖö£büªü*ýhÐî@.+uðU,ª,ÐÐößö©ÜÃr@üvbo>ä㪪ðÃ*.üÄöäöB<ð©oã>@ãb.ßЩߣܢ:Uå+B©ß©Ã.*üBaßߪÐ~zCu©üAÜrÜrA_Ürb>¢bÐ,vä>hbOäü,aîbbb:@u~î**:a:£ä|ÜA@oÜä+Z:¢b~ßoßßÜzü>ÄÖ~vbh,bãäb@r¢BðåährÃÖaåhýCO_¢uh©,äa:UC¢¢Ö@Ö,v/z~¢öB©©züî~åUÖCb~UßvöÃÖ_.ý,zO©a/Ã*,|:BCä_zððvåãÐ@Ãð>~a<¢ãB_Cv*hzîhrð,|ª>hðÖ£ÖßU_o©ß>Ð_ã©äÖÐ*|ýªOo¢AC©î+üB/+£vßåaãaö¢_©~+z|b¢ßUöh*|>hßhäUzã.ZOO.båÐ@_Aý£@A©ßCäÐhã>rzÄ*ÖrÃhÄzÃvZOChaÐBÖ/B+ðýB'), ('.~Ã~ßüåÄÐh@ß,*ÃöuÖ>ÄüäabbbBüß*£b+.zÐýÄÖäðð,>/<ýAöü_vv<_~/>oA*vߪz:Ä¢ÜO+rÐ+z_îBhü.å@:aUzãߣÖðBv,öðrý:Ð,:_B>~_,oývC~.@Ä¢_C>O.uvî~oÖüU@ÄAuA/ý+@ÃÜ:£©<ß_äåuZ©äö|üuvOð.ß/ð>|b*,bÐUA:ÐÐÜ~ßBbZäÐöãäbÃbrÄoªvýAÄOîÐO<ß@A£/ußr£>BåBðÃü£Äa£*åAB/oÐÄb.å,äßbuîr/äåã~ubÐOb+Ð_rÄ|hð>örv>BhUªÄaZä:b:ZoÖ>zßAÄýÃ*zäézÃhÖöýh+ÜÄz£+Ä'), (''), (N'Bî|ß©¢Ãð>ZßÜã.îbÄ¢ÐÃC:hßýßýo©aB>/©ÜÜB@a@bA>ä_aäðÐZývr**O£höOªu¢bövvüðb:,aßAOBCa+Ähä|Üa©r©ÃZª+ßÃu¢<Ã>>ãö~bå<.zob@Cª<:+bzö¢bzuÜäArCß|£/@äåOZ<î_vå@¢ß<Ö*uä~oÖå/@Äßuävv@ª:b¢Ðªvbª/.*Oߢý.vååðý>â:,<>UAUa+îOÄãAÐüßüÖ*|uÄBßãª.,~¢ü,ývuß~+,h*ßð/v|UhðhaÐ+bu©,Ã.:ä¢ÜvuzäÖ@Ou¢+Or.ÜÃ_Z+v<:ªuAîb|/îöðZÄA£rüÃ>¢Öî,+OäãîÄhCB~o*ÃaZöÄüÜ*Ã:å>+h<~ªä©Ä|räãAu©ÐÖßãÐ|Äür©Öߣü~ÄðZ,<Öu|@uð:Üzb~äªoö£ovðäbaÖü@ð|©Öî>rz¢ßBð@brãz*ðaä*h/ã~ö££oîÄßüuîuÐ/|,|ý+ãÄ©uÄAÜÃßü©ª.uðz||©:î,C|ßzª~ð,£z+ß~CðÐð¢.uîäz£>aßBaßå_::ªC..:OÜ:z*u¢£ß.'), (N'bbÃ>vUOߪÖß+ß/ã*h_ßz@Or:<_ü.å+aÄOOã<Üüzårªã:öb>ð.v@v¢@CäãuAÐZßðuÐCO£ª+|orîBð*Ü>.AAaªãÖbÃbü¢|ðªª/©ªÄãåäzbÄ*bÄ.O_bУÃUß*.ýA@|¢ÐauªzÃUÐb©@oÐöå>Ã,vå:|ãZî+£*rÐß,zÃzÄC<,ÄößabC_@ã:îz£u©OoOöÄüAð@*ähäA¢O,ra|ö£|Üo,ãßåz/oh£>o@oÖ/©aZ©rý©>rv_B£©Ä|¢/Ü*CuArðÃar_<©r<~îð+å|OÄ*ª¢Üz_<öö_B./Z:ýbÐ@ý:üЪz£bÜÜrÐä~¢Ü£//¢o_v~ö|ßAZ:öZoArU,åa<Ã>ÃoÖßußß_ß|£C+:O,ßb@ªÜzßð~ã,,,Ö.üðÃãCãhzýUÜ£.£A©ÜbaBüüBÐ,*ãu.:/hboÃOêb_£Ð@+ýÃ/v_oªZ,©:ýãü<ßýîî_ߢªuüãýoa<:U:ÐÐÄî~ÄUãCÜ,ÐÃ+Ähv_Ößü_,brZÃo:Zîur|BUÜå/O©ÃÃär@Z>vaÐðÃ/å~b/oî+,*|B.UBîu/CåÐÃrz*å*.äCobÖuUOÖ_ßbbAr£:/::Öbä,Bv©ß©vÄ_ã>>UO@*OýðoâbßÄ>~äð:î©ßUßö>|:@>ßUu||ü<öbU:ãåoÖA:üzB.ßBðßÃý.|ä£|.Ãå,ävo_CðãO<ãðBAðA~C/bahZÐåüb.u¢å/rZ,oOßßü>öð<ýÖî+¢ßb/üªäu~_Z|b_¢|~.Ðß©ÖäÜz<ªbußÖCbÄÜ.|<<ª/hª£_Uðö*+î~ABÃäöZB@aßýÖÜo>+ÜraBðC+_orub|£ÐåðoBüaîýoÃbob£ZCý>£u£u*ü/ÐvÖ<~,:bzbäoª>é,+Bvã©@ªª~rªª©@@orª:Ö@~Z£bÜ~:ü.ýü|UåuêbÖoåaoä>£|*ý.îUðäÜߣÖåðh¢ou£A/£Z<ª@Ã~£~hÜ~hACüaBÄ¢,B/bärãaUãörßAÃ|+ääðä£Cä@bÜv©:ãö/ýãbZOÐ/Ab¢zOCîî.üß|O/ru©råäÄr_h¢zbßOªvOC:åÜaß©,OååãZÖaߢ/bZäÐã_>ÄäbBÄßĪ/Ö_/rå|@Ããzä>z~bA~OOîvÄbU_bßzboBüAåý<+.|_ßOå_Ãý,ZabC¢_ÄoA>O©ßÖrª©uå::ªª©o££Bbã_|_Ã@zAA>:zÐöüOÐÖߪªrZß|öÃ.,üüåªbrü¢hCuå|¢Ö/CÄ©¢>/åä@<¢uÖýÐãî£b@|УÐa~ª£|Äb~|,/UAßî_BAB¢ªÐåh,.ýî|Uå.bð¢ðßUzß/AÃ+~>ßCÖ|._£Ahvâ¢Zzüð©Zo,Bý>ÐZröA_@äߣå~ärÃãüCÄÐäUð媪ÖýÐ,@ã.Ã|rrUO~_¢ßü.ÐCÄý+ã+_öb_ã@zZb,A:ä<öÐ@äUå¢bCª¢ÖßrzrÖbBB*_ý¢CöÖ<ã<ðBÃCýä¢ö*ÜC/Öb:~ü<ý/|uÐ,.UÐ_u_rb©oý*Ð+Övª~ªroÃî~îü@+üA©+öaý+/Or+_baC,.Oao/z*Ä|Zzý¢£UaäB£@¢,Ä,.ä.,UÃbÃÜO>Ü@O_Ð*©.Щ+ß|ö*Ãý,¢ÜA>¢Ö~îö<år£r:h>@©|îOüýüÐbAä:îýBzo.<Äð©:ýbü©ãЪ:ÜaÐ.Ü壪.ÄB+ÐUußß,£A_brßå¢@>ð:>z/u/ª@OzðCåbýãzÄÐãOä:B~îÐßö_h+hÃürÜð@ã£Z¢bÐî©ýrü|ðÜ©Öªbrä*Äß~©O|ýrBÜb,rîOîu,,©UЪüüuª>ö+o~boCäÄüîOð:î/îoÐå<ä,©ãrBýOªÃöü>vТ>zAß*OUÐåbC©CZöu/Ooß/äÃbC©Cr£OÖCÖ/ö©©bü_üZª£,¢öߢî/åZB/ßö©ª.@ýöa/ÄÃ:Ö/:¢h©©oÄ_¢îö£¢~Ü'), (0x86C692589A736BD5D7741E6D8EDC33FC5A4F6C421A5C4C55BD6451787A0876B28E0BBB3043DA32E3D11102C09DAF140B4A7C978D0906B22A793D9B3521F35ACFFD6CDE822103B87F1C897108598BB70E4F452DFE70E9A8885990B6063FFCC1DEB733C230D092EA47C417708094A9D0EE858DE6DCC55B5E14C45629914CB14020C8925126C8873DBC5BE63A597927F3B0C0C881B215E5195BD4AE6C7A6958FA12D74FB80257A925FD4F2980DE21059B9C6278D084308D0AE279F5521A1AC35302EB2781296FF15816A28362EB643A39CE12D017F08876E14A44D589554060CC000EC08828B7), (0x8EBA1C29159FDB52AF42A3AC3A50B9435455115E29EC9B7BD911), (0xC1C8537B74D6971F9B7E417596A6FEBC20C5BE0645D461D401A5A11EA15004526209ED795031C6792223B9D7D0E992469CBFB94C8E7203ED667F7ACE34787E4B7AEE128DB9856BEFFF44E3211A8A0317125B81E197B7C3F006FF12D0B6F745A9A56D5DE1D7058C1753CA4C4A8EE1D2DC7B62BCD8F69CB3C22A2186BA729B3807FF3A7CAD2D223F0DCF6A8ECC6B7962252C3655543B6CB208B99AB7B67ED2A5B892454B546425AF5922AF098C0EE757B0BE618D3B45E3CC938773F3926A898EFCC4D53A262E0EC00687FB318C6225F9D24306F71D446972AE78B8CCF1321CEE99200DC739AC3182B0A187B449B240306179204E649271B75B628CAD7641CFD36A0D986B545DC0261284477BBDB428FB37876B7712CE8A06AF556CD61F830B6ED2B34A3C19D5DB03B9F93BDF4AF5F9A63A9075EFD658C19B8291BBFEF1EA078F78D9A90A6AECE262AB67BD1892AABCB95CC69C8E0D1C977AF1AEB98819DC12CEF2AC67714CEF3C4DAE13436F9AA809D8D501A22B4E78825C412F18BB325A48CE55EE26E5434B6D6C894EE0F9D827DF48A5E1B2183AE7807A2A0A2F1DD6811B54CB751AAB8223958A9436A1FF9888841A4FCF1651A72F946D6EABBB381B509608338B2E620D33C6814C2884044580E2A28615CD066BC9AD9BE1AC3DD6685C6E439F98CC0C5A210C1B0994057EAB9027EDC919B206838F9D69DE928160F6EF18EFBA4064ACB4D5476508B1FCD6C32FEF5084500D4FA967C00FFB622EC79FAC251A7B15C36B2B7B38F4D14DFED193C7A6AEA230DCA5E2C946528054B151A780C55C8BE25AAD6B84250917187E5C69EE7C34BC7F246FD07F38B2CF71EAD7C9E64C5088A246B16CF8431E0BD28EC94AEAE891D87C95275C568B0BA9A8DEF9994D3F30CB2ED4C7A8CBC8C33C0663FDF16E67E58959FE4D5125F432163A07C41A4984BD925DFD1C1621E80DB4D2EB55F28E1A3B40F870404FF2DFA639A2B16EC403A9F281A56A94714ACF6770F1987E3A9E3F871FCC8421D9436EA07D57E374707A48B128F9D34D2385C9F52908D05D5A606C9A62294EF87F87183E37CA171A675BF7F6A8E75641CAF2649A028EF7D07311461CEA4811462B5031A0E09516596EAF8DCE11DAB4730A2BD070C4B4F5F09048CA2584FA2F1F4AB0CA57B5B56134DC0B2B520129BF995CD211BF78A082775A401097CBF0D473806E84600F5DBD55C99B94B988A3EF668930C9B1E96FA6A92E53FC74A4C969E36B8D292A55E8AFF15BBF5DD0CC8EEB751AA0E9A26238A10C7DA32BC6049B10031A882D0D05CC02AA6CA9C2D79C99C65654523F9BBCEC5132EC1CBCB2CCE9ECC0AF5AB64451EE7F4EAE3F45B865C96FD3DCC561B25B84563E26FA10E91F5FDD82BD023841E381F465D2E0FD7DA6A8CD1240CE0A), (0xDB77416314031168D028CBD1E9CE16232C86DBF947B3FE044AE2B215E69B415F8A0FE62298D220172A1BACB3C4C6DBF478C614482F8DA728793D183251FB8135E66B47DAE8F48A5966C3CF2B064A3F8406BE9C1F87F92FFC68BDA95ABAEDC62E9A77CC587F010C843BBBE26CBE7B212FFD942B935E62AEED3B4A712A4A309F78FCA0918F7DE60405B118E3CB17C23EEC9C7A5C25C133CF38C9DF1D348FE23A0B1B69701DE991B1179026E1467EE2D6790C848DD0D379B7C8D059C59DC9D076CFDDD8AFAD5221030AC845959B5289B9E708A3280A546938A1B2A74C90CC144DC0B01168A6322926EB8182078EE41C76479FDE9425A76B7B74A00DFAAAD4723EB4F7D5EA402013B4DF7D3D88D161A9BD963104F1ED7F28184496F406242E7B160F4353960F3136268B29B5A86AE3A912F6506479D0815135CFBDA6A92C0D90B10126798E0E12AE64FADD65C4CA4561208EBF933D7D472DF203F1509C7CC902970A9BAA57F47A0DCC23043399B4BD1017305A094F4627C97AF6376439A9CCB595ED544209ACBB0C13B2C61A7913933D45E1396B21BFB351E2D13060BC16D322564E9EAC607B076B744EF69D7F0D506662F91E58706094D53A025F377C5A4FFCDEA3C32B75E7DCC9D9CDF6D3C915D1D581C9FEC3F77BB2F5BAC9725D1CCFEF19FEF9BEDC4A24F17A1C547EA26AC00B243189B5B25C8C0563F1CD71AC757FAD0ADEDCD5D056F58B5DD883A6A2FD0F8BF9BD4D2C93193CBD71F45BEA7CB344059DA773C48DEA3BCD3CFE58D9), ('99999999-9999-9999-9999-999999999999'), ('3033-06-11 22:03:27.832'), ('2034-03-25 03:58:00'), ('10/31/2016 11:46:25 AMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/0110/31/2016 11:46:25 AMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/01'), (' '), ('0338-01-15'), ('7589-10-29 06:22:50.6660670'), ('0001-01-01 12:00:00.0000000+00:00'))"; + break; + default: + break; + } + return $query; +} + +function Repro() +{ + StartTest("pdo_fetch_bindcolumn_fetchmode"); + try + { + FetchMode_BoundMixed(); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("pdo_fetch_bindcolumn_fetchmode"); +} + +Repro(); + +?> +--EXPECT-- + + +...Starting 'pdo_fetch_bindcolumn_fetchmode' test... +Comparing data in row 1 +Comparing data in row 2 + +Done +...Test 'pdo_fetch_bindcolumn_fetchmode' completed successfully. + diff --git a/test/pdo_sqlsrv/pdo_fetch_columns_fetchmode.phpt b/test/pdo_sqlsrv/pdo_fetch_columns_fetchmode.phpt new file mode 100644 index 000000000..dff299826 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_fetch_columns_fetchmode.phpt @@ -0,0 +1,646 @@ +--TEST-- +fetch columns using fetch mode +--SKIPIF-- + +--FILE-- +exec("CREATE TABLE $tableName ([c1_int] int, [c2_tinyint] tinyint, [c3_smallint] smallint, [c4_bigint] bigint, [c5_bit] bit, [c6_float] float, [c7_real] real, [c8_decimal] decimal(28,4), [c9_numeric] numeric(32,4), [c10_money] money, [c11_smallmoney] smallmoney, [c12_char] char(512), [c13_varchar] varchar(512), [c14_varchar_max] varchar(max), [c15_nchar] nchar(512), [c16_nvarchar] nvarchar(512), [c17_nvarchar_max] nvarchar(max), [c18_text] text, [c19_ntext] ntext, [c20_binary] binary(512), [c21_varbinary] varbinary(512), [c22_varbinary_max] varbinary(max), [c23_image] image, [c24_uniqueidentifier] uniqueidentifier, [c25_datetime] datetime, [c26_smalldatetime] smalldatetime, [c27_timestamp] timestamp, [c28_xml] xml, [c29_time] time, [c30_date] date, [c31_datetime2] datetime2, [c32_datetimeoffset] datetimeoffset)"); + + $numRows = 0; + $query = GetQuery($tableName, ++$numRows); + $stmt = $conn->query($query); + + $query = GetQuery($tableName, ++$numRows); + $stmt = $conn->query($query); + + $stmt = $conn->prepare("SELECT * FROM $tableName ORDER BY c27_timestamp"); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 0); + $result = $stmt->execute(); + $meta = $stmt->getColumnMeta(0); + $colName = $meta['name']; + + // Fetching with fetch mode PDO::FETCH_ASSOC + echo "\nComparing data in column 0 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_ASSOC); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 0); + $value = $row[$colName]; + CompareData($stmt, $i, 0, $value, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 1); + $result = $stmt->execute(); + $meta = $stmt->getColumnMeta(1); + $colName = $meta['name']; + + // Fetching with fetch mode PDO::FETCH_ASSOC + echo "\nComparing data in column 1 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_ASSOC); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 1); + $value = $row[$colName]; + CompareData($stmt, $i, 1, $value, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 2); + $result = $stmt->execute(); + + // Fetching with fetch mode PDO::FETCH_NUM + echo "\nComparing data in column 2 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_NUM); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 2); + $value = $row[2]; + CompareData($stmt, $i, 2, $value, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 3); + $result = $stmt->execute(); + + // Fetching with fetch mode PDO::FETCH_COLUMN + echo "\nComparing data in column 3 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_COLUMN); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 3); + CompareData($stmt, $i, 3, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 4); + $result = $stmt->execute(); + + // Fetching with fetch mode PDO::FETCH_COLUMN + echo "\nComparing data in column 4 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_COLUMN); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 4); + CompareData($stmt, $i, 4, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 5); + $result = $stmt->execute(); + + // Fetching with the default fetch mode + echo "\nComparing data in column 5 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 5); + CompareData($stmt, $i, 5, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 6); + $result = $stmt->execute(); + + // Fetching with fetch mode PDO::FETCH_BOTH + echo "\nComparing data in column 6 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_BOTH); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 6); + $value = $row[6]; + CompareData($stmt, $i, 6, $value, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 7); + $result = $stmt->execute(); + + // Fetching with fetch mode PDO::FETCH_COLUMN + echo "\nComparing data in column 7 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_COLUMN); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 7); + CompareData($stmt, $i, 7, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 8); + $result = $stmt->execute(); + + // Fetching with fetch mode PDO::FETCH_COLUMN + echo "\nComparing data in column 8 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_COLUMN); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 8); + CompareData($stmt, $i, 8, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 9); + $result0 = $stmt->execute(); + + // Fetching with fetch mode PDO::FETCH_NUM + echo "\nComparing data in column 9 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_NUM); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 9); + $value = $row[9]; + CompareData($stmt, $i, 9, $value, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 10); + $result1 = $stmt->execute(); + $meta = $stmt->getColumnMeta(10); + $colName = $meta['name']; + + // Fetching with fetch mode PDO::FETCH_ASSOC + echo "\nComparing data in column 10 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_ASSOC); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 10); + $value = $row[$colName]; + CompareData($stmt, $i, 10, $value, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 11); + $result2 = $stmt->execute(); + + // Fetching with fetch mode PDO::FETCH_NUM + echo "\nComparing data in column 11 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_NUM); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 11); + $value = $row[11]; + CompareData($stmt, $i, 11, $value, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 12); + $result3 = $stmt->execute(); + $meta = $stmt->getColumnMeta(12); + $colName = $meta['name']; + + // Fetching with fetch mode PDO::FETCH_ASSOC + echo "\nComparing data in column 12 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_ASSOC); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 12); + $value = $row[$colName]; + CompareData($stmt, $i, 12, $value, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 13); + $result4 = $stmt->execute(); + + // Fetching with the default fetch mode + echo "\nComparing data in column 13 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 13); + CompareData($stmt, $i, 13, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 14); + $result5 = $stmt->execute(); + + // Fetching with the default fetch mode + echo "\nComparing data in column 14 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 14); + CompareData($stmt, $i, 14, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 15); + $result6 = $stmt->execute(); + $meta = $stmt->getColumnMeta(15); + $colName = $meta['name']; + + // Fetching with fetch mode PDO::FETCH_ASSOC + echo "\nComparing data in column 15 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_ASSOC); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 15); + $value = $row[$colName]; + CompareData($stmt, $i, 15, $value, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 16); + $result7 = $stmt->execute(); + $meta = $stmt->getColumnMeta(16); + $colName = $meta['name']; + + // Fetching with fetch mode PDO::FETCH_ASSOC + echo "\nComparing data in column 16 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_ASSOC); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 16); + $value = $row[$colName]; + CompareData($stmt, $i, 16, $value, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 17); + $result8 = $stmt->execute(); + + // Fetching with fetch mode PDO::FETCH_COLUMN + echo "\nComparing data in column 17 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_COLUMN); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 17); + CompareData($stmt, $i, 17, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 18); + $result9 = $stmt->execute(); + + // Fetching with fetch mode PDO::FETCH_NUM + echo "\nComparing data in column 18 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_NUM); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 18); + $value = $row[18]; + CompareData($stmt, $i, 18, $value, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 19); + $result0 = $stmt->execute(); + + // Fetching with the default fetch mode + echo "\nComparing data in column 19 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 19); + CompareData($stmt, $i, 19, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 20); + $result1 = $stmt->execute(); + $meta = $stmt->getColumnMeta(20); + $colName = $meta['name']; + + // Fetching with fetch mode PDO::FETCH_ASSOC + echo "\nComparing data in column 20 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_ASSOC); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 20); + $value = $row[$colName]; + CompareData($stmt, $i, 20, $value, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 21); + $result2 = $stmt->execute(); + + // Fetching with the default fetch mode + echo "\nComparing data in column 21 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 21); + CompareData($stmt, $i, 21, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 22); + $result3 = $stmt->execute(); + + // Fetching with fetch mode PDO::FETCH_COLUMN + echo "\nComparing data in column 22 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_COLUMN); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 22); + CompareData($stmt, $i, 22, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 23); + $result4 = $stmt->execute(); + + // Fetching with fetch mode PDO::FETCH_COLUMN + echo "\nComparing data in column 23 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_COLUMN); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 23); + CompareData($stmt, $i, 23, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 24); + $result5 = $stmt->execute(); + + // Fetching with the default fetch mode + echo "\nComparing data in column 24 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 24); + CompareData($stmt, $i, 24, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 25); + $result6 = $stmt->execute(); + + // Fetching with the default fetch mode + echo "\nComparing data in column 25 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 25); + CompareData($stmt, $i, 25, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 26); + $result7 = $stmt->execute(); + + // Fetching with fetch mode PDO::FETCH_COLUMN + echo "\nComparing data in column 26 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_COLUMN); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 26); + CompareData($stmt, $i, 26, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 27); + $result8 = $stmt->execute(); + + // Fetching with the default fetch mode + echo "\nComparing data in column 27 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 27); + CompareData($stmt, $i, 27, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 28); + $result9 = $stmt->execute(); + $meta = $stmt->getColumnMeta(28); + $colName = $meta['name']; + + // Fetching with fetch mode PDO::FETCH_ASSOC + echo "\nComparing data in column 28 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_ASSOC); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 28); + $value = $row[$colName]; + CompareData($stmt, $i, 28, $value, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 29); + $result0 = $stmt->execute(); + + // Fetching with the default fetch mode + echo "\nComparing data in column 29 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 29); + CompareData($stmt, $i, 29, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 30); + $result1 = $stmt->execute(); + + // Fetching with fetch mode PDO::FETCH_COLUMN + echo "\nComparing data in column 30 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_COLUMN); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 30); + CompareData($stmt, $i, 30, $row, $data); + } + + $stmt->closeCursor(); + $stmt->setFetchMode(PDO::FETCH_COLUMN, 31); + $result2 = $stmt->execute(); + + // Fetching with fetch mode PDO::FETCH_NUM + echo "\nComparing data in column 31 and rows \n"; + for ($i = 1; $i <= $numRows; $i++) + { + echo $i . "\t"; + $row = $stmt->fetch(PDO::FETCH_NUM); + $query = GetQuery($tableName, $i); + $data = GetColumnData($stmt, $query, $i, 31); + $value = $row[31]; + CompareData($stmt, $i, 31, $value, $data); + } + $stmt = null; + $conn = null; +} + +function GetQuery($tableName, $index) +{ + $query = ""; + switch ($index) + { + case 1: + $query = "INSERT INTO $tableName ([c1_int], [c2_tinyint], [c3_smallint], [c4_bigint], [c5_bit], [c6_float], [c7_real], [c8_decimal], [c9_numeric], [c10_money], [c11_smallmoney], [c12_char], [c13_varchar], [c14_varchar_max], [c15_nchar], [c16_nvarchar], [c17_nvarchar_max], [c18_text], [c19_ntext], [c20_binary], [c21_varbinary], [c22_varbinary_max], [c23_image], [c24_uniqueidentifier], [c25_datetime], [c26_smalldatetime], [c28_xml], [c29_time], [c30_date], [c31_datetime2], [c32_datetimeoffset]) VALUES ((-1), (null), (-13744), (1), (0), (1.79E+308), (1), (0.9132), (0.4765), (0.8474), (-214748.3648), ('£¢,å.uÐh.ý/BrýBãarýa,UåO/Üßh@<ÐuU+Oär.rvAߢ©O_ÄO,_ãýbUo.ÖO<¢.~£öUOäãßU¢ªaÐüª¢raîb¢Üý¢ÐoýrÜCað~ä:oÃ.ý©ä.hîuý*v~Ü_O~|ßß©z_aä£AC¢Ã:å@/ðßAuuu¢b.ÖãÄ£ýªã+ab£>,åüßr,aZ||<ÜhäÐo+z|O~ðÜOhýA_Üz/ßåö|ðb/aä¢ßãO+ö@håÃaÃ@:ð_Chobª@U+:|îÐZzvAb*ãÃÃZ~h¢bÜåä©:ªåýßzª/rð©AöðZ@Ä>ð>CBÃßãß~A:_Ð,>ßCZãZ@ö:£CðA£+©ãB,vü'), ('*îBhaÖ|üÃOv_oßý©.ýüb>ýÜÜr<ðO*oÖoã|baBvb*îOO/ßu.Z.rü,_aîaåÄZßv>ÐßUoOßbzävÜAÖ*|:~âZ_A_,¢ã£bC,üub.<,O£Aªrb+Ī>v~::C¢OüüÃvä_+OaOåîCbößý£î|ß.Ä¢¢,z@b,îröÜ©uÄävÜ,Ã>ª£A~ur+ý@ýörb.ÜOÖCýC|~©ö*.ÐBh+COBîCüªßBZÐ.,uý~ªãöÃ_©.~öaýbuß>UãoäÜBoZß~üaÃ,hr:üÜßîo:ã<Ü@üBý@|vß<|u+u£|.bC>/haÐ*Börbðü*å,rÐãÜzîÐ>r*Äö£Ärh/+©*å¢uUuÖoÜö@Öýu|azbÄÃCuhßü:åÖ¢/bb¢©_@ª>~_~Ðö_Ã~ÄÐbÄîbЩ|BÐßUß*ý_+åoC,ZªB.Ðo©ð_a*öC:ßÜUÜrªrª£u/.AbZb~|_OßhÄäBozªßåCOrUU¢~Ðü@OÄöäüzh¢£ãªAaCOäîÜAÃü+îýª¢.Zß:ðhrBZßÃß/OaCo£©åa,åh.*Co+Ähð£ü_åövruªä©ß@ª@*:B*v*Ä¢a/©b~AbÖª£Öh:©Coî/:vhÐb¢ßãßÄU,åªö*@Z+AvÖU*@uÖoOBh©îÃßUÐa£ðäzÜB,zöbÃ@ärBUðîör¢ã.ªvü_©AÖb£Ã<£/oöýhüOZÄ<ÃUð|£Öîz_.ß@vbß~Ðvrabß,~ÃbýðßU/|ÄhªÄ¢C.ýo*obäîîîO~uîbÃ/ää+å|Üü@ZýUßC:Bö¢åräÄ©*ÐÜObÖua@ªoa|z¢C<@ö|ªªãZ,ÜãðUýäoã.v_:üB~Ãîýo¢,hðbU~@ÐzO©v,Aãß©h>ÖýOobBÃ>.+äâéý£ðäý.+:@r¢UbövÜAÜ>/¢rýäý~BB+<>AªÄAråßhB,|©ö:ã¢_hªãðhvbߣbå/ZUbbÄ~©,ðbåu¢.Ab_A/hö~üÜ¢~îz©U|ßðÄßh<¢uäoU¢bÄ¢ZÐuüU¢£Ð>ÐvZ/hÃ+Щ@bZðªîªîß~üÃöîbavobÃýöOOubäOrboß_ö|£z,h*,+ßbÜßß+u.å@vAÃ~åCÃ_b/ÄÖ.hoý+/ÄåAÖz£hB/:v>ößr©|>UüÖrĪZö£bâ¢ßýßÄý>_Ðb/ßÃUU|>î_Öª©Ö.©>O/:+ýB/ßß>>hBuoAÜr_ü@<+Ð<Ö@öAübªhußbb+b*+å/Öb*ßz~|å_äÃüÐbÄîuª<Üä:îýå/Bö.Crª£Aª©Cör,AÜZ.BzÜðo|¢*C~öZ<Ä@ÜazîäªBb+ð.@*Ã_*ßßß,aßz|+A_CO,ßrr|aZBr:OãBOÄöªUvÖhðЩî>ýÄÜ_ãbüåýBOZÜÃUU~*¢|ªÖÜv+b:B|zbaª*©¢Cärr¢ÜZ<~@å*,b*~,Coßbߪã_a£ýЩ£ððÐ@ÃÃ,ýß:ZÃäoCÐ@ü<£>oå~zU,âhzÖîäü/£_©îýC**ÜCÖÃ/vhaUAoÜAor/zÄ+Ãh|ÜýOÃbüZ~£+ß|ßO@Ãv*az>åÄr,>*U~ZÜ©rr*Ü>ÐroÄÃ,ßö>+að¢:AÃßbåZýz~£bý+ªh+ªãÐr|hãªß@åUîhz*üäÐ>/C@Ö¢'), (N':ª>|åUvA+/ß,ÖÖBZðZ:ß|uCå~ßCbÄ~©Ö>,¢Ü/.ÜOB_ä<__ÐÃArãzzzðu>ªýbhO*ÜÖAî,Czä@@UÐA+£*AB/b>Ð+/o:.Zã/ÄbîrbÄ>¢*|Ð+*ßbªîäãUöýÄhãb.ªÐðÐaABßrßßvðã/Öå*h.~,~|_:~>Ä*Ü,Azîå.ßÄ*uüäÜb~ð.@uãßÄ£ãuo,O|:ªBåA:U¢ö_+b£ßoª@ß>ü_oü>@ýÃ.<©ÐA¢hå£äýÖ£*z:ýäÜoîooo_*Ãüð@O*A¢ß~£ý¢Uýîî+ð+üCb|ßB.hßýÐÜaBÜZa*Uý:å~vßÄ*ZZ£.avüb>ÖAãîuCOîo~:BUB*OuððB|ÜÐBÜBäoªÄ@bbZ_ý@+Ö*Ä©BuUUbrzrß*büðüZÐhhUAz:b.Aö|+Ãåo~.åÃ@ä@b£ä.ðoaB+~ÃÜu¢b©+£härB£ü@îo<|bZßå¢B¢Oî_ð,öªý©ð©|@Ð@A+ýzöaåîAý|_zvîå¢@<>U@'), (null), (null), (N'öã|v/îZh¢Zý@ðã/vÄÖAAAbubîh@b:*~zÜ,ªÃÜý<ýz,är<¢Z£ãuö_|rªîª>,Z.UÄvÄÃÐ|UÐ@ÐvbЩrAªvãäuu,AÖ|ÜÄbv¢O~bÃ~@ÜåÖ.BÄuU@>öÄ~îB:_a>î©ðOÜ_©UCB<£ü¢_ß,Bo<ãð+ã¢vÖAb,C~Ü<ßî:ob£:ßßBzbßbuåÜ£äü_Ährz,,ªZ|ý¢bA,~.ÜvOO©O££/<Ãßo¢<ÄßðbÖuãÄvã>vBÄaÜÄ£uÄ¢:+.ärAÐ||aß+*ߢöh©A|*._*Z¢,üZa:~ä.îüOð_£ÃvÖbý,bäüa>ãOhZbßb~ª£Öv||u@ðð©ÜrC.äb©:+ð|_ýv@¢,ÄBähC+öýöýr@ÖåoðzUZÄßvu.,Ä£ACÜaAöäßßb_£ãO.ðb<ö¢A.ª©auî~:å<Ü/Ðîåoýo~åB*äߪ:_,*Oö:B¢£@BýßAZ+ö¢ÜuCv_ÜbZ+ÐöbÐå/Ü,OBÃ_*zBv+ba*|ªÐ.Ua,zUä~C£b,©ªÜr|b£BvUb:ðaaoÄAößCr©<äA:Cz@~åUö:©ªä:Zî>rýÃýÐZ@ðÄ,ÐÐ<ü.>ÖîCb>A+£Ð.ýbö:£hhOarv~ªv*©ö_îab*åB.ü@~ao£bvzZ:ýUÖ~ªvüOroZãÄßBãÐÄ*©Oãbã|oã|uZZüî©Ãß*/ß,Äåu©©äObßz~ü£vhrbðABC£ýäaäßo.A.Z|Z>üßaüÃýÜÖîÐz*£@>Ð.,ÃUbå+£ßbA©Üðv/+ßO,bü+C*åBhÄ_O£îzýîäA/B:,o£üCýü<åüã*CÃ:A~ðOßuövå,Ü:ð,|z+Bð©ßÐouîCÃß|*Zߣ_åvCuZr:îÖ~+_Ab*£>UOa©z/ÃZ©|CÄ_Büß.@ZrhßÐuîü~å+bª>îäA¢¢å|ä:ö££zOu>,У~b:*<<ÜÜ+äßð~ü£ßÃb+O@ö/ÜOobîÄÖB>£:a:<@~oãCra£abÃÃ,_:A_h£¢©hz,åb¢ÖzvhüO*ob,üãrÐåO_üra£Ð.BãOã~+_ßr/+*oOß:r©Ðvãâî~>£U,bÜ*zOh>|bhC@|Ö.ã.ÐýÐ_ý*ð<~.uvvbÐv/o©AaüA*åo_ªÖvörboÖ£_äb/.äªÐvZÜb.UhªÖß,Üö.©ßßzÐz+Z/v>hÐÄÃ<îO.ª©£BðÄ¢bbzÜ>**u,CZC@z./î|ßã~å:@öååÜÃUa:/:/vü©Üoß>*|OÜÃBOUÖ|CåAO£ßߪ<||CBãÃbåC:uÜ£ab_å*orÜ~:>äü£Ö<£.ÃýB¢£_h£¢>Z,ªöÖC*:aB~|@©ýÃßÃ:ªîÄrÜýZä~ßßöüª~@CO_CãzZ:|ãh<:£öÄüÄÖîhÄ,ߣbäZÐü~ab*ZO/.Ö£+:CÃ|î£_Ãrü*ýAä_*å¢bZCöª~ãövbZb~üB|ĪÄUÐ/z¢@aUAA<Üã_ßÃ+u>_CÄö+:,h,+å:ªzßðßz:_ßZÖzrb~_ßbåU+¢åh~ZãråîA+ÖbðßîA|hö¢ªbhoüäbCB~CUbü/©+@*b,özü¢©öO>båbßCbOO/.B:bªßZavã_vîZ<+å~©ýÖ~ÐäO£b£a¢_£_ãbU¢z*_©¢.C©uoª¢:U>@rÃß+ªåüЩý£zåÐbruÖ|uCzhO¢rü<>A~+AC*oUåA:,ßa¢ÖßÜ>B,,ÃÄv.å_£Ð,î>u£/vvÜ.îö*ÄBäzz@/ß:>+B£å©ÖÐ<¢¢o£|å~,r<_ýbr/bý¢.b|arðö/CCý_¢_böv*Ob|üÖözüZ:.o©ªîb*£îª/UÄhÖ:,ÃäaðhðBäðb:*¢ÄU¢>aü<.£|O/A©ðö+/rZ|¢BZ@Uu~Ðüýîzvåo¢rCßýübZß@BUOð~£uAbbh*ýÜÐîé~vBÜßÖ*oZ/zª~ßðuýýîªÐZ©,UÐZ~:C>ü¢Ü>Ð@<,/>Ozvý,ßv~¢vUÃrãÃbÄÃuB£äb~öübarÐ@ª>B|ý,,äöaýßäUv.öß©ßßozãzuÄb/Öv+åÖ£rBvézãvb©Ar*©~Cr|ðÐ:ovuÖÃ*:rÖ¢öC¢bZ©Ca@üåuoZA+,ä£bßüarbãböüü,b*ABBЪv:b|/Ü|ðBöÐ*öª~Ãß'), (0xEC6077ADB74D7703D8702004DF829BCEDB649DCC4D2D2261447BAC0823FC3E796832A4884FB435E03B46CBFE47B3A046C323AECAB31AF1BE3D16683BA16EE0DC31A79CADDE127E272EBC910662231990DA6545004D73C54D40E54B394BFA3FCC66EECDA016F368B0A5879BF689EA5C1AFDD8603B28E08EBEE14F6CF8C745DB347DC4A073567879E7FD955BC6D7CEC35588313C739903A386600EBFC7866FE85FAC6779C54AE9C3845F783D9385C8E6128C176F9608679A79211A1247B9B2618EADFB197055FE0B9F6DB71420C50F019828AC3A6F), (0x5744CCFFA330D67BCBAC17AFE689AE75BC8E0BCF2851537AB311187A1F0C77F18E5BA4D4A4555ADAC9F2EC6709162977E9B3EFAC63302805F1524C92175B5CBE3426218BE5D9D0673331063664EB709DE7A1906B1CCB8E5D329EE35209C7C36D952D32E2F49E9110E288783229F2A105E1AEAB75CAF0A26997C35847F57E5E6C6D99A036B88DA84910808994525B3440FDDE715A1C4DA2A58BC94B3145491A642A0CC490516A4C530661654A660E173C8F184A170C034F20F6FBABEF427703C66525694697A3EE92911E54BAE8573E7DB20FA22CFE035727BCA49955BE7BE0B38B03E2C2EAD8B28E008FA25E0101545038E32F5C7423916799EF906D3E61EEBAFD0E85447E5AD00588E308B185A84E1D1BD2E26C4B833F68727B29FB48454F9EA0E761F37B10D2DD132AD4901BDFE1F0A172516B7F826E79CE1DD10331D4BD43936A109E475AA20B00045821AEAF4D9399395AD5F3E41E1D79E7245D3ECEAC3F6D91FCB1CE43A946D046), (0x294DCA1ED03E6AF879E750AF4BF2255F3544CC325719B31DB39BC4558F1405AC78A3F32B1C068D0063B4C586414C65DC1E49108B7938231099AD6B347A146865E1A337A7FEF9422FB7CCCEA3542DDC6635E83745037A323F80E3926F9A58854E4B5FA49D15BEDD2407E0D4AC697FBB6BD104FE92DD23616770F7261B67D3955E478057F5893E51770A123E23A586D50128269E955AF37128FD3C2D1E98C2BD334B7565E927C6E292B38787CAE43EC1EA2125F24035FF03530E2FF74C1132DE48550BD82F20ECD961430BE1D26BA643BF7A42FD73CF7CFD4B7112DAF8CE958180A83E75D96691CA344B91FC291D31E768EB38D2CE356B79D80D8CBD0E11E092AE8A612A2D316A59E878C8273E80D32E402A720D96C3B24B3CC59DCBD9D3BC236BFE4E9FBC07BA3680DFE9566D443B58395E7DE39FD3FCEBD715ED67949E7F14BCA5BB40313471396F3B8CB7D95CDDF88A44927B56D883980163C7A61953A2E25FD49AC888FB2605EC4374634644117B38F4DD4F0C03BEE321233ECE6CCB1F1C99AA5705C215708F1E8D8F13642051BC514C6E257652D55C16B6A764BC5798202357C99CED0CB923844D317F74AA7F00D2817C205DFAA646D4FBEF0B6D0BD2C6F46EEF0D57B5CF45924AA0282156E76B37A6923BDA77C328B082C7F21CADB5797B6A8A05BB72A91CB1378E125A7E257D1383D4C67896EB7DAAC75CD4EDDD28E59426ADB7CCE1B0C4FD7589A3E9B0CD325D4ADE99D8EF00E47E0D5AF315D42FD40EA87D33D06EB131D30FC9030D4794FAF92977A3FE8F0CA526C938BF87BCAF2946B49540339A62EF98ADC6C826FDD7377860FAEC5D8BD67F9BD70D0735F1AA16609FBC58B253C65FC7880A50C9447F29F2014626C2C2CCBADE15A55B8C5AB9A602AF6786407E8425999B24D48185B55757E41534AB84549ED3017A9CAD6BD26CCF634D1ADCF9E8737C208C269DF738585F4E03A84584FB7E5AC9B23F04E7782EC8B8051E379B7A5DFBA1B88BF72D00DCC8213C5F6729264A67CFBF1247A96E94A85D5EE5F11A20C4D3A6ADA3CC70862CC9D676E3AB18C79F91BBB668DC6816523B398069180DCFA1D1D0D28E), (0xAC0A1A39104D3AC0DBB7D2195FC6F99A86E7F70CDAEEAA4AE664091103ED297E9464964E1122AD619C7A5EC997FFAE08A73749EB9687B8BD60D053AB4429BDED8D5485FA30AB89643996706090E1B3E7B60069CCA43EE80CABD8ED41CF011C73BD703B437AB3D8FCADE5B1FF17582D7F1D6CF543BFF0494F6C784E57BD48943779FCA31FA5706C02286D1EBE8CE8F553AB6D23620CD9B4CC27EBD70165803E655079851AB50DD9ACFFF21B51D28AC28383FBAC5024312BA048D6F7BA996B9DA72EB86D1262DA9D9D9377631ABE62F99C28537E69D4EE411E4EE5D1DE161F1394547322191DB020A85D0EBCADCE10E2E6DC5B9145EC33D340774EC47D09BE877463CFC54A3FE07F7832D60CC53294503E02EB02BA8ECDA720A0E2A2CEECA39F9E874749FE4A98A6FCDC181316270D0EE2FE857B1DBCCCE59528A5AA5D3DB08C8F376D3EEA4A51F36A4405DE75BA91F992D3BFCF662781E2BA61B4D6A5EE49BE2B8C83DEB9CE2497AC9211D8B7EE70DA96AB17897DE12667B58B8488967B4D7BFB46B2E937B23FC4AF2723D316A82ACBF1D93FFAD6C0414A651B282E4A9C01314495DD703B87A3E46B53D956BD52510D60B896BD3B53A53B0568831B8911791326F28F81CBBA906A355B8E83E6EB8C12CA1BCD910544F5F0F0A26AD203885A5AD9C62FCBC3D041A5282C87DFC521541ADC70506D44E80DE2FC9E902850BD66AD0134AA20BBC04FFAD92768D9BC152BCF4D4FF69238EC15F0B84DCF253F19556BC5DADE9076345F1B2156941C803425E672C1DA00C6D475141EBA676DF129BBC0D1FC14E2379B5819F0DB70E158F9708428E8B37D3E55A5F065C972BCCCF129F89BD34B831F42AFD769C10FEA6393BC2549E34509763D827B56237D6D299B4DFFB2784684AEEC64E538DB147D46BB8DD20C4C72E9AB1F815D51CF2CFCC541AECD731037EA4C37775D7F60D09A2904359B95AB60DC29645392F7E933DEBF671FF62D46093683A385D4D414694B4FE7334C9991661AE1D1A40FBCA5F36304989E1740D96DE3FBFF18F2258C0714FA08430FB5E6452E0105155BA2F97ADDAF22D03C76520A757950519A7973F455CA8F15B361E3AD1E5370163BC4114001853A4303BBCB9DA7FECE956495ABB48D10C09112E4C67CCC74B2E8063BCFB068104F143E30F199FEF26DB5934D4988A8BB892A03802E1DBEBE778E09E3976C2F1D2D544596765C1E2793207611E87E2B29404BB2A4ADE8E1325680B9638F1B5A01857620F44312452C0CDBED0DA6ACD5F862E0A24CB98B6F4572133FF5A2BB9877C5758B725D36E62E058597D1FBD48BA9AAC001AF780E48FA06DA822FD24F8A504375473120639A2BF9744633F39E4A9E87954AE1BAE8FFB72D916B83B4B65BB5FB478D868C5A894726D5B504C714076890E3A83C05A8965B7590038FF7177643189038AC), ('46eb23a8-9377-41f4-8b05-9d93707c88e7'), (null), ('1952-09-02 17:15:00'), ('10/31/2016 11:46:28 AMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/0110/31/2016 11:46:28 AMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/00'), ('06:05:55.2800727'), ('5983-05-08'), ('2001-01-01 12:00:01.0000000'), ('3303-02-12 05:25:44.5483616+00:00'))"; + break; + case 2: + $query = "INSERT INTO $tableName ([c1_int], [c2_tinyint], [c3_smallint], [c4_bigint], [c5_bit], [c6_float], [c7_real], [c8_decimal], [c9_numeric], [c10_money], [c11_smallmoney], [c12_char], [c13_varchar], [c14_varchar_max], [c15_nchar], [c16_nvarchar], [c17_nvarchar_max], [c18_text], [c19_ntext], [c20_binary], [c21_varbinary], [c22_varbinary_max], [c23_image], [c24_uniqueidentifier], [c25_datetime], [c26_smalldatetime], [c28_xml], [c29_time], [c30_date], [c31_datetime2], [c32_datetimeoffset]) VALUES ((-831496210), (null), (-28188), (9223372036854775807), (0), (-1.79E+308), (0), (0.9942), (null), (0.8968), (-214748.3648), ('büUüî@ßOb©:+Uî>äÜÃåß.AUbC£@Är~üZ©BOÜhBbvZCªvîüý:>>.rbã.AÄOãUýbü<ÄoÄhÐÐÄã¢@Z/üoh©brÐOÖußÄhböUßvrhh~ÖvãÐÜÜÄ~:*CªÐaĪîåuvöðî:~ÃÖ:ã*zhZ./åß+:ü>oß<~|zö|r,*îä¢ã,.hBavÖBaüZ*ªãß|/vßßC/åa+ßî¢üýU:Ü~>.r+üu/Ã<ªUý*Ä/ßî£bãÄü_hÐO,ChAÐã~A*,+bZ~+/övÖ,>Orhbª.ðä@åb¢ßäZ|/å/.z,b<ã*>v:@Ðbä_.*üOßoÃUvð:~@£ÄvB©+|<ÖüÜh||O,ßÖ./>äA,@,ÜzÄä@r~zã~o/bÐzb£+rAUª>ä:oboAÜ©å~vªUÖî<|~uÄ¢r.Ä©C.u©OÖ_aBZür*åÜ,©@î~ТЩ:ußU*buoÄ@|äý|bUoBbh:©ou£ÖZCß+ßZß.¢UöZ©bbß@ã*î.B:©/£~~rßb~¢~Ü'), (' '), ('Ub~ößzä/ab£o*åÐ*OÃhðOÐuOãO+ÃBvö/hhbäão£*|r~@|¢ÐÃåU~/U/@_ã,C¢öO*ÐhuArßä@AAß,ýoÄ£r:©ßäÃ@oÄ¢_A:AA.,äã,z~_åaÐ|.b¢bz~vãbaý,ýCz*z¢ðßÜChCÄ£boîÄCåCý,ßÖUvöªoÃ|.bb/bÜ:ZU>¢+î@+Ã@Cö+åCvaÖ_~b+üOª:ªÄ£~©BhU㢢,aåUî~:>uz©Zßb©_O.ðZzaðzßÄBäaßBA>££Ö£*hÜ@Ä,Cð.ã_ý~öäð*z,b~:O>ª>/u¢ßo.ðåäUhÜ¢£ß,,å|ä/äuCo*v©båövðröîZ¢ÃhbÄb¢Ü~ÄÖvrbzöÐb|ý@£ßhUßýZäã.ÃîbÜO/ÜÐߢ*~¢_.äߣ*Oo,îßüäýãåBzðÖZb+CZC_ü*Ü,obr¢ãüO©_£uZaZß*/öãÃZ/ã*ßBa>bBÖuäoßuÃhÄ..Ã>Ãî©büðÜ¢AÐvÄÃîaÄÐu*_/ä©ßroÃu@ÃéBäoªhAA|Z<Ð@ª/ÜzÄüýrzuo|ÜAß:@î.@uAh£ãvýâzÄßÖ<_ªoÜäbã:vC>:üz~ý_+ßz~ÐÐUäÃz_¢¢>o©>hAhðöãaܪߢÖåC/aßåzðßäððOÖzã©£zÜ>o_äª.BÃ|ühÃÜZðåzB>ðãßO_ö+ã¢Ä:@ð:O_ðvýüB+|u*üÖ|ªZA<©C+or+ö+rÐ/v.h~uªÜa¢*h.|v|ã|OßU*ÃüäßBa*|*£Ö,ðZãO._üãv/h@Äßî£@,o/ªbA*ªðÃß>Ü.zrbCßZZÐ_U:AuC,U,hOÐoÖýÖãß+ßýðªî¢/ãuA~,¢£hÃuhAßur©z©ZAu~uzvüö<Ъ©_/ßZoußÜ~BAbÖªßAC¢*¢ð¢ªOUýÄZ/©O.b|¢¢ýöb:>îÄör@>Ð<ðãã.üÖðߢAo@_+ðî£ýOýrbO~îhAî£ýÖ@ýã>ã*ýBßÄß,ðîðü_ßA|@ZÖUå©v@ãÄao¢v£_Ääb~£å+v/ÃUÃüO>C¢:Uru~ªOb>vBâ֣U.vÃÄ:î¢ð<ãr.ª_©uî|OA:ZCUî@o¢vªßð¢/~ðß.o_¢vÖÖ.Ü:ö¢åßb|ªßBh/ßöÖa©åavßOüÐ/@,©/o|+äCbuý.ßÖ+a¢<Ü.~uܪªåÖCývüåüaðoåã|âÐCßUCö@b<ßüðüãå+U~*ßð:+_a+BäOã|bZî*~r:üª|ýOAߣUrîh_ðbÜr@h|:<åbÜý*ZüÃarvÖUCððU*Ð,BåübZ£a_Äß/£a>Ä>uOÄ@©~rÃäÜ©öãZUßßb+aBÐÃÃZ:üOߢÖÜ//Ãb¢uÐ_ÃZO_ýbÃ/|ªãöCÄ,@@AruªaåUaî_.ªrr~*ã*ß_oÃuÖ|¢OÜߣÐbO|ªa>ð©.ö_b_vß+.Uªv,~ü**ýÐvß_r+**ßÄð/ÃßÃÖ+Äo,ÄÐvýzCîöýî<åO<*_ßb,ÄCzßý|z~ýã:a£zã>_Öb_oß_*îUAuuaAÜ||~ZOußÜb~AÄu+<åu¢/./B|b+b:+AÄ+*ZO¢Ðz+,Ãðß,åaBª_Uvo媢*<ý@ðhÜ:Ö+uÄ.bÐÖ|äuÐ>¢Ä©bv<îCÖ|<ЩãoÐß/Uî>bA©zÃ_ß@ÐZ£åhÐÜz:©ÃåzýßÖüÖr~aÐ/ýßa~ÃaÖ~ðB¢Avãä_C,.+Ü~Aobrð*ö*u>ýä©bhobzÄBÖÜÄü_ðBrbOª+©.Üã@B:ð£o|bzO_ÃAZªz+bv©ª.åo_rÄÜuoäZÜb,¢*î£öÜüU£Z|@üßAý/BvoBuv,/:ßãh*Uîüîüü::zî¢hUäýÄÖürO/r>îZ.b_r>ýhBzb£|bãb_ýÜ,|öý/.ÐÄߢöîA/bª|îðußî>bðß*hÃCo©//B+*/£C<ßO@h.ar>bîb¢b~AâzÄvCUßÖAÐüî_ßh©rãab©<¢Z/,AbåÜ>bäð.îÜOoåÜAðÜba@ßððßä:uãhÄ/ãÖrÖäUuð'), (N',UîAÃhZ¢|äu/århüü£ª¢bvO*+/©Ao©_hüå:ÃaßOzör~är.åýªåZª*/_Cb~©vü¢ÐBÄzßã~zî*U,å:UZ|ö|zrÄÄÃ~Üh//aÐbüåîU£ãÖabäBA/ªhÐðß|Uö©.A.AÖAÄhåî¢O.ý_ý£ÄO_U+ª©vü£.>¢:>CZ<åä¢BÐzîüO.uOhOöOãb..b/ÐÖÜ,z©v:hbC@©ha¢u|:¢/Äî.:Cäz*ýUÄÖvhb£@ßou~ObÃa<ÄýîbCããÄ,uBrAoZCuBéýîÄäÄÖv,ä@ßÐ:©oz:ðCäð~Üä_zÜaö<üüa+<ßZb,+|:ää.,Ü+ýüÃzýßÖ/Cäz.ýv:,|äÄbO*A.|ÖZ<Äîªîå@<'), (N'ªÃ|,Aãu*A@îÜÃ**ß>¢<Ãa+ð:BaBãhßO|C:ªAü+OU*¢o+ÄîÄör_ãã~åC/bbÜ.~*bußÜ>Öu<ãC/r*,r~ÐOzo¢¢ü*üu*Oüå~ÜÃa_ö|ö/öÄÖÃÐ.+_Ðu>*ªB.ÄÐaAýOö+>|£~ðªÃªrZ©ßªoB+@îråhozý*:bBba:+aå_uö,Ðaor:ð,,o*££@Bübrzu£u>|ª@räZßÄ¢å.CoOÄðÐ.¢üvÐ*,ðÃuýzoU<~Ãubbª<ÄÜu.öß,Z~ãaUrßCBÄ@îäA.åBüîÐCu@*_+ßAÄrB.ª|,£ozîb£:ª@_oÐ/Zåh/Abvbb><î.ß/å¢Czz£ÖÐßbäb©£ýß,¢,Ðßb©,_v*~©ãa©äAÄî/ä/ß_o*+Oýª.BÃBvabªßüÖÜAZOböbru£ðb.@rªO©ÐZO|Ãð<üÐУß/åð©B,>*B,zýÖüßUCåAC¢aoý/*Ü/å~oUza,ÜÃ+.£îv/b£z<Ðvî¢_Üýu|oýÜ<öA~Bü/ððBa|Ü<.r*~b*CäAoüü£übvAhha.ÃOöî£,,ÐhÄ¢îÃý,<äܪÐ:a~Z@*Zb©v,ürßýÄßO,_vüâ©,ZbZbäz©ÄrÐÃ,©r_bÖb¢ÜA@z,äBa/ö@~b:ßUý+¢b¢äܪvA/@oaOr¢aå+ÜÜðuÖzuÜÄhªðäü_ÐhýýðUðA+/ªã.ÖZüb~<£r>:b¢AöBäÐ~ßh>ãa.O_+.>zZЩÃZUAîððü¢ðZr*b¢,¢>äªOßßý>öîhuÐoo*ü*©*UA.:rh@©åB|::rCýÖßÃãb@o,vb+U@Uz~ß+rßB£ãaU|,£AuOßO_~BåßvÐåAooßvh£ßü¢býzîBý©~@h@+Aä|büÃuÃab>ðb>Ãuý.ÖäbªBßä£CÜ:zhb¢@,ýßÖýåî<*Ö¢a>ªhÜä|.a,aübAävAr_åÖÐvðaö_åÄ<©ÖåbÜa@£©:~£ªh,aÜÄh¢ävßååZ'), ('hßzÃÄ|ÄUBýUãÖ._bZBCh|ýOãÖBª.öýo>ßã@äCîöb/CðÜ:Zä:ÐĪÜobCh£>öªözZCãÖAîîÃü.hbÄ/b.,:uhÃu..zÐÐ+u£ö*BCãßöÃUü|AÖO¢C,ÃbuB>,ߣbÄ/:zO|ÜB@Uößý~:ÖßoÜBßÜ.zCrýª@©uöhU<ßýä£CãOö:U>ªbA:üA~ö>rChäB>o~äaý£ÖB©Öü@©U¢ãüb¢ªð|bÄO,rÖv©ãý|¢©¢b/Uääý,Äý@ðÃå,obu>~¢@hߢ/ýßýîüüAªýÖ_ßÜÖðO+Ä©:@äå>ÜÜbbbBðª¢/åo,ßA|åBU:Ö£/h:hoîCö@hOðý_îßðr+åÜß|©C~/üvä@zZ/¢ö><:@Öuå©ã£î|aßÄbBå䢪ÜAª>h©£¢å¢~îö*<ÖäC|öîß>Ãäüär..UzýãBb|/vu_ý©|ß|îåCö:b©ðü_©b:/CÐÖ'), (N''), (0x00), (0x), (0x57CDF160B1CD42B39A4C3844CF1719168847B6FECC6079994BD995251FC8961EFFA573173276CF40D35D8FD9E1ADB125E67F2A35C3AE6CF6545715D8381C93D2B619442AA302E31277752A6FD19FB89D276F3F9F9D615A50387DC3DB60F708B6C9BD22C7688781E49B18BD4D83FD25B49F77B1C8DCF43555BEF4F2253E08B2806D74A6137DF035A0ED5B0484A30DCC3B580F3CE84640D9D587CC0874955CA593653CDF0F561136AE4210DA81F0B0B1B127B6CD2FCCC93A2D9AD18BB0E7C10B91B5701F662DBCE446D88DA6356558E5D71B574CDE8E76C79B02B275858585C7800548CB7F914A836AD286563E2304C741ECB49590742C023FA883647B475FC053C5252F1D8D6545D0D3E20C08208878FDEA3499D1F0370CD8458BD70EE6082373C50379FDD5AAB4866EC5BC9220FA1F1F0A669013C5EF628E1956D7018D37E9CABE99421D0F7A283F7F12622B7A79B84B6CB803807710ADD5A0EAE47ED3B3F836DBF2D387B7010F903D5093B38D37139F9E8B94D5346953AEEB6C7C2496AA6CCB192B4F88A530936AA87242267CFA4869D744DF471E2302719E249B4B85EBFA93E4C79961E78BF96EF8292DC1272C32F123134D51CB25ADF629DEE9819448E5BD78AE42B460E6814B4A704FF5F5404A72F1AA27719DA8C8BE1AA33809A178D9AF44704978EA7E903D9201065AD5B700E893778FEA20741FCFE68399BDAE78A9D2979FB185F7D1887319EADF9BA26DE963A250752AE9EF8ECF50799166E4D38F195834C336067BF1C2EE1BD03694842D789A361B5E037EE8A710E1357D3F218F465BC5436DAAB35C275EB33CCD1E583ACB4B18CCAEB83016D94C1B2525457382CC8C8ADBCF41C0CEE7DAF3FF50421A89B8A669312755E18D2AAF69218F8D37E1EB306F41937C6B8A8B4AE4D3C431C69631926C7EDB415B77ABFCB01FD79F3F59A211131FD3D9F53B3ADFA6DC710DC9F8E8D2F0FC21B806A9D5F89597CC4BB2EC0B8B31B21DA7C3579D3044FB9B7E059E33B83704AF4237EA0B6A49DA435D6FEE2CB9D0E6DB17DA410E985FF1740A0D56F2F7641314AE3DC85347A6B35EE9133FC055CFE2AD1FC21BDDF5F516E34675015CF2E84CF95CDA7E7C0892947027E325851F301F3B2BA9D23548361EB827E50CD1A5566B01C745647A5065A58C2DABB612CF91C31556C630491517B125BBC6552286C3CBD07724BDDACBA4EAC50346079C7F0CE89522F67BDF2522EBAF943EBE8A1083066AE0E59AABD3E949B1DB6B45CE0F14A5AFDDBF008F48ECAB55380D458DE660B5803F9DBC9A713DC238ACC903BADD1DA07F980FAC51827721F43A4572C5A3BCCB7BB5C58E72570B3DA0FDC7E27EE8F0781B6DC6F4D6B364FDC87BC8602BCAFC95F0FE8704178E2D278DD10C54BB94A20B4ACD5757DCC7F4C851C7C5F68FAB12D50032F28060EB608C3F9E6705A60F4234D9BD165E73A4B82809BFB350C83798E1BF375389A221AA5E6DCA183E60EF214184911DD295B3615B79C977A0380FC4080685466FBCB992B712B7F0A98C7AC71A9E71CB371AC64C0BD5F80FD8AA658FCFFC770B581C5C0A1C1482C4C1555D14962DD2D8DC09BD2D6410A3E9F36A82E70C63872E296577DFED2B427DD0F7C760E4B1CA226C8DB3C63F4AA747787217B2919BB75ECD2EEA31B5F2EAB0C7405C6D484205419F607A7FB0C1EFDFBD2F677A148FEB353F6993B6C6996C79A2), (0xFEED3AFF356DD613312038AD0B3E0B73868B6F9C3754262DDFAF4F7A05F400DCAEC3F1F18330310D3D7CBA1507BB8777BB26E5EE3365C7A9C70C20861E5B0D3C1F5CFF484D19EF565A625FBA9A11262327D7BEDF0E12A949FC472A760FABEEE16F7DF5ABBB3F2AA1368F93D0050C0FB5E6FC5E469D2D2E0CB2B64C06EE7946AF737D4B1C1C7B68E8AD1CA97F7FD843EF377590134CA744414FE8F805F324B2BC48E45D88C0F3996A9476998084AE8DDA735CCE79E83362CB380ACD338362F48969EC379A7BBA2F44DC257FD60EC4BDA05B1E91975539D31582914FB62565E7318110169777F25EB82C899DC3B48BBD744C2DD864D15C3330182118EA6B791E763D4D54FEAE262868BFD86ACB9B1060F6D4DB69F88D836025DCE57E55DA744DB36A27866636BFC5260470A5F8F1679408C121158F0F26E8BAED2F21C9A7D28D4A8BB761748AF1310EAC79C31A6501776DDF7CDF65DD200F1F752287F782FE8698F7B0DE659B4D695CC78C22FFB9A89A1B5B3B9D31908E02105C1796EB93398CAEF22B22B42212D29112829D50FD0F65CC886B9B4661550868AECE0983B77EC88D00740D8E86E6F949690B1E0DF0B1124CB1C963289E454C9C23BA0554084EDA94B9104F8902D746A27151DD5636FA77FCBBBCD1ED1BA0EFBB27706BCBE0A4401A308A53E062884ADA83C0B64C67F666284209994C7CEC7819209462916C7AC1CD11C325ACA7979A3272F76A5AE9A254300A4289D70BF49D43113ABFCE26B86E08FEE93BA3D1B981AB6E66D985821E2F7E3F328729F0EAC11C25E19A6DD7CC0BB988615B0067B05F50C1DE68A41A18C1F30A418EF431451713281E7EF01F13D3A25A20FC20C22E168FD3366712821C010D20A762953E1787434947D848326E31AE0AC54AFA1BA030DB2BFF21FBDD05910B1C70D078B13E644398B8D67B56CD5C64), ('99999999-9999-9999-9999-999999999999'), ('4303-03-26 08:57:46.916'), ('2079-06-06 23:59:00'), ('10/31/2016 11:46:28 AMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/0110/31/2016 11:46:28 AMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/01'), ('02:05:50.7400842'), ('0169-06-07'), ('9999-12-31 11:59:59.9999999'), ('2669-10-09 12:27:15.2132842+00:00'))"; + break; + default: + break; + } + return $query; +} + +function Repro() +{ + StartTest("pdo_fetch_columns_fetchmode"); + try + { + FetchMode_GetAllColumnsEx(); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("pdo_fetch_columns_fetchmode"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'pdo_fetch_columns_fetchmode' test... + +Comparing data in column 0 and rows +1 2 +Comparing data in column 1 and rows +1 2 +Comparing data in column 2 and rows +1 2 +Comparing data in column 3 and rows +1 2 +Comparing data in column 4 and rows +1 2 +Comparing data in column 5 and rows +1 2 +Comparing data in column 6 and rows +1 2 +Comparing data in column 7 and rows +1 2 +Comparing data in column 8 and rows +1 2 +Comparing data in column 9 and rows +1 2 +Comparing data in column 10 and rows +1 2 +Comparing data in column 11 and rows +1 2 +Comparing data in column 12 and rows +1 2 +Comparing data in column 13 and rows +1 2 +Comparing data in column 14 and rows +1 2 +Comparing data in column 15 and rows +1 2 +Comparing data in column 16 and rows +1 2 +Comparing data in column 17 and rows +1 2 +Comparing data in column 18 and rows +1 2 +Comparing data in column 19 and rows +1 2 +Comparing data in column 20 and rows +1 2 +Comparing data in column 21 and rows +1 2 +Comparing data in column 22 and rows +1 2 +Comparing data in column 23 and rows +1 2 +Comparing data in column 24 and rows +1 2 +Comparing data in column 25 and rows +1 2 +Comparing data in column 26 and rows +1 2 +Comparing data in column 27 and rows +1 2 +Comparing data in column 28 and rows +1 2 +Comparing data in column 29 and rows +1 2 +Comparing data in column 30 and rows +1 2 +Comparing data in column 31 and rows +1 2 +Done +...Test 'pdo_fetch_columns_fetchmode' completed successfully. diff --git a/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_binary.phpt b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_binary.phpt new file mode 100644 index 000000000..2e38da2ee --- /dev/null +++ b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_binary.phpt @@ -0,0 +1,105 @@ +--TEST-- +prepare with cursor buffered and fetch a varbinary column +--SKIPIF-- + +--FILE-- +setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); +$sample = 'asdgasdgasdgsadg'; + +$query = 'CREATE TABLE #TESTTABLE (exist varbinary(max))'; +$stmt = $conn->exec($query); +$query = 'INSERT INTO #TESTTABLE VALUES(:p0)'; +$stmt = $conn->prepare($query); +$stmt->bindParam(':p0', $sample, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY); +$stmt->execute(); + +$query = 'SELECT TOP 1 * FROM #TESTTABLE'; + +//prepare with no buffered cursor +print "no buffered cursor, stringify off, fetch_numeric off\n"; //stringify and fetch_numeric is off by default +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +//prepare with client buffered cursor +print "\nbuffered cursor, stringify off, fetch_numeric off\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +$stmt = null; +$conn = null; + +?> +--EXPECT-- +no buffered cursor, stringify off, fetch_numeric off +string(16) "asdgasdgasdgsadg" + +no buffered cursor, stringify off, fetch_numeric on +string(16) "asdgasdgasdgsadg" + +no buffered cursor, stringify on, fetch_numeric on +string(16) "asdgasdgasdgsadg" + +no buffered cursor, stringify on, fetch_numeric off +string(16) "asdgasdgasdgsadg" + +buffered cursor, stringify off, fetch_numeric off +string(16) "asdgasdgasdgsadg" + +buffered cursor, stringify off, fetch_numeric on +string(16) "asdgasdgasdgsadg" + +buffered cursor, stringify on, fetch_numeric on +string(16) "asdgasdgasdgsadg" + +buffered cursor, stringify on, fetch_numeric off +string(16) "asdgasdgasdgsadg" diff --git a/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_char.phpt b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_char.phpt new file mode 100644 index 000000000..f9f07b482 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_char.phpt @@ -0,0 +1,105 @@ +--TEST-- +prepare with cursor buffered and fetch a varchar column +--SKIPIF-- + +--FILE-- +setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); +$sample = "eight"; + +$query = 'CREATE TABLE #TESTTABLE (exist varchar(10))'; +$stmt = $conn->exec($query); +$query = 'INSERT INTO #TESTTABLE VALUES(:p0)'; +$stmt = $conn->prepare($query); +$stmt->bindValue(':p0', $sample, PDO::PARAM_STR); +$stmt->execute(); + +$query = 'SELECT TOP 1 * FROM #TESTTABLE'; + +//prepare with no buffered cursor +print "no buffered cursor, stringify off, fetch_numeric off\n"; //stringify and fetch_numeric is off by default +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +//prepare with client buffered cursor +print "\nbuffered cursor, stringify off, fetch_numeric off\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +$stmt = null; +$conn = null; + +?> +--EXPECT-- +no buffered cursor, stringify off, fetch_numeric off +string(5) "eight" + +no buffered cursor, stringify off, fetch_numeric on +string(5) "eight" + +no buffered cursor, stringify on, fetch_numeric on +string(5) "eight" + +no buffered cursor, stringify on, fetch_numeric off +string(5) "eight" + +buffered cursor, stringify off, fetch_numeric off +string(5) "eight" + +buffered cursor, stringify off, fetch_numeric on +string(5) "eight" + +buffered cursor, stringify on, fetch_numeric on +string(5) "eight" + +buffered cursor, stringify on, fetch_numeric off +string(5) "eight" diff --git a/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_datetime.phpt b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_datetime.phpt new file mode 100644 index 000000000..7e48158a5 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_datetime.phpt @@ -0,0 +1,105 @@ +--TEST-- +prepare with cursor buffered and fetch a datetime column +--SKIPIF-- + +--FILE-- +setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); +$sample = '2012-06-18 10:34:09'; + +$query = 'CREATE TABLE #TESTTABLE (exist datetime)'; +$stmt = $conn->exec($query); +$query = 'INSERT INTO #TESTTABLE VALUES(:p0)'; +$stmt = $conn->prepare($query); +$stmt->bindParam(':p0', $sample, PDO::PARAM_LOB); +$stmt->execute(); + +$query = 'SELECT TOP 1 * FROM #TESTTABLE'; + +//prepare with no buffered cursor +print "no buffered cursor, stringify off, fetch_numeric off\n"; //stringify and fetch_numeric is off by default +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +//prepare with client buffered cursor +print "\nbuffered cursor, stringify off, fetch_numeric off\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +$stmt = null; +$conn = null; + +?> +--EXPECT-- +no buffered cursor, stringify off, fetch_numeric off +string(23) "2012-06-18 10:34:09.000" + +no buffered cursor, stringify off, fetch_numeric on +string(23) "2012-06-18 10:34:09.000" + +no buffered cursor, stringify on, fetch_numeric on +string(23) "2012-06-18 10:34:09.000" + +no buffered cursor, stringify on, fetch_numeric off +string(23) "2012-06-18 10:34:09.000" + +buffered cursor, stringify off, fetch_numeric off +string(23) "2012-06-18 10:34:09.000" + +buffered cursor, stringify off, fetch_numeric on +string(23) "2012-06-18 10:34:09.000" + +buffered cursor, stringify on, fetch_numeric on +string(23) "2012-06-18 10:34:09.000" + +buffered cursor, stringify on, fetch_numeric off +string(23) "2012-06-18 10:34:09.000" diff --git a/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_decimal.phpt b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_decimal.phpt new file mode 100644 index 000000000..daa882213 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_decimal.phpt @@ -0,0 +1,105 @@ +--TEST-- +prepare with cursor buffered and fetch a decimal column +--SKIPIF-- + +--FILE-- +setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); +$sample = 1234567890.1234; + +$query = 'CREATE TABLE #TESTTABLE (exist decimal(16, 6))'; +$stmt = $conn->exec($query); +$query = 'INSERT INTO #TESTTABLE VALUES(:p0)'; +$stmt = $conn->prepare($query); +$stmt->bindValue(':p0', $sample, PDO::PARAM_INT); +$stmt->execute(); + +$query = 'SELECT TOP 1 * FROM #TESTTABLE'; + +//prepare with no buffered cursor +print "no buffered cursor, stringify off, fetch_numeric off\n"; //stringify and fetch_numeric is off by default +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +//prepare with client buffered cursor +print "\nbuffered cursor, stringify off, fetch_numeric off\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +$stmt = null; +$conn = null; + +?> +--EXPECT-- +no buffered cursor, stringify off, fetch_numeric off +string(17) "1234567890.123400" + +no buffered cursor, stringify off, fetch_numeric on +string(17) "1234567890.123400" + +no buffered cursor, stringify on, fetch_numeric on +string(17) "1234567890.123400" + +no buffered cursor, stringify on, fetch_numeric off +string(17) "1234567890.123400" + +buffered cursor, stringify off, fetch_numeric off +string(17) "1234567890.123400" + +buffered cursor, stringify off, fetch_numeric on +string(17) "1234567890.123400" + +buffered cursor, stringify on, fetch_numeric on +string(17) "1234567890.123400" + +buffered cursor, stringify on, fetch_numeric off +string(17) "1234567890.123400" diff --git a/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_decimal_bindColumn_int.phpt b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_decimal_bindColumn_int.phpt new file mode 100644 index 000000000..99a144e4e --- /dev/null +++ b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_decimal_bindColumn_int.phpt @@ -0,0 +1,113 @@ +--TEST-- +prepare with cursor buffered and fetch a decimal column with the column bound and specified to pdo type int +--SKIPIF-- + +--FILE-- +setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); +$sample = 1234567890.1234; + +$query = 'CREATE TABLE #TESTTABLE (exist decimal(18, 8))'; +$stmt = $conn->exec($query); +$query = 'INSERT INTO #TESTTABLE VALUES(:p0)'; +$stmt = $conn->prepare($query); +$stmt->bindValue(':p0', $sample, PDO::PARAM_INT); +$stmt->execute(); + +$query = 'SELECT exist FROM #TESTTABLE'; + +//prepare with no buffered cursor +print "no buffered cursor, stringify off, fetch_numeric off\n"; //stringify and fetch_numeric is off by default +$stmt = $conn->prepare($query); +$stmt->execute(); +$stmt->bindColumn('exist', $decimal_col, PDO::PARAM_INT); +$value = $stmt->fetch( PDO::FETCH_BOUND ); +var_dump ($decimal_col); + +print "\nno buffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$stmt->bindColumn('exist', $decimal_col, PDO::PARAM_INT); +$value = $stmt->fetch(PDO::FETCH_BOUND); +var_dump ($decimal_col); + +print "\nno buffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$stmt->bindColumn('exist', $decimal_col, PDO::PARAM_INT); +$value = $stmt->fetch(PDO::FETCH_BOUND); +var_dump ($decimal_col); + +print "\nno buffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query); +$stmt->execute(); +$stmt->bindColumn('exist', $decimal_col, PDO::PARAM_INT); +$value = $stmt->fetch(PDO::FETCH_BOUND); +var_dump ($decimal_col); + +//prepare with client buffered cursor +print "\nbuffered cursor, stringify off, fetch_numeric off\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$stmt->bindColumn('exist', $decimal_col, PDO::PARAM_INT); +$value = $stmt->fetch(PDO::FETCH_BOUND); +var_dump ($decimal_col); + +print "\nbuffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$stmt->bindColumn('exist', $decimal_col, PDO::PARAM_INT); +$value = $stmt->fetch(PDO::FETCH_BOUND); +var_dump ($decimal_col); + +print "\nbuffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$stmt->bindColumn('exist', $decimal_col, PDO::PARAM_INT); +$value = $stmt->fetch(PDO::FETCH_BOUND); +var_dump ($decimal_col); + +print "\nbuffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$stmt->bindColumn('exist', $decimal_col, PDO::PARAM_INT); +$value = $stmt->fetch(PDO::FETCH_BOUND); +var_dump ($decimal_col); + +$stmt = null; +$conn = null; + +?> +--EXPECT-- +no buffered cursor, stringify off, fetch_numeric off +int(1234567890) + +no buffered cursor, stringify off, fetch_numeric on +int(1234567890) + +no buffered cursor, stringify on, fetch_numeric on +string(10) "1234567890" + +no buffered cursor, stringify on, fetch_numeric off +string(10) "1234567890" + +buffered cursor, stringify off, fetch_numeric off +int(1234567890) + +buffered cursor, stringify off, fetch_numeric on +int(1234567890) + +buffered cursor, stringify on, fetch_numeric on +string(10) "1234567890" + +buffered cursor, stringify on, fetch_numeric off +string(10) "1234567890" diff --git a/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_float.phpt b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_float.phpt new file mode 100644 index 000000000..afed939a0 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_float.phpt @@ -0,0 +1,141 @@ +--TEST-- +prepare with cursor buffered and fetch a float column +--SKIPIF-- + +--FILE-- +setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); +$sample = 1234567890.1234; + +$query = 'CREATE TABLE #TESTTABLE (exist float(53))'; +$stmt = $conn->exec($query); +$query = 'INSERT INTO #TESTTABLE VALUES(:p0)'; +$stmt = $conn->prepare($query); +$stmt->bindValue(':p0', $sample, PDO::PARAM_INT); +$stmt->execute(); + +$query = 'SELECT TOP 1 * FROM #TESTTABLE'; + +//prepare with no buffered cursor +print "no buffered cursor, stringify off, fetch_numeric off\n"; //stringify and fetch_numeric is off by default +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); +$ok = FlatsAreEqual($sample, $value) ? 'TRUE' : 'FALSE'; +print "\nFetched value = Input? $ok\n\n"; + +print "no buffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); +$ok = FlatsAreEqual($sample, $value) ? 'TRUE' : 'FALSE'; +print "\nFetched value = Input? $ok\n\n"; + +print "no buffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); +$ok = FlatsAreEqual($sample, $value) ? 'TRUE' : 'FALSE'; +print "\nFetched value = Input? $ok\n\n"; + +print "no buffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); +$ok = FlatsAreEqual($sample, $value) ? 'TRUE' : 'FALSE'; +print "\nFetched value = Input? $ok\n\n"; + +//prepare with client buffered cursor +print "buffered cursor, stringify off, fetch_numeric off\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); +$ok = FlatsAreEqual($sample, $value) ? 'TRUE' : 'FALSE'; +print "\nFetched value = Input? $ok\n\n"; + +print "buffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); +$ok = FlatsAreEqual($sample, $value) ? 'TRUE' : 'FALSE'; +print "\nFetched value = Input? $ok\n\n"; + +print "buffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); +$ok = FlatsAreEqual($sample, $value) ? 'TRUE' : 'FALSE'; +print "\nFetched value = Input? $ok\n\n"; + +print "buffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); +$ok = FlatsAreEqual($sample, $value) ? 'TRUE' : 'FALSE'; +print "\nFetched value = Input? $ok\n\n"; + +$stmt = null; +$conn = null; + +?> +--EXPECT-- +no buffered cursor, stringify off, fetch_numeric off +string(15) "1234567890.1234" + +Fetched value = Input? TRUE + +no buffered cursor, stringify off, fetch_numeric on +float(1234567890.1234) + +Fetched value = Input? TRUE + +no buffered cursor, stringify on, fetch_numeric on +string(15) "1234567890.1234" + +Fetched value = Input? TRUE + +no buffered cursor, stringify on, fetch_numeric off +string(15) "1234567890.1234" + +Fetched value = Input? TRUE + +buffered cursor, stringify off, fetch_numeric off +string(15) "1234567890.1234" + +Fetched value = Input? TRUE + +buffered cursor, stringify off, fetch_numeric on +float(1234567890.1234) + +Fetched value = Input? TRUE + +buffered cursor, stringify on, fetch_numeric on +string(15) "1234567890.1234" + +Fetched value = Input? TRUE + +buffered cursor, stringify on, fetch_numeric off +string(15) "1234567890.1234" + +Fetched value = Input? TRUE diff --git a/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_float_bindColumn_lob.phpt b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_float_bindColumn_lob.phpt new file mode 100644 index 000000000..01c3d60b9 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_float_bindColumn_lob.phpt @@ -0,0 +1,117 @@ +--TEST-- +prepare with cursor buffered and fetch a float column with the column bound and specified to type LOB +--SKIPIF-- + +--FILE-- +setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); +$sample = 1234567890.1234; + +$query = 'CREATE TABLE #TESTTABLE (exist float(53))'; +$stmt = $conn->exec($query); +$query = 'INSERT INTO #TESTTABLE VALUES(:p0)'; +$stmt = $conn->prepare($query); +$stmt->bindValue(':p0', $sample, PDO::PARAM_INT); +$stmt->execute(); + +$query = 'SELECT exist FROM #TESTTABLE'; + +//prepare with no buffered cursor +print "no buffered cursor, stringify off, fetch_numeric off\n"; //stringify and fetch_numeric is off by default +$stmt = $conn->prepare($query); +$stmt->execute(); +$stmt->bindColumn('exist', $float_col, PDO::PARAM_LOB); +$value = $stmt->fetch(); +var_dump ($float_col); + +print "\nno buffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$stmt->bindColumn('exist', $float_col, PDO::PARAM_LOB); +$value = $stmt->fetch(); +var_dump ($float_col); + +print "\nno buffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$stmt->bindColumn('exist', $float_col, PDO::PARAM_LOB); +$value = $stmt->fetch(); +var_dump ($float_col); + +print "\nno buffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query); +$stmt->execute(); +$stmt->bindColumn('exist', $float_col, PDO::PARAM_LOB); +$value = $stmt->fetch(); +var_dump ($float_col); + +//prepare with client buffered cursor +print "\nbuffered cursor, stringify off, fetch_numeric off\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$stmt->bindColumn('exist', $float_col, PDO::PARAM_LOB); +$value = $stmt->fetch(); +var_dump ($float_col); + +print "\nbuffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$stmt->bindColumn('exist', $float_col, PDO::PARAM_LOB); +$value = $stmt->fetch(); +var_dump ($float_col); + +print "\nbuffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$stmt->bindColumn('exist', $float_col, PDO::PARAM_LOB); +$value = $stmt->fetch(); +var_dump ($float_col); + +print "\nbuffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$stmt->bindColumn('exist', $float_col, PDO::PARAM_LOB); +$value = $stmt->fetch(); +var_dump ($float_col); + +$stmt = null; +$conn = null; + +?> +--EXPECT-- +no buffered cursor, stringify off, fetch_numeric off +string(15) "1234567890.1234" + +no buffered cursor, stringify off, fetch_numeric on +string(15) "1234567890.1234" + +no buffered cursor, stringify on, fetch_numeric on +string(15) "1234567890.1234" + +no buffered cursor, stringify on, fetch_numeric off +string(15) "1234567890.1234" + +buffered cursor, stringify off, fetch_numeric off +string(15) "1234567890.1234" + +buffered cursor, stringify off, fetch_numeric on +string(15) "1234567890.1234" + +buffered cursor, stringify on, fetch_numeric on +string(15) "1234567890.1234" + +buffered cursor, stringify on, fetch_numeric off +string(15) "1234567890.1234" diff --git a/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_int.phpt b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_int.phpt new file mode 100644 index 000000000..8c6f65fcb --- /dev/null +++ b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_int.phpt @@ -0,0 +1,105 @@ +--TEST-- +prepare with cursor buffered and fetch a int column +--SKIPIF-- + +--FILE-- +setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); +$sample = 1234567890; + +$query = 'CREATE TABLE #TESTTABLE (exist int)'; +$stmt = $conn->exec($query); +$query = 'INSERT INTO #TESTTABLE VALUES(:p0)'; +$stmt = $conn->prepare($query); +$stmt->bindValue(':p0', $sample, PDO::PARAM_INT); +$stmt->execute(); + +$query = 'SELECT TOP 1 * FROM #TESTTABLE'; + +//prepare with no buffered cursor +print "no buffered cursor, stringify off, fetch_numeric off\n"; //stringify and fetch_numeric is off by default +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +//prepare with client buffered cursor +print "\nbuffered cursor, stringify off, fetch_numeric off\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +$stmt = null; +$conn = null; + +?> +--EXPECT-- +no buffered cursor, stringify off, fetch_numeric off +string(10) "1234567890" + +no buffered cursor, stringify off, fetch_numeric on +int(1234567890) + +no buffered cursor, stringify on, fetch_numeric on +string(10) "1234567890" + +no buffered cursor, stringify on, fetch_numeric off +string(10) "1234567890" + +buffered cursor, stringify off, fetch_numeric off +string(10) "1234567890" + +buffered cursor, stringify off, fetch_numeric on +int(1234567890) + +buffered cursor, stringify on, fetch_numeric on +string(10) "1234567890" + +buffered cursor, stringify on, fetch_numeric off +string(10) "1234567890" diff --git a/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_int_bindColumn_int.phpt b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_int_bindColumn_int.phpt new file mode 100644 index 000000000..623f3327d --- /dev/null +++ b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_int_bindColumn_int.phpt @@ -0,0 +1,114 @@ +--TEST-- +prepare with cursor buffered and fetch a int column with the column bound and specified as pdo type int +--SKIPIF-- + +--FILE-- +setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); + +$sample = 1234567890; + +$query = 'CREATE TABLE #TESTTABLE (exist int)'; +$stmt = $conn->exec($query); +$query = 'INSERT INTO #TESTTABLE VALUES(:p0)'; +$stmt = $conn->prepare($query); +$stmt->bindValue(':p0', $sample, PDO::PARAM_INT); +$stmt->execute(); + +$query = 'SELECT exist FROM #TESTTABLE'; + +//prepare with no buffered cursor +print "no buffered cursor, stringify off, fetch_numeric off\n"; //stringify and fetch_numeric is off by default +$stmt = $conn->prepare($query); +$stmt->execute(); +$stmt->bindColumn('exist', $int_col, PDO::PARAM_INT); +$value = $stmt->fetch( PDO::FETCH_BOUND ); +var_dump ($int_col); + +print "\nno buffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$stmt->bindColumn('exist', $int_col, PDO::PARAM_INT); +$value = $stmt->fetch( PDO::FETCH_BOUND ); +var_dump ($int_col); + +print "\nno buffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$stmt->bindColumn('exist', $int_col, PDO::PARAM_INT); +$value = $stmt->fetch( PDO::FETCH_BOUND ); +var_dump ($int_col); + +print "\nno buffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query); +$stmt->execute(); +$stmt->bindColumn('exist', $int_col, PDO::PARAM_INT); +$value = $stmt->fetch( PDO::FETCH_BOUND ); +var_dump ($int_col); + +//prepare with client buffered cursor +print "\nbuffered cursor, stringify off, fetch_numeric off\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$stmt->bindColumn('exist', $int_col, PDO::PARAM_INT); +$value = $stmt->fetch( PDO::FETCH_BOUND ); +var_dump ($int_col); + +print "\nbuffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$stmt->bindColumn('exist', $int_col, PDO::PARAM_INT); +$value = $stmt->fetch( PDO::FETCH_BOUND ); +var_dump ($int_col); + +print "\nbuffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$stmt->bindColumn('exist', $int_col, PDO::PARAM_INT); +$value = $stmt->fetch( PDO::FETCH_BOUND ); +var_dump ($int_col); + +print "\nbuffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$stmt->bindColumn('exist', $int_col, PDO::PARAM_INT); +$value = $stmt->fetch( PDO::FETCH_BOUND ); +var_dump ($int_col); + +$stmt = null; +$conn = null; + +?> +--EXPECT-- +no buffered cursor, stringify off, fetch_numeric off +int(1234567890) + +no buffered cursor, stringify off, fetch_numeric on +int(1234567890) + +no buffered cursor, stringify on, fetch_numeric on +string(10) "1234567890" + +no buffered cursor, stringify on, fetch_numeric off +string(10) "1234567890" + +buffered cursor, stringify off, fetch_numeric off +int(1234567890) + +buffered cursor, stringify off, fetch_numeric on +int(1234567890) + +buffered cursor, stringify on, fetch_numeric on +string(10) "1234567890" + +buffered cursor, stringify on, fetch_numeric off +string(10) "1234567890" diff --git a/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_money.phpt b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_money.phpt new file mode 100644 index 000000000..e6502be2f --- /dev/null +++ b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_money.phpt @@ -0,0 +1,105 @@ +--TEST-- +prepare with cursor buffered and fetch a money column +--SKIPIF-- + +--FILE-- +setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); +$sample = 1234567890.1234; + +$query = 'CREATE TABLE #TESTTABLE (exist money)'; +$stmt = $conn->exec($query); +$query = 'INSERT INTO #TESTTABLE VALUES(:p0)'; +$stmt = $conn->prepare($query); +$stmt->bindValue(':p0', $sample, PDO::PARAM_INT); +$stmt->execute(); + +$query = 'SELECT TOP 1 * FROM #TESTTABLE'; + +//prepare with no buffered cursor +print "no buffered cursor, stringify off, fetch_numeric off\n"; //stringify and fetch_numeric is off by default +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +//prepare with client buffered cursor +print "\nbuffered cursor, stringify off, fetch_numeric off\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +$stmt = null; +$conn = null; + +?> +--EXPECT-- +no buffered cursor, stringify off, fetch_numeric off +string(15) "1234567890.1234" + +no buffered cursor, stringify off, fetch_numeric on +string(15) "1234567890.1234" + +no buffered cursor, stringify on, fetch_numeric on +string(15) "1234567890.1234" + +no buffered cursor, stringify on, fetch_numeric off +string(15) "1234567890.1234" + +buffered cursor, stringify off, fetch_numeric off +string(15) "1234567890.1234" + +buffered cursor, stringify off, fetch_numeric on +string(15) "1234567890.1234" + +buffered cursor, stringify on, fetch_numeric on +string(15) "1234567890.1234" + +buffered cursor, stringify on, fetch_numeric off +string(15) "1234567890.1234" diff --git a/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_money_bindColumn_int.phpt b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_money_bindColumn_int.phpt new file mode 100644 index 000000000..328a4cab2 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_money_bindColumn_int.phpt @@ -0,0 +1,115 @@ +--TEST-- +prepare with cursor buffered and fetch a money column with the column bound and specified as pdo type int +--SKIPIF-- + +--FILE-- +setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); + +$sample = 1234567890.1234; + +$query = 'CREATE TABLE #TESTTABLE (exist money)'; +$stmt = $conn->exec($query); +$query = 'INSERT INTO #TESTTABLE VALUES(:p0)'; +$stmt = $conn->prepare($query); +$stmt->bindValue(':p0', $sample, PDO::PARAM_INT); +$stmt->execute(); + +$query = 'SELECT exist FROM #TESTTABLE'; + +//prepare with no buffered cursor +print "no buffered cursor, stringify off, fetch_numeric off\n"; //stringify and fetch_numeric is off by default +$stmt = $conn->prepare($query); +$stmt->execute(); +$stmt->bindColumn('exist', $money_col, PDO::PARAM_INT); +$value = $stmt->fetch(PDO::FETCH_BOUND); +var_dump ($money_col); + +print "\nno buffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$stmt->bindColumn('exist', $money_col, PDO::PARAM_INT); +$value = $stmt->fetch(PDO::FETCH_BOUND); +var_dump ($money_col); + +print "\nno buffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$stmt->bindColumn('exist', $money_col, PDO::PARAM_INT); +$value = $stmt->fetch(PDO::FETCH_BOUND); +var_dump ($money_col); + +print "\nno buffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query); +$stmt->execute(); +$stmt->bindColumn('exist', $money_col, PDO::PARAM_INT); +$value = $stmt->fetch(PDO::FETCH_BOUND); +var_dump ($money_col); + +//prepare with client buffered cursor +print "\nbuffered cursor, stringify off, fetch_numeric off\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$stmt->bindColumn('exist', $money_col, PDO::PARAM_INT); +$value = $stmt->fetch(PDO::FETCH_BOUND); +var_dump ($money_col); + +print "\nbuffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$stmt->bindColumn('exist', $money_col, PDO::PARAM_INT); +$value = $stmt->fetch(PDO::FETCH_BOUND); +var_dump ($money_col); + +print "\nbuffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$stmt->bindColumn('exist', $money_col, PDO::PARAM_INT); +$value = $stmt->fetch(PDO::FETCH_BOUND); +var_dump ($money_col); + +print "\nbuffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$stmt->bindColumn('exist', $money_col, PDO::PARAM_INT); +$value = $stmt->fetch(PDO::FETCH_BOUND); +var_dump ($money_col); + + +$stmt = null; +$conn = null; + +?> +--EXPECT-- +no buffered cursor, stringify off, fetch_numeric off +int(1234567890) + +no buffered cursor, stringify off, fetch_numeric on +int(1234567890) + +no buffered cursor, stringify on, fetch_numeric on +string(10) "1234567890" + +no buffered cursor, stringify on, fetch_numeric off +string(10) "1234567890" + +buffered cursor, stringify off, fetch_numeric off +int(1234567890) + +buffered cursor, stringify off, fetch_numeric on +int(1234567890) + +buffered cursor, stringify on, fetch_numeric on +string(10) "1234567890" + +buffered cursor, stringify on, fetch_numeric off +string(10) "1234567890" diff --git a/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_multicolumns.phpt b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_multicolumns.phpt new file mode 100644 index 000000000..096b3c68f --- /dev/null +++ b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_multicolumns.phpt @@ -0,0 +1,271 @@ +--TEST-- +prepare with cursor buffered and fetch from numeric columns. +--DESCRIPTION-- +Uses buffered cursor to fetch from float, int, and decimal columns that have positive, negative and zero value. +--SKIPIF-- + +--FILE-- +setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); +$sample = 1234567890.1234; +$sample1 = -1234567890.1234; +$sample2 = 1; +$sample3 = -1; +$sample4 = 0.5; +$sample5 = -0.55; + +$query = 'CREATE TABLE #TESTTABLE (a float(53), neg_a float(53), b int, neg_b int, c decimal(16, 6), neg_c decimal(16, 6), zero int, zerof float(53), zerod decimal(16,6))'; +$stmt = $conn->exec($query); +$query = 'INSERT INTO #TESTTABLE VALUES(:p0, :p1, :p2, :p3, :p4, :p5, 0, 0, 0)'; +$stmt = $conn->prepare($query); +$stmt->bindValue(':p0', $sample, PDO::PARAM_INT); +$stmt->bindValue(':p1', $sample1, PDO::PARAM_INT); +$stmt->bindValue(':p2', $sample2, PDO::PARAM_INT); +$stmt->bindValue(':p3', $sample3, PDO::PARAM_INT); +$stmt->bindValue(':p4', $sample4, PDO::PARAM_INT); +$stmt->bindValue(':p5', $sample5, PDO::PARAM_INT); +$stmt->execute(); + +$query = 'SELECT TOP 1 * FROM #TESTTABLE'; + +//prepare with no buffered cursor +print "\nno buffered cursor, stringify off, fetch_numeric off\n"; //stringify and fetch_numeric is off by default +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetch(PDO::FETCH_NUM); +var_dump ($value); + +print "\nno buffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetch(PDO::FETCH_NUM); +var_dump ($value); + +print "\nno buffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetch(PDO::FETCH_NUM); +var_dump ($value); + +print "\nno buffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetch(PDO::FETCH_NUM); +var_dump ($value); + +//prepare with client buffered cursor +print "\nbuffered cursor, stringify off, fetch_numeric off\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetch(PDO::FETCH_NUM); +var_dump ($value); + +print "\nbuffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetch(PDO::FETCH_NUM); +var_dump ($value); + +print "\nbuffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetch(PDO::FETCH_NUM); +var_dump ($value); + +print "\nbuffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetch(PDO::FETCH_NUM); +var_dump ($value); + +$stmt = null; +$conn = null; + +?> +--EXPECT-- +no buffered cursor, stringify off, fetch_numeric off +array(9) { + [0]=> + string(15) "1234567890.1234" + [1]=> + string(16) "-1234567890.1234" + [2]=> + string(1) "1" + [3]=> + string(2) "-1" + [4]=> + string(7) ".500000" + [5]=> + string(8) "-.550000" + [6]=> + string(1) "0" + [7]=> + string(3) "0.0" + [8]=> + string(7) ".000000" +} + +no buffered cursor, stringify off, fetch_numeric on +array(9) { + [0]=> + float(1234567890.1234) + [1]=> + float(-1234567890.1234) + [2]=> + int(1) + [3]=> + int(-1) + [4]=> + string(7) ".500000" + [5]=> + string(8) "-.550000" + [6]=> + int(0) + [7]=> + float(0) + [8]=> + string(7) ".000000" +} + +no buffered cursor, stringify on, fetch_numeric on +array(9) { + [0]=> + string(15) "1234567890.1234" + [1]=> + string(16) "-1234567890.1234" + [2]=> + string(1) "1" + [3]=> + string(2) "-1" + [4]=> + string(7) ".500000" + [5]=> + string(8) "-.550000" + [6]=> + string(1) "0" + [7]=> + string(1) "0" + [8]=> + string(7) ".000000" +} + +no buffered cursor, stringify on, fetch_numeric off +array(9) { + [0]=> + string(15) "1234567890.1234" + [1]=> + string(16) "-1234567890.1234" + [2]=> + string(1) "1" + [3]=> + string(2) "-1" + [4]=> + string(7) ".500000" + [5]=> + string(8) "-.550000" + [6]=> + string(1) "0" + [7]=> + string(3) "0.0" + [8]=> + string(7) ".000000" +} + +buffered cursor, stringify off, fetch_numeric off +array(9) { + [0]=> + string(15) "1234567890.1234" + [1]=> + string(16) "-1234567890.1234" + [2]=> + string(1) "1" + [3]=> + string(2) "-1" + [4]=> + string(7) ".500000" + [5]=> + string(8) "-.550000" + [6]=> + string(1) "0" + [7]=> + string(1) "0" + [8]=> + string(7) ".000000" +} + +buffered cursor, stringify off, fetch_numeric on +array(9) { + [0]=> + float(1234567890.1234) + [1]=> + float(-1234567890.1234) + [2]=> + int(1) + [3]=> + int(-1) + [4]=> + string(7) ".500000" + [5]=> + string(8) "-.550000" + [6]=> + int(0) + [7]=> + float(0) + [8]=> + string(7) ".000000" +} + +buffered cursor, stringify on, fetch_numeric on +array(9) { + [0]=> + string(15) "1234567890.1234" + [1]=> + string(16) "-1234567890.1234" + [2]=> + string(1) "1" + [3]=> + string(2) "-1" + [4]=> + string(7) ".500000" + [5]=> + string(8) "-.550000" + [6]=> + string(1) "0" + [7]=> + string(1) "0" + [8]=> + string(7) ".000000" +} + +buffered cursor, stringify on, fetch_numeric off +array(9) { + [0]=> + string(15) "1234567890.1234" + [1]=> + string(16) "-1234567890.1234" + [2]=> + string(1) "1" + [3]=> + string(2) "-1" + [4]=> + string(7) ".500000" + [5]=> + string(8) "-.550000" + [6]=> + string(1) "0" + [7]=> + string(1) "0" + [8]=> + string(7) ".000000" +} + diff --git a/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_strings_to_integers.phpt b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_strings_to_integers.phpt new file mode 100644 index 000000000..ff0e1a8b4 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_strings_to_integers.phpt @@ -0,0 +1,232 @@ +--TEST-- +prepare with cursor buffered and fetch various columns with the column bound and specified to pdo type int +--SKIPIF-- + +--FILE-- +setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); + + $decimal = -2345209.3103; + $numeric = 987234.9919; + $salary = "3456789.15"; + $debt = "98765.99"; + + $query = 'CREATE TABLE #TESTTABLE ([c_decimal] decimal(28,4), [c_numeric] numeric(32,4), [c_varchar] varchar(20), [c_nvarchar] nvarchar(20))'; + + $stmt = $conn->exec($query); + + $query = 'INSERT INTO #TESTTABLE VALUES(:p0, :p1, :p2, :p3)'; + $stmt = $conn->prepare($query); + $stmt->bindValue(':p0', $decimal); + $stmt->bindValue(':p1', $numeric); + $stmt->bindValue(':p2', $salary); + $stmt->bindValue(':p3', $debt); + $stmt->execute(); + + $decimal2 = $decimal * 2; + $numeric2 = $numeric * 2; + $salary2 = $salary * 2; + $debt2 = $debt * 2; + + $stmt->bindValue(':p0', $decimal2); + $stmt->bindValue(':p1', $numeric2); + $stmt->bindValue(':p2', $salary2); + $stmt->bindValue(':p3', $debt2); + $stmt->execute(); + + $decimal3 = $decimal * 3; + $numeric3 = $numeric * 3; + $salary3 = $salary * 3; + $debt3 = $debt * 3; + + $stmt->bindValue(':p0', $decimal3); + $stmt->bindValue(':p1', $numeric3); + $stmt->bindValue(':p2', $salary3); + $stmt->bindValue(':p3', $debt3); + $stmt->execute(); + + $stmt = null; + + echo ("Input values:\n\torginal:$decimal\t$numeric\t$salary\t$debt\n\tdoubles:$decimal2\t$numeric2\t$salary2\t$debt2\n\ttriples:$decimal3\t$numeric3\t$salary3\t$debt3\n"); + + $query = 'SELECT * FROM #TESTTABLE'; + + // prepare with no buffered cursor + echo "\n\nComparing results (stringify off, fetch_numeric on):\n"; + // no buffered cursor, stringify off, fetch_numeric on + $conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); + $stmt1 = $conn->prepare($query); + $stmt1->execute(); + + // buffered cursor, stringify off, fetch_numeric on + $conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); + $stmt2 = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); + $stmt2->execute(); + + compareResults($stmt1, $stmt2); + + $stmt1 = null; + $stmt2 = null; + + echo "\n\nComparing results (stringify off, fetch_numeric off):\n"; + // no buffered cursor, stringify off, fetch_numeric off + $conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, false); + $conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); + $stmt1 = $conn->prepare($query); + $stmt1->execute(); + + // buffered cursor, stringify off, fetch_numeric off + $conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, false); + $conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); + $stmt2 = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); + $stmt2->execute(); + + compareResults($stmt1, $stmt2); + + $stmt1 = null; + $stmt2 = null; + + $conn = null; +} + +function compareResults($stmt1, $stmt2) +{ + $stmt1->bindColumn('c_decimal', $decimal_col1, PDO::PARAM_INT); + $stmt1->bindColumn('c_numeric', $numeric_col1, PDO::PARAM_INT); + $stmt1->bindColumn('c_varchar', $salary_col1, PDO::PARAM_INT); + $stmt1->bindColumn('c_nvarchar', $debt_col1, PDO::PARAM_INT); + + $stmt2->bindColumn('c_decimal', $decimal_col2, PDO::PARAM_INT); + $stmt2->bindColumn('c_numeric', $numeric_col2, PDO::PARAM_INT); + $stmt2->bindColumn('c_varchar', $salary_col2, PDO::PARAM_INT); + $stmt2->bindColumn('c_nvarchar', $debt_col2, PDO::PARAM_INT); + + $numRows = 3; + for ($i = 1; $i <= $numRows; $i++) + { + echo "\nreading row " . $i . "\n"; + + $value1 = $stmt1->fetch( PDO::FETCH_BOUND ); + $value2 = $stmt2->fetch( PDO::FETCH_BOUND ); + + compareData($decimal_col1, $decimal_col2); + compareData($numeric_col1, $numeric_col2); + compareData($salary_col1, $salary_col2); + compareData($debt_col1, $debt_col2); + } +} + +function compareData($data1, $data2) +{ + if ($data1 != $data2) + echo "Not matched!\n"; + else + echo "Matched!\n"; + + echo ("\tExpected: "); var_dump ($data1); + echo ("\tActual: "); var_dump ($data2); +} + +test(); + +?> +--EXPECT-- +Input values: + orginal:-2345209.3103 987234.9919 3456789.15 98765.99 + doubles:-4690418.6206 1974469.9838 6913578.3 197531.98 + triples:-7035627.9309 2961704.9757 10370367.45 296297.97 + + +Comparing results (stringify off, fetch_numeric on): + +reading row 1 +Matched! + Expected: int(-2345209) + Actual: int(-2345209) +Matched! + Expected: int(987234) + Actual: int(987234) +Matched! + Expected: int(3456789) + Actual: int(3456789) +Matched! + Expected: int(98765) + Actual: int(98765) + +reading row 2 +Matched! + Expected: int(-4690418) + Actual: int(-4690418) +Matched! + Expected: int(1974469) + Actual: int(1974469) +Matched! + Expected: int(6913578) + Actual: int(6913578) +Matched! + Expected: int(197531) + Actual: int(197531) + +reading row 3 +Matched! + Expected: int(-7035627) + Actual: int(-7035627) +Matched! + Expected: int(2961704) + Actual: int(2961704) +Matched! + Expected: int(10370367) + Actual: int(10370367) +Matched! + Expected: int(296297) + Actual: int(296297) + + +Comparing results (stringify off, fetch_numeric off): + +reading row 1 +Matched! + Expected: int(-2345209) + Actual: int(-2345209) +Matched! + Expected: int(987234) + Actual: int(987234) +Matched! + Expected: int(3456789) + Actual: int(3456789) +Matched! + Expected: int(98765) + Actual: int(98765) + +reading row 2 +Matched! + Expected: int(-4690418) + Actual: int(-4690418) +Matched! + Expected: int(1974469) + Actual: int(1974469) +Matched! + Expected: int(6913578) + Actual: int(6913578) +Matched! + Expected: int(197531) + Actual: int(197531) + +reading row 3 +Matched! + Expected: int(-7035627) + Actual: int(-7035627) +Matched! + Expected: int(2961704) + Actual: int(2961704) +Matched! + Expected: int(10370367) + Actual: int(10370367) +Matched! + Expected: int(296297) + Actual: int(296297) diff --git a/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_unicode.phpt b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_unicode.phpt new file mode 100644 index 000000000..b8174cba6 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_fetch_cursorBuffered_unicode.phpt @@ -0,0 +1,105 @@ +--TEST-- +prepare with cursor buffered and fetch a nvarchar column +--SKIPIF-- + +--FILE-- +setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); +$sample = "가각"; + +$query = 'CREATE TABLE #TESTTABLE (exist nvarchar(10))'; +$stmt = $conn->exec($query); +$query = 'INSERT INTO #TESTTABLE VALUES(:p0)'; +$stmt = $conn->prepare($query); +$stmt->bindValue(':p0', $sample, PDO::PARAM_STR); +$stmt->execute(); + +$query = 'SELECT TOP 1 * FROM #TESTTABLE'; + +//prepare with no buffered cursor +print "no buffered cursor, stringify off, fetch_numeric off\n"; //stringify and fetch_numeric is off by default +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nno buffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +//prepare with client buffered cursor +print "\nbuffered cursor, stringify off, fetch_numeric off\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify off, fetch_numeric on\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify on, fetch_numeric on\n"; +$conn->setAttribute( PDO::ATTR_STRINGIFY_FETCHES, true); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +print "\nbuffered cursor, stringify on, fetch_numeric off\n"; +$conn->setAttribute( PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE, false); +$stmt = $conn->prepare($query, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, PDO::SQLSRV_ATTR_CURSOR_SCROLL_TYPE => PDO::SQLSRV_CURSOR_BUFFERED)); +$stmt->execute(); +$value = $stmt->fetchColumn(); +var_dump ($value); + +$stmt = null; +$conn = null; + +?> +--EXPECT-- +no buffered cursor, stringify off, fetch_numeric off +string(6) "가각" + +no buffered cursor, stringify off, fetch_numeric on +string(6) "가각" + +no buffered cursor, stringify on, fetch_numeric on +string(6) "가각" + +no buffered cursor, stringify on, fetch_numeric off +string(6) "가각" + +buffered cursor, stringify off, fetch_numeric off +string(6) "가각" + +buffered cursor, stringify off, fetch_numeric on +string(6) "가각" + +buffered cursor, stringify on, fetch_numeric on +string(6) "가각" + +buffered cursor, stringify on, fetch_numeric off +string(6) "가각" diff --git a/test/pdo_sqlsrv/pdo_fetch_fetchinto_query_args.phpt b/test/pdo_sqlsrv/pdo_fetch_fetchinto_query_args.phpt new file mode 100644 index 000000000..2d0641e3a --- /dev/null +++ b/test/pdo_sqlsrv/pdo_fetch_fetchinto_query_args.phpt @@ -0,0 +1,134 @@ +--TEST-- +fetch columns using fetch mode and different ways of binding columns +--SKIPIF-- + +--FILE-- +exec("CREATE TABLE $tableName ([c1_int] int, [c2_tinyint] tinyint, [c3_smallint] smallint, [c4_bigint] bigint, [c5_bit] bit, [c6_float] float, [c7_real] real, [c8_decimal] decimal(28,4), [c9_numeric] numeric(32,4), [c10_money] money, [c11_smallmoney] smallmoney, [c12_char] char(512), [c13_varchar] varchar(512), [c14_varchar_max] varchar(max), [c15_nchar] nchar(512), [c16_nvarchar] nvarchar(512), [c17_nvarchar_max] nvarchar(max), [c18_text] text, [c19_ntext] ntext, [c20_binary] binary(512), [c21_varbinary] varbinary(512), [c22_varbinary_max] varbinary(max), [c23_image] image, [c24_uniqueidentifier] uniqueidentifier, [c25_datetime] datetime, [c26_smalldatetime] smalldatetime, [c27_timestamp] timestamp, [c28_xml] xml, [c29_time] time, [c30_date] date, [c31_datetime2] datetime2, [c32_datetimeoffset] datetimeoffset)"); + + $numRows = 0; + $query = GetQuery($tableName, ++$numRows); + $stmt = $conn->query($query); + + $query = GetQuery($tableName, ++$numRows); + $stmt = $conn->query($query); + $stmt = null; + + $sql = "SELECT * FROM $tableName ORDER BY c27_timestamp"; + $obj1 = new PdoTestClass(); + $stmt1 = $conn->query($sql, PDO::FETCH_INTO, $obj1); + + $obj2 = new PdoTestClass2(1, 2); + $stmt2 = $conn->prepare($sql); + $result = $stmt2->execute(); + $stmt2->setFetchMode(PDO::FETCH_INTO, $obj2); + + VerifyResults($stmt1, $stmt2, $tableName); + + $stmt1 = null; + $stmt2 = null; + $conn = null; +} + +function VerifyResults($stmt1, $stmt2, $tableName) +{ + $numFields = $stmt1->columnCount(); + + $i = 0; + while ($obj1 = $stmt1->fetch()) + { + $obj2 = $stmt2->fetch(); + + echo "Comparing data in row " . ++$i . "\n"; + $query = GetQuery($tableName, $i); + $dataArray = InsertDataToArray($stmt1, $query, $numFields, $i); + + CheckObject($stmt1, $obj1, $i, $dataArray); + CheckObject($stmt2, $obj2, $i, $dataArray); + } +} + +function CheckObject($stmt, $obj, $row, $dataArray) +{ + $j = 0; + foreach ($obj as $value) + { + CompareData($stmt, $row, $j, $value, $dataArray[$j]); + $j++; + } +} + +function GetQuery($tableName, $index) +{ + $query = ""; + switch ($index) + { + case 1: + $query = "INSERT INTO $tableName ([c1_int], [c2_tinyint], [c3_smallint], [c4_bigint], [c5_bit], [c6_float], [c7_real], [c8_decimal], [c9_numeric], [c10_money], [c11_smallmoney], [c12_char], [c13_varchar], [c14_varchar_max], [c15_nchar], [c16_nvarchar], [c17_nvarchar_max], [c18_text], [c19_ntext], [c20_binary], [c21_varbinary], [c22_varbinary_max], [c23_image], [c24_uniqueidentifier], [c25_datetime], [c26_smalldatetime], [c28_xml], [c29_time], [c30_date], [c31_datetime2], [c32_datetimeoffset]) VALUES ((-218991553), (1), (23494), (1864173810), (0), (1), (-3.4E+38), (0.3607), (0.6259), (0.3426), (0.7608), ('bAB:+:|©ßÄ.:B¢UBüÖÄýÃ<ß©ÖaÃbvßZö+/AZ:rzvbåvh_£+Ðr<Äbý.ßãr@výߣöÜ£|B©~ö©Ö/:ðßr©CB©öäßbuöö£rBðö*:/ö>>ý|ÄoUßö¢|>ý£_.O*åÜCÄ.ªha,ãÖßBý>äÐOC_üߪah¢.:©~~@Öý|£ßßb..ÃÜ.bC@|ýCî+v£,BOB|ßrÃ+ßvubC:äAöBÐCZarüaBã<|©uUC¢~.|~ýÃbý>£@Ca_Ð.îÖäÐo££.ªZ¢bU£CýðUå*vCoßý@©bAz£_ª.obüÄ¢öÖhüÄbaÖä_@rÖ£.hß~bУü~'), ('B:ä.ß.å.bbCÜO,UÖ+¢rBßoð>zÖzZzä+Ö<Ð:©oÐ@,ýÜößbüAä**U@b|Or:ýbAb~brÃ+Z:öªª£BãBauC.*Ä<öý¢äÄð_uro£>Z/ÄÐCЩ~ðÖТ.u:oýz~Ð*¢¢bªß©,ðÄ,:ý¢_ÃZ>ýéC_rva:>>+Uå~îo©ß£hZbZ©r,Z¢ßÃÖä>*îbrb/ß~,oå|:>äb<äî©+Ä¢,:zãü,©ßÖ>Ü|Ããöª+ß~ðî/CÖå/_*ßãrh£vÃÜÖªãOÄ+CbÃðOU@v_ãÜÜÐöz|ö_äzýîZ¢ð.hOãÜý,r_Z'), ('UZß_Z++ä_Ö:r©Z*,,uÖbýÜB*:Üä.~r©U>ýZ|@<ªövbä.Ö¢CÄAßobzaü>r>b_@öZ*bOÄ©aÜåî¢ßßðîÃ~ß©h+ÖA~ð>aß+a,b:zß_*|ð:ÄvðU:@rAª@îvä+ª_z>vr©r/å__+>h,+Aîu:Bßßh.ZýrãCCrbÐUuãvÄß>ãbÐîoÐîuoä+£î>Ä_+åð©a~Ö/zvÜåh@ÖO:öUÜbuU|BýÃUÖ~Ou_Ä<.ÜC>vZZ~åüab£BOOöUö:h¢+~Aî@©ÖB_+:b+.z<ý<Ü£,ªBîAh~.uüªU*Ü.|<+ߣãÜ/£¢ªÖÜä>U>Ã>UÜ>Cä+b+å|ÜrÄ~ýÜý¢ÃCߢO:Z:.ß_ÐÐB|ã_£b+@/|>åäå.åoÜB@£ß~ãªAß/üvßoã©©åb+Ä£CU~ZÐz|å|uA:rBZühåba_b:v©ÐauÐaB/,å@|ý.îv>ðäÖU,öÖ+ÃÐOZÃBAßZ¢azzo|h¢b*~ÖýÖüß_ªrÄAZÜvåAZðCÃÜ<ÖÄÜîüoÜzª¢zªo¢Äür@o@ãBv*ub:Cvu>,~BýZýbã+ßîB.üoBv*zĪ@v££//©îУA,hðAb¢/ýhÃßÃðaä,böoßü@ååz<+ä|/ð¢oäÄvAhA£î*~ðÄ~У|bªü|äbåUbЪv~/ÄÜo@bZª*öð_î¢ðüoÐÖÄZ@ãübzßãaü./,*îäo|b©+öÄ£AAü:öZîýä|vîåßBrv:ª,_@h|ÐbߢÃb**ßOðA+*îÄb.~ßbýý*:ä.ð+*C_î.Ðå>ZzÜuöBÄåbäð_åzhöz@Ðb,Bßö££<öîz@©|AhÄ,ãßaßßOA@£+|>ýüZªßýüöð£ÐO/vÄ*UüUª@Ãå@>BÃz>@>+/£oBÖî'), (N'üªrobã|ß*Ã@hrUãÐ.vöß©@ßz_uu,Ä_,Ã+hÜ*ö£uª£ä£Ãå<Ãvb:Ä<ö@o<Üå£ãªObßzãÜb<@ÜÖb+Oßäh:b_ö*vãîÐäüz|ba,ý<Üã,Aâß|Ãö/ª*+ª£:~z£äßü/BðCoöÄÖ©+ÄAAÖ.,îhߪå>h_ªÐð¢:b+¢üåöðÜ@£ªüOÖu¢*~åbO.>buböü,@:ABz~aBbhß<ª.@O¢ÃÐîîUoA|UÃä_Ðßaü,ýr~äuÖ:C~Büý.ãZßÖ|ðÜüý*_ªCrr.å*¢Uaðßb>ß:©|aüî@|Bð£öä'), (N'ZO*åuÐãªî,~+,Üb.|v.>:u.:ÄhbÃÖ<ª+a|ÐOðAÐu+.|CÜa@BÃ@|oh|~ÜboavÃu,ðîÜ<©.Aä¢|rbuäOrZÐhA~CzB|:©ð¢ð>+ðäöÄ||rßߪÃîO,Oã_hÖ:Oaå©ð+£~îOÃobCBýb,äð.ubÐä:OBUã.O|zßåZ:åCÄߣððîåBhé|£ÄAoBÃo:,ö/ýßU*bAvß>A*îoüäÃ'), (N'©~¢@©ß.OO¢z:ÖÜ+£CÃ~ãbäîo_ZßäOUýÜv¢vä,Z~_©äBoO~ªhß*ÖaßzÃßÃ<ý+ý_ýö£_oC@@vßBAOrÖÐýöÄ©bä@ýöüð:oîzu_Cäo_£.<£Zbðîßh>büC:£ªrOb*+@å>b*ªr+_uaÖß~boß:.r/v|r¢ÐÐåbrv~üÃ/Azbh:ÖC>:zÐzä~/,Ö©Cðu*Z/¢åzZ*ö:ßChbäÐzöåöOÄ@~£/Щ¢¢£aöuhßboBroCÐ>¢C*~/h£b,ýãÖhÖ|£+£hã~.~üäu£+zzßUuårü<ߢ*ý~£ü..£Zª<ã_üîîu_+ÄO@vÐbr~_v|~O~AßäaÖ¢~<~*ÖäoAî>îÜUªo@åªözrZªhb>ªýhoOäܪrªÖ~rÜCZb>|*ãß©röüß@©boåuÖåoîÐZAa£,~Üz,orîuBªÐ©ß,ÃbBhüð£u£ðÖO'), ('ýß/Zãz~üöߣh:©Ð|ßaa@@Üh.ÄUÄh©*uaUb©a£Ã+o:ß@Ü'), (N'OäACaÜuÄ+.Ov@ÐÖZö.Üvåub,zã+ÃÜð_Ö>ýÜß>+uUa,z¢<.ä/Ä@~+ßßýöÜ£ßo.|ö/ä/Ü@üöߪO_v@ð:ðîýðýU+oðÃaãaã|bã~ÃbÃ@B@hðüAhÃßbAÄåv£hª*öý+ÄAvÄrðoßöårÐ@bbBÖo|>¢*ö£Üða@:vußZ@+ÖÐßÃßÄC**_CCÜ.bäO.@Ð,b¢övð£+é.:aÄz,ü>ÖÜ>ý¢C£ßUB,.A.ßÜýÃBã.îbÜ©ÃCÃBbBÃîÄ£Ðu,:@Z<©_üv¢ý©uÄ£vCbãÄÐzðýöÄoaÄ@*Üb|ªuª_öu_ß,bCAå,b@@*Ö@_vÖZu~ÃB.©~hªoððäåðãÜ_vÖÄübb_ÄBOOÐa_£Üî:OZbÖr>rã~h©£/ðÐýýa~v_£|Ã~,üåo.ZBü<£><__uÖu>,b<ÜUýA|¢r¢ð|Ð,oß@zÃOä|©övu@:<*@zoO¢C¢ÄåhäÃå+|BÜB+ÐÐ:_z_>ßßýÜ@BhäC¢._Öbrß:_*OÃz.o:/bÖ¢bÜã©hzßÐC¢Ö_AuöÃU*z@ðaýü+ß>/ßzBa.uAã|å¢Ð/b*ð~££b:>rbÜuÄbÜåZzã+îß_ÖhßrBh+ЪBã©b.ÄOC|<*Ouåå£*©zÐb£Ðb_*ý£_©Ð~ª/aÃãr©bðªCÐvZÖUZ<ÜäÜ,>/ªo/ÜüîªîÖÖ~ßåOßCýuß:_aÜuªÖ*båäßröªB©ßîBaarý@Äö,B©£ä_~Aåª,OOu~_aåö,ävBC*Bhß:zAv_£,u,UýZ£îÄ>v¢Ðå:>rB~zBBý|ZÜ,Öª~~C£_ä*hÜî©Ðö~¢ãÐ,U+öCðÃr_vuãöuîåzhðoüOAB*:Oðªh_,Ä~,C.£<£:/a~BZß©Öä£/ÃÃÖruv¢©ÐÜ¢.Öäh+ãÜ>©©'), (0x69C465C11581CB199C423F5ADAB10D08FBC98CA537ADE0F745A40A46E7EBF13678AE4020751008ECA0A59DA462FD031A024E5DAA578E93BBE36D7C70778431B15008E22B71ED93EAC0A005920F3B9548A1EF44998D47DEEA1B843C089397741B74EC545A1AD8A815BB72EAB28BDC95E087D8B022B9638070135CE9526220C976972887D7543078AE083DDDA0A6FBC5F3290CCE9A1A2F6408C3D27BB9BDCEAE4527A23B6354BE8C575F01197B85E0CA1796F62956522F5B68C4), (0xB5BFF13A8F987804C0629E6A7F763A1816E882E3076322C6A557F2F746D39ED5AB0AA2A010DEECED67C6573457BED6DCF44352DBFC2F79519C2A9537A580BEEDC3C8BF75D49A0837FB957B410BEE6FE68016030281C3D97B905004E649B447E6086A708EFF61075A3B1ADF67B33845AEBBAEB78F7DBB6C00EF44E4839622EE474D9539A17DE0E71F0EA8C766E371C7580A552A9AFDB8684DFE709FBA7C84C4182C981A1EFFA431DAC79780D5F3051D7D7D8C7840F75349942CEBA30C402CA28AE3AE394A57A858662450D365389359F853213DEF0C8421D942F6116302D83057244BF49BA56446ACC22AA085B4B9454FE721BD907B3C2938A988F49A96F9C13464E468E3D573B75C62FB87A2ABC7D458B0C17CE01BA0DBE821BBF21C6FAB16C9686B20D0506279736A612E80B4878CE1B39BEAD47DE119C40880C219809BECB7E5BE3A40A604084D470876), (0x5B33992F1168D4C0414C87515CC7D0A060F2CE75779BF64C4B3AAF939C8D746A5F53AD4D28EA6F3318F6A372B3EE4A3D38ADE716A844FAC03C4DE3D7B84024B3D71CF2091A827875839B5D80F784995DEF725BEFA65EC21A58ED10DB06987AD7D2F09A96FC4122B53571920CE779C8B8B386E746E4350D795AD7B02C729C6FEB2185AE07E90260AD4FA6B935CBB533DE2457277FB033F29DE2203C2591F6439801A7EB61CBC1CEB0263AF73E7BD8AEA4A3D1081A75EF3BED921024C9C63B1C5963213324C9D11362897659763CB4210A729781BFED28221260CCB318AC9AA23B8A73706F8495DAAA9F6ABFD2A58F22DC3066DB9712B4CE930E9B04D96E63906F9B871585067738C1143FFB3D03D5C8A0AAD7E745BF0B29D6A4DD60E891013B3BD94F371E7A9DD5B92D1983D2B9919038D2632F967C4BB08F5D3EE0291650301303BF63B39EAA260C012E17A587561C124D27162DD1A4BF8E9EA7C03BBCACA2DDE870CFF92DDC9A273C22944D330B080722CEDCEE3902415FFFD515F7EAEB50558B3ABD178723E5708DEEF0AE0F725B939EB919EED0B3A3E52E6FF958C7A33D51D23FC2F94DF07FFEE96B614B11924F8D7A815830D26285D796D7E817298CA8E9B09FDCD0AF6145AE391A05645157D49B206BDD464A0C7F6FB9EA62760768D55C), (null), (null), (null), ('2079-06-06 23:59:00'), ('10/31/2016 11:46:19 AMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/0110/31/2016 11:46:19 AMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/01'), (null), ('0001-01-01'), ('0498-06-25 12:16:38.7590909'), ('0534-02-18 04:26:43.4190075+00:00'))"; + break; + case 2: + $query = "INSERT INTO $tableName ([c1_int], [c2_tinyint], [c3_smallint], [c4_bigint], [c5_bit], [c6_float], [c7_real], [c8_decimal], [c9_numeric], [c10_money], [c11_smallmoney], [c12_char], [c13_varchar], [c14_varchar_max], [c15_nchar], [c16_nvarchar], [c17_nvarchar_max], [c18_text], [c19_ntext], [c20_binary], [c21_varbinary], [c22_varbinary_max], [c23_image], [c24_uniqueidentifier], [c25_datetime], [c26_smalldatetime], [c28_xml], [c29_time], [c30_date], [c31_datetime2], [c32_datetimeoffset]) VALUES ((1), (1), (22772), (-9223372036854775808), (0), (1), (-2.3), (0.9047), (0.6343), (-922337203685477.5808), (-214748.3648), (null), ('ä|uÜC£r¢@Ü_@vC~bzCOBÖrö~ÖÜ/Ü~ýÐüðvbvªbÐ.özoÃÃå£rb:>åãvb©ª©A*u/b@A~ªýAz>u.Üo/AvåährÄC@äC£r/©ðb,O@U©£CZ£OÖöv>bC£¢zÜoraÄðaO:üߢ£|oaª£O,¢Ü~>AüOu,b@|ß+oåOoßz£<©*ä~C.B<><_ð+B_îü©îã.hv¢vý,UÜZî_ã+ýÄaßZv@.>>rÐãUßäzªabaBãåo+£*ýÃu@Abýª¢ÃÄß/å@rßb:AÃ|h:ChðZßv/ãBb>ßvÄÃßUuu¢îu©h~¢bb:_Ü,îhÄß*väÃ*,ÄöC.©Ü:z@_î>ßÄOr*ð>/Av>zß©|:î+b_*Öå©üÃUãrCaU>.*aªhððOî+/<ߢau'), (' '), (N'oAß_U©Ã©uîvUã,z_ãÖ:C+/,Ðha+ÜåOäãÖözýrã|ðaAo,C@£ßÖß©ß>¢uÖÐuC©*.ß_@oüÄbzåÜåBAOUBª¢+_ab@A+hÄ|vüÐ媢u£åö_öÜ:öîö,~b@¢£>zß,Ða<ßãý>Aîbý@/öªu£b/Ö~Cªb'), (N'£A£*u~ßU>¢.hÄöv.AäüäoCî.ý/îbߢ/,ãU*:.~ß.ÄO:ýã@+<>oBÐCC/_hU*ßÃÖ:åraz:ªßab/~£@ÃvÐãßzhuaÄüÖ|ÜßOîä©o£Ã|ü:äuÃäÜUOß,_Öª¢ß@äubäOuChÖZh~î>åýÐÖ.üB<,u<ßöOUbªZboZ.£ÄÜrÐbð~¢Ãvz>_aãrã..äß..ZöåÃÃã@Ör>+aýruA|ߪÜ@£ÄÄbÜBuÜå_ãz+îßOUåßo_BaOaãaª,äbr¢å£UO¢ðÖvýzö@Ä¢Z:ãzðߪý_Ã@bðB£,A>¢Ã>U_a¢übî_ßb©ZuÄh|_C.aîC|©~ý££ªv:îAhAîßÃüÖÄ:Ö£äÜÄ,>ã>+uÃ~hý+bü.Uö@¢Üvb©UÐäo£Z:+ðßßZvhÜÜB©*|åð<£ý+:@UAb@¢ÐUC£Oª,Cßb|UÃhCOÐ@Cð_ÜzvrOväöCîÐZÃ_î£hîbü/Bãî.zu*z@@öªBöðã:a*@OÃOßöýªr_ª¢böBÃ<+ßäb@¢ª.ßĪªüßÄîÐ:U/©B:z¢Cßðåå£ýv:>¢hva|bÜAU.aUÐîÐ*>äUßU,|'), (null), ('Ã@îbªz@zbÖ::Ä+åbOî¢åbao|oha£UU~ã£Ä,vCrßÃÐ.ãüåbhîîoO£ß>ÜÃ**å:zäbãOªßýý¢öýBðh©OrÃCýBÐbböAhöÃößz++å*aßvuoðZur|î*B>h©Üä+ªuÃobuÜh>ªZ<ã©h>£ÃabÖö£äo+_U*Bv¢rßÃ>|@ðzüåî+¢bîÄÃAîv>ܪ©ªãýÄÄ_ß.zÃUAü©öhÜÄCåbZuB:ß|zOah/OAîÄ@rª/b@AöãäÐABÜ>ܩТZªîvåü>rz|ãäöÖu¢~BÃß_vZv~B_u/@+Ü<.ªB¢ðÐ<ªZÄ,ýaßvähî©üöbAz£Äß:vßßrb,_oCa©,urU|îv|ZU,vªÄß_z|ßüuöAz@îOö£UCÐhUZÖÐã<.,h>Oî_r@Uäuª*A::råÖ©Ð*ðAh£h*.bß>B,ªb:ã/üéÃÜA@,Bßä|ãbß©bu10/31/2016 11:46:19 AMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/0110/31/2016 11:46:19 AMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/00'), ('01:21:33.8136175'), ('0413-05-13'), ('2016-10-31 11:46:19.9521697'), ('6050-11-19 01:00:40.4482745+00:00'))"; + break; + default: + break; + } + return $query; +} + +function Repro() +{ + StartTest("pdo_fetch_fetchinto_query_args"); + try + { + FetchInto_Query_Args(); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("pdo_fetch_fetchinto_query_args"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'pdo_fetch_fetchinto_query_args' test... +Constructor called with 0 arguments +Constructor called with 2 arguments +Comparing data in row 1 +Comparing data in row 2 + +Done +...Test 'pdo_fetch_fetchinto_query_args' completed successfully. + diff --git a/test/pdo_sqlsrv/pdo_getAttribute_clientInfo.phpt b/test/pdo_sqlsrv/pdo_getAttribute_clientInfo.phpt new file mode 100644 index 000000000..f85a0e35c --- /dev/null +++ b/test/pdo_sqlsrv/pdo_getAttribute_clientInfo.phpt @@ -0,0 +1,22 @@ +--TEST-- +Test client info by calling PDO::getAttribute with PDO::ATTR_CLIENT_VERSION +--FILE-- +getAttribute( PDO::ATTR_CLIENT_VERSION )); + +//free the connection +$conn=null; +?> +--EXPECTREGEX-- +Array +\( + \[(DriverDllName|DriverName)\] => (msodbcsql1[1-9].dll|libmsodbcsql-[1-9]{2}.[0-9].so.[0-9].[0-9]) + \[DriverODBCVer\] => [0-9]{1,2}\.[0-9]{1,2} + \[DriverVer\] => [0-9]{1,2}\.[0-9]{1,2}\.[0-9]{4} + \[ExtensionVer\] => [0-9]\.[0-9]\.[0-9](\-((rc)|(preview))(\.[0-9]+)?)?(\+[0-9]+)? +\) \ No newline at end of file diff --git a/test/pdo_sqlsrv/pdo_nested_query_mars.phpt b/test/pdo_sqlsrv/pdo_nested_query_mars.phpt new file mode 100644 index 000000000..26cf0c7a2 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_nested_query_mars.phpt @@ -0,0 +1,108 @@ +--TEST-- +fetch multiple result sets with MARS on and then off +--SKIPIF-- + +--FILE-- +SetAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + $stmt = $conn->exec("CREATE TABLE $tableName ([c1_int] int, [c2_varchar] varchar(20))"); + + $query = "INSERT INTO $tableName ([c1_int], [c2_varchar]) VALUES (1, 'Dummy value 1')"; + $stmt = $conn->query($query); + + $query = "INSERT INTO $tableName ([c1_int], [c2_varchar]) VALUES (2, 'Dummy value 2')"; + $stmt = $conn->query($query); + + $query = "SELECT * FROM $tableName ORDER BY [c1_int]"; + $stmt = $conn->query($query); + $numRows = 0; + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) + $numRows++; + + if ($numRows !== 2) echo "Number of rows is unexpected!\n"; + $stmt = null; + + // more than one active results + $stmt1 = $conn->query($query); + $stmt2 = $conn->prepare($query); + $stmt2->execute(); + + echo "\nNumber of columns in First set: " . $stmt2->columnCount() . "\n"; + while ($row = $stmt1->fetch(PDO::FETCH_ASSOC)) + { + print_r($row); + } + + echo "\nNumber of columns in Second set: " . $stmt1->columnCount() . "\n\n"; + while ($row = $stmt2->fetch(PDO::FETCH_OBJ)) + { + print_r($row); + } + + $stmt1 = null; + $stmt2 = null; + $conn = null; +} + +function Repro() +{ + StartTest("pdo_nested_query_mars"); + try + { + NestedQuery_Mars(true); + NestedQuery_Mars(false); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("pdo_nested_query_mars"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'pdo_nested_query_mars' test... + +Number of columns in First set: 2 +Array +( + [c1_int] => 1 + [c2_varchar] => Dummy value 1 +) +Array +( + [c1_int] => 2 + [c2_varchar] => Dummy value 2 +) + +Number of columns in Second set: 2 + +stdClass Object +( + [c1_int] => 1 + [c2_varchar] => Dummy value 1 +) +stdClass Object +( + [c1_int] => 2 + [c2_varchar] => Dummy value 2 +) +SQLSTATE[IMSSP]: The connection cannot process this operation because there is a statement with pending results. To make the connection available for other queries, either fetch all results or cancel or free the statement. For more information, see the product documentation about the MultipleActiveResultSets connection option. +Done +...Test 'pdo_nested_query_mars' completed successfully. diff --git a/test/pdo_sqlsrv/pdo_query_timeout.phpt b/test/pdo_sqlsrv/pdo_query_timeout.phpt new file mode 100644 index 000000000..ec56fbfb8 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_query_timeout.phpt @@ -0,0 +1,92 @@ +--TEST-- +test query time out at the connection level and statement level +--SKIPIF-- + +--FILE-- +exec("CREATE TABLE $tableName ([c1_int] int, [c2_varchar] varchar(25))"); + + $query = "INSERT INTO $tableName ([c1_int], [c2_varchar]) VALUES (1, 'QueryTimeout 1')"; + $stmt = $conn->query($query); + + $query = "INSERT INTO $tableName ([c1_int], [c2_varchar]) VALUES (2, 'QueryTimeout 2')"; + $stmt = $conn->query($query); + + $query = "SELECT * FROM $tableName"; + + if ($connLevel) + { + echo "Setting query timeout as an attribute in connection\n"; + $conn->setAttribute(constant('PDO::SQLSRV_ATTR_QUERY_TIMEOUT'), 1); + $stmt = $conn->query("WAITFOR DELAY '00:00:03'; $query"); + + var_dump($conn->errorInfo()); + } + else + { + echo "Setting query timeout in the statement\n"; + $stmt = $conn->prepare("WAITFOR DELAY '00:00:03'; $query", array(constant('PDO::SQLSRV_ATTR_QUERY_TIMEOUT') => 1)); + $stmt->execute(); + + var_dump($stmt->errorInfo()); + } + + $stmt = null; + $conn = null; +} + +function Repro() +{ + StartTest("pdo_query_timeout"); + try + { + QueryTimeout(true); + QueryTimeout(false); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("pdo_query_timeout"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'pdo_query_timeout' test... +Setting query timeout as an attribute in connection +array(3) { + [0]=> + string(5) "HYT00" + [1]=> + int(0) + [2]=> + string(63) "[Microsoft][ODBC Driver 13 for SQL Server]Query timeout expired" +} +Setting query timeout in the statement +array(3) { + [0]=> + string(5) "HYT00" + [1]=> + int(0) + [2]=> + string(63) "[Microsoft][ODBC Driver 13 for SQL Server]Query timeout expired" +} + +Done +...Test 'pdo_query_timeout' completed successfully. diff --git a/test/pdo_sqlsrv/pdo_statement_rowcount_query.phpt b/test/pdo_sqlsrv/pdo_statement_rowcount_query.phpt new file mode 100644 index 000000000..f0c8fe7ce --- /dev/null +++ b/test/pdo_sqlsrv/pdo_statement_rowcount_query.phpt @@ -0,0 +1,181 @@ +--TEST-- +test rowCount() with different querying method and test nextRowset() with different fetch +--SKIPIF-- + +--FILE-- +exec("CREATE TABLE $tableName ([c1_int] int, [c2_real] real)"); + + $numRows = 5; + for ($i = 1; $i <= $numRows; $i++) + { + InsertData($conn, $tableName, $i); + } + + FetchRowsets($conn, $tableName, $numRows); + + for ($i = 1; $i <= $numRows; $i++) + { + UpdateData($conn, $tableName, $i, $exec); + } + + DeleteData($conn, $tableName, $exec); + + $stmt = null; + $conn = null; +} + +function InsertData($conn, $tableName, $value) +{ + $query = "INSERT INTO $tableName VALUES ($value, $value * 1.0)"; + $stmt = $conn->query($query); +} + +function UpdateData($conn, $tableName, $value, $exec) +{ + $newValue = $value * 100; + $query = "UPDATE $tableName SET c1_int = $newValue WHERE (c1_int = $value)"; + $rowCount = 0; + + if ($exec) + { + $rowCount = $conn->exec($query); + } + else + { + $stmt = $conn->prepare($query); + $rowCount = $stmt->rowCount(); + if ($rowCount > 0) + echo "Number of rows affected prior to execution should be 0!\n"; + + $stmt->execute(); + $rowCount = $stmt->rowCount(); + } + + if ($rowCount !== 1) + echo "Number of rows affected should be 1!\n"; + + $stmt = null; +} + +function CompareValues($actual, $expected) +{ + if ($actual != $expected) + { + echo "Unexpected value $value returned! Expected $expected.\n"; + } +} + +function FetchRowsets($conn, $tableName, $numRows) +{ + $query = "SELECT [c1_int] FROM $tableName ORDER BY [c1_int]"; + $queries = $query . ';' . $query . ';' . $query; + $stmt = $conn->query($queries); + + $i = 0; + while ($row = $stmt->fetch(PDO::FETCH_LAZY)) + { + $value = (int)$row['c1_int']; + CompareValues($value, ++$i); + } + + if ($i != $numRows) + { + echo "Number of rows fetched $i is unexpected!\n"; + } + + $result = $stmt->nextRowset(); + if ($result == false) + { + echo "Missing result sets!\n"; + } + + $rows = $stmt->fetchAll(PDO::FETCH_NUM); + $i = 0; + foreach ($rows as $row) + { + foreach ($row as $key => $value) + { + $value = (int)$value; + CompareValues($value, ++$i); + } + } + + $result = $stmt->nextRowset(); + if ($result == false) + { + echo "Missing result sets!\n"; + } + + $stmt->bindColumn('c1_int', $value); + $i = 0; + while ($row = $stmt->fetch(PDO::FETCH_BOUND)) + { + CompareValues($value, ++$i); + } + + $result = $stmt->nextRowset(); + if ($result != false) + { + echo "Number of result sets exceeding expectation!\n"; + } +} + +function DeleteData($conn, $tableName, $exec) +{ + $query = "DELETE TOP(3) FROM $tableName"; + $rowCount = 0; + + if ($exec) + { + $rowCount = $conn->exec($query); + } + else + { + $stmt = $conn->query($query); + $rowCount = $stmt->rowCount(); + } + + if ($rowCount <= 0) + echo "Number of rows affected should be > 0!\n"; + + $stmt = null; +} + +function Repro() +{ + StartTest("pdo_statement_rowcount_query"); + try + { + RowCount_Query(true); + RowCount_Query(false); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("pdo_statement_rowcount_query"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'pdo_statement_rowcount_query' test... + +Done +...Test 'pdo_statement_rowcount_query' completed successfully. diff --git a/test/pdo_sqlsrv/pdo_stored_proc_fetch_datatypes.phpt b/test/pdo_sqlsrv/pdo_stored_proc_fetch_datatypes.phpt new file mode 100644 index 000000000..2936e9cae --- /dev/null +++ b/test/pdo_sqlsrv/pdo_stored_proc_fetch_datatypes.phpt @@ -0,0 +1,320 @@ +--TEST-- +call stored procedures with inputs of ten different datatypes to get outputs of various types +--SKIPIF-- + +--FILE-- +exec("CREATE PROC $procName (@p1 BIGINT, @p2 BIGINT, @p3 NCHAR(128) OUTPUT) + AS BEGIN SELECT @p3 = CONVERT(NCHAR(128), @p1 + @p2) END"); + + $inValue1 = '12345678'; + $inValue2 = '11111111'; + $outValue = '0'; + + $stmt = $conn->prepare("{CALL $procName (?, ?, ?)}"); + $stmt->bindValue(1, $inValue1); + $stmt->bindValue(2, $inValue2); + $stmt->bindParam(3, $outValue, PDO::PARAM_STR, 300); + $stmt->execute(); + + $expected = "23456789"; + $outValue = trim($outValue); + if (strncasecmp($outValue, $expected, strlen($expected))) + { + echo "Output value $outValue is unexpected! Expected $expected\n"; + } + + $stmt = null; +} + +function ProcFetch_Decimal($conn) +{ + $procName = GetTempProcName(); + + $stmt = $conn->exec("CREATE PROC $procName (@p1 DECIMAL, @p2 DECIMAL, @p3 CHAR(128) OUTPUT) + AS BEGIN SELECT @p3 = CONVERT(CHAR(128), @p1 + @p2) END"); + + $inValue1 = '2.1'; + $inValue2 = '5.3'; + $outValue = '0'; + + $stmt = $conn->prepare("{CALL $procName (?, ?, ?)}"); + $stmt->bindValue(1, $inValue1); + $stmt->bindValue(2, $inValue2); + $stmt->bindParam(3, $outValue, PDO::PARAM_STR, 300); + $stmt->execute(); + + $expected = "7"; + $outValue = trim($outValue); + if (strncasecmp($outValue, $expected, strlen($expected))) + { + echo "Output value $outValue is unexpected! Expected $expected\n"; + } + + $stmt = null; +} + +function ProcFetch_Float($conn) +{ + $procName = GetTempProcName(); + + $stmt = $conn->exec("CREATE PROC $procName (@p1 FLOAT, @p2 FLOAT, @p3 FLOAT OUTPUT) + AS BEGIN SELECT @p3 = CONVERT(FLOAT, @p1 + @p2) END"); + + $inValue1 = '2.25'; + $inValue2 = '5.5'; + $outValue = '0'; + + $stmt = $conn->prepare("{CALL $procName (?, ?, ?)}"); + $stmt->bindValue(1, $inValue1); + $stmt->bindValue(2, $inValue2); + $stmt->bindParam(3, $outValue, PDO::PARAM_STR, 300); + $stmt->execute(); + + $expected = "7.75"; + $outValue = trim($outValue); + if (strncasecmp($outValue, $expected, strlen($expected))) + { + echo "Output value $outValue is unexpected! Expected $expected\n"; + } + + $stmt = null; +} + +function ProcFetch_Int($conn) +{ + $procName = GetTempProcName(); + + $stmt = $conn->exec("CREATE PROC $procName (@p1 INT, @p2 INT, @p3 INT OUTPUT) + AS BEGIN SELECT @p3 = CONVERT(INT, @p1 + @p2) END"); + + $inValue1 = '1234'; + $inValue2 = '5678'; + $outValue = '0'; + + $stmt = $conn->prepare("{CALL $procName (?, ?, ?)}"); + $stmt->bindValue(1, $inValue1); + $stmt->bindValue(2, $inValue2); + $stmt->bindParam(3, $outValue, PDO::PARAM_STR, 300); + $stmt->execute(); + + $expected = "6912"; + $outValue = trim($outValue); + if (strncasecmp($outValue, $expected, strlen($expected))) + { + echo "Output value $outValue is unexpected! Expected $expected\n"; + } + + $stmt = null; +} + +function ProcFetch_Money($conn) +{ + $procName = GetTempProcName(); + + $stmt = $conn->exec("CREATE PROC $procName (@p1 MONEY, @p2 MONEY, @p3 MONEY OUTPUT) + AS BEGIN SELECT @p3 = CONVERT(MONEY, @p1 + @p2) END"); + + $inValue1 = '22.3'; + $inValue2 = '16.1'; + $outValue = '0'; + + $stmt = $conn->prepare("{CALL $procName (?, ?, ?)}"); + $stmt->bindValue(1, $inValue1, PDO::PARAM_STR); + $stmt->bindParam(2, $inValue2, PDO::PARAM_STR); + $stmt->bindParam(3, $outValue, PDO::PARAM_STR, 300); + $stmt->execute(); + + $expected = "38.40"; + $outValue = trim($outValue); + if (strncasecmp($outValue, $expected, strlen($expected))) + { + echo "Output value $outValue is unexpected! Expected $expected\n"; + } + + $stmt = null; +} + +function ProcFetch_Numeric($conn) +{ + $procName = GetTempProcName(); + + $stmt = $conn->exec("CREATE PROC $procName (@p1 NUMERIC, @p2 NUMERIC, @p3 NCHAR(128) OUTPUT) + AS BEGIN SELECT @p3 = CONVERT(NCHAR(128), @p1 + @p2) END"); + + $inValue1 = '2.8'; + $inValue2 = '5.4'; + $outValue = '0'; + + $stmt = $conn->prepare("{CALL $procName (?, ?, ?)}"); + $stmt->bindValue(1, $inValue1); + $stmt->bindParam(2, $inValue2); + $stmt->bindParam(3, $outValue, PDO::PARAM_STR, 300); + $stmt->execute(); + + $expected = "8"; + $outValue = trim($outValue); + if (strncasecmp($outValue, $expected, strlen($expected))) + { + echo "Output value $outValue is unexpected! Expected $expected\n"; + } + + $stmt = null; +} + +function ProcFetch_Real($conn) +{ + $procName = GetTempProcName(); + + $stmt = $conn->exec("CREATE PROC $procName (@p1 REAL, @p2 REAL, @p3 REAL OUTPUT) + AS BEGIN SELECT @p3 = CONVERT(REAL, @p1 + @p2) END"); + + $inValue1 = '3.4'; + $inValue2 = '6.6'; + $outValue = '0'; + + $stmt = $conn->prepare("{CALL $procName (?, ?, ?)}"); + $stmt->bindValue(1, $inValue1); + $stmt->bindParam(2, $inValue2); + $stmt->bindParam(3, $outValue, PDO::PARAM_STR, 300); + $stmt->execute(); + + $expected = "10"; + $outValue = trim($outValue); + if (strncasecmp($outValue, $expected, strlen($expected))) + { + echo "Output value $outValue is unexpected! Expected $expected\n"; + } + + $stmt = null; +} + +function ProcFetch_SmallInt($conn) +{ + $procName = GetTempProcName(); + + $stmt = $conn->exec("CREATE PROC $procName (@p1 SMALLINT, @p2 SMALLINT, @p3 NCHAR(32) OUTPUT) + AS BEGIN SELECT @p3 = CONVERT(NCHAR(32), @p1 + @p2) END"); + + $inValue1 = '34'; + $inValue2 = '56'; + $outValue = '0'; + + $stmt = $conn->prepare("{CALL $procName (?, ?, ?)}"); + $stmt->bindValue(1, $inValue1); + $stmt->bindParam(2, $inValue2); + $stmt->bindParam(3, $outValue, PDO::PARAM_STR, 300); + $stmt->execute(); + + $expected = "90"; + $outValue = trim($outValue); + if (strncasecmp($outValue, $expected, strlen($expected))) + { + echo "Output value $outValue is unexpected! Expected $expected\n"; + } + + $stmt = null; +} + +function ProcFetch_SmallMoney($conn) +{ + $procName = GetTempProcName(); + + $stmt = $conn->exec("CREATE PROC $procName (@p1 SMALLMONEY, @p2 SMALLMONEY, @p3 SMALLMONEY OUTPUT) + AS BEGIN SELECT @p3 = CONVERT(SMALLMONEY, @p1 + @p2) END"); + + $inValue1 = '10'; + $inValue2 = '11.7'; + $outValue = '0'; + + $stmt = $conn->prepare("{CALL $procName (?, ?, ?)}"); + $stmt->bindValue(1, $inValue1, PDO::PARAM_STR); + $stmt->bindParam(2, $inValue2, PDO::PARAM_STR); + $stmt->bindParam(3, $outValue, PDO::PARAM_STR, 300); + $stmt->execute(); + + $expected = "21.70"; + $outValue = trim($outValue); + if (strncasecmp($outValue, $expected, strlen($expected))) + { + echo "Output value $outValue is unexpected! Expected $expected\n"; + } + + $stmt = null; +} + +function ProcFetch_TinyInt($conn) +{ + $procName = GetTempProcName(); + + $stmt = $conn->exec("CREATE PROC $procName (@p1 TINYINT, @p2 TINYINT, @p3 CHAR(32) OUTPUT) + AS BEGIN SELECT @p3 = CONVERT(CHAR(32), @p1 + @p2) END"); + + $inValue1 = '11'; + $inValue2 = '12'; + $outValue = '0'; + + $stmt = $conn->prepare("{CALL $procName (?, ?, ?)}"); + $stmt->bindValue(1, $inValue1); + $stmt->bindParam(2, $inValue2); + $stmt->bindParam(3, $outValue, PDO::PARAM_STR, 300); + $stmt->execute(); + + $expected = "23"; + $outValue = trim($outValue); + if (strncasecmp($outValue, $expected, strlen($expected))) + { + echo "Output value $outValue is unexpected! Expected $expected\n"; + } + + $stmt = null; +} + +function Repro() +{ + set_time_limit(0); + StartTest("pdo_stored_proc_fetch_datatypes"); + try + { + require_once("autonomous_setup.php"); + $database = "tempdb"; + $conn = new PDO( "sqlsrv:server=$serverName;Database=$database", $username, $password); + + ProcFetch_BigInt($conn); + ProcFetch_Decimal($conn); + ProcFetch_Float($conn); + ProcFetch_Int($conn); + ProcFetch_Money($conn); + ProcFetch_Numeric($conn); + ProcFetch_Real($conn); + ProcFetch_SmallInt($conn); + ProcFetch_SmallMoney($conn); + ProcFetch_TinyInt($conn); + + $conn = null; + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("pdo_stored_proc_fetch_datatypes"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'pdo_stored_proc_fetch_datatypes' test... + +Done +...Test 'pdo_stored_proc_fetch_datatypes' completed successfully. + diff --git a/test/pdo_sqlsrv/pdo_tools.inc b/test/pdo_sqlsrv/pdo_tools.inc new file mode 100644 index 000000000..959fa51c5 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_tools.inc @@ -0,0 +1,446 @@ +getColumnMeta($colIndex); + $colType = $meta['sqlsrv:decl_type']; + $colName = $meta['name']; + + if (! IsUpdatable($colName)) + { + return true; // do nothing for non-IsUpdatable fields + } + + return CompareDataValue($colType, $rowIndex, $colName, $actual, $expected); +} + +function CompareCharacterData($actual, $expected) +{ + $matched = false; + if ($actual === $expected) + { + $matched = true; + } + else + { + $len = strlen($expected); + + $result = strncmp($expected, $actual, $len); + if ($result == 0) + { + $matched = true; + } + } + + //echo "Expected: $expected\nActual: $actual\n"; + if (! $matched) + { + echo "Data corruption!! Expected: $expected\nActual: $actual\n"; + } + + return $matched; +} + +function DumpMetadata($stmt) +{ + $numFields = $stmt->columnCount(); + for ($j = 0; $j < $numFields; $j++) + { + $meta = $stmt->getColumnMeta($j); + var_dump($meta); + } +} + +function GetColumnData($stmt, $query, $rowIndex, $colIndex) +{ + $skipCount = 0; + $data = ""; + for ($j = 0; $j <= $colIndex; $j++) + { + $meta = $stmt->getColumnMeta($j); + $type = $meta['sqlsrv:decl_type']; + $name = $meta['name']; + + if (!IsUpdatable($name)) + { + $skipCount++; + } + else + { + if ($j == $colIndex) + { + $data = GetInsertData($query, $type, $rowIndex, $j + 1, $skipCount); + break; + } + } + } + + return $data; +} + +function InsertDataToArray($stmt, $query, $numFields, $rowIndex) +{ + $dataArray = array(); + + $skipCount = 0; + for ($j = 0; $j < $numFields; $j++) + { + $meta = $stmt->getColumnMeta($j); + $type = $meta['sqlsrv:decl_type']; + $name = $meta['name']; + + $colIndex = $j + 1; + if (!IsUpdatable($name)) + { + $skipCount++; + array_push($dataArray, ""); + } + else + { + $data = GetInsertData($query, $type, $rowIndex, $colIndex, $skipCount); + array_push($dataArray, $data); + } + } + + return $dataArray; +} + +function GetInsertData($query, $colType, $rowIndex, $colIndex, $skip) +{ + $data = strstr($query, "(("); + $pos = 1; + if ($data === false) + { + die("Failed to retrieve data on row $rowIndex"); + } + $data = substr($data, 2); + + while ($pos < ($colIndex - $skip)) + { + $data = strstr($data, ", ("); + $pos++; + + if ($data === false) + { + die("Failed to retrieve data on column $pos"); + } + $data = substr($data, 3); + } + + // Is it's XML type, we can't use the closing bracket as the next delimiter + // because a bracket can be part of the xml data, unless the data is null + $str = ")"; + $pos = strpos($data, $str); + if ($pos === false) + { + die("Failed to isolate data on row $rowIndex, column $pos"); + } + $tmp = substr($data, 0, $pos); + if ((strcasecmp($tmp, "null") == 0) || strlen($tmp) == 0) + { + $tmp = ""; + } + else if (IsXml($colType)) + { + $str = ">')"; + $pos = strpos($data, $str); + $tmp = substr($data, 0, $pos + 2); + } + + $data = $tmp; + + if (IsDataUnicode($colType, $data)) // this includes unicode data type and XML data that is in Unicode + { // N'data' + $data = substr($data, 2, strlen($data) - 3); + } + else if (IsLiteral($colType)) + { // 'data' + $data = substr($data, 1, strlen($data) - 2); + } + else if (IsBinary($colType)) + { // 0xdata + $data = substr($data, 2); + } + + return (trim($data)); +} + +function CompareBinaryStream($inputFile, $actual) +{ + // open input file first + $stream = fopen($inputFile, "r"); + + $len = strlen($actual); + echo "Comparing data...\n"; + $matched = true; + $numbytes = _CHUNK_SIZE; + + $pos = 0; + while (! feof($stream) && $pos < $len) + { + $contents = fread($stream, $numbytes); + + // if $actual is empty, check if $contents is also empty + $contents_len = strlen($contents); + if ($len == 0) + { + $matched = ($contents_len == 0); + break; + } + + // Compare contents (case-sensitive) + $count = ($contents_len < $numbytes) ? $contents_len : $numbytes; + $result = substr_compare($actual, $contents, $pos, $count); + + if ($result != 0) + { + $matched = false; + echo "Data corruption!!\nExpected: $contents\nActual:" . substr($actual, $pos, $count) . "\n"; + break; + } + + $pos += $count; + } + + // close the data stream + fclose($stream); + + return $matched; +} + +function IsUpdatable($colName) +{ + $pos = strpos($colName, "_"); + $type = substr($colName, $pos + 1); + + return (strcasecmp($type, "timestamp") != 0); +} + +function IsDataUnicode($colType, $data) +{ + if (IsUnicode($colType)) + return true; + + // This input string may be an XML string in unicode (i.e. // N'...') + $letterN = 'N'; + $index = strpos($data, $letterN); + + // Note the use of ===. Simply == would not work as expected + // because the position of letterN 'N' may be the 0th (first) character + // and strpos will return false if not found. + if ($index === 0) { + return true; + } + + return false; +} + +function IsUnicode($type) +{ + switch ($type) + { + case 'nchar' : + case 'nvarchar' : + case 'ntext' : + return true; + default: + break; + } + return (false); +} + +function IsXml($type) +{ + return ($type == 'xml'); +} + +function IsBinary($type) +{ + switch ($type) + { + case 'binary': + case 'varbinary': + case 'image': + return true; + default: + break; + } + return (false); +} + +function IsDateTime($type) +{ + switch ($type) + { + case 'datetime' : + case 'datetime2' : + case 'smalldatetime' : + case 'date' : + case 'time' : + case 'datetimeoffset' : + return true; + default: + break; + } + return (false); +} + +function IsLiteral($type) +{ + switch ($type) + { + case 'char' : + case 'nchar' : + case 'varchar' : + case 'nvarchar' : + case 'text' : + case 'ntext' : + case 'uniqueidentifier' : + case 'datetime' : + case 'datetime2' : + case 'smalldatetime' : + case 'date' : + case 'time' : + case 'datetimeoffset' : + case 'xml' : + return true; + default: + break; + } + return (false); +} + +?> \ No newline at end of file diff --git a/test/pdo_sqlsrv/pdo_utf8_stored_proc_unicode_chars.phpt b/test/pdo_sqlsrv/pdo_utf8_stored_proc_unicode_chars.phpt new file mode 100644 index 000000000..1bc223ac1 --- /dev/null +++ b/test/pdo_sqlsrv/pdo_utf8_stored_proc_unicode_chars.phpt @@ -0,0 +1,105 @@ +--TEST-- +call a stored procedure with unicode input to get output back as unicode; also test with xml data +--SKIPIF-- + +--FILE-- +exec("CREATE PROC $procName (@p1 XML, @p2 CHAR(512) OUTPUT) + AS BEGIN SELECT @p2 = CONVERT(CHAR(512), @p1) END"); + + $stmt = $conn->prepare("{CALL $procName (?, ?)}"); + $stmt->bindValue(1, $inValue1); + $stmt->bindParam(2, $outValue1, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 512); + $stmt->execute(); + + var_dump(trim($outValue1)); + + $stmt = null; +} + +function StoredProc_Surrogate($conn) +{ + $inValue1 = pack('H*', 'F2948080EFBFBDEFBFBDF48FBA83EFBFBDEFBFBDEFBFBDEFBFBDEFBFBDF48FB080EFBFBDEFBFBDEFBFBDF392A683EFBFBDF090808BF0908080F0908A83EFBFBDEFBFBDEFBFBDF48FBFBFEFBFBDEFBFBDF090808BF0908683EFBFBDF48FBFBFF2948880EFBFBDF0A08FBFEFBFBDF392A880F0A08A83F294808BF0908880EFBFBDEFBFBDEFBFBDEFBFBDF48FB080F48FB683EFBFBDF0908080EFBFBDF392AA83F48FB683EFBFBDF2948080F2948A83EFBFBDF0A08080F392A880EFBFBDF2948FBFEFBFBDEFBFBDEFBFBDEFBFBDF48FB683EFBFBDEFBFBDEFBFBDF48FBFBFF0908080EFBFBDEFBFBDEFBFBDEFBFBDF48FBFBFEFBFBDF48FB880F0908683F392A080F0908FBFEFBFBDEFBFBDEFBFBDEFBFBDEFBFBDF2948FBFEFBFBDF0908683EFBFBDF0A08A83F48FBA83EFBFBDF48FB08B'); + $outValue1 = "TEST"; + + $procName = GetTempProcName(); + $stmt = $conn->exec("CREATE PROC $procName (@p1 NVARCHAR(1000), @p2 NVARCHAR(1000) OUTPUT) + AS BEGIN SELECT @p2 = CONVERT(NVARCHAR(1000), @p1) END"); + + $stmt = $conn->prepare("{CALL $procName (?, ?)}"); + $stmt->bindValue(1, $inValue1); + $stmt->bindParam(2, $outValue1, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 1000); + $stmt->execute(); + + var_dump ($outValue1 === $inValue1); + + $stmt = null; +} + +function StoredProc_Unicode($conn) +{ + $inValue1 = pack('H*', 'E9AA8CE597BFE382A1E38381C3BDD086C39FD086C3B6C39CE3838FC3BDE8A1A4C3B6E38390C3A4C3B0C2AAE78687C3B0E2808DE6B490C4B1E385AFE382BFE9B797E9B797D79CC39FC383DAAFE382B0E597BFE382BDE382B0E58080D187C3BCE382BCE385AFD290E78687E38381C3AEE382BCE9B797E2808CC3BB69E888B3D790D291E382AFD0A7E58080C39CE69B82D291C384C3BDD196E3839DE8A1A4C3AEE382BCC3BCE8A1A4E382BFD290E2808FE38380C4B0D187C3A5E3839DE382BDE382AFC396E382B0E382BFC3B6C396D0A7E385B0E3838FC3A3C2AAD990D187C3B6C3BBC384C3B0C390D18FE382BEC4B0E382BCD086C39FE3838FE4BE83E382BCC384E382BDD79CC3BCC39FE382BFE382BCE2808DE58080E58081D196C384D794D794C3B6D18FC3AEC3B6DA98E69B82E6B490C3AEE382BEDAAFD290'); + $outValue1 = "TEST"; + + $procName = GetTempProcName(); + $stmt = $conn->exec("CREATE PROC $procName (@p1 NVARCHAR(MAX), @p2 NCHAR(1024) OUTPUT) + AS BEGIN SELECT @p2 = CONVERT(NCHAR(1024), @p1) END"); + + $stmt = $conn->prepare("{CALL $procName (?, ?)}"); + $stmt->bindValue(1, $inValue1); + $stmt->bindParam(2, $outValue1, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 1500); + $stmt->execute(); + + $outValue1 = trim($outValue1); + var_dump ($outValue1 === $inValue1); + + $stmt = null; +} + +function Repro() +{ + StartTest("pdo_utf8_stored_proc_unicode_chars"); + try + { + require_once("autonomous_setup.php"); + + set_time_limit(0); + $database = "tempdb"; + + $conn = new PDO( "sqlsrv:server=$serverName;Database=$database", $username, $password); + + StoredProc_Xml($conn); + StoredProc_Surrogate($conn); + StoredProc_Unicode($conn); + + $conn = null; + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("pdo_utf8_stored_proc_unicode_chars"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'pdo_utf8_stored_proc_unicode_chars' test... +string(47) "Je préfère l'été" +bool(true) +bool(true) + +Done +...Test 'pdo_utf8_stored_proc_unicode_chars' completed successfully. + diff --git a/test/sqlsrv/sqlsrv_bind_param_out_string.phpt b/test/sqlsrv/sqlsrv_bind_param_out_string.phpt new file mode 100644 index 000000000..4cb111315 --- /dev/null +++ b/test/sqlsrv/sqlsrv_bind_param_out_string.phpt @@ -0,0 +1,459 @@ +--TEST-- +Verify the Binary and Char encoding output when binding output string with SQLSTYPE option with different size. +--DESCRIPTION-- +Tests different sizes of output string which may cause ODBC to return trunc error info. +With unixODBC 2.3.4, when connection pooling is enabled, error information maybe returned differently +than older versions (or with pooling disabled). +The NVARCHAR(1) section would cause an ODBC call to return an errorinfo to the driver causing the statement to fail. +With unixODBC 2.3.4 + pooling the statement executes without error. +--FILE-- + +"$username", "PWD"=>"$password"); +$conn = sqlsrv_connect($serverName, $connectionInfo); +if( $conn === false ) { + die( print_r( sqlsrv_errors(), true )); +} +$conn = null; + +$conn = sqlsrv_connect($serverName, $connectionInfo); +if( $conn === false ) { + die( print_r( sqlsrv_errors(), true )); +} + + +$bindtable = "#BindStringTest"; +$sproc = "#uspPerson"; + +// Create table +$stmt = sqlsrv_query( $conn, "CREATE TABLE $bindtable (PersonID int, Name nvarchar(50))" ); +if( $stmt === false ) { + die( print_r( sqlsrv_errors(), true )); +} + +$stmt = sqlsrv_query( $conn, "INSERT INTO $bindtable (PersonID, Name) VALUES (10, N'Miller')" ); +if( $stmt === false ) { + die( print_r( sqlsrv_errors(), true )); +} + +$stmt = sqlsrv_query( $conn, "INSERT INTO $bindtable (PersonID, Name) VALUES (11, N'JSmith')" ); +if( $stmt === false ) { + die( print_r( sqlsrv_errors(), true )); +} + +$tsql_createSP = "CREATE PROCEDURE $sproc + @id int, @return nvarchar(50) OUTPUT + AS + BEGIN + SET NOCOUNT ON; + SET @return = (SELECT Name FROM $bindtable WHERE PersonID = @id) + END"; + +$stmt = sqlsrv_query( $conn, $tsql_createSP); +if( $stmt === false ) +{ + echo "Error in executing statement 2.\n"; + die( print_r( sqlsrv_errors(), true)); +} + +$tsql_callSP = "{call $sproc( ? , ?)}"; + + +//*********************************************************************************************** + +echo "NVARCHAR(32)\n"; +echo "---------Encoding char-----------\n"; +$id = 10; +$return = ""; +$params = array( + array($id, SQLSRV_PARAM_IN), + array(&$return, SQLSRV_PARAM_OUT, + SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR), + SQLSRV_SQLTYPE_NVARCHAR(32) + )); + +if( $stmt = sqlsrv_query($conn, $tsql_callSP, $params) === false) +{ + print_r( sqlsrv_errors(), true); +} + +$expectedLength = 6; +$expectedValue = "Miller"; +$actualLength = strlen($return); +$actualValue = $return; +compareResults ( $expectedLength, $expectedValue, $actualLength, $actualValue ); + +echo "---------Encoding binary---------\n"; +$id = 10; +$return = ""; +$params = array( + array($id, SQLSRV_PARAM_IN), + array(&$return, SQLSRV_PARAM_OUT, + SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_BINARY), + SQLSRV_SQLTYPE_NVARCHAR(32) + )); +if( $stmt = sqlsrv_query($conn, $tsql_callSP, $params) == false) + { + print_r( sqlsrv_errors(), true); + } + +$expectedLength = 12; +$expectedValue = "M\0i\0l\0l\0e\0r\0"; +$actualLength = strlen($return); +$actualValue = $return; +compareResults ( $expectedLength, $expectedValue, $actualLength, $actualValue ); + +//*********************************************************************************************** +echo "\n\n"; +echo "NVARCHAR(50)\n"; +echo "---------Encoding char-----------\n"; +$id = 10; +$return = ""; +$params = array( + array($id, SQLSRV_PARAM_IN), + array(&$return, SQLSRV_PARAM_OUT, + SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR), + SQLSRV_SQLTYPE_NVARCHAR(50) + )); + +if( $stmt = sqlsrv_query($conn, $tsql_callSP, $params) === false) +{ + print_r( sqlsrv_errors(), true); +} + +$expectedLength = 6; +$expectedValue = "Miller"; +$actualLength = strlen($return); +$actualValue = $return; +compareResults ( $expectedLength, $expectedValue, $actualLength, $actualValue ); + + +echo "---------Encoding binary---------\n"; +$id = 10; +$return = ""; +$params = array( + array($id, SQLSRV_PARAM_IN), + array(&$return, SQLSRV_PARAM_OUT, + SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_BINARY), + SQLSRV_SQLTYPE_NVARCHAR(50) + )); +if( $stmt = sqlsrv_query($conn, $tsql_callSP, $params) == false) + { + print_r( sqlsrv_errors(), true); + } + +$expectedLength = 12; +$expectedValue = "M\0i\0l\0l\0e\0r\0"; +$actualLength = strlen($return); +$actualValue = $return; +compareResults ( $expectedLength, $expectedValue, $actualLength, $actualValue ); + +//*********************************************************************************************** +echo "\n\n"; +echo "NVARCHAR(1)\n"; +echo "---------Encoding char-----------\n"; +$id = 10; +$return = ""; + + +$params = array( + array($id, SQLSRV_PARAM_IN), + array(&$return, SQLSRV_PARAM_OUT, + SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR), + SQLSRV_SQLTYPE_NVARCHAR(1) + )); + +// with unixODBC 2.3.4 connection pooling the statement may not fail. +if( $stmt = sqlsrv_query($conn, $tsql_callSP, $params) === false) +{ + echo "Statement should fail\n"; +} + +$expectedLength = 1; +$expectedValue = "M"; +$actualValue = $return; +$actualLength = strlen($return); +compareResults ( $expectedLength, $expectedValue, $actualLength, $actualValue ); + +echo "---------Encoding binary---------\n"; +$id = 10; +$return = ""; +$params = array( + array($id, SQLSRV_PARAM_IN), + array(&$return, SQLSRV_PARAM_OUT, + SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_BINARY), + SQLSRV_SQLTYPE_NVARCHAR(1) + )); +if( $stmt = sqlsrv_query($conn, $tsql_callSP, $params) == false) + { + echo "Statement should fail\n"; + } + +$expectedLength = 2; +$expectedValue = "M\0"; +$actualLength = strlen($return); +$actualValue = $return; +compareResults ( $expectedLength, $expectedValue, $actualLength, $actualValue ); + +//*********************************************************************************************** +echo "\n\n"; +echo "NCHAR(32)\n"; +echo "---------Encoding char-----------\n"; +$id = 10; +$return = ""; +$params = array( + array($id, SQLSRV_PARAM_IN), + array(&$return, SQLSRV_PARAM_OUT, + SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR), + SQLSRV_SQLTYPE_NCHAR(32) + )); + +if( $stmt = sqlsrv_query($conn, $tsql_callSP, $params) === false) +{ + print_r( sqlsrv_errors(), true); +} + +$expectedLength = 32; +$expectedValue = "Miller "; +$actualLength = strlen($return); +$actualValue = $return; +compareResults ( $expectedLength, $expectedValue, $actualLength, $actualValue ); + +echo "---------Encoding binary---------\n"; +$id = 10; +$return = ""; +$params = array( + array($id, SQLSRV_PARAM_IN), + array(&$return, SQLSRV_PARAM_OUT, + SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_BINARY), + SQLSRV_SQLTYPE_NCHAR(32) + )); +if( $stmt = sqlsrv_query($conn, $tsql_callSP, $params) == false) + { + print_r( sqlsrv_errors(), true); + } + +$expectedLength = 64; +$expectedValue = "M\0i\0l\0l\0e\0r\0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0"; +$actualLength = strlen($return); +$actualValue = $return; +compareResults ( $expectedLength, $expectedValue, $actualLength, $actualValue ); + +//*********************************************************************************************** +echo "\n\n"; +echo "NCHAR(0)\n"; +echo "---------Encoding char-----------\n"; +$id = 10; +$return = ""; +$params = array( + array($id, SQLSRV_PARAM_IN), + array(&$return, SQLSRV_PARAM_OUT, + SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR), + SQLSRV_SQLTYPE_NCHAR(0) + )); + +if( $stmt = sqlsrv_query($conn, $tsql_callSP, $params) === false) +{ + echo "Statement should fail\n"; +} + +$expectedLength = 0; +$expectedValue = ""; +$actualLength = strlen($return); +$actualValue = $return; +compareResults ( $expectedLength, $expectedValue, $actualLength, $actualValue ); + +echo "---------Encoding binary---------\n"; +$id = 10; +$return = ""; +$params = array( + array($id, SQLSRV_PARAM_IN), + array(&$return, SQLSRV_PARAM_OUT, + SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_BINARY), + SQLSRV_SQLTYPE_NCHAR(0) + )); +if( $stmt = sqlsrv_query($conn, $tsql_callSP, $params) == false) + { + echo "Statement should fail\n"; + } + +$expectedLength = 0; +$expectedValue = ""; +$actualLength = strlen($return); +$actualValue = $return; +compareResults ( $expectedLength, $expectedValue, $actualLength, $actualValue ); + +//*********************************************************************************************** +echo "\n\n"; +echo "NCHAR(50)\n"; +echo "---------Encoding char-----------\n"; +$id = 10; +$return = ""; +$params = array( + array($id, SQLSRV_PARAM_IN), + array(&$return, SQLSRV_PARAM_OUT, + SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR), + SQLSRV_SQLTYPE_NCHAR(50) + )); + +if( $stmt = sqlsrv_query($conn, $tsql_callSP, $params) === false) +{ + print_r( sqlsrv_errors(), true); +} + +$expectedLength = 50; +$expectedValue = "Miller "; +$actualLength = strlen($return); +$actualValue = $return; +compareResults ( $expectedLength, $expectedValue, $actualLength, $actualValue ); + +echo "---------Encoding binary---------\n"; +$id = 10; +$return = ""; +$params = array( + array($id, SQLSRV_PARAM_IN), + array(&$return, SQLSRV_PARAM_OUT, + SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_BINARY), + SQLSRV_SQLTYPE_NCHAR(50) + )); +if( $stmt = sqlsrv_query($conn, $tsql_callSP, $params) == false) + { + print_r( sqlsrv_errors(), true); + } + +$expectedLength = 100; +$expectedValue = "M\0i\0l\0l\0e\0r\0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0"; +$actualLength = strlen($return); +$actualValue = $return; +compareResults ( $expectedLength, $expectedValue, $actualLength, $actualValue ); + +//*********************************************************************************************** +// NCHAR 1: less than length of the returned value +echo "\n\n"; +echo "NCHAR(1)\n"; +echo "---------Encoding char-----------\n"; +$id = 10; +$return = ""; +$params = array( + array($id, SQLSRV_PARAM_IN), + array(&$return, SQLSRV_PARAM_OUT, + SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR), + SQLSRV_SQLTYPE_NCHAR(1) + )); + +if( $stmt = sqlsrv_query($conn, $tsql_callSP, $params) === false) +{ + print_r( sqlsrv_errors(), true); +} + +$expectedLength = 1; +$expectedValue = "M"; +$actualValue = $return; +$actualLength = strlen($return); +compareResults ( $expectedLength, $expectedValue, $actualLength, $actualValue ); + +echo "---------Encoding binary---------\n"; +$id = 10; +$return = ""; +$params = array( + array($id, SQLSRV_PARAM_IN), + array(&$return, SQLSRV_PARAM_OUT, + SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_BINARY), + SQLSRV_SQLTYPE_NCHAR(1) + )); +if( $stmt = sqlsrv_query($conn, $tsql_callSP, $params) == false) + { + print_r( sqlsrv_errors(), true); + } + +$expectedLength = 2; +$expectedValue = "M\0"; +$actualValue = $return; +$actualLength = strlen($return); +compareResults ( $expectedLength, $expectedValue, $actualLength, $actualValue ); + +sqlsrv_close($conn); + +$status = true; + +/** +* Compares actual output to expected one +* @param $expectedLength The length of the expected value +* @param $expectedValue The expected value +* @param $actualLength The length of the actual value +* @param $actualValue The actual value +*/ +function compareResults ( $expectedLength, $expectedValue, $actualLength, $actualValue ) +{ + $match = false; + if ( $expectedLength == $actualLength) + { + if ( strncmp ( $actualValue, $expectedValue, $expectedLength ) == 0 ) + { + $match = true; + } + } + if ( !$match ) + { + echo "The actual result is different from the expected one \n"; + } + else + { + echo "The actual result is the same as the expected one \n"; + } +} +?> +--EXPECT-- +NVARCHAR(32) +---------Encoding char----------- +The actual result is the same as the expected one +---------Encoding binary--------- +The actual result is the same as the expected one + + +NVARCHAR(50) +---------Encoding char----------- +The actual result is the same as the expected one +---------Encoding binary--------- +The actual result is the same as the expected one + + +NVARCHAR(1) +---------Encoding char----------- +Statement should fail +The actual result is the same as the expected one +---------Encoding binary--------- +Statement should fail +The actual result is the same as the expected one + + +NCHAR(32) +---------Encoding char----------- +The actual result is the same as the expected one +---------Encoding binary--------- +The actual result is the same as the expected one + + +NCHAR(0) +---------Encoding char----------- +Statement should fail +The actual result is the same as the expected one +---------Encoding binary--------- +Statement should fail +The actual result is the same as the expected one + + +NCHAR(50) +---------Encoding char----------- +The actual result is the same as the expected one +---------Encoding binary--------- +The actual result is the same as the expected one + + +NCHAR(1) +---------Encoding char----------- +The actual result is the same as the expected one +---------Encoding binary--------- +The actual result is the same as the expected one diff --git a/test/sqlsrv/sqlsrv_client_info.phpt b/test/sqlsrv/sqlsrv_client_info.phpt new file mode 100644 index 000000000..9fad7661e --- /dev/null +++ b/test/sqlsrv/sqlsrv_client_info.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test sqlsrv_client_info +--SKIPIF-- +--FILE-- + +--EXPECTREGEX-- +array\(4\) { + \[\"(DriverDllName|DriverName)\"\]=> + (string\(15\) \"msodbcsql1[1-9].dll\"|string\(24\) \"libmsodbcsql-[1-9]{2}.[0-9].so.[0-9].[0-9]\") + \[\"DriverODBCVer\"\]=> + string\(5\) \"[0-9]{1,2}\.[0-9]{1,2}\" + \[\"DriverVer\"\]=> + string\(10\) \"[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{4}\" + \[\"ExtensionVer\"\]=> + string\([0-9]+\) \"[0-9]\.[0-9]\.[0-9](\-((rc)|(preview))(\.[0-9]+)?)?(\+[0-9]+)?" +} \ No newline at end of file diff --git a/test/sqlsrv/sqlsrv_close_twice.phpt b/test/sqlsrv/sqlsrv_close_twice.phpt new file mode 100644 index 000000000..d28c92e68 --- /dev/null +++ b/test/sqlsrv/sqlsrv_close_twice.phpt @@ -0,0 +1,61 @@ +--TEST-- +Free statement twice +--FILE-- +"$username", "PWD"=>"$password"); + $conn = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn ) { FatalError("Could not connect.\n"); } + + $tableName = GetTempTableName(); + + $stmt = sqlsrv_query($conn, "CREATE TABLE $tableName ([c1_int] int, [c2_tinyint] tinyint)"); + sqlsrv_free_stmt($stmt); + + $stmt = sqlsrv_query($conn, "SELECT * FROM $tableName"); + sqlsrv_free_stmt($stmt); + sqlsrv_free_stmt($stmt); + sqlsrv_close($conn); + +} + +//-------------------------------------------------------------------- +// Repro +// +//-------------------------------------------------------------------- +function Repro() +{ + StartTest("sqlsrv_close_twice"); + try + { + CloseTwice(); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("sqlsrv_close_twice"); +} + +Repro(); + +?> +--EXPECTREGEX-- + +...Starting 'sqlsrv_close_twice' test... + +Warning: sqlsrv_free_stmt\(\): supplied resource is not a valid ss_sqlsrv_stmt resource in .+sqlsrv_close_twice.php on line [0-9]+ + +Done +...Test 'sqlsrv_close_twice' completed successfully. diff --git a/test/sqlsrv/sqlsrv_complex_query.phpt b/test/sqlsrv/sqlsrv_complex_query.phpt new file mode 100644 index 000000000..e4e073975 --- /dev/null +++ b/test/sqlsrv/sqlsrv_complex_query.phpt @@ -0,0 +1,103 @@ +--TEST-- +Test a complex query with IDENTITY_INSERT +--FILE-- +$username, "PWD"=>$password, "CharacterSet"=>"UTF-8"); + $conn = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn ) { FatalError("Could not connect.\n"); } + + $tableName = GetTempTableName(); + + $stmt = sqlsrv_query($conn, "CREATE TABLE $tableName ([c1_int] int IDENTITY, [c2_tinyint] tinyint, [c3_smallint] smallint, [c4_bigint] bigint, [c5_varchar] varchar(512))"); + sqlsrv_free_stmt($stmt); + + $noExpectedRows = 0; + $noActualRows = 0; + $stmt = sqlsrv_query($conn, "SET IDENTITY_INSERT $tableName ON;"); + sqlsrv_free_stmt($stmt); + $noExpectedRows++; + + $stmt = sqlsrv_query($conn, "INSERT INTO $tableName (c1_int, c2_tinyint, c3_smallint, c4_bigint, c5_varchar) VALUES (1324944463, 105, 18521, 2022363960, 'üv£ª©*@*rãCaC|/ä*,,@ý©bvªäîCUBão_+ßZhUªî¢~ÖÜ/ª@ä+ßßar~Özr,aß/,bCaü<ÖÐhÐbß<î/ðzãý+bÜ:Zßöüª@BÖUßUßaåab|¢ª¢|ü£/ÃßzzuªãA.ªZUöß<©a>OzübBüÜ|bZ./öbvß*rbö>ß©r//~ÖCÜhð¢bßz:¢Ä+_Ã__£ý£Uýh:v¢bý,©Ü£©,A:Zh>ßåvö+Ä>Ã.ßvC|:Ü*Üü*åz|b.©©üAý@uU.oOÜýAÜÐÜð©OB|rrîbU<övoUßäZÃÖ<ÄåªAÄ.Ua*ÖOªB,åîzB:ÜhövÖZhýðüC')"); + sqlsrv_free_stmt($stmt); + + $stmt = sqlsrv_query($conn, "SET IDENTITY_INSERT $tableName OFF;"); + sqlsrv_free_stmt($stmt); + $stmt = sqlsrv_query($conn, "INSERT INTO $tableName (c1_int, c2_tinyint, c3_smallint, c4_bigint, c5_varchar) VALUES (-1554807493, 253, -12809, -1698802997, 'ßöîÄ@v+oß+î|ruý*Ü¢ãÖ~.*ArABªßOBzUU£ßUuÜ<ðýr|b~_äaü/OÖzv.¢ä>>OÜ+¢vªzöªoB_ä+ߪrÜö£>U~ãÖð~ðýur,ÖvZh¢ªZ>vªUäåîz,>ÃräðäýðO_ä*a,ö+üÐß~bÃü¢<<+îýÐöäªO/zA+:îZ,öBÐü<î£îåhBÖzßÄ~,:>bð<~aÐãö¢*¢våvÃÐåî@a_Äu£öa~våu>¢Bã©å:Aßã£Üvåö+aä£U<¢b@|zbãÖ@ÃãUb|ÄB£©,~ßð©ðUßöZÜöî£Zz<>åäZßð©ßaÖÖ¢bð£ßÄ>îÃÃ.~z>h_ý~ÜrüÖBruß+ª©CB©O>rå,Chro,£ßbZ_ß©,ÃUu|ßåüÄ/ý*åu|~Ö.ßZUoä:~A~CZhðU|öZ:ä/£Ä*î©ÄhävhbrzîÐ@.rãß©@uÜ©~>ÖÜööCÄzÜCü+>oZÄÜ/ABßA_b|b¢bÜh<|uBr.B*rü>aCª|AÄ©@öÖßÖ~ÖüoîzÄ¢zz~Ãýö|vUå>|CÄUü~>buÃv<ä~Ö+.ü*ªbuî_bBC©.oîCbåîÐÖUa~/U>öAäÐBu~ozîZ/zrOOä:ß©bßo.ü©A¢höÖoßÖü>r+A/ßaªrß:ª@|bhhªª/oå<Ö:rüa+oC¢~uÄü>/.ãbOöª_b@bbߢ|uzߪ֢~uäýub©ãaZäC£ÄrÖ,üöäu+Ãîö|||,U.BråãoýbüåöÃburöoî+>öä©î,u_öb©@C:ÜåÜîÜåAÖzýbð|Z<Ãý.£rîZ|/z@¢£AýZ,ßuZ*:b.AzТä¢üßöbvbväð|<**~Uv.Ð*Ä©B*ýCUöa¢åO©Ãß*ÃÃ|ÜðA@îÃßaBöüahUUA+ߣ_u|~äö.©hr£oBo<äãüO+_åO:Z~Üoîßzb£ª£A.AÖÜÄ._O_å£ß');SET IDENTITY_INSERT $tableName OFF;"); + sqlsrv_free_stmt($stmt); + + echo "Number of rows inserted: $noExpectedRows\n"; + + $stmt = sqlsrv_query($conn, "SELECT * FROM $tableName"); + while ($result = sqlsrv_fetch($stmt)) + { + $noActualRows++; + } + sqlsrv_free_stmt($stmt); + + echo "Number of rows fetched: $noActualRows\n"; + + if ($noActualRows != $noExpectedRows) + { + echo("Number of rows does not match expected value\n"); + } + sqlsrv_close($conn); + +} + +//-------------------------------------------------------------------- +// Repro +// +//-------------------------------------------------------------------- +function Repro() +{ + StartTest("sqlsrv_statement_complex_query"); + try + { + ComplexQuery(); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("sqlsrv_statement_complex_query"); +} + +Repro(); + +?> +--EXPECTF-- + +...Starting 'sqlsrv_statement_complex_query' test... +[Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Cannot insert explicit value for identity column in table '%s' when IDENTITY_INSERT is set to OFF. +544 +23000 +Number of rows inserted: 2 +Number of rows fetched: 2 + +Done +...Test 'sqlsrv_statement_complex_query' completed successfully. diff --git a/test/sqlsrv/sqlsrv_data_types_explict_fetch.phpt b/test/sqlsrv/sqlsrv_data_types_explict_fetch.phpt new file mode 100644 index 000000000..bc52d2db2 --- /dev/null +++ b/test/sqlsrv/sqlsrv_data_types_explict_fetch.phpt @@ -0,0 +1,100 @@ +--TEST-- +Test insert various data types and fetch as strings +--FILE-- +$username, "PWD"=>$password, "CharacterSet"=>"UTF-8"); + $conn = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn ) { FatalError("Could not connect.\n"); } + + $tableName = GetTempTableName(); + + $stmt = sqlsrv_query($conn, "CREATE TABLE [$tableName] ([c1_int] int, [c2_tinyint] tinyint, [c3_smallint] smallint, [c4_bigint] bigint, [c5_bit] bit, [c6_float] float, [c7_real] real, [c8_decimal] decimal(28,4), [c9_numeric] numeric(32,4), [c10_money] money, [c11_smallmoney] smallmoney, [c12_char] char(512), [c13_varchar] varchar(512), [c14_varchar_max] varchar(max), [c15_uniqueidentifier] uniqueidentifier, [c16_datetime] datetime, [c17_smalldatetime] smalldatetime, [c18_timestamp] timestamp)"); + sqlsrv_free_stmt($stmt); + + $numRows = 0; + $data = GetInputData(++$numRows); + $stmt = sqlsrv_query($conn, "INSERT INTO [$tableName] (c1_int, c2_tinyint, c3_smallint, c4_bigint, c5_bit, c6_float, c7_real, c8_decimal, c9_numeric, c10_money, c11_smallmoney, c12_char, c13_varchar, c14_varchar_max, c15_uniqueidentifier, c16_datetime, c17_smalldatetime) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $data); + sqlsrv_free_stmt($stmt); + + $data = GetInputData(++$numRows); + $stmt = sqlsrv_query($conn, "INSERT INTO [$tableName] (c1_int, c2_tinyint, c3_smallint, c4_bigint, c5_bit, c6_float, c7_real, c8_decimal, c9_numeric, c10_money, c11_smallmoney, c12_char, c13_varchar, c14_varchar_max, c15_uniqueidentifier, c16_datetime, c17_smalldatetime) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $data); + sqlsrv_free_stmt($stmt); + + $data = GetInputData(++$numRows); + $stmt = sqlsrv_query($conn, "INSERT INTO [$tableName] (c1_int, c2_tinyint, c3_smallint, c4_bigint, c5_bit, c6_float, c7_real, c8_decimal, c9_numeric, c10_money, c11_smallmoney, c12_char, c13_varchar, c14_varchar_max, c15_uniqueidentifier, c16_datetime, c17_smalldatetime) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $data); + sqlsrv_free_stmt($stmt); + + $data = GetInputData(++$numRows); + $stmt = sqlsrv_query($conn, "INSERT INTO [$tableName] (c1_int, c2_tinyint, c3_smallint, c4_bigint, c5_bit, c6_float, c7_real, c8_decimal, c9_numeric, c10_money, c11_smallmoney, c12_char, c13_varchar, c14_varchar_max, c15_uniqueidentifier, c16_datetime, c17_smalldatetime) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $data); + sqlsrv_free_stmt($stmt); + + $stmt = sqlsrv_query($conn, "SELECT * FROM $tableName ORDER BY c18_timestamp"); + + $metadata = sqlsrv_field_metadata($stmt); + $numFields = count($metadata); + $noActualRows = Verify($stmt, $metadata, $numFields, "utf-8"); + + if ($noActualRows !== $numRows) + { + echo "Number of Actual Rows $noActualRows is unexpected!\n"; + } + + sqlsrv_close($conn); +} + +function GetInputData($index) +{ + switch ($index) + { + case 1: + return array(array(-1512760629, null, null, null), array(167, null, null, null), array(-28589, null, null, null), array(-1991578776, null, null, null), array(0, null, null, null), array(1, null, null, null), array(0, null, null, null), array(0.0979, null, null, null), array(0.3095, null, null, null), array(0.8224, null, null, null), array(0.6794, null, null, null), array('~Ö~.üoö©UßB.|ÃÄ£*/v|U/*bZ£ÄUÜß*+ööî*©ðü©bðr@éåbOý|©©hob/>Cz<Äå::Ð<¢ß+ü/:ª@zrß.¢Ü£bÜU©ÃßÜßðoß©r*bÜböOUvãahub£ãäªb>_ã£BOÜA©ãü/ߢß.ov:Ö<:_+uÜC:£oöü*BzC,Äö~Zî@/Z/r@/©<~.ã¢Aaü>ý_zz@rÖ¢aU@,ABð/¢ß>z/ã@/ªUA~CoÄ,>bö|Ö>A,v+©CbC/Oo>©ßa©boAîÐvOo>ã|Cåöo+ÃhÖBAbo,+<ßã/£@å+ßAÜ@äÖÜOBäß~öu*ã+a<îoo|¢üýoBaÃÜ£ãCaC@ha,äzäî¢ü@å£b~råîUbßr©ãßÐ:@UhAO>u*uýBbäZ£aý>v:ðC~ÜöåðzZ>O|Cä+£>öz./Ö+uÜ', null, null, null), array(',ßhr©+|v@,Ã+BZ|îAÐß_öýða_AoäAOÜ*ýC@hoBßßaä+ýöCäAä_Ä¢/Uî.äC©¢rÃuz¢*,ýß.Ðöðý@b£öb.OCý@>hðÖrCZb/Oªz¢A+ªÖäu<ßÜÄ/ÐßÖîbU:bÄÐã>/£ÜÃBÃ@Ð.r:ªª>©zî_ÄÄ:@A.+.aoÖ@¢åOåOBB|+Cvüa_+hz|~COoACAî¢+*Ä©*ýî~|.Äz|u+o~:<@>Arb:~£z<äbãv>Ðr©:ðýCößÖ¢UAîãý:Ã~.C*C¢uÖ*~CÄ*äAb>h@h_>,|u<<.,vå,.BAuo£_ãB.Örö.Ä>zoba~C©hArªB£Zü~oÃbb>î+ääÄCbÐýª*Üýburäßv/åOüA:Oß:obvz©ý/ßroäaª/bªvz©rÐ,ZäߢªÄ.ã.@z¢|ð*aCý©:ýÄövã,öAbö+ÖCb~uÖ£züî|_ö~*CÃ>+ý/_ß+ãÐz/|ÖÐAv©ob.©£vöÃÃã:ðvC/@£Zð©O,åã@.u,BAÐbO£Z,Oü|Z/UBAß©ªA@býUuz.UýÖUöv|ª£B,Тßb*ÃУUðZäbãßOäAA>ãåUb,/Ä¢aä©:ð.öýr<Ðz@~b<öhÄ.CBÄ|ª¢|ä+ÜÃîüC¢,vãö£îãü.ZÄüUßßBuÐz>ðoBãZäB¢:ßã+.üÃOBOb@ZCZvî©ZA~©:O©£ÄuOý£Üßr_¢<+|ZhªýA©ßOßäãö£~bAÜ*©ÄÜv:aB|ZÄbªÃß|BýåýÃ.@ä:ð+*baOÖOÜvߣßAÃ~å>,bCOoa._~obböhãz*b©b|Büîã/aîzür.ßîhß*Ðr*£<ª~CÃz©ß>êîãövCr+Öa@u¢ü£ZAabü¢å*.b>,ÜhB*Bßvª>üüäÃh,:zhUý¢<.v£Ö@bÐ|/äÜÐ/r£Ã..*,ozbo,ãU/Avã@ÜzÖãÄ+zräö|CböÄoߣÖã©uzbr>+ÃãZ_/ruÖ©Öß.ðß/|ýÜbä/Ð,ßr:Ü~Ðßüh,ßî+ZoÜ/©oaÄ:>O|CÜov>z_£vÜhý:©aåߣaBðbUßa©OUЩ,Ðvr<ö¢Ã©bZUB_aßüaoCîß_ª£UzåO|O¢äb,©a@Au*/að,ÜUÜ£ã,_ßåbv*A£+:>|:©+ßvbäb>/ÃÖv<¢råý_U*o£ßüýC*ýäÃÜãå|UaöýÄÜÖîCCCßßÄßÜ,îurZa|ãvö@B¢Öîî.ð+Oðaã<~v_Äär*£oBz墩vUößåß*:CÖ_Ðba©oî_ßB©/C:oäßövåaåäß,rO/oßä.©~Ð@.vBrBU_*Ü_,@£Aa.oUЩäU£:ü>,ýUUÖ|Ä©:_ãbÜÖ+_Aãã©Ühß:U/ãb£o£©u¢å_B_Üßßý~>|B<ýz*rߪzÐuOßa*Ä¢aZîOãoäß/@baäÜ~zîhüäÜZöãbð', null, null, null), array('54e16f51-64f1-4d62-a028-582b553c2de5', null, null, null), array('2130-04-16 14:12:00.131', null, null, null), array('2032-05-10 23:32:00', null, null, null)); + case 2: + return array(array(-1111886816, SQLSRV_PARAM_IN, null, null), array(27, SQLSRV_PARAM_IN, null, null), array(-20174, SQLSRV_PARAM_IN, null, null), array(-840346326, SQLSRV_PARAM_IN, null, null), array(0, SQLSRV_PARAM_IN, null, null), array(0, SQLSRV_PARAM_IN, null, null), array(0, SQLSRV_PARAM_IN, null, null), array(0.4880, SQLSRV_PARAM_IN, null, null), array(0.9184, SQLSRV_PARAM_IN, null, null), array(0.6916, SQLSRV_PARAM_IN, null, null), array(0.7257, SQLSRV_PARAM_IN, null, null), array('<ö©ååä,ääÐ*bhîvr~aöb/BzZÜ@öðß@_Ä££r__£>£Ð£ðbUB~/ãbo.>îzöã*,ßå/+zuu.+BZßzA,aÖzüåão£©BãÄbä~ýooÜ,+äßÐ:UÃrz|vä,Bå~¢ä<_£uÜv<_O|ßBC¢_£Ahöª_¢oözCßýzöüý+zÄUÖhB@Uîbh/u/©zÐbÖ¢A*ã,Ãî£<>rUªßÐßîZîåb:+¢|A_BÃo©ªäu,*ýååbU:bÖÄß|¢>¢ÖaãrÃO©Äv+oßöZãª,+/.ãa/㣪,¢ðÐ<î¢b.£Ü©_r©vª@î:>ÖðB:OrBÜЪý|bßbÜ|åUOåîOãÄãuÐ|/îörB£ÃßZZÄ@Z©bÜB:.¢@b££U¢äÐvÐ+ý+uzÃb+üo+öv~_©~Uhbª,ßCb+UZö>Üü', SQLSRV_PARAM_IN, null, null), array('|öÐob*+ÐÖ,..Ä¢ß@>îß*äî|å>~Oo+/o+*/ü|îî,ðö*ýåãob:zb|Äßîvb¢,Ã,UªbbrAbZ©uªª@ä,_ð©A*>Ðävä:|:oîö_rý©+vî©ßBßßb>üOö@Öoö*+î@ÐßrÖ<¢hÜZb._raUaýUUÄößßîU¢ð.ÐýrãBh¢>Äðz<©AÜ/|©Ö@>hüBCO~öýZ>äÄÐAzä~/b.ÜzbðÜbða++ªå/ð~ACÐî~©>./<Ööý<~ýuÃBÐãåo*h©ö£öîüZß:ZÐä_>Ðvî©_äbb©ö¢*b@BÐÜb+bî+åßAåîu|/A.Ä.~hvb:@zå|Ä,ªÃZß@v©ßvB@Bð:£öß@uðr££ðü<Ä¢äÖaßO.:rª/Ao,ª:ZbA+¢ß|>,*ßoöA+ãb|Aü@bÄð@a:+,ouªýª+£ðr*Bã¢+rCðUU_ÖÃ>îö>r©v:U_v@vCÜ>', SQLSRV_PARAM_IN, null, null), array('ývC|ãv:|öbÃAÖ~oÐA,~ßß,b:+ba¢+AbOýzvÄvý/a_är<ßüÃ,~,<¢Z/_î|/bv£¢C*.bÄABz@výb¢.Ä*ä,.AßC|/î~Ü,hãðo+îÐäbÄv£vUäO£rßhOu|Äå¢ßaÜýohvÄOÃ+ãÐÄ©ävoCÖÖ|v+ßÄÖ¢rîvuvÐBÐbb_C+~bOãßzö.~CåUÐ.O<.©>v.h|ýªöÜO¢ý,o>B_ýu£hîüå£oääý©îbÐÄBßßÄU>@||Öß~ÐÄÜ£åruÖ_ªz@>.CÖöBZ_vÃb©zãÐÖC~*rBb/hB+ßÄäüO>@vrä+ܪ:£öUB//üý©~zª©Z>~ob£ä,+ýîÖãÖ,@ýAÖu,*UU.ãÜå,BaCäªa|bðv.ªBvö+*ªÃª<©||+ZöU*ÖräüýUüÜåUÐßr,öÃ@ÜîÃßaobZzªîh@ðãÃ*Üvo+U>CÜöAO>,b.vvuÄB/Ðäã©hBA£ohýßä¢Ã@h_/|AbCåßð_@åuÃh~ðb.*ÄB,BCÜîrÃ@<ÄÜCÄZ|.©Öüãr|_Üð:ãuö|vo:/A<îZu©h/bßCBýäA@.©,äåß|+ã:+:|î:ªÃvUB>,_ZÄß>Уß<ýr/o¢Ü~|rî_:ÜZÃäo+@/ĪöAACbhbzãÄaü,uhÐßßBÐbOöðÖaAö*,h.Ö,v.h>Ä:<åbß/ßî:Ð/_Ã*ý|ÖbB+bChý<~¢uaüÖªzC©UOCC>öB~uîã:bÖã@zbh¢z*î¢Uß~î>üãr~©Ö,£ü¢/ý|îb¢C|åª><@Ö.u:bÄߣßbo,ÐU>£ßZÜßAîB©A:rUýßÐ~uÜÖ<~Öî£b©.îAß,ZuÄýªb<|ðOÜð.Ö|:BbA<ÄvîCäÐîª:aÐö,CðAZßh@ÜrãZßß@î@rzãý*©Az~CäoäCî<ã|Zã@ovö_Ã>/ªzbuabuÃîöb<åÄÄÃv*îBöãýUrbýbbå<£OªÐvb¢oßîr|å@ãöß:ªÃOß.>Ü*ßaöbo£a>.vvý/¢£OCrÐvBÖ,COªoA>,Aü.:oÐãã:+~>oUOª*:ÄOü+ßO,ÄO|b>Ü_ªýAUТÜ_/ß,_üéö+îãªÜObªªvÜa>bÜö~bîouðäÐÃoÜOüZuÄbUOh©OÖ/ö:©<ãÖb+A:öîÜ>Ð/bBðª.å¢ZbbüUå¢Z.Z>uÜv,îöC/o_+zð~@ÜB~vhabß,/ÜÜß<.o_¢Zvöo©rü>ýÐbðÐo.ÖC_ÄCh>oüåöho*öÖ,ßãZ|ª/,Z©a*Ð:ê,A*ä:.<ßBývÐbßhAüÄBA@BO_B*ã>>ßU:v_ÜZªîð.uãO~zÄz<@ü,A*£BvãßÜC~ýzvÖã:_Aä/bÜÃß©î¢r.a+ü@:uB¢/>:ßhßãU_îãýÖ~AABß©Ã@ÄÖßz~åz@ü.Ö<*~ãäßOÜÄv~Īb_ör*bvÃÖýZZ<ö¢.|Ð>ÜåaCAîâãßu/aå|@U*¢Bb*+bZr_.ã|,h_BöÄb.ðZ©//î_~v/ð/,bð¢/:@öãß+vÜv/båðöã:ã/z:£î<_ÐöC>.Ozrð©@rC~Bö,£o<:Ã*z_ªöÜ,z,ªboB,+öCr*¢î*<£~ýb:U|©Bh/ãÜÖý:obhå£+Z+r:o|v+bÐhãåaüÐöbãðöAÃ|ªOCÖO|Ü<ãvv¢ãýbý.ÐbÄÃðåü>/BbbÄ/véäý:@o>öÃaªÐ+îüýã_röýä©zhvÜ<Ã/CäaðoCB|å~~ÖaðvuC_hBrOrzÃßO©ZU.AvvåÖÐ/ÐãåZ©£,UãÖAîhUzªrö£Ãu+ð/v¢o_<ÐA@', null, null, SQLSRV_SQLTYPE_CHAR(512)), array('ÄßZrð@~ö:ü:£,CoÄ©böBAO,ð:aA>ãÜBÐ@./:A.Z/bÖÜ,>ßî>ýßß©b/<@/,Öî>BBÃäÐCüÃÐÃvÜ_AZ.ý/©C_>aö/£Böða©£,öý£B_ÜÃðßvh|î|.oB/öBÜö¢BÐ/bAAÜÄa£.ªA©z<£ýOÐrå._bÄÜß~Ä_ªý,|+BãîA~Cî@ü+@ÜüzCªr.rzåazUöCzBߪ©Bö+ü*ZãÖ@AC*UA¢..aÜü*ArÃz£B:ßßÄ+Ã/ãª+ßZ_Ü<ßäîýýî@ðÄÜßÃÖðova£ªOöÄzÖ©ãrabªÐUrår+Ü*©OöåBö|a©î:bß©ð~_C_o*hÃ@åBb|<åÄß@©ý.Ubª,O£Oz|üßbz£+bã¢a@>:aaîý_Ür£|hÃ@z<_hüÃü,öîZýuã_¢üå£<ðßAª>rC.Bî.©,ß*å|é*_B>CÄîÖÃU~ÃÃ>rª>/ð©Ö|~ZA>¢¢/@£bZuZößzðå~:/h@uÐoOrã<¢aîßüß<¢BZzO¢@.:rvÜo>ABzC/ÜßÖ::r©O/v*@üaäzßZhU@aßvüî:©ü~ðª©_b£ä£ãB@:bhCÄZÜzOUßoåîÜý><', null, null, SQLSRV_SQLTYPE_VARCHAR(512)), array('Üarä+Öã/ür:h:AÐbðÃov¢©+ß*C/ߣZ£,ozz@UuÜ,ääßBÐB+hhãäz*rîC©/@u*bßÃ|býhÄrãÃîÜ/ÜäUbuÜv£ß:*bü.räßÐ_bßbC_©Cr:ðao/|ßhU.+v+aö+ЪÄÖÄ,C|ãÄßvð>ovü:<:bý/båz£B>ö~ýrbãO/@ÄüoðrÃrüz_ã:@ð|@ZÐO©ä,Öabîhßbä©ýã<Ð>vhßÐäîaBUA/©:ÄÖBaÜ£zuhäz|.ð:åä¢bObuhö<ßö,£Öa<>**C|ýbß.UhZãÄü*,>ÖÄO@.*>ÃOåbvÃ/ýb/äCîuÜß>¢C+|<*Üã|*.Ü*båöîv/O/*äÖÖÖ©+CA£Zr~ªz,ðA@ãuCzªO*ÄCzuoÄ*UüäöaUCÖO~£ö,uC,Aß>++Äbh/ý.o>Cv>ªäz¢:/ðß.BA_éßC~ÖZ:©*ý|ðÐ@AãövbZo+_î>ð¢äÄüvÃ@<ÜrZ~ÖããßvåÖÄÐîîö:ßöU@zvrBã©~ü+Äå/UÖã|,_U<*b£hßOÄüÖ_:Ðvö<ðb>îoUäîOåZ>ob.bZÄÜOu¢bZ£üªrãUohZZî<å¢brÄ|î+ÜuzaOvr©©bðÐhOäoðOâ~Äbhßßö.Äã+bh£@bª:Ä*å|ßC_|+@ÃÐ/Z<.ðbOou,zßößÄã~>Ãß~<>*ÖaîöªU::Ðü/bªÖÄ:å/uzAbªý.Äüäãåoößh£ðoU|ýöåbý.¢uãÜuðoUOz©.ð_îvª¢äßãßãOÐ>Bb+*åbuåvu@¢üã,äzÃ>/ªCbåvZ*rCÃOÖÄÃbßýã/+/:ðbßäuî<,*aãCªB,£*ª©:©b@ÖîZß~åäÐÄB:å+~ð_uÄðÄ*ãzrão|ü::A,+¢bbÖªZ:UäCru£ÐZÐöåvvbb@å~:/ðã©rä£ßªÖBß,oýß@UvÜã,Aoz¢Oð/_|Oohå_/rî*ªãh_¢h>Cvv|v¢ßªbîÃ*\/@Ã~bßar|ýü¢åbîÐUðO£Üãî~+ã,oÜîö>+UbÄ+ÖðÜ£Äý@>üÐßabîCð¢Cª¢CuU.ã:©b>U¢ýO+>ý.abã.B,B|oÃýã|Öh@CCüzArß_ðBÃýÐ*ýªÐbhbÐäuÃ__C_©UbO¢zÄ~/ß>.vuZðhoC*Öb>å,.ßUîZß@bväÃa>+.£.oð|Ðß>|Z_+.ÜÜ~Ürßu_:ÃCýýza+ªð©ßÐÄ+î|z£¢ZâÜ/Bz>vðßÃhäOÐAö|/ßCü+å~Ãb/ÃuîO¢uÖb+~åa@BÃhü£ä@¢äªÖußOÐUåä/UbªÄî@_£/©Ã,©.vAvuîöß|ßߢhüßbAß>Ä<Ü:>ýuüÜÄ£ßOýA~a<Ö@î_.b.¢hð.Z>£Bߪ+¢ªZU/@@äB.orÐîå¢ð>*<äAv~,ß@ýü~+~*Ðå¢ý_å_bÄb~_<<ßÄ:o¢zrC<ªa~BäÐýA©ßB.Uhîß+rAÖå¢ýö.îîaýåUC¢/Aüöß©zÄaðÐ,b|||+vCO+~üA£ÄöãýbÜ_üßãCðã|_ÄbäÃU~***<¢¢höUãbözbÄ>Ðühr.vÐ:£_Ä~@/o,a_abý_>ßr*å|bob¢îãBî~<üBÜouÄBar_üß.ÐÐ,©ýuÖUöäÐÐîZýªÃ*vß|~îZßZÜÐrh*~UÜ*î@OBÃßraUb:*/B/@OÄaãoßBãÃhöBb@Uªý*|£U+ü*¢ß¢häUðOb/*.rßOrÖåüO<ý*aöCa@ªoä>ÐC.UO+ZUrÜA©Oã,ro+î+,Üå¢<¢rÐu.ªî|ãÃB,ða,ªÐüÄü©ßBÖß+uv>BöußÜ|h|aßohB*ovãu+@Ü£ßO©ßßBý:b+£bÐÖäªo:UAÐo_ã~>ö<ühåÖÐî>å*v¢ßa_>/ZÖ:åbbäz¢Ä*Ü¢ÜåubvÖUî@Ã:¢<Üß_.*Öh,o/uz.B_/Äã|Ü/öOÐ.ÐßU@ßbav~zAßu+ª£U¢<ýÖä©Ä>ßãåäbã¢ßýªöåä,*ubßß@¢><üCozÐЩäC_aauC/_<.ýuÜ£Ö,uCÜÃbåräZ,ðÐî@îbzÖã+ã,CB£ZzB¢vÄ*+Üb¢üýßU*oÄärãü@öîaß.|äý©bÖ|BuA©ª,C/ZB*ð~aÃÃvîü©+ªÃ+Ã_öuu¢ZöbÄuð©O¢Z@_uä|bu,äOÐÜbBr@|Ãüb/îr©ß.ååßÜabZ©hß+ãߪz|+Aå@äü>Ä+ýu|å¢z|bhr*ªbO©>/ö,hÐå+Öå_OßZ|ð,b.AäÐß_@ßß©.üüZäuA/aC|£CäßýbhÖÖªZö@ÃhßÖ£/å*örüßðU*~vhðv_Üðýðß<+bAbBa:ªÄ/vܪUuÄîîabãßO>:,Ãýðußßäö@vîhäÜ>£¢hý+zAZbaBðУ|å|ªÐ*:Ã>ª:ð£ÐüßÖbuªOOA>Bb©ÃärÐîhzö,+|C:Aö', SQLSRV_PARAM_IN, null, SQLSRV_SQLTYPE_VARCHAR(512)), array('|:ÃZ*UvAÃC:+ãb@ÃÃÖãZä|Üzß~:rðß~ub>ö£+++ªðÃuaå~|zA:ÜvCãÃa©,@ÖßbCå|rz+Cåzz,U+OzÜ:rAhO@ÃîözÐÃî©åvBb|Oî*<Ü<@¢ýzÜðßöAz|.UÖZUbb_åBüîÖ©O~Z©@o.vv£|ÜäÖ:~CbîzÜoA_OaÄuOÜÃobð_¢/îßã@zC*ä£öuuߣîª/îa_Ü>@:OB>ü.ÄörßorUbßý,hÜ|£A@b©/z.*u¢+<öaA.£/©_¢/üãBö:üOÄ+OãbîÃÐ@ßð©>U/+r¢b<ªÖÄCAaª|U|>å:o@vo£äB*©C£ÐåhO_>î*.@~ü£bßbzh>üzbr*ÐhO|ÖöCð¢b,oå.AÜ£o>ö~_£BãßßOOo*©©ß:,Z*ª:,£+|ãoîCÄzo~vÖO@bÐðoðÖ:ÖÐ>bü£äOB.bUåu¢©Z:îîßüoBöZZ>_z©A/B*£vîöý*/öåC|ßro*~¢|Ärbä@/~,>b:bü££/ßzCC:_Ö@Aü.åAðêÐb|Äîhãa,>£>*hrÃðbZ/,@CO<_ß_AÃ+|.ä+îbö_ÃÜZªý_¢övÜhZr,ðÜzÖ,öh¢höÄÄo+OCAãßO©Chr©bÐ_ßÄ>~av~u:hßrBrörv£OvC©£uãÜî*oahärzãý©b©î./aüv:o~|öðAî:/hbU', SQLSRV_PARAM_IN, null, SQLSRV_SQLTYPE_VARCHAR('max')), array('34eeff6c-7d28-4323-9e28-d6b499fde336', SQLSRV_PARAM_IN, null, SQLSRV_SQLTYPE_UNIQUEIDENTIFIER), array('4191-02-05 02:41:51.953', SQLSRV_PARAM_IN, null, SQLSRV_SQLTYPE_DATETIME), array('1975-12-01 15:24:00', SQLSRV_PARAM_IN, null, SQLSRV_SQLTYPE_SMALLDATETIME)); + default: + return array(); + } +} + +function Repro() +{ + StartTest("sqlsrv_data_types_explict_fetch"); + try + { + ExplicitFetch(); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("sqlsrv_data_types_explict_fetch"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'sqlsrv_data_types_explict_fetch' test... +Comparing data in row 1 +Comparing data in row 2 +Comparing data in row 3 +Comparing data in row 4 + +Done +...Test 'sqlsrv_data_types_explict_fetch' completed successfully. diff --git a/test/sqlsrv/sqlsrv_data_types_fetch_binary_stream.phpt b/test/sqlsrv/sqlsrv_data_types_fetch_binary_stream.phpt new file mode 100644 index 000000000..6780bc37a --- /dev/null +++ b/test/sqlsrv/sqlsrv_data_types_fetch_binary_stream.phpt @@ -0,0 +1,111 @@ +--TEST-- +Test insert various data types and fetch as strings +--FILE-- + "tempdb", "UID"=>$username, "PWD"=>$password, "CharacterSet"=>"UTF-8"); + $conn = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn ) { FatalError("Could not connect.\n"); } + + $tableName = GetTempTableName(); + + $stmt = sqlsrv_query($conn, "CREATE TABLE $tableName ([c1_int] int, [c2_char] char(512), [c3_varchar] varchar(512), [c4_varchar_max] varchar(max), [c5_nchar] nchar(512), [c6_nvarchar] nvarchar(512), [c7_nvarchar_max] nvarchar(max), [c8_text] text, [c9_ntext] ntext, [c10_binary] binary(512), [c11_varbinary] varbinary(512), [c12_varbinary_max] varbinary(max), [c13_image] image, [c14_timestamp] timestamp)"); + sqlsrv_free_stmt($stmt); + + $numRows = 0; + $query = GetQuery($tableName, ++$numRows); + $stmt = sqlsrv_query($conn, $query); + sqlsrv_free_stmt($stmt); + + $query = GetQuery($tableName, ++$numRows); + $stmt = sqlsrv_query($conn, $query); + sqlsrv_free_stmt($stmt); + + $sql = "SELECT * FROM $tableName ORDER BY c14_timestamp"; + $stmt = sqlsrv_query($conn, $sql); + $metadata = sqlsrv_field_metadata($stmt); + $numFields = count($metadata); + + $stmt2 = sqlsrv_query($conn, $sql); + $i = 0; + while ($result = sqlsrv_fetch($stmt)) + { + echo "Comparing data in row " . ++$i . "\n"; + $dataArray = sqlsrv_fetch_array($stmt2, SQLSRV_FETCH_NUMERIC); + for ($j = 1; $j < $numFields - 1; $j++) // skip the first and timestamp columns + { + if ($j < 9) { // character fields + $value = sqlsrv_get_field($stmt, $j, SQLSRV_PHPTYPE_STRING('UTF-8')); + CompareValues($value, $dataArray[$j]); + } + else { // binary fields + $stream = sqlsrv_get_field($stmt, $j, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY)); + CompareBinaryData($stream, $dataArray[$j]); + } + } + } + $noActualRows = $i; + + sqlsrv_free_stmt($stmt); + sqlsrv_free_stmt($stmt2); + sqlsrv_close($conn); +} + +function CompareValues($actual, $expected) +{ + return (strncasecmp($actual, $expected, strlen($expected)) === 0); +} + +function GetQuery($tableName, $index) +{ + $query = ""; + switch ($index) + { + case 1: + $query = "INSERT INTO $tableName ([c1_int], [c2_char], [c3_varchar], [c4_varchar_max], [c5_nchar], [c6_nvarchar], [c7_nvarchar_max], [c8_text], [c9_ntext], [c10_binary], [c11_varbinary], [c12_varbinary_max], [c13_image]) VALUES ((1), ('üb_rÃß|AZ_Uß.zðýªu+bz©£+_ü_©+o<öoý@îÐbÄÖðîä.ª>ärBãý>brCZ:O©ÄvåÃCbZ¢/ßAU__ªh.ßuÖAB*|_Oýîüär:|,ý>AuÐ*Zä:.b~:ö:bÐ@r:¢¢özhöb.©|ªªÄh|CCobî:O©ö>üÐA<îhÄuBÖ+_ÄBÜUîråß>åZ.zö|/zý:öaãOubðÜ/î+ª.O~.bZ©|ýßhab/¢hö~vðCz/_åð|Oü/:îCvîrÖ|>h£'), (' '), ('ßBß/ßãã¢:>bÜA@hÖ<~|*uåß_/.,BhvÃãUÃbãÖÜO~ªZÃßß/ÄA*,OåîߣöZva.:ÖÜÜhäß@ý|î+~A.<<ðBÄÐv|aÄBaÐbý*bz*Ü>ö¢ãåCÃahb*ÜÐ*¢*ý++.vöÖbAãB:ýuãbUUð_äBr~bU.ð+zZ,:©*Ðöö@_O|ßAauaðUZ_©bÜßö*O:ªOª>ý+ãbîÐU,ýz_:ÐB¢//ýß,äðrý/zvoårÜßO+A©zÜo<å_bhUß+åh¢ªäbOOÄAßðCCåUv|Ðv+büC©ß*>*äbÖ¢ö,aU¢ðÖýo*£_ãb+ývߪ_|aßO@öAÄÄäãöAzoÐåa©¢üvOÐ*~ßÜý@bb>rbö|ßÐÃîbZz>Ã>@î¢BUhü~vßBäöCUÐOßÜ<ãUrobvüÐðüåu©bzä+.ßð@£ßh<üß~£zC@Ðr©vÄ.Bªä,@:/bhî+ãÜZý>u¢ÜðÜuö*@åU>ß©Üö>ÖCb:_*Ö:ÖU>.hb©Oüßbz~£å©_ä£OðU>C.+aoöbÄvAuîBßvB£îOª>ã~£.¢/Ü/îî~hA~<ö>OBð~ÖCbðÖî+ß<+OzoåüåChöu+o~©ÜbußohÄB©ðB<~<å@.¢/|,ßåÃ>b,AoÄr~_.oé|©*£B£uÜ@z£v/ßÖÐaZöO_zBÖ©ðüÐ@ðOzrääöBîvO£îýÖÖÜÐå:ä@Br>Cu~ªýoÃ@v~hzb~üߣCAÜ|£**aåOBv£/bCÄТ,>ðB>C£/¢/Äoî©u.b/ö>îU~Bü~U¢obr+ã*/hOðv/ýîÄ~OAOª/aýÄÜUÐhîãCðåav|u+*~uBuoh@>ý_aðö.£rhb@~~ªZu*ß+|ý£o+ßâ+zÜã|UÖÖ¢îðO_ußC>ÐßÜüöäå+ßü@*+£BvÜvå,Uözßä©z/¢ãzO_ãAð£/<î<ÜZU.UvßîÖüîÖuÜ<öBZ_.Äb@r_bah+.Zðª>h©£rhÜÐCÃbãh_C>o£býý@~Að*£*îB.ÃÄå~Uªö©å_ÄöhýäZhB£bÄÄa*Ã|ßÃ*îb*~o.ÜÖüåîrýr:v|:bbA@uUaÃýÄ_åÃÜvzü<,+ü~b|ouÖåÄ@|bCCÖ¢Z,ßb|>/bubOCðÃUüîO<>ý>+ý@hüoa*bb£öAv~oö£v£ßAã~/@ööÖz¢Bv©©z~,ýzýhvöärör|ZßöÖaO_ßÖ,üub~Ö:_©,ªUª|£ü£©ÖåÄr~Ð,<@©+vÃCUÜO.î>ÖÖ~¢äÐBu,,©aCBÖU,~îö*|ßߢªuöhOüÖýv>¢ü£u>*ý|ß|ÃÃU@ßahZuu£Cv+_©Ðü+ýðãhߪð/Ab,b|:Äðu:+Oã<ÜAä@ÃvÃã¢aOߢaACÃObÄUoäª|ß©¢/vªoo<îªZZî©ÐO:+äÐßÃîCÖOCCr¢OUöå¢b/*/a£oC/ã,Z/übÄ>Ðã'), (null), (N'Z@/bAUZ/A+AA©ÜBöãb©~ÐÐ:ªÄ|,Ã/ö@ãßCÐbß@Ä,£.z<ÃoBBbZÖÄ~ðaÐb£b*î@Ö|ü>bbU<ߪrO©C|að_C©Ö@rbbäª>h>.våObÄ@å¢î¢*ouröu:©oãÄ_<ß>Ð:./a£bzäªrãý:ð>äub.+üåC¢oßý©ÄÖ/,|ýb:U£ß,A©@£Ößbhvßäîäåð,h_b~ý:ðª.zZßäbb::BZЪu.~ÖîU:_ZZß>*>åªZ>ýäå<ÖågetMessage(); + } + echo "\nDone\n"; + EndTest("sqlsrv_data_types_fetch_binary_stream"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'sqlsrv_data_types_fetch_binary_stream' test... +Comparing data in row 1 +Comparing data in row 2 + +Done +...Test 'sqlsrv_data_types_fetch_binary_stream' completed successfully. diff --git a/test/sqlsrv/sqlsrv_execute_twice.phpt b/test/sqlsrv/sqlsrv_execute_twice.phpt new file mode 100644 index 000000000..34161c5e3 --- /dev/null +++ b/test/sqlsrv/sqlsrv_execute_twice.phpt @@ -0,0 +1,72 @@ +--TEST-- +Free statement twice +--FILE-- +$username, "PWD"=>$password); + $conn = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn ) { FatalError("Could not connect.\n"); } + + $tableName = GetTempTableName(); + + $stmt = sqlsrv_query($conn, "CREATE TABLE $tableName ([c1_int] int, [c2_tinyint] tinyint)"); + sqlsrv_free_stmt($stmt); + + $stmt = sqlsrv_query($conn, "SELECT * FROM $tableName"); + sqlsrv_execute($stmt); + + $errors = sqlsrv_errors(SQLSRV_ERR_ALL); + $e = $errors[0]; + $value1 = $e['message']; + print "$value1\n"; + $value2 = $e['code']; + print "$value2\n"; + $value3 = $e['SQLSTATE']; + print "$value3\n"; + + sqlsrv_free_stmt($stmt); + sqlsrv_close($conn); + +} + +//-------------------------------------------------------------------- +// Repro +// +//-------------------------------------------------------------------- +function Repro() +{ + StartTest("sqlsrv_statement_execute_twice"); + try + { + ExecuteTwice(); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("sqlsrv_statement_execute_twice"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'sqlsrv_statement_execute_twice' test... +A statement must be prepared with sqlsrv_prepare before calling sqlsrv_execute. +-23 +IMSSP + +Done +...Test 'sqlsrv_statement_execute_twice' completed successfully. diff --git a/test/sqlsrv/sqlsrv_fetch_datetime_as_strings.phpt b/test/sqlsrv/sqlsrv_fetch_datetime_as_strings.phpt new file mode 100644 index 000000000..8e8c34950 --- /dev/null +++ b/test/sqlsrv/sqlsrv_fetch_datetime_as_strings.phpt @@ -0,0 +1,120 @@ +--TEST-- +Test fetching datatime fields as strings +--FILE-- +c3_datetime; + $value2 = $row['c3_datetime']; + + if ($value1 !== $value2) + echo "Data corrupted: $value1 !== $value2\n"; + + $value1 = $obj->c4_smalldatetime; + $value2 = $row['c4_smalldatetime']; + + if ($value1 !== $value2) + echo "Data corrupted: $value1 !== $value2\n"; + } while (++$rowFetched < $numRows); +} + +function GetQuery($tableName, $index) +{ + $query = ""; + switch ($index) + { + case 1: + $query = "INSERT INTO $tableName ([c1_int], [c3_datetime], [c4_smalldatetime]) VALUES ((2073189157), ('1753-01-01 00:00:00.000'), (null))"; + break; + case 2: + $query = "INSERT INTO $tableName ([c1_int], [c3_datetime], [c4_smalldatetime]) VALUES ((-920147222), ('3895-08-29 00:41:03.351'), ('1936-01-05 21:34:00'))"; + break; + case 3: + $query = "INSERT INTO $tableName ([c1_int], [c3_datetime], [c4_smalldatetime]) VALUES ((-2147483648), ('1753-01-01 00:00:00.000'), ('1915-11-08 19:46:00'))"; + break; + case 4: + $query = "INSERT INTO $tableName ([c1_int], [c3_datetime], [c4_smalldatetime]) VALUES ((1269199053), (null), ('2075-04-27 22:16:00'))"; + break; + default: + break; + } + return $query; +} + +function Repro() +{ + StartTest("sqlsrv_fetch_datetime_as_strings"); + try + { + set_time_limit(0); + sqlsrv_configure('WarningsReturnAsErrors', 1); + + require_once("autonomous_setup.php"); + + // Connect + $connectionInfo = array("UID"=>$username, "PWD"=>$password, 'ReturnDatesAsStrings'=>true); + $conn = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn ) { FatalError("Could not connect.\n"); } + + FetchDateTime_AsString($conn); + + sqlsrv_close($conn); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("sqlsrv_fetch_datetime_as_strings"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'sqlsrv_fetch_datetime_as_strings' test... + +Done +...Test 'sqlsrv_fetch_datetime_as_strings' completed successfully. diff --git a/test/sqlsrv/sqlsrv_fetch_field_twice_data_types.phpt b/test/sqlsrv/sqlsrv_fetch_field_twice_data_types.phpt new file mode 100644 index 000000000..54ca0ff0f --- /dev/null +++ b/test/sqlsrv/sqlsrv_fetch_field_twice_data_types.phpt @@ -0,0 +1,141 @@ +--TEST-- +Test calling sqlsrv_get_field twice in a row. Intentionally trigger various error messages. +--FILE-- += count($metadata)) + { + $value1 = sqlsrv_get_field($stmt, $idx); + PrintError(true); // errors expected because the idx is out of bound + } + else + { + $colType = $metadata[$idx]['Type']; + + if (IsDateTime($colType)) + { + $value1 = sqlsrv_get_field($stmt, $idx, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR)); + } + else + { + $value1 = sqlsrv_get_field($stmt, $idx); + } + var_dump($value1); + + PrintError($errorExpected); + } +} + +function PrintError($errorExpected = true) +{ + $errors = sqlsrv_errors(SQLSRV_ERR_ALL); + if (count($errors) > 0) + { + $e = $errors[0]; + var_dump($e['message']); + } + else if ($errorExpected) + { + echo "An error is expected!\n"; + } +} + +function Repro() +{ + StartTest("sqlsrv_fetch_field_twice_data_types"); + try + { + set_time_limit(0); + sqlsrv_configure('WarningsReturnAsErrors', 1); + + require_once("autonomous_setup.php"); + + // Connect + $connectionInfo = array("UID"=>$username, "PWD"=>$password); + $conn = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn ) { FatalError("Could not connect.\n"); } + + FetchFieldTwice($conn); + + sqlsrv_close($conn); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("sqlsrv_fetch_field_twice_data_types"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'sqlsrv_fetch_field_twice_data_types' test... +string(79) "A statement must be prepared with sqlsrv_prepare before calling sqlsrv_execute." +string(63) "The statement must be executed before results can be retrieved." +string(52) "An invalid parameter was passed to sqlsrv_get_field." +string(52) "An invalid parameter was passed to sqlsrv_get_field." +int(968580013) +bool(false) +string(25) "Field 0 returned no data." +float(1.09) +bool(false) +string(25) "Field 1 returned no data." +float(3.4379999637604) +bool(false) +string(25) "Field 2 returned no data." +string(23) "1756-04-16 23:27:09.130" +bool(false) +string(25) "Field 3 returned no data." +string(52) "An invalid parameter was passed to sqlsrv_get_field." +string(52) "An invalid parameter was passed to sqlsrv_get_field." + +Done +...Test 'sqlsrv_fetch_field_twice_data_types' completed successfully. diff --git a/test/sqlsrv/sqlsrv_fetch_missing_row.phpt b/test/sqlsrv/sqlsrv_fetch_missing_row.phpt new file mode 100644 index 000000000..261c0231a --- /dev/null +++ b/test/sqlsrv/sqlsrv_fetch_missing_row.phpt @@ -0,0 +1,68 @@ +--TEST-- +Fetch missing row +--FILE-- +$username, "PWD"=>$password); + $conn = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn ) { FatalError("Could not connect.\n"); } + + $tableName = GetTempTableName(); + + $stmt = sqlsrv_query($conn, "CREATE TABLE $tableName ([c1_int] int, [c2_tinyint] tinyint, [c3_smallint] smallint, [c4_bigint] bigint, [c5_bit] bit, [c6_float] float, [c7_real] real, [c8_decimal] decimal(28,4), [c9_numeric] numeric(32,4), [c10_money] money, [c11_smallmoney] smallmoney, [c12_char] char(512), [c13_varchar] varchar(512), [c14_varchar_max] varchar(max), [c15_nchar] nchar(512), [c16_nvarchar] nvarchar(512), [c17_nvarchar_max] nvarchar(max), [c18_text] text, [c19_ntext] ntext, [c20_binary] binary(512), [c21_varbinary] varbinary(512), [c22_varbinary_max] varbinary(max), [c23_image] image, [c24_uniqueidentifier] uniqueidentifier, [c25_datetime] datetime, [c26_smalldatetime] smalldatetime, [c27_timestamp] timestamp, [c28_xml] xml, [c29_time] time, [c30_date] date, [c31_datetime2] datetime2, [c32_datetimeoffset] datetimeoffset)"); + sqlsrv_free_stmt($stmt); + + $stmt = sqlsrv_query($conn, "SELECT * FROM $tableName"); + $result1 = sqlsrv_fetch($stmt); + $result2 = sqlsrv_fetch($stmt); + + $errors = sqlsrv_errors(SQLSRV_ERR_ALL); + $e = $errors[0]; + $value1 = $e['message']; + print "$value1\n"; + $value2 = $e['code']; + print "$value2\n"; + $value3 = $e['SQLSTATE']; + print "$value3\n"; + + sqlsrv_free_stmt($stmt); + sqlsrv_close($conn); +} + +function Repro() +{ + StartTest("sqlsrv_fetch_missing_row"); + try + { + MissingRow_Fetch(); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("sqlsrv_fetch_missing_row"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'sqlsrv_fetch_missing_row' test... +There are no more rows in the active result set. Since this result set is not scrollable, no more data may be retrieved. +-22 +IMSSP + +Done +...Test 'sqlsrv_fetch_missing_row' completed successfully. diff --git a/test/sqlsrv/sqlsrv_fetch_object_class.phpt b/test/sqlsrv/sqlsrv_fetch_object_class.phpt new file mode 100644 index 000000000..9b1db31df --- /dev/null +++ b/test/sqlsrv/sqlsrv_fetch_object_class.phpt @@ -0,0 +1,140 @@ +--TEST-- +Test insert various data types and fetch as strings +--FILE-- + "tempdb", "UID"=>$username, "PWD"=>$password, "CharacterSet"=>"UTF-8"); + $conn = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn ) { FatalError("Could not connect.\n"); } + + $tableName = GetTempTableName(); + + $stmt = sqlsrv_query($conn, "CREATE TABLE $tableName ([c1_int] int, [c2_tinyint] tinyint, [c3_smallint] smallint, [c4_bigint] bigint, [c5_bit] bit, [c6_float] float, [c7_real] real, [c8_decimal] decimal(28,4), [c9_numeric] numeric(32,4), [c10_money] money, [c11_smallmoney] smallmoney, [c12_char] char(512), [c13_varchar] varchar(512), [c14_varchar_max] varchar(max), [c15_nchar] nchar(512), [c16_nvarchar] nvarchar(512), [c17_nvarchar_max] nvarchar(max), [c18_text] text, [c19_ntext] ntext, [c20_binary] binary(512), [c21_varbinary] varbinary(512), [c22_varbinary_max] varbinary(max), [c23_image] image, [c24_uniqueidentifier] uniqueidentifier, [c25_datetime] datetime, [c26_smalldatetime] smalldatetime, [c27_timestamp] timestamp, [c28_xml] xml, [c29_time] time, [c30_date] date, [c31_datetime2] datetime2, [c32_datetimeoffset] datetimeoffset)"); + sqlsrv_free_stmt($stmt); + + $numRows = 0; + $query = GetQuery($tableName, ++$numRows); + $stmt = sqlsrv_query($conn, $query); + sqlsrv_free_stmt($stmt); + + $query = GetQuery($tableName, ++$numRows); + $stmt = sqlsrv_query($conn, $query); + sqlsrv_free_stmt($stmt); + + $stmt = sqlsrv_prepare($conn, "SELECT * FROM $tableName ORDER BY c27_timestamp"); + sqlsrv_execute($stmt); + + $metadata = sqlsrv_field_metadata($stmt); + $numFields = count($metadata); + $i = 0; + while ($obj = sqlsrv_fetch_object($stmt, "TestClass3", array(1, 2, 3))) + { + echo "Comparing data in row " . ++$i . "\n"; + $query = GetQuery($tableName, $i); + $dataArray = InsertDataToArray($query, $metadata, $i); + $values = (array) $obj; + for ($j = 0; $j < $numFields; $j++) + { + $colName = $metadata[$j]['Name']; + $value = $values[$colName]; + CompareData($metadata, $i, $j, $value, $dataArray[$j], False, True); + } + } + $noActualRows = $i; + + $i = 0; + sqlsrv_execute($stmt); + while ($obj = sqlsrv_fetch_object($stmt, "TestClass2", array(1, 2))) + { + echo "Comparing data in row " . ++$i . "\n"; + $query = GetQuery($tableName, $i); + $dataArray = InsertDataToArray($query, $metadata, $i); + $values = (array) $obj; + for ($j = 0; $j < $numFields; $j++) + { + $colName = $metadata[$j]['Name']; + $value = $values[$colName]; + CompareData($metadata, $i, $j, $value, $dataArray[$j], False, True); + } + } + $noActualRows = $i; + + sqlsrv_free_stmt($stmt); + sqlsrv_close($conn); +} + +function GetQuery($tableName, $index) +{ + $query = ""; + switch ($index) + { + case 1: + $query = "INSERT INTO $tableName ([c1_int], [c2_tinyint], [c3_smallint], [c4_bigint], [c5_bit], [c6_float], [c7_real], [c8_decimal], [c9_numeric], [c10_money], [c11_smallmoney], [c12_char], [c13_varchar], [c14_varchar_max], [c15_nchar], [c16_nvarchar], [c17_nvarchar_max], [c18_text], [c19_ntext], [c20_binary], [c21_varbinary], [c22_varbinary_max], [c23_image], [c24_uniqueidentifier], [c25_datetime], [c26_smalldatetime], [c28_xml], [c29_time], [c30_date], [c31_datetime2], [c32_datetimeoffset]) VALUES ((-596308883), (0), (1), (-856437494), (1), (0), (1), (0.2409), (0.4671), (1), (0.1303), (null), ('zöhUarCßZOÖ_O@+Ö¢ZvÐCã<_u£O/*U~uÜv©Ð,_oÃ/B+ßzC£O*UzÐrª|buvðäaÃ:bª@Üðä¢,BhªzA>©uCýýbBðäAoÄ~@BªZ©Ð£zOß*Ð*ÄäuªªZ@ª|bßåaª+CÖ>ªuvCZ>ãð~.O>/ÜU©,uÃU/åOýöbÜ.©CvO/zÖ@bª~ÖÖÃÄC/b£b¢*uh:@bÐAZOUÄ/UÐob|ä.ÐÜzåhÐðva<Ö.*A*/Ua/a|aåÐ:>@az~üÖzãý©ð~üvhãAvä+zîozîbCãäÄîª/©rîö/@aB>b©>ÃAoåÄýªåBO¢äaÃî¢<üvÖ*hzbuåªÜävßä>ßrAüöhÐZÐ*>ªböÖ¢,¢_Üðo|ÐB©ã.ãAß,Ö+r<å©_ã|:¢ßã:oöãh<©ZB~©©ZäZzz<Ä_CäÃÐZÐÐBÃu<_Öå©>å|Ã|ob©ß_ß~ßU@uýðvЪ>r_/Ð~ªäCCî.rß/ÜÜh+ArîO>höãOa<¢>obaÃavߪ>ß©/îOª:B.'), ('ÖÖ@zÜ_.uܪü*,B_uäª<Ã:©üýAäböaö>ö<Ã*ÐÐÖr©UßÄ,Ãä¢@:åä*@äZuu~OýýO/ýîrCÃbzÃUh~Ä.:ãb©@îî.ÄZb£¢ACð~uÃb.Ð>>Ððbvavªh>bAOÜÃðî¢ýÐ+~ð~:ÜrBCh<ÖUÐ.bÖªß,:å+Ur:Ö@å:ÐvöOoîör.bA,ªö/ãvv£hÐîho,:.>Ö*~/üüª,COh,îÜî~~~<ß.©OÜåÐÄßCßßÐ>:ª/£*AÐbCUUüý|~ßý¢BBhß|uvßU*,/å:zãBýhß:+ðB£¢>Öß~rýÖå*+ðÃAr,|ß.ÄÄ+ß©o<~©ooÐoAoðÖ@ü©C,ÃýCöî.öö:î|@.ðvÃB©C¢*~ТOî@C:äªCZza+ÃÄvb£ÄÄUo£¢U©b/z|>bCv@Öýîã@ªz:uBîîý,,bý¢ä<:|'), (N' '), (N'Z|ßUîBOüvoßrCöÐ/_*ÜbAð@>:UßbrТ,Coaå/ãaßß/Bår.Ö@ÄCÐöÃz,+Azß©ZCÜ||/BööãýÄzüv¢ß£ZA@Z+býÃÃßÜ©ãCa*>©£_zÜzß~ähA¢ÄAÜ_.aßoaÜÃ~åÐZoZaäÃý<ªüZz@ÐÄÄ>ööbýÜaC:CuO>îüö:ba¢Zäv+£u/ßUb>b:ZZÖ£ßÖ@oo|Ð<ßýÄa*ä<ÄB/¢©ª/Ö+uä+£hÖr¢rz£z@£:öoªÜ.*öCUUz*_ßC:~ß<¢üåýåOÄ|*ü+ß@_<*A>_£:hÃÜüßäB>rÃCßAa>boЪÃÜ¢hî:ßßbbv~bý|C,:üÜ*ÐCÃîüaÃOB£Öüßö~a<©ª>éªa@¢_z|bîzzä>b.Z,öbb,/@ªvAüBðÜ,Z£b@©.*>,¢bÖ:©ö<@¢oZ£/£Zo>î+>*:hCöAr:_ÐîA:Ã/*Ãböz~<>Ö>ÐäaÜ+O>ýaAOî¢>¢ÖAüåvvrÖrö>/öbîåü,£rorÃO|.A/£U/b~z~|>ª>r@BßßäÖ|ðBor_üZ:_+ß*äuÜCö@:ä¢>+,,î:Ãb.ä*ßäB*<_aC:£å¢+~Ö:hÃCv<öB_|'), (0xD35A6A86054875A44046409962581502342C6344FD8635EC1395F8357448F3F191003B3130746C9B9EC07B4C32D764F9AA94050A90AB2A4D257D736F4F4030F8534E07621DE4D1BFC0C8A53C0AE8BA3B31FE8AE042E961E5D6ED0BB201FD4B5E9083F9E3CF02DCC6C3464AC806EE423DC3373E51B64FB56AED218C30D81EBDC37C46AB87EFD66B2E22C41CFC9E98DFE7AACEEFC9BEFAA840CD8FF5AD76ABEDA488874BBF42BB4EEDCB0F2EF133B9CB5542A485092FF404829E6ABA60E0BEB876D67873174C1FA5EF8001FDAFCBB60D13C3A06AD226E3759382C821D800ED0C0D56B81BBA45B30823FE96892DF654B7E85CA69C3F53E650F203DF9484FECDEE92F5EF59139A52CE109847D3905A479C2E11387B5951CDBA706728B7651E842431A7F63807FBA34D0AD88CA60B13C098BB426672C55194412735E9AB729A68F11422A1E8630E95336DEB7181C526AE5CA790FC23B8115FDF12B510D112F8DB6F709A92E971D734ACAD3304DAE0137B01868C03E19E453903C3C1D6AEFEC421751001112B93C5EBD05C4F75840C85FEFF3A0E4A85F4FAD02B608F26AF0185AEE9128FCADE02506DC1A033844ECFB4F63EC3D774EF799B801631E5CA049F3BCED6A08C727DBA20FCE9A189E4C075815BAC98E8EC2A11BF6F760EB4AD1C8668226465ADAD42417883A3DA8A4EEFB6BFA0AF8A1D6BB64FA4C5E11CFC6F0672E0633866), (0xC7D3196A20644950877180BF4E13FE9268FD6B15C1E8CC2545097C30F92715883664D8DB70B34B5106533E6F9C3C20F3744EFA3AFB6A9ADF07F42517E818565F5BF789EA3B2221B5B1190F6DAA5C8808E988BCAB2DDA8DCCC9F8D37C8E3469EDFDDE14A4B335B8512C4489E15B2D35AA6B1C2D5F5CAB32806ABD21424EA5277DB02170CB48E355B3D06B7EE851AC709CC329117106099151AB933AF6147502871D0C3039BD696287C67A8FF12D4A2FBD4C857E2594B576A7901E1FB4A85F9F5A68F7CB457B37DE59C689AB8C79A02461647DAA8FF6DCF3679589A99F4AADDE67DA3488367FE94214A6255F0A0AEA2DF0FABD502BB510638C0463B0F28E3F0F18AB44B14517EEE27B3A95E8D17DE85DAB5BB8A48C5DB2B1CAD0FC321B3950866715465EC538E8D80BDBD5F11F27920E1B060496D59A83BBF992E6741BBCC741EA0F81BB3789977273DF99B188C092A23EED161434B9B0CC928A65335173BD4F13930710A6D6D7916F9223F501D233380044352DA5B20D305EB429AC246320FF22499DF4B982FC681685A5A196BACBC0572D330D3E90A96186D7B1F1AD2A6D0C7224D3B7353E7E7E47CD16200D6B99A4E96855F73012C0929F3B6EE2D00ABBEC17992F72E7138B19AEB5C5717989531B3D0D0844D576DB5F634018F9CF9CAD3D112A08743B27BCD6DD3B487A4D4F1916E853A4C3027716A1BDD00EA6FA92491207), (0x80DFDF16503166992D6112132702117CF7E93B9A1466B76A1816DB4BF13572C4F0CA9508738E73D0107C745BBEFB7EF880CD1B1D4DC43A1A2875FE39551BA8F7EE4D235D6C080869766A8A97F25BAC1C97E3CA241A55772B907BE0FE8F397BF4D47C6D71D8218B78C5B2A7E23AA227CCC9E1A2725184DD99D5F7CCF1270AD93DEE95C376ED3A447557525F68AD95F0ED531335AE9609A3509ED49CE0549A50BAD969F4A5DFB1DF8E9D2C1AFE2575EB4006DF9D13D42AA6E5F173D7199E6320BC01A48F44A14B0EA234A61169EEA42A29E95CD975FD3CE6AEC30EB36BD9C5F0390C5EFD81E5A69FBBD1FADE2D193CF74C48AD2F418AABBFC4BEE1819297A2C96EB6D85D8FA7A94342BD1EA4035DB894861666232B96AEAE619F38C304250C232E306F7741DF67A59E6AED846B06BC67054CFA7B307F9DD80729FCF06FE63E1CB0FA75D2ED4052A7AFC184C1A829435AE3D1BDB82B90F2AF92976F18E37736B82BD0D37091E979C4FA53CC6FFADC2FDDE5A10D9D2986F12008C63F56D13AC3378ACB96D756D2C9F957F8BDD7C382B4B66791324169988FA4DFB368CBAA22F3C08F95E52E46588713D8144530C8195D851189EF3F0782CEF23CF1F8A26AFE4E3505FD472E9D856F0F091F6955525EDBC656E2B92133B3B80DC6F2F2555FE4A8D9C5102BCAD12EE78B19E035E719789FDE15324C87442D0251453A67AA931AAF25768F8F423210F427FB2E07537ED1F34D53133F2D982195970EDA8597C63CF7FE3010708AE85CAB043D258B1625AFD27447195680DB818D55FAF834588B5C60BE3609226D606865F7683AEF72957E725E071150ADE57722AF831B90F0285379E1C4CDDF1C8C6513DEB45F17A0911ABF7B86D5507A0CB3D8BFE672EA44D874CE14C10EAEC79F55D1A2FD71F8865F821D695B156A5302FFB09B27E324E6C58CBA56A387FCA7FE715972416FA69363), (0xC648FDACD01D6A0B6039F39937DDFED9AE5F8F380AAFF91E79E5B3D32FCE1C38DFE25E9EC7E0EA38387B9C6E0AD821954295F833D30FF6164EDE32EA6A96DC911CBAB9557F6012CE7557FF8E138B14A1C31E9199D6E865CFEB484FE9ADFFCDA29E0B514F1ECC16E1832ABE7C0F6703C3CA90274B0542BB3455EA693610282075895DF00739C583F608AF15AC2AE8BF83458C1E1CD8829C5B501DF93362DFD15A0948F3B277FB89040D3043552C0E096D2AE5F1830A049D07C094B71BCB4F9328DEBBA3E1F50D0C4A031A0FA73E472E41138C097DEE4D5005ABECF2E3436D38BD9C1A77716B28771DD9A680F0F4F5C8796576083F46163A916A9D35091A280795E1520A23D0BDD6EB14EBA347CD6010B523797ECD65F97686E0E606CDF26E02B09FEA0EA2EBA5A9A79F1C2A5B72F2C30A8D7FE5A1AA3A30E7DB8442EAB608F8A6E8F3A8E2516ECA7DD0D62D48CF1B13E22FC407388610565B927C76662BEF1972484727F4AE1B81EB567D1D40CE717BF7054C8B9C7851D87ED422929A7641B11E495244BA994A4404321BD208F3058D10F07F50EF637CF9F66EA9107B78E77504CC0F077C3CC16DCB08775A6C7FCF8BCEA57199F6E0C1AADC584E4BF029C89B5A96DD3CE40E10E43F1185E6FC129D869F1D41D6074D8E240A643B13EE756DA13FDC0FC5A28297B0848D6AE55AEAAEB9BAC7BCD2D7E2840D18A9328FD2FCF5C9A3E4A71002D7D41C75914179E298D92FC5715926C89AC94D5802ACF95017DD8797A14166338EA6E2E3905D46A10A1A7FD012CA619E397E3B475B39876CEE7F9F967842190279C1528437A4109EA2B5ACDA29D349C43EC30E5FF8C9B2088CAD860DC94576EF50B6D50D4C4A66956D9CA4A68CAD421B35DB58B434B90AAF0E49F78A1D02D55D3FBC8973FD3C77F45D78F25B250C7CDF6B6BD8EDECC1BA96AB26FE0352), ('9d30ba7e-f6f0-4aa7-a7b1-bd074f458078'), ('2016-10-31 13:39:46.362'), ('1938-07-12 22:15:00'), ('10/31/2016 1:39:46 PMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/0010/31/2016 1:39:46 PMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/01'), ('05:35:51.9401724'), ('2016-10-31'), ('4685-03-06 12:32:44.5405972'), ('4052-05-14 01:15:44.4184521+00:00'))"; + break; + case 2: + $query = "INSERT INTO $tableName ([c1_int], [c2_tinyint], [c3_smallint], [c4_bigint], [c5_bit], [c6_float], [c7_real], [c8_decimal], [c9_numeric], [c10_money], [c11_smallmoney], [c12_char], [c13_varchar], [c14_varchar_max], [c15_nchar], [c16_nvarchar], [c17_nvarchar_max], [c18_text], [c19_ntext], [c20_binary], [c21_varbinary], [c22_varbinary_max], [c23_image], [c24_uniqueidentifier], [c25_datetime], [c26_smalldatetime], [c28_xml], [c29_time], [c30_date], [c31_datetime2], [c32_datetimeoffset]) VALUES ((2147483647), (6), (13193), (499351064), (0), (0), (1), (0.1990), (null), (null), (0.9601), ('üo.hý~BZ~|.b+OäÐbäv©,~<ßAöªB*ßuC~oÐözB@ÐUö+Äz©BAu>£BßßÖ,Ã~BAýýüÜ'), ('r:î.ý*_//uÜ@,ä~åãoCzÜ/+vÐý>ÖUý~+Aoî~zb£Üv+*oîbÄO.Ch¢rüÐÜB£ÃýäÜO:£/>rüý|Ö@*b.bO+©ZZ+Cäühb:C>Ã.£î>Oî_>ª@r.~,BåðzÄîvaÄ|/b~Ãv/Öä@ä+å:|uO©åbÜBö|<ävCh/ª/,ð+bhzäuoÖ+îÄau:+B@u,üö<>>Cßýz¢:ð:üöB@båß©îaÐbã:£ãÖbî+A/ýå~©rAuähðývbv+äa£/ÐbðÖ:£©Oh||_|.|örð/©Ü:Aåßb~.+>å'), ('z*bhha|äbZ~,/ä>*hðªü£ZAAö,bUß©©_v£Bräbß.Cð+Öz/£Äða+ü/zvAzbOÖözA/¢ACßÜvßüä@raäã©ãr*h.uvîCÐ::ÄCåä:COZýBAbãÖ@höbðOOhöhB>O/*îh/ABãý£Üî©_©ÖOv:Ü>ÖÜo©_v@üöÐ+£aå£O_î_>OOU©_.Üä£Ðé~Ð<åܪäbð.v©£A|v©ßUªuvý>Z¢ý~oäÐîzrb~ßðªa>ã>OãÖéî:uÖÜÄ:CÐZÖª@B|U~_УUîh_Ī|/î|h_r.ÜðC©O,.ßrAßhOba<ör+©äZ@öB¢ðã¢.ü~ÐZ.ãåBb|rCA¢BB**u+.>©._v+/ðå_¢_î|Obb@bªãoß<ÖvåãaZª¢va<ðzÜC<:OOA~~CbðbvãhÖ|*äößý<ªð~öavîbvÐZ,ªo©ýÜîohßðöaÖ<@:hb,ýCýävªB|zuý©zü<_ªå+bA¢ä©©ü|O_Ö:ðr+zU¢Zß,oßz*¢ãuvª//îða+__ãüU/ÐC¢aUß/vCöÐßoa¢r@ZruU<ý:Ð~>¢ö/Ðð|ö/ÃÃz,Aßý><ÃbÜýÐ*a_ÜAOvhov©zß*ÄußUr~ö@Oðo:Uý_Ü©ß>åª.rh_Öo_@AÄÄý£Üuäã|.ßß㪢ªöZ¢.¢äãðÖzA©Ð:/.ýhu::ªrZîßvbBÜ|ª_ðßåðC/äåbîߪÖßýÖ/hߣ|<äÐ,~,ÄÖbÄÐoBÄöär+ß>ߢ£¢UCUðÄÜbZ+~výaîuÖ+h.ýÐubz£:ar:ÐîC>ßßã|zzý.~,v¢hªðAoÜ>za~ãðÃ*_ZbA£©o@OB.rAã/~oäßÃ@ãbovö/ß>uüðäüßÄ*_Öª:£/ã£üЩî//ýCýßÃrðÖÃU+aöC>*bAÄU£CO'), (N''), (N' '), (N'ÜîbßýßähC>/Üb+b¢<Äo¢©¢OOÜäöÖövü.:<<<ühhÃ>ððuãåbßoUü_+Ã_hÄåbCäBrä_a*ªî¢©*~|Bü~©~å~U~£ÜA£v@++ObB©:orhîa_öÃbäu_~äüß+©a..uÜÖßý<Ö~ßzhªhO_v_<:ÖhÜzÜ+_b*U¢hC,ð~z:OîðUCääBoªbubÜO©üÄAUÄ¢£vîA>Cãßz¢ªð:*Ðö+hAð:ðZA:ý/ß/u_bÐ~v©+B+ÖU*Z:£h*ãðA*îußoÄýåª>ÃA.BB@OäbbªUÜZ©C£ã,Z©ªå,å£ãö/|Ã<@äbröO+Cö<Üä/BCöCAbh>ZãBhau:ÃU/@.CÖîU_ýuAöböüð:ÃAU|ã©o~~©/vrh@åäÖZ.Ãüî_üÃUýUªoã+.v£hC.U<Ã_,a©|Z@Ca,r:ª/*ü~h/o*ü@~ðßååÖÖ+böa/@@zCö>CªÜ£îßãZO_UãZ*~ä/ÖÖ.¢,UAo@ªaã:vA<Ãu,ÖöaaAª~rCu£©ä£b~,_äÐ*Ð<.Oã:Ðvu+¢COC<ÐÐ,AßbîöåöoO+Ä£ðã>ba>¢ãrhãöîäA_©_¢ã©oßðvã_@u©v,|~/Ü£hBýBîOåüBabã/@©ÖäýÜa|ÜOüBª_å<,*:Uå@/¢ÐÖýöüoã:©ßoª¢Äª£ÜB,ðAaZ£a>Ðâª_ýUhCußb~ª+@/ß+vä©Ðß<ßC@ªÐ:*ð>:oãbvO+>'), ('Ä@ß|_~@ZУböãCÖäÐ_,Ü:hBhrÃ+_Oî+b+ðÜv*öboöbrä.raö@z¢örª/~/©+ärýCãvüªî+>_ß>rã.öuÖý©/aäv.äÖ@O㩪rüöð+~/¢C~AÜãu~v.>|ubÜBUßüürßüUUZ£Ab>~Oh@h¢våߪßrßA<ãZr'), (N'Ob|ÜUîÄ:oo£Uö:CC:Ðv.Ü|+OCOß*o*å+Üh£>*üazðð~bßÜð¢boB£uª*ßb@b_ÜZaha,O>BoA@Ðü>äüv.+UOUýuuhoßä.ãð<|£ð:b.ª:_îCªðUC>ßßBÄv~AaîÜUaÃUÜrªU/äö@rýÜß©*å£zåbzA¢Örrüªî_Zo~Övhðý©ãU|z~Bö<îÃhv<+ü,rh:,bO£ßzO¢>BßCz.+vÐBaªÄzO>AA©ßU.,+@+_.ª¢a>.Ð~î©>zü¢Uª|vo©uzêߩ.+bÄ:¢üäü©BB_OýÐvß|ÄÃoaßßB*ÃzBîArãa+@rrä*B©~><ÐýÃ>AäAbüu+vå*vZ|äÜbåÃO¢ub¢Ã,~>:z+,+ýßbAaCäÜauzåªb|ßßåýßZîBãä>.,.ZzÐZUC.oü|oÐߪîOU~rðbЪrbßä:£/öýbOîðo@<ýÐ|ßOh_zßvÜr<ªv£AOår<,ß|:¢Ã¢z<@<Ð~üîÄhvÖ<+.bC_å.*©>AråhßßbU,*CßÖÃAOäB©ßîîhÐBüÖ:îÐZZ©ýBäOäüåÜvßÖ**zB|ZÜ:|Ä_¢b.ýð,h|rvß,Ðu>ÃÄ£oäZZÐ,a_aãåvb~üü>ÜÜäA>£Ð~<|öªäbªbß,äUz+Aü,,ZÃöru/ÜÖÐî䪩r|ÄvãböoÜvrvOBÄO/Öå©C*A£vz_ãC*ÄruУêBOî:r_/ÐðAzb~zhüð|ä@bý@_Cb/|ab<getMessage(); + } + echo "\nDone\n"; + EndTest("sqlsrv_fetch_object_class"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'sqlsrv_fetch_object_class' test... +Constructor called with 3 arguments +Comparing data in row 1 +Constructor called with 3 arguments +Comparing data in row 2 +Constructor called with 2 arguments +Comparing data in row 1 +Constructor called with 2 arguments +Comparing data in row 2 + +Done +...Test 'sqlsrv_fetch_object_class' completed successfully. diff --git a/test/sqlsrv/sqlsrv_param_floats.phpt b/test/sqlsrv/sqlsrv_param_floats.phpt new file mode 100644 index 000000000..dadb092c7 --- /dev/null +++ b/test/sqlsrv/sqlsrv_param_floats.phpt @@ -0,0 +1,112 @@ +--TEST-- +Test insertion with floats +--FILE-- +$username, "PWD"=>$password); + $conn = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn ) { FatalError("Could not connect.\n"); } + + $tableName = GetTempTableName(); + + $stmt = sqlsrv_query($conn, "CREATE TABLE $tableName ([c1_float] float, [c2_real] real)"); + sqlsrv_free_stmt($stmt); + + if ($withParams) + { + $stmt = sqlsrv_prepare($conn, "INSERT INTO $tableName (c1_float, c2_real) VALUES (?, ?)", array(array(&$v1, SQLSRV_PARAM_IN), array(&$v2, SQLSRV_PARAM_IN))); + } + else + { + $stmt = sqlsrv_prepare($conn, "INSERT INTO $tableName (c1_float, c2_real) VALUES (?, ?)", array(&$v1, &$v2)); + } + + $values = array(); + + $v1 = 1.0; + array_push($values, $v1); + $v2 = 2.0; + array_push($values, $v2); + sqlsrv_execute($stmt); + + $v1 = 11.0; + array_push($values, $v1); + $v2 = 12.0; + array_push($values, $v2); + sqlsrv_execute($stmt); + + $v1 = 21.0; + array_push($values, $v1); + $v2 = 22.0; + array_push($values, $v2); + sqlsrv_execute($stmt); + + $v1 = 31.0; + array_push($values, $v1); + $v2 = 32.0; + array_push($values, $v2); + sqlsrv_execute($stmt); + + $v1 = 41.0; + array_push($values, $v1); + $v2 = 42.0; + array_push($values, $v2); + sqlsrv_execute($stmt); + + sqlsrv_free_stmt($stmt); + + $idx = 0; + $stmt = sqlsrv_query($conn, "SELECT * FROM $tableName"); + while ($result = sqlsrv_fetch($stmt)) + { + for ($i = 0; $i < 2; $i++) + { + $value = sqlsrv_get_field($stmt, $i); + + $expected = $values[$idx++]; + $diff = abs(($value - $expected) / $expected); + if ($diff > _EPSILON) + { + echo "Value $value is unexpected\n"; + } + } + } + sqlsrv_free_stmt($stmt); + sqlsrv_close($conn); +} + +function Repro() +{ + StartTest("sqlsrv_statement_exec_param_floats"); + try + { + ExecData(true); + ExecData(false); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("sqlsrv_statement_exec_param_floats"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'sqlsrv_statement_exec_param_floats' test... + +Done +...Test 'sqlsrv_statement_exec_param_floats' completed successfully. diff --git a/test/sqlsrv/sqlsrv_param_ints_with_deletes.phpt b/test/sqlsrv/sqlsrv_param_ints_with_deletes.phpt new file mode 100644 index 000000000..9ed080aa2 --- /dev/null +++ b/test/sqlsrv/sqlsrv_param_ints_with_deletes.phpt @@ -0,0 +1,162 @@ +--TEST-- +Test insertion with floats +--FILE-- +$username, "PWD"=>$password); + $conn = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn ) { FatalError("Could not connect.\n"); } + + $tableName = GetTempTableName(); + + $stmt = sqlsrv_query($conn, "CREATE TABLE $tableName ([c1_int] int, [c2_smallint] smallint)"); + sqlsrv_free_stmt($stmt); + + if ($withParams) + { + $stmt = sqlsrv_prepare($conn, "INSERT INTO $tableName (c1_int, c2_smallint) VALUES (?, ?)", array(array(&$v1, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_INT), array(&$v2, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_INT))); + } + else + { + $stmt = sqlsrv_prepare($conn, "INSERT INTO $tableName (c1_int, c2_smallint) VALUES (?, ?)", array(array(&$v1), array(&$v2))); + } + $values = array(); + $numRows = 0; + + $v1 = 1; + array_push($values, $v1); + $v2 = 2; + array_push($values, $v2); + sqlsrv_execute($stmt); + $numRows++; + + $v1 = 11; + array_push($values, $v1); + $v2 = 12; + array_push($values, $v2); + sqlsrv_execute($stmt); + $numRows++; + + $v1 = 21; + array_push($values, $v1); + $v2 = 22; + array_push($values, $v2); + sqlsrv_execute($stmt); + $numRows++; + + $v1 = 31; + array_push($values, $v1); + $v2 = 32; + array_push($values, $v2); + sqlsrv_execute($stmt); + $numRows++; + + $v1 = 41; + array_push($values, $v1); + $v2 = 42; + array_push($values, $v2); + sqlsrv_execute($stmt); + $numRows++; + + sqlsrv_free_stmt($stmt); + + $idx = 0; + $stmt = sqlsrv_query($conn, "SELECT * FROM $tableName"); + while ($result = sqlsrv_fetch($stmt)) + { + for ($i = 0; $i < 2; $i++) + { + $value = sqlsrv_get_field($stmt, $i); + + $expected = $values[$idx++]; + if ($expected !== $value) + { + echo "Value $value is unexpected\n"; + } + } + } + sqlsrv_free_stmt($stmt); + + DeleteRows($conn, $numRows, $tableName); + sqlsrv_close($conn); +} + +function DeleteRows($conn, $numRows, $tableName) +{ + $stmt1 = sqlsrv_prepare($conn, "SELECT * FROM $tableName"); + $stmt2 = sqlsrv_prepare($conn, "DELETE TOP(3) FROM $tableName"); + + $noExpectedRows = $numRows; + $noDeletedRows = 3; + + while ($noExpectedRows > 0) + { + sqlsrv_execute($stmt1); + $noActualRows = 0; + while ($result = sqlsrv_fetch($stmt1)) + { + $noActualRows++; + } + echo "Number of Actual Rows: $noActualRows\n"; + if ($noActualRows != $noExpectedRows) + { + echo("Number of retrieved rows does not match expected value\n"); + } + sqlsrv_execute($stmt2); + $noAffectedRows = sqlsrv_rows_affected($stmt2); + $noActualRows = ($noExpectedRows >= $noDeletedRows)? $noDeletedRows : $noExpectedRows; + echo "Number of Affected Rows: $noAffectedRows\n"; + if ($noActualRows != $noAffectedRows) + { + echo("Number of deleted rows does not match expected value\n"); + } + $noExpectedRows -= $noDeletedRows; + } + + sqlsrv_free_stmt($stmt1); + sqlsrv_free_stmt($stmt2); +} + +function Repro() +{ + StartTest("sqlsrv_statement_exec_param_ints"); + try + { + ExecData(true); + ExecData(false); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("sqlsrv_statement_exec_param_ints"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'sqlsrv_statement_exec_param_ints' test... +Number of Actual Rows: 5 +Number of Affected Rows: 3 +Number of Actual Rows: 2 +Number of Affected Rows: 2 +Number of Actual Rows: 5 +Number of Affected Rows: 3 +Number of Actual Rows: 2 +Number of Affected Rows: 2 + +Done +...Test 'sqlsrv_statement_exec_param_ints' completed successfully. diff --git a/test/sqlsrv/sqlsrv_param_query_array_inputs.phpt b/test/sqlsrv/sqlsrv_param_query_array_inputs.phpt new file mode 100644 index 000000000..6174d36b6 --- /dev/null +++ b/test/sqlsrv/sqlsrv_param_query_array_inputs.phpt @@ -0,0 +1,158 @@ +--TEST-- +Test insert various numeric data types and fetch them back as strings +--FILE-- +$username, "PWD"=>$password); + $conn = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn ) { FatalError("Could not connect.\n"); } + + $numRows = 5; + + ExecData_Value($conn, $numRows); + ExecData_Value($conn, $numRows, SQLSRV_PHPTYPE_INT); + ExecData_Param($conn, $numRows, true); + ExecData_Param($conn, $numRows); + + sqlsrv_close($conn); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("sqlsrv_param_query_array_inputs"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'sqlsrv_param_query_array_inputs' test... +Insert integers without PHP type +1, 2 +11, 12 +21, 22 +31, 32 +41, 42 +Insert integers as SQLSRV_PHPTYPE_INT +1, 2 +11, 12 +21, 22 +31, 32 +41, 42 +Insert floats with direction specified +1.0, 2.0 +11.0, 12.0 +21.0, 22.0 +31.0, 32.0 +41.0, 42.0 +Insert floats without direction +1.0, 2.0 +11.0, 12.0 +21.0, 22.0 +31.0, 32.0 +41.0, 42.0 + +Done +...Test 'sqlsrv_param_query_array_inputs' completed successfully. diff --git a/test/sqlsrv/sqlsrv_param_query_data_types.phpt b/test/sqlsrv/sqlsrv_param_query_data_types.phpt new file mode 100644 index 000000000..0f319efe7 --- /dev/null +++ b/test/sqlsrv/sqlsrv_param_query_data_types.phpt @@ -0,0 +1,65 @@ +--TEST-- +Test insert various numeric data types and fetch them back as strings +--FILE-- +$username, "PWD"=>$password); + $conn = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn ) { FatalError("Could not connect.\n"); } + + ParamQuery($conn, "float", SQLSRV_SQLTYPE_FLOAT, 12.345); + ParamQuery($conn, "money", SQLSRV_SQLTYPE_MONEY, 56.78); + ParamQuery($conn, "numeric(32,4)", SQLSRV_SQLTYPE_NUMERIC(32, 4), 12.34); + ParamQuery($conn, "real", SQLSRV_SQLTYPE_REAL, 98.760); + ParamQuery($conn, "smallmoney", SQLSRV_SQLTYPE_SMALLMONEY, 56.78); + + sqlsrv_close($conn); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("sqlsrv_param_query_data_types"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'sqlsrv_param_query_data_types' test... + +Done +...Test 'sqlsrv_param_query_data_types' completed successfully. diff --git a/test/sqlsrv/sqlsrv_statement_cancel.phpt b/test/sqlsrv/sqlsrv_statement_cancel.phpt new file mode 100644 index 000000000..4efaed9e5 --- /dev/null +++ b/test/sqlsrv/sqlsrv_statement_cancel.phpt @@ -0,0 +1,105 @@ +--TEST-- +Call sqlsrv_cancel and then sqlsrv_fetch +--FILE-- +$username, "PWD"=>$password, "CharacterSet"=>"UTF-8"); + $conn = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn ) { FatalError("Could not connect.\n"); } + + $tableName = GetTempTableName(); + + $stmt2 = sqlsrv_query($conn, "CREATE TABLE $tableName ([c1_int] int, [c2_tinyint] tinyint, [c3_smallint] smallint, [c4_bigint] bigint, [c5_bit] bit, [c6_float] float, [c7_real] real, [c8_decimal] decimal(28,4), [c9_numeric] numeric(32,4), [c10_money] money, [c11_smallmoney] smallmoney, [c12_char] char(512), [c13_varchar] varchar(512), [c14_varchar_max] varchar(max), [c15_nchar] nchar(512), [c16_nvarchar] nvarchar(512), [c17_nvarchar_max] nvarchar(max), [c18_text] text, [c19_ntext] ntext, [c20_binary] binary(512), [c21_varbinary] varbinary(512), [c22_varbinary_max] varbinary(max), [c23_image] image, [c24_uniqueidentifier] uniqueidentifier, [c25_datetime] datetime, [c26_smalldatetime] smalldatetime, [c27_timestamp] timestamp, [c28_xml] xml, [c29_time] time, [c30_date] date, [c31_datetime2] datetime2, [c32_datetimeoffset] datetimeoffset)"); + sqlsrv_free_stmt($stmt2); + + $numRows = 0; + $query = GetQuery($tableName, ++$numRows); + $stmt3 = sqlsrv_query($conn, $query); + sqlsrv_free_stmt($stmt3); + + $query = GetQuery($tableName, ++$numRows); + $stmt4 = sqlsrv_query($conn, $query); + sqlsrv_free_stmt($stmt4); + + $query = GetQuery($tableName, ++$numRows); + $stmt5 = sqlsrv_query($conn, $query); + sqlsrv_free_stmt($stmt5); + $stmt6 = sqlsrv_query($conn, "SELECT * FROM $tableName"); + $result1 = sqlsrv_fetch($stmt6); + sqlsrv_cancel($stmt6); + sqlsrv_fetch($stmt6); + $errors = sqlsrv_errors(SQLSRV_ERR_ALL); + $count1 = count($errors); + $e = $errors[0]; + $value1 = $e['message']; + print "$value1\n"; + $value2 = $e['code']; + print "$value2\n"; + $value3 = $e['SQLSTATE']; + print "$value3\n"; + sqlsrv_free_stmt($stmt6); + sqlsrv_close($conn); + +} + +function GetQuery($tableName, $index) +{ + $query = ""; + switch ($index) + { + case 1: + $query = "INSERT INTO $tableName ([c1_int], [c2_tinyint], [c3_smallint], [c4_bigint], [c5_bit], [c6_float], [c7_real], [c8_decimal], [c9_numeric], [c10_money], [c11_smallmoney], [c12_char], [c13_varchar], [c14_varchar_max], [c15_nchar], [c16_nvarchar], [c17_nvarchar_max], [c18_text], [c19_ntext], [c20_binary], [c21_varbinary], [c22_varbinary_max], [c23_image], [c24_uniqueidentifier], [c25_datetime], [c26_smalldatetime], [c28_xml], [c29_time], [c30_date], [c31_datetime2], [c32_datetimeoffset]) VALUES ((-740876517), (null), (-13014), (9223372036854775807), (0), (1), (0), (100000000000000000000000), (100000000000000000000000), (0.5369), (0.8851), ('ðªÃªÃz>£Ã>Äbßvß*ý~:*ã©BoÃCrß.ЩÄ:h.Ö£<¢rÄöÖZ++b*hr©Z:ö@v@@ð|C©Uöãa£©äbÃ_üU¢åðßßzbåÃrb+v>¢huh|bbAÄß<+Ð.>b@C*Oz£+ÐĪ>uýbå<ÐhAÄã|üðo~oCz:~£.ªÃöAboýß@/ö|äb©ðý¢ª,ÜUüo/aÖ~ÖîîOO~rC+oaabb£äÃv_,ªv:ðuB©¢b@ýäAuzOÃuav¢ÜübCaOö_*O*ÜÃßuܪ.vOýãö_<¢u|©r©bu~~br<îß/_OäUߣ©a>Ar|b>ðA@©.ö.åC@v|Cro|h@<Ü:©bv©ü~_OO<@OB©aÃß>äA©b*ýU_:äðåÄBvAUüUa:+äÃöbÜ+A|oä+aªÖÜ¢Ðv/:hÃvzÜ/îb.b/ßb>oýBZuå@îÄb_Ã>_U¢uü~auO/£Z+:ühB:~üBªß@:b|öuýrßbð,ßßß*¢ÃaB£:ÖÃßUî<Äb~£ßÃääoäÄOA>+ýÖÜßb©Üaýßu©vrbßÄ£vä©@|¢Cb¢OÖýßboBÜða:äßðA~äªaª©Cbý|Ö£ÃübÄývZ@/zÐåßåÜ*ß~î:@/rýZÖÜZÄb_>C|>b@|aÃäýÖh,î<îÄ~ã+ß~ªbÖb/U@aß+ÜUÖU.Ããu|r~_©b¢,ZåªhuOÃ_ö/*:hÜoãO.+hor@a֪ߪýb.Ãub+~,¢,B_åA£ýBß_/@Uܪöð_£+@a|UÐCüüßåvãZ_u<Ã/ðÄ/ýü@zãaöîZoãðAB+_vhîÃaZðUªrÐ|Cv>¢öö_AböîBAb@Ð:îv/äö.ZaA/ÃAUТZ.ÜA©rýb~z<*Uß©ðÜOßÃöZÃOårªî_ãaßrvߣz>buðOä_îä/AÃýÄ~o<ªb|Ðz£CýýaªvC~ÜÖ:oÄßo._Aöh,o~ãðÐ*¢£ã¢hrßðbu+î¢Ðävð__å*Zr|_Üovö.hBäö@ööhZöååCooCz/_î©Z,äa*/vB+A|ü©bvAÃuî*ßU~ý:Ob,.<ÖÐbÐäÄýðO_©böð*ð:bîb¢O¢|åbßå|h,åÃîZßððu|bÖb,©Öz©£_Ðü>zä|C>äßîB,Aoß+A¢_ý@ã*AähUîCÖhUA/.,+bÐÄ/b:©ö,Auå,vbC_rCoZý/äªÐbÜä+ªÖ.aýîß~:.©B>CAAÖ>bC>rZubbzãã*,îbA/<<,vhZüÜÄ>O@zã~ý~ÃÐä.h>ÜüÐÜÃ>+,Aoa,*äuZrAÐBU:~:+|î:u_î,îUÖ.ý>býCbßðB@ABÄa|åÜbu*.v.C~ðh@v¢hB~ÖüÄuß>*£aüÜ/<.ävaCOåÐzÜ+ßAßAö*:.h/åCý£ÜoÄ©ÜZ~|.,Ð|ä,üuä:O*/ÜÄzÄÃ_+vA@Ðv,+AOb|>ßU¢.z.|_h><,<ª/zbzÄB>Ä,oªBhUhßüzÄ<©äã.vz©BhOååuß|£hªB~Ã@bvî|*Z.*_oÃýð|<©A,:,|OvÄå*Ã@©+rhÜoß~>Ðü+Äß©Ðruîýo>|ÄCzüåýrÃa¢îÃoö_uÖÖîoz/B©Ð@|@£:Ä*Oß>a*:_Ü|ß*åv<+äªýßã¢Z:Bä~rüãý~hªý,ßv£OzCUª:î/öãÃÜ¢,£ã/v<<£ÖU~ö|urZZb_~üß<Ð,ÄaO/£,vb,r>Ö~B+ßý/b|zArÃh©ÖoO£~OCA|:vrCäZåOAÐ_ÄüoÜü,,obÃß>vü¢BäТZ¢_|î_ßzrv/äOü¢öÜa/Ãrßüüå©ÜðoUOA<.:îO/UUOboî£ßª_©aäB:A/>©~©UÖåhüb.,ß_ÄÜ*Öo@C£bzbbUUh,Bª/üöU¢Üa>zðOßU:ßaöu@*v_Zä~Uªr@¢a~ýßüß~:o~ÖÃrr:Ub¢uuZðåÖzîÃb©+OßüÃð¢ã:>a/>bðªª*B/*OüüZzbÄu>bh@ßß.öÄ@Zã.¢hußßäüoÐ|~£*OrãÃ,ãðªü/åðÄU_£åãߪð|ãÖ>@uÐbÖ@|ä:¢OBaC:ðß©Ä+åbª/@äÐÜb/¢,Brå¢O@rðzbv£+|äÄ+ÃCîC,ª/¢z~îÜÜßaýßýßUãÖZ:ßAßßüböýa/+zÄUĪ:ýäözh_UU£_|A<@öß~|*_.ö|ð/>Uö+ßã+¢z.,Oß|+ývßÃÃbUAÖvZÜýý_Chåu+Aðv>ªßAîb/OÜß+z+*,ÐOß/~,~/b*oBßzr©OB*:ßo:+üzB_ý£©OßÖhb|ª+îîoÐÄÐý¢ä|CouAî~~Ð:~+ðhýã>~bb~öuã/åªãa:£ãÃðhÃäZC_|äåü~_U:zU£_|ßh+ãîUÃB~ýhãÖÃaaZüO:__ÐbUvå¢o@ÜßBvîßßäüA:/üäÐCãäU/aZ:BAU.Z~£,böbu+Ö<Üur:ahaB~ä*h:a,Ð><+aU£,>Z*©,>î£,,,bAr~vZBðÃ|ö/r,Ãu~ÖýÐrhãÐhÃ>¢¢©uüÜbð+@ðrbðzöã|åCvÄvzî,£oöO>:ªßhÄOö©*äU@ªA~/_ßÄüCv¢uaÃZ|Ãîbv>oÄÖ*Uä<.Ü@/@©Ðh>haoüAvU¢UhAå.ý/ßüa:*ßbZöu~+ÜrÐ*öob|îåz<å/_ßbÐ*:_ð©||åÃaoB£ª|êr©£+.>o©ªaöýÄ|zÖä£+|©åCÐðüb|hbä,ßßzh:+öö+vb_ªåü:ä*ßörCð*_î///¢__h~Oîuoz@Ã.r.ß~CAýªÃßvîoÃåýª_ð__ÖÖ_,AÄbrÄAZUßð_@üÜ./ßðÐUu.@Au|Ü~oå:©ZOB*ð,ýÖý£,Ö*>£Ö_CÐãaZo¢rbýhUÄBð<årÜÃb>/ðýU~AÖÃÖîAbbo¢£aA>Cå.ä@Z|üA|Ä/Uboå_ývß_b_AýoÜrvB¢îCªuUZvBãÃ/,*z+o@:,C+ßCÄ~ß:<ª/O>ð~ªß.£bObzÄoßrÄvUåA>äZBbUzßzÐzö:ÖÐ|Öå+rAbBöðBÜöUîhðªåbÐ@Z|ãäZýüääaUÖ©ö.åÃý:Ü*oü<,|/ª.*~ÃaAÖ~,:@:~Ö¢>b+*U,£uBåöOö:ã+/Ãbbä*ÐOåý>Ö©~£ö:ý<©Ãª£UzöAÐ.ZßC_bbÖ_ÃÖo+o:Uîî~_uaÐüýOÃãbßÖîZaÜ~r+r~>î/Öuzz@h,*.,@>.|ãh+.UÃÐðää+.åb|Ãab*ªýЩäoé<*_Ü@+a+uäourÃã,<öCU*ßÐ,>u|AUªzBãAäÃzßãßhîo+rðb:*âhz+|/vÐ,ð©O:Ub,Cb,£<ð_£að/ÖZ~OCÃ~üoÜ<>:/~:îhö:îZãßübÃrâ©+¢a@:ßÖ|>åv媣ªöuå<¢@b<@<:Üuba+Z|CCä/ðh£oª<~£.uh,B<*uýoZo>býa_<>@ý*>_Ð_zÖß<îªåäbu¢ãý|ab~öãÄöäh££Cýb©bÖ¢£~o~._UÃv¢aÜ,Ã>ð>ðÜ_Ãa~:¢OãÜ¢ßrübb_bvÐã_~U~vöåh~u:©Ub~/Ã<:+rBüîãbä<|@@>ª..AÐCÄvß*>uü+bZî£ä~ã,¢/¢+ÖrB/~bÐübäÃ_Ã|Üo|å¢Öð<ý|~î©ð©rÜü/,,>O,Ü/@avr¢,üzß©ßÖßä/vu_ä©.ßzäbÄBzOvýoBrUîrÜöOö+Bý.Ao|öBU£_BaÄÄ.hîv£C|©©£ª¢@b<ª©ÄbÃzoýhî.r:,B+ýZbZbr~>:vå@.£babîßÜßzUÜ~¢b¢/£BvB©OÖð,ÄöU¢ZТ£~>ß.h|~*_©bvÐ/Cübßo¢.Ö<*b©Oä@rA@oðA~ßa@|ÄÜC@ã©vßZ|>|ýUãA>*<+Äß*¢_Cß,|ObZªî£¢ö©/aðbu£|üoÃr|zÃAOýößîh_ååvC>OüB¢rBßî<:©ªÃb~öBoýå+v.îÃãb@åhAÜCo+ýbba<>ß~Ö*+Bß|ªÜÄvuCð|Oð,AzAz/å>_Ä~åao_.~é~zÐuüZ,z>åA::åh¢/oÖU*:å~BüÐÖ|Öã|u墢©ß+ÖöB.ª>vhýä|Buß/*C:hCý~¢ÜÖb>r|U_ü¢ßazubvBããÐåa£¢Ðß|@o_Ã+o**£|ýb~Ð*ª>.ßCCbOAZhãÐÖB/Ü.aÖ,/ö<ãüå.ÄBÜvý|/orðÃ::ý@.u*¢~|Cu©~ýüo|öühu©>ð@äão*öuäÐ|z.ð|u@+Zä~åCÄaªUªvü_rÜ>~å+>:Uªî,öaÃ|uýÄ:Üößîb.oã|B*üîO*_î+©äaðbv©@OÄ*Aaª|@Övüª_>r©îoUö>Ö©h©å*ä:äî|u_r:>@bÐ/,/b~ZßO£*AîaÐA/Ar+CvÃbî,/+ývÖO,b@_Bzª~,borBãa_@@Ü/Zhö<Ðz_Äoöãîåo£ß@rðB:£ýbC>üb,îä<>*åuhbßÜßî//uvzöOOaZªÃý©oå+u+>zUb+.|Z/Ã<.oz_r~ãäOAäOå|åß+rbUÄ~/Z~o+ääÜ©Ü@|î:+::~b@b*£h,_>~rb+/ÜßÖaübuüý/,BÃz©:<îÜ>rO_b©:Üã,Z|~.bßbÄ+<,+b@£ü_:bäACZzåu~Z©*_Z.ªÃäßâ_~ÖC:,CCÃîBCýÄü*Ovv_ãußAaöBü>ãÜOäã_ZZaäðÜBî.|r|ª/U@~@oÜzÜÄB>Zh£ãCðvhoÃAo/*ÖÐz.<ß.@|uzr©Ãbu@~î+£¢vAUh*~UäAA@,+++>~Öbb@¢ªrUîüaav_åöBhou¢ö@~Azß_¢,v£o_ö>ðü@BªhÃîÜZÜooOªÃÃå¢ßuîö<>ªC/öüö©<@UAh*ä>ð@r£::ÃUÜBz/ruãö,B/äüãÜbCBZUå~@Äoßßß|vU/Zu£ä£@ßhZÐb/ÐðUää:vAubã£î|oî<ÜîßÄîÃCåßZbßhBÃüü+öÖÃåУ..~Oð©+zðÃ@ßUÄãuhüboOrBüo©öOuhÜîOoz@CðöhöÖî:~åÄU_Ä¢Äß~+ÖÄA|voðbOÃ+.AÜC*zîöýß,/ªü|./zO/©Ob@@@|Ðü:zÄ~zoÐüäßÖÖu@|,Z/~ÄÖ>ÜývÃrývªßÖoü|>©äZßã/~@/©/Ã>CuBýAuö_ÄZ¢üÐÄUüý~vübÐ:hÜåzðU~¢v@@h,ÐÜhÖªöö|©ãBÐz|/boÐ/.ßörhîAvh©+:u|åUu/_+CÜå<öܪªÄh|BßBЪÜ~aã~Ãßîz.åo/zr££+Z£îåUObuÜu*Тozßh£*OrbßhbA|+Ã@äð:Öüªh£îðÄ|Z_.¢_ÃU/ßð@<ÐUö*ßu£Ä_U+.väOУ>Ö/<©ÜUÖ:@äCvÄð.ýAУßßÃvaaboý*©@@ÜzOBýb<Ã~,ÄߪU|:ýZã:bã©bh<£ÐBÜBã*ª@,ÐzýüUüu:ü>.Ü>Äýbãb/ð£hö@/Öªßvå:aÐoÐÃZärCªuB©båu,Übavo~Öª+>|>,/OBA,AzýZÖüäz*/bZ:_@rAuäOão/CzßzÄÖobý£Ããð,*,Uzbö>/vz,*ßa/b~öÜvÐo+:ü.vZä£Ð~zbª/@©äoBã@ý*vüb*Ä|AUUÜOAß*©©O|£ªßAÖ/ý|îbªOî£+BÃ:OühbÃzbZ..Äzr>ðvå.@Ur©+o©ü£bå_ÃЩuavУÜzBB_ßUÖÄhrýö£/oOãüboåäîîB~Ö<<~O@îßÃz¢COoBaã<ýbb:hzoz©>î:Or:u@ZU~A>AßÖã~ÄÜîbåa/îA@Z*o.äã/ðuh/Ãü©ßÖv:@AUÄZÐ:_Ü:A/ÖZ/Äröboo£¢å@ÄhAßUuCÖý.ývªA/ö*býîß,CvU<ä©BZä.+rªª/Ä_rîÃÜî/:ªð©uß~£ýÄ*AÖ~Ü+:£Ä_~î.:ã@¢_ÜýCªuãßäöaåU|©hÖäãÄOAåý~ÐßîÖð/:ÜuUß@îOvä>ßî@b_åýv£:Oovvå.ð_ÖÖ,ß:AvãCAazZ|äÄuü<>röðßÃÖöv*o£z~Aðð/zßãð_<ÜÃåhCî*£Aܪv>ýÄ@OüröߢZ,öar|*ÄUO/ýÄCߢã+ý@¢_üÜ/ðÐߣäĪÃo,@OBÃßZz@/ã@Z~Ã|hãüvaÖ.Oªvã@b,<ãz_ÖZ:ÐÃOuZA|ðî£hCbÐå£.o¢Bý@/üÜUCöýOÖã,C.oÜbÄÐãvâÃ,ý©ªrð,Cr:uUu:Að¢ðÐîzÖü*Äå*:îvÐßßZ,v<*ßU+ÐO©Oî_ª©ßu*üÐ+£a*îzªörðÐ.<öbÜ:vC<|ª|zhß*ÐÜBA.äbðÖUh:<©/@vðÜ:ª_î+ür>OÜBÄOBýäoBå*|.az_zß©ßCbZ,,+ÐOåÖbO+åh£|ö*>ßU/,ªrA~r,Ah|ÄbÄßzßÖU©Z*ßhr_åÃü+Ðð££ß:ãuoªuhüb|Ä_.©©,ÄOAå_£/BÃߢå>|Ä/ãÖråöãîª+zoã::Bbvvð£/öÃ@oC:o:Ãü<ßvÄ©<Ü/åZ:_u>ª£UÄ~¢u¢baîbÃÐã,ÐoÃ+ÄAOÖ:ª>ãb*ý/|Zääß|<@vüh,|ÐA<ª©h+Ovv¢¢äzðöäã/u~ßÃ|ªuaaÃOîð+výu*ýBðUZvauUðU_~/hÐhýð*ðý/h*@b,ÄU~zÄ¢äÐ@ýv_Ã*+ZÖbvbªÜZo|UUbZ@aÖªª+_@zbb:bÜ.îh¢,|ü>üv~¢bb+ãßoßÄ@öZb..oäoar¢_ýåv.¢å_*aAvî£*v<ªbrü,CzöbüBbOB/ovv,>ðãb:BÃÄÃÖzüOÐ.©*.îhuÄb.båuZbbB¢+üÜ|ÜaÜäÄ.£rÖaî+Ü/BÜ+hhßã:a|ä.£££Ãªuöäîz¢A:ßbä£býå@¢ö*vuãýÄzauaZÖý|b.Ã.î@ßhzÃ*Ðüßü~ýåAÃz/,,üo~Z.Aobbzª£z>¢CoOö_>UÐ_b£a.ÐzU£AZ:Öð>Öv_v©©rzU@vð_h<ãîÄ/bUÖAÖzÖbü¢AAäO©:©au~b*Ð,@CßÜCoO.ÐzåUýUßöðªuÃur<î:b_:bîĪCÄßÃbßÐß©Ü|åã¢>oüÖzCA~u'), (null), (null), (N'CýOÃ:v*Ð:Ä|~ÐCðÄ£~bß~,>zª~|_<,.ßßä©Ãªä:|ZÖÐvrÐ,î£_ÜÄrrZÖ>äBäÐßUbzÖÜå_ß©uCäO£åöªÃª¢~îOÐÖ~ã<@©ü:ü@:./ý~Ä©ðÖ|rr*vßrå+AüAb¢hBab+ýå:Üã@ZrOÖC._¢î@BÜð.b.Äa.©.B/ö,*r*ÃÄ<ßÐ>ZA+B¢~zCU,.AöZåoZurä.bßåÖªz~öý|@å>@ý>üvöãªCB_*.ð:_.UªäbUu<+aUÖoUãîo:ßî©*övAßöÄ*.r.C/ªZða.vÖa¢UÃB/äv£Oöh|äbZzãvZ@Cößã¢Ö©_ýhA_h©Ðêö+b:ÄuUv|~_aªOCüuå©:ã<ÃOУbîª/OzªÐåðub/Ð|~bOh_,üð~îÜbUÖ<ÃåÄbo+©h,r.åZrÐo<öåv.>brvbýA@/v*ý.u*++|rððßðh@©ÄãÖzC,ÃhbÜ/ZrÜChü@+b@ã|<äzZäübªßÐ:örÐÐh~>Ã:A©b.ããßB._ðåü|ðßArßOýo¢|Üãð/u+Ü|ã,@ßÜî:AoýrUß|ü£ßîB,Ã@<åA_£að,äAÖ+b~ACAhÖßaýö,Öräv¢zv.å*ð£ÜUU:BÜho@:@.¢Ãåü¢å>>ð©Ü/h©Ü_Ü*>Ä©,*ÜåZÄuäÜäZÄ<©ð:zßaä/ÄB<ãz:aª.oößÐu*BbzoU£hß>ЩaãB<|>äu©UzbývuU,Ä+îÖ/~*u<ãªß~zýB£:O@öª<ö@|BßazîA,ÜBCßð~UÖuB£U/Bözü+ãAÐ:BåüUå<|uhö~/ßrävÐäðÜÄ@ßÃb:o>bübý©zýUäÃÃÜOaüÄ©aZÐ:âüCöЪbvO/ZbooåªÖ>r¢.bOh~Ä|CAbo:A++BäĪ.Oª>U>CãßßbUß@ßv~ßü,AbðUCväAßßÜÖbåß:ß|ð©:äÖzüß*öuBÜzî*|+U+,ý¢BbýAzrðÃ,ªuOýãðv~,_+£Ö_©übvAvZö/~.Cî*b:ßÃoBßA©£ð@zãý@U/Z@A*v©_rO©ßªªÄAö@öÄ©<£Ð£Z:+_ö<üîzüß,ZÐohoüîhubAr<,*bß~ü©ß.bãzaUÐÄîv£î©£ßÜ~@>Ö~/u.ob~CîBÐao~å©*ãoÄO:*ß.zßÐ|Zub<îrýã/höêßß_£ÐbÜC:Ö+ß|hb/aävä~¢å©_U+îãîÃrA~£_UÖ~Äü/ä>ÐÃ*bî./Z©ãAOðåB<Ääv_bhÖý>|oUv|îhÖ,öäðZa:>.|r|<ª,©CýBoz/~ð+ª*uoaBöå/_öu|/äãb£~|:Aöߪo|ßý:ö+ö|Ä©r*.:v©Ab:/~~Uzvßý+î|.:|ä_håý~~ZýÐr¢ÐUhZÜýå+o~ý_©Oo+~£hUÜÜ_îCÜb>äC~ãbÃ|_äbC~@B.v|¢rß/uÄ*ªöäöÐUOaö.>Aao>ý¢£>@_~Щ,v+@~Ub£/uUCߪߢåC¢Cª+v.CuOÜÐrßArr~:åÃ:Ä*ä¢Üî,oAãå£.ö¢baýü,*bZîu/uî¢a+ÐrÃðßÖÐ@>Öbhöä|/bªC|<ðZB£bü.*Ã<_A>h/ÄAß*Z><£vð*b©ýhz@:åßîªvÖß*oßZ|C:ÄCÄbÜßvü:©ãÐÄîÖ+_hA~ªz_CÜb|ü*©*Äßî*_vB_ÄOð,UÖ_bå~ßvh__ä,ªªvÄUz£ÜzCðß~rb/ªz.Ãöv+ua©,@,OOvböðÃßã:äZªð£ªUZ,Öä|rho:*ubÃ~öC.Cð©Ö¢v,ªÜä|.++ТÜ+aÜ_£ýCå@ª:ÜhäðorßÄö>ÃB+Uß*ªÜBý@/ðuö*å>ö_åCÃöߢý¢uh|aÃvÃð/vä£_B.¢ð+u£ýã*zÜ.¢|//:O*ü_ö/@Щ_Aðª¢ZaÜÄba<,+£.ßUuZ£C>ýãÃZ||b|Üîßvh~äåZu/*aho|Ð:ýüÖ<ö£¢@ßCýÜ££b¢@|uC,*îbÄrÜîã<ÃU@U>CßZöh©¢ÜÐî_ªÜv.¢¢*ªb©bÃÜÖäÄÃ+:ÖU.oðßu¢b<Ö|ooo¢a£/ãbîîOãbh_rvüö/ZovO¢*¢.ýUhZBå_ªhäbU@,ã+rzä©Ã/ß>ßhåaî/.Zß:b£ÜîÐo¢öb/îÄîîzðüZ<öÄ~:£>üa_ÃÄ<Ü/bzO~zªÃbÐ*.ªBuüÃürh.ÜobU+öCZã~C*£ÄÜîýubA,ÐAãÄu+ü|*ãý:îß_ü>ý:>ß.,~£ß.AüÖUhBAbCU|h~oÐ>ÖhîÖåUö@Uª|~*£vb/üðªª~ã+åÜ.Äðãäzbî£/Öb@ßaUý__:Ð<ü<Ä¢UhîoZ_äCãu~.Öu@/aã**o|/|ÄhCbOßÃa>@@Ö<ª*ÖBü.<îh<ßZbv~zzh,äð/ýUbðÐä|@rî*/îÜ@.Ooü£|©ZßC|CÄO+Cå|o+@AA©ª*£Uîö¢,ßßîöuåvåzöZßOÖäzäß<åÐ/a,o>,zð..ã>OzðZ.îývZA|Öu>ä>z.C>Ö£,Ü_ßÐ@ööî|:zý/ðA:å<ª/,<£öý@ãªaZ+Ö_ðhÖ¢O>*+CýZî>/|ZüuahraZåäÐýC*îvb~:@ÜvßÄüvbv<*A@bZzAb*ª*ðäåÖ:>rarÐu*AðÜAh@AåCÐã|ãuðãAårÐüCªð.bv>bbbÖBÃ.ÜrAü+|£_@o|ÃA@hrß>Öö*îãä<ßÄB_A©ãbîöö~ð+ßÜÐÃ,r~Uüð|:ß,Cö:+.bý>ý|Ü:¢,.BöÜ~ÐZßA@.Cîî*AÃz*|hååÄ@@ÄZÖ*ã|a¢ZªýÄåbbzîööZoBoöå:BbU@ruUbAabÄÃãBZ¢ÐAü:v<ßýöÜu*¢hß<,:ö+Ü.Ü:ßAbvrvBrå>/îîýãª/_U:AÐ/äUuZ.hðãzv_£u,|ßéa¢voAýhb>~_,ãzb©ZBîvöAðÃvßýb*ðåßbÐß_b@äß©öBª.ÐÄZbå_¢b©~:êîuabÐ~ÄÐzB_|~ßUC¢aðzv|BÃü:.UÐ.o+ã>¢¢ß~r_îÃ.¢Ü_zÐ+üb~@+z*CzCZO:ýîöoÄbO¢zAß./ªo>ð/C©îÜ'), ('ã>Ov@<:î+:Ã@©ªãu|Ö£aÖCöÐO¢.Äo@|u|+*uîîBäªîbüð©ãzªåBhh*ãÄ_:BîbÖÖãî<özU¢*£©Ü/äbüß_ßBCv//br@£Ã:ßrßãhrb:Ä@bü|<<,ðü¢~£~Bö£>/>,Ðߢðîã<ö~Ðäî+ßZbhÐüöÄZ|aCßUBär©ß~büÄ/b©¢a/*UÜ©vÖßî@Ö<_Ã/U¢ßBª+B,bb*Zä~¢Bb*ðvüzU<_>vöÄî*A,_<ßu|A£züOÃzýîUZ/ÃC¢/<ö++~BBhÃhÐZðzCßä@zZöaC|h_ªA£vuu/üb@<äýð|OvAüAb~C@|Oß*<<ßßuA@b>.ð@äüUª*ý@,ÐÜÐB~B¢Ä££ö/>ÃåCo+ÃåBÜ<£åÃ+~üUBäüCö,©.üo.ý@ßåý/@.ð*zrU+,¢Ä¢>rB<+ªåÖBoOßÜ,@öz@ouaU*+rC~öÃÜuCüüÖu,ð:/ßraz¢/äýî|oªB:Уð>öî*ãüü_/ÜýAU~,bÐ.ßUaÐßU~bCª¢A_uBzåü_BýUbßO©ä'), (N'ýÜ_,Aö,ðÖo©ÜÜä+î.UÜððÃ/|£/|Or|h.ª,hßB£@vÐ.hßäzr,ÄåÜ.BbÐZ+üÖ¢.rÄrAvo.Ð_ßÜÖ>r_|¢Ãzro>*ÜÐZ_£ã*UÜbÄÃ:BÐä<>©ß*@:£@bßB/hßýO,CårvaÐ,C©vUüzÜ*ß.+üä@B./£*Äuã¢UÐ>büã©O>ð/uãO.|ÖaÜ¢Ð:AzäA>Ü¢©AovAa_huåA/ZvrAB~Ã:uîßÃorö*å~ßîvößoäb@rv<@|ýî~ÜZÐ@b*ÄbhuãzAäoU£bho*OÖ,uÄv¢ObobÖ|~î©öAÜ>*Crä>äÖuZU|@aã@ZÜýhA.ÃBBªz~~:ßBhU~ob|@Öã_,åߪ|ÐÐb¢åüåÐb©aCvovoß@o/U/Ã:ÖUUZ@aßZ>Aªä@ãðhU@@@b/u~~+ª,£oZzA¢å¢ÐªrbäÄ¢U~.£ü~AoÐîO+zA©Äh//©zÖvãåüZ/©Z:©+ßýýOУߢa|.äU~ªbåb£/bZ@z~ÖaZ¢@/:_a>A©_/ߢbzOåü¢,Ä+ÜußuZ_>êü¢@ý>Cö*Ub|,*©ãßaüz/ªC¢ªUÐr£ZÄü|ýð:oCbãbð£,zhü/~ü/Z|oUaãaðÖÖðzA_Ca./rÃÃühv@öÖz:vz£©ä/.,Ðð¢orZbC¢¢äOh~a,ZÖz/îÖbBÄ<<:Z£oBТÃ>ª_<©bhå*îCzÄZv,BBü>üå_:Ðߣãü:Ö<@î_ÜÜZ£,ÖäÐrªhÜhAvbýÖCÄ¢bbÐä/zðåh£ßßÜ>ªß<ªÖCo*ä~b>ßÃ.ÖÄ.rðÐÃ|ßö:öãbö+ü,|©u_h,ª:Ðroßð>u>,ð.ªãÜðv©£ZozvðubCUaou~aª<ý<,aAöÐ+©aö+_ßÖüå>B/hßbUU/+.£ððBvÐ+/<öhCOorh©ßßzýð~îÃ+b_BÖb£ä>BbUÜCð¢ßzýýÄBz¢ðª:ªb.Ä+a.î©ß*Äî>UÄbhåîÃîÃO¢ªîýUÖðooªbßb.ÄU+rUß<ªb@:.U@~îZa.üÐ*_Bî:Äz_zazuÄ/BÜðîO+rB>CÐãBv,ðüBBaß_äb~bßu,Ua¢a©AöAUãAo.©|rö¢äO©UAbbý||:*h|ýÄuBBß:u/åÐvbä.äzã¢/üAÐaý_üÃ<.ªðÄ>oÄ::BCO¢ÖÜ@ÖaOªÄu¢ÄÄ~öürC~äÖÖavß~~ÃÃ/åÐ>u*vö>u_ÜBÜOürýîuÖuz_v/åÐ>ÄO/@îv+årrÜîîOBªÜbübßÃý©ÜC|ðãöß>ýã|bboBb|._Ö*Aü~zªZäªr,OaãAr/oÃzU><ãoböîÃÖb+î*öbOãÐðÃ*îÜ<+buhî£.Ðu>ä|C/u©,oãhaZÃåöaª/Ö£î~Ä,ßAÐÖÜB©£©ãb@b/@vZob¢:b,*rîbüýª~väÖ¢rö¢.Ö<,£äß/üOð<*Ð_bðÄ©,|åAÄ£bUߣzßZ*©ÜZhb:__Üöåb@vãÐßßî||b_ÄÜÐ~ªýß©,¢h©üUðävhäßöo©Cß.bä>åÖߪU~,*åð|ýZ>/,ªå>åü£/Äv~_C¢ÜOðöo@å+bЩ|_.rZß©ÃuÖr_~ý@U*b*©AvÐBÖ£bCü_A_oãz/ur.<ðäåå|©*ö£U_vÐb¢ZßZ:©Ö_ÄÄÄÃ+ЩBaCÃäÐO,ã|BZB<ÄýÜßCuA¢öÖÐÐ,hOoåZªZ|U/~åz/îüÖ+,©býÄðåU@¢uýABÃBob¢Öü,Ävb|ÃäO_CÐü<Ä<ßåüªbbîÄ:©ÜªBßZ_~Oß.:,BäÃOh¢,@A~,uZZBa©ð>ýã/ÜbÜ,u~hߣZA/ÜBðåðv*ö£rrå@a/~@åð:_Ãbª/Ö.ß+uðbOå@ýbÜau£îÜ~ååäuo~vÖ,~åBa*:>ÖåÄߣð@Ð_åO£ÜöoĪa/üÖZä*Bz+vÖOUÐÄB_åÃÜuO@ªövÃðßC,/üãÃaÜhh>ÃZ@ðªîzä,£A£bÄOÜãa_ß~,ÖßAüö/£:ßCbbbu,OÄÃ_ЪäBÖ,v£îoÖ¢+ðz_Ðî¢üårößî~a£ü.©ZäUãßîÃvª©ßÖvb@ÄCÖéZBÄ©_©AOO,£Ã>@<ÜBb@¢A£aZB:©Ö.äååvÐ,rh~zhä>BuACUܪ֪Aub¢©B.|býZßz>Ö.Ühv¢_Ü,Ü__ßvýOîh£vã©rBÄBÖAUh~ÄÜÐZÄ>¢*hbvãZBCZh~åBhhA©Br©/oå@_UOãÜbüZÄvß@r~ßîaªßª:+b:|Ðbr>ãrOv~ЪCU+UoZoß*£ãbvZ£ß+vboOÖvAýÜßåb¢U¢ãrßÜU|:hruBîîýðOO,ßa@~/,ü*U.@ZÖÄ.uub@å~ßßðüü£,CaãªÃÃßuBvß/ßðzA£î<,@©Öã©zßAOª¢:ЪrU|î¢bðoCüZBB£>ßvb>UäÖv/<*|Ü|~ro_.*_ö<ÖÖý|üUOhB¢zö.ðð/Z_ßbÜ@î<:+oÐu©OC,u:ýbðßAU*uö<ªoZUCBßÖåÃuã@Cªb<î::r|O<ö*,ÖÖã:Züaãrå:ÖßubO*äz,ýh@Oýr:/ÖÃ+ÐßO|rBaU*Ö,ü£åU,ýuUª~ß_*rA~ÜCu_<+@<,uÐÖ*äoAO_býä.îÄoao|ßCo+o@UCBrî¢C/äov>îÐ.Ü+ßCbÐ+u@+ÖC:bÖO*BobÄ£ð£_ßA*ßr+C~öÜh>ýZÖuzßýÐuö.©+Ä,örbUC~Ü|z:.Ãb@ªAß~zߢ*ob¢ß|_.¢zUýÃhÖ._aðuÖ:ßðCðu£î~bbåÖ¢ba¢ZAuhÄChÄ,+ã¢Z|.ªäå+o>î*î>AurBö_Ã.ðÐåa¢ÖÃÜ/_äßvZ_©ZåÐÄäC.Ãz©©åöª:ãou+ã@~Uh©,b+>BrÖÄ_ßbßü|ßzrÃöbßßßBA£bðÄoÄ£~AUÄuA/,ZÄruÜ|ö|,|ªðÖ_OZÖ>©,@:îbÜ@||,öªa.:bÖã@ÜåCbBA©OÃÃðbAzaa£o~b/Üoa.Cbv/Äbb|äÜOoaãb~<:O+_/ýäv@ýurßOZä<ðb_¢bA>z£_ßä¢*@@özü©äÄb.hrbä+b~îz|îAbä,h'), (0x878FABDD9DE03A221ED7C36A8309F81B39EC15FB3C12D30D864ABD06F3A869C4084A5DAAB5E56C1EE8CE0CE57D6FCD74FFBE92F03072A074BB9D575323342F756DFE6138AC4D655480F7136E06EE90167C49063416799496AAE9EF178D19FAB49E96787E0E95C7B2583D6F385E316ECC0D41D6D92DFB5FF369CB8DC35E4DC767FC5ECF6F761108E78154DCD8095B37787A220A4B422186A3378414420704530A76083C0061FE56FB39EF58D91F87E90D9414483C437B24DBD82C38F2FCC5DF7D00D161011F37167BCB0E1253C9AD84B09A07AEF3BC17C7FBE3602735C664FF730FDAD84D25E8EE5CFDCC703468D0122AA88757F517ECC1E90A651DBF0FE1B5670F9E43EED4368AB11851F5EFA79292124EFD8D3E0C095C2319EF43BFCA2E4D1C170825CA8C245671FCA5DCC5F6D14177D30A711254765A064120D4E5F3CBE7EA04D9D89F6CC88629A61B42662C962C47ADCBECBFBD3AC7A0AD1F886C4F707E31BEF2C11DF9A20B0A84476B3834F3D9ABF38C3727DE272CC91137F14D3F19DA369D10A83AD50F4E0BC0E13B75CF), (0xB945DD78C239565397C5F70BC1B1BDCA6B6D359B234B9FD5E43E2B66FCEBB6FA82CA370862A117FC46BD1074DD048C5A0316D00899F4486DA50794840DEF56AB0FFC88F779B468CA563854663B2BF7E0B1D163E51BAE608E81C9625A0C92EF56666565E07B95E04EAE06B2619FE2327A10B3D23B8C708F609CFA75AF520EBDC349FDFFD5C616651CF0143715FCFFEE9F97E84A59C0B3CAF6D50444801F31FC9F49EE17A2E25CB4F94EB64A77397A649C0BD51869C3630395320900C1D2E4FCBF1897CC0DE74CBD3A34510A0A6852BD5B9FA875491892DBE5EB826FD95CF2266AB98A5FA1AD57B4BF18DE357259F92CE04BA422296EB3A785BBE72165DCE4DD412A9F50DDF31BAD48F3B531395C698BF2558F8DB7D0FDFC06E3D9E5C6364FE33400F448BAA84FEC30F6D936B9816D29525C2E104D5626712DA34AFA1A35E712A3D2FC386820D14A06A25DC0F6C6428475AF936A073F96DDDA821B165D54D1FA0FC792E68535C0318AE309AAF9657B6660C6856AA27D0A643C1E5DE605BAEDB1D063B12E335CFF40EF61DF2435ECE47507B4B696CF675791BD2DAA66D7DA2CD0F658D996B34C3204C7457B409EE52F503AE8DE500457E1690B207105B1986814350E2EDC124EC1BB81B1CE8AEB17F2D7FE5A2CEFFBDCCC9E766F8A93DA2C522FDC670B8FB7523DEB2623CE5288577DF32D9907576C791858428F66A3C32DE0555E), (0x0B621FAC1D40C8D80D79161EF197654025FBC2634EB24C28EB9928F94379F3E8AAF9E7CA7A5A3A2CB1404AC87847B12CC79F2F63DD4A355915F6C08318CF9494862E74F8AF9BC6CBC196B20E6783B0A4E7FB31A44A900B60C38EB48399B613E2ABB6424AD3B97C2CD863A1469827F191461C9B1C9DF04AF622143421E643310B82CF62B14165D12D7F04CBE6EEC4C79C9D223C7D1AF744BB6C4C27BE855B46953296C4C8C44050E04B6E9D992463075E4C9884C306B3F08B8BA744F43D12A823BD36B358FFFFD75CD25C32AC5AAA970845C972EDD7838E7EA6393D1DFB5BA238C579DBEDB0AF5E4DC027F0AA814330E0103BAF74A0BB4B39A734B2C6C2BA6076B9F9E7E0CEA958956A252CB092E4FD62085C0DC0AC2E980A2EA2457BFC988A06C67AF1885C501166E219097A8E9BA7C33750BD65ACA0C98A60DCB22C63DD99D29A26E918F37505B84BA6DD92241D7C92FA8243ACDA245925B06627809EE403058036E067B18FCFC24A051A05C3376642601F31E09AECF875CCC3678D4D851A66A3D812EE3D14E06BB28062D50A546279FFE41F7EB2226A943E6A9BED274274C5EBB462EB2478054C3FC62D1989236B7861ED8D69659CB3806D7DAFD378F244700B9DEA56F1775487DFD33FECF5510A1BFF228C39B50B5F4F00E27DA7C832D34C81BD0DEC381587E9990589925CC78B1C7393D355650ABA003E9A550EFAADBEADFFF26A37431EE2E99BA3A0AF81CCF238576133345E7EE677030DAE9EBF78EFEB46DC936A5C53D955B1EAB9C26A0B7E71A81DB798798A4F810CF334356F442A23B4B468A53887DB0388DE8373C4230DF78E3CF5A2C05671BC8D125D691FA3E56CC0960EB5A3D9392041B3109B06DBBDE8E53CA7334F87625D42AB17262972E3E4F916B32E155854B503D4600D45D6B5B2557583E3FCB11D3833B072F7C113F6CFD02CA1F0278FD28DE8F2307A2655186CF565D0B4EE00E847F87BFA65E55DF3EFDD913C1834C58AC6A3F5FB0A80A311DD9706015C4242E1CF4359F7AC946DA88AFF409C9518FF3730DA0A11F804DEC755691CCDDF5B96AD9BB06DD5DBCDDE31354D700B40067CC598CED1813831E9CA6592A243779FC82F689301E5AB2A5B63FCD8DBAA94D3874FEC5735108A15756AC6A26F482A9ABA968540A2AC0496196D726E845F563E36920B5356206AB8A5531E971E09BA1338621E45255330DA4A563EC79D1C901514886BDD3CD7449A2BCC9B4F8E6D7810B25F3522411019E261310800E2A21A88C20883969DDDD6601D831958B7E14BDDDD2D143DE66DD3036F887C0BCF44B889B2138C85E9E272D589D505BDF7C02B80E52B22B48EDCA2543580261561CA91D9CB90A6A454C5F3FBBB3FB41068150BAE5DFB25A32203FBD570385069BB5C74BE442BF26719862C203726F84E2891EB1F7578B765A4EDB7C795D1331C748A405FCAF6CC3C23A394D6CF056CFB0BACADDF4C31F442A40E1957742AD2485210ABADE5998432C5AFFBD1E3E1959E80BBBCE92454CF4395FEBABCDC74C7F9D14C83BF5ABE1672277B199D35225FC3787AD6B96DE924FE406817E7DEC75550E70200975DD644C2A449C1A93A320D729EF643619E0E8BE727857FF2A72E936025C9B63322C866A236141424287BC30D5AA448E884F4B2D876186FD757511B75B56183717CDA50D690A12A89F967BFACC1719802E6ABDB3017DDBC0A598E4BE5F99F6EC7F752917F547257E3C928DF0F58C216E5B9188F0985525A9F1E457D0155459059F8F8B46EE018AD7354F867EEFDACB19678652BE00F6441A4F8F2610FF5558D84988517600EA705A16B1CB58DEB6BA17293E689F019AF4A93B61076EEB69E7DFE6BE25677955188D1608A75F3AFB4B88D50EF7B0ECC9D6BE83B83AAFD3117EACC9EB721091529DC425EB88F8F3A57E30157E99DC7226E31CD776D3C11A78AA0499FA854F892AF77271239B0140DDCADE49FA8A6477923AA30855392A7ECCB9BD41845EF9102EB6EA77176B4E9BE1DC09BC05872FEE358D07CFE24733E1DD03A479EDBFCC8EC1CE1B439FED6036FC0716793F6E794599CF1C0757293DE78308AA13B6C4BE321F8AEA377BDC5E481CC0D3DB20BAB26E8A6EE01EA3B527A88023C097434C702758E469B48431D9BD70C3EA965552C6C8563B9957E49F8E5A5341B7481BB704C040BC723C50FDEA4885229DDFDA91532D6CF84107B32832C9560F51428A8191B9CF1A4598E08A77584140C2B1F1BE8FC1EE89DB1375FD0D2879B8D6419CA7CE0390D410B05BBA4CE280E8B6725580C7A78F9F53F0A67E43C20D1D1F27A435CBA972CF211D9DCF76344CF8928D369AD2F8F12EB1FD53DD5D12904EB33E9B153E5B2D1D0F965FAA19C0291FB3ADEBB69B724A26367573CE5595620E8D5F1C379927CA4760298B4CA94714E1D43429AF36D9B330E474EEB8D76EC76A24411CBAB3E1868BE3945671E70D8CEF6091FA117BC2D7B3ABDB532449017FF1622118582A5A2DE2BD9DBB92733149D6F7FF583574A5EE5179691EE89E6242D224651FC5E524C506641763EE0735306A817C3C49A93A8CBC32C6EEB13B45444B4AD97E1E2173E1C33A51D16D32004A3428B45722360938E9D853932E4603CB1EC318932DC722390D8A691F57692F8A227CAA8886EE221541A08435DDE0C37D2686B29A196D1C7D067B4997CCE9D180B8D970A1AB7B3430A0F3518D32FC6B2CB6FBE8C0B68560B5503D820B948A5857DF037CF46021D1BB4281F9161B9F3A0A102CD0D10100DA3378BB516DE9389C16AAF9AE2F7F66BC952A3D7E248C4A99B0F377FB77A98756CE39498BB4D063C219F5E27B11F11A9AA9603BA6C382A5A72E11906A714D146D13A2DFF635DB07C4B66B643EA9CF87CFE8ED42076DD0834B93A25D933FF950DCD175577F112454CE6876E0682E66FD5E99C081840B0CFF331F9452938D6494CD1A976D247808AEC48873AEF6E02B2D2CA50F096F77DCD1C486145F7CC1C14103E2234D8709C8E68111BCFB876DF842F47735EE8E6B25554DC598AE53A92202C722AB14CCDD9622DC18784DBAD14A668DD16B058BD2C298BCDE0FC1712A92E7EFBA3464C2D38616D1031265F2D79A6C7B2210724E2C76E4500257FEDDC4B1A175906E009CD593AA4B442488C06CA5E53393464F1A1099C3335004C08B87490C5160F0627999CF958E6636F9F7FE13F36C62CB3A7E729754F69ADD4CC0D32EB40B28276F6C337B99C3A0B0A3E99FDB353C115418CC1E8DEEC99B6BDECC82C4BB3772FEDFD6A48728F72166CDB1E37B56BF9800BF8F15E7EC9A3895D0C79CDD40EC057C66A10B6E979A3B21AAB7B02CE610151F3472152C218B02459E0EA6515A4415E1BC7704A5B429792553F44D34DA1BBFB0B28DA8DEC6D94ADBAEC5D088E3D9D75691CE706F0B6F6B0B08FFD83D4DCD6B825EE5AEDCAB472AE32C3906FE48F0317A2CE6A30B9B40B543229DD5C6F11D9DD15A5E39FE2B0ABB5AA38D42D2686CC208CE5E10672A6FE70E305BBA0D7163F20EAB2593EAC6335F222B58681E0DD2EAB5DBCD08930D36B6FA773BCDDF50BDD94F9B343732C8D7428B0EFE3BC207D8F05D60F431B45B5F01746EA9739A758FD17D7F2872C9ABB7ECF47A7D841EFAF4F2AE3B606E5C8C24E43C32B2C41F63B8158F2CBE42DF5626B1B9173D39EDCAE27979B6C55F052174F15A443686E8E3CD90C26804F24CA2135804BEA5454EFAF67150495A68AE59006DA7BCF89B1FAFC8D549AC6775C5F02CC7A37D5A567C3FA26F4DC5369F8964F26957A74A8FB9783864E5D00BA28370AB601C82C5210EA9E1780A995D5A69394BE4BA0E2E2EA5AD1E2B44E5709C340FDBCD19D672F6AFC15ABDB5D275102ADE0BBC9416F875528CCA7F7499EC292955340ABD903092B64544E8A36078C327FE0066E9C4081D07666A9D1BF38205D53184609E7A628AAD69064ED20FD1F213F7577689853F654D26F35725A376B2B33F1361EC0824BD9B75C970CDC93B0784787914AC1B7C50022F1377771B54F9F2438BA2EC60160BD2A9DB03CBCE9773FBFBC2BD2A6216A7B2C36FBCF4BD367020CF8E7A3D881B24627D41F230689433879F7B8B48A7CF903CE3E028F0591715635AE2FC301D4663D0AE5ABD1014674A3F2C355531BB3778FFFE4D49A7F22409562C8ED58598036A5917AAAA4D1270188CA5F9C423C1E3B82379FC41D00CCBEE8A4156E39581C49728CAFC2A008D2BED7E24BD01F85FE59448C6B20BABC18A5C5BCC2FFBCB8C830AD152AB58C5C9B7964E1EC3BB4FC9E62A6BC2AACEDFB8FB6730AFCE346D3021F191B220A5B48CCE8F1F1BCD8CFDDF1C81E5F59FF8E1C43B1867342825FB73390DFCD2198D994075EEF41BBFC3FB6E6951933C5E77A0290FDD87184E7064A8939BD2BF902BC58EF8958FA104C614672CF8DAC692BF24B16DD3C23C0670F1F57A5B8823E13BDE4D8C0443B8E7FF2439C91FFB55A59E05D4672141BC59997877939A36A94DF085E11A8D3A8E7B6BC97EBF8872E685AC4FEC45A3BCCFEA11E3F29BCC155DB87AFBD89A0A3B18638768FB57D30CC12691E1F74A5A539A33C606F8A947F2AF567BB6349C9A5C8B612788CE4AB168171512DBF9DA2E136E175194C3F3427F1B94C9A4DC1CC8348C35668612C1955F825DEFE3866BF8C52858481D4AF588882EB86D29810C9C0A4CEE5FB473A7F0AC72021276136EE8BFABF48C73C4AAF986BCDE576A647BDE75C1E5A6A81C34518067AB9B38E31274CFCFAD8D8C80183591F4C907954096380623ACB42DB840A367930C1C191FB0A3AA69979AC6FE41E5B9A004A3533CBC3FC1739505365E47078F0A15F983FC2C8244156D3BA90B7117E1B70A7DA39D503AE6CC4AA57AAB6D4C12900BBCD85851BD83826F3DCF8086C6027D237F53C953F1B9EB12C7A1870798B8111918FFB44F99654CFA212E126B56358492FD87EDE8594C1A02FD459A1C0C8AD685AE777DD65E3D9A1A16DF32C3977FBC822CE40A10CA38CFDCD5B14253CB30ED96579CBCDEB7AE44BFEDD3D17A19566B7D8917EF1870B5CB75B7A100ACFB365EE5E19C7C0AB2DDCA7EAF4A22E66745B38F45C4CAB341C52591D1472716ADA7C4A774EB987CDA60CAAB4D70792692D51E61ED8157267BABA41C66EA297BB6B3D0F7757B717BBD46A4D50A2F65C15BFF0F0C28B5292C40AE3BD9477C15F0374EF489AF71A11763A2B4A6DC721C4C35D2C077DB2D52F18AA4B6D74FA8243120B4ADCB3AEC21DA4DF7A885F0824FDE81FF9374BB9E1519FBF2FEFACAD9D7BB7E837627D4511159A0E629E384DCF10854D8454004BF75929F83DF37ED370F641FED077D0C27FA30DE49C3C56421852F01E695F29487B6BF1DE3884081E96C79E6C5D3A7C5840C3CEE0471BAEBA02E7E0EB025F6911CDF9826586F189FB9BEF4DD59EEAE5DED598DEA690480160BC36DB51A41D1B375E8D9E63), (0x4E3AD24557CDD91C180201156A80C28085F822A84F1637567DD41677104C8126BEC68F6CBD02A992E319C34FA208B0B69B0C186B956E8238027CC783B7620BCB), ('1f7a31bf-3955-4aff-8aa2-526b140ddf40'), ('6416-03-01 22:55:30.055'), ('1927-09-22 16:45:00'), ('10/31/2016 1:39:16 PMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/0010/31/2016 1:39:16 PMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/00'), ('07:09:35.0713400'), ('9787-11-17'), ('0341-02-07 07:17:21.4060236'), ('0904-05-22 12:00:53.5170304+00:00'))"; + break; + case 2: + $query = "INSERT INTO $tableName ([c1_int], [c2_tinyint], [c3_smallint], [c4_bigint], [c5_bit], [c6_float], [c7_real], [c8_decimal], [c9_numeric], [c10_money], [c11_smallmoney], [c12_char], [c13_varchar], [c14_varchar_max], [c15_nchar], [c16_nvarchar], [c17_nvarchar_max], [c18_text], [c19_ntext], [c20_binary], [c21_varbinary], [c22_varbinary_max], [c23_image], [c24_uniqueidentifier], [c25_datetime], [c26_smalldatetime], [c28_xml], [c29_time], [c30_date], [c31_datetime2], [c32_datetimeoffset]) VALUES ((1), (145), (24152), (9223372036854775807), (1), (1), (0), (0.7225), (0), (0.0540), (null), ('<*<ãÖ<ö+AÐ_rßäAzAh@bz_ÖßÄ_büAb£b'), ('bh£o.Ößã,|O>ãrÜrüÄä£ßßzÜu.ü*üb<î@uöo,ýB*@Ã,U@buÜUä©+<£ßvßäöýß<åZBZü¢Uªßýª@hh/bvoOrbB.B/ä/©+_AC|bßborb¢@©bÃÜö@ÃãÖªÜߪ.ÜåaåCOªUZö>übz*îbB~Ã/AÐ*<*Öߢðvzü©AOh*ö/ð/ÜÐvý:+>ã|ÃuîüÖoÃ.ß/Ü¢+Ãoa/ZhÖÄhhÜavab>î,zÜ,~bbÃZA<öoýhß.ACüab*Bã_Bhü+h:ýÃ~>Oý_*zÄ|hªvÜ@B¢zÐßÃ>/üvãZOý_üO/Üðå©ðß+BraÖäýßî~ãåb/¢ZOh@îhUhzOªöO@ã¢/Ã>+Ð<<ÃCZA.¢h©îÜß<ÐÖhA©BöîãhðßZbö.O|bîßÐ:.ªBä_o@Ão,ABäZ©ßUÜ~¢|r@Ö*©Ö<+Ðî£aZÖ/~U/Ð*:Ö/UöBC_ÐßCUBîrB+@ä/A*:<.b|_uUa+äZB:b>.~¢ö¢öß.ð.|zrÖ|ZZCzöää_~Z>ßÖ,ßßÖaäCZßBÄ>ÃaooýîAUß~ýýhh£_AA£hhAahªßz+£U/©>¢©+ÖîböU,ubÃßZBb<ÐCzãoî|ßÃ*ßuzb<ßU©ÜýßBÃbäªÜ+ö:bÜr@Üz*©<ÜßörÄoabh¢å_£*Bâ:vü|hOäUZaAßZo<ªOýoäåüåã|¢Öbî//BãoäbÃð£¢Bü/hýUä:/ö:*ðãÐ>.ha@/ß*ä~ðühz.îv+|Öî_ÖãZÜz£öüBoa/+©_îCrz£||bZÄhaboü,bßö£ZÄÖBh,å>ÖöÄöÐ++U*:výOßabO¢îßCßöª/aUr,Bov©bZ*aOZÃßÐA¢|ü<@ÄÃð@©ba*ua,Özb:|Ð@Ão©ßªÄ**î£~|£äß*_©+AA£ðoUbýrÃbbo.£Ob£rÄ.o*o+ÜÃ+_üý@ßOÄ>bU>|_ÄC©ã~.oý©ÄÄzööäÄ<~.|Ä:UÃ_výÃohßh©OÄA©zÜ,@,åUZOäuãÜ~ÃBýßväüZZ.<ß@å|©ÖUßAhßab*~ý.+/Öã.~hb©+/OÄA>üA|++Ö_BýaÖ/åbö>Ãå~öä©£/öÖ>ý.ߣ*CzAaßu¢£ß*ÜߣhUýÐåÖzCb¢z.C.¢U_Äo,/Z~AðÄ@U@b*rAÃТ©ßa,Z£ª:uä©ößovbOüC.~*ªCÖvOBAuvîzzA£u|ãåz,|öß|<*ßvab|zA*rå¢a<@.aªÖ£¢ß~zÖü©vßÜaü£¢>ð¢,Uzo+ýC*öh,îÐzZÃUÃAÄî:*ªýaäB*r£|ããÖ£ãbî~©uð/uUî£@zªð/,bßÄB¢BãÐÐCîÃ:ýb*:zOåbb<@uüßv./~/Ä¢öößÐ:ßÖð>ß@_ßðªOäZÖ|*ý*rä©v|zz|>ýßAC|Ää,CC|©ýÃhîÃr|Z©oZöª~äß_OªOUA|ýå<£h/,/r/ÃuO@+äCÜUßã@b_üäbãð@,.öhoau|.åZÖB@î+ÃZo*>.auÐ<ßðÃZ+|>ÃbZvA++£|,,_b/|£¢oÜ©ªAý.Ð/ÃrZåB@ÖU.<¢b£ößÃöA¢Ä£bUZbhªåå©bî|¢Ãh+©våÜãABA|@ããðBüÜAÜ£üýãüðä,Ð.Ä@AvÃ*vÖÖðßaov@¢Übü~BC_ãAO+ãzöð:zÃzA>|oªßraBü¢ßÄ*+oß/oZªýOu@ü:/ßý+Ä<üüßCAh,ÄbZ*©¢,ÜrB¢ð*Ðäuöðb..<|zßhzöü__z:zruv+u>:,bÄzbZ|ubZB.ZÐoÄ+ßhaöä*Ã:îßÄBýhß/r+Ö<©Ã©ÃUîu/îhªA_î_B<>_ÖAäh@ähBoZüB+.uÄC<*ÃüCU_Ör©~bªÄöÄãa:ß|oßBßbhðbu£Zr/¢hß~£Üz,ZO~a|~a._,ßî~z@~obBªÄüAvåOBßîv,©u£CBÐh/U,ä:äÜoAbhA¢b*_|bÃAß/rhÃîð+ßÐ.:üðã|,Ðåö.@ßÖäÐå:oÃbb.ÃzabuO|ð.*Z£ÃbÄUßhãOÖ¢zª:Zöa>rh©*Avªã@o|zaaO@Co©OO+_Uî©ba.ªöu|/Or£z£ßC/ZýZäТCB*CZßZãª//,O~/îrzÖ~ßüåß@åbÜb|üAð<åzvãöÖh*¢uîvª_ý,ÜüCoßou_ª.Ð@Üb<,:ÐÃC£,,a:<*£îUZ_ÜÃÜýðÜÃÐBÐu_a¢~~Ü@ßääåÖ,ªCÄzß~£*COÐbv<:ÃböAîoãýãîÜå.//Ãîö,,ßb+î@Bå.ßå>ZZbhßîäãuÜCå/bÄUðÄ@ãhåb££Äb@ßv/oö.<~*ZªßABh¢ÄoðäßäüÄzA+/r/@Cä+Aü*öða~Cî£BÄßAÐ<ö<ÜOÄöZÐäðbb+îß>ðÃbOvÖUîZÃözªªUzÃÖ>A*©£B©¢Baü@Üýä¢ßCü|OOuäîAýýCUÃÐ,¢/ÖhUAü@©©uðÜðü<üßC+C~Zß>Ü¢BÃ>ã*Uho~B>_býA@_ýðCCA_h/|+UAhö©>/åãoßåâÖ.+>Zb+BbÖß|©@bo*/ßîîC/oßb£Br+ÐBU@+£o©h>ýhý,hCßîã©ß,BßÄ£üO©U.UåÄAÄZho.ýÃvZîÖhbAÄuÖv__*a<ßÄÃýýîbÐvZ*/ß©Ö/ÃhCßåö@îoüa©ý+oÃÃã+:ÐaÃ,ro>ãĪå|ýäã.ur~ãrÜãAå/Öðh£ÖýzZÃÃ:ÖªÐ<©O|b<ÃC@Ö<>U@UöO©>ß.~ÄbäîuÃOoü<ªã,_ªvü/Ö£/,OUÐßbÖ@ßUßzåöCÄouýö*ßýå.CÐ+îÃbbÜo*å¢o/£:£Orß@>~>|ßOÖÄbªO+zÃz.ªBrÖ|ТuBýß*@âßBî¢hå+îåZbbÖÄUäÐzAbbabüÖüU:ß,.O,ü.v/bO_Urz:>©å@ãhBA<£_ÜAðåO¢îB>îäÃÜzý/©h@ßåêOýî*Bß|¢ýBräÄ:åöã£b:<ßBîZ/u@hðzÃÜöbÜ_BÜüÄ*+är.£©C,_<,a*a_Cüðbvª/Bvý*bOý©Oåß<~ð+.,ÐÖ£_ruAhAU/Cäî/ÐöÖö.Z¢ð,äZ>rå:ªÖ~_*@üåîAörAö~|*ü+Ö¢o/ýBCßUÃîÐãUª£©_z~ðÖbäî:bªýßZü_ãhß/*ª:rÃÐraZCö/Zîaa,:ý~z@|a_ã/,örýCßrzöå,uAäãª*hoÃðvüh,ouCßb/©äzßbBCã¢b~bhauüÐ<ðuå+h@Cýb¢ö|B@î:Ä+ÐAÜ@rZ|¢*rßCoO@£îß_zÄßÄBa@åbüboÃzåUÃÄ.aªß_oðoö:ÜA<ªbî.£ð*Ã>Ã.>£UAhßvöãð@ßö>O£ßöbbCa@>BÜðuz*aîzO*åîåahOßr_BvüîÜoZÐîððåzßü.ãßaÜAßv<ÃåäÖhö£UCOÄ¢>ÜOÖo|©ß@Üý£o,B|åvªÐ£CßåZ_~öv©ÖhC*îb£U¢>C:üðîu~Üäb,ä~üý,öZ<¢üÄ_äaä_ã>Að£©CªroîübößBrZî|h+_B*ßý@/îCîbÃÖvßoÐO<,Ürbz.©h¢*|Cz,<ööªäêoZbað,r|vA|ÄbÖ~zba,z+ß||ßÖZv*å~å@årUb|Ä,@o,:z,_/rr<~¢uCaz£OðuÃA~_ýå@*bC>,,üЪ©OB,bܪOãðZz<ö.+ÜoßCßîz@AbCBüOuU./©r£ÄAðbZövrAåÃ.rUðßrý,ã~aBߣîª@rCZörb+_ZßãÜä.Ovî+_¢©_ߣC+bÄöC.,*ÖýðªÖrhî,_,hªüoßãîv,ýäÃz£ßãa©ªO/<:B/v©oo,Ðvý:>_,îåCrCa+îZªöð,huß+üÃoåÖ|oÐCýv~ÄåoZüZ:BrC©ÐUÜu>>£<ß+@o*ö>aAbzªÐߣðb*ÖßBb.+ðöö/_£oУý~>îîbü:z:Üub/>aCOÄ@*ÃÜ©bäÃbÐ:У*hB,Aü~>ß:_Cý/bý>a,<:rzzßßäb.ðÄäÐhåîzBýh¢uÄåo£©£ßÃ|ÄbvOhßß~rC_båÖ©.ä_h©.Auãu>:hoorUÐ,aß:üÖB_@ßabhãh@UßB£ahÃã/ö£,£.Aðv+>ÐäöîßbhåUuÜB£z£ð+B¢Äu*üAaBÄåBÖbßß+.£Zðz~äv/ª©äýbý>Ãß©£v.îîåÃ+UÜ@oöZZða¢:ßAãüî+,oB©å¢bvohbýÖ,A£u¢>ð:Ä|ÄhýäUA£ßz@__Ð~Ã+h:åßhröUU.hßu<ýð©ª.@îÖßu@+Ü>rãzb_U*<|ð.@OÖ¢äåã|ä@¢åCOo<.£©vß/:/åuîroÃb~££,Ö<_îbüU*OCza:ã¢ÄªßîCvª+Ãß~ßUÖOuUðZ¢CÖäü,rðÃuhÖAüÄß>ÖÐ_ChBãBöÐä@ð*ðh|b|ã_üÄ<@.O>AðÜ@rO*Ã*b©åÖrãÜîrªÜuöZAð*<¢Z/~ÃüÐ,©Bzhö~Zß.vb£Ö~åÐÐ.ð>ýðAÖßß|îåÖýhߣUUh<*ãvî|<..OÜ:ýZãîý.Öb~*Ca,î£vðãC*¢~Ubbub+|+/¢ß<åuð>uðaOBÃAåß:aBãU*b:,åä_+©>/./AîCÃ*uЪüýÖbß_r¢,,ðö~:UöC*böäU_ÖÄUýüÃÖÃåB£+BÄZbz*ÖZB>:䪣o|ýoßÐÄ:ý,||uð¢ÄbäðboUãvÖ¢Cü:UU,,*_OÃÄZî©£Äð_ÜBã©,:ªð_<ðÐÐ/O¢ÖaÖCOoî./a*|A._|ðÖü@Zzbß©:ääª<üZCvî¢üß+ªr:u+BAîCö+ßý:©*:üö:ÐzAßübb/Ö>ðªC,+zäbÃÄ¢|ÐðU©üã:ö<£A*¢Zo£vzAªo¢aÜ©ªb+>+ZuãO~C|ZbuýßAv~ÜÖbhrß+©a,Cî£ýãZã>ýbßüß©@UåzÐr@*£ÖãZ.îAå~ÜBªoußÜCßüÃO£rr~Üa*Üܪä¢vãîo_îð:C>aäO@Z:Brðußoa_£Ð¢åÄCßOUýå,î¢~îAUbhO*,vÐå©|©¢ßCã+_ßvbÖýÃã¢r¢î|>£Ar~bå*Z**oã:U@¢oÜ|_bÖ¢ý@b<+Äo£ßzOð£/UAüAu>ðåî|/zabã*A.å.rba/üªoÃ*@vzåOðÖª@ävÃCª_AbÄCßZ¢öÖÄb:rö<~rvð¢åaÄÐÖu._hÄ|oCÖv*©oÜßßå+,Ãb*©U@vrvåbßAoîz<ÃCðb>Bßa£zAÃåÖZ£:+ÃßÐuh@Ã@öÐbzußÖåüC~rÐ+@a.åCß,hßoªßr@Ð<ü/+üobözbUðaÜobu¢*zÄßv,åCßöîÐ/~Uh@ooäÖO:bbßåå,+¢B+OäOa©ÄA>ä+CAª©©©äUaî,ähå£Ð<@ýÖ:zß+uÄbhährr_BªOýzÄz,ðU_>Bîßuu/öªÄ.|ßAüz~ªUzZßu*Ä¢,îýÖÜörªåßð>ßvÐvªßÄb.ö+.ÐßÃðuÄå~Bªã@öäö<*Ooo,bÜüªAO.£©u/|ªaýUZ+oî+.u/rzÖäuÄrßOa©AÄ*r@>ö/,.ü+ãürbßýUA©__,Ä:|.öa¢,~+ö|öo©//ýãAUüðåA©.ßðüý>oö>bð_<,ܪÜ>a©B£*ã¢ÃÄ@hÖ_©,Z¢ß:¢+<,aÃ~>å@B+zß©ßÐ_voOÜühoC_vBüÖ*ÖOuv>~BßaÐäz+UAÃÐrübuÄzÄZ@AzzB<ÜÖÜ¢h|.zh:|Zr|ªv:ýo_h,ÄÜÖ~>UýCÖ~|ö,ßä>aßß:C@ar£@oBC~ÜßýäªZz¢¢Öî.ÖüÐvOß.öý+ÖÃvrÜ_ðýBåaoßÖö@u~o.rb_ÄÜA>,*+Äoª/bZª,_ßâ©A,~Oýz©|ãß~hÃo|/Ðb|©Ðoã~+©©îãb,Ä~.>*rä>b©ßä,aZ,CAüßÐhööä_ýßz©ÖÐß.ä|Z©uuä~@aðZ<|bZ_åäU©~£<¢ßrbo,îbbüoÐb<ßÖðo¢öa|b:ÐACåä_ÖZðãA:aß.CBãu@.+rbbCz>öÃ:bÄÜzhvar|råßU/,ÐCÖ@ãO*|b,ãbãÖrU*U.üÐU>väB£ÃZ_|ö£Ã,rÖ:ävÐoÄözrO:*ö_|ä<©<£>©Ö_©U@ßå.h+a@î,hU~__ü£îO*+ýaBOAð|UÜBÐbîrh/ßbBz:£oÐrbðB_aä*zî_ßÜrB::UCZ.O©*._ãäBAî+ã,üöý<ÐÜU,Öý©*©ªö©åO_åzA/~ÄýOýUZaOü,uo:ý@+Aa:ÃÃbåuî:oÄßübö_.ÖÖ~Uh:ý>+v+ÜråÃoãZ~Ðî£CöbßCZ+azZ£AuÜÜÜåýÄrêåhuvA©CÜ,ß@B¢¢oz*ÃC+übho©î.b/ªAÄü_böªäUÄî|îã_Coh¢~©ab*£ßýb¢CUb+ßÖßhB|rÐ*_Üä*Bã+ð*ßhu/£AߪªBoÄOhbz£zÃo¢ãÜuö>ã¢O<ãö¢Ozhý,î¢O:@/z¢+¢ßA:@ÃÜÄü,a>hOO/CUrBýãðzv/büoz+îzhrßoa*vä<*ÜýîÖ/aA,oC_+ßåÄObªß|©aBoaü+vCîðu@>o*,©£öhðrßÜÜ/ö:ãv©bð©ÖåÐÖ:©ÖvUOZãZÄ+ß/üä/Ößz,u|.ßZ£vOªß.:£ðOZ,©öª>öhuBaäÄr>ðö~*@îUöüªðCUÜ|bBäÄîZ.OÐvß|ýBî<åZ.vb/Ã*Ã,Ä©öoä+ð©:ãbä:u@brÄß+hh~ãbäB>>¢._A_ªÖU|/:¢z£b.aäoÜýrü_zU|BBCýv:oã/_ãð£Öß©Z+Ðß>_/býðÄ>.:ýÄZA©h:/OOoߢäoö_Ao|Ão~/b|Ãbý+Щ:ý|h¢ªBÃräO|©Ãð|åb,ÃzãÖßCäüB:,/ß<>,¢zazðð>+ãýAÜ.£hoöüA*ªUÐAÜ£ýUß:+boZZuåÐ:Öã>ðãbb|:Zr<ä/hÜ+~ý|Zðu_,¢ö¢B*îZr@v@C*åöÃb|ö¢ü@©A_ö£åOoã¢ü_uC<uýÄÖ>uAU£ªöÖrÐößr©@ZªÄ,ý|BÄ_ý*ÃÐ.rUZîu*ývÜý~Uã,AaA>ývz+ö©/_|zð~b:AC/*.:vuãB/bBa+<ä_~urCrhz£<Ãß©*OîhuÄöÄ¢~rÖ/uðî|/ob<.ýäuðîZaÖüª:oÜuhüߣ_oðaa<Ãýr.Bb_ÐrðrAîZߣÃ䪢zv:ÄÖ~£__Z>ýãÜuîb¢£ðbÄöãABb>ãå>b..o/|@£@/aOð:rrCbå|brÃ|ªzª©©@héß:ª:¢ß+~üh@b_A.ßîö/öz:ãÐã|Cöãýavz_Ca¢Ö@U_ýBbo>bvOäÖ|ÐÐ*+ªäªbÃ.ÐühuÖað.Oh:o/**Ö|*@äÜýU:|ªOÖ.Üh<~CvCööÖb*ß©¢C|zaaäzv|ã£ÐÐÄ©hßoa/ýüªZbuߪ~:@üz£zavOÐ_<åîÐ>_.uZ¢uOÜU¢oüaößAÄÃB*©/B.©ä£:<üBbåß_ãªzürzrbaoAUuö@Örß,ãBZã¢ÖªÐzZ@BBu/ü:,Äåa<+bU¢ª/@örîU>ü/_ÖÃu¢~åÜ@böAßüb,>ð++ÖuªahOu+bªãªUý/ÃÃ>U/~~|O©~ª_åß/*CªÃzoÃB:+_Äîu*ßã|,Äa©ðßo©.+~~Ä>£zC_a,ßbAå©özÜÜý>C/ÃOß@©Öz_å£b:ÐÖäh@/äâäãÖva.Cä@ðhüUäz_~_/bîöZ.~aĪ@ÜĪaü£|oo¢¢¢bîãÃCaÐßaªßvîbarüa/Ü<ÐÖã~zrä.~Ä,<Üåzoåß|ZZ<Ðåýýä¢Ã©b~o©r*ä~züzzð*UÐC~obBOä>OUAüª**UÄð¢ßZCÃýZZ@ªüü|,¢Uäv:£~îÄÃ>özîýý¢bªaÐ<:aîOÜßÃU@rÄ£**¢:*ÜÖ'), (N'îî,*,>b_î_ßbý¢/>Uä,å*ª:ãvý£Ü,ü|Ðh*>h*or,Bzb::z.åÐa@åü_BZ<_b,äZhðüBö©hZhB£ýÜa_ý,üªÖb,<ÃÖ¢uOÃßbß_ßoh<+,ÖÖ/ä.UýÖBÜ./|Üv,öC@üB¢u.ä~ý+Uz,ÃÐA+©/@¢:oa|:CuªÃzªßîåöªu~|aöå:ð/>©£.o:ÜbBuvuå~:Ðåzb©@<ßÜ/hBä@©|ÄbCü:ªr_åßÐß©Ã,*ýBvb~.vîaäåüA*î|/©|hÜ¢ah©ßoãÜ©hBAßCÜuªýzßuö~ÄU>_îO,aCu~,Bh.ßu:C+ÐÜðUuhzßÃU*|Ã///Z¢ðªvhüßuÐÃBrOb+B~äðzUzÜä|*ååAÄ©Äü@¢@_b~ßCA>oü:B~>CbzhÐÐßBðOAa,uÃ<ä~>vCOußz£ðãÄbrä:z+ß+ÜÄrã<:ã.ßÄCäªz,ðã>ãBßü.aª/öO+uo>ßh>/ý,*äß@AaÜÐaÜãð¢ß@Ä~ßZOub@©b~|£b<ßöö:hýZvö.uå.o*/¢*üb~ÄhßoZ*h<<:h©|öîýo©_.Zäîü+£*z¢örÃýîCßhZã£hß<öBuär::<©/Ãväuãß©ýßä_U:©£ãbãäãîU>,öåhÜhåo>_Uz¢v~z@o£*ööã|u++ªªã_/ÜubAÄb+B/CoA</,¢Öv©ßîÃühÖöüÐAa¢îÄßßüð_Öî©aBÖª>_bb|Aö>Ð@Ü|oÜ*ã©zýbªöÄ¢/Ãr_ÜCå~u_U.ð£<üÃ/üZb.ÜÜ.baÃCÄa_ß/©åß/Т¢O*¢@öðaäa,Oý/|Aî:CÄBO<__Ä~>ýªhUÃ*©äbov£ÖÃüÐO©|C++OÐoOª+¢Üö©ßuhUBCC¢üª>bªvZU¢ü.£.üU|ä£.,ßbîä£ýãåaüîC/ßÐßBUªhå@aÜ:Z<*Ã|oäÄÖßåÄ¢/¢//u©bvrªU::¢bU>ZbC.*@@O<ßA.©ýãC<ãüÐ:v*ÄobåbUB|ß>auöð*vö:+üBäå,/BUC,Ð|U.aßÜÜC+*++obv+~ur,©h@£vBÜ,ÜuðChäv+ÃvÖBª|+~.uZ:£.BÃ//U.bß+.a.*C.urZßî©Z>CÜBßöubßzÖ,CUÃТåvîð*Brruooaý©ÐÐßrz£hªC|ZªÃ©üao|>Ãð¢Ü,hA~å~ßbAß©a£zA,bUßa£*ÄCO.u£ðî©îýBarußä+ö.îî@å:CBB£|£©©A¢Ã|bÐzBÖ©ßhb.a.©|/||ߣ/.ä.Ößãðý>Co£ÄzhvBAhAbÐĪÜZÃbÃÃoöÐv©ã~U/*>ð,Ä@.¢ªCr:_©ª+Ãhßü@håZßürî/©ZÃäªß_o+ýB,ÃBðOöã@ªðåbO*hĪßbüߪ*ðß@Ã~î~êð|ßUßå>obü¢Ä/AУ~bÃBh£ßü.,ÄÃUUªAUvo£_åîÄ*îåäü£@ÖÜAaãå~__ýA>,o+å©ð*©îßr>ßäb|Uåê¢:ß*ýr.£Ã:uUÐ<ªª@bUZîBuäª.bãööZ£z:åö,Aå<@Äý<~öÜ+U>bo£,Ä@rðЪC|ÃÐoªöZ~©uܪv~üå~@/:£bü,üuãbªý_uðÜoî/ãrã/b<Özªü*:ã.üA_î>£Zz£ýð|/ä//rö¢O:*Äîb©¢ð**:Ü@~aÐå+å,£uA@>_AååOÖ.ã£ü£*£ããA+ýz_obääÄ_äbU|uzr._¢Ðbh~böäª,.U@b*vUÐü*rOUÃÄ+ÜäbvAuãAü.ý>Cvî~å,|*ÃãÜÖîouÖ£/*bßä/./AUCoåZ~~Ööß|CaCC+©öBZ+åýB,_bðÄvã@hãh:Oß_roor/O@/rö/O>ZhÃ+Cb>Ü>£A©öAýoýÃOå/îCO©|ðåCäývB+rýoÜzCZÖÄ@C|Ä~h¢©£©Ö~ªßýar+b~©O¢bCbÜ*ä¢ÐbßvßýÃbÖü©Bbä,üå*|UAîoÐ/r./~>,ZßaöÄß*aý*h¢Cî|hÖÄor:ܪªßåb䪪U>U~,zbî©o|z~ðîvbßåb£Ð/vö@O/CßÐ<..b£+__UbäAý©CrÃÄ_ãvý_ö_bý£åC£ßã:bîoäUð@v¢aßÃ:ªßZ@Īý:>å:_~,î£C:br_ªuAã:¢zý+_oã¢,ß~ªðOäa~aÐz©|¢£@|Ð>ðaªUÃUý©oÜäð~rZ+ã.ÜrZU.hU¢Z/öÃã.rOa.:ãbU,/ß+:>UCüvA*ߣ,åª.zU¢Ã|<ð:Ð.rîîaz_ãä<îhao¢Ða@U,Z£>zÐZÄU*ýöo<ü>aCªvßü@_|,Ã@vöü_,rãªOð|/v,ä@>_Ö©A©ª¢.u//ßBööbß/Z,<~ö¢+zB~oý/BýAa¢a<¢**ChÜ/ßbýª+>ü|hAößbÃ*@bUuýzßbðzb*ßöb*/OO|UBüß@<_äabãüßvãZåîßBaabZzhhªBÃ@¢äCB.b:Ð_ßöbä>B|_CÖ<@,B|UbÃ>,zðÜz|rB©O:r/Ovzbörßu~ª>*rauÜ~ã*.ö*räoÖZvýå+©_bzCÜ>zãåvßÄ:/B|ý*B*Bß<äb<îOî@uÄUßßoÃBýB_@@Ã|>/УÖZ©ßa~Ð~v.~Üh/Ahhã|ubãZßvhbU¢ßa|.BãßaOvß/_+O|©vÜöz£*ðb*ÐCv¢ävzZh©£+ÜBzÃýuªz|ß@U.îOÄrÃßhußu+bªOðßÃ.ý©å¢>ð:üzO>ýĪarübªb:å>Cüäü£.bÃ>å,_ª@vÄßÜÄ>üÖß_ÜA,uãrªüCoÜ£¢üß~v@ýBzb/ÄÃ+ßzÐ._,o*OªaßãZZ/./Ö¢Bßühr<ÖÄuâÃ_>.vuУ,zª:uB©A.h~ß:v~CZC//ßî©+uZ©BäaüÖßoCÐãã,>B:ö:u*bãaað>Örýª©uuð/~O,OãüvoäZ:Öð*+örhåUãBãB*vÐã,b¢ßÃãvåßB,üÐ_ðb_U>+ßr:_U£A¢©_ÖOO|>.ÖOB:o|ÜB~býuv¢A¢ho<~A@©£>özozoåbý_**oAOU:+ür©ß+A@CbaBî,U@:öuUªÜ.oîuÖZÃüîå:Ã:u+äÜzAzCð_>ý¢>hª_ZbCvüz>+Aª*ÐUBUýh¢¢Z/Ö~_¢üßU.ßÄ++,ª,~oUA,.v:ý,©/Ua>å@ZB_@ª©a@uüuîý,å@ä/ü+ªðA>C|UZ.a,zããbZbåü@U_h:A_ýaßî,ª@@ð,bb,b/ÐBu~îbozª<ý:£ßßzîÃua>ðB_/ðåC<ãÄO:,ob,äª>ªß>Or¢~ÜBÖU¢,<@@+ª£äÃzCÐ_*AU£ÖöAbÐ.Ã:ðzß*CAÄ~bßýå£ÄÜrÐßZÃÜ£åªzC*ßr|©bßb/Zä_~Z.h<_A,aboã*ðCaÃv/OaýÃî,_Cöb~v>+ruýv¢O*~öCv£,rÖöß,hä©_ªª>Üö.B*/ß©,hUuÜöÄo+ö¢,aaÐåUÖr*ý¢+uU.~BoÜa,ߣÖýð,Cbäb~ÖÜZöð£Öî.Aß>ÜÜaü,+ªaªöU~,vÐöå¢h>ðb¢<ü<£:.å¢+ýhýuð/ÐÄUbýß_Ä|©ðßAÜå*|Äo|ýðÄoªÄzåªuZ>A:å:uåbßövîý@¢äã<£~vb+/ßýB£Bz+/Ü~î/Cã+¢ÐAÄ£ýä>/ö©A.ÃAb.auo©*AB_ßöüvãbz|:b|hª_+/Ü.Ãö*vrÃö.vbaîZbÖÐCB|¢Ü¢/h*Oî+ß>äÐîð*or|ÖZ*:ßu||ß>,ä.Uäh¢b@OöAܪ~ßuvý+Ъ_~+Uv*ßOªÜ,/üübªåÜzv£aªÄ_Öåaav|/ÖÜzãî¢äZU*ªo£+¢¢Ð¢.ub<ü@ü©Ð_<ßOzuü©r£uÄvîaAz.:bOhUZ.å*,Zßßäuî*ã:hZöÃÄ.ü>îh*A:©B_~_,r@ß:î~+/ã+<+|O~oC@,>ÖZß>Ða*ähÄ*£+ö¢ö+ãAB*ýhh:ÜÜää>üArb£ðÄZ'), ('u>vCAßa¢|£ßva£ÐZ:ZzÄubChääÄAB¢ÖhZuÄÃ~ðîåßbUÜ©Ö>¢,Ð+Äzä.Ðoz.ZbB~/rBOßöAÐ_./ðOß+>C+B©+Ubã:ßü_U@¢ãÃ>ß|~|Ä©*aãzåðuðßãZðö:rOhUÖüý@ãªr£ßbCÖ@a/¢ÄB~ªzazÜ©aOr£.Zßý_*©zîý>,~hªa.*ªßACý|orð<¢.äOÐB.ÖåÖÃU£ßO~*@v©|îO©üZ©,îü.ÜîäUoäUäÄO/bÜ.bÖBãhü.rvðÐuru:/aäð+ð*ß~AÐB£~Cð++ÄäbBbbUzz|©ýßr|AÐzBUöãh¢CÄÄ>.Ã:ubBýC<Ã+ß@Z>uuãhC+ßÖßßB/åÄ/ý+,Üð¢C:ðÃr'), (null), (0x60476FFCA499BDDBA9CF815CB0FEB6FAAA4FC769CC408EAB832902E0BB655A552BF5B6B24DE9A4B5BAD9ABB5EC05E7D46A5D7739726A411FB9C4787B96DC2043742C31BA4704ACC0AA12AEF394D9BF7E412E755DEE21E2C1B396F98971281EDEB96841C0D42C8C66B1B68E60BB4E8BDF05FA3A6766C25452496F06B10B234F81F3D0392C97FEA914A20FAC38938206650B198476EEB677F713EF766425DA5B8D670C6CEA155E48065025C556161CBEC769A1A5F19FD8923D584219A88845EFC7B41ED186151B4FACD17D26C9F121E0F630AFFA833569EE8E792F92D2459F7D0B36FDA2F74B37B14E52F82021B2C94B37612277D94A6B924B30420DE5897C6731001A93F37FE9ABF8FDAC313C48CDDBB0E35A712227A4C1CA6B56C7082ACCC5D591EF21973658B878777FDB9E39550262675D012E0B44095B59C8872822A3CD31E75CAB59AC44798BA2F9ABA8C82391155364A1CDCA96C94CE6C53E6ED09056D4B1AAB6DDAAA9B623E3768C12996193363672D4BD01006750925E73E6050BBA11A3D7F61D6CB46BAAAD7DEA5309B7B3843207375EBB98D2B143664A4C36CF1DD7BC7A6FC26A75CA82072A1083151347DBABEEB4FED45B560A0445DA06691E73DD6013968E48F11ABC3DB45791884E9B2F1E6FA0481B1F02602464BD249BC418E8B63223027CB892BAD3F7C02004C482B6A9), (null), (0x0F), (0xC24110366AE333F521799B6FDA552B99B366DCE675235EE25B5FE2067BF1DC1D6A8C6FE1F2464DAF86DDD6478495EA2C8B0FF7801E97B59FE32DDA0A012D7A309C7D044EE549A76C192D60974D165EC675B57B6BF95CFFD2D6D0FEC46B43AD5963A5AA06909B4641688A67F0371D52CCCF14944BB10E363F7E3177154BE200D57F0634A76C5735DA6E39026FF50E9BB97E31F557AE61A7556F6A885E2431F68689917130E9AA6077DEBADD780BC74A6F96BE961AEDA8271E5EDF3801CFD7B63D437CE5649D6BD0D3D07D79F4842F49A72018C8659ADC99E16952D109725FA806049F348FE2E6D22AEDC249702E33992F9590E0B60E50A267E304FA4A99C66171D472F0E4FABAC53A469D78D89228B236B9A274E27FF1F8B3FCCDACDEEC87902761D89BBC43B434DBCAA66F70D8CAD4BA51C391F7517EF2E27A3CE82D0EE74EBF0D5076BA8DF6F3046D9918D88187DB32F8F18C28F698D5E3E5B94106CC07CCE258B0638754192D5BCF8C8AB8661960F260B6341C5B25C9747B93D4D3B4ED3766CC3580D12454DDDEC43059690E1C7DCC584FA616D3B08632E7EF0CC14559A7E25524EC30998FCD0CD855582BCC5F655E16087B644621931BAE4DE935471C996B887614EA304C32C981993D7D585B668789AEAB3CDE439B3391D0814BA698C4BCBBEDA2554B7B2EC9D5B1E2ACE415C352E661AB99715D8C45DAE0595FCAE723E9D581C26BB9113C0E80E1662C60EF4F7C0C2E6444ED2A4A5D605D7A6A22CEFEEE8EF9D762525899D5259C198FF760E4EB91DD529B82DEFCAA36640A5B96D1ECB1E2779D6617EC29B3948F1F5011BA65FF788ED9447B636CB0FD2C2BED4E3E3F53B067AD80C27ED3A4B39F07F2BFAB997CFF0AE307F8A7367F0AED69EBC13B655650CBA0A90DE53DFABB3491DC5C79F15193AFEE435B375B08312E75D514E8E37839B0A2F30BEF6E19CDE84CC316592391FC1758114C22FB18709878DF7068E5D25018A3ABD7FD46A340D57672EB97F1D70AE4D8FD90D22C16B5898273778FA965037A72FEB678B9FED0B4D076AC892DD8A6A0D48B8FE7417EEC8CF64D7BD32BB02C106E7125F320922ADA2DDB01B56A2C5CAACCD7BB1DD51B38F3122A816C83FC89204A9B1ABCB3B37F4261B5BA657D3621CAF1D00754F50E3A533831E1F610BE563052E16ACE119FF6195779BC2060D276DB08B77BB2F5342A3C60C78382D28931A35E8A129CCB53B851D9EDFC7C511AF265BA05ED5942A43A1EB62E6E4A1B7447CD4719C1D5C0D90FB5FE29D80737ADEA46D41EC7CC9BD760BA50F4E69DE56E3564A62F3438581CA5E1F6385A18CB32E608442775FDAD7A326FB90785CBF372D090F473600879B2EDB778E5D6627D47EE1D0EDD59BDF837B72CFCC47F5097D9ED8368C92458D1DD8F913ABE84C8A4CFF2711967BD16181398BCBC340CB4339D), ('99999999-9999-9999-9999-999999999999'), ('1930-05-27 03:16:08.180'), ('2079-06-06 23:59:00'), ('10/31/2016 1:39:16 PMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/0010/31/2016 1:39:16 PMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/01'), (null), ('0012-05-06'), ('2001-01-01 12:01:00.0000000'), ('0194-08-22 09:42:54.8280810+00:00'))"; + break; + case 3: + $query = "INSERT INTO $tableName ([c1_int], [c2_tinyint], [c3_smallint], [c4_bigint], [c5_bit], [c6_float], [c7_real], [c8_decimal], [c9_numeric], [c10_money], [c11_smallmoney], [c12_char], [c13_varchar], [c14_varchar_max], [c15_nchar], [c16_nvarchar], [c17_nvarchar_max], [c18_text], [c19_ntext], [c20_binary], [c21_varbinary], [c22_varbinary_max], [c23_image], [c24_uniqueidentifier], [c25_datetime], [c26_smalldatetime], [c28_xml], [c29_time], [c30_date], [c31_datetime2], [c32_datetimeoffset]) VALUES ((-1), (0), (8483), (761407419), (1), (0), (1), (0.4844), (0.0452), (0.7332), (-214748.3648), ('ã+å>h@ýð£ð|ß:.Oh|ß~|uÖ|rZäåÜb,ü|.rßÜ<Ðårܪäü/ðAÃäîO++Ðubß©rv¢uävöý,U¢.Ããð+Ü¢îªß+ãrîOOªO©ýÄýß@ªª|Ö~a/_Üb:u+:aü¢oråä:.z©b+ßÐvî/åzzÜuä*~,ßbh<öãhOÄ+_Üð£hOuB>£¢ß@oa*AhuÖÜã£@A.vãÄUu¢aî,©üÃO~ýÜãðÖa_ý<¢ßaöüªÃh/ªÖð.,u/aߢß+,+ö©ÜaaÄÖAäv,'), ('©bZÃ@|b/£ª,ª@ÖrîrBU:bvrªÃ:©~å£avßr*ÖzBäãZ_AO¢/rýãöbZäaO,äÃýbå>|ý~CßZ.<~BU/o_UAývu©Öð~Ð/ÜAüå£BÜößüAª@ªîª,,üA/ä£CãÄÐ'), ('£/äÃAv:~öý><+|u/>©zb+|ªÃað,ãbð,ðÖA*¢Ðß|¢hß/ý|ü>Bî.rb@C,bßOÃCî¢@a¢|Ä*u¢Ä©BÄö|h¢hA:Zö£Ðz.£©Uß|h:Ð@Z.+aUoävÄ|ößoßöOA£Ã¢©äZZhbÃýßh@©ü/vÐvCÜZ/©öO+ª>ãZ¢@@ÜBä/Bbär<å<|AZãÐ_uðîä.OaðCð|~ãÃO£aîå~ä¢Ov~ß|r,hbÖÖZbĪ£+ðã@ýhz¢¢Ovða,üoêУZ~£ß_üãßã|¢>A,_üÐ+£böüO,ð:hÄܪª<üö*ßvbüaZ@ßb|Üî¢äa/*ö©Ä*.UåbãhaUöh@bAÖÃÃ,¢Ö/OBßh|@äÜov@ZUa,aOåOh>_C.Uß~B*Ðö*ðvoZ:Ð_zZUbãuãA+©@@:ªð£ý/åÖðÖ:/zO,üãB~:+åäU<:ÜAý|Щu/åz+_zAãß,_ߣ+:ãäOvbbo~ÖÃo_£äÜ,aÜrîZb¢zÜ|¢~>z/ßb*rC+<~ovz|©+Ü,ýaý_b:übÐÃUC/azb*+öüä/äouZð>+ßb~©äýäCrß|ªhZöÐ._öÃBzO|ß_üÜAr~|<Ãö£Ã<|A<üC~.,ÐCî/ãÜüßv<äAä*ABbýuýC:*zböüðuCOªh/ßãä¢,ߪ©.<Ü£ªua,îh+.vvܪ+åßA~oZUå/@Ou:¢/,a~bUO@ÜOÄßh:@öAßuîbö_bBÐðUahvýCüOh.ß.ßÄa£oABÄÜ|zÄ+zoOzöü<+zð@£îÐÃov+_r.:rbz,AaaoÄÃ/ðÃüßäO:*b<Ü@avz.|>Oß@üåöhý~ö<*oußrüAÐ,.Obä+ü:_zCĪ:©_îðößa£ä¢@åÄz|ÃßZvÃOBýÄ£¢î@ªÃvAü:|:h©üU¢Öo£Üü¢ðoÄaÃzrÃ+.vüãäbbA|/öãABb¢,©åZa__brå©b>~ÄÖÖObäÃC.~©hb*AÜîb£,z©*.*åÖð£ü,A|üÄObãbröUUz¢å:OA/üª.Bvb/+ãoCÖ>/O£~C£ãÄbA::b.aÜ/ÄöOð|bÄä,ª.äb@ßu£@CÖ*o,zåüÜî/AßåãoOßýO<©ßräb.©öãZ.>AuÖb|~äbªzß:*ß@AðzýU:A<ðCzzîraö¢A_Ü£Bb£UCCå*aÜ@Uî£A@ZoAaÜßüUvöã~,O/ßAäöã©ÖCzhCî+ßba~ý/*å@ÜåvC.üoZzüß+ÐuAÄOã_AÄä©î¢:OöUªöä_Zvý©ÐvÜüAãhBýbäýåߪßãßîu+@öÜubÄAöß/öbA<~ÖbÃa@ߢ,*ö,ß+bÄ@+ÜzuzaÐýhChO£îöã*AbÜBîÄ_å|:v©îÃåCð~vÄUUÖ*Äå,©:Ö:a_Oä.£ö.,AC+.,_Ä>a:Äîåü|roßb.årr/rOZC~a,,ßüvvÃ+äîÃÄ,OðÄ~ü<~ªü>öÖrߢð_ßC<ßvC/¢ðbUýüoîaüö:*:bý@.vaãubߣåßu,/ZoðÃÄ|OßhA+UÄöåß_|¢Ä|Ö¢Ä.ÜîböZÖ.ÃîßýAðÃîÃ,vÃåu<üäZbZoÖAðßbä©.ZvvAÜåßo~Ö|üßåã/oð.Ca©B*©ßv__*+äO>£h.U~Oåürã©*v.Ü>ðZ>Ð.@ßCÖAããÜ>~*v,|ß©ßðruA_+ArÄU*båäöãh,Z@,b_::@öBÐB@üßZ.>,z,äOßÖA*U£AßrvÃböÄBßßba.ö>¢Ð,uª:<:ãý/z|Z@COåðZ@ßãåå~zÃ|v,:U*CZüabª*Ü/ã¢oßZÄäh>©üßî>+ACßå~¢ýbrorooßzöÐ.huU.@,ä.uü~+*.<©a<|åäb©|ö¢B_ÄzoÄu.ÜUB¢¢.ao.a>äãßÃ@ßä.ä_b|Ä<åZ*Äîßåhð£r|.äoåé©bBßZãO@zz,åÄÃ.hÐCÃ<@r¢Äðo<ö.aUüã.î¢+Bý>@,>|ÖAö_oUCAOuo::,äh,UCZb/bZßÜߣhröCÄbüårößhårܪu*ý£Ö,<>îývAÐ..ýö/<ý/ä£:bzªß.ZbÃä_|£å~r/©.zÜzOÐÜ~UîÃßvÜ£Ã||/ÜÃbªîªOrãÜB+uAza|äCîªãuo..åªÖðö*aÜ£ýzÄäÐa_ðßh_<ÜöÖBã/©ãð:ðO@Ä~<ðãÜ+:.*Äãý.åbî:aåðC£ýãBð*öÐ_,_+a/baü,oA+¢AvãAßÜAaîz~ªðÃß*Z£,:ýå<£ÄîÖAö~vå|OÃ_Ü.*v_<|åo+£.ÖЪäý+ÄA|ßÜðã@,ä/ZvzO,~UAC©ã¢Oh:Aäo©C.ðb|¢ðü£/:abÃ:äb*r+o*ßåÃå/+©*îü+ÄÖA,OÜ~:¢¢¢©©ÖðÐZ+ãß@Ü~A.©O|ZZ@<©+ö.>î~£î_ÐrraC@¢,ýu*_Oü:*ßB,åz*Bra,ü*ßvau,BýaÐ_Z~_C*£uîb>._Äö,aßbîrý,©+¢ÐîÖ©Zã+ßh£+ßOß>öbå£Äö~bã,vðC@|ððO>ªÐãbý©uaÐßh£©Ãv£.î_ß:å|öÜÖÜ.ýªª¢üb©Üb/Aü:oBCh,U|böz_bäÜäðîzuåãahr@©ªA>~üå|,vÜ:ß.@u+Avb|BZßãOCßbªhüî¢Ä©_|,*©@<>BÜCß_oÃãÃß©ð.A£ßÄ,brb.hoBÜ©h+zîý>~AÄ+vöðuåý©zöÐöð@@vZ£ab£üÐÜ@_>,î©:ãaö/:/hýr/>äobÐuãߣÃã|üb.|O/Ã,ªÜ£>åðýbbãh©ß£oB|Äßz£ªUüªvbåaåUÐZßßÄr©oßuÜÄß|OÖzîza<¢,Ða@©åªåCbr~/+aß:åå|abåå://_ÐüÄåßBîbßr|Ü|îCÄ@uCßÖ>ªuÃhzz<Öü*O:ß+ß>uBýð_*©ÜãðåZð£b|îãäÄ*baß@*aäOß>uüÐvrÜüüv|îz./Oãzv¢_ü@CoobO.Ozß~A/©zO,äßöå~h/Ö¢,*@Ä~~U_Ää~BC~|ÜüÖ*vüÜä©ð.ߪBöüÖ.<ßb©¢uaßîö<¢vÖr,B¢.b<£ª<äÜoÖ£:ÜåßÄ©Ü>C*@*>bã,b£©ªrý*~©ðßrªßäbUh:b*¢©ßUb~ozabÄððu/@ýÐ_CÄaÐv£Üuîa©Ü/ãüCv|AöýC:,¢uä¢C,zÖîü¢¢ð_¢Z*UZ*vvUvvzU:Īhª|*©.ð¢Ü£+A@ÄA+OÐöТÐßCC*ý~*ßCåbzãAbªår,Ä>£ýUÜ_UðC@>üü.Ü:rz/*vö@<üOåýZ~ãÐ+îuOCå~<*/â,B*/U¢,~ßb/_C@Z~£U£_ÃÜ¢boªz*ÖüýäUîbäã<ÖÃrvöZ>Ãbª~ýßbßoð¢>vU©ZAãßb~Zu//ÐO@ü*.ßzª>|ÄÖÖhðbBü<,~rb,o/CUî.ßOov£~ãß@ßoÃÜCªZBÃh>OUüAoü/~oýÄbÃbÐ_ª<@*Uv:©uå:üßå*:C/r~rCC©hU£_BBaÃ,bâoßUðßZßv_<ßZ©UüUåhz<+ärý¢ð~häÜ~ÐOÄZzoZßðzãh©:+åãCÖßUÐuvzªUZåÐÃ/ÜåbBöü£Bª+.h_Ä_|vAÖaCö*ýü:üÄðýðr£.,Ü,Uðä>©uå*bЪbÄAãýÃZß|bh@aöoª/r@C*ÖoaBå@:Ð:©åÐ,£rüBröC~uZB/ä_>¢Cåã©uu|ýCCaª@ßÃBbbOîüCäö©@avÃüåÖÖU.ýbaßÖ.Cä/z_ª>aäzA¢+_aaîýÄuvzoUUãU/ÃAAZ/>äv:£hð@vß©ãh,Ð.üoAb_CßÄObÃ*bzßvÖräÃÖ~UäßÄa>@.C<_AÐäauî,b|Uª<ª:üý,Bö@b£.ðoZßCZOÜöußb~üv@Z>¢Oz©.Ovb@CzOö>,*öãöbvÜ,>£uß,,AC~£A:ßhrðr|:zÖhB:Ua::hîã©vz©~rðh©*UÐßÖO:B.Ü:ãåÐübZã_ýîîªÜOOu><¢Ðv/ßý@.ZÃb~*A+<ýß|+~Z+.hÖ/©ü¢~üö£Übo/BÐ:ÃaouhAã>U¢C_ýüzÄrî.@/Ð~Zü+uªb*/a£Ö~A*ö|¢/O:ro+/öö*ßüÜu<ã:OvÜßu.îrCîu,v,v+ÜBuZ,CªðZ£Ö_:u.ZÖªhÃÜãOß_ab:O|Ãö_ªýCU|bb©ã@~©+Öå>ö£ÃU~ªöð:Ö+boÖÐüßaäuvbr@bAð*ªCovoüUðaÄöabrßßÄý@BÜ¢å+î£rî:oo|©¢z*~bðO>ßübbãObU/ßb_ß|üUß,@Ü*>ã_.*:åÖOßroarr¢z<@zb¢Ã<>:,>,_,/ð©î:ª|U£|ÄüäßObߣ/b¢U,*ß>å£bZa+£.ßU*zÜaÖråÖ+©ß£Z,|ãö>Üo_*BüÐîo+|*zå/Z.,£ýh©u*ÄÐo/h¢¢ÐaußZãb_ra**¢+£bü_r,ßî*üZ>~<¢.ðoä.rÐvBC:+ä/üßz¢ýb©råöUãß©v>ßvªîßbo>rhðßä.ÜAö<+Oýå~.öObu¢~.baªzoÜö¢å¢ß.ãCå*Övbä~b,ÃAÖðb,<~ýaä©öÖBUBb,~üî@ß@+:öðåÜ<å>öÄCärÄhÃýã¢îuЩaüßO>/ß_ö.Ðð@£BU,ß:ß,hUä©/vî©O¢CÐZîðüv,boOo:<Ü¢AîªUBßîvåÄö@boåäÖܪrrÖovB.,©Oüß,îßuabö_*ãAAuAÖzîvz/©å~.ZÐzhÃ.Ubîî|¢UðäßßUU,OÄöU*b<,å|h@z.öZÜßãð~öh*ü*ðÄåCo*@ÄýuýÄÐÜ~/ßrýã@ªAZ/üAovªª:îä/AorãbzAo*b@ßA+.ß>Cß*êÃrz*/.£_ßä*_U¢@+ßO|äö*zÄî£@ßU£:>CÜZh*£Üã©+ÐBr>OåªbßUOÃCAAbZð*hBßÜ©ß/>ß/.z@îoÖu@.:£rrãrZ/£vBU+ä>@Uðz_ÃÜ.ߢ.ð©Üüvß~å<Ãöîý~+,ßrÄobªBrã_åoÜ/Äb*CbßýUª_+bzª,Ab,/<_äü©üÖ+/__~ÖãÐb+OO>>Ð>@Ãb/Z>ãß>@ÖzåãCÃoz<|Ðbü¢U~_aãäåðÐb+vª_<åªÐbbý@äuU@aOAOÜ/Ä:OÄüãü¢¢ãªã<ãb£ã~üýAî¢ÐÄZÖ*ãÄå|vö~o+ÖîÖÜ/:oîAÜ//,*:rÜ.ßß:aÃb¢ßðöb|_UðvBÃruª<<ãÃ_*î:+:*@_Ü+ðÖuÃh£@uä>uo@CUÜa_ß*+ª*oÐÐ*~>ÐAý>~+*:_BüüuýrZO,*C©züÐ:ýz/bö/ZðÐh:u©öÜîz>:ß,C¢Cä|*a<ã.bUb~Að,~ÃÃA>äÖb@:~r+ã@îbåÃZr,bZ<îÐ+üª,ÐüðîÜh*¢Ü,ßAî:U>||*ýÄ+£OOª,|ªC,Bîbãu/öÖÜÐUîð.*Oär/Oߢ¢Ã+*ÖÄOÖÜA©ýÄhãªabªß~v::ÐÜä._*oð~U£bãð>>ð~.ðBCÃîªu|orBZö>ýãvðrßÖCUÖÄ/|©ãbC/_<>zb|ÄBb©ÜߪO~rä~ÄÜßÃ>Cb<äå.¢äªh*,/Uü|:+a/_äoååü@U>üý©zOvO_:_uÜ:å©vßhöåAv.ßvüUå~ýîî+,£hÃbUýßAýãߣbý@¢bã|,<ĪäbuaZö:¢*/bU@ªÐîöBýv|a¢îU,üîb*ýîð|ßaaý@b_r:rýÖýa*ðªv<:Aä/*Öîü||a:OzöÜÐåüªðÐ+|.î@,ö|hÐÄ:>_ö~ÃuªCý£:Üß:AUªb£Ã|ÐÃZa/U_aý/vÐÐß/ãhOÖýßÐÄC£Bb*ÄöBBaåÜä©~vübBýuobb¢¢/:äîÄÖýüo,*OOZA*OÄãb~o~ðÜðÃÐ<öªa:ÐZ>urzhÜå>OðÜîßüåý*'), (N'bUäðCßbU@rßzÖ:a_Bü.ÄvÃÃ.ýýaåÜ~üUßäÃb¢zb_b@,v.¢A:ß/ßað@Z+~<öCÜo>ðU__îÜöîßåå£Üz.a,ü~B+ßö*v~z>o+üÜîAðåvrob¢B_îä@©>:AÐåbU¢*rvb_.@@za¢AuÖö|ýrÄöB.vðÄBßãv_örbå~©ýo¢©BªuåU<:Ð@>ÐÃ+z@ðö++/~ÃuÜb.ü*ov|ã~bã@O,Ãu©B*ßßvãÖ,£Ä¢ßrb/+:ãã@B|uðîBZ>aÖ~ÃCÜ>*/üß~rü_|ðA,ý.hÐ|ãÄ|_Bäîo_v+îhöÃ/ªbö>AUzCAÃýåÄzbäaAã.röU~b£bðª£/ý+ü,zru@ª./>/åA:rO>åBBvu©ã,/.r,_.Ua@ÖöÜ©Ü@UýÜ<ßÃAOãÖBÖzåBÐÐ<ãßC,AîBoä@Äv/ãB~äv:OaÃ,r+¢/£öC/auZãü,äüä+©ß@>~zv©ÖAßZ_:h/ða.>:uÖBÃACýCOaz~ã+'), (N'ÐßzhýrBªÐÄãÃ|<ã|,ð/b/ß_rZ_|a@ÄÄBZ|OuB+ö*ZZ~ÄoÖrððÜ:ðUCä:£bbaaÖ,aZªa,~.ö*_ð~/|ZO<_+_bArä>ßuz>u~äîb¢<_:aã@îå,b,.Z>*z£o~oöߣ@|+B:Cüb©,öߣa@@aOoßßC.ðãhîöÄ*åÃÃîð:>/<Ö/aÐA*©ÃZC£|ýÜüã.o/UZra+z>vCÖBbA~Ð..Ü,+ªo<ªßbÜîîÐb_Zboo_.©.|b_örb¢ýU+|baßãBã¢rz_~+.Ä|Üý/|äaBýß@£_,Ö/ߣ_Oý_>ubzðr+äýÄCu©Z£|Ã>_öaýz:zu:åÖðãuÄavÜ*uößÐCßß@ZÐ<ßuöA£A@@î¢aÄÖ>Cbåî_£Aär<|Ðrîo@öA>ýb@üߪ©@ÜäÐuUbUýÜö¢ÖB/ðA>>ðߢ*.ÃýrÜ/¢bbzåCva>uZ©üî.|*v.|h>b©>/ßÐa<+ßî~hî|~ðÜÄßU+b©~<üAÖÖîå*hÖ©îZ|åßa£ã|ÜbvÐUb*<|_..Ã+ßåîö+ßÃ:hÜÖãrCß/Äz>Ä|/ܪvªÖåh*,<+îzßߣä*,aßBðýß+Cz©Ö*~zÖ,hîÄ+ðZ+ðA*£BýߣÖhÖhªZÃöÄ,ÜßâCߪ~.©Ðhü:Ä/oå©hvC@aarßohb:öaüh<Ãzî_b@~hðªoZ/ohßZ|C£z©¢ðü/:*ußCýZUÖäýCBÖ_,B.A@Öýö£©<ä>hAÃý|¢bUðh,r:>bBö¢ä*aßArbÄCߪüÄã>¢vbðBåÖÜ¢¢©/îvÃð<_b/CöCßz@ä_ýðbß|ÄßuAoãÖC|,O,Üo//îC:©.+Ãou¢ªarßÄ~åäO<<åZÃZz~|ð:|+:Bbߪhh+hbß|UÐðÖâ@ðüüüAãÖ+bÜCußbU~BÄîýÖÄãz,bÐ:~.ßåzð£,>hbüãßb~Aãa>ýoßbÜ¢Ürh£~öBZÜÃüUðä/åBü©öhü£vZ|buß|ä+Aåäã+BOoUÄa¢v/|Bªöv©@£ðO*+Ð,vO+å,<@uaÄ©v/¢©:b@ß:ãÐîävOä,üÃ@ý,ßåb*Cußî*bîZaUåý¢O¢CUzO©å¢ÐªBöva_@£a~vöü.>~Ã/CU+Öã@AOÜbÜÄ¢C¢o,+o||ÐbåZð*U©ÐÖÖ@uÜ,,äU:ußÜ/åZöo*ßah.Cå,r<<ðoß@AzAr.*UÜ_BÐ*Ðü¢ýaýOîäÄ¢*,+.Oî,*v/zÐBäB|ßBA>A©Üh.~><ðýî©*ÄÃßAöbåhÜ:ð/u_hî/+ßãuªÃ¢rý¢/ð.Z@©..Ov@äAo*vuäÐOA*|@¢BßBBarßü::r+h.Öãhü£ð@ÜÃå*:Ö>ß~b,îÃ/ãZzObÃî~ÄCðb:ü*î,ðªCzhuÖ|:*oå+ã::ýð|ãß|uªOýÖ/+z_<ÃÄ£<öÐä<êCBöbý|ªr/>|b@Ãî*Öªãzß//@££@a,AÄ©Üã~Ö,@ªzuÜuBÜAßð:a_:ðbaÄu~Ã@CbîÜBb£Ð_*<@UÐÃßå@ßßBOOZAª.å>äa:zäߪCöh@bÜ~ÐaÃU©<@oðÖ,>özªÐ>ÃÖuÃzaO.ðBÄö+ZÜz¢:Z++Ö/ýÄbÃð+äv@r£ãZ_î.ý>ãÐ+ßu~<¢O*äz,hð*uýUzvbbßOÖÄ:<ÜÄbZä@abO<@uZO_/rß@îüZðo©rߣ|¢<äah.¢ßa_¢ðvb@ÐBüå|.ýðr|@>ßÐ,@~ý£roÜîªrZåýÃU//~Uîbh£|£<¢ðãð,åî_Ü<@båßB£ßÜ£*|ãu,uäU~h|ärîÃößåUýzü@b,.>@.v|büîîZ:,>ðÐ>UC.îU>*Ðu>>:ÄOBð+~Z_@ãåh~C,Ð<£UB~h/BZub>~h.|ãa|å,Z¢_Orý.Uv*CC¢Uªu,ä~Öý£C>ßö+:*z|~>+OaÄð,hAãaåü,öåßz:oýC,©>b,U¢öîüß_¢vb~@<£aä,ª,ü__©_h_böbB/ÖÃßußüÃ|/uAU_öUhzîB.öUZ_bäö*î¢r|hBÃZÃ/uîÄAöÖ>vC~å,ÜAüÃ<>.voða+©ßa>C/Uö:îÃOÄîz|bÜÐ,<@äo~:¢rî/UZå*+oÐaoÃzððå+Üý~Oär.r£îhöãð©ßbbA£.z+_oßbªAb_~üßß:bAbräBu:uråb>åvåîUü<¢AaAoßo~+|übCrÖaýßÜZbðzöðüCoß©ÃÐãzãAaabbö£b©Uãüvhvåb<©.ÄÄbBrÃýßÄåuuß,ÐýüÜÄ+/ã©ÄBýãA@Ü¢voðCzöðã,öä,Üa¢oî.vðZÖzüåA,aräüvöUübäv.Abðz/~:åÃ<ãö¢uä*_ãüuZ~î£_ü~:_b|Z¢aUä+/å./hÃ_+ð+Abð/rîbCv£ZBAzðoðb>|öÖAAbÃãAßßbåÃOä¢Öb~Cýü,BÐ+|ü+ðZª~/uÖ:uðÃüuvö,ßöovð@*bUö>£>*ª/Uv.@bOÜ¢öa+<ÄîUA<>Ã/.Ä:.ü_*<ÐBüå*UÄüå/z¢O|zðhä+*Ähböäo<ä|ãåßö/<+hÜ*UZbB*Cr:©ªåßAü:©h£Cb©r>CUß.aðäraCßßä<@AªßÖ+Уª>¢~hÃ+U,å,£ß+ÐOÐhîÄ,C©/BCýCööu>¢ðA_ð¢ýßäÜÐî/r©oz.b¢:Av>ãr<ЩüÃ.ðCÄ/ý:¢>~,ruÃÖOÃÐ|B¢~ýZ*ü>AªÖäððÖ+¢öhAUZîb.ßßü*hU_ÄzßÐ@ª@_aAÄvýäßbÃ_ÃCߪÖåå*Ã*_>hObuZßbzz*zã:<ÄÖÖã£rßß:CÖC~ðäOîOý@î_OÖ~aa,u+ßöovoC~ãÃ*Ã+Öö©ß_Üuv.ßîðBð©CuÃü|ª~bhvߣ¢©rð+Ä_+©oBA.*ÄäãZ>:o©ÃЪßrý>._|ÐCªªrä_r|~aöh©|råÐUäÜ+>üýÜBvC>:îzUå,*_/CbüÜð£B>ð:Ü~ååå/ýªö@*©å|ZðÐz,ão£O~~Ã*ã:£,ZOã*ð|A:ßîÜ,abB>ð+<ĪOB|u@UÐUÐÖ¢bîAýhrB¢uð|hîãußrÄoßÄ¢_å,@ýäCü¢ßOÖuv©¢ü£,Z:_||öð/+h¢¢uU>UZÐöh¢ü*B*:_ãhäU.äª~©:bvuãßîz>Ð>a+u+åA>ÜzC:rB/bZ>îuÖ¢Ããßu<Äzßbaª¢ü_>î>++,ßU|aåoßÖ>./Uüäz@/h/*OöUBãªhåª.ý_ä,ß/Zß+zå|z©ª+£Brü>+öAOåa:OvaöoB.î,ªbîuªßB:¢¢~@<öb©¢î£~ãrð.ã¢bZö.uUÃübAzÐå~ã~|U:öÄ*üv_OÜz|.h>.ýÄß@u.zß@îa*åAbÖU£ÃüîðÖ*©äb<,.©îã*îäAb*ãCCO/'), (' '), (N'~zÖ:@>bü<ã++ã:BUC>|COÄoZãäßÐ*.ÐrîÖßBî:*äãî~Uü>vÃboã:BA_åh:ª©Ä*£bBo:B£a+©oÄZvCð**~B£o|ZCäuðü:ã©h@v@hßAOAbßov.ÐUÖrCvBªÃ<@ßbªåÄAðß@|ßa¢ß@Z.b~+,AÄhüOÜz~~|ßßý*Ü:zzAå+ÖäöUh/ªüÃ_CCCÜ*<î_vªUðýür¢:ÖãbÖ_vO>ðå¢büU_Öîzä©öÜOð:arÃ_,ä@vuhbßböÐuZä.>ÜåÐ@Öb_vöãß:obü_ACßÖC<üä,C:©îß:©hOî©Ä.*¢zOrÄå<*ßä*åî>Äz~/bÃaähýBoBßu/üð~hA/hC©>@ÜßO<*v©ßäzu£Ä*ÜorB_ߣC+î/ZÖb_CÐrÃ*¢+¢ÖUoh/örau/¢îZ~~©<Ä.U@ÃUUu*Ã_bvÃ@*vîOhî¢|ý@::äou_o_r¢uBBbaðîbU©öüÐB|A©,_|BãUýUß,bCh,_bbvUoãOra|Zz~<ÄÖªOåÜa£_,ãBßr_ãüCZ/îÃãzåãrz|||ö/ßB¢<ðv¢@/_å.bAü©o~OAo|AðZzA|ÃbýãîÃABð,bãÃî>oöîßßU£.ü+îvubÃoªUbß*_b>,aäÖÜ_+*Ubäý,@uzA©A>ý.ßAur:~¢bh¢î//ß,î¢/a|AorÄÜbaÖÜ©@|>ýrã@~bÜÐoîUBüB/ðhbª>/,£ß_/,~åZ>C*ð/ª|,b+uãäUü¢ßüªß£¢ðbb¢~aýhÄrãä/hÖbÃã,ÖýUUª_,äî¢.üb©äOUäßa_.ð£AaýßãäÖZÖ:å£ÃãAÃv.+ÖzCÃzÃZaU£:ß>oorZÖCßA+äåßr_ß*A**@ÄOoÐüZzüävÖðhªz.:£/~/.åÜÖ©ªü,ãoö/¢CäOh>ý/zAãÐü£¢r.å,ðÜbZZ.üzÄ+ªACß@_>:rzh:hC+AbßaýÖüüÜA©|ß~ßoOZbÄaÐðaz,rC>ÄãrU¢ößЩ*ÜUrÐðuCbvo£<_ãÃ_üz.*roýrªähböÜvvªÐÜ¢ö::ÖªUäãbУ>Ü¢Oa.Ã@ªu_<©/ÄU|©ÄU@_Öª£_ÐÐüZoCåu£zz~Uäðro,/ýß*îýZo,>CüAa|>©ö|Zb.ª:Ü.öü/ã*z+,O£Ö.ãüaýÖ.BÃZzAÜrü©äZa.*|@bzÖ|hߪ£ãîÐvCªZB©O*BC¢ö©£,£>bou.ä*îÃuOUZB£>hAöãb~r+ra<,/,BîÜoB~©©z.ßêä<öbýhýbß<Ð_b,ü*åvö<îZ~uoãÃßb<@üu~AÖ+uhîå:CßA_ACr*oA*@bÃUbUîUö.:_r@BA@rªubö+,/hhª~ªÄZ<£Ä@+>züU©öb©vßaöbÄh~ßv~ÄZãðBzÃ*Ãhb~ß~Ãaå¢ý/azÄhzC©>î~ÐÃ,hßb£.äöüª+_rUr+.ÄUüßã|.~Īü©r/C/,r©Ü¢+>Öb:.öOðbðZbr*Üä_ª.<ößåZÜoUBãA|ªÜ*ÖrÜ.o:,ß_b+CuÜ©@©b+h/ÃåÜ©UÄBbA+Ãzä~|BC:üBovãð©ö<:z,>u¢ðb*ýÖîÐZÄ>Ä©ß+rB.|¢.bU/bãaZU£Ü©å<Ãö_uB,_uß<ÜCUä~v*îßäß~©£ZoÖ¢>£ðããrh/©äzoBovߣðªoÐüzäãa©Cvîöö£îÖh_öZbÐoª>ª©Ö£Zåý+|ªî@*býß_ahÜî+_O/Cvâ|:|,ãUOUaß.î~,bauß:ü<@ÄAß~UC|uOªzÖao*C@ßß~_rÖåzü>OOZßÐhAÐ_|UabÃܢߪã+î©Bz¢hîü>vöUv£,AîÜ~ªý/ß|UßÖåÖªöZ<¢ª@býr~UbUU¢aÖ/zÖÐaaU,<ä|bß,Auî*£Ü©båüî~ý*ðo~ðub*~aäðvuuC£_ð,Orã+ðýUB+/Üß:AðUZÖß+ðB¢hÖ£z@¢Ä©/O+äuuß.>£©ãßbzüýðCU©Cå@ä~©+/@h*vZ|öåOUA@+*ÄvUãb:©*ª>z~>@,Bß©bÐzßoUªÖ~ðÖo|ãßZU¢AO~rßö>ÖrvÖb¢b¢©ð/özî.aåO££/BªÐ<:ß©<ªO_v:öhZz_ðãßbÜBrZ>_ü¢AOZb£ª|v¢ß/obÖî©äüvÐ|©ÐߢAã¢vozh>üh+ü,Z_ÐbðB.£ýAr_/@UUb,:>:¢Üðý:@Z©Bª_Ä>ÃÐa@Т.ýAß/ÐÐßåUîÜî<öÃÜßb<~Cüî:©ãöß_u|£ßB:~ü>vÐÄ..Oߢu|aür:vbZah+Üîßý*a*hb,>BßzßÖåÄ~Ä£Aª.ß~AC+Üß::¢Ð+ðÐb.ä©|ãbîoî©_O~:/ÄÐZ.oÜýuÜZ~b©o~/ßh£oäü>Ü*ð/h:ãªuýaîýb_~Z/¢åUUauýzuÐAöv|ÖU_bu+ãÜöÄ+b©vª+v~*ÖUbU@*Ä/ßuB~vÄ*ö~äö_åö~ÐÐå<:ª@z©ýaÐ_ða|ãCB+OCãßßu,O,hÄ£,CÄB*£C©Oh>Ö|ÖßA|ZB/ߪ,ªîbÃuu*ð_Z,*.rðrOa/oA¢bUA/+£BAZãßÖBrvüî:äuüa_|©CÄðuCüZß©¢b¢A_aýCå<+.C.<*C~o.<<£åÐÃîoÃZ.C_zrÐAÖ*Ãã+CbOvaz<îa,h/rh:ÖzãBß:ªbuåßOÐZ+U>|B+~Ã:Ã~ÃßZAýCBbvZ/>~að@aö.rhЪ£h£äBßäbäh@h£zauÜÃh:aðÖî_Oã|Öb>:ör£î+UaU/u~*båvrýÄ£@ýZªÄ,Ð*ðüzzß©bO:©Cå@ÃåAÜ+.ã©ð£~A/ý:'), (0x1BD3592E27D31FD6B0FB1A576E3F59A69A7B7C55823CF28F413F3598D7F2810C502D6A3E1DFF8DFDB5F6E89DDBAEF96DB2C756150666EFDFE0C9EDE89D86FFBE790E0740D41B899AEE7E9F8B5355B49245C8E6109C6C06EA3E8B5E5312A55F2FF72A23CDA7B898973DBB2687C7638B8B155AA2D5A0EF220D081D0249BD3688481E6F942931E6EA8D2F4ED2E0457E22DAFFD23DB703898F070716C58AB54EDA0733DE6857CE62592F6F14A5511D41C789FA284AEAF8D04594E08D211B2160D8E174CAAC6715CB0B9C780E48EEE43DEAC54E3B908C04EF0F6398D37641403E0D0F3BC4DD529560742E1DAD71E98756B0A3A25BCCE5CF4BDD84BB49CE4154C95C3A0039B31F609730EDC7626F567E26DB4223D39EE571283FEFE758974C9232D9535137E84EA391420A2ADF1D6DDC8606956D8C1E812A77C8D8F9C3380700E45B95881B05473D8C9F929093BA920AD113615201DE06145828DA6E0F54DF583B0A468388E5C180BF57E0EC8CF097BC36CE28B0D7B5FE0655812FF22BD82E38BF395589740F81EC51E092AAFD198768911D37412C2F81850B402D07B5CE54E629A82D529A0D48274C3C5EF62254083CF9C7600EA0EC0B8FB8D07E34E17936838BAC8154EB35CE84D410F4F0D18A62B737F10EED6D46453C9D9D9ACA8E1446D205DA6B76D2B350C3F9DC3990F81BBE2E6DC7FCEF6B4815456645B74D9A04F5BFCA21EA), (null), (0x0A), (0x4AF4910CB54381DF6B5CC71856), ('1805b74e-0bd8-46d8-a647-0af16fd18c1b'), ('7041-06-04 22:06:45.738'), ('1993-04-30 03:32:00'), ('10/31/2016 1:39:16 PMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/0010/31/2016 1:39:16 PMThe quick brown fox jumps over the lazy dog0123456789,.;:?[]{}()-+*\%^=~!@#_|/00'), ('05:20:41.8865910'), ('1766-07-10'), (null), ('6153-12-09 08:49:27.7938112+00:00'))"; + break; + default: + break; + } + return $query; +} + +//-------------------------------------------------------------------- +// Repro +// +//-------------------------------------------------------------------- +function Repro() +{ + StartTest("sqlsrv_statement_cancel"); + try + { + Cancel(); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("sqlsrv_statement_cancel"); +} + +Repro(); + +?> +--EXPECTREGEX-- + +...Starting 'sqlsrv_statement_cancel' test... +\[Microsoft\](\[ODBC Driver 13 for SQL Server\]|\[ODBC Driver Manager\])( Function sequence error|Associated statement is not prepared) +0 +(HY010|HY007) + +Done +...Test 'sqlsrv_statement_cancel' completed successfully. diff --git a/test/sqlsrv/sqlsrv_statement_query_timeout.phpt b/test/sqlsrv/sqlsrv_statement_query_timeout.phpt new file mode 100644 index 000000000..2416463f0 --- /dev/null +++ b/test/sqlsrv/sqlsrv_statement_query_timeout.phpt @@ -0,0 +1,77 @@ +--TEST-- +Test sending queries (query or prepare) with a timeout specified. Errors are expected. +--FILE-- + 1)); + } + else + { + $stmt = sqlsrv_prepare($conn, "WAITFOR DELAY '00:00:05'; SELECT * FROM $tableName", array(), array('QueryTimeout' => 1)); + sqlsrv_execute($stmt); + } + + $errors = sqlsrv_errors(SQLSRV_ERR_ALL); + $e = $errors[0]; + + print($e['message'] . "\n"); + print($e['code'] . "\n"); + print($e['SQLSTATE'] . "\n"); + +} + +function Repro() +{ + StartTest("sqlsrv_statement_query_timeout"); + try + { + set_time_limit(0); + sqlsrv_configure('WarningsReturnAsErrors', 1); + + require_once("autonomous_setup.php"); + $database = "tempdb"; + + // Connect + $connectionInfo = array("UID"=>$username, "PWD"=>$password); + $conn = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn ) { FatalError("Could not connect.\n"); } + + QueryTimeout($conn, true); + QueryTimeout($conn, false); + + sqlsrv_close($conn); + + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("sqlsrv_statement_query_timeout"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'sqlsrv_statement_query_timeout' test... +[Microsoft][ODBC Driver 13 for SQL Server]Query timeout expired +0 +HYT00 +[Microsoft][ODBC Driver 13 for SQL Server]Query timeout expired +0 +HYT00 + +Done +...Test 'sqlsrv_statement_query_timeout' completed successfully. diff --git a/test/sqlsrv/sqlsrv_statement_query_timeout_transaction.phpt b/test/sqlsrv/sqlsrv_statement_query_timeout_transaction.phpt new file mode 100644 index 000000000..9eacc6aca --- /dev/null +++ b/test/sqlsrv/sqlsrv_statement_query_timeout_transaction.phpt @@ -0,0 +1,90 @@ +--TEST-- +Test sending queries (query or prepare) with a timeout specified using transactions. Errors are expected. +--FILE-- + 1)); + $errors = sqlsrv_errors(SQLSRV_ERR_ALL); + $e = $errors[0]; + + print($e['message'] . "\n"); + print($e['code'] . "\n"); + print($e['SQLSTATE'] . "\n"); + + if ($commit) + sqlsrv_commit($conn1); + else + sqlsrv_rollback($conn1); + + sqlsrv_query($conn2, "DROP TABLE $tableName"); +} + +function Repro() +{ + StartTest("sqlsrv_statement_query_timeout_transaction"); + try + { + set_time_limit(0); + sqlsrv_configure('WarningsReturnAsErrors', 1); + + require_once("autonomous_setup.php"); + + // Connect + $connectionInfo = array("UID"=>$username, "PWD"=>$password, 'ConnectionPooling'=>0); + $conn1 = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn1 ) { FatalError("Could not connect.\n"); } + + $conn2 = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn2 ) { FatalError("Could not connect.\n"); } + + QueryTimeout($conn1, $conn2, true); + QueryTimeout($conn1, $conn2, false); + + sqlsrv_close($conn1); + sqlsrv_close($conn2); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("sqlsrv_statement_query_timeout_transaction"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'sqlsrv_statement_query_timeout_transaction' test... +[Microsoft][ODBC Driver 13 for SQL Server]Query timeout expired +0 +HYT00 +[Microsoft][ODBC Driver 13 for SQL Server]Query timeout expired +0 +HYT00 + +Done +...Test 'sqlsrv_statement_query_timeout_transaction' completed successfully. diff --git a/test/sqlsrv/sqlsrv_stored_proc_varchar.phpt b/test/sqlsrv/sqlsrv_stored_proc_varchar.phpt new file mode 100644 index 000000000..9daefcf72 --- /dev/null +++ b/test/sqlsrv/sqlsrv_stored_proc_varchar.phpt @@ -0,0 +1,78 @@ +--TEST-- +Test stored procedure that returns a varchar +--FILE-- +$username, "PWD"=>$password); + $conn = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn ) { FatalError("Could not connect.\n"); } + + $procName = GetTempProcName(); + + $tsql = "CREATE PROC $procName (@p1 VARCHAR(37) OUTPUT, @p2 VARCHAR(21), @p3 VARCHAR(14)) + AS + BEGIN + SET @p1 = CONVERT(VARCHAR(37), @p2 + @p3) + END"; + $stmt = sqlsrv_query($conn, $tsql); + sqlsrv_free_stmt($stmt); + $retValue = ''; + $stmt = sqlsrv_prepare($conn, "{CALL $procName (?, ?, ?)}", array(array(&$retValue, SQLSRV_PARAM_OUT, null, SQLSRV_SQLTYPE_NVARCHAR(38)), array('Microsoft SQL Server ', SQLSRV_PARAM_IN), array('Driver for PHP', SQLSRV_PARAM_IN))); + $retValue = ''; + sqlsrv_execute($stmt); + echo("$retValue\n"); + $retValue = 'Microsoft SQL Server Driver for PH'; + sqlsrv_execute($stmt); + echo("$retValue\n"); + $retValue = 'ABCDEFGHIJKLMNOPQRSTUWXYZMicrosoft '; + sqlsrv_execute($stmt); + echo("$retValue\n"); + $retValue = 'ABCDEFGHIJKLMNOPQRSTUWXYZ_Microsoft SQL Server Driver for PHP'; + sqlsrv_execute($stmt); + echo("$retValue\n"); + $retValue = 'Microsoft SQL Server Driver for'; + sqlsrv_execute($stmt); + echo("$retValue\n"); + sqlsrv_free_stmt($stmt); + sqlsrv_close($conn); +} + +function Repro() +{ + StartTest("sqlsrv_stored_proc_varchar"); + try + { + StoredProc_varchar(); + } + catch (Exception $e) + { + echo $e->getMessage(); + } + echo "\nDone\n"; + EndTest("sqlsrv_stored_proc_varchar"); +} + +Repro(); + +?> +--EXPECT-- + +...Starting 'sqlsrv_stored_proc_varchar' test... +Microsoft SQL Server Driver for PHP +Microsoft SQL Server Driver for PHP +Microsoft SQL Server Driver for PHP +Microsoft SQL Server Driver for PHP +Microsoft SQL Server Driver for PHP + +Done +...Test 'sqlsrv_stored_proc_varchar' completed successfully. diff --git a/test/sqlsrv/srv_069_fetch_empty_nvarchar_buffered.phpt b/test/sqlsrv/srv_069_fetch_empty_nvarchar_buffered.phpt new file mode 100644 index 000000000..c1568d997 --- /dev/null +++ b/test/sqlsrv/srv_069_fetch_empty_nvarchar_buffered.phpt @@ -0,0 +1,44 @@ +--TEST-- +GitHub issue #69 - fetching an empty nvarchar using client buffer +--SKIPIF-- +--FILE-- + 'buffered']); + if (! $stmt) { print_errors(); } + + $return = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); + print_r($return); + + // Free the statement and connection resources. + sqlsrv_free_stmt( $stmt); + sqlsrv_close( $conn); +} + +test(); + +print "Done"; +?> +--EXPECT-- +Array +( + [Empty_Nvarchar_Max] => +) +Done \ No newline at end of file diff --git a/test/sqlsrv/srv_223_sqlsrv_fetch_absolute.phpt b/test/sqlsrv/srv_223_sqlsrv_fetch_absolute.phpt new file mode 100644 index 000000000..f7138e4cb --- /dev/null +++ b/test/sqlsrv/srv_223_sqlsrv_fetch_absolute.phpt @@ -0,0 +1,59 @@ +--TEST-- +sqlsrv_fetch() with SQLSRV_SCROLL_ABSOLUTE using out of range offset +--SKIPIF-- +--FILE-- + 0) + { + echo $message . "\n"; + } + die( print_r( sqlsrv_errors(), true)); +} + +function test() +{ + require_once("autonomous_setup.php"); + + // Connect + $conn = sqlsrv_connect($serverName, $connectionInfo); + if( !$conn ) { print_errors(); } + + // Prepare the statement + $sql = "select name from sys.databases"; + $stmt = sqlsrv_prepare( $conn, $sql, array(), array("Scrollable"=>SQLSRV_CURSOR_CLIENT_BUFFERED) ); + if( $stmt === false ) { print_errors(); } + sqlsrv_execute($stmt); + + // Get row count + $row_count = sqlsrv_num_rows( $stmt ); + if ($row_count == 0) { print_errors("There should be at least one row!\n"); } + + sqlsrv_execute($stmt); + $row = sqlsrv_fetch($stmt, SQLSRV_SCROLL_FIRST); + $field = sqlsrv_get_field($stmt, 0); + if (! $field) { print_errors(); } + + $row = sqlsrv_fetch($stmt, SQLSRV_SCROLL_LAST); + $field = sqlsrv_get_field($stmt, 0); + if (! $field) { print_errors(); } + + // this should return false + $row = sqlsrv_fetch($stmt, SQLSRV_SCROLL_ABSOLUTE, $row_count); + if ($row) { print_errors("This should return false!"); } + $field = sqlsrv_get_field($stmt, 0); + if ($field !== false) { print_errors("This should have resulted in error!"); } + + sqlsrv_free_stmt( $stmt); + sqlsrv_close($conn); +} + +test(); + +print "Done"; +?> + +--EXPECT-- +Done diff --git a/test/sqlsrv/srv_230_sqlsrv_buffered_numeric_types.phpt b/test/sqlsrv/srv_230_sqlsrv_buffered_numeric_types.phpt new file mode 100644 index 000000000..895c463e3 --- /dev/null +++ b/test/sqlsrv/srv_230_sqlsrv_buffered_numeric_types.phpt @@ -0,0 +1,208 @@ +--TEST-- +Read numeric types from SQLSRV with buffered query. +--DESCRIPTION-- +Test numeric conversion (number to string, string to number) functionality for buffered queries with SQLSRV. +--SKIPIF-- +--FILE-- +"$username", "PWD"=>"$password", "CharacterSet" => "UTF-8"); +$conn = sqlsrv_connect($serverName, $connectionInfo); +if( $conn === false ) { + die( print_r( sqlsrv_errors(), true )); +} + +$sample = 1234567890.1234; +$sample1 = -1234567890.1234; +$sample2 = 1; +$sample3 = -1; +$sample4 = 0.5; +$sample5 = -0.55; + +$query = 'CREATE TABLE #TESTTABLE (a float(53), neg_a float(53), b int, neg_b int, c decimal(16, 6), neg_c decimal(16, 6), zero int, zerof float(53), zerod decimal(16,6))'; + +// Create table +$stmt = sqlsrv_query( $conn, $query ); +if( $stmt === false ) { + die( print_r( sqlsrv_errors(), true )); +} + +$query = 'INSERT INTO #TESTTABLE (a, neg_a, b, neg_b, c, neg_c, zero, zerof, zerod) VALUES(?, ?, ?, ?, ?, ?, 0, 0, 0)'; +$params = array($sample, $sample1, $sample2, $sample3, $sample4, $sample5); + +$stmt = sqlsrv_query( $conn, $query, $params ); +if( $stmt === false ) { + die( print_r( sqlsrv_errors(), true )); +} +$params = array($sample4, $sample5, 100000, -1234567, $sample, $sample1); +$stmt = sqlsrv_query( $conn, $query, $params ); +if( $stmt === false ) { + die( print_r( sqlsrv_errors(), true )); +} + + + + +$query = 'SELECT TOP 2 * FROM #TESTTABLE'; +$stmt = sqlsrv_query( $conn, $query, array(), array("Scrollable"=>SQLSRV_CURSOR_CLIENT_BUFFERED)); +if(!$stmt) +{ + echo "Statement could not be prepared.\n"; + die( print_r( sqlsrv_errors(),true)); +} +sqlsrv_execute( $stmt ); + +$array = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_NUMERIC ); +var_dump($array); +$array = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_NUMERIC ); +var_dump($array); + + + + +$numFields = sqlsrv_num_fields( $stmt ); +$meta = sqlsrv_field_metadata( $stmt ); +$rowcount = sqlsrv_num_rows( $stmt); +for($i = 0; $i < $rowcount; $i++){ + sqlsrv_fetch( $stmt, SQLSRV_SCROLL_ABSOLUTE, $i ); + for($j = 0; $j < $numFields; $j++) { + $name = $meta[$j]["Name"]; + print("\ncolumn: $name\n"); + $field = sqlsrv_get_field( $stmt, $j, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR) ); + var_dump($field); + if ($meta[$j]["Type"] == SQLSRV_SQLTYPE_INT) + { + $field = sqlsrv_get_field( $stmt, $j, SQLSRV_PHPTYPE_INT ); + var_dump($field); + } + $field = sqlsrv_get_field( $stmt, $j, SQLSRV_PHPTYPE_FLOAT); + var_dump($field); + } +} + +sqlsrv_free_stmt($stmt); +sqlsrv_close($conn); + +?> +--EXPECT-- +array(9) { + [0]=> + float(1234567890.1234) + [1]=> + float(-1234567890.1234) + [2]=> + int(1) + [3]=> + int(-1) + [4]=> + string(7) ".500000" + [5]=> + string(8) "-.550000" + [6]=> + int(0) + [7]=> + float(0) + [8]=> + string(7) ".000000" +} +array(9) { + [0]=> + float(0.5) + [1]=> + float(-0.55) + [2]=> + int(100000) + [3]=> + int(-1234567) + [4]=> + string(17) "1234567890.123400" + [5]=> + string(18) "-1234567890.123400" + [6]=> + int(0) + [7]=> + float(0) + [8]=> + string(7) ".000000" +} + +column: a +string(15) "1234567890.1234" +float(1234567890.1234) + +column: neg_a +string(16) "-1234567890.1234" +float(-1234567890.1234) + +column: b +string(1) "1" +int(1) +float(1) + +column: neg_b +string(2) "-1" +int(-1) +float(-1) + +column: c +string(7) ".500000" +float(0.5) + +column: neg_c +string(8) "-.550000" +float(-0.55) + +column: zero +string(1) "0" +int(0) +float(0) + +column: zerof +string(1) "0" +float(0) + +column: zerod +string(7) ".000000" +float(0) + +column: a +string(3) "0.5" +float(0.5) + +column: neg_a +string(5) "-0.55" +float(-0.55) + +column: b +string(6) "100000" +int(100000) +float(100000) + +column: neg_b +string(8) "-1234567" +int(-1234567) +float(-1234567) + +column: c +string(17) "1234567890.123400" +float(1234567890.1234) + +column: neg_c +string(18) "-1234567890.123400" +float(-1234567890.1234) + +column: zero +string(1) "0" +int(0) +float(0) + +column: zerof +string(1) "0" +float(0) + +column: zerod +string(7) ".000000" +float(0) + diff --git a/test/sqlsrv/srv_231_string_truncation_varchar_max.phpt b/test/sqlsrv/srv_231_string_truncation_varchar_max.phpt new file mode 100644 index 000000000..96d2a9b81 --- /dev/null +++ b/test/sqlsrv/srv_231_string_truncation_varchar_max.phpt @@ -0,0 +1,189 @@ +--TEST-- +GitHub issue #231 - String truncation when binding varchar(max) +--SKIPIF-- +--FILE-- +$username, "PWD"=>$password); +$conn = sqlsrv_connect($serverName, $connectionInfo); +if( $conn === false ) { + die( print_r( sqlsrv_errors(), true )); +} + +$tableName = "#testDataTypes_GH231"; +$columnNames = array( "c1","c2" ); + +for ($k = 1; $k <= 8; $k++) +{ + $sqlType = GetSqlType($k); + $dataType = "[$columnNames[0]] int, [$columnNames[1]] $sqlType"; + + $sql = "CREATE TABLE [$tableName] ($dataType)"; + $stmt1 = sqlsrv_query($conn, $sql); + sqlsrv_free_stmt($stmt1); + + $sql = "INSERT INTO [$tableName] ($columnNames[0], $columnNames[1]) VALUES (?, ?)"; + $data = GetData($k); + $phpType = GetPhpType($k); + $driverType = GetDriverType($k, strlen($data)); + + $params = array($k, array($data, SQLSRV_PARAM_IN, $phpType, $driverType)); + $stmt2 = sqlsrv_prepare($conn, $sql, $params); + sqlsrv_execute($stmt2); + sqlsrv_free_stmt($stmt2); + + ExecProc($conn, $tableName, $columnNames, $k, $data, $sqlType); + + $stmt3 = sqlsrv_query($conn, "DROP TABLE [$tableName]"); + sqlsrv_free_stmt($stmt3); +} + +sqlsrv_close($conn); + + +function ExecProc($conn, $tableName, $columnNames, $k, $data, $sqlType) +{ + $spArgs = "@p1 int, @p2 $sqlType OUTPUT"; + $spCode = "SET @p2 = ( SELECT c2 FROM $tableName WHERE c1 = @p1 )"; + $procName = "testBindOutSp"; + + $stmt1 = sqlsrv_query($conn, "CREATE PROC [$procName] ($spArgs) AS BEGIN $spCode END"); + sqlsrv_free_stmt($stmt1); + + echo "\nData Type: ".$sqlType." binding as \n"; + + $direction = SQLSRV_PARAM_OUT; + echo "Output parameter: \t"; + CallProc($conn, $procName, $k, $direction, $data); + + $direction = SQLSRV_PARAM_INOUT; + echo "InOut parameter: \t"; + CallProc($conn, $procName, $k, $direction, $data); + + $stmt2 = sqlsrv_query($conn, "DROP PROC [$procName]"); + sqlsrv_free_stmt($stmt2); +} + +function CallProc($conn, $procName, $k, $direction, $data) +{ + $driverType = GetDriverType($k, strlen($data)); + $callArgs = "?, ?"; + + // Data to initialize $callResult variable. This variable should be shorter than inserted data in the table + $initData = "ShortString"; + $callResult = $initData; + + // Make sure not to specify the PHP type + $params = array( array( $k, SQLSRV_PARAM_IN ), + array( &$callResult, $direction, null, $driverType )); + $stmt = sqlsrv_query($conn, "{ CALL [$procName] ($callArgs)}", $params); + if($stmt === false) { + die( print_r( sqlsrv_errors(), true )); + } + + // $callResult should be updated to the value in the table + $matched = ($callResult === $data); + if ($matched) + echo "data matched!\n"; + else + echo "failed!\n"; + + sqlsrv_free_stmt($stmt); +} + +function GetData($k) +{ + $data = "LongStringForTesting"; + if ($k == 8) { + $data = "The quick brown fox jumps over the lazy dog0123456789"; + } + + return $data; +} + +function GetPhpType($k) +{ + $phpType = SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR); + if ($k == 7) { + $phpType = SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_BINARY); + } + + return $phpType; +} + +function GetSqlType($k) +{ + switch ($k) + { + case 1: return ("char(512)"); + case 2: return ("varchar(512)"); + case 3: return ("varchar(max)"); + case 4: return ("nchar(512)"); + case 5: return ("nvarchar(512)"); + case 6: return ("nvarchar(max)"); + case 7: return ("varbinary(max)"); + case 8: return ("xml"); + default: break; + } + return ("udt"); +} + +function GetDriverType($k, $dataSize) +{ + switch ($k) + { + case 1: return (SQLSRV_SQLTYPE_CHAR($dataSize)); + case 2: return (SQLSRV_SQLTYPE_VARCHAR($dataSize)); + case 3: return (SQLSRV_SQLTYPE_VARCHAR('max')); + case 4: return (SQLSRV_SQLTYPE_NCHAR($dataSize)); + case 5: return (SQLSRV_SQLTYPE_NVARCHAR($dataSize)); + case 6: return (SQLSRV_SQLTYPE_NVARCHAR('max')); + case 7: return (SQLSRV_SQLTYPE_VARBINARY('max')); + case 8: return (SQLSRV_SQLTYPE_XML); + + default: break; + } + return (SQLSRV_SQLTYPE_UDT); +} + +?> + +--EXPECT-- + +Data Type: char(512) binding as +Output parameter: data matched! +InOut parameter: data matched! + +Data Type: varchar(512) binding as +Output parameter: data matched! +InOut parameter: data matched! + +Data Type: varchar(max) binding as +Output parameter: data matched! +InOut parameter: data matched! + +Data Type: nchar(512) binding as +Output parameter: data matched! +InOut parameter: data matched! + +Data Type: nvarchar(512) binding as +Output parameter: data matched! +InOut parameter: data matched! + +Data Type: nvarchar(max) binding as +Output parameter: data matched! +InOut parameter: data matched! + +Data Type: varbinary(max) binding as +Output parameter: data matched! +InOut parameter: data matched! + +Data Type: xml binding as +Output parameter: data matched! +InOut parameter: data matched! + diff --git a/test/sqlsrv/srv_308_empty_output_param.phpt b/test/sqlsrv/srv_308_empty_output_param.phpt new file mode 100644 index 000000000..638acbea0 --- /dev/null +++ b/test/sqlsrv/srv_308_empty_output_param.phpt @@ -0,0 +1,47 @@ +--TEST-- +GitHub issue #308 - empty string set to output parameter on stored procedure +--DESCRIPTION-- +A variation of the example in GitHub issue 308. A NULL value returned as output parameter will remain as NULL. +--SKIPIF-- +--FILE-- + +--EXPECT-- +OUT value: NULL +Done diff --git a/test/sqlsrv/tools.inc b/test/sqlsrv/tools.inc new file mode 100644 index 000000000..7336f3c75 --- /dev/null +++ b/test/sqlsrv/tools.inc @@ -0,0 +1,928 @@ +')"; + $pos = strpos($data, $str); + $tmp = substr($data, 0, $pos + 2); + } + + $data = $tmp; + + if (IsDataUnicode($colType, $data)) // this includes unicode data type and XML data that is in Unicode + { // N'data' + $data = substr($data, 2, strlen($data) - 3); + } + else if (IsLiteral($colType)) + { // 'data' + $data = substr($data, 1, strlen($data) - 2); + } + else if (IsBinary($colType)) + { // 0xdata + $data = substr($data, 2); + } + + return (trim($data)); +} + +function IsStreamable($type) +{ + switch ($type) + { + case _SQL_CHAR: // char + return true; + case _SQL_WCHAR: // nchar + return true; + case _SQL_VARCHAR: // varchar + return true; + case _SQL_WVARCHAR: // nvarchar + return true; + case _SQL_LONGVARCHAR: // text + return true; + case _SQL_WLONGVARCHAR: // ntext + return true; + case _SQL_BINARY: // binary + return true; + case _SQL_VARBINARY: // varbinary + return true; + case _SQL_LONGVARBINARY: // image + return true; + case _SQL_SS_XML: // xml + return true; + default: + break; + } + return (false); +} + +function IsNumeric($type) +{ + switch ($type) + { + case _SQL_INTEGER : // int + return true; + case _SQL_TINYINT : // tinyint + return true; + case _SQL_SMALLINT : // smallint + return true; + case _SQL_BIGINT : // bigint + return true; + case _SQL_BIT : // bit + return true; + case _SQL_FLOAT : // float + return true; + case _SQL_REAL : // real + return true; + case _SQL_DECIMAL : // decimal + return true; + case _SQL_NUMERIC : // numeric, money, smallmoney + return true; + default: break; + } + return (false); +} + +function IsChar($type) +{ + switch ($type) + { + case _SQL_WCHAR: // nchar + return true; + case _SQL_VARCHAR: // varchar + return true; + case _SQL_WVARCHAR: // nvarchar + return true; + case _SQL_LONGVARCHAR: // text + return true; + case _SQL_WLONGVARCHAR: // ntext + return true; + case _SQL_SS_XML: // xml + return true; + default: + break; + } + return (false); +} + +function IsBinary($type) +{ + switch ($type) + { + case _SQL_BINARY: // binary + return true; + case _SQL_VARBINARY: // varbinary + return true; + case _SQL_LONGVARBINARY: // image + return true; + default: + break; + } + return (false); +} + +function IsDateTime($type) +{ + switch ($type) + { + case _SQL_TYPE_TIMESTAMP: // datetime, smalldatetime + return true; + case _SQL_TYPE_DATE: // date + return true; + case _SQL_SS_TIME2: // time + return true; + case _SQL_SS_TIMESTAMPOFFSET: // datetimeoffset + return true; + default: + break; + } + return (false); +} + +function IsDataUnicode($colType, $data) +{ + if (IsUnicode($colType)) + return true; + + // This input string may be an XML string in unicode (i.e. // N'...') + $letterN = 'N'; + $index = strpos($data, $letterN); + + // Note the use of ===. Simply == would not work as expected + // because the position of letterN 'N' may be the 0th (first) character + // and strpos will return false if not found. + if ($index === 0) { + return true; + } + + return false; +} + +function IsUnicode($type) +{ + switch ($type) + { + case _SQL_WCHAR: // nchar + return true; + case _SQL_WVARCHAR: // nvarchar + return true; + case _SQL_WLONGVARCHAR: // ntext + return true; + default: + break; + } + return (false); +} + +function IsXml($type) +{ + return ($type == _SQL_SS_XML); +} + +function IsUpdatable($colName) +{ + $pos = strpos($colName, "_"); + $type = substr($colName, $pos + 1); + + return (strcasecmp($type, "timestamp") != 0); +} + +function IsLiteral($type) +{ + switch ($type) + { + case _SQL_CHAR: // char + return true; + case _SQL_WCHAR: // nchar + return true; + case _SQL_VARCHAR: // varchar + return true; + case _SQL_WVARCHAR: // nvarchar + return true; + case _SQL_LONGVARCHAR: // text + return true; + case _SQL_WLONGVARCHAR: // ntext + return true; + case _SQL_GUID: // uniqueidentifier + return true; + case _SQL_TYPE_TIMESTAMP: // datetime, smalldatetime + return true; + case _SQL_TYPE_DATE: // date + return true; + case _SQL_SS_TIME2: // time + return true; + case _SQL_SS_TIMESTAMPOFFSET: // datetimeoffset + return true; + case _SQL_SS_XML: // xml + return true; + default: + break; + } + return (false); +} + +?> \ No newline at end of file