@@ -460,6 +460,56 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa
460460 return 1 ;
461461}
462462
463+ #if FB_API_VER >= 40
464+ /* set coercing a data type */
465+ static void set_coercing_data_type (XSQLDA * sqlda )
466+ {
467+ /* Data types introduced in Firebird 4.0 are difficult to process using the Firebird Legacy API. */
468+ /* These data types include DECFLOAT(16), DECFLOAT(34), INT128 (NUMERIC/DECIMAL(38, x)), */
469+ /* TIMESTAMP WITH TIME ZONE, and TIME WITH TIME ZONE. In any case, at least the first three data types */
470+ /* can only be mapped to strings. The last two too, but for them it is potentially possible to set */
471+ /* the display format, as is done for TIMESTAMP. This function allows you to ensure minimal performance */
472+ /* of queries if they contain columns and parameters of the above types. */
473+ unsigned int i ;
474+ short dtype ;
475+ short nullable ;
476+ XSQLVAR * var ;
477+ for (i = 0 , var = sqlda -> sqlvar ; i < sqlda -> sqld ; i ++ , var ++ ) {
478+ dtype = (var -> sqltype & ~1 ); /* drop flag bit */
479+ nullable = (var -> sqltype & 1 );
480+ switch (dtype ) {
481+ case SQL_INT128 :
482+ var -> sqltype = SQL_VARYING + nullable ;
483+ var -> sqllen = 46 ;
484+ var -> sqlscale = 0 ;
485+ break ;
486+
487+ case SQL_DEC16 :
488+ var -> sqltype = SQL_VARYING + nullable ;
489+ var -> sqllen = 24 ;
490+ break ;
491+
492+ case SQL_DEC34 :
493+ var -> sqltype = SQL_VARYING + nullable ;
494+ var -> sqllen = 43 ;
495+ break ;
496+
497+ case SQL_TIMESTAMP_TZ :
498+ var -> sqltype = SQL_VARYING + nullable ;
499+ var -> sqllen = 58 ;
500+ break ;
501+
502+ case SQL_TIME_TZ :
503+ var -> sqltype = SQL_VARYING + nullable ;
504+ var -> sqllen = 46 ;
505+ break ;
506+ default :
507+ break ;
508+ }
509+ }
510+ }
511+ #endif
512+
463513/* map driver specific error message to PDO error */
464514void php_firebird_set_error (pdo_dbh_t * dbh , pdo_stmt_t * stmt , const char * state , const size_t state_len ,
465515 const char * msg , const size_t msg_len ) /* {{{ */
@@ -605,6 +655,11 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */
605655 break ;
606656 }
607657
658+ #if FB_API_VER >= 40
659+ /* set coercing a data type */
660+ set_coercing_data_type (& S -> out_sqlda );
661+ #endif
662+
608663 /* allocate the input descriptors */
609664 if (isc_dsql_describe_bind (H -> isc_status , & s , PDO_FB_SQLDA_VERSION , & num_sqlda )) {
610665 break ;
@@ -618,6 +673,11 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */
618673 if (isc_dsql_describe_bind (H -> isc_status , & s , PDO_FB_SQLDA_VERSION , S -> in_sqlda )) {
619674 break ;
620675 }
676+
677+ #if FB_API_VER >= 40
678+ /* set coercing a data type */
679+ set_coercing_data_type (S -> in_sqlda );
680+ #endif
621681 }
622682
623683 stmt -> driver_data = S ;
0 commit comments