Skip to content

Commit 12d404b

Browse files
committed
ext/pdo_sqlite: EXPLAIN mode support for SQL statements.
available since 3.41.0 we can reprepare a statement in either explain, explain query plan or the usual prepared mode.
1 parent 5740607 commit 12d404b

File tree

5 files changed

+75
-3
lines changed

5 files changed

+75
-3
lines changed

ext/pdo_sqlite/pdo_sqlite.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "ext/pdo/php_pdo_driver.h"
2727
#include "php_pdo_sqlite.h"
2828
#include "php_pdo_sqlite_int.h"
29+
#include "zend_enum.h"
2930
#include "zend_exceptions.h"
3031
#include "pdo_sqlite_arginfo.h"
3132

ext/pdo_sqlite/pdo_sqlite.stub.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ class Sqlite extends \PDO
3636
/** @cvalue PDO_SQLITE_ATTR_BUSY_STATEMENT */
3737
public const int ATTR_BUSY_STATEMENT = UNKNOWN;
3838

39+
/** @cvalue PDO_SQLITE_ATTR_EXPLAIN_STATEMENT */
40+
public const int ATTR_EXPLAIN_STATEMENT = UNKNOWN;
41+
42+
public const int EXPLAIN_MODE_PREPARED = 0;
43+
public const int EXPLAIN_MODE_EXPLAIN = 1;
44+
public const int EXPLAIN_MODE_EXPLAIN_QUERY_PLAN = 2;
45+
3946
/** @cvalue SQLITE_OK */
4047
public const int OK = UNKNOWN;
4148

ext/pdo_sqlite/pdo_sqlite_arginfo.h

Lines changed: 25 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: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ enum {
7474
PDO_SQLITE_ATTR_OPEN_FLAGS = PDO_ATTR_DRIVER_SPECIFIC,
7575
PDO_SQLITE_ATTR_READONLY_STATEMENT,
7676
PDO_SQLITE_ATTR_EXTENDED_RESULT_CODES,
77-
PDO_SQLITE_ATTR_BUSY_STATEMENT
77+
PDO_SQLITE_ATTR_BUSY_STATEMENT,
78+
PDO_SQLITE_ATTR_EXPLAIN_STATEMENT
7879
};
7980

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

ext/pdo_sqlite/sqlite_statement.c

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,21 +387,60 @@ static int pdo_sqlite_stmt_get_attribute(pdo_stmt_t *stmt, zend_long attr, zval
387387
ZVAL_TRUE(val);
388388
}
389389
break;
390+
case PDO_SQLITE_ATTR_EXPLAIN_STATEMENT:
391+
#if SQLITE_VERSION_NUMBER >= 3041000
392+
ZVAL_LONG(val, (zend_long)sqlite3_stmt_isexplain(S->stmt));
393+
return 1;
394+
#else
395+
zend_value_error("explain statement unsupported");
396+
return 0;
397+
#endif
390398
default:
391399
return 0;
392400
}
393401

394402
return 1;
395403
}
396404

405+
static int pdo_sqlite_stmt_set_attribute(pdo_stmt_t *stmt, zend_long attr, zval *zval)
406+
{
407+
pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
408+
409+
switch (attr) {
410+
case PDO_SQLITE_ATTR_EXPLAIN_STATEMENT:
411+
#if SQLITE_VERSION_NUMBER >= 3041000
412+
if (Z_TYPE_P(zval) != IS_LONG) {
413+
zend_type_error("explain mode must be of type int");
414+
return 0;
415+
}
416+
if (Z_TYPE_P(zval) < 0 || Z_TYPE_P(zval) > 2) {
417+
zend_value_error("explain mode must be one of the EXPLAIN_MODE_* constants");
418+
return 0;
419+
}
420+
if (sqlite3_stmt_explain(S->stmt, (int)Z_LVAL_P(zval)) != SQLITE_OK) {
421+
return 0;
422+
}
423+
424+
return 1;
425+
#else
426+
zend_value_error("explain statement unsupported");
427+
return 0;
428+
#endif
429+
default:
430+
return 0;
431+
}
432+
433+
return 1;
434+
}
435+
397436
const struct pdo_stmt_methods sqlite_stmt_methods = {
398437
pdo_sqlite_stmt_dtor,
399438
pdo_sqlite_stmt_execute,
400439
pdo_sqlite_stmt_fetch,
401440
pdo_sqlite_stmt_describe,
402441
pdo_sqlite_stmt_get_col,
403442
pdo_sqlite_stmt_param_hook,
404-
NULL, /* set_attr */
443+
pdo_sqlite_stmt_set_attribute, /* set_attr */
405444
pdo_sqlite_stmt_get_attribute, /* get_attr */
406445
pdo_sqlite_stmt_col_meta,
407446
NULL, /* next_rowset */

0 commit comments

Comments
 (0)