From 992cfa2ab79d626a982787c73adf7585b74e6641 Mon Sep 17 00:00:00 2001 From: Vladimir Romashchenko Date: Sat, 29 Mar 2025 14:37:46 -0400 Subject: [PATCH 1/4] Propagate composite type field types from parser to plugin proto --- internal/cmd/shim.go | 18 +- internal/engine/postgresql/convert.go | 3 +- internal/engine/postgresql/parse.go | 23 +- internal/plugin/codegen.pb.go | 271 +++++++++++++----------- internal/sql/ast/composite_type_stmt.go | 3 +- internal/sql/astutils/rewrite.go | 1 + internal/sql/catalog/types.go | 63 ++++-- protos/plugin/codegen.proto | 1 + 8 files changed, 228 insertions(+), 155 deletions(-) diff --git a/internal/cmd/shim.go b/internal/cmd/shim.go index 654500429a..20a77248a9 100644 --- a/internal/cmd/shim.go +++ b/internal/cmd/shim.go @@ -6,6 +6,7 @@ import ( "github.com/sqlc-dev/sqlc/internal/config/convert" "github.com/sqlc-dev/sqlc/internal/info" "github.com/sqlc-dev/sqlc/internal/plugin" + "github.com/sqlc-dev/sqlc/internal/sql/ast" "github.com/sqlc-dev/sqlc/internal/sql/catalog" ) @@ -59,6 +60,18 @@ func pluginWASM(p config.Plugin) *plugin.Codegen_WASM { return nil } +func identifierSlice(types []*ast.TypeName) []*plugin.Identifier { + ids := []*plugin.Identifier{} + for _, typ := range types { + ids = append(ids, &plugin.Identifier{ + Catalog: typ.Catalog, + Schema: typ.Schema, + Name: typ.Name, + }) + } + return ids +} + func pluginCatalog(c *catalog.Catalog) *plugin.Catalog { var schemas []*plugin.Schema for _, s := range c.Schemas { @@ -74,8 +87,9 @@ func pluginCatalog(c *catalog.Catalog) *plugin.Catalog { }) case *catalog.CompositeType: cts = append(cts, &plugin.CompositeType{ - Name: typ.Name, - Comment: typ.Comment, + Name: typ.Name, + Comment: typ.Comment, + ColTypeNames: identifierSlice(typ.ColTypeNames), }) } } diff --git a/internal/engine/postgresql/convert.go b/internal/engine/postgresql/convert.go index f56a572c16..80cbea75f5 100644 --- a/internal/engine/postgresql/convert.go +++ b/internal/engine/postgresql/convert.go @@ -889,7 +889,8 @@ func convertCompositeTypeStmt(n *pg.CompositeTypeStmt) *ast.CompositeTypeStmt { } rel := parseRelationFromRangeVar(n.Typevar) return &ast.CompositeTypeStmt{ - TypeName: rel.TypeName(), + TypeName: rel.TypeName(), + ColDefList: convertSlice(n.GetColdeflist()), } } diff --git a/internal/engine/postgresql/parse.go b/internal/engine/postgresql/parse.go index 40af125962..2723b5215b 100644 --- a/internal/engine/postgresql/parse.go +++ b/internal/engine/postgresql/parse.go @@ -392,9 +392,26 @@ func translate(node *nodes.Node) (ast.Node, error) { case *nodes.Node_CompositeTypeStmt: n := inner.CompositeTypeStmt rel := parseRelationFromRangeVar(n.Typevar) - return &ast.CompositeTypeStmt{ - TypeName: rel.TypeName(), - }, nil + stmt := &ast.CompositeTypeStmt{ + TypeName: rel.TypeName(), + ColDefList: &ast.List{}, + } + for _, val := range n.GetColdeflist() { + switch item := val.Node.(type) { + case *nodes.Node_ColumnDef: + rel, err := parseRelationFromNodes(item.ColumnDef.TypeName.Names) + if err != nil { + return nil, err + } + stmt.ColDefList.Items = append(stmt.ColDefList.Items, &ast.ColumnDef{ + Colname: item.ColumnDef.GetColname(), + TypeName: rel.TypeName(), + IsLocal: true, + CollClause: convertCollateClause(item.ColumnDef.GetCollClause()), + }) + } + } + return stmt, nil case *nodes.Node_CreateStmt: n := inner.CreateStmt diff --git a/internal/plugin/codegen.pb.go b/internal/plugin/codegen.pb.go index 525ffc72ef..cfdef55710 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"` + ColTypeNames []*Identifier `protobuf:"bytes,3,rep,name=col_type_names,json=colTypeNames,proto3" json:"col_type_names,omitempty"` } func (x *CompositeType) Reset() { @@ -446,6 +447,13 @@ func (x *CompositeType) GetComment() string { return "" } +func (x *CompositeType) GetColTypeNames() []*Identifier { + if x != nil { + return x.ColTypeNames + } + return nil +} + type Enum struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1254,117 +1262,121 @@ 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, 0x77, 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, 0x38, 0x0a, 0x0e, + 0x63, 0x6f, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x54, 0x79, 0x70, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 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 +1418,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 + 8, // 7: plugin.CompositeType.col_type_names:type_name -> plugin.Identifier + 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/ast/composite_type_stmt.go b/internal/sql/ast/composite_type_stmt.go index f9a19b2653..d85fdc88f7 100644 --- a/internal/sql/ast/composite_type_stmt.go +++ b/internal/sql/ast/composite_type_stmt.go @@ -1,7 +1,8 @@ package ast type CompositeTypeStmt struct { - TypeName *TypeName + TypeName *TypeName + ColDefList *List } func (n *CompositeTypeStmt) Pos() int { diff --git a/internal/sql/astutils/rewrite.go b/internal/sql/astutils/rewrite.go index 93c5be3cfb..6a9bfcf79a 100644 --- a/internal/sql/astutils/rewrite.go +++ b/internal/sql/astutils/rewrite.go @@ -495,6 +495,7 @@ func (a *application) apply(parent ast.Node, name string, iter *iterator, n ast. case *ast.CompositeTypeStmt: a.apply(n, "TypeName", nil, n.TypeName) + a.apply(n, "ColDefList", nil, n.ColDefList) case *ast.Const: a.apply(n, "Xpr", nil, n.Xpr) diff --git a/internal/sql/catalog/types.go b/internal/sql/catalog/types.go index 464472bcf2..373fe168c2 100644 --- a/internal/sql/catalog/types.go +++ b/internal/sql/catalog/types.go @@ -28,8 +28,9 @@ func (e *Enum) isType() { } type CompositeType struct { - Name string - Comment string + Name string + ColTypeNames []*ast.TypeName + Comment string } func (ct *CompositeType) isType() { @@ -101,6 +102,16 @@ func stringSlice(list *ast.List) []string { return items } +func columnTypeNamesSlice(list *ast.List) []*ast.TypeName { + items := []*ast.TypeName{} + for _, item := range list.Items { + if n, ok := item.(*ast.ColumnDef); ok { + items = append(items, n.TypeName) + } + } + return items +} + func (c *Catalog) getType(rel *ast.TypeName) (Type, int, error) { ns := rel.Schema if ns == "" { @@ -136,7 +147,8 @@ func (c *Catalog) createCompositeType(stmt *ast.CompositeTypeStmt) error { return sqlerr.TypeExists(tbl.Name) } schema.Types = append(schema.Types, &CompositeType{ - Name: stmt.TypeName.Name, + Name: stmt.TypeName.Name, + ColTypeNames: columnTypeNamesSlice(stmt.ColDefList), }) return nil } @@ -277,16 +289,11 @@ func (c *Catalog) alterTypeSetSchema(stmt *ast.AlterTypeSetSchemaStmt) error { oldSchema.Types = append(oldSchema.Types[:idx], oldSchema.Types[idx+1:]...) newSchema.Types = append(newSchema.Types, typ) - // Update all the table columns with the new type - for _, schema := range c.Schemas { - for _, table := range schema.Tables { - for _, column := range table.Columns { - if column.Type == oldType { - column.Type.Schema = *stmt.NewSchema - } - } + c.updateTypeNames(func(t *ast.TypeName) { + if *t == oldType { + t.Schema = *stmt.NewSchema } - } + }) return nil } @@ -343,8 +350,9 @@ func (c *Catalog) renameType(stmt *ast.RenameTypeStmt) error { case *CompositeType: schema.Types[idx] = &CompositeType{ - Name: newName, - Comment: typ.Comment, + Name: newName, + ColTypeNames: typ.ColTypeNames, + Comment: typ.Comment, } case *Enum: @@ -359,16 +367,33 @@ func (c *Catalog) renameType(stmt *ast.RenameTypeStmt) error { } - // Update all the table columns with the new type + c.updateTypeNames(func(t *ast.TypeName) { + if *t == *stmt.Type { + t.Name = newName + } + }) + + return nil +} + +func (c *Catalog) updateTypeNames(typeUpdater func(t *ast.TypeName)) error { for _, schema := range c.Schemas { + // Update all the table columns with the new type for _, table := range schema.Tables { for _, column := range table.Columns { - if column.Type == *stmt.Type { - column.Type.Name = newName - } + typeUpdater(&column.Type) + } + } + // Update all the composite fields with the new type + for _, typ := range schema.Types { + composite, ok := typ.(*CompositeType) + if !ok { + continue + } + for _, fieldType := range composite.ColTypeNames { + typeUpdater(fieldType) } } } - return nil } diff --git a/protos/plugin/codegen.proto b/protos/plugin/codegen.proto index e6faf19bad..bc38c520aa 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 Identifier col_type_names = 3; } message Enum { From f9d1b90ede268ca51fb395d43853b8e4f351485e Mon Sep 17 00:00:00 2001 From: Vladimir Romashchenko Date: Sun, 30 Mar 2025 13:39:01 -0500 Subject: [PATCH 2/4] Pass full column definition instead of just typename --- internal/cmd/shim.go | 73 ++++++++++++++++------------------- internal/plugin/codegen.pb.go | 23 ++++++----- internal/sql/catalog/types.go | 42 +++++++++++++------- protos/plugin/codegen.proto | 2 +- 4 files changed, 73 insertions(+), 67 deletions(-) diff --git a/internal/cmd/shim.go b/internal/cmd/shim.go index 20a77248a9..2b2537ff71 100644 --- a/internal/cmd/shim.go +++ b/internal/cmd/shim.go @@ -6,7 +6,6 @@ import ( "github.com/sqlc-dev/sqlc/internal/config/convert" "github.com/sqlc-dev/sqlc/internal/info" "github.com/sqlc-dev/sqlc/internal/plugin" - "github.com/sqlc-dev/sqlc/internal/sql/ast" "github.com/sqlc-dev/sqlc/internal/sql/catalog" ) @@ -60,16 +59,38 @@ func pluginWASM(p config.Plugin) *plugin.Codegen_WASM { return nil } -func identifierSlice(types []*ast.TypeName) []*plugin.Identifier { - ids := []*plugin.Identifier{} - for _, typ := range types { - ids = append(ids, &plugin.Identifier{ - Catalog: typ.Catalog, - Schema: typ.Schema, - Name: typ.Name, +func columnSlice(cols []*catalog.Column, table *catalog.Table) []*plugin.Column { + var columns []*plugin.Column + for _, c := range cols { + l := -1 + if c.Length != nil { + l = *c.Length + } + var tableId *plugin.Identifier = nil + if table != nil { + tableId = &plugin.Identifier{ + Catalog: table.Rel.Catalog, + Schema: table.Rel.Schema, + Name: table.Rel.Name, + } + } + 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: tableId, }) } - return ids + return columns } func pluginCatalog(c *catalog.Catalog) *plugin.Catalog { @@ -87,47 +108,21 @@ func pluginCatalog(c *catalog.Catalog) *plugin.Catalog { }) case *catalog.CompositeType: cts = append(cts, &plugin.CompositeType{ - Name: typ.Name, - Comment: typ.Comment, - ColTypeNames: identifierSlice(typ.ColTypeNames), + Name: typ.Name, + Comment: typ.Comment, + Columns: columnSlice(typ.Columns, nil), }) } } var tables []*plugin.Table for _, t := range s.Tables { - var columns []*plugin.Column - for _, c := range t.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{ - Catalog: t.Rel.Catalog, - Schema: t.Rel.Schema, - Name: t.Rel.Name, - }, - }) - } tables = append(tables, &plugin.Table{ Rel: &plugin.Identifier{ Catalog: t.Rel.Catalog, Schema: t.Rel.Schema, Name: t.Rel.Name, }, - Columns: columns, + Columns: columnSlice(t.Columns, t), Comment: t.Comment, }) } diff --git a/internal/plugin/codegen.pb.go b/internal/plugin/codegen.pb.go index cfdef55710..45602014ed 100644 --- a/internal/plugin/codegen.pb.go +++ b/internal/plugin/codegen.pb.go @@ -396,9 +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"` - ColTypeNames []*Identifier `protobuf:"bytes,3,rep,name=col_type_names,json=colTypeNames,proto3" json:"col_type_names,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() { @@ -447,9 +447,9 @@ func (x *CompositeType) GetComment() string { return "" } -func (x *CompositeType) GetColTypeNames() []*Identifier { +func (x *CompositeType) GetColumns() []*Column { if x != nil { - return x.ColTypeNames + return x.Columns } return nil } @@ -1262,15 +1262,14 @@ 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, 0x77, 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, 0x12, 0x38, 0x0a, 0x0e, - 0x63, 0x6f, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x49, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x54, 0x79, 0x70, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x48, 0x0a, 0x04, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x12, + 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, @@ -1418,7 +1417,7 @@ 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.CompositeType.col_type_names:type_name -> plugin.Identifier + 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 diff --git a/internal/sql/catalog/types.go b/internal/sql/catalog/types.go index 373fe168c2..b98387c0ca 100644 --- a/internal/sql/catalog/types.go +++ b/internal/sql/catalog/types.go @@ -28,9 +28,9 @@ func (e *Enum) isType() { } type CompositeType struct { - Name string - ColTypeNames []*ast.TypeName - Comment string + Name string + Columns []*Column + Comment string } func (ct *CompositeType) isType() { @@ -102,11 +102,11 @@ func stringSlice(list *ast.List) []string { return items } -func columnTypeNamesSlice(list *ast.List) []*ast.TypeName { - items := []*ast.TypeName{} +func columnDefsSlice(list *ast.List) []*ast.ColumnDef { + items := []*ast.ColumnDef{} for _, item := range list.Items { if n, ok := item.(*ast.ColumnDef); ok { - items = append(items, n.TypeName) + items = append(items, n) } } return items @@ -146,10 +146,22 @@ func (c *Catalog) createCompositeType(stmt *ast.CompositeTypeStmt) error { if _, _, err := schema.getType(stmt.TypeName); err == nil { return sqlerr.TypeExists(tbl.Name) } - schema.Types = append(schema.Types, &CompositeType{ - Name: stmt.TypeName.Name, - ColTypeNames: columnTypeNamesSlice(stmt.ColDefList), - }) + ct := &CompositeType{ + Name: stmt.TypeName.Name, + } + for _, col := range columnDefsSlice(stmt.ColDefList) { + ct.Columns = append(ct.Columns, &Column{ + Name: col.Colname, + Type: *col.TypeName, + IsNotNull: col.IsNotNull, + IsUnsigned: col.IsUnsigned, + IsArray: col.IsArray, + ArrayDims: col.ArrayDims, + Comment: col.Comment, + Length: col.Length, + }) + } + schema.Types = append(schema.Types, ct) return nil } @@ -350,9 +362,9 @@ func (c *Catalog) renameType(stmt *ast.RenameTypeStmt) error { case *CompositeType: schema.Types[idx] = &CompositeType{ - Name: newName, - ColTypeNames: typ.ColTypeNames, - Comment: typ.Comment, + Name: newName, + Columns: typ.Columns, + Comment: typ.Comment, } case *Enum: @@ -390,8 +402,8 @@ func (c *Catalog) updateTypeNames(typeUpdater func(t *ast.TypeName)) error { if !ok { continue } - for _, fieldType := range composite.ColTypeNames { - typeUpdater(fieldType) + for _, fieldType := range composite.Columns { + typeUpdater(&fieldType.Type) } } } diff --git a/protos/plugin/codegen.proto b/protos/plugin/codegen.proto index bc38c520aa..fa31a3bfed 100644 --- a/protos/plugin/codegen.proto +++ b/protos/plugin/codegen.proto @@ -61,7 +61,7 @@ message Schema { message CompositeType { string name = 1; string comment = 2; - repeated Identifier col_type_names = 3; + repeated Column columns = 3; } message Enum { From 69ccc9472cd8743b0699d66a5ceb1dff30b1b617 Mon Sep 17 00:00:00 2001 From: Vladimir Romashchenko Date: Fri, 4 Apr 2025 01:25:24 -0500 Subject: [PATCH 3/4] Untested golang codegen for pgx v5 --- internal/codegen/golang/composite_type.go | 8 ++ internal/codegen/golang/gen.go | 64 +++++++++------- internal/codegen/golang/imports.go | 19 ++++- internal/codegen/golang/opts/enum.go | 4 + internal/codegen/golang/postgresql_type.go | 23 ++++-- internal/codegen/golang/result.go | 76 +++++++++++++++++++ .../codegen/golang/templates/pgx/dbCode.tmpl | 24 ++++++ .../codegen/golang/templates/template.tmpl | 11 +++ 8 files changed, 193 insertions(+), 36 deletions(-) create mode 100644 internal/codegen/golang/composite_type.go diff --git a/internal/codegen/golang/composite_type.go b/internal/codegen/golang/composite_type.go new file mode 100644 index 0000000000..64e102e398 --- /dev/null +++ b/internal/codegen/golang/composite_type.go @@ -0,0 +1,8 @@ +package golang + +type CompositeType struct { + SQLName string + Name string + Comment string + Fields []Field +} diff --git a/internal/codegen/golang/gen.go b/internal/codegen/golang/gen.go index 5b7977f500..85603f389b 100644 --- a/internal/codegen/golang/gen.go +++ b/internal/codegen/golang/gen.go @@ -17,13 +17,14 @@ import ( ) type tmplCtx struct { - Q string - Package string - SQLDriver opts.SQLDriver - Enums []Enum - Structs []Struct - GoQueries []Query - SqlcVersion string + Q string + Package string + SQLDriver opts.SQLDriver + Enums []Enum + Structs []Struct + CompositeTypes []CompositeType + GoQueries []Query + SqlcVersion string // TODO: Race conditions SourceName string @@ -109,12 +110,17 @@ func Generate(ctx context.Context, req *plugin.GenerateRequest) (*plugin.Generat if err != nil { return nil, err } + driver := parseDriver(options.SqlPackage) if err := opts.ValidateOpts(options); err != nil { return nil, err } enums := buildEnums(req, options) + compositeTypes := []CompositeType{} + if driver.IsPGXV5() { + compositeTypes = buildCompositeTypes(req, options) + } structs := buildStructs(req, options) queries, err := buildQueries(req, options, structs) if err != nil { @@ -125,46 +131,49 @@ func Generate(ctx context.Context, req *plugin.GenerateRequest) (*plugin.Generat enums, structs = filterUnusedStructs(enums, structs, queries) } - if err := validate(options, enums, structs, queries); err != nil { + if err := validate(options, enums, compositeTypes, structs, queries); err != nil { return nil, err } - return generate(req, options, enums, structs, queries) + return generate(req, options, enums, compositeTypes, structs, queries) } -func validate(options *opts.Options, enums []Enum, structs []Struct, queries []Query) error { - enumNames := make(map[string]struct{}) +func validate(options *opts.Options, enums []Enum, compositeTypes []CompositeType, structs []Struct, queries []Query) error { + usedNames := make(map[string]string) for _, enum := range enums { - enumNames[enum.Name] = struct{}{} - enumNames["Null"+enum.Name] = struct{}{} + usedNames[enum.Name] = "enum" + usedNames["Null"+enum.Name] = "enum" } - structNames := make(map[string]struct{}) for _, struckt := range structs { - if _, ok := enumNames[struckt.Name]; ok { - return fmt.Errorf("struct name conflicts with enum name: %s", struckt.Name) + if usedType, ok := usedNames[struckt.Name]; ok { + return fmt.Errorf("struct name conflicts with %s name: %s", usedType, struckt.Name) + } + usedNames[struckt.Name] = "struct" + } + for _, ct := range compositeTypes { + if usedType, ok := usedNames[ct.Name]; ok { + return fmt.Errorf("composite type name conflicts with %s name: %s", usedType, ct.Name) } - structNames[struckt.Name] = struct{}{} + usedNames[ct.Name] = "composite type" } if !options.EmitExportedQueries { return nil } for _, query := range queries { - if _, ok := enumNames[query.ConstantName]; ok { - return fmt.Errorf("query constant name conflicts with enum name: %s", query.ConstantName) - } - if _, ok := structNames[query.ConstantName]; ok { - return fmt.Errorf("query constant name conflicts with struct name: %s", query.ConstantName) + if usedType, ok := usedNames[query.ConstantName]; ok { + return fmt.Errorf("query constant name conflicts with %s name: %s", usedType, query.ConstantName) } } return nil } -func generate(req *plugin.GenerateRequest, options *opts.Options, enums []Enum, structs []Struct, queries []Query) (*plugin.GenerateResponse, error) { +func generate(req *plugin.GenerateRequest, options *opts.Options, enums []Enum, compositeTypes []CompositeType, structs []Struct, queries []Query) (*plugin.GenerateResponse, error) { i := &importer{ - Options: options, - Queries: queries, - Enums: enums, - Structs: structs, + Options: options, + Queries: queries, + Enums: enums, + CompositeTypes: compositeTypes, + Structs: structs, } tctx := tmplCtx{ @@ -183,6 +192,7 @@ func generate(req *plugin.GenerateRequest, options *opts.Options, enums []Enum, Q: "`", Package: options.Package, Enums: enums, + CompositeTypes: compositeTypes, Structs: structs, SqlcVersion: req.SqlcVersion, BuildTags: options.BuildTags, diff --git a/internal/codegen/golang/imports.go b/internal/codegen/golang/imports.go index 9e7819e4b1..84890cfd53 100644 --- a/internal/codegen/golang/imports.go +++ b/internal/codegen/golang/imports.go @@ -58,10 +58,11 @@ func mergeImports(imps ...fileImports) [][]ImportSpec { } type importer struct { - Options *opts.Options - Queries []Query - Enums []Enum - Structs []Struct + Options *opts.Options + Queries []Query + Enums []Enum + CompositeTypes []CompositeType + Structs []Struct } func (i *importer) usesType(typ string) bool { @@ -72,6 +73,13 @@ func (i *importer) usesType(typ string) bool { } } } + for _, ct := range i.CompositeTypes { + for _, f := range ct.Fields { + if hasPrefixIgnoringSliceAndPointerPrefix(f.Type, typ) { + return true + } + } + } return false } @@ -132,6 +140,9 @@ func (i *importer) dbImports() fileImports { case opts.SQLDriverPGXV5: pkg = append(pkg, ImportSpec{Path: "github.com/jackc/pgx/v5/pgconn"}) pkg = append(pkg, ImportSpec{Path: "github.com/jackc/pgx/v5"}) + if len(i.CompositeTypes) > 0 { + pkg = append(pkg, ImportSpec{Path: "github.com/jackc/pgx/v5/pgtype"}) + } default: std = append(std, ImportSpec{Path: "database/sql"}) if i.Options.EmitPreparedQueries { diff --git a/internal/codegen/golang/opts/enum.go b/internal/codegen/golang/opts/enum.go index 40457d040a..ed628928f1 100644 --- a/internal/codegen/golang/opts/enum.go +++ b/internal/codegen/golang/opts/enum.go @@ -48,6 +48,10 @@ func (d SQLDriver) IsPGX() bool { return d == SQLDriverPGXV4 || d == SQLDriverPGXV5 } +func (d SQLDriver) IsPGXV5() bool { + return d == SQLDriverPGXV5 +} + func (d SQLDriver) IsGoSQLDriverMySQL() bool { return d == SQLDriverGoSQLDriverMySQL } diff --git a/internal/codegen/golang/postgresql_type.go b/internal/codegen/golang/postgresql_type.go index 398d01e2e8..372b4541ea 100644 --- a/internal/codegen/golang/postgresql_type.go +++ b/internal/codegen/golang/postgresql_type.go @@ -587,13 +587,26 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi for _, ct := range schema.CompositeTypes { if rel.Name == ct.Name && rel.Schema == schema.Name { - if notNull { - return "string" + if !driver.IsPGXV5() { + if notNull { + return "string" + } + if emitPointersForNull { + return "*string" + } + return "sql.NullString" } - if emitPointersForNull { - return "*string" + + var ctName string + if schema.Name == req.Catalog.DefaultSchema { + ctName = StructName(ct.Name, options) + } else { + ctName = StructName(schema.Name+"_"+ct.Name, options) + } + if notNull { + return ctName } - return "sql.NullString" + return "*" + ctName } } } diff --git a/internal/codegen/golang/result.go b/internal/codegen/golang/result.go index 515d0a654f..99e561bcdf 100644 --- a/internal/codegen/golang/result.go +++ b/internal/codegen/golang/result.go @@ -60,6 +60,82 @@ func buildEnums(req *plugin.GenerateRequest, options *opts.Options) []Enum { return enums } +func topoSort(graph map[string]map[string]bool, visited map[string]bool, node string, sorted *[]string) { + visited[node] = true + for child := range graph[node] { + if visited[child] { + continue + } + topoSort(graph, visited, child, sorted) + } + *sorted = append(*sorted, node) +} + +// Orders types in order such that pgtype.Map can successfully register them +func sortedCompositeTypes(compositeTypes map[string]CompositeType) []CompositeType { + // Map of composite type names to a set of every child composite type name + graph := make(map[string]map[string]bool) + for typeName, ct := range compositeTypes { + graph[typeName] = make(map[string]bool) + for _, field := range ct.Fields { + fieldType := trimSliceAndPointerPrefix(field.Type) + if _, ok := compositeTypes[fieldType]; ok { + graph[typeName][fieldType] = true + } + } + } + + visited := make(map[string]bool) + sorted := []string{} + for typeName := range compositeTypes { + if visited[typeName] { + continue + } + topoSort(graph, visited, typeName, &sorted) + } + + compositeTypeArr := []CompositeType{} + for _, typeName := range sorted { + compositeTypeArr = append(compositeTypeArr, compositeTypes[typeName]) + } + return compositeTypeArr +} + +func buildCompositeTypes(req *plugin.GenerateRequest, options *opts.Options) []CompositeType { + compositeTypes := make(map[string]CompositeType) + for _, schema := range req.Catalog.Schemas { + if schema.Name == "pg_catalog" || schema.Name == "information_schema" { + continue + } + for _, ct := range schema.CompositeTypes { + var typeName string + var sqlName string + if schema.Name == req.Catalog.DefaultSchema { + typeName = ct.Name + sqlName = ct.Name + } else { + typeName = schema.Name + "_" + ct.Name + sqlName = schema.Name + "." + ct.Name + } + typeName = StructName(typeName, options) + compositeType := CompositeType{ + SQLName: sqlName, + Name: typeName, + Comment: ct.Comment, + } + for _, column := range ct.Columns { + compositeType.Fields = append(compositeType.Fields, Field{ + Name: StructName(column.Name, options), + Type: goType(req, options, column), + Comment: column.Comment, + }) + } + compositeTypes[typeName] = compositeType + } + } + return sortedCompositeTypes(compositeTypes) +} + func buildStructs(req *plugin.GenerateRequest, options *opts.Options) []Struct { var structs []Struct for _, schema := range req.Catalog.Schemas { diff --git a/internal/codegen/golang/templates/pgx/dbCode.tmpl b/internal/codegen/golang/templates/pgx/dbCode.tmpl index 236554d9f2..c074697ae7 100644 --- a/internal/codegen/golang/templates/pgx/dbCode.tmpl +++ b/internal/codegen/golang/templates/pgx/dbCode.tmpl @@ -10,6 +10,10 @@ type DBTX interface { {{- if .UsesBatch }} SendBatch(context.Context, *pgx.Batch) pgx.BatchResults {{- end }} +{{- if gt (len .CompositeTypes) 0 }} + LoadTypes(ctx context.Context, typeNames []string) ([]*pgtype.Type, error) + TypeMap() *pgtype.Map +{{- end }} } {{ if .EmitMethodsWithDBArgument}} @@ -27,6 +31,26 @@ type Queries struct { {{end}} } +{{if gt (len .CompositeTypes) 0}} +{{if not .EmitMethodsWithDBArgument}} +func (q *Queries) RegisterTypes(ctx context.Context) error { + db := q.db +{{else}} +func (q *Queries) RegisterTypes(ctx context.Context, db *Queries) error { +{{end}} + typeNames := []string{ + {{- range .CompositeTypes}} + "{{.SQLName}}", + {{- end}} + } + dataTypes, err := db.LoadTypes(ctx, typeNames) + if err != nil { + return err + } + db.TypeMap().RegisterTypes(dataTypes) + return nil +} +{{end}} {{if not .EmitMethodsWithDBArgument}} func (q *Queries) WithTx(tx pgx.Tx) *Queries { return &Queries{ diff --git a/internal/codegen/golang/templates/template.tmpl b/internal/codegen/golang/templates/template.tmpl index afd50c01ac..7d73ecb225 100644 --- a/internal/codegen/golang/templates/template.tmpl +++ b/internal/codegen/golang/templates/template.tmpl @@ -150,6 +150,17 @@ func All{{ .Name }}Values() []{{ .Name }} { {{ end }} {{end}} +{{range .CompositeTypes}} +{{if .Comment}}{{comment .Comment}}{{end}} +type {{.Name}} struct { {{- range .Fields}} + {{- if .Comment}} + {{comment .Comment}}{{else}} + {{- end}} + {{.Name}} {{.Type}} {{if .Tag}}{{$.Q}}{{.Tag}}{{$.Q}}{{end}} + {{- end}} +} +{{end}} + {{range .Structs}} {{if .Comment}}{{comment .Comment}}{{end}} type {{.Name}} struct { {{- range .Fields}} From 91ee0b000bdcdb706f0b609027e50b1208388d10 Mon Sep 17 00:00:00 2001 From: Vladimir Romashchenko Date: Tue, 8 Apr 2025 11:39:25 -0500 Subject: [PATCH 4/4] Fix pgx.Tx use and array support --- internal/codegen/golang/imports.go | 3 +++ internal/codegen/golang/templates/pgx/dbCode.tmpl | 14 +++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/internal/codegen/golang/imports.go b/internal/codegen/golang/imports.go index 84890cfd53..b9859f239b 100644 --- a/internal/codegen/golang/imports.go +++ b/internal/codegen/golang/imports.go @@ -142,6 +142,9 @@ func (i *importer) dbImports() fileImports { pkg = append(pkg, ImportSpec{Path: "github.com/jackc/pgx/v5"}) if len(i.CompositeTypes) > 0 { pkg = append(pkg, ImportSpec{Path: "github.com/jackc/pgx/v5/pgtype"}) + if !i.Options.EmitMethodsWithDbArgument { + pkg = append(pkg, ImportSpec{Path: "fmt"}) + } } default: std = append(std, ImportSpec{Path: "database/sql"}) diff --git a/internal/codegen/golang/templates/pgx/dbCode.tmpl b/internal/codegen/golang/templates/pgx/dbCode.tmpl index c074697ae7..c83b37c302 100644 --- a/internal/codegen/golang/templates/pgx/dbCode.tmpl +++ b/internal/codegen/golang/templates/pgx/dbCode.tmpl @@ -10,6 +10,10 @@ type DBTX interface { {{- if .UsesBatch }} SendBatch(context.Context, *pgx.Batch) pgx.BatchResults {{- end }} +} + +type DB interface { + DBTX {{- if gt (len .CompositeTypes) 0 }} LoadTypes(ctx context.Context, typeNames []string) ([]*pgtype.Type, error) TypeMap() *pgtype.Map @@ -20,7 +24,7 @@ type DBTX interface { func New() *Queries { return &Queries{} {{- else -}} -func New(db DBTX) *Queries { +func New(db DB) *Queries { return &Queries{db: db} {{- end}} } @@ -34,13 +38,17 @@ type Queries struct { {{if gt (len .CompositeTypes) 0}} {{if not .EmitMethodsWithDBArgument}} func (q *Queries) RegisterTypes(ctx context.Context) error { - db := q.db + db, ok := q.db.(DB) + if !ok { + return fmt.Errorf("cannot register types with a transaction object") + } {{else}} -func (q *Queries) RegisterTypes(ctx context.Context, db *Queries) error { +func (q *Queries) RegisterTypes(ctx context.Context, db DB) error { {{end}} typeNames := []string{ {{- range .CompositeTypes}} "{{.SQLName}}", + "_{{.SQLName}}", {{- end}} } dataTypes, err := db.LoadTypes(ctx, typeNames)