Documentation
¶
Overview ¶
Package spanner implements AST conversion from memefish (Spanner SQL parser) to sqlc's internal AST.
Key architectural decisions:
List initialization: All sqlcast.List fields that are walked by the compiler must be initialized with empty Items arrays, not nil. The compiler's Walk function expects to iterate over these lists and will panic on nil. Fields that are conditionally accessed (like WhereClause) can be nil.
Star (*) handling: Spanner's Star nodes must be wrapped in ColumnRef to match PostgreSQL's AST structure. This wrapping is critical for the compiler's hasStarRef() and column expansion logic to work correctly. The pattern is: ResTarget -> ColumnRef -> A_Star.
THEN RETURN conversion: Spanner's THEN RETURN clause is converted to PostgreSQL's RETURNING clause, maintaining the same AST structure patterns (especially for Star nodes).
Function names: Spanner supports namespaced functions (e.g., NET.IPV4_TO_INT64, SAFE.DIVIDE). All path components are joined with dots to preserve the full function name for resolution.
Package spanner provides the Cloud Spanner SQL parser for sqlc.
Named Parameters Design Decision ¶
Unlike PostgreSQL, MySQL, and SQLite engines which convert named parameters (e.g., @name or sqlc.arg('name')) to positional parameters in the SQL query, the Spanner engine preserves named parameters (@name) in the generated SQL.
This is because:
- Cloud Spanner natively supports named parameters with @ syntax
- The go-sql-spanner driver can bind positional arguments to named parameters
- Other drivers (lib/pq, go-sql-driver/mysql) don't support sql.Named()
For consistency with other engines and to minimize changes to the common code generation logic, sqlc currently generates code using positional arguments even for Spanner. This avoids the need for engine-specific parameter handling in the shared codegen layer, relying instead on the go-sql-spanner driver's ability to automatically bind positional arguments to named parameters.
This is a pragmatic trade-off for the initial implementation. Future versions may consider more native support for named parameters using sql.Named() once the common codegen layer can better accommodate engine-specific differences.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewCatalog ¶
func NewIdentifier ¶
Types ¶
type Parameter ¶
Parameter represents a query parameter with its name and position
func ExtractParameters ¶
ExtractParameters extracts all @param style parameters from an AST node Uses ast.Preorder for cleaner, more idiomatic implementation
type Parser ¶
type Parser struct{}
func (*Parser) CommentSyntax ¶
func (p *Parser) CommentSyntax() source.CommentSyntax
CommentSyntax returns the comment syntax supported by Spanner
func (*Parser) IsReservedKeyword ¶
IsReservedKeyword checks if a string is a reserved keyword in Spanner SQL. It uses memefish's built-in IsKeyword function which perfectly matches the official Cloud Spanner reserved keywords list.
This implementation is maintenance-free as it automatically stays in sync with memefish's keyword definitions, which are based on the official Spanner SQL specification.