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.

close GH-18829
This commit is contained in:
David Carlier 2025-06-10 19:24:35 +01:00
parent 5740038026
commit 71a254489c
No known key found for this signature in database
GPG key ID: 2FB76A8CE6CD2B41
7 changed files with 511 additions and 3 deletions

View file

@ -26,6 +26,11 @@
#include "php_pdo_sqlite.h"
#include "php_pdo_sqlite_int.h"
#if defined(__APPLE__)
// If more than one usage, a Zend macro could be created
// around this runtime check
#include <Availability.h>
#endif
static int pdo_sqlite_stmt_dtor(pdo_stmt_t *stmt)
{
@ -387,6 +392,23 @@ static int pdo_sqlite_stmt_get_attribute(pdo_stmt_t *stmt, zend_long attr, zval
ZVAL_TRUE(val);
}
break;
case PDO_SQLITE_ATTR_EXPLAIN_STATEMENT:
#if SQLITE_VERSION_NUMBER >= 3041000
#if defined(__APPLE__)
if (__builtin_available(macOS 14.2, *)) {
#endif
ZVAL_LONG(val, (zend_long)sqlite3_stmt_isexplain(S->stmt));
return 1;
#if defined(__APPLE__)
} else {
zend_value_error("explain statement unsupported");
return 0;
}
#endif
#else
zend_value_error("explain statement unsupported");
return 0;
#endif
default:
return 0;
}
@ -394,6 +416,46 @@ static int pdo_sqlite_stmt_get_attribute(pdo_stmt_t *stmt, zend_long attr, zval
return 1;
}
static int pdo_sqlite_stmt_set_attribute(pdo_stmt_t *stmt, zend_long attr, zval *zval)
{
pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
switch (attr) {
case PDO_SQLITE_ATTR_EXPLAIN_STATEMENT:
#if SQLITE_VERSION_NUMBER >= 3041000
#if defined(__APPLE__)
if (__builtin_available(macOS 14.2, *)) {
#endif
if (Z_TYPE_P(zval) != IS_LONG) {
zend_type_error("explain mode must be of type int, %s given", zend_zval_value_name(zval));
return 0;
}
if (Z_LVAL_P(zval) < 0 || Z_LVAL_P(zval) > 2) {
zend_value_error("explain mode must be one of the EXPLAIN_MODE_* constants");
return 0;
}
if (sqlite3_stmt_explain(S->stmt, (int)Z_LVAL_P(zval)) != SQLITE_OK) {
return 0;
}
return 1;
#if defined(__APPLE__)
} else {
zend_value_error("explain statement unsupported");
return 0;
}
#endif
#else
zend_value_error("explain statement unsupported");
return 0;
#endif
default:
return 0;
}
return 1;
}
const struct pdo_stmt_methods sqlite_stmt_methods = {
pdo_sqlite_stmt_dtor,
pdo_sqlite_stmt_execute,
@ -401,7 +463,7 @@ const struct pdo_stmt_methods sqlite_stmt_methods = {
pdo_sqlite_stmt_describe,
pdo_sqlite_stmt_get_col,
pdo_sqlite_stmt_param_hook,
NULL, /* set_attr */
pdo_sqlite_stmt_set_attribute, /* set_attr */
pdo_sqlite_stmt_get_attribute, /* get_attr */
pdo_sqlite_stmt_col_meta,
NULL, /* next_rowset */