1
1
/*
2
2
+----------------------------------------------------------------------+
3
- | Copyright IBM Corporation 2005-2008 |
3
+ | Copyright IBM Corporation 2005-2014 |
4
4
+----------------------------------------------------------------------+
5
5
| |
6
6
| Licensed under the Apache License, Version 2.0 (the "License"); you |
@@ -119,6 +119,7 @@ typedef struct _conn_handle_struct {
119
119
SQLSMALLINT errormsg_recno_tracker ;
120
120
int flag_pconnect ; /* Indicates that this connection is persistent */
121
121
int flag_transaction ; /* Indicates that transaction is commited */
122
+ int expansion_factor ; /* Maximum expected expansion factor for the length of mixed character data when converted to the application code page from datavase code page */
122
123
} conn_handle ;
123
124
124
125
typedef union {
@@ -174,6 +175,8 @@ typedef struct _stmt_handle_struct {
174
175
db2_result_set_info * column_info ;
175
176
db2_row_type * row_data ;
176
177
char * exec_many_err_msg ;
178
+ int expansion_factor ; /* maximum expected expansion factor for the length of mixed character data */
179
+ /* when converted to the application code page from the database code page*/
177
180
} stmt_handle ;
178
181
179
182
@@ -496,6 +499,8 @@ static stmt_handle *_db2_new_stmt_struct(conn_handle* conn_res)
496
499
stmt_res -> s_i5_sys_naming = conn_res -> c_i5_sys_naming ;
497
500
#endif /* PASE */
498
501
502
+ stmt_res -> expansion_factor = conn_res -> expansion_factor ;
503
+
499
504
stmt_res -> head_cache_list = NULL ;
500
505
stmt_res -> current_node = NULL ;
501
506
@@ -543,12 +548,12 @@ PHP_MINIT_FUNCTION(ibm_db2)
543
548
#endif
544
549
545
550
ZEND_INIT_MODULE_GLOBALS (ibm_db2 , php_ibm_db2_init_globals , NULL );
551
+ REGISTER_LONG_CONSTANT ("DB2_I5_NAMING_ON" , SQL_TRUE , CONST_CS | CONST_PERSISTENT );
552
+ REGISTER_LONG_CONSTANT ("DB2_I5_NAMING_OFF" , SQL_FALSE , CONST_CS | CONST_PERSISTENT );
546
553
547
554
#ifdef PASE /* i5OS db2_setoptions */
548
555
REGISTER_LONG_CONSTANT ("DB2_I5_FETCH_ON" , SQL_TRUE , CONST_CS | CONST_PERSISTENT );
549
556
REGISTER_LONG_CONSTANT ("DB2_I5_FETCH_OFF" , SQL_FALSE , CONST_CS | CONST_PERSISTENT );
550
- REGISTER_LONG_CONSTANT ("DB2_I5_NAMING_ON" , SQL_TRUE , CONST_CS | CONST_PERSISTENT );
551
- REGISTER_LONG_CONSTANT ("DB2_I5_NAMING_OFF" , SQL_FALSE , CONST_CS | CONST_PERSISTENT );
552
557
REGISTER_LONG_CONSTANT ("DB2_I5_JOB_SORT_ON" , SQL_TRUE , CONST_CS | CONST_PERSISTENT );
553
558
REGISTER_LONG_CONSTANT ("DB2_I5_JOB_SORT_OFF" , SQL_FALSE , CONST_CS | CONST_PERSISTENT );
554
559
REGISTER_LONG_CONSTANT ("DB2_I5_DBCS_ALLOC_ON" , SQL_TRUE , CONST_CS | CONST_PERSISTENT );
@@ -682,7 +687,8 @@ static int _php_ibm_db2_conn (zend_rsrc_list_entry *le TSRMLS_DC)
682
687
PHP_RSHUTDOWN_FUNCTION (ibm_db2 )
683
688
{
684
689
zend_hash_apply (& EG (persistent_list ), (apply_func_t ) _php_ibm_db2_conn TSRMLS_CC );
685
-
690
+ _php_db2_clear_conn_err_cache (TSRMLS_C );
691
+ _php_db2_clear_stmt_err_cache (TSRMLS_C );
686
692
return SUCCESS ;
687
693
}
688
694
/* }}} */
@@ -1277,6 +1283,28 @@ static void _php_db2_assign_options( void *handle, int type, char *opt_key, zval
1277
1283
default :
1278
1284
php_error_docref (NULL TSRMLS_CC , E_WARNING , "DB2_ATTR_CASE attribute can only be set on connection or statement resources" );
1279
1285
}
1286
+ } else if (!STRCASECMP (opt_key , "i5_naming" )) {
1287
+ /* i5_naming - SQL_ATTR_DBC_SYS_NAMING
1288
+ DB2_I5_NAMING_ON value turns on DB2 UDB CLI iSeries system naming mode. Files are qualified using the slash (/) delimiter. Unqualified files are resolved using the library list for the job..
1289
+ DB2_I5_NAMING_OFF value turns off DB2 UDB CLI default naming mode, which is SQL naming. Files are qualified using the period (.) delimiter. Unqualified files are resolved using either the default library or the current user ID.
1290
+ */
1291
+ pvParam = option_num ;
1292
+ switch (option_num ) {
1293
+ case DB2_I5_NAMING_ON :
1294
+ case DB2_I5_NAMING_OFF :
1295
+ #ifdef PASE
1296
+ ((conn_handle * )handle )-> c_i5_sys_naming = option_num ;
1297
+ rc = SQLSetConnectAttr ((SQLHDBC )((conn_handle * )handle )-> hdbc , SQL_ATTR_DBC_SYS_NAMING , (SQLPOINTER )& pvParam , SQL_NTS );
1298
+ #else
1299
+ rc = SQLSetConnectAttr ((SQLHDBC )((conn_handle * )handle )-> hdbc , SQL_ATTR_DBC_SYS_NAMING , (SQLPOINTER )pvParam , SQL_NTS );
1300
+ #endif
1301
+ if ( rc == SQL_ERROR ) {
1302
+ _php_db2_check_sql_errors ((SQLHSTMT )((conn_handle * )handle )-> hdbc , SQL_HANDLE_DBC , rc , 1 , NULL , -1 , 1 TSRMLS_CC );
1303
+ }
1304
+ break ;
1305
+ default :
1306
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "i5_naming attribute must be DB2_I5_NAMING_ON or DB2_I5_NAMING_OFF)" );
1307
+ }
1280
1308
#ifdef PASE /* i5/OS new set options */
1281
1309
} else if (!STRCASECMP (opt_key , "i5_lib" )) {
1282
1310
/* i5_lib - SQL_ATTR_DBC_DEFAULT_LIB
@@ -1320,24 +1348,6 @@ static void _php_db2_assign_options( void *handle, int type, char *opt_key, zval
1320
1348
} else {
1321
1349
php_error_docref (NULL TSRMLS_CC , E_WARNING , "i5_libl missing library list" );
1322
1350
}
1323
- } else if (!STRCASECMP (opt_key , "i5_naming" )) {
1324
- /* i5_naming - SQL_ATTR_DBC_SYS_NAMING
1325
- DB2_I5_NAMING_ON value turns on DB2 UDB CLI iSeries system naming mode. Files are qualified using the slash (/) delimiter. Unqualified files are resolved using the library list for the job..
1326
- DB2_I5_NAMING_OFF value turns off DB2 UDB CLI default naming mode, which is SQL naming. Files are qualified using the period (.) delimiter. Unqualified files are resolved using either the default library or the current user ID.
1327
- */
1328
- pvParam = option_num ;
1329
- switch (option_num ) {
1330
- case DB2_I5_NAMING_ON :
1331
- case DB2_I5_NAMING_OFF :
1332
- ((conn_handle * )handle )-> c_i5_sys_naming = option_num ;
1333
- rc = SQLSetConnectAttr ((SQLHDBC )((conn_handle * )handle )-> hdbc , SQL_ATTR_DBC_SYS_NAMING , (SQLPOINTER )& pvParam , SQL_NTS );
1334
- if ( rc == SQL_ERROR ) {
1335
- _php_db2_check_sql_errors ((SQLHSTMT )((conn_handle * )handle )-> hdbc , SQL_HANDLE_DBC , rc , 1 , NULL , -1 , 1 TSRMLS_CC );
1336
- }
1337
- break ;
1338
- default :
1339
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "i5_naming (DB2_I5_NAMING_ON , DB2_I5_NAMING_OFF )");
1340
- }
1341
1351
} else if (!STRCASECMP (opt_key , "i5_job_sort" )) {
1342
1352
/* i5_job_sort - SQL_ATTR_JOB_SORT_SEQUENCE (conn is hidden 10046)
1343
1353
DB2_I5_JOB_SORT_ON value turns on DB2 UDB CLI job sort mode.
@@ -1777,7 +1787,12 @@ static int _php_db2_bind_column_helper(stmt_handle *stmt_res TSRMLS_DC)
1777
1787
case SQL_LONGVARGRAPHIC :
1778
1788
#endif /* PASE */
1779
1789
target_type = SQL_C_CHAR ;
1780
- in_length = stmt_res -> column_info [i ].size + 1 ;
1790
+ /* Multiply the size by expansion factor to handle cases where client and server code page are different*/
1791
+ if (stmt_res -> expansion_factor > 1 ){
1792
+ in_length = stmt_res -> column_info [i ].size * stmt_res -> expansion_factor + 1 ;
1793
+ } else {
1794
+ in_length = stmt_res -> column_info [i ].size + 1 ;
1795
+ }
1781
1796
row_data -> str_val = (SQLCHAR * )ecalloc (1 , in_length );
1782
1797
1783
1798
rc = SQLBindCol ((SQLHSTMT )stmt_res -> hstmt , (SQLUSMALLINT )(i + 1 ),
@@ -2013,6 +2028,7 @@ static int _php_db2_connect_helper( INTERNAL_FUNCTION_PARAMETERS, conn_handle **
2013
2028
int conn_null = 0 ;
2014
2029
int conn_was_pclose = 0 ;
2015
2030
#endif /* PASE */
2031
+ struct sqlca sqlca ;
2016
2032
2017
2033
conn_alive = 1 ;
2018
2034
@@ -2179,6 +2195,20 @@ static int _php_db2_connect_helper( INTERNAL_FUNCTION_PARAMETERS, conn_handle **
2179
2195
break ;
2180
2196
}
2181
2197
2198
+ /* Get maximum expected expansion factor for the length of mixed character data when converted to the */
2199
+ /* application code page from the database code page*/
2200
+ rc = SQLGetSQLCA ((SQLHENV ) conn_res -> henv , (SQLHDBC ) conn_res -> hdbc , SQL_NULL_HSTMT , & sqlca );
2201
+
2202
+ if ( rc == SQL_ERROR ) {
2203
+ _php_db2_check_sql_errors (conn_res -> hdbc , SQL_HANDLE_DBC , rc , 1 , NULL , -1 , 1 TSRMLS_CC );
2204
+ SQLDisconnect ((SQLHDBC )conn_res -> hdbc );
2205
+ SQLFreeHandle ( SQL_HANDLE_DBC , conn_res -> hdbc );
2206
+ SQLFreeHandle (SQL_HANDLE_ENV , conn_res -> henv );
2207
+ break ;
2208
+ } else {
2209
+ conn_res -> expansion_factor = sqlca .sqlerrd [1 ];
2210
+ }
2211
+
2182
2212
/* Get the AUTOCOMMIT state from the CLI driver as cli driver could have changed autocommit status based on it's
2183
2213
* precedence */
2184
2214
rc = SQLGetConnectAttr ((SQLHDBC )conn_res -> hdbc , SQL_ATTR_AUTOCOMMIT ,(SQLPOINTER )(& conn_res -> auto_commit ), 0 , NULL );
@@ -3649,6 +3679,7 @@ static int _php_db2_bind_data( stmt_handle *stmt_res, param_node *curr, zval **b
3649
3679
SQLSMALLINT valueType ;
3650
3680
SQLPOINTER paramValuePtr ;
3651
3681
int nullterm = 0 ;
3682
+ int origlen = -1 ;
3652
3683
3653
3684
/* Clean old zval value and create a new one */
3654
3685
if ( curr -> value != 0 && curr -> param_type != DB2_PARAM_OUT && curr -> param_type != DB2_PARAM_INOUT )
@@ -3704,7 +3735,7 @@ static int _php_db2_bind_data( stmt_handle *stmt_res, param_node *curr, zval **b
3704
3735
convert_to_string (* bind_data );
3705
3736
}
3706
3737
if (curr -> param_type == DB2_PARAM_OUT || curr -> param_type == DB2_PARAM_INOUT ) {
3707
- int origlen = Z_STRLEN_PP (bind_data );
3738
+ origlen = Z_STRLEN_PP (bind_data );
3708
3739
if (IS_INTERNED ((* bind_data )-> value .str .val )) {
3709
3740
Z_STRVAL_PP (bind_data ) = estrndup (Z_STRVAL_PP (bind_data ), origlen );
3710
3741
}
@@ -3856,7 +3887,11 @@ static int _php_db2_bind_data( stmt_handle *stmt_res, param_node *curr, zval **b
3856
3887
case SQL_CLOB :
3857
3888
case SQL_DBCLOB :
3858
3889
if (curr -> param_type == DB2_PARAM_OUT || curr -> param_type == DB2_PARAM_INOUT ) {
3859
- curr -> bind_indicator = (curr -> value )-> value .str .len ;
3890
+ if (origlen != -1 ) {
3891
+ curr -> bind_indicator = origlen ;
3892
+ } else {
3893
+ curr -> bind_indicator = (curr -> value )-> value .str .len ;
3894
+ }
3860
3895
valueType = SQL_C_CHAR ;
3861
3896
paramValuePtr = (SQLPOINTER )((curr -> value )-> value .str .val );
3862
3897
} else {
@@ -3869,7 +3904,11 @@ static int _php_db2_bind_data( stmt_handle *stmt_res, param_node *curr, zval **b
3869
3904
3870
3905
case SQL_BLOB :
3871
3906
if (curr -> param_type == DB2_PARAM_OUT || curr -> param_type == DB2_PARAM_INOUT ) {
3872
- curr -> bind_indicator = (curr -> value )-> value .str .len ;
3907
+ if (origlen != -1 ) {
3908
+ curr -> bind_indicator = origlen ;
3909
+ } else {
3910
+ curr -> bind_indicator = (curr -> value )-> value .str .len ;
3911
+ }
3873
3912
#ifdef PASE /* i5/OS V6R1 incompatible change */
3874
3913
if (is_i5os_classic ){
3875
3914
valueType = SQL_C_BINARY ;
@@ -3907,7 +3946,11 @@ static int _php_db2_bind_data( stmt_handle *stmt_res, param_node *curr, zval **b
3907
3946
case SQL_VARBINARY :
3908
3947
case SQL_XML :
3909
3948
/* account for bin_mode settings as well */
3910
- curr -> bind_indicator = (curr -> value )-> value .str .len ;
3949
+ if (origlen != -1 ) {
3950
+ curr -> bind_indicator = origlen ;
3951
+ } else {
3952
+ curr -> bind_indicator = (curr -> value )-> value .str .len ;
3953
+ }
3911
3954
#ifdef PASE /* i5/OS V6R1 incompatible change */
3912
3955
if (is_i5os_classic ){
3913
3956
valueType = SQL_C_BINARY ;
@@ -6589,7 +6632,8 @@ PHP_FUNCTION(db2_lob_read)
6589
6632
zval * stmt = NULL ;
6590
6633
stmt_handle * stmt_res ;
6591
6634
int rc , i = 0 ;
6592
- SQLINTEGER out_length , length = BUFSIZ , colnum = 1 ;
6635
+ SQLINTEGER out_length ;
6636
+ long length = BUFSIZ , colnum = 1 ;
6593
6637
void * out_ptr = NULL ;
6594
6638
6595
6639
/* Parse out the parameters */
0 commit comments