Skip to content

Commit 0e02565

Browse files
committed
Add TIME_TZ SQL_TIMESTAMP_TZ types
1 parent 6ccbde7 commit 0e02565

File tree

1 file changed

+114
-19
lines changed

1 file changed

+114
-19
lines changed

ibase_query.c

Lines changed: 114 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
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

Comments
 (0)