From 07812e482fd7f3d1d9b209bca7084f471165f352 Mon Sep 17 00:00:00 2001 From: Wes Wickwire Date: Thu, 11 Sep 2025 16:03:17 -0400 Subject: [PATCH 1/5] Lookup composite types when selecting from function --- internal/compiler/output_columns.go | 5 +++++ internal/compiler/query_catalog.go | 20 +++++++++++++++++++ internal/engine/postgresql/parse.go | 26 +++++++++++++++++++++++-- internal/sql/ast/composite_type_stmt.go | 1 + internal/sql/catalog/public.go | 18 +++++++++++++++++ internal/sql/catalog/types.go | 19 +++++++++++++++++- 6 files changed, 86 insertions(+), 3 deletions(-) diff --git a/internal/compiler/output_columns.go b/internal/compiler/output_columns.go index b0a15e6ac4..54a5b4c9db 100644 --- a/internal/compiler/output_columns.go +++ b/internal/compiler/output_columns.go @@ -544,6 +544,11 @@ func (c *Compiler) sourceTables(qc *QueryCatalog, node ast.Node) ([]*Table, erro Schema: fn.ReturnType.Schema, Name: fn.ReturnType.Name, }) + + // Successfully found the table + if err != nil { + table, err = qc.GetCompositeType(fn.ReturnType) + } } if table == nil || err != nil { if n.Alias != nil && len(n.Alias.Colnames.Items) > 0 { diff --git a/internal/compiler/query_catalog.go b/internal/compiler/query_catalog.go index 80b59d876c..51eecf6ce8 100644 --- a/internal/compiler/query_catalog.go +++ b/internal/compiler/query_catalog.go @@ -107,3 +107,23 @@ func (qc QueryCatalog) GetFunc(rel *ast.FuncName) (*Function, error) { ReturnType: funcs[0].ReturnType, }, nil } + +func (qc QueryCatalog) GetCompositeType(rel *ast.TypeName) (*Table, error) { + ty, err := qc.catalog.GetCompostiteType(rel) + if err != nil { + return &Table{}, err + } + + tblName := &ast.TableName{ + Catalog: rel.Catalog, + Schema: rel.Schema, + Name: rel.Name, + } + + var cols []*Column + for _, tyCol := range ty.Columns { + cols = append(cols, ConvertColumn(tblName, tyCol)) + } + + return &Table{Rel: tblName, Columns: cols}, nil +} diff --git a/internal/engine/postgresql/parse.go b/internal/engine/postgresql/parse.go index 40af125962..abdc310905 100644 --- a/internal/engine/postgresql/parse.go +++ b/internal/engine/postgresql/parse.go @@ -392,9 +392,31 @@ func translate(node *nodes.Node) (ast.Node, error) { case *nodes.Node_CompositeTypeStmt: n := inner.CompositeTypeStmt rel := parseRelationFromRangeVar(n.Typevar) - return &ast.CompositeTypeStmt{ + + stmt := &ast.CompositeTypeStmt{ TypeName: rel.TypeName(), - }, nil + } + + for _, elt := range n.GetColdeflist() { + switch item := elt.Node.(type) { + case *nodes.Node_ColumnDef: + rel, err := parseRelationFromNodes(item.ColumnDef.TypeName.Names) + if err != nil { + return nil, err + } + + stmt.Cols = append(stmt.Cols, &ast.ColumnDef{ + Colname: item.ColumnDef.Colname, + TypeName: rel.TypeName(), + IsNotNull: false, // Composite types cannot have constraints + IsArray: isArray(item.ColumnDef.TypeName), + ArrayDims: len(item.ColumnDef.TypeName.ArrayBounds), + PrimaryKey: false, + }) + } + } + + return stmt, nil case *nodes.Node_CreateStmt: n := inner.CreateStmt diff --git a/internal/sql/ast/composite_type_stmt.go b/internal/sql/ast/composite_type_stmt.go index f9a19b2653..3e1a42b64d 100644 --- a/internal/sql/ast/composite_type_stmt.go +++ b/internal/sql/ast/composite_type_stmt.go @@ -2,6 +2,7 @@ package ast type CompositeTypeStmt struct { TypeName *TypeName + Cols []*ColumnDef } func (n *CompositeTypeStmt) Pos() int { diff --git a/internal/sql/catalog/public.go b/internal/sql/catalog/public.go index 19fd50722f..3fcd6e7a97 100644 --- a/internal/sql/catalog/public.go +++ b/internal/sql/catalog/public.go @@ -131,3 +131,21 @@ func (c *Catalog) GetTable(rel *ast.TableName) (Table, error) { return *table, err } } + +func (c *Catalog) GetCompostiteType(rel *ast.TypeName) (CompositeType, error) { + ty, _, err := c.getType(rel) + if err != nil { + return CompositeType{}, err + } + + cTy, ok := ty.(*CompositeType) + if !ok { + return CompositeType{}, fmt.Errorf("Type %s is not a composite type", rel.Name) + } + + if ty == nil { + return CompositeType{}, err + } else { + return *cTy, err + } +} diff --git a/internal/sql/catalog/types.go b/internal/sql/catalog/types.go index 464472bcf2..13f3c4f974 100644 --- a/internal/sql/catalog/types.go +++ b/internal/sql/catalog/types.go @@ -30,6 +30,7 @@ func (e *Enum) isType() { type CompositeType struct { Name string Comment string + Columns []*Column } func (ct *CompositeType) isType() { @@ -135,8 +136,24 @@ func (c *Catalog) createCompositeType(stmt *ast.CompositeTypeStmt) error { if _, _, err := schema.getType(stmt.TypeName); err == nil { return sqlerr.TypeExists(tbl.Name) } + + var cols []*Column + for _, cDef := range stmt.Cols { + cols = append(cols, &Column{ + Name: cDef.Colname, + Type: *cDef.TypeName, + IsNotNull: cDef.IsNotNull, + IsUnsigned: cDef.IsUnsigned, + IsArray: cDef.IsArray, + ArrayDims: cDef.ArrayDims, + Comment: cDef.Comment, + Length: cDef.Length, + }) + } + schema.Types = append(schema.Types, &CompositeType{ - Name: stmt.TypeName.Name, + Name: stmt.TypeName.Name, + Columns: cols, }) return nil } From 88809133d56928a4c4ca49183440f92107529702 Mon Sep 17 00:00:00 2001 From: Wes Wickwire Date: Thu, 11 Sep 2025 16:04:08 -0400 Subject: [PATCH 2/5] Generate structs for composite types --- internal/cmd/shim.go | 25 +++ internal/codegen/golang/result.go | 84 ++++++---- internal/plugin/codegen.pb.go | 270 ++++++++++++++++-------------- internal/sql/catalog/types.go | 1 + protos/plugin/codegen.proto | 1 + 5 files changed, 218 insertions(+), 163 deletions(-) diff --git a/internal/cmd/shim.go b/internal/cmd/shim.go index 654500429a..d1d6248b73 100644 --- a/internal/cmd/shim.go +++ b/internal/cmd/shim.go @@ -73,9 +73,34 @@ func pluginCatalog(c *catalog.Catalog) *plugin.Catalog { Vals: typ.Vals, }) case *catalog.CompositeType: + var columns []*plugin.Column + for _, c := range typ.Columns { + l := -1 + if c.Length != nil { + l = *c.Length + } + columns = append(columns, &plugin.Column{ + Name: c.Name, + Type: &plugin.Identifier{ + Catalog: c.Type.Catalog, + Schema: c.Type.Schema, + Name: c.Type.Name, + }, + Comment: c.Comment, + NotNull: c.IsNotNull, + Unsigned: c.IsUnsigned, + IsArray: c.IsArray, + ArrayDims: int32(c.ArrayDims), + Length: int32(l), + Table: &plugin.Identifier{ + Name: typ.Name, + }, + }) + } cts = append(cts, &plugin.CompositeType{ Name: typ.Name, Comment: typ.Comment, + Columns: columns, }) } } diff --git a/internal/codegen/golang/result.go b/internal/codegen/golang/result.go index 515d0a654f..12e3ff8de2 100644 --- a/internal/codegen/golang/result.go +++ b/internal/codegen/golang/result.go @@ -67,40 +67,11 @@ func buildStructs(req *plugin.GenerateRequest, options *opts.Options) []Struct { continue } for _, table := range schema.Tables { - var tableName string - if schema.Name == req.Catalog.DefaultSchema { - tableName = table.Rel.Name - } else { - tableName = schema.Name + "_" + table.Rel.Name - } - structName := tableName - if !options.EmitExactTableNames { - structName = inflection.Singular(inflection.SingularParams{ - Name: structName, - Exclusions: options.InflectionExcludeTableNames, - }) - } - s := Struct{ - Table: &plugin.Identifier{Schema: schema.Name, Name: table.Rel.Name}, - Name: StructName(structName, options), - Comment: table.Comment, - } - for _, column := range table.Columns { - tags := map[string]string{} - if options.EmitDbTags { - tags["db"] = column.Name - } - if options.EmitJsonTags { - tags["json"] = JSONTagName(column.Name, options) - } - addExtraGoStructTags(tags, req, options, column) - s.Fields = append(s.Fields, Field{ - Name: StructName(column.Name, options), - Type: goType(req, options, column), - Tags: tags, - Comment: column.Comment, - }) - } + s := buildStruct(req, options, schema, table.Rel.Name, table.Comment, table.Columns) + structs = append(structs, s) + } + for _, ty := range schema.CompositeTypes { + s := buildStruct(req, options, schema, ty.Name, ty.Comment, ty.Columns) structs = append(structs, s) } } @@ -110,6 +81,51 @@ func buildStructs(req *plugin.GenerateRequest, options *opts.Options) []Struct { return structs } +func buildStruct( + req *plugin.GenerateRequest, + options *opts.Options, + schema *plugin.Schema, + rawName string, + comment string, + columns []*plugin.Column, +) Struct { + var tableName string + if schema.Name == req.Catalog.DefaultSchema { + tableName = rawName + } else { + tableName = schema.Name + "_" + rawName + } + structName := tableName + if !options.EmitExactTableNames { + structName = inflection.Singular(inflection.SingularParams{ + Name: structName, + Exclusions: options.InflectionExcludeTableNames, + }) + } + s := Struct{ + Table: &plugin.Identifier{Schema: schema.Name, Name: rawName}, + Name: StructName(structName, options), + Comment: comment, + } + for _, column := range columns { + tags := map[string]string{} + if options.EmitDbTags { + tags["db"] = column.Name + } + if options.EmitJsonTags { + tags["json"] = JSONTagName(column.Name, options) + } + addExtraGoStructTags(tags, req, options, column) + s.Fields = append(s.Fields, Field{ + Name: StructName(column.Name, options), + Type: goType(req, options, column), + Tags: tags, + Comment: column.Comment, + }) + } + return s +} + type goColumn struct { id int *plugin.Column diff --git a/internal/plugin/codegen.pb.go b/internal/plugin/codegen.pb.go index 525ffc72ef..45602014ed 100644 --- a/internal/plugin/codegen.pb.go +++ b/internal/plugin/codegen.pb.go @@ -396,8 +396,9 @@ type CompositeType struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Comment string `protobuf:"bytes,2,opt,name=comment,proto3" json:"comment,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Comment string `protobuf:"bytes,2,opt,name=comment,proto3" json:"comment,omitempty"` + Columns []*Column `protobuf:"bytes,3,rep,name=columns,proto3" json:"columns,omitempty"` } func (x *CompositeType) Reset() { @@ -446,6 +447,13 @@ func (x *CompositeType) GetComment() string { return "" } +func (x *CompositeType) GetColumns() []*Column { + if x != nil { + return x.Columns + } + return nil +} + type Enum struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1254,117 +1262,120 @@ var file_plugin_codegen_proto_rawDesc = []byte{ 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0e, 0x63, - 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x22, 0x3d, 0x0a, + 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x22, 0x67, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x48, 0x0a, 0x04, - 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x76, 0x61, 0x6c, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x18, 0x0a, 0x07, - 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, - 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x71, 0x0a, 0x05, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, - 0x24, 0x0a, 0x03, 0x72, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, - 0x52, 0x03, 0x72, 0x65, 0x6c, 0x12, 0x28, 0x0a, 0x07, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, - 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x07, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, - 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x52, 0x0a, 0x0a, 0x49, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x61, 0x74, 0x61, 0x6c, - 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, - 0x67, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x8e, 0x04, - 0x0a, 0x06, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, - 0x6e, 0x6f, 0x74, 0x5f, 0x6e, 0x75, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x6e, 0x6f, 0x74, 0x4e, 0x75, 0x6c, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x61, 0x72, - 0x72, 0x61, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x41, 0x72, 0x72, - 0x61, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, - 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6c, 0x65, - 0x6e, 0x67, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0e, 0x69, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x64, - 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x73, - 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x20, 0x0a, 0x0c, 0x69, 0x73, - 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0a, 0x69, 0x73, 0x46, 0x75, 0x6e, 0x63, 0x43, 0x61, 0x6c, 0x6c, 0x12, 0x14, 0x0a, 0x05, - 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, - 0x70, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x05, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1f, 0x0a, 0x0b, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x26, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x6c, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x07, + 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x07, 0x63, + 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x22, 0x48, 0x0a, 0x04, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, + 0x22, 0x71, 0x0a, 0x05, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x24, 0x0a, 0x03, 0x72, 0x65, 0x6c, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x03, 0x72, 0x65, 0x6c, 0x12, + 0x28, 0x0a, 0x07, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x0e, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, + 0x52, 0x07, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, + 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, + 0x65, 0x6e, 0x74, 0x22, 0x52, 0x0a, 0x0a, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, + 0x72, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x8e, 0x04, 0x0a, 0x06, 0x43, 0x6f, 0x6c, 0x75, + 0x6d, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x6f, 0x74, 0x5f, 0x6e, 0x75, + 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6e, 0x6f, 0x74, 0x4e, 0x75, 0x6c, + 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x41, 0x72, 0x72, 0x61, 0x79, 0x12, 0x18, 0x0a, 0x07, + 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, + 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x24, + 0x0a, 0x0e, 0x69, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x12, 0x20, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x5f, + 0x63, 0x61, 0x6c, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x46, 0x75, + 0x6e, 0x63, 0x43, 0x61, 0x6c, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x05, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x69, 0x73, 0x5f, 0x73, 0x71, 0x6c, 0x63, - 0x5f, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, - 0x53, 0x71, 0x6c, 0x63, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x12, 0x33, 0x0a, 0x0b, 0x65, 0x6d, 0x62, - 0x65, 0x64, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x72, 0x52, 0x0a, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x23, - 0x0a, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x18, - 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x12, - 0x1d, 0x0a, 0x0a, 0x61, 0x72, 0x72, 0x61, 0x79, 0x5f, 0x64, 0x69, 0x6d, 0x73, 0x18, 0x11, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x09, 0x61, 0x72, 0x72, 0x61, 0x79, 0x44, 0x69, 0x6d, 0x73, 0x22, 0x94, - 0x02, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x63, 0x6d, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, - 0x6d, 0x64, 0x12, 0x28, 0x0a, 0x07, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x6f, 0x6c, - 0x75, 0x6d, 0x6e, 0x52, 0x07, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, 0x2d, 0x0a, 0x06, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, - 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x63, - 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, - 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x11, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x6e, - 0x74, 0x6f, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x72, 0x52, 0x11, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x6f, 0x5f, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x4b, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, - 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x06, 0x63, 0x6f, - 0x6c, 0x75, 0x6d, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6c, 0x75, - 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x06, 0x63, 0x6f, 0x6c, 0x75, - 0x6d, 0x6e, 0x22, 0x87, 0x02, 0x0a, 0x0f, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, - 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, - 0x6e, 0x2e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, - 0x69, 0x6e, 0x67, 0x73, 0x12, 0x29, 0x0a, 0x07, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, - 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x52, 0x07, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x12, - 0x27, 0x0a, 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0d, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, - 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x71, 0x6c, 0x63, - 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, - 0x73, 0x71, 0x6c, 0x63, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0e, - 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5f, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x67, 0x6c, - 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x36, 0x0a, 0x10, - 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x22, 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x0c, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x66, - 0x69, 0x6c, 0x65, 0x73, 0x32, 0x4f, 0x0a, 0x0e, 0x43, 0x6f, 0x64, 0x65, 0x67, 0x65, 0x6e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3d, 0x0a, 0x08, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x12, 0x17, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x47, 0x65, 0x6e, 0x65, - 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x6c, - 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x7c, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6c, 0x75, - 0x67, 0x69, 0x6e, 0x42, 0x0c, 0x43, 0x6f, 0x64, 0x65, 0x67, 0x65, 0x6e, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x50, 0x01, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x73, 0x71, 0x6c, 0x63, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x73, 0x71, 0x6c, 0x63, 0x2f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0xa2, 0x02, 0x03, - 0x50, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0xca, 0x02, 0x06, 0x50, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0xe2, 0x02, 0x12, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x06, 0x50, 0x6c, 0x75, - 0x67, 0x69, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x05, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, + 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x26, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x22, 0x0a, 0x0d, 0x69, 0x73, 0x5f, 0x73, 0x71, 0x6c, 0x63, 0x5f, 0x73, 0x6c, 0x69, 0x63, 0x65, + 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x53, 0x71, 0x6c, 0x63, 0x53, 0x6c, + 0x69, 0x63, 0x65, 0x12, 0x33, 0x0a, 0x0b, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x5f, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0a, 0x65, 0x6d, + 0x62, 0x65, 0x64, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, + 0x08, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x08, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x72, 0x72, + 0x61, 0x79, 0x5f, 0x64, 0x69, 0x6d, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x44, 0x69, 0x6d, 0x73, 0x22, 0x94, 0x02, 0x0a, 0x05, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x6d, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, 0x6d, 0x64, 0x12, 0x28, 0x0a, 0x07, + 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x07, 0x63, + 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, 0x2d, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x40, 0x0a, + 0x11, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x6f, 0x5f, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x11, 0x69, 0x6e, + 0x73, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x6f, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x22, + 0x4b, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, + 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x6f, + 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x22, 0x87, 0x02, 0x0a, + 0x0f, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x2c, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x73, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x29, + 0x0a, 0x07, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, + 0x52, 0x07, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x12, 0x27, 0x0a, 0x07, 0x71, 0x75, 0x65, + 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x07, 0x71, 0x75, 0x65, 0x72, 0x69, + 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x71, 0x6c, 0x63, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x71, 0x6c, 0x63, 0x5f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, + 0x0a, 0x0e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x36, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x05, 0x66, 0x69, + 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x32, 0x4f, + 0x0a, 0x0e, 0x43, 0x6f, 0x64, 0x65, 0x67, 0x65, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x3d, 0x0a, 0x08, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x17, 0x2e, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, + 0x7c, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x42, 0x0c, 0x43, + 0x6f, 0x64, 0x65, 0x67, 0x65, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x28, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x71, 0x6c, 0x63, 0x2d, 0x64, + 0x65, 0x76, 0x2f, 0x73, 0x71, 0x6c, 0x63, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0xa2, 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02, 0x06, + 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0xca, 0x02, 0x06, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0xe2, + 0x02, 0x12, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x06, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1406,26 +1417,27 @@ var file_plugin_codegen_proto_depIdxs = []int32{ 7, // 4: plugin.Schema.tables:type_name -> plugin.Table 6, // 5: plugin.Schema.enums:type_name -> plugin.Enum 5, // 6: plugin.Schema.composite_types:type_name -> plugin.CompositeType - 8, // 7: plugin.Table.rel:type_name -> plugin.Identifier - 9, // 8: plugin.Table.columns:type_name -> plugin.Column - 8, // 9: plugin.Column.table:type_name -> plugin.Identifier - 8, // 10: plugin.Column.type:type_name -> plugin.Identifier - 8, // 11: plugin.Column.embed_table:type_name -> plugin.Identifier - 9, // 12: plugin.Query.columns:type_name -> plugin.Column - 11, // 13: plugin.Query.params:type_name -> plugin.Parameter - 8, // 14: plugin.Query.insert_into_table:type_name -> plugin.Identifier - 9, // 15: plugin.Parameter.column:type_name -> plugin.Column - 1, // 16: plugin.GenerateRequest.settings:type_name -> plugin.Settings - 3, // 17: plugin.GenerateRequest.catalog:type_name -> plugin.Catalog - 10, // 18: plugin.GenerateRequest.queries:type_name -> plugin.Query - 0, // 19: plugin.GenerateResponse.files:type_name -> plugin.File - 12, // 20: plugin.CodegenService.Generate:input_type -> plugin.GenerateRequest - 13, // 21: plugin.CodegenService.Generate:output_type -> plugin.GenerateResponse - 21, // [21:22] is the sub-list for method output_type - 20, // [20:21] is the sub-list for method input_type - 20, // [20:20] is the sub-list for extension type_name - 20, // [20:20] is the sub-list for extension extendee - 0, // [0:20] is the sub-list for field type_name + 9, // 7: plugin.CompositeType.columns:type_name -> plugin.Column + 8, // 8: plugin.Table.rel:type_name -> plugin.Identifier + 9, // 9: plugin.Table.columns:type_name -> plugin.Column + 8, // 10: plugin.Column.table:type_name -> plugin.Identifier + 8, // 11: plugin.Column.type:type_name -> plugin.Identifier + 8, // 12: plugin.Column.embed_table:type_name -> plugin.Identifier + 9, // 13: plugin.Query.columns:type_name -> plugin.Column + 11, // 14: plugin.Query.params:type_name -> plugin.Parameter + 8, // 15: plugin.Query.insert_into_table:type_name -> plugin.Identifier + 9, // 16: plugin.Parameter.column:type_name -> plugin.Column + 1, // 17: plugin.GenerateRequest.settings:type_name -> plugin.Settings + 3, // 18: plugin.GenerateRequest.catalog:type_name -> plugin.Catalog + 10, // 19: plugin.GenerateRequest.queries:type_name -> plugin.Query + 0, // 20: plugin.GenerateResponse.files:type_name -> plugin.File + 12, // 21: plugin.CodegenService.Generate:input_type -> plugin.GenerateRequest + 13, // 22: plugin.CodegenService.Generate:output_type -> plugin.GenerateResponse + 22, // [22:23] is the sub-list for method output_type + 21, // [21:22] is the sub-list for method input_type + 21, // [21:21] is the sub-list for extension type_name + 21, // [21:21] is the sub-list for extension extendee + 0, // [0:21] is the sub-list for field type_name } func init() { file_plugin_codegen_proto_init() } diff --git a/internal/sql/catalog/types.go b/internal/sql/catalog/types.go index 13f3c4f974..631a7c9368 100644 --- a/internal/sql/catalog/types.go +++ b/internal/sql/catalog/types.go @@ -155,6 +155,7 @@ func (c *Catalog) createCompositeType(stmt *ast.CompositeTypeStmt) error { Name: stmt.TypeName.Name, Columns: cols, }) + // schema.Tables = append(schema.Tables, &Table{Rel: tbl, Columns: cols}) return nil } diff --git a/protos/plugin/codegen.proto b/protos/plugin/codegen.proto index e6faf19bad..fa31a3bfed 100644 --- a/protos/plugin/codegen.proto +++ b/protos/plugin/codegen.proto @@ -61,6 +61,7 @@ message Schema { message CompositeType { string name = 1; string comment = 2; + repeated Column columns = 3; } message Enum { From 35dd0ae221b9a2044f397dcd40b3e16ad15c74a6 Mon Sep 17 00:00:00 2001 From: Wes Wickwire Date: Thu, 11 Sep 2025 16:54:52 -0400 Subject: [PATCH 3/5] Updated existing tests to pass --- .../testdata/composite_type/pgx/v4/go/models.go | 10 ++++++++++ .../testdata/composite_type/pgx/v5/go/models.go | 12 ++++++++++++ .../testdata/composite_type/stdlib/go/models.go | 10 ++++++++++ 3 files changed, 32 insertions(+) diff --git a/internal/endtoend/testdata/composite_type/pgx/v4/go/models.go b/internal/endtoend/testdata/composite_type/pgx/v4/go/models.go index 6ed24d1fa0..6f256f6617 100644 --- a/internal/endtoend/testdata/composite_type/pgx/v4/go/models.go +++ b/internal/endtoend/testdata/composite_type/pgx/v4/go/models.go @@ -12,3 +12,13 @@ type FooPath struct { PointOne sql.NullString PointTwo sql.NullString } + +type FooPointType struct { + X sql.NullInt32 + Y sql.NullInt32 +} + +type PointType struct { + X sql.NullInt32 + Y sql.NullInt32 +} diff --git a/internal/endtoend/testdata/composite_type/pgx/v5/go/models.go b/internal/endtoend/testdata/composite_type/pgx/v5/go/models.go index 6ed24d1fa0..ef02039f98 100644 --- a/internal/endtoend/testdata/composite_type/pgx/v5/go/models.go +++ b/internal/endtoend/testdata/composite_type/pgx/v5/go/models.go @@ -6,9 +6,21 @@ package querytest import ( "database/sql" + + "github.com/jackc/pgx/v5/pgtype" ) type FooPath struct { PointOne sql.NullString PointTwo sql.NullString } + +type FooPointType struct { + X pgtype.Int4 + Y pgtype.Int4 +} + +type PointType struct { + X pgtype.Int4 + Y pgtype.Int4 +} diff --git a/internal/endtoend/testdata/composite_type/stdlib/go/models.go b/internal/endtoend/testdata/composite_type/stdlib/go/models.go index 6ed24d1fa0..6f256f6617 100644 --- a/internal/endtoend/testdata/composite_type/stdlib/go/models.go +++ b/internal/endtoend/testdata/composite_type/stdlib/go/models.go @@ -12,3 +12,13 @@ type FooPath struct { PointOne sql.NullString PointTwo sql.NullString } + +type FooPointType struct { + X sql.NullInt32 + Y sql.NullInt32 +} + +type PointType struct { + X sql.NullInt32 + Y sql.NullInt32 +} From e6fff7a05144d33a8f2b0e97ea2daba83a5b24a7 Mon Sep 17 00:00:00 2001 From: Wes Wickwire Date: Thu, 11 Sep 2025 17:35:16 -0400 Subject: [PATCH 4/5] New pgx tests --- internal/compiler/output_columns.go | 2 +- .../select_fn/postgresql/pgx/v5/go/db.go | 32 ++++++++++ .../select_fn/postgresql/pgx/v5/go/models.go | 59 +++++++++++++++++++ .../postgresql/pgx/v5/go/query.sql.go | 58 ++++++++++++++++++ .../select_fn/postgresql/pgx/v5/query.sql | 5 ++ .../select_fn/postgresql/pgx/v5/schema.sql | 13 ++++ .../select_fn/postgresql/pgx/v5/sqlc.json | 13 ++++ internal/sql/catalog/types.go | 1 - 8 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/db.go create mode 100644 internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/models.go create mode 100644 internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/query.sql.go create mode 100644 internal/endtoend/testdata/select_fn/postgresql/pgx/v5/query.sql create mode 100644 internal/endtoend/testdata/select_fn/postgresql/pgx/v5/schema.sql create mode 100644 internal/endtoend/testdata/select_fn/postgresql/pgx/v5/sqlc.json diff --git a/internal/compiler/output_columns.go b/internal/compiler/output_columns.go index 54a5b4c9db..12bfc89e06 100644 --- a/internal/compiler/output_columns.go +++ b/internal/compiler/output_columns.go @@ -545,7 +545,7 @@ func (c *Compiler) sourceTables(qc *QueryCatalog, node ast.Node) ([]*Table, erro Name: fn.ReturnType.Name, }) - // Successfully found the table + // Failed to find table, check for type with name. if err != nil { table, err = qc.GetCompositeType(fn.ReturnType) } diff --git a/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/db.go b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/db.go new file mode 100644 index 0000000000..1e00549714 --- /dev/null +++ b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/db.go @@ -0,0 +1,32 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 + +package querytest + +import ( + "context" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" +) + +type DBTX interface { + Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error) + Query(context.Context, string, ...interface{}) (pgx.Rows, error) + QueryRow(context.Context, string, ...interface{}) pgx.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx pgx.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/models.go b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/models.go new file mode 100644 index 0000000000..c5e65efed6 --- /dev/null +++ b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/models.go @@ -0,0 +1,59 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 + +package querytest + +import ( + "database/sql/driver" + "fmt" + + "github.com/jackc/pgx/v5/pgtype" +) + +type Foo string + +const ( + FooBar Foo = "bar" + FooBaz Foo = "baz" +) + +func (e *Foo) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = Foo(s) + case string: + *e = Foo(s) + default: + return fmt.Errorf("unsupported scan type for Foo: %T", src) + } + return nil +} + +type NullFoo struct { + Foo Foo + Valid bool // Valid is true if Foo is not NULL +} + +// Scan implements the Scanner interface. +func (ns *NullFoo) Scan(value interface{}) error { + if value == nil { + ns.Foo, ns.Valid = "", false + return nil + } + ns.Valid = true + return ns.Foo.Scan(value) +} + +// Value implements the driver Valuer interface. +func (ns NullFoo) Value() (driver.Value, error) { + if !ns.Valid { + return nil, nil + } + return string(ns.Foo), nil +} + +type Bar struct { + Foo NullFoo + Baz pgtype.Int4 +} diff --git a/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/query.sql.go b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/query.sql.go new file mode 100644 index 0000000000..c58f04f4d9 --- /dev/null +++ b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/query.sql.go @@ -0,0 +1,58 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.30.0 +// source: query.sql + +package querytest + +import ( + "context" +) + +const selectBars = `-- name: SelectBars :many +SELECT foo, baz FROM bar_fn() +` + +func (q *Queries) SelectBars(ctx context.Context) ([]Bar, error) { + rows, err := q.db.Query(ctx, selectBars) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Bar + for rows.Next() { + var i Bar + if err := rows.Scan(&i.Foo, &i.Baz); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const selectFoos = `-- name: SelectFoos :many +SELECT foo_fn FROM foo_fn() +` + +func (q *Queries) SelectFoos(ctx context.Context) ([]NullFoo, error) { + rows, err := q.db.Query(ctx, selectFoos) + if err != nil { + return nil, err + } + defer rows.Close() + var items []NullFoo + for rows.Next() { + var foo_fn NullFoo + if err := rows.Scan(&foo_fn); err != nil { + return nil, err + } + items = append(items, foo_fn) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/query.sql b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/query.sql new file mode 100644 index 0000000000..3a0d295fb3 --- /dev/null +++ b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/query.sql @@ -0,0 +1,5 @@ +-- name: SelectBars :many +SELECT * FROM bar_fn(); + +-- name: SelectFoos :many +SELECT * FROM foo_fn(); diff --git a/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/schema.sql b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/schema.sql new file mode 100644 index 0000000000..cb33edeced --- /dev/null +++ b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/schema.sql @@ -0,0 +1,13 @@ +CREATE TYPE foo AS ENUM ('bar', 'baz'); + +CREATE TYPE bar AS (foo foo, baz INTEGER); + +CREATE FUNCTION bar_fn() +RETURNS SETOF bar LANGUAGE SQL STABLE AS $$ +SELECT * FROM VALUES ('bar', 1); +$$; + +CREATE FUNCTION foo_fn() +RETURNS SETOF foo LANGUAGE SQL STABLE AS $$ +SELECT * FROM VALUES ('bar'); +$$; diff --git a/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/sqlc.json b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/sqlc.json new file mode 100644 index 0000000000..32ede07158 --- /dev/null +++ b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/sqlc.json @@ -0,0 +1,13 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "engine": "postgresql", + "sql_package": "pgx/v5", + "name": "querytest", + "schema": "schema.sql", + "queries": "query.sql" + } + ] +} diff --git a/internal/sql/catalog/types.go b/internal/sql/catalog/types.go index 631a7c9368..13f3c4f974 100644 --- a/internal/sql/catalog/types.go +++ b/internal/sql/catalog/types.go @@ -155,7 +155,6 @@ func (c *Catalog) createCompositeType(stmt *ast.CompositeTypeStmt) error { Name: stmt.TypeName.Name, Columns: cols, }) - // schema.Tables = append(schema.Tables, &Table{Rel: tbl, Columns: cols}) return nil } From c11b647f34145970b23bfb1367996d57bf9beefe Mon Sep 17 00:00:00 2001 From: Wes Wickwire Date: Thu, 11 Sep 2025 18:07:46 -0400 Subject: [PATCH 5/5] Added support for embeding custom types --- internal/compiler/output_columns.go | 8 ++- internal/compiler/query_catalog.go | 2 +- internal/compiler/resolve.go | 11 ++++ .../select_fn/postgresql/pgx/v5/go/models.go | 50 ++-------------- .../postgresql/pgx/v5/go/query.sql.go | 57 ++++++++++++++----- .../select_fn/postgresql/pgx/v5/query.sql | 9 ++- .../select_fn/postgresql/pgx/v5/schema.sql | 11 +--- 7 files changed, 76 insertions(+), 72 deletions(-) diff --git a/internal/compiler/output_columns.go b/internal/compiler/output_columns.go index 12bfc89e06..b47e25feb5 100644 --- a/internal/compiler/output_columns.go +++ b/internal/compiler/output_columns.go @@ -545,9 +545,13 @@ func (c *Compiler) sourceTables(qc *QueryCatalog, node ast.Node) ([]*Table, erro Name: fn.ReturnType.Name, }) - // Failed to find table, check for type with name. if err != nil { - table, err = qc.GetCompositeType(fn.ReturnType) + // No table, check to see if there a type + tyTable, tyErr := qc.GetTableForType(fn.ReturnType) + if tyErr == nil { + table = tyTable + err = nil + } } } if table == nil || err != nil { diff --git a/internal/compiler/query_catalog.go b/internal/compiler/query_catalog.go index 51eecf6ce8..16f54039d7 100644 --- a/internal/compiler/query_catalog.go +++ b/internal/compiler/query_catalog.go @@ -108,7 +108,7 @@ func (qc QueryCatalog) GetFunc(rel *ast.FuncName) (*Function, error) { }, nil } -func (qc QueryCatalog) GetCompositeType(rel *ast.TypeName) (*Table, error) { +func (qc QueryCatalog) GetTableForType(rel *ast.TypeName) (*Table, error) { ty, err := qc.catalog.GetCompostiteType(rel) if err != nil { return &Table{}, err diff --git a/internal/compiler/resolve.go b/internal/compiler/resolve.go index b1fbb1990e..5612337b4e 100644 --- a/internal/compiler/resolve.go +++ b/internal/compiler/resolve.go @@ -94,6 +94,17 @@ func (comp *Compiler) resolveCatalogRefs(qc *QueryCatalog, rvs []*ast.RangeVar, continue } + tyName := &ast.TypeName{ + Catalog: embed.Table.Catalog, + Schema: embed.Table.Schema, + Name: embed.Table.Name, + } + ty, err := c.GetCompostiteType(tyName) + if err == nil { + embed.Table = &ast.TableName{Name: ty.Name} + continue + } + return nil, fmt.Errorf("unable to resolve table with %q: %w", embed.Orig(), err) } diff --git a/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/models.go b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/models.go index c5e65efed6..62c4b45ba9 100644 --- a/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/models.go +++ b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/models.go @@ -5,55 +5,15 @@ package querytest import ( - "database/sql/driver" - "fmt" - "github.com/jackc/pgx/v5/pgtype" ) -type Foo string - -const ( - FooBar Foo = "bar" - FooBaz Foo = "baz" -) - -func (e *Foo) Scan(src interface{}) error { - switch s := src.(type) { - case []byte: - *e = Foo(s) - case string: - *e = Foo(s) - default: - return fmt.Errorf("unsupported scan type for Foo: %T", src) - } - return nil -} - -type NullFoo struct { - Foo Foo - Valid bool // Valid is true if Foo is not NULL -} - -// Scan implements the Scanner interface. -func (ns *NullFoo) Scan(value interface{}) error { - if value == nil { - ns.Foo, ns.Valid = "", false - return nil - } - ns.Valid = true - return ns.Foo.Scan(value) -} - -// Value implements the driver Valuer interface. -func (ns NullFoo) Value() (driver.Value, error) { - if !ns.Valid { - return nil, nil - } - return string(ns.Foo), nil +type Bar struct { + Foo pgtype.Text + Baz pgtype.Int4 } -type Bar struct { - Foo NullFoo +type Foo struct { + Foo pgtype.Text Baz pgtype.Int4 } diff --git a/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/query.sql.go b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/query.sql.go index c58f04f4d9..3998673292 100644 --- a/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/query.sql.go +++ b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/go/query.sql.go @@ -7,22 +7,29 @@ package querytest import ( "context" + + "github.com/jackc/pgx/v5/pgtype" ) -const selectBars = `-- name: SelectBars :many -SELECT foo, baz FROM bar_fn() +const selectFooEmbed = `-- name: SelectFooEmbed :many +SELECT foo.foo, foo.baz, 1 AS one FROM foo_fn() AS foo ` -func (q *Queries) SelectBars(ctx context.Context) ([]Bar, error) { - rows, err := q.db.Query(ctx, selectBars) +type SelectFooEmbedRow struct { + Foo Foo + One int32 +} + +func (q *Queries) SelectFooEmbed(ctx context.Context) ([]SelectFooEmbedRow, error) { + rows, err := q.db.Query(ctx, selectFooEmbed) if err != nil { return nil, err } defer rows.Close() - var items []Bar + var items []SelectFooEmbedRow for rows.Next() { - var i Bar - if err := rows.Scan(&i.Foo, &i.Baz); err != nil { + var i SelectFooEmbedRow + if err := rows.Scan(&i.Foo.Foo, &i.Foo.Baz, &i.One); err != nil { return nil, err } items = append(items, i) @@ -34,22 +41,46 @@ func (q *Queries) SelectBars(ctx context.Context) ([]Bar, error) { } const selectFoos = `-- name: SelectFoos :many -SELECT foo_fn FROM foo_fn() +SELECT foo, baz FROM foo_fn() ` -func (q *Queries) SelectFoos(ctx context.Context) ([]NullFoo, error) { +func (q *Queries) SelectFoos(ctx context.Context) ([]Foo, error) { rows, err := q.db.Query(ctx, selectFoos) if err != nil { return nil, err } defer rows.Close() - var items []NullFoo + var items []Foo + for rows.Next() { + var i Foo + if err := rows.Scan(&i.Foo, &i.Baz); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const selectSingleColumn = `-- name: SelectSingleColumn :many +SELECT baz FROM foo_fn() +` + +func (q *Queries) SelectSingleColumn(ctx context.Context) ([]pgtype.Int4, error) { + rows, err := q.db.Query(ctx, selectSingleColumn) + if err != nil { + return nil, err + } + defer rows.Close() + var items []pgtype.Int4 for rows.Next() { - var foo_fn NullFoo - if err := rows.Scan(&foo_fn); err != nil { + var baz pgtype.Int4 + if err := rows.Scan(&baz); err != nil { return nil, err } - items = append(items, foo_fn) + items = append(items, baz) } if err := rows.Err(); err != nil { return nil, err diff --git a/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/query.sql b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/query.sql index 3a0d295fb3..21684a205e 100644 --- a/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/query.sql +++ b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/query.sql @@ -1,5 +1,8 @@ --- name: SelectBars :many -SELECT * FROM bar_fn(); - -- name: SelectFoos :many SELECT * FROM foo_fn(); + +-- name: SelectFooEmbed :many +SELECT sqlc.embed(foo), 1 AS one FROM foo_fn() AS foo; + +-- name: SelectSingleColumn :many +SELECT baz FROM foo_fn(); diff --git a/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/schema.sql b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/schema.sql index cb33edeced..0b69861601 100644 --- a/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/schema.sql +++ b/internal/endtoend/testdata/select_fn/postgresql/pgx/v5/schema.sql @@ -1,13 +1,8 @@ -CREATE TYPE foo AS ENUM ('bar', 'baz'); +CREATE TYPE foo AS (foo TEXT, baz INTEGER); -CREATE TYPE bar AS (foo foo, baz INTEGER); - -CREATE FUNCTION bar_fn() -RETURNS SETOF bar LANGUAGE SQL STABLE AS $$ -SELECT * FROM VALUES ('bar', 1); -$$; +CREATE TABLE bar (foo TEXT, baz INTEGER); CREATE FUNCTION foo_fn() RETURNS SETOF foo LANGUAGE SQL STABLE AS $$ -SELECT * FROM VALUES ('bar'); +SELECT foo, baz FROM bar; $$;