Skip to content

Commit 22bd2ae

Browse files
committed
ext/sqlite3: explain statement support addition.
similar to what have been done for pdo/sqlite as having statement explain support to simulate how a query would operate or for more advanced users, analysing the VM routines used for possible optimisations. close GH-18853
1 parent e931017 commit 22bd2ae

File tree

5 files changed

+500
-1
lines changed

5 files changed

+500
-1
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,8 @@ PHP NEWS
247247
- Sqlite:
248248
. Added Sqlite3Stmt::busy to check if a statement is still being executed.
249249
(David Carlier)
250+
. Added Sqlite3Stmt::explain to produce a explain query plan from
251+
the statement. (David Carlier)
250252

251253
- Standard:
252254
. Fixed crypt() tests on musl when using --with-external-libcrypt

ext/sqlite3/sqlite3.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
#include "SAPI.h"
2727

2828
#include <sqlite3.h>
29+
#ifdef __APPLE__
30+
#include <Availability.h>
31+
#endif
2932

3033
#include "zend_exceptions.h"
3134
#include "sqlite3_arginfo.h"
@@ -1500,6 +1503,60 @@ PHP_METHOD(SQLite3Stmt, busy)
15001503
RETURN_FALSE;
15011504
}
15021505

1506+
#if SQLITE_VERSION_NUMBER >= 3043000
1507+
PHP_METHOD(SQLite3Stmt, explain)
1508+
{
1509+
#ifdef __APPLE__
1510+
if (__builtin_available(macOS 14.2, *)) {
1511+
#endif
1512+
php_sqlite3_stmt *stmt_obj;
1513+
zval *object = ZEND_THIS;
1514+
stmt_obj = Z_SQLITE3_STMT_P(object);
1515+
1516+
ZEND_PARSE_PARAMETERS_NONE();
1517+
1518+
SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1519+
SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1520+
1521+
RETURN_LONG((zend_long)sqlite3_stmt_isexplain(stmt_obj->stmt));
1522+
#ifdef __APPLE__
1523+
} else {
1524+
zend_throw_error(NULL, "explain statement unsupported");
1525+
}
1526+
#endif
1527+
}
1528+
1529+
PHP_METHOD(SQLite3Stmt, setExplain)
1530+
{
1531+
#ifdef __APPLE__
1532+
if (__builtin_available(macOS 14.2, *)) {
1533+
#endif
1534+
php_sqlite3_stmt *stmt_obj;
1535+
zend_long mode;
1536+
zval *object = ZEND_THIS;
1537+
stmt_obj = Z_SQLITE3_STMT_P(object);
1538+
1539+
ZEND_PARSE_PARAMETERS_START(1, 1)
1540+
Z_PARAM_LONG(mode)
1541+
ZEND_PARSE_PARAMETERS_END();
1542+
1543+
if (mode < 0 || mode > 2) {
1544+
zend_argument_value_error(1, "must be one of the SQLite3Stmt::EXPLAIN_MODE_* constants");
1545+
RETURN_THROWS();
1546+
}
1547+
1548+
SQLITE3_CHECK_INITIALIZED(stmt_obj->db_obj, stmt_obj->initialised, SQLite3);
1549+
SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt);
1550+
1551+
RETURN_BOOL(sqlite3_stmt_explain(stmt_obj->stmt, (int)mode) == SQLITE_OK);
1552+
#ifdef __APPLE__
1553+
} else {
1554+
zend_throw_error(NULL, "explain statement unsupported");
1555+
}
1556+
#endif
1557+
}
1558+
#endif
1559+
15031560
/* bind parameters to a statement before execution */
15041561
static int php_sqlite3_bind_params(php_sqlite3_stmt *stmt_obj) /* {{{ */
15051562
{

ext/sqlite3/sqlite3.stub.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,15 @@ public function readOnly(): bool {}
274274
public function reset(): bool {}
275275

276276
public function busy(): bool {}
277+
278+
#if SQLITE_VERSION_NUMBER >= 3043000
279+
public const int EXPLAIN_MODE_PREPARED = 0;
280+
public const int EXPLAIN_MODE_EXPLAIN = 1;
281+
public const int EXPLAIN_MODE_EXPLAIN_QUERY_PLAN = 2;
282+
283+
public function explain(): int {}
284+
public function setExplain(int $mode): bool {}
285+
#endif
277286
}
278287

279288
/** @not-serializable */

ext/sqlite3/sqlite3_arginfo.h

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

0 commit comments

Comments
 (0)