@@ -443,14 +443,139 @@ class Dialect(metaclass=_Dialect):
443443 to "WHERE id = 1 GROUP BY id HAVING id = 1"
444444 """
445445
446- EXPAND_ALIAS_REFS_EARLY_ONLY_IN_GROUP_BY = False
446+ EXPAND_ONLY_GROUP_ALIAS_REF = False
447447 """Whether alias reference expansion before qualification should only happen for the GROUP BY clause."""
448448
449+ ANNOTATE_ALL_SCOPES = False
450+ """Whether to annotate all scopes during optimization. Used by BigQuery for UNNEST support."""
451+
452+ DISABLES_ALIAS_REF_EXPANSION = False
453+ """
454+ Whether alias reference expansion is disabled for this dialect.
455+
456+ Some dialects like Oracle do NOT support referencing aliases in projections or WHERE clauses.
457+ The original expression must be repeated instead.
458+
459+ For example, in Oracle:
460+ SELECT y.foo AS bar, bar * 2 AS baz FROM y -- INVALID
461+ SELECT y.foo AS bar, y.foo * 2 AS baz FROM y -- VALID
462+ """
463+
464+ SUPPORTS_ALIAS_REFS_IN_JOIN_CONDITIONS = False
465+ """
466+ Whether alias references are allowed in JOIN ... ON clauses.
467+
468+ Most dialects do not support this, but Snowflake allows alias expansion in the JOIN ... ON
469+ clause (and almost everywhere else)
470+
471+ For example, in Snowflake:
472+ SELECT a.id AS user_id FROM a JOIN b ON user_id = b.id -- VALID
473+
474+ Reference: https://docs.snowflake.com/en/sql-reference/sql/select#usage-notes
475+ """
476+
449477 SUPPORTS_ORDER_BY_ALL = False
450478 """
451479 Whether ORDER BY ALL is supported (expands to all the selected columns) as in DuckDB, Spark3/Databricks
452480 """
453481
482+ PROJECTION_ALIASES_SHADOW_SOURCE_NAMES = False
483+ """
484+ Whether projection alias names can shadow table/source names in GROUP BY and HAVING clauses.
485+
486+ In BigQuery, when a projection alias has the same name as a source table, the alias takes
487+ precedence in GROUP BY and HAVING clauses, and the table becomes inaccessible by that name.
488+
489+ For example, in BigQuery:
490+ SELECT id, ARRAY_AGG(col) AS custom_fields
491+ FROM custom_fields
492+ GROUP BY id
493+ HAVING id >= 1
494+
495+ The "custom_fields" source is shadowed by the projection alias, so we cannot qualify "id"
496+ with "custom_fields" in GROUP BY/HAVING.
497+ """
498+
499+ TABLES_REFERENCEABLE_AS_COLUMNS = False
500+ """
501+ Whether table names can be referenced as columns (treated as structs).
502+
503+ BigQuery allows tables to be referenced as columns in queries, automatically treating
504+ them as struct values containing all the table's columns.
505+
506+ For example, in BigQuery:
507+ SELECT t FROM my_table AS t -- Returns entire row as a struct
508+ """
509+
510+ SUPPORTS_STRUCT_STAR_EXPANSION = False
511+ """
512+ Whether the dialect supports expanding struct fields using star notation (e.g., struct_col.*).
513+
514+ BigQuery allows struct fields to be expanded with the star operator:
515+ SELECT t.struct_col.* FROM table t
516+ RisingWave also allows struct field expansion with the star operator using parentheses:
517+ SELECT (t.struct_col).* FROM table t
518+
519+ This expands to all fields within the struct.
520+ """
521+
522+ EXCLUDES_PSEUDOCOLUMNS_FROM_STAR = False
523+ """
524+ Whether pseudocolumns should be excluded from star expansion (SELECT *).
525+
526+ Pseudocolumns are special dialect-specific columns (e.g., Oracle's ROWNUM, ROWID, LEVEL,
527+ or BigQuery's _PARTITIONTIME, _PARTITIONDATE) that are implicitly available but not part
528+ of the table schema. When this is True, SELECT * will not include these pseudocolumns;
529+ they must be explicitly selected.
530+ """
531+
532+ QUERY_RESULTS_ARE_STRUCTS = False
533+ """
534+ Whether query results are typed as structs in metadata for type inference.
535+
536+ In BigQuery, subqueries store their column types as a STRUCT in metadata,
537+ enabling special type inference for ARRAY(SELECT ...) expressions:
538+ ARRAY(SELECT x, y FROM t) → ARRAY<STRUCT<...>>
539+
540+ For single column subqueries, BigQuery unwraps the struct:
541+ ARRAY(SELECT x FROM t) → ARRAY<type_of_x>
542+
543+ This is metadata-only for type inference.
544+ """
545+
546+ REQUIRES_PARENTHESIZED_STRUCT_ACCESS = False
547+ """
548+ Whether struct field access requires parentheses around the expression.
549+
550+ RisingWave requires parentheses for struct field access in certain contexts:
551+ SELECT (col.field).subfield FROM table -- Parentheses required
552+
553+ Without parentheses, the parser may not correctly interpret nested struct access.
554+
555+ Reference: https://docs.risingwave.com/sql/data-types/struct#retrieve-data-in-a-struct
556+ """
557+
558+ SUPPORTS_NULL_TYPE = False
559+ """
560+ Whether NULL/VOID is supported as a valid data type (not just a value).
561+
562+ Databricks and Spark v3+ support NULL as an actual type, allowing expressions like:
563+ SELECT NULL AS col -- Has type NULL, not just value NULL
564+ CAST(x AS VOID) -- Valid type cast
565+ """
566+
567+ COALESCE_COMPARISON_NON_STANDARD = False
568+ """
569+ Whether COALESCE in comparisons has non-standard NULL semantics.
570+
571+ We can't convert `COALESCE(x, 1) = 2` into `NOT x IS NULL AND x = 2` for redshift,
572+ because they are not always equivalent. For example, if `x` is `NULL` and it comes
573+ from a table, then the result is `NULL`, despite `FALSE AND NULL` evaluating to `FALSE`.
574+
575+ In standard SQL and most dialects, these expressions are equivalent, but Redshift treats
576+ table NULLs differently in this context.
577+ """
578+
454579 HAS_DISTINCT_ARRAY_CONSTRUCTORS = False
455580 """
456581 Whether the ARRAY constructor is context-sensitive, i.e in Redshift ARRAY[1, 2, 3] != ARRAY(1, 2, 3)
0 commit comments