From 3fb42a382cdd64015375eec4c3a8d708ea17a06b Mon Sep 17 00:00:00 2001 From: Simonov Denis Date: Fri, 25 Oct 2019 18:38:01 +0200 Subject: [PATCH] Add support for Interbase 1 dialect --- NEWS | 4 ++ UPGRADING | 3 ++ ext/pdo_firebird/firebird_driver.c | 18 +++++--- ext/pdo_firebird/firebird_statement.c | 4 +- ext/pdo_firebird/php_pdo_firebird_int.h | 4 +- ext/pdo_firebird/tests/dialect_1.phpt | 58 +++++++++++++++++++++++++ 6 files changed, 83 insertions(+), 8 deletions(-) create mode 100644 ext/pdo_firebird/tests/dialect_1.phpt diff --git a/NEWS b/NEWS index 01336b9c73..1d6e10fdf7 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,10 @@ PHP NEWS -Opcache: . Fixed bug #78512 (Cannot make preload work). (Dmitry) +- PDO_Firebird: + . Implemented FR #65690 (PDO_Firebird should also support dialect 1). + (Simonov Denis) + - Reflection: . Fixed bug #78697 (ReflectionClass::implementsInterface - inaccurate error message with traits). (villfa) diff --git a/UPGRADING b/UPGRADING index c91d90fbf7..e648f78e80 100644 --- a/UPGRADING +++ b/UPGRADING @@ -591,6 +591,9 @@ PHP 7.4 UPGRADE NOTES exists "?" operator. For more details see the RFC: https://wiki.php.net/rfc/pdo_escape_placeholders +- PDO_Firebird: + . The extension now also support dialect 1 in addition to dialect 3. + - Reflection: . Numeric value of class, property, function and constant modifiers was changed. Don't filter methods and properties through diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index 8b2a128963..b1869f2695 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -417,7 +417,7 @@ static int firebird_alloc_prepare_stmt(pdo_dbh_t *dbh, const char *sql, size_t s } /* prepare the statement */ - if (isc_dsql_prepare(H->isc_status, &H->tr, s, 0, new_sql, PDO_FB_DIALECT, out_sqlda)) { + if (isc_dsql_prepare(H->isc_status, &H->tr, s, 0, new_sql, H->sql_dialect, out_sqlda)) { RECORD_ERROR(dbh); efree(new_sql); return 0; @@ -624,6 +624,7 @@ static int pdo_firebird_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* { "dbname", NULL, 0 }, { "charset", NULL, 0 }, { "role", NULL, 0 }, + { "dialect", "3", 0 }, { "user", NULL, 0 }, { "password", NULL, 0 } }; @@ -632,14 +633,14 @@ static int pdo_firebird_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* pdo_firebird_db_handle *H = dbh->driver_data = pecalloc(1,sizeof(*H),dbh->is_persistent); - php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 5); + php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 6); - if (!dbh->username && vars[3].optval) { - dbh->username = pestrdup(vars[3].optval, dbh->is_persistent); + if (!dbh->username && vars[4].optval) { + dbh->username = pestrdup(vars[4].optval, dbh->is_persistent); } - if (!dbh->password && vars[4].optval) { - dbh->password = pestrdup(vars[4].optval, dbh->is_persistent); + if (!dbh->password && vars[5].optval) { + dbh->password = pestrdup(vars[5].optval, dbh->is_persistent); } do { @@ -660,6 +661,11 @@ static int pdo_firebird_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* } } + H->sql_dialect = PDO_FB_DIALECT; + if (vars[3].optval) { + H->sql_dialect = atoi(vars[3].optval); + } + /* fire it up baby! */ if (isc_attach_database(H->isc_status, 0, vars[0].optval, &H->db,(short)(dpb-dpb_buffer), dpb_buffer)) { break; diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c index 75d7221923..8e9b024f2d 100644 --- a/ext/pdo_firebird/firebird_statement.c +++ b/ext/pdo_firebird/firebird_statement.c @@ -374,7 +374,9 @@ static int firebird_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, /* {{ *ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL); - if (n >= 0) { + if ((var->sqltype & ~1) == SQL_DOUBLE) { + *len = slprintf(*ptr, CHAR_BUF_LEN, "%.*F", -var->sqlscale, *(double*)var->sqldata); + } else if (n >= 0) { *len = slprintf(*ptr, CHAR_BUF_LEN, "%" LL_MASK "d.%0*" LL_MASK "d", n / f, -var->sqlscale, n % f); } else if (n <= -f) { diff --git a/ext/pdo_firebird/php_pdo_firebird_int.h b/ext/pdo_firebird/php_pdo_firebird_int.h index 3694d362c0..dca1a575f0 100644 --- a/ext/pdo_firebird/php_pdo_firebird_int.h +++ b/ext/pdo_firebird/php_pdo_firebird_int.h @@ -86,10 +86,12 @@ typedef struct { char *time_format; char *timestamp_format; + unsigned sql_dialect:2; + /* prepend table names on column names in fetch */ unsigned fetch_table_names:1; - unsigned _reserved:31; + unsigned _reserved:29; } pdo_firebird_db_handle; diff --git a/ext/pdo_firebird/tests/dialect_1.phpt b/ext/pdo_firebird/tests/dialect_1.phpt new file mode 100644 index 0000000000..829025c162 --- /dev/null +++ b/ext/pdo_firebird/tests/dialect_1.phpt @@ -0,0 +1,58 @@ +--TEST-- +PDO_Firebird: support 1 sql dialect +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); + $dbh->setAttribute(PDO::FB_ATTR_TIMESTAMP_FORMAT, '%Y-%m-%d %H:%M:%S'); + + $sql = + 'SELECT + 1 as N, + 2.0 as F, + cast(0.76 as numeric(15, 2)) as K, + cast(\'2019-06-12\' as date) as DT + FROM RDB$DATABASE'; + $query = $dbh->prepare($sql); + $query->execute(); + $row = $query->fetch(\PDO::FETCH_OBJ); + var_dump($row->N); + var_dump($row->F); + var_dump($row->K); + var_dump($row->DT); + + unset($query); + + $dbh->exec('RECREATE TABLE test_d1(K numeric(15, 2), DT date)'); + $sql='INSERT INTO test_d1(K, DT) values(?, ?)'; + $query = $dbh->prepare($sql); + $query->execute([0.76, '2019-06-12']); + unset($query); + + $sql='SELECT * FROM test_d1'; + $query = $dbh->prepare($sql); + $query->execute(); + $row = $query->fetch(\PDO::FETCH_OBJ); + var_dump($row->K); + var_dump($row->DT); + + unset($query); + unset($dbh); + echo "done\n"; + +?> +--EXPECT-- +int(1) +string(8) "2.000000" +string(4) "0.76" +string(19) "2019-06-12 00:00:00" +string(4) "0.76" +string(19) "2019-06-12 00:00:00" +done -- 2.40.0