Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
1a7cead
Move identity cache from PHP into the Rust extension
adamziel Apr 30, 2026
c8b4037
Apply rustfmt formatting
adamziel Apr 30, 2026
ea2a4d1
rustfmt: collapse short match arm
adamziel Apr 30, 2026
50189eb
Pass &mut ZendObject to Zval::set_object in ext-php-rs 0.15
adamziel Apr 30, 2026
30a38ae
Take &mut ZendObject from cache instead of casting &T to &mut T
adamziel Apr 30, 2026
0c945e0
Add cycle-collection tests for the Rust-side identity cache
adamziel Apr 30, 2026
079968b
Add custom gc_handler for WP_MySQL_Native_Ast
adamziel Apr 30, 2026
9d668b2
rustfmt: collapse and wrap
adamziel Apr 30, 2026
7b1ad32
rustfmt: wrap long if-let line
adamziel Apr 30, 2026
89a4619
Patch GC handler per-instance for PHP 8.2 compat
adamziel Apr 30, 2026
778ee69
Replace zend_get_gc_buffer_* with a Rust-owned trace buffer
adamziel Apr 30, 2026
f6b0a52
Move native_ast lookup before gc handler install (debug)
adamziel Apr 30, 2026
a5fe11f
DEBUG: disable install_gc_handler_for to localize CI failure
adamziel Apr 30, 2026
d67fec5
Patch get_gc in-place on the shared handlers struct
adamziel Apr 30, 2026
85081fd
DEBUG: make get_gc a no-op to localize segfault
adamziel Apr 30, 2026
1f7ce2a
Re-enable trace zval construction with the in-place handler patch
adamziel Apr 30, 2026
8b24b49
Revert gc_handler attempt; mark cycle tests incomplete
adamziel Apr 30, 2026
4778276
Make Rust AST cache GC-safe
adamziel May 1, 2026
790556c
Retry SQLite source downloads in PHPUnit workflow
adamziel May 1, 2026
ed685e3
Fallback to SQLite GitHub mirror in CI
adamziel May 1, 2026
d349802
Break native AST wrapper cycles
adamziel May 1, 2026
2d93be2
Update native parser CI smoke checks
adamziel May 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions .github/workflows/mysql-parser-extension-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,31 @@ jobs:
$parser = $driver->create_parser( "SELECT 1" );
$parser->next_query();
$ast = $parser->get_query_ast();
$property = ( new ReflectionClass( $ast ) )->getProperty( "native_ast" );
$property->setAccessible( true );
$native_ast = $property->getValue( $ast );
if ( ! is_object( $native_ast ) || "WP_MySQL_Native_Ast" !== get_class( $native_ast ) ) {
if ( ! ( $ast instanceof WP_MySQL_Native_Parser_Node ) ) {
fwrite( STDERR, "SQLite driver did not return a native-backed AST.\n" );
exit( 1 );
}
$reflection = new ReflectionObject( $ast );
if ( $reflection->hasProperty( "native_ast" ) || $reflection->hasProperty( "native_node_index" ) ) {
fwrite( STDERR, "Native wrapper still stores Rust AST handle properties.\n" );
exit( 1 );
}
$first = $ast->get_first_child_node();
if ( ! ( $first instanceof WP_MySQL_Native_Parser_Node ) ) {
fwrite( STDERR, "Native wrapper did not return a native-backed child node.\n" );
exit( 1 );
}
if ( $first !== $ast->get_first_child_node() ) {
fwrite( STDERR, "Native wrapper identity is not stable across reads.\n" );
exit( 1 );
}
$synthetic = new WP_Parser_Node( 0, "synthetic" );
$first->append_child( $synthetic );
$same_first = $ast->get_first_child_node();
if ( $same_first !== $first || ! in_array( $synthetic, $same_first->get_children(), true ) ) {
fwrite( STDERR, "Materialized native wrapper was lost from the parent cache.\n" );
exit( 1 );
}
'

- name: Run PHPUnit tests with SQLite driver using parser extension
Expand Down
25 changes: 24 additions & 1 deletion .github/workflows/phpunit-tests-run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,31 @@ jobs:
else
TAG="version-${VERSION}"
fi
wget -O sqlite.tar.gz "https://sqlite.org/src/tarball/sqlite.tar.gz?r=${TAG}"
SQLITE_SOURCE="https://sqlite.org/src/tarball/sqlite.tar.gz?r=${TAG}"
SQLITE_MIRROR="https://github.com/sqlite/sqlite/archive/refs/tags/${TAG}.tar.gz"
DOWNLOADED=0
for url in "$SQLITE_SOURCE" "$SQLITE_MIRROR"; do
for attempt in 1 2 3 4 5; do
if wget -O sqlite.tar.gz "$url"; then
DOWNLOADED=1
break 2
fi
if [ "$attempt" -lt 5 ]; then
sleep $(( attempt * 10 ))
fi
done
done
if [ "$DOWNLOADED" -ne 1 ]; then
exit 1
fi
tar xzf sqlite.tar.gz
if [ ! -d sqlite ]; then
SQLITE_DIR=$(find . -maxdepth 1 -type d -name 'sqlite-*' | head -n 1)
if [ -z "$SQLITE_DIR" ]; then
exit 1
fi
mv "$SQLITE_DIR" sqlite
fi
cd sqlite
./configure --prefix=/usr/local CFLAGS="-DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_FTS5 -DSQLITE_USE_URI -DSQLITE_ENABLE_JSON1" LDFLAGS="-lm"
make -j$(nproc)
Expand Down
30 changes: 26 additions & 4 deletions .github/workflows/wp-tests-phpunit-native-extension-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,36 @@ $driver = new WP_PDO_MySQL_On_SQLite( 'mysql-on-sqlite:path=:memory:;dbname=wp;'
$parser = $driver->create_parser( 'SELECT 1' );
$parser->next_query();
$ast = $parser->get_query_ast();
$property = ( new ReflectionClass( $ast ) )->getProperty( 'native_ast' );
$property->setAccessible( true );
$native_ast = $property->getValue( $ast );

if ( ! is_object( $native_ast ) || 'WP_MySQL_Native_Ast' !== get_class( $native_ast ) ) {
if ( ! ( $ast instanceof WP_MySQL_Native_Parser_Node ) ) {
fwrite( STDERR, "WordPress PHP test container did not select the native-backed AST.\n" );
exit( 1 );
}

$reflection = new ReflectionObject( $ast );
if ( $reflection->hasProperty( 'native_ast' ) || $reflection->hasProperty( 'native_node_index' ) ) {
fwrite( STDERR, "Native wrapper still stores Rust AST handle properties.\n" );
exit( 1 );
}

$first = $ast->get_first_child_node();
if ( ! ( $first instanceof WP_MySQL_Native_Parser_Node ) ) {
fwrite( STDERR, "Native wrapper did not return a native-backed child node.\n" );
exit( 1 );
}

if ( $first !== $ast->get_first_child_node() ) {
fwrite( STDERR, "Native wrapper identity is not stable across reads.\n" );
exit( 1 );
}

$synthetic = new WP_Parser_Node( 0, 'synthetic' );
$first->append_child( $synthetic );
$same_first = $ast->get_first_child_node();
if ( $same_first !== $first || ! in_array( $synthetic, $same_first->get_children(), true ) ) {
fwrite( STDERR, "Materialized native wrapper was lost from the parent cache.\n" );
exit( 1 );
}
EOF

node tools/local-env/scripts/docker.js run --rm php php -m | grep -qx 'wp_mysql_parser'
Expand Down
1 change: 0 additions & 1 deletion packages/mysql-on-sqlite/src/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@

if ( class_exists( 'WP_MySQL_Native_Parser', false ) ) {
require_once __DIR__ . '/mysql/native/mysql-rust-bridge.php';
require_once __DIR__ . '/mysql/native/class-wp-mysql-native-ast-cache.php';
require_once __DIR__ . '/mysql/native/class-wp-mysql-native-parser-node.php';
require_once __DIR__ . '/mysql/native/class-wp-mysql-parser.php';
} else {
Expand Down

This file was deleted.

Loading
Loading