Skip to content

Commit 6736286

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.
1 parent 2e2494f commit 6736286

File tree

3 files changed

+108
-1
lines changed

3 files changed

+108
-1
lines changed

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"
@@ -1496,6 +1499,60 @@ PHP_METHOD(SQLite3Stmt, busy)
14961499
RETURN_FALSE;
14971500
}
14981501

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

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)