You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 40f5d7e
Browse filesBrowse the repository at this point in the historyBrowse files
googlesql: Spanner schemas, arrays, and a function seed from Spanner (#4645)
* googlesql: convert ALTER TABLE, views, renames and HIDDEN columns
ALTER TABLE was dropped as unsupported, so columns it added, dropped or
retyped never reached the catalog. It now converts ADD/DROP COLUMN,
Spanner's ALTER COLUMN (which restates the type and nullability), ALTER
COLUMN ... DROP NOT NULL, RENAME COLUMN and RENAME TO; RENAME TABLE
converts too. CREATE [OR REPLACE] VIEW and DROP VIEW convert, and a
HIDDEN column is left out of SELECT * as Spanner does.
The new googlesql cases' schemas were checked against Spanner Omni.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8QoGi6VRtADkb4jL3BFHP
* googlesql: type arrays, UNNEST, subscripts and typed literals
The converter now handles typed literals (DATE, TIMESTAMP, NUMERIC, JSON,
bytes), array constructors, INTERVAL, the OFFSET/ORDINAL/SAFE_* subscripts
and "x IN UNNEST(array)", which becomes "x = ANY(array)".
In the analysis core:
- A subscript is the array's element, nullable, with an integer index.
- ARRAY(subquery) is an array of the column, not its first value.
- "x = ANY(array)" types a placeholder as an array of x's type, as
PostgreSQL does; sqlc.slice() still gets the element.
- A polymorphic function taking anyarray and returning anyelement, as
unnest does, returns the array's element, and a function in FROM takes
that resolved type, with its alias naming the column.
GoogleSQL gains an unnest seed. analyze_arrays is checked against Spanner
Omni; the rest are in array_unnest, where Spanner's wire types lose the
nullability and lengths the golden pins.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8QoGi6VRtADkb4jL3BFHP
* googlesql: seed Spanner's functions and operators
functions.jsonl held only count, so every other function typed as any.
It now lists 291 signatures across aggregates, math, strings, dates and
timestamps, JSON, arrays, hashing, search and vector distance. Their
return types, and those of the operators, were read from Spanner Omni by
compiling each call in PLAN mode; the search functions and
PENDING_COMMIT_TIMESTAMP, which cannot be compiled in a select list, are
typed from Spanner's reference. Spanner has no window functions, so none
are listed.
GoogleSQL now propagates NULL through function arguments, with the
functions that return NULL from non-null input marked nullable.
The converter maps COALESCE, IFNULL, NULLIF, IF, GREATEST and LEAST onto
the nodes the core types them by, makes SAFE.f(...) nullable, passes date
parts (DAY, WEEK(MONDAY)) as strings rather than columns, and converts
EXTRACT.
In the core, an operator a dialect lists now replaces the one its
arithmetic rule generates for the same operands, which is how INT64 /
INT64 is a FLOAT64; and a placeholder passed for a polymorphic parameter
takes its type from the other arguments, so the value in
array_includes(array, @v) is the array's element.
analyze_functions is checked against Spanner Omni; func_nullability
covers what Spanner's wire types cannot report.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8QoGi6VRtADkb4jL3BFHP
* goldeneye: generate Spanner's types, functions and operators
Spanner keeps no catalog of its library, so goldeneye now reads it by
asking. spanner/library.jsonl lists the function signatures to try; each
is compiled in PLAN mode against a probe database, and the ones Spanner
accepts are written to functions.jsonl with the type it reports. A
polymorphic signature is tried with INT64 and STRING and its result must
hold for both. Calls a select list cannot make are compiled the way they
can be: SEARCH in a WHERE clause, SCORE over a search index,
PENDING_COMMIT_TIMESTAMP in an INSERT. operators.jsonl is every binary
operator Spanner accepts over the operands tried, and types.jsonl the
types the dialect lists, each one Spanner has checked by a cast; the
GoogleSQL types only BigQuery has are kept as they are.
The generated files hold the same records the seed already did; they
are rewritten in goldeneye's compact form, and TestDialect now checks
all four files against Spanner. The dialect package's Function gains
never_null, which the seed already reads.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8QoGi6VRtADkb4jL3BFHP
---------
Co-authored-by: Claude <noreply@anthropic.com>
0 commit comments