Skip to content

Commit 38514c1

Browse files
committed
ext/pdo_sqlite: add ATTR_SQL and ATTR_EXPANDED_SQL statement attributes
Add support for retrieving the SQL text of a prepared statement via PDOStatement::getAttribute(), mirroring SQLite3Stmt::getSQL(). Pdo\Sqlite::ATTR_SQL - original SQL text (sqlite3_sql) Pdo\Sqlite::ATTR_EXPANDED_SQL - SQL with bound parameters expanded (sqlite3_expanded_sql) Closes GH-21322
1 parent 72d1b29 commit 38514c1

File tree

8 files changed

+91
-2
lines changed

8 files changed

+91
-2
lines changed

ext/pdo_sqlite/config.m4

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ if test "$PHP_PDO_SQLITE" != "no"; then
1717
[],
1818
[$PDO_SQLITE_SHARED_LIBADD])
1919

20+
PHP_CHECK_LIBRARY([sqlite3], [sqlite3_expanded_sql],
21+
[AC_DEFINE([HAVE_SQLITE3_EXPANDED_SQL], [1],
22+
[Define to 1 if SQLite library has the 'sqlite3_expanded_sql'
23+
function.])],
24+
[],
25+
[$PDO_SQLITE_SHARED_LIBADD])
26+
2027
PHP_CHECK_LIBRARY([sqlite3], [sqlite3_load_extension],
2128
[],
2229
[AC_DEFINE([PDO_SQLITE_OMIT_LOAD_EXTENSION], [1],

ext/pdo_sqlite/config.w32

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ if (PHP_PDO_SQLITE != "no") {
88

99
ADD_EXTENSION_DEP('pdo_sqlite', 'pdo');
1010
AC_DEFINE("HAVE_SQLITE3_COLUMN_TABLE_NAME", 1, "Define to 1 if SQLite library was compiled with the SQLITE_ENABLE_COLUMN_METADATA and has the 'sqlite3_column_table_name' function.");
11+
AC_DEFINE("HAVE_SQLITE3_EXPANDED_SQL", 1, "Define to 1 if SQLite library has the 'sqlite3_expanded_sql' function.");
1112
ADD_MAKEFILE_FRAGMENT();
1213
} else {
1314
WARNING("pdo_sqlite not enabled; libraries and/or headers not found");

ext/pdo_sqlite/pdo_sqlite.stub.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ class Sqlite extends \PDO
4242
/** @cvalue PDO_SQLITE_ATTR_TRANSACTION_MODE */
4343
public const int ATTR_TRANSACTION_MODE = UNKNOWN;
4444

45+
/** @cvalue PDO_SQLITE_ATTR_SQL */
46+
public const int ATTR_SQL = UNKNOWN;
47+
48+
#ifdef HAVE_SQLITE3_EXPANDED_SQL
49+
/** @cvalue PDO_SQLITE_ATTR_EXPANDED_SQL */
50+
public const int ATTR_EXPANDED_SQL = UNKNOWN;
51+
#endif
52+
4553
public const int TRANSACTION_MODE_DEFERRED = 0;
4654
public const int TRANSACTION_MODE_IMMEDIATE = 1;
4755
public const int TRANSACTION_MODE_EXCLUSIVE = 2;

ext/pdo_sqlite/pdo_sqlite_arginfo.h

Lines changed: 15 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/pdo_sqlite/php_pdo_sqlite_int.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ enum {
7777
PDO_SQLITE_ATTR_EXTENDED_RESULT_CODES,
7878
PDO_SQLITE_ATTR_BUSY_STATEMENT,
7979
PDO_SQLITE_ATTR_EXPLAIN_STATEMENT,
80-
PDO_SQLITE_ATTR_TRANSACTION_MODE
80+
PDO_SQLITE_ATTR_TRANSACTION_MODE,
81+
PDO_SQLITE_ATTR_SQL,
82+
PDO_SQLITE_ATTR_EXPANDED_SQL
8183
};
8284

8385
typedef int pdo_sqlite_create_collation_callback(void*, int, const void*, int, const void*);

ext/pdo_sqlite/sqlite_statement.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,32 @@ static int pdo_sqlite_stmt_get_attribute(pdo_stmt_t *stmt, zend_long attr, zval
408408
zend_value_error("explain statement unsupported");
409409
return 0;
410410
#endif
411+
case PDO_SQLITE_ATTR_SQL: {
412+
const char *sql = sqlite3_sql(S->stmt);
413+
if (sql) {
414+
ZVAL_STRING(val, sql);
415+
} else {
416+
ZVAL_NULL(val);
417+
}
418+
return 1;
419+
}
420+
421+
case PDO_SQLITE_ATTR_EXPANDED_SQL: {
422+
#ifdef HAVE_SQLITE3_EXPANDED_SQL
423+
char *sql = sqlite3_expanded_sql(S->stmt);
424+
if (sql) {
425+
ZVAL_STRING(val, sql);
426+
sqlite3_free(sql);
427+
} else {
428+
ZVAL_NULL(val);
429+
}
430+
return 1;
431+
#else
432+
zend_value_error("expanded sql unsupported");
433+
return -1;
434+
#endif
435+
}
436+
411437
default:
412438
return 0;
413439
}

ext/pdo_sqlite/tests/subclasses/pdo_sqlite_constants.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ var_dump(Pdo\Sqlite::OPEN_CREATE);
1414
var_dump(Pdo\Sqlite::ATTR_READONLY_STATEMENT);
1515
var_dump(Pdo\Sqlite::ATTR_EXTENDED_RESULT_CODES);
1616
var_dump(Pdo\Sqlite::ATTR_BUSY_STATEMENT);
17+
var_dump(Pdo\Sqlite::ATTR_SQL);
1718

1819
?>
1920
--EXPECTF--
@@ -26,3 +27,4 @@ int(%d)
2627
int(%d)
2728
int(%d)
2829
int(%d)
30+
int(%d)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
Pdo\Sqlite::ATTR_SQL and Pdo\Sqlite::ATTR_EXPANDED_SQL usage
3+
--EXTENSIONS--
4+
pdo_sqlite
5+
--SKIPIF--
6+
<?php
7+
if (!defined('Pdo\Sqlite::ATTR_EXPANDED_SQL')) die('skip sqlite3_expanded_sql not available');
8+
?>
9+
--FILE--
10+
<?php
11+
12+
$db = new Pdo\Sqlite('sqlite::memory:');
13+
14+
$stmt = $db->prepare('SELECT :name AS greeting, :num AS number');
15+
var_dump($stmt->getAttribute(Pdo\Sqlite::ATTR_SQL));
16+
var_dump($stmt->getAttribute(Pdo\Sqlite::ATTR_EXPANDED_SQL));
17+
18+
$stmt->bindValue(':name', 'hello world');
19+
$stmt->bindValue(':num', 42, PDO::PARAM_INT);
20+
$stmt->execute();
21+
22+
var_dump($stmt->getAttribute(Pdo\Sqlite::ATTR_SQL));
23+
var_dump($stmt->getAttribute(Pdo\Sqlite::ATTR_EXPANDED_SQL));
24+
?>
25+
--EXPECT--
26+
string(40) "SELECT :name AS greeting, :num AS number"
27+
string(39) "SELECT NULL AS greeting, NULL AS number"
28+
string(40) "SELECT :name AS greeting, :num AS number"
29+
string(46) "SELECT 'hello world' AS greeting, 42 AS number"

0 commit comments

Comments
 (0)