Skip to content

Commit 830a9b2

Browse files
committed
Add lazy native parser node facade
When a native parser is in use, expose query results through a node class that defers child materialization until callers actually walk the tree. The base WP_Parser_Node::$children visibility is loosened to protected so the facade can populate it on demand.
1 parent 0f3cbb6 commit 830a9b2

3 files changed

Lines changed: 179 additions & 1 deletion

File tree

packages/mysql-on-sqlite/src/load.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
if ( class_exists( 'WP_MySQL_Native_Parser', false ) ) {
2929
require_once __DIR__ . '/mysql/mysql-rust-bridge.php';
30+
require_once __DIR__ . '/mysql/class-wp-mysql-native-parser-node.php';
3031
require_once __DIR__ . '/mysql/native/class-wp-mysql-parser.php';
3132
} else {
3233
require_once __DIR__ . '/mysql/class-wp-mysql-parser.php';
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
<?php
2+
3+
/**
4+
* Native-backed parser node.
5+
*
6+
* This subclass keeps the regular WP_Parser_Node API while delegating lazy AST
7+
* reads to the optional native MySQL parser extension. The base node remains a
8+
* plain PHP tree node for the polyfill parser.
9+
*/
10+
class WP_MySQL_Native_Parser_Node extends WP_Parser_Node {
11+
private $native_ast = null;
12+
private $native_node_index = null;
13+
14+
public function __construct( $rule_id, $rule_name, $native_ast = null, $native_node_index = null ) {
15+
parent::__construct( $rule_id, $rule_name );
16+
17+
$this->native_ast = $native_ast;
18+
$this->native_node_index = $native_node_index;
19+
}
20+
21+
/** @inheritDoc */
22+
public function append_child( $node ) {
23+
$this->materialize_native_children();
24+
parent::append_child( $node );
25+
}
26+
27+
/** @inheritDoc */
28+
public function merge_fragment( $node ) {
29+
$this->materialize_native_children();
30+
if ( $node instanceof self ) {
31+
$node->materialize_native_children();
32+
}
33+
parent::merge_fragment( $node );
34+
}
35+
36+
/** @inheritDoc */
37+
public function has_child(): bool {
38+
if ( $this->has_native_ast() ) {
39+
return wp_sqlite_mysql_native_ast_has_child( $this->native_ast, $this->native_node_index );
40+
}
41+
return parent::has_child();
42+
}
43+
44+
/** @inheritDoc */
45+
public function has_child_node( ?string $rule_name = null ): bool {
46+
if ( $this->has_native_ast() ) {
47+
return wp_sqlite_mysql_native_ast_has_child_node( $this->native_ast, $this->native_node_index, $rule_name );
48+
}
49+
return parent::has_child_node( $rule_name );
50+
}
51+
52+
/** @inheritDoc */
53+
public function has_child_token( ?int $token_id = null ): bool {
54+
if ( $this->has_native_ast() ) {
55+
return wp_sqlite_mysql_native_ast_has_child_token( $this->native_ast, $this->native_node_index, $token_id );
56+
}
57+
return parent::has_child_token( $token_id );
58+
}
59+
60+
/** @inheritDoc */
61+
public function get_first_child() {
62+
if ( $this->has_native_ast() ) {
63+
return wp_sqlite_mysql_native_ast_get_first_child( $this->native_ast, $this->native_node_index );
64+
}
65+
return parent::get_first_child();
66+
}
67+
68+
/** @inheritDoc */
69+
public function get_first_child_node( ?string $rule_name = null ): ?WP_Parser_Node {
70+
if ( $this->has_native_ast() ) {
71+
return wp_sqlite_mysql_native_ast_get_first_child_node( $this->native_ast, $this->native_node_index, $rule_name );
72+
}
73+
return parent::get_first_child_node( $rule_name );
74+
}
75+
76+
/** @inheritDoc */
77+
public function get_first_child_token( ?int $token_id = null ): ?WP_Parser_Token {
78+
if ( $this->has_native_ast() ) {
79+
return wp_sqlite_mysql_native_ast_get_first_child_token( $this->native_ast, $this->native_node_index, $token_id );
80+
}
81+
return parent::get_first_child_token( $token_id );
82+
}
83+
84+
/** @inheritDoc */
85+
public function get_first_descendant_node( ?string $rule_name = null ): ?WP_Parser_Node {
86+
if ( $this->has_native_ast() ) {
87+
return wp_sqlite_mysql_native_ast_get_first_descendant_node( $this->native_ast, $this->native_node_index, $rule_name );
88+
}
89+
return parent::get_first_descendant_node( $rule_name );
90+
}
91+
92+
/** @inheritDoc */
93+
public function get_first_descendant_token( ?int $token_id = null ): ?WP_Parser_Token {
94+
if ( $this->has_native_ast() ) {
95+
return wp_sqlite_mysql_native_ast_get_first_descendant_token( $this->native_ast, $this->native_node_index, $token_id );
96+
}
97+
return parent::get_first_descendant_token( $token_id );
98+
}
99+
100+
/** @inheritDoc */
101+
public function get_children(): array {
102+
if ( $this->has_native_ast() ) {
103+
return wp_sqlite_mysql_native_ast_get_children( $this->native_ast, $this->native_node_index );
104+
}
105+
return parent::get_children();
106+
}
107+
108+
/** @inheritDoc */
109+
public function get_child_nodes( ?string $rule_name = null ): array {
110+
if ( $this->has_native_ast() ) {
111+
return wp_sqlite_mysql_native_ast_get_child_nodes( $this->native_ast, $this->native_node_index, $rule_name );
112+
}
113+
return parent::get_child_nodes( $rule_name );
114+
}
115+
116+
/** @inheritDoc */
117+
public function get_child_tokens( ?int $token_id = null ): array {
118+
if ( $this->has_native_ast() ) {
119+
return wp_sqlite_mysql_native_ast_get_child_tokens( $this->native_ast, $this->native_node_index, $token_id );
120+
}
121+
return parent::get_child_tokens( $token_id );
122+
}
123+
124+
/** @inheritDoc */
125+
public function get_descendants(): array {
126+
if ( $this->has_native_ast() ) {
127+
return wp_sqlite_mysql_native_ast_get_descendants( $this->native_ast, $this->native_node_index );
128+
}
129+
return parent::get_descendants();
130+
}
131+
132+
/** @inheritDoc */
133+
public function get_descendant_nodes( ?string $rule_name = null ): array {
134+
if ( $this->has_native_ast() ) {
135+
return wp_sqlite_mysql_native_ast_get_descendant_nodes( $this->native_ast, $this->native_node_index, $rule_name );
136+
}
137+
return parent::get_descendant_nodes( $rule_name );
138+
}
139+
140+
/** @inheritDoc */
141+
public function get_descendant_tokens( ?int $token_id = null ): array {
142+
if ( $this->has_native_ast() ) {
143+
return wp_sqlite_mysql_native_ast_get_descendant_tokens( $this->native_ast, $this->native_node_index, $token_id );
144+
}
145+
return parent::get_descendant_tokens( $token_id );
146+
}
147+
148+
/** @inheritDoc */
149+
public function get_start(): int {
150+
if ( $this->has_native_ast() ) {
151+
return wp_sqlite_mysql_native_ast_get_start( $this->native_ast, $this->native_node_index );
152+
}
153+
return parent::get_start();
154+
}
155+
156+
/** @inheritDoc */
157+
public function get_length(): int {
158+
if ( $this->has_native_ast() ) {
159+
return wp_sqlite_mysql_native_ast_get_length( $this->native_ast, $this->native_node_index );
160+
}
161+
return parent::get_length();
162+
}
163+
164+
private function has_native_ast(): bool {
165+
return null !== $this->native_ast;
166+
}
167+
168+
private function materialize_native_children(): void {
169+
if ( ! $this->has_native_ast() ) {
170+
return;
171+
}
172+
173+
$this->children = wp_sqlite_mysql_native_ast_get_children( $this->native_ast, $this->native_node_index );
174+
$this->native_ast = null;
175+
$this->native_node_index = null;
176+
}
177+
}

packages/mysql-on-sqlite/src/parser/class-wp-parser-node.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class WP_Parser_Node {
1515
*/
1616
public $rule_id;
1717
public $rule_name;
18-
private $children = array();
18+
protected $children = array();
1919

2020
public function __construct( $rule_id, $rule_name ) {
2121
$this->rule_id = $rule_id;

0 commit comments

Comments
 (0)