3737#include "ext/standard/php_standard.h"
3838#include "php_interbase.h"
3939#include "php_ibase_includes.h"
40+ #include "pdo_firebird_utils.h"
4041
4142#define ISC_LONG_MIN INT_MIN
4243#define ISC_LONG_MAX INT_MAX
@@ -266,10 +267,10 @@ static int _php_ibase_alloc_array(ibase_array **ib_arrayp, XSQLDA *sqlda, /* {{{
266267 break ;
267268// Boolean data type exists since FB 3.0
268269#ifdef SQL_BOOLEAN
269- case blr_bool :
270- a -> el_type = SQL_BOOLEAN ;
271- a -> el_size = sizeof (FB_BOOLEAN );
272- break ;
270+ case blr_bool :
271+ a -> el_type = SQL_BOOLEAN ;
272+ a -> el_size = sizeof (FB_BOOLEAN );
273+ break ;
273274#endif
274275 case blr_short :
275276 a -> el_type = SQL_SHORT ;
@@ -303,6 +304,20 @@ static int _php_ibase_alloc_array(ibase_array **ib_arrayp, XSQLDA *sqlda, /* {{{
303304 a -> el_type = SQL_TYPE_TIME ;
304305 a -> el_size = sizeof (ISC_TIME );
305306 break ;
307+ #if FB_API_VER >= 40
308+ // These are converted to VARCHAR via isc_dpb_set_bind tag at connect
309+ // blr_dec64
310+ // blr_dec128
311+ // blr_int128
312+ case blr_sql_time_tz :
313+ a -> el_type = SQL_TIME_TZ ;
314+ a -> el_size = sizeof (ISC_TIME_TZ );
315+ break ;
316+ case blr_timestamp_tz :
317+ a -> el_type = SQL_TIMESTAMP_TZ ;
318+ a -> el_size = sizeof (ISC_TIMESTAMP_TZ );
319+ break ;
320+ #endif
306321 case blr_varying :
307322 case blr_varying2 :
308323 /**
@@ -614,17 +629,19 @@ static int _php_ibase_bind_array(zval *val, char *buf, zend_ulong buf_size, /* {
614629 break ;
615630// Boolean data type exists since FB 3.0
616631#ifdef SQL_BOOLEAN
617- case SQL_BOOLEAN :
618- convert_to_boolean (val );
619- // On Windows error unresolved symbol Z_BVAL_P is thrown, so we use Z_LVAL_P
620- * (FB_BOOLEAN * ) buf = Z_LVAL_P (val );
621- break ;
632+ case SQL_BOOLEAN :
633+ convert_to_boolean (val );
634+ // On Windows error unresolved symbol Z_BVAL_P is thrown, so we use Z_LVAL_P
635+ * (FB_BOOLEAN * ) buf = Z_LVAL_P (val );
636+ break ;
622637#endif
623638 case SQL_DOUBLE :
624639 convert_to_double (val );
625640 * (double * ) buf = Z_DVAL_P (val );
626641 break ;
627642 case SQL_TIMESTAMP :
643+ // TODO:
644+ // case SQL_TIMESTAMP_TZ:
628645 convert_to_string (val );
629646#ifdef HAVE_STRPTIME
630647 strptime (Z_STRVAL_P (val ), INI_STR ("ibase.timestampformat" ), & t );
@@ -660,6 +677,8 @@ static int _php_ibase_bind_array(zval *val, char *buf, zend_ulong buf_size, /* {
660677 isc_encode_sql_date (& t , (ISC_DATE * ) buf );
661678 break ;
662679 case SQL_TYPE_TIME :
680+ // TODO:
681+ // case SQL_TIME_TZ:
663682 convert_to_string (val );
664683#ifdef HAVE_STRPTIME
665684 strptime (Z_STRVAL_P (val ), INI_STR ("ibase.timeformat" ), & t );
@@ -714,6 +733,13 @@ static int _php_ibase_bind(XSQLDA *sqlda, zval *b_vars, BIND_BUF *buf, /* {{{ */
714733 case SQL_TIMESTAMP :
715734 case SQL_TYPE_DATE :
716735 case SQL_TYPE_TIME :
736+ #if FB_API_VER >= 40
737+ case SQL_INT128 :
738+ case SQL_DEC16 :
739+ case SQL_DEC34 :
740+ case SQL_TIMESTAMP_TZ :
741+ case SQL_TIME_TZ :
742+ #endif
717743 force_null = (Z_STRLEN_P (b_var ) == 0 );
718744 }
719745
@@ -737,6 +763,9 @@ static int _php_ibase_bind(XSQLDA *sqlda, zval *b_vars, BIND_BUF *buf, /* {{{ */
737763 struct tm t ;
738764
739765 case SQL_TIMESTAMP :
766+ // TODO:
767+ // case SQL_TIMESTAMP_TZ:
768+ // case SQL_TIME_TZ:
740769 case SQL_TYPE_DATE :
741770 case SQL_TYPE_TIME :
742771 if (Z_TYPE_P (b_var ) == IS_LONG ) {
@@ -756,6 +785,8 @@ static int _php_ibase_bind(XSQLDA *sqlda, zval *b_vars, BIND_BUF *buf, /* {{{ */
756785 format = INI_STR ("ibase.dateformat" );
757786 break ;
758787 case SQL_TYPE_TIME :
788+ // TODO:
789+ // case SQL_TIME_TZ:
759790 format = INI_STR ("ibase.timeformat" );
760791 }
761792 if (!strptime (Z_STRVAL_P (b_var ), format , & t )) {
@@ -775,6 +806,8 @@ static int _php_ibase_bind(XSQLDA *sqlda, zval *b_vars, BIND_BUF *buf, /* {{{ */
775806 isc_encode_sql_date (& t , & buf [i ].val .dtval );
776807 break ;
777808 case SQL_TYPE_TIME :
809+ // TODO:
810+ // case SQL_TIME_TZ:
778811 isc_encode_sql_time (& t , & buf [i ].val .tmval );
779812 break ;
780813 }
@@ -954,8 +987,20 @@ static void _php_ibase_alloc_xsqlda(XSQLDA *sqlda) /* {{{ */
954987 case SQL_ARRAY :
955988 var -> sqldata = emalloc (sizeof (ISC_QUAD ));
956989 break ;
990+ #if FB_API_VER >= 40
991+ // These are converted to VARCHAR via isc_dpb_set_bind tag at connect
992+ // case SQL_DEC16:
993+ // case SQL_DEC34:
994+ // case SQL_INT128:
995+ case SQL_TIMESTAMP_TZ :
996+ var -> sqldata = emalloc (sizeof (ISC_TIMESTAMP_TZ ));
997+ break ;
998+ case SQL_TIME_TZ :
999+ var -> sqldata = emalloc (sizeof (ISC_TIME_TZ ));
1000+ break ;
1001+ #endif
9571002 default :
958- php_error (E_WARNING , "Unhandled sqltype: %d for sqlname %s %s:%d. This is most likely due to this PHP driver has been not kept up with newer server version " , var -> sqltype , var -> sqlname , __FILE__ , __LINE__ );
1003+ php_error (E_WARNING , "Unhandled sqltype: %d for sqlname %s %s:%d" , var -> sqltype , var -> sqlname , __FILE__ , __LINE__ );
9591004 break ;
9601005 } /* switch */
9611006
@@ -1430,9 +1475,9 @@ static int _php_ibase_var_zval(zval *val, void *data, int type, int len, /* {{{
14301475 break ;
14311476// Boolean data type exists since FB 3.0
14321477#ifdef SQL_BOOLEAN
1433- case SQL_BOOLEAN :
1434- ZVAL_BOOL (val , * (FB_BOOLEAN * ) data );
1435- break ;
1478+ case SQL_BOOLEAN :
1479+ ZVAL_BOOL (val , * (FB_BOOLEAN * ) data );
1480+ break ;
14361481#endif
14371482 case SQL_SHORT :
14381483 n = * (short * ) data ;
@@ -1483,6 +1528,44 @@ static int _php_ibase_var_zval(zval *val, void *data, int type, int len, /* {{{
14831528 case SQL_DOUBLE :
14841529 ZVAL_DOUBLE (val , * (double * ) data );
14851530 break ;
1531+ #if FB_API_VER >= 40
1532+ // These are converted to VARCHAR via isc_dpb_set_bind tag at connect
1533+ // case SQL_DEC16:
1534+ // case SQL_DEC34:
1535+ // case SQL_INT128:
1536+ case SQL_TIME_TZ :
1537+ case SQL_TIMESTAMP_TZ :
1538+ char timeZoneBuffer [40 ] = {0 };
1539+ unsigned year , month , day , hours , minutes , seconds , fractions ;
1540+
1541+ if ((type & ~1 ) == SQL_TIME_TZ ){
1542+ format = INI_STR ("ibase.timeformat" );
1543+ fb_decode_time_tz ((ISC_TIME_TZ * ) data , & hours , & minutes , & seconds , & fractions , sizeof (timeZoneBuffer ), timeZoneBuffer );
1544+ ISC_TIME time = fb_encode_time (hours , minutes , seconds , fractions );
1545+ isc_decode_sql_time (& time , & t );
1546+ } else {
1547+ format = INI_STR ("ibase.timestampformat" );
1548+ fb_decode_timestamp_tz ((ISC_TIMESTAMP_TZ * ) data , & year , & month , & day , & hours , & minutes , & seconds , & fractions , sizeof (timeZoneBuffer ), timeZoneBuffer );
1549+ ISC_TIMESTAMP ts ;
1550+ ts .timestamp_date = fb_encode_date (year , month , day );
1551+ ts .timestamp_time = fb_encode_time (hours , minutes , seconds , fractions );
1552+ isc_decode_timestamp (& ts , & t );
1553+ }
1554+
1555+ if (flag & PHP_IBASE_UNIXTIME ) {
1556+ ZVAL_LONG (val , mktime (& t ));
1557+ } else {
1558+ char timeBuf [80 ] = {0 };
1559+ l = strftime (timeBuf , sizeof (timeBuf ), format , & t );
1560+ if (l == 0 ) {
1561+ return FAILURE ;
1562+ }
1563+
1564+ size_t l = sprintf (string_data , "%s %s" , timeBuf , timeZoneBuffer );
1565+ ZVAL_STRINGL (val , string_data , l );
1566+ }
1567+ break ;
1568+ #endif
14861569 case SQL_DATE : /* == case SQL_TIMESTAMP: */
14871570 format = INI_STR ("ibase.timestampformat" );
14881571 isc_decode_timestamp ((ISC_TIMESTAMP * ) data , & t );
@@ -2040,9 +2123,9 @@ static void _php_ibase_field_info(zval *return_value, XSQLVAR *var) /* {{{ */
20402123 switch (var -> sqltype & ~1 ) {
20412124// Boolean data type exists since FB 3.0
20422125#ifdef SQL_BOOLEAN
2043- case SQL_BOOLEAN :
2044- precision = 1 ;
2045- break ;
2126+ case SQL_BOOLEAN :
2127+ precision = 1 ;
2128+ break ;
20462129#endif
20472130 case SQL_SHORT :
20482131 precision = 4 ;
@@ -2070,9 +2153,9 @@ static void _php_ibase_field_info(zval *return_value, XSQLVAR *var) /* {{{ */
20702153 break ;
20712154// Boolean data type exists since FB 3.0
20722155#ifdef SQL_BOOLEAN
2073- case SQL_BOOLEAN :
2074- s = "BOOLEAN" ;
2075- break ;
2156+ case SQL_BOOLEAN :
2157+ s = "BOOLEAN" ;
2158+ break ;
20762159#endif
20772160 case SQL_LONG :
20782161 s = "INTEGER" ;
@@ -2105,6 +2188,18 @@ static void _php_ibase_field_info(zval *return_value, XSQLVAR *var) /* {{{ */
21052188 case SQL_QUAD :
21062189 s = "QUAD" ;
21072190 break ;
2191+ #if FB_API_VER >= 40
2192+ // These are converted to VARCHAR via isc_dpb_set_bind tag at connect and will appear to clients as VARCHAR
2193+ // case SQL_DEC16:
2194+ // case SQL_DEC34:
2195+ // case SQL_INT128:
2196+ case SQL_TIMESTAMP_TZ :
2197+ s = "TIMESTAMP_TZ" ;
2198+ break ;
2199+ case SQL_TIME_TZ :
2200+ s = "TIME_TZ" ;
2201+ break ;
2202+ #endif
21082203 }
21092204 add_index_string (return_value , 4 , s );
21102205 add_assoc_string (return_value , "type" , s );
0 commit comments