### Install Go Plugin for Protobuf Generation Source: https://github.com/substrait-io/substrait-go/blob/main/README.md Installs the Go plugin for protobuf, which is required for generating Go code from .proto files. Ensure your GOPATH is included in your system's PATH. ```bash go install google.golang.org/protobuf/cmd/protoc-gen-go@latest export PATH="$PATH:$(go env GOPATH)/bin" ``` -------------------------------- ### Generate Go Protobuf Files with buf Source: https://github.com/substrait-io/substrait-go/blob/main/README.md Executes the 'go generate' command to automatically generate updated .pb.go files. This process requires buf and the Go protobuf plugin to be installed and will reference the primary substrait-io repository. ```bash go generate ``` -------------------------------- ### Create Simple Query Plan in Go using substrait-go Source: https://context7.com/substrait-io/substrait-go/llms.txt Demonstrates building a basic query plan that reads from a table, filters rows based on a condition, and projects specific columns. It utilizes the plan builder to construct the plan step-by-step and serializes it to protobuf format. Dependencies include the substrait-go library. ```go package main import ( "fmt" "github.com/substrait-io/substrait-go/v7/expr" "github.com/substrait-io/substrait-go/v7/extensions" "github.com/substrait-io/substrait-go/v7/plan" "github.com/substrait-io/substrait-go/v7/types" ) func main() { // Load default extension collection extCollection, err := extensions.GetDefaultCollection() if err != nil { panic(err) } // Create a plan builder builder := plan.NewBuilder(extCollection) // Define table schema schema := types.NamedStruct{ Names: []string{"id", "name", "age"}, Struct: types.StructType{ Nullability: types.NullabilityRequired, Types: []types.Type{ &types.Int32Type{Nullability: types.NullabilityRequired}, &types.StringType{Nullability: types.NullabilityRequired}, &types.Int32Type{Nullability: types.NullabilityRequired}, }, }, } // Create a named table scan scan := builder.NamedScan([]string{"users"}, schema) // Create filter condition: age > 18 ageRef, _ := builder.RootFieldRef(scan, 2) ageLiteral, _ := expr.NewLiteral(int32(18), false) filterExpr, _ := builder.ScalarFn( extensions.SubstraitDefaultURNPrefix+"comparison", "gt:i32_i32", nil, ageRef, ageLiteral, ) // Apply filter filtered, _ := builder.Filter(scan, filterExpr) // Project name and age columns nameRef, _ := builder.RootFieldRef(filtered, 1) ageRefProj, _ := builder.RootFieldRef(filtered, 2) projected, _ := builder.Project(filtered, nameRef, ageRefProj) // Create the plan queryPlan, _ := builder.Plan(projected, []string{"name", "age"}) // Serialize to protobuf protoPlan, _ := queryPlan.ToProto() fmt.Printf("Created plan with %d relations\n", len(protoPlan.Relations)) } ``` -------------------------------- ### Serialize and Deserialize Substrait Plans in Go Source: https://context7.com/substrait-io/substrait-go/llms.txt Demonstrates how to convert Substrait plans between Go objects and protobuf byte format. It covers creating a plan, serializing it to protobuf, marshaling to bytes, and then deserializing and restoring the Go plan object. Dependencies include 'bytes', 'fmt', and various substrait-go packages. ```go package main import ( "bytes" "fmt" "github.com/substrait-io/substrait-go/v7/extensions" "github.com/substrait-io/substrait-go/v7/plan" "github.com/substrait-io/substrait-go/v7/types" proto "github.com/substrait-io/substrait-protobuf/go/substraitpb" "google.golang.org/protobuf/proto" ) func main() { // Create a simple plan collection, _ := extensions.GetDefaultCollection() builder := plan.NewBuilder(collection) schema := types.NamedStruct{ Names: []string{"id", "value"}, Struct: types.StructType{ Nullability: types.NullabilityRequired, Types: []types.Type{ &types.Int32Type{Nullability: types.NullabilityRequired}, &types.StringType{Nullability: types.NullabilityRequired}, }, }, } scan := builder.NamedScan([]string{"my_table"}, schema) queryPlan, _ := builder.Plan(scan, []string{"id", "value"}) // Serialize to protobuf protoPlan, err := queryPlan.ToProto() if err != nil { panic(err) } // Marshal to bytes planBytes, err := proto.Marshal(protoPlan) if err != nil { panic(err) } fmt.Printf("Serialized plan size: %d bytes\n", len(planBytes)) // Deserialize from bytes var deserializedProto proto.Plan if err := proto.Unmarshal(planBytes, &deserializedProto); err != nil { panic(err) } // Convert back to Go plan object restoredPlan, err := plan.FromProto(&deserializedProto, collection) if err != nil { panic(err) } // Access plan properties roots := restoredPlan.GetRoots() fmt.Printf("Plan has %d root relation(s)\n", len(roots)) if len(roots) > 0 { rootNames := roots[0].Names() fmt.Printf("Output columns: %v\n", rootNames) } // Check plan version version := restoredPlan.Version() fmt.Printf("Substrait version: %d.%d.%d\n", version.GetMajorNumber(), version.GetMinorNumber(), version.GetPatchNumber()) } ``` -------------------------------- ### Apply ROW_NUMBER() Window Function with Partitioning and Ordering in Go Source: https://context7.com/substrait-io/substrait-go/llms.txt This Go code snippet demonstrates how to construct a `ROW_NUMBER()` window function using substrait-go. It includes setting up the extension registry, defining the base schema, and specifying partitioning by department and ordering by salary in descending order. The function returns the constructed window function expression and its type. ```go package main import ( "fmt" "github.com/substrait-io/substrait-go/v7/expr" "github.com/substrait-io/substrait-go/v7/extensions" "github.com/substrait-io/substrait-go/v7/types" ) func main() { collection, _ := extensions.GetDefaultCollection() extSet := extensions.NewSet() reg := expr.NewExtensionRegistry(extSet, collection) // Schema: department, employee, salary baseSchema := &types.RecordType{ Nullability: types.NullabilityRequired, Types: []types.Type{ &types.StringType{Nullability: types.NullabilityRequired}, &types.StringType{Nullability: types.NullabilityRequired}, &types.Float64Type{Nullability: types.NullabilityRequired}, }, } b := expr.ExprBuilder{ Reg: reg, BaseSchema: baseSchema, } // ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) windowFnID := extensions.ID{ URN: extensions.SubstraitDefaultURNPrefix + "window", Name: "row_number:", } // Partition by department (field 0) deptRef := b.RootRef(expr.NewStructFieldRef(0)) // Order by salary (field 2) descending salaryRef := b.RootRef(expr.NewStructFieldRef(2)) sortField := expr.SortField{ Expr: expr.MustExpr(salaryRef.Build()), Kind: types.SortDescNullsLast, } windowFunc, err := b.WindowFunc(windowFnID, nil). Args(). Partitions(deptRef). Sort(sortField). Build() if err != nil { panic(err) } fmt.Printf("Window function created\n") fmt.Printf("Return type: %s\n", windowFunc.GetType()) fmt.Printf("Partition count: %d\n", len(windowFunc.Partitions)) fmt.Printf("Sort fields: %d\n", len(windowFunc.Sorts)) } ``` -------------------------------- ### Download Substrait Grammar Files (Go) Source: https://github.com/substrait-io/substrait-go/blob/main/types/parser/baseparser/README.md This snippet shows the `go generate` directives used to download the Substrait grammar files (SubstraitLexer.g4 and SubstraitType.g4) from a specified commit hash in the Substrait repository. These files are essential for regenerating the type parser. Ensure you replace `` with the correct commit identifier. ```go //go:generate wget https://raw.githubusercontent.com/substrait-io/substrait//grammar/SubstraitLexer.g4 //go:generate wget https://raw.githubusercontent.com/substrait-io/substrait//grammar/SubstraitType.g4 ``` -------------------------------- ### Build Nested Expressions with ExprBuilder (Go) Source: https://context7.com/substrait-io/substrait-go/llms.txt This Go code demonstrates constructing nested expressions, such as arithmetic operations, using the fluent ExprBuilder API. It requires the substrait-go/expr, substrait-go/extensions, and substrait-go/types packages. The function takes an extension registry and a base schema to build and return an expression. ```go package main import ( "fmt" "github.com/substrait-io/substrait-go/v7/expr" "github.com/substrait-io/substrait-go/v7/extensions" "github.com/substrait-io/substrait-go/v7/types" ) func main() { // Get extension collection and create registry collection, _ := extensions.GetDefaultCollection() extSet := extensions.NewSet() reg := expr.NewExtensionRegistry(extSet, collection) // Define input schema baseSchema := &types.RecordType{ Nullability: types.NullabilityRequired, Types: []types.Type{ &types.Int32Type{Nullability: types.NullabilityRequired}, &types.StringType{Nullability: types.NullabilityRequired}, &types.Float64Type{Nullability: types.NullabilityRequired}, }, } // Create expression builder with registry and schema b := expr.ExprBuilder{ Reg: reg, BaseSchema: baseSchema, } // Build nested expression: (field_0 + 10) * field_2 fnID := extensions.ID{ URN: extensions.SubstraitDefaultURNPrefix + "arithmetic", Name: "add:i32_i32", } addExpr, _ := b.ScalarFunc(fnID, nil).Args( b.RootRef(expr.NewStructFieldRef(0)), b.Wrap(expr.NewLiteral(int32(10), false)), ).Build() multID := extensions.ID{ URN: extensions.SubstraitDefaultURNPrefix + "arithmetic", Name: "multiply:fp64_fp64", } // Cast int32 result to fp64, then multiply castExpr, _ := b.Cast( b.Expression(addExpr), &types.Float64Type{Nullability: types.NullabilityRequired}, ).Build() result, err := b.ScalarFunc(multID, nil).Args( b.Expression(castExpr), b.RootRef(expr.NewStructFieldRef(2)), ).Build() if err != nil { panic(err) } fmt.Printf("Expression type: %s\n", result.GetType()) } ``` -------------------------------- ### Build Inner and Outer Joins with Conditions in Go Source: https://context7.com/substrait-io/substrait-go/llms.txt Illustrates how to construct join relations, specifically inner joins, using the Substrait-Go library. It defines schemas for two tables ('orders' and 'customers'), establishes a join condition based on matching customer IDs, and then builds the join operation. Dependencies include 'fmt' and substrait-go packages for expressions, extensions, plans, and types. ```go package main import ( "fmt" "github.com/substrait-io/substrait-go/v7/expr" "github.com/substrait-io/substrait-go/v7/extensions" "github.com/substrait-io/substrait-go/v7/plan" "github.com/substrait-io/substrait-go/v7/types" ) func main() { collection, _ := extensions.GetDefaultCollection() builder := plan.NewBuilder(collection) // Left table: orders (order_id, customer_id, amount) ordersSchema := types.NamedStruct{ Names: []string{"order_id", "customer_id", "amount"}, Struct: types.StructType{ Nullability: types.NullabilityRequired, Types: []types.Type{ &types.Int32Type{Nullability: types.NullabilityRequired}, &types.Int32Type{Nullability: types.NullabilityRequired}, &types.Float64Type{Nullability: types.NullabilityRequired}, }, }, } // Right table: customers (customer_id, name) customersSchema := types.NamedStruct{ Names: []string{"customer_id", "name"}, Struct: types.StructType{ Nullability: types.NullabilityRequired, Types: []types.Type{ &types.Int32Type{Nullability: types.NullabilityRequired}, &types.StringType{Nullability: types.NullabilityRequired}, }, }, } orders := builder.NamedScan([]string{"orders"}, ordersSchema) customers := builder.NamedScan([]string{"customers"}, customersSchema) // Join condition: orders.customer_id = customers.customer_id // Field 1 from left (orders.customer_id), Field 0 from right (customers.customer_id) leftKey, _ := builder.RootFieldRef(orders, 1) rightKey, _ := builder.JoinedRecordFieldRef(orders, customers, 3) // offset by orders columns eqFnID := extensions.ID{ URN: extensions.SubstraitDefaultURNPrefix + "comparison", Name: "equal:i32_i32", } joinCondition, _ := builder.ScalarFn( eqFnID.URN, eqFnID.Name, nil, leftKey, rightKey, ) // Create inner join joined, err := builder.Join( orders, customers, joinCondition, plan.JoinTypeInner, ) if err != nil { panic(err) } // Project result columns outputNames := []string{ "order_id", "customer_id", "amount", "customer_name", } queryPlan, _ := builder.Plan(joined, outputNames) fmt.Printf("Join plan created with type: %d\n", joined.Type()) } ``` -------------------------------- ### Create Aggregate Relations with Grouping (Go) Source: https://context7.com/substrait-io/substrait-go/llms.txt This Go code shows how to create an aggregate relation with grouping by a specific column and calculating multiple measures, such as average and count. It utilizes the plan.Builder from substrait-go and requires substrait-go/expr, substrait-go/extensions, substrait-go/plan, and substrait-go/types. The function returns a Substrait plan for the aggregation. ```go package main import ( "fmt" "github.com/substrait-io/substrait-go/v7/expr" "github.com/substrait-io/substrait-go/v7/extensions" "github.com/substrait-io/substrait-go/v7/plan" "github.com/substrait-io/substrait-go/v7/types" ) func main() { collection, _ := extensions.GetDefaultCollection() builder := plan.NewBuilder(collection) // Schema: department, employee_id, salary schema := types.NamedStruct{ Names: []string{"department", "employee_id", "salary"}, Struct: types.StructType{ Nullability: types.NullabilityRequired, Types: []types.Type{ &types.StringType{Nullability: types.NullabilityRequired}, &types.Int32Type{Nullability: types.NullabilityRequired}, &types.Float64Type{Nullability: types.NullabilityRequired}, }, }, } scan := builder.NamedScan([]string{"employees"}, schema) // Create aggregate measures salaryRef, _ := builder.RootFieldRef(scan, 2) // AVG(salary) avgSalary, _ := builder.AggregateFn( extensions.SubstraitDefaultURNPrefix+"aggregate", "avg:fp64", nil, salaryRef, ) // COUNT(*) countAll, _ := builder.AggregateFn( extensions.SubstraitDefaultURNPrefix+"aggregate", "count:any", nil, ) measures := []plan.AggRelMeasure{ builder.Measure(avgSalary, nil), builder.Measure(countAll, nil), } // Group by department (column 0) aggregated, err := builder.AggregateColumns(scan, measures, 0) if err != nil { panic(err) } // Create plan outputNames := []string{"department", "avg_salary", "employee_count"} queryPlan, _ := builder.Plan(aggregated, outputNames) fmt.Printf("Aggregate plan created with %d grouping columns\n", len(aggregated.GroupingExpressions())) } ``` -------------------------------- ### Load and Use Custom Extension Functions with Substrait Go Source: https://context7.com/substrait-io/substrait-go/llms.txt Demonstrates loading custom scalar functions from a YAML file into an extension collection. It then retrieves a function by its ID, registers it with an extension set and registry, and creates a function expression. This process is essential for extending Substrait's capabilities with user-defined logic. ```go package main import ( "bytes" "fmt" "github.com/substrait-io/substrait-go/v7/extensions" "github.com/substrait-io/substrait-go/v7/expr" "github.com/substrait-io/substrait-go/v7/types" ) func main() { // Create new collection collection := &extensions.Collection{} // Load extension YAML yamlContent := ` urn: extension:io.example:custom scalar_functions: - name: custom_add description: Custom addition function impls: - args: - value: i32 - value: i32 return: i32 ` reader := bytes.NewReader([]byte(yamlContent)) if err := collection.Load("https://example.com/custom.yaml", reader); err != nil { panic(err) } // Get a scalar function from the collection funcID := extensions.ID{ URN: "extension:io.example:custom", Name: "custom_add:i32_i32", } scalarFunc, ok := collection.GetScalarFunc(funcID) if !ok { panic("Function not found") } fmt.Printf("Loaded function: %s\n", scalarFunc.Name()) // Create extension set and registry extSet := extensions.NewSet() reg := expr.NewExtensionRegistry(extSet, collection) // Create function call arg1, _ := expr.NewLiteral(int32(5), false) arg2, _ := expr.NewLiteral(int32(10), false) funcExpr, err := expr.NewScalarFunc(reg, funcID, nil, arg1, arg2) if err != nil { panic(err) } // Get function anchor for use in plans anchor := extSet.GetFuncAnchor(funcID) fmt.Printf("Function registered with anchor: %d\n", anchor) fmt.Printf("Result type: %s\n", funcExpr.GetType()) } ``` -------------------------------- ### Create Literal Values with Substrait Go Source: https://context7.com/substrait-io/substrait-go/llms.txt Illustrates the creation of various literal values supported by the Substrait Go library, including primitive types (integers, strings, floats), null values, structs, lists, and maps. This functionality is fundamental for constructing expressions and plans within Substrait. ```go package main import ( "fmt" "github.com/substrait-io/substrait-go/v7/expr" "github.com/substrait-io/substrait-go/v7/types" ) func main() { // Primitive literals intLit, _ := expr.NewLiteral(int32(42), false) strLit, _ := expr.NewLiteral("hello", false) floatLit, _ := expr.NewLiteral(3.14, false) fmt.Printf("Int: %s\n", intLit.ValueString()) fmt.Printf("String: %s\n", strLit.ValueString()) fmt.Printf("Float: %s\n", floatLit.ValueString()) // Null literal nullInt := expr.NewNullLiteral( &types.Int32Type{Nullability: types.NullabilityNullable}, ) fmt.Printf("Null: %s\n", nullInt) // Struct literal structFields := expr.StructLiteralValue{intLit, strLit} structLit := &expr.ProtoLiteral{ Value: structFields, Type: &types.StructType{ Nullability: types.NullabilityRequired, Types: []types.Type{ &types.Int32Type{Nullability: types.NullabilityRequired}, &types.StringType{Nullability: types.NullabilityRequired}, }, }, } fmt.Printf("Struct: %s\n", structLit) // List literal listItems, _ := expr.NewLiteral([]int32{1, 2, 3}, false) fmt.Printf("List type: %s\n", listItems.GetType()) // Map literal mapLit := &expr.ProtoLiteral{ Value: expr.MapLiteralValue{ {Key: strLit, Value: intLit}, {Key: expr.MustExpr(expr.NewLiteral("world", false)), Value: expr.MustExpr(expr.NewLiteral(int32(100), false))}, }, Type: &types.MapType{ Nullability: types.NullabilityRequired, Key: &types.StringType{Nullability: types.NullabilityRequired}, Value: &types.Int32Type{Nullability: types.NullabilityRequired}, }, } fmt.Printf("Map: %s\n", mapLit) } ``` -------------------------------- ### Generate Substrait Parser Code (Go) Source: https://github.com/substrait-io/substrait-go/blob/main/types/parser/baseparser/README.md This command is used to generate the Go parser code for Substrait types after updating the grammar files. It leverages the `go generate` tool to process the directives defined in the `generate.go` file within the `grammar` directory. This process creates the necessary lexer and parser code based on the specified ANTLR4 grammar files. ```bash go generate ./grammar/... ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.