@@ -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