Documentation
¶
Overview ¶
Package memebridge converts memefish GoogleSQL AST nodes into Cloud Spanner types and values.
The conversion pipeline is:
GoogleSQL text → memefish.ParseExpr / ParseType → ast.Expr / ast.Type → memebridge → spannerpb.Type + spanner.GenericColumnValue
memebridge evaluates literal expressions (including CAST and SAFE_CAST), applies expected-type coercion for STRUCT fields and ARRAY elements, and maps memefish types to spannerpb.Type via spantype/typector. GCV wire assembly uses spanvalue/gcvctor.
Entry points ¶
ParseExprToGCV parses a SQL expression string and returns a GenericColumnValue. ParseExprFile is the same with a filename for memefish error positions. MemefishExprToGCV converts an already-parsed ast.Expr. MemefishTypeToSpannerpbType maps ast.Type to spannerpb.Type.
The cliparams subpackage parses CLI-style name:value parameter assignments.
Semantic source of truth ¶
Literal evaluation and CAST behavior aim to match Cloud Spanner (and googlesql cast tables). Temporal casts without an explicit time zone use America/Los_Angeles. Build with the memebridge_tzdata tag to embed IANA tzdata on minimal runtimes.
Special contracts ¶
PENDING_COMMIT_TIMESTAMP() is recognized case-insensitively and yields a TIMESTAMP GenericColumnValue whose string wire value is the placeholder "spanner.commit_timestamp()". Downstream Spanner clients interpret this sentinel; memebridge preserves it through TIMESTAMP→STRING casts.
Array literals require elements to coerce to the declared or inferred element type by default. Use WithLegacyArrayWirePassthrough on MemefishExprToGCV, ParseExprToGCV, or ParseExprFile to restore pre-v0.7 behavior that preserves original element wire values when coercion fails. Strict coercion is always used on expected-type paths (typed STRUCT fields, ARRAY<T> annotations in typed contexts).
Index ¶
- Variables
- func MemefishExprToGCV(expr ast.Expr, opts ...EvalOption) (spanner.GenericColumnValue, error)
- func MemefishTypeToSpannerpbType(typ ast.Type) (*sppb.Type, error)
- func ParseExprFile(filename, expr string, opts ...EvalOption) (spanner.GenericColumnValue, error)
- func ParseExprToGCV(expr string, opts ...EvalOption) (spanner.GenericColumnValue, error)
- func ScalarTypeNameToTypeCode(name ast.ScalarTypeName) (sppb.TypeCode, bool)
- type EvalOption
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrCannotInferArrayElementType is returned when an untyped array literal // has no inferrable element type (for example, an empty array with no // explicit ARRAY<T> annotation). ErrCannotInferArrayElementType = errors.New("cannot infer element type for array literal without explicit type") // ErrUnsupportedExpr is returned when MemefishExprToGCV encounters an // expression kind it does not evaluate. ErrUnsupportedExpr = errors.New("unsupported expression") // ErrUnsupportedType is returned when MemefishTypeToSpannerpbType encounters a // type kind it does not support. ErrUnsupportedType = errors.New("unsupported type") )
var ( // ErrUnsupportedCast is returned when CAST cannot convert between the // source and destination Spanner types. ErrUnsupportedCast = errors.New("unsupported cast") )
Functions ¶
func MemefishExprToGCV ¶
func MemefishExprToGCV(expr ast.Expr, opts ...EvalOption) (spanner.GenericColumnValue, error)
MemefishExprToGCV evaluates a memefish expression AST node to a GenericColumnValue. It handles literals, STRUCT and ARRAY literals, CAST and SAFE_CAST, INTERVAL literals, and PENDING_COMMIT_TIMESTAMP().
Unsupported expression kinds return an error. By default, ARRAY<T> literals require elements to coerce to T; use WithLegacyArrayWirePassthrough to restore pre-v0.7 permissive wire preservation on coercion failure.
Example ¶
package main
import (
"fmt"
"github.com/apstndb/memebridge"
"github.com/cloudspannerecosystem/memefish"
)
func main() {
expr, err := memefish.ParseExpr("", `STRUCT(1 AS x, ["a", "b"] AS tags)`)
if err != nil {
panic(err)
}
gcv, err := memebridge.MemefishExprToGCV(expr)
if err != nil {
panic(err)
}
fmt.Println(gcv.Type.GetStructType().GetFields()[0].GetName())
fmt.Println(gcv.Type.GetStructType().GetFields()[1].GetType().GetArrayElementType().GetCode())
}
Output: x STRING
Example (Array) ¶
package main
import (
"fmt"
"github.com/apstndb/memebridge"
"github.com/cloudspannerecosystem/memefish"
)
func main() {
expr, err := memefish.ParseExpr("", `ARRAY<INT64>[1, 2, 3]`)
if err != nil {
panic(err)
}
gcv, err := memebridge.MemefishExprToGCV(expr)
if err != nil {
panic(err)
}
fmt.Println(gcv.Type.GetCode(), gcv.Type.GetArrayElementType().GetCode())
}
Output: ARRAY INT64
Example (Cast) ¶
package main
import (
"fmt"
"github.com/apstndb/memebridge"
"github.com/cloudspannerecosystem/memefish"
)
func main() {
expr, err := memefish.ParseExpr("", `CAST(TRUE AS STRING)`)
if err != nil {
panic(err)
}
gcv, err := memebridge.MemefishExprToGCV(expr)
if err != nil {
panic(err)
}
fmt.Println(gcv.Type.GetCode(), gcv.Value.GetStringValue())
}
Output: STRING true
Example (PendingCommitTimestamp) ¶
package main
import (
"fmt"
"github.com/apstndb/memebridge"
"github.com/cloudspannerecosystem/memefish"
)
func main() {
expr, err := memefish.ParseExpr("", `PENDING_COMMIT_TIMESTAMP()`)
if err != nil {
panic(err)
}
gcv, err := memebridge.MemefishExprToGCV(expr)
if err != nil {
panic(err)
}
fmt.Println(gcv.Type.GetCode())
}
Output: TIMESTAMP
func MemefishTypeToSpannerpbType ¶
MemefishTypeToSpannerpbType maps a memefish ast.Type to spannerpb.Type. Named types other than UUID require disambiguation between STRUCT and ENUM and currently return an error until descriptor support is added.
func ParseExprFile ¶ added in v0.7.0
func ParseExprFile(filename, expr string, opts ...EvalOption) (spanner.GenericColumnValue, error)
ParseExprFile is like ParseExprToGCV but passes filename to memefish for error positions only.
func ParseExprToGCV ¶ added in v0.7.0
func ParseExprToGCV(expr string, opts ...EvalOption) (spanner.GenericColumnValue, error)
ParseExprToGCV parses a GoogleSQL expression string and evaluates it to a GenericColumnValue.
Example ¶
package main
import (
"fmt"
"github.com/apstndb/memebridge"
)
func main() {
gcv, err := memebridge.ParseExprToGCV(`CAST(42 AS STRING)`)
if err != nil {
panic(err)
}
fmt.Println(gcv.Type.GetCode(), gcv.Value.GetStringValue())
}
Output: STRING 42
func ScalarTypeNameToTypeCode ¶ added in v0.6.4
func ScalarTypeNameToTypeCode(name ast.ScalarTypeName) (sppb.TypeCode, bool)
ScalarTypeNameToTypeCode maps a memefish scalar type name to the corresponding Spanner TypeCode. The second return value is false when the name is not a known scalar type (for example UUID, which memefish models as a NamedType).
Types ¶
type EvalOption ¶ added in v0.7.0
type EvalOption func(*evalOptions)
EvalOption configures expression evaluation.
func WithLegacyArrayWirePassthrough ¶ added in v0.7.0
func WithLegacyArrayWirePassthrough() EvalOption
WithLegacyArrayWirePassthrough restores pre-v0.7 behavior where ARRAY<T> literals preserve original element wire values when coercion to T fails. The default is strict coercion, which returns an error on incompatible elements.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package cliparams converts CLI-style query parameter assignments ("name:value" arguments or already-split name→value maps) into cloud.google.com/go/spanner.GenericColumnValue maps, using memefish literal parsing via github.com/apstndb/memebridge.
|
Package cliparams converts CLI-style query parameter assignments ("name:value" arguments or already-split name→value maps) into cloud.google.com/go/spanner.GenericColumnValue maps, using memefish literal parsing via github.com/apstndb/memebridge. |