Skip to content

Commit 4d459ff

Browse files
committed
Don't depend on fb_get_master_interface() and fb_get_statement_interface() at compile time. Rather dynamically check if fbclient has them.
1 parent cb0a577 commit 4d459ff

File tree

4 files changed

+70
-41
lines changed

4 files changed

+70
-41
lines changed

ibase_query.c

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,20 +1377,27 @@ static int _php_ibase_var_zval(zval *val, void *data, int type, int len, /* {{{
13771377
// case SQL_INT128:
13781378
case SQL_TIME_TZ:
13791379
case SQL_TIMESTAMP_TZ:
1380+
// Should be converted to VARCHAR via isc_dpb_set_bind tag at
1381+
// connect if fbclient does not have fb_get_master_instance().
1382+
// Assert this just in case.
1383+
if(!IBG(master_instance)) {
1384+
assert(false && "UNREACHABLE");
1385+
}
1386+
13801387
char timeZoneBuffer[40] = {0};
13811388
unsigned year, month, day, hours, minutes, seconds, fractions;
13821389

13831390
if((type & ~1) == SQL_TIME_TZ){
13841391
format = INI_STR("ibase.timeformat");
1385-
fb_decode_time_tz((ISC_TIME_TZ *) data, &hours, &minutes, &seconds, &fractions, sizeof(timeZoneBuffer), timeZoneBuffer);
1386-
ISC_TIME time = fb_encode_time(hours, minutes, seconds, fractions);
1392+
fb_decode_time_tz(IBG(master_instance), (ISC_TIME_TZ *) data, &hours, &minutes, &seconds, &fractions, sizeof(timeZoneBuffer), timeZoneBuffer);
1393+
ISC_TIME time = fb_encode_time(IBG(master_instance), hours, minutes, seconds, fractions);
13871394
isc_decode_sql_time(&time, &t);
13881395
} else {
13891396
format = INI_STR("ibase.timestampformat");
1390-
fb_decode_timestamp_tz((ISC_TIMESTAMP_TZ *) data, &year, &month, &day, &hours, &minutes, &seconds, &fractions, sizeof(timeZoneBuffer), timeZoneBuffer);
1397+
fb_decode_timestamp_tz(IBG(master_instance), (ISC_TIMESTAMP_TZ *) data, &year, &month, &day, &hours, &minutes, &seconds, &fractions, sizeof(timeZoneBuffer), timeZoneBuffer);
13911398
ISC_TIMESTAMP ts;
1392-
ts.timestamp_date = fb_encode_date(year, month, day);
1393-
ts.timestamp_time = fb_encode_time(hours, minutes, seconds, fractions);
1399+
ts.timestamp_date = fb_encode_date(IBG(master_instance), year, month, day);
1400+
ts.timestamp_time = fb_encode_time(IBG(master_instance), hours, minutes, seconds, fractions);
13941401
isc_decode_timestamp(&ts, &t);
13951402
}
13961403

@@ -1408,7 +1415,7 @@ static int _php_ibase_var_zval(zval *val, void *data, int type, int len, /* {{{
14081415
}
14091416
break;
14101417
#endif
1411-
case SQL_DATE: /* == case SQL_TIMESTAMP: */
1418+
case SQL_TIMESTAMP:
14121419
format = INI_STR("ibase.timestampformat");
14131420
isc_decode_timestamp((ISC_TIMESTAMP *) data, &t);
14141421
goto format_date_time;
@@ -1911,8 +1918,14 @@ static void _php_ibase_field_info(zval *return_value, ibase_query *ib_query, int
19111918
// is_outvar
19121919

19131920
#if FB_API_VER >= 40
1914-
if(IBG(fb_get_master_interface) && IBG(fb_get_statement_interface)) {
1915-
if(fb_insert_field_info(IB_STATUS, ib_query, is_outvar, num, return_value)){
1921+
if(IBG(master_instance) && IBG(get_statement_interface)) {
1922+
void *statement = NULL;
1923+
if(((fb_get_statement_interface_t)IBG(get_statement_interface))(IB_STATUS, &statement, &ib_query->stmt)){
1924+
_php_ibase_error();
1925+
RETURN_FALSE;
1926+
}
1927+
1928+
if(fb_insert_field_info(IBG(master_instance), IB_STATUS, is_outvar, num, return_value, statement)){
19161929
_php_ibase_error();
19171930
RETURN_FALSE;
19181931
}
@@ -2208,8 +2221,13 @@ static int _php_ibase_alloc_ht_aliases(ibase_query *ib_query)
22082221
zend_hash_init(ib_query->ht_aliases, ib_query->out_fields_count, NULL, ZVAL_PTR_DTOR, 0);
22092222

22102223
#if FB_API_VER >= 40
2211-
if(IBG(fb_get_master_interface) && IBG(fb_get_statement_interface)) {
2212-
if(fb_insert_aliases(IB_STATUS, ib_query)){
2224+
if(IBG(master_instance) && IBG(get_statement_interface)) {
2225+
void *statement = NULL;
2226+
if(((fb_get_statement_interface_t)IBG(get_statement_interface))(IB_STATUS, &statement, &ib_query->stmt)){
2227+
return FAILURE;
2228+
}
2229+
2230+
if(fb_insert_aliases(IBG(master_instance), IB_STATUS, ib_query, statement)){
22132231
return FAILURE;
22142232
}
22152233
} else {

interbase.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "SAPI.h"
4545
#include <stdbool.h>
4646
#include <time.h>
47+
#include "pdo_firebird_utils.h"
4748

4849
#define ROLLBACK 0
4950
#define COMMIT 1
@@ -1002,9 +1003,23 @@ int _php_ibase_attach_db(char **args, size_t *len, zend_long *largs, isc_db_hand
10021003
}
10031004

10041005
#if FB_API_VER >= 40
1005-
// Do not handle directly INT128 or DECFLOAT, convert to VARCHAR at server instead
1006-
const char compat[] = "int128 to varchar;decfloat to varchar";
1007-
dpb_len = slprintf(dpb, buf_len, "%c%c%s", isc_dpb_set_bind, (char)(sizeof(compat) - 1), compat);
1006+
const char *compat_buf;
1007+
char compat_buf_size;
1008+
1009+
// ibase_query(): Data type unknown
1010+
// If fbclient >= 4 then convert to VARCHAR at server only INT128 and DECFLOAT
1011+
// If we have older client, convert also timezone types
1012+
if(IBG(client_major_version) >= 4) {
1013+
const char compat[] = "INT128 TO VARCHAR;DECFLOAT TO VARCHAR";
1014+
compat_buf = compat;
1015+
compat_buf_size = sizeof(compat) - 1;
1016+
} else {
1017+
const char compat[] = "INT128 TO VARCHAR;DECFLOAT TO VARCHAR;TIME WITH TIME ZONE TO TIME WITHOUT TIME ZONE;TIMESTAMP WITH TIME ZONE TO TIMESTAMP WITHOUT TIME ZONE";
1018+
compat_buf = compat;
1019+
compat_buf_size = sizeof(compat) - 1;
1020+
}
1021+
1022+
dpb_len = slprintf(dpb, buf_len, "%c%c%s", isc_dpb_set_bind, compat_buf_size, compat_buf);
10081023
dpb += dpb_len;
10091024
buf_len -= dpb_len;
10101025
#endif

pdo_firebird_utils.cpp

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,16 @@ extern "C" unsigned fb_get_client_version(void *master_ptr)
3232
return util->getClientVersion();
3333
}
3434

35-
extern "C" ISC_TIME fb_encode_time(unsigned hours, unsigned minutes, unsigned seconds, unsigned fractions)
35+
extern "C" ISC_TIME fb_encode_time(void *master_ptr, unsigned hours, unsigned minutes, unsigned seconds, unsigned fractions)
3636
{
37-
Firebird::IMaster* master = Firebird::fb_get_master_interface();
37+
Firebird::IMaster* master = (Firebird::IMaster*)master_ptr;
3838
Firebird::IUtil* util = master->getUtilInterface();
3939
return util->encodeTime(hours, minutes, seconds, fractions);
4040
}
4141

42-
extern "C" ISC_DATE fb_encode_date(unsigned year, unsigned month, unsigned day)
42+
extern "C" ISC_DATE fb_encode_date(void *master_ptr, unsigned year, unsigned month, unsigned day)
4343
{
44-
Firebird::IMaster* master = Firebird::fb_get_master_interface();
44+
Firebird::IMaster* master = (Firebird::IMaster*)master_ptr;
4545
Firebird::IUtil* util = master->getUtilInterface();
4646
return util->encodeDate(year, month, day);
4747
}
@@ -57,10 +57,10 @@ static void fb_copy_status(const ISC_STATUS* from, ISC_STATUS* to, size_t maxLen
5757
}
5858

5959
/* Decodes a time with time zone into its time components. */
60-
extern "C" void fb_decode_time_tz(const ISC_TIME_TZ* timeTz, unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions,
60+
extern "C" void fb_decode_time_tz(void *master_ptr, const ISC_TIME_TZ* timeTz, unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions,
6161
unsigned timeZoneBufferLength, char* timeZoneBuffer)
6262
{
63-
Firebird::IMaster* master = Firebird::fb_get_master_interface();
63+
Firebird::IMaster* master = (Firebird::IMaster*)master_ptr;
6464
Firebird::IUtil* util = master->getUtilInterface();
6565
Firebird::IStatus* status = master->getStatus();
6666
Firebird::CheckStatusWrapper st(status);
@@ -69,12 +69,12 @@ extern "C" void fb_decode_time_tz(const ISC_TIME_TZ* timeTz, unsigned* hours, un
6969
}
7070

7171
/* Decodes a timestamp with time zone into its date and time components */
72-
extern "C" void fb_decode_timestamp_tz(const ISC_TIMESTAMP_TZ* timestampTz,
72+
extern "C" void fb_decode_timestamp_tz(void *master_ptr, const ISC_TIMESTAMP_TZ* timestampTz,
7373
unsigned* year, unsigned* month, unsigned* day,
7474
unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions,
7575
unsigned timeZoneBufferLength, char* timeZoneBuffer)
7676
{
77-
Firebird::IMaster* master = Firebird::fb_get_master_interface();
77+
Firebird::IMaster* master = (Firebird::IMaster*)master_ptr;
7878
Firebird::IUtil* util = master->getUtilInterface();
7979
Firebird::IStatus* status = master->getStatus();
8080
Firebird::CheckStatusWrapper st(status);
@@ -83,18 +83,14 @@ extern "C" void fb_decode_timestamp_tz(const ISC_TIMESTAMP_TZ* timestampTz,
8383
timeZoneBufferLength, timeZoneBuffer);
8484
}
8585

86-
extern "C" int fb_insert_aliases(ISC_STATUS* st, ibase_query *ib_query)
86+
extern "C" int fb_insert_aliases(void *master_ptr, ISC_STATUS* st, ibase_query *ib_query, void *statement_ptr)
8787
{
88-
Firebird::IMaster* master = Firebird::fb_get_master_interface();
88+
Firebird::IMaster* master = (Firebird::IMaster*)master_ptr;
8989
Firebird::ThrowStatusWrapper status(master->getStatus());
90-
Firebird::IStatement* statement = NULL;
90+
Firebird::IStatement* statement = (Firebird::IStatement *)statement_ptr;
9191
Firebird::IMessageMetadata* meta = NULL;
9292
ISC_STATUS res;
9393

94-
if (res = fb_get_statement_interface(st, &statement, &ib_query->stmt)){
95-
return res;
96-
}
97-
9894
try {
9995
meta = statement->getOutputMetadata(&status);
10096
unsigned cols = meta->getCount(&status);
@@ -118,18 +114,15 @@ extern "C" int fb_insert_aliases(ISC_STATUS* st, ibase_query *ib_query)
118114
return 0;
119115
}
120116

121-
extern "C" int fb_insert_field_info(ISC_STATUS* st, ibase_query *ib_query, int is_outvar, int num, zval *into_array)
117+
extern "C" int fb_insert_field_info(void *master_ptr, ISC_STATUS* st, int is_outvar, int num,
118+
zval *into_array, void *statement_ptr)
122119
{
123-
Firebird::IMaster* master = Firebird::fb_get_master_interface();
120+
Firebird::IMaster* master = (Firebird::IMaster*)master_ptr;
124121
Firebird::ThrowStatusWrapper status(master->getStatus());
125-
Firebird::IStatement* statement = NULL;
122+
Firebird::IStatement* statement = (Firebird::IStatement *)statement_ptr;
126123
Firebird::IMessageMetadata* meta = NULL;
127124
ISC_STATUS res;
128125

129-
if (res = fb_get_statement_interface(st, &statement, &ib_query->stmt)){
130-
return res;
131-
}
132-
133126
try {
134127
if(is_outvar) {
135128
meta = statement->getOutputMetadata(&status);
@@ -157,4 +150,4 @@ extern "C" int fb_insert_field_info(ISC_STATUS* st, ibase_query *ib_query, int i
157150
return 0;
158151
}
159152

160-
#endif
153+
#endif // FB_API_VER >= 40

pdo_firebird_utils.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,24 @@ extern "C" {
2727
#endif
2828

2929
unsigned fb_get_client_version(void *master_ptr);
30+
ISC_TIME fb_encode_time(void *master_ptr, unsigned hours, unsigned minutes, unsigned seconds, unsigned fractions);
31+
ISC_DATE fb_encode_date(void *master_ptr, unsigned year, unsigned month, unsigned day);
3032

31-
void fb_decode_time_tz(const ISC_TIME_TZ* timeTz, unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions,
33+
void fb_decode_time_tz(void *master_ptr, const ISC_TIME_TZ* timeTz, unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions,
3234
unsigned timeZoneBufferLength, char* timeZoneBuffer);
3335

34-
void fb_decode_timestamp_tz(const ISC_TIMESTAMP_TZ* timestampTz,
36+
void fb_decode_timestamp_tz(void *master_ptr, const ISC_TIMESTAMP_TZ* timestampTz,
3537
unsigned* year, unsigned* month, unsigned* day,
3638
unsigned* hours, unsigned* minutes, unsigned* seconds, unsigned* fractions,
3739
unsigned timeZoneBufferLength, char* timeZoneBuffer);
3840

39-
int fb_insert_aliases(ISC_STATUS* st, ibase_query *ib_query);
40-
int fb_insert_field_info(ISC_STATUS* st, ibase_query *ib_query, int is_outvar, int num, zval *into_array);
41+
int fb_insert_aliases(void *master_ptr, ISC_STATUS* st, ibase_query *ib_query, void *statement_ptr);
42+
int fb_insert_field_info(void *master_ptr, ISC_STATUS* st, int is_outvar, int num, zval *into_array, void *statement_ptr);
4143

4244
#ifdef __cplusplus
4345
}
4446
#endif
45-
#endif
47+
48+
#endif // FB_API_VER >= 40
4649

4750
#endif /* PDO_FIREBIRD_UTILS_H */

0 commit comments

Comments
 (0)