Home

Awesome

go-zetasql

Go GoDoc

Go bindings for ZetaSQL

ZetaSQL can parse all queries related to Cloud Spanner and BigQuery. This functionality is provided from the Go language using cgo.

Features

Status

In the features of ZetaSQL, you can use the functions of the following packages. Will be added sequentially.

PackageSupported
parseryes
publicpartial
analyzeryes
scriptingno
reference_implno

Prerequisites

go-zetasql uses cgo. Therefore, CGO_ENABLED=1 is required to build.
Also, the compiler recommends clang++. Please set CXX=clang++ to install.

Environment NameValue
CGO_ENABLED1 ( required )
CXXclang++ ( recommended )

Installation

go get github.com/goccy/go-zetasql

The first time you run it, it takes time to build all the ZetaSQL code used by go-zetasql.

Synopsis

Parse SQL statement

package main

import (
  "github.com/goccy/go-zetasql"
  "github.com/goccy/go-zetasql/ast"
)

func main() {

  stmt, err := zetasql.ParseStatement("SELECT * FROM Samples WHERE id = 1", nil)
  if err != nil {
    panic(err)
  }

  // use type assertion and get concrete nodes.
  queryStmt := stmt.(*ast.QueryStatementNode)
}

If you want to know the specific node of ast.Node, you can traverse by using ast.Walk.

package main

import (
  "fmt"

  "github.com/goccy/go-zetasql"
  "github.com/goccy/go-zetasql/ast"
)

func main() {

  stmt, err := zetasql.ParseStatement("SELECT * FROM Samples WHERE id = 1", nil)
  if err != nil {
    panic(err)
  }

  // traverse all nodes of stmt.
  ast.Walk(stmt, func(n ast.Node) error {
    fmt.Printf("node: %T loc:%s\n", n, n.ParseLocationRange())
    return nil
  })
}

Analyze SQL statement

If you have table information, you can use the analyzer API by using it as a Catalog. By using analyzer API, you can parse SQL based on table information and output normalized node. If you want to know the specific node of resolved_ast.Node, you can traverse by using resolved_ast.Walk.

package main

import (
  "fmt"

  "github.com/goccy/go-zetasql"
  "github.com/goccy/go-zetasql/resolved_ast"
  "github.com/goccy/go-zetasql/types"
)

func main() {
  const tableName = "Samples"
  catalog := types.NewSimpleCatalog("catalog")
  catalog.AddTable(
    types.NewSimpleTable(tableName, []types.Column{
      types.NewSimpleColumn(tableName, "id", types.Int64Type()),
      types.NewSimpleColumn(tableName, "name", types.StringType()),
    }),
  )
  catalog.AddZetaSQLBuiltinFunctions()
  out, err := zetasql.AnalyzeStatement("SELECT * FROM Samples WHERE id = 1000", catalog, nil)
  if err != nil {
    panic(err)
  }

  // get statement node from zetasql.AnalyzerOutput.
  stmt := out.Statement()

  // traverse all nodes of stmt.
  if err := resolved_ast.Walk(stmt, func(n resolved_ast.Node) error {
    fmt.Printf("%T\n", n)
    return nil
  }); err != nil {
    panic(err)
  }
}

Also, you can use the node.DebugString() API to dump the result of resolved_ast.Node. This helps to understand all nodes of statement.

stmt := out.Statement()
fmt.Println(stmt.DebugString())

License

Apache-2.0 License

Since go-zetasql builds all source code including dependencies at install time, it directly contains the source code of the following libraries. Therefore, the license is set according to the license of the dependent library.