Skip to content

Commit 3abb2b7

Browse files
authored
Refactor documentation for select_output_name_to_ordinal_stack
1 parent b9cf8b9 commit 3abb2b7

1 file changed

Lines changed: 13 additions & 27 deletions

File tree

wp-includes/sqlite-ast/class-wp-sqlite-driver.php

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -227,33 +227,19 @@ class WP_SQLite_Driver {
227227
);
228228

229229
/**
230-
* A stack of maps for resolving ORDER BY unqualified names to select-item expressions.
231-
*
232-
* Motivation:
233-
* - MySQL allows ORDER BY to reference output columns by their column names (or aliases)
234-
* without qualification (e.g., ORDER BY name), and it resolves the reference against
235-
* the SELECT list when unambiguous. SQLite requires the term to be either a positional
236-
* index or a resolvable expression (e.g., t1.name) and will error on ambiguity. To provide
237-
* MySQL-compatible behavior, we keep track of SELECT output names and their corresponding
238-
* translated expressions so ORDER BY terms can be rewritten to safe expressions.
239-
*
240-
* Lifecycle:
241-
* - We push an empty frame at the start of translating a querySpecification (single SELECT).
242-
* - As each selectItem is translated, we record an output name → translated expression mapping:
243-
* - Explicit alias: SELECT expr AS alias → alias → expr
244-
* - Plain column ref: SELECT t1.name → name → t1.name
245-
* - Computed expression without alias: SELECT CONCAT('a','b') → 'CONCAT(…)'
246-
* - If the same output name appears more than once, the entry is marked ambiguous (null).
247-
* - ORDER BY translation consults the top stack frame to resolve simple unqualified terms.
248-
* - We pop any frames pushed during the current queryExpression after its children are translated.
249-
*
250-
* Semantics:
251-
* - Only simple unqualified ORDER BY tokens (name or `name`) are considered for rewrite.
252-
* - If the name uniquely matches an output column in the current SELECT list, we rewrite the
253-
* term to the recorded translated expression (e.g., `name` → `t1`.`name` or alias token).
254-
* - If the name is ambiguous or not found, we leave the ORDER BY term unchanged so SQLite can
255-
* raise a meaningful error consistent with MySQL’s ambiguity rules.
256-
*
230+
* A stack of column maps for resolving unqualified ORDER BY names to select-item expressions.
231+
*
232+
* Every query is a tree consisting of zero or more sub-SELECT queries. This stack keeps track
233+
* of selected columns per SELECT. This map is then used to resolve ambiguities in the ORDER BY
234+
* clause, e.g.
235+
*
236+
* SELECT name from t1 JOIN t2 ORDER BY name
237+
*
238+
* Becomes
239+
*
240+
* SELECT name from t1 JOIN t2 ORDER BY t1.name
241+
*
242+
* @see https://github.com/wordpress/sqlite-database-integration/issues/228
257243
* @var array<int, array<string, string|null>> Stack of frames: name(lowercase) → expression|null
258244
*/
259245
private $select_output_name_to_ordinal_stack = array();

0 commit comments

Comments
 (0)