Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 29 additions & 22 deletions examples/authors/ydb/query.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

101 changes: 101 additions & 0 deletions internal/codegen/golang/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"strings"

"github.com/sqlc-dev/sqlc/internal/codegen/golang/opts"
"github.com/sqlc-dev/sqlc/internal/codegen/sdk"
"github.com/sqlc-dev/sqlc/internal/metadata"
"github.com/sqlc-dev/sqlc/internal/plugin"
)
Expand Down Expand Up @@ -294,6 +295,106 @@ func (v QueryValue) YDBParamMapEntries() string {
return "\n" + strings.Join(parts, ",\n")
}

// ydbBuilderMethodForColumnType maps a YDB column data type to a ParamsBuilder method name.
func ydbBuilderMethodForColumnType(dbType string) string {
switch strings.ToLower(dbType) {
case "bool":
return "Bool"
case "uint64":
return "Uint64"
case "int64":
return "Int64"
case "uint32":
return "Uint32"
case "int32":
return "Int32"
case "uint16":
return "Uint16"
case "int16":
return "Int16"
case "uint8":
return "Uint8"
case "int8":
return "Int8"
case "float":
return "Float"
case "double":
return "Double"
case "json":
return "JSON"
case "jsondocument":
return "JSONDocument"
case "utf8", "text", "string":
return "Text"
case "date":
return "Date"
case "date32":
return "Date32"
case "datetime":
return "Datetime"
case "timestamp":
return "Timestamp"
case "tzdate":
return "TzDate"
case "tzdatetime":
return "TzDatetime"
case "tztimestamp":
return "TzTimestamp"

//TODO: support other types
Copy link

Copilot AI Sep 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TODO comment should specify which types need to be supported or reference an issue. An empty return value could lead to the panic in YDBParamsBuilder without clear indication of what's missing.

Suggested change
//TODO: support other types
// TODO: support additional YDB types such as Decimal, UUID, DyNumber, Optional, List, Tuple, Struct, Dict, Variant, Void, Null, and others as needed.
// See https://github.com/ydb-platform/ydb-go-sdk/blob/main/table/types/types.go for the full list of YDB types.
// Alternatively, track progress at https://github.com/sqlc-dev/sqlc/issues/XXXX

Copilot uses AI. Check for mistakes.
default:
return ""
}
}

// YDBParamsBuilder emits Go code that constructs YDB params using ParamsBuilder.
func (v QueryValue) YDBParamsBuilder() string {
if v.isEmpty() {
return ""
}

var lines []string

for _, field := range v.getParameterFields() {
if field.Column != nil && field.Column.IsNamedParam {
name := field.Column.GetName()
if name == "" {
continue
}
paramName := fmt.Sprintf("%q", addDollarPrefix(name))
variable := escape(v.VariableForField(field))

var method string
if field.Column != nil && field.Column.Type != nil {
method = ydbBuilderMethodForColumnType(sdk.DataType(field.Column.Type))
}

goType := field.Type
isPtr := strings.HasPrefix(goType, "*")
if isPtr {
goType = strings.TrimPrefix(goType, "*")
}

if method == "" {
panic(fmt.Sprintf("unknown YDB column type for param %s (goType=%s)", name, goType))
Copy link

Copilot AI Sep 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The panic message should include the actual column type that wasn't recognized. Consider including sdk.DataType(field.Column.Type) in the error message to help with debugging.

Suggested change
panic(fmt.Sprintf("unknown YDB column type for param %s (goType=%s)", name, goType))
panic(fmt.Sprintf("unknown YDB column type for param %s (goType=%s, columnType=%s)", name, goType, sdk.DataType(field.Column.Type)))

Copilot uses AI. Check for mistakes.
}

if isPtr {
lines = append(lines, fmt.Sprintf("\t\t\tParam(%s).BeginOptional().%s(%s).EndOptional().", paramName, method, variable))
} else {
lines = append(lines, fmt.Sprintf("\t\t\tParam(%s).%s(%s).", paramName, method, variable))
}
}
}

if len(lines) == 0 {
return ""
}

params := strings.Join(lines, "\n")
return fmt.Sprintf("\nquery.WithParameters(\n\t\tydb.ParamsBuilder().\n%s\n\t\t\tBuild(),\n\t\t),\n", params)
}

func (v QueryValue) getParameterFields() []Field {
if v.Struct == nil {
return []Field{
Expand Down
43 changes: 17 additions & 26 deletions internal/codegen/golang/templates/ydb-go-sdk/queryCode.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ func (q *Queries) {{.MethodName}}(ctx context.Context, {{if $.EmitMethodsWithDBA
{{- if .Arg.IsEmpty }}
row, err := {{$dbArg}}.QueryRow(ctx, {{.ConstantName}}, opts...)
{{- else }}
row, err := {{$dbArg}}.QueryRow(ctx, {{.ConstantName}},
append(opts, query.WithParameters(ydb.ParamsFromMap(map[string]any{ {{.Arg.YDBParamMapEntries}} })))...,
row, err := {{$dbArg}}.QueryRow(ctx, {{.ConstantName}},
append(opts, {{.Arg.YDBParamsBuilder}})...,
)
{{- end }}
{{- if or (ne .Arg.Pair .Ret.Pair) (ne .Arg.DefineType .Ret.DefineType) }}
Expand Down Expand Up @@ -61,10 +61,10 @@ func (q *Queries) {{.MethodName}}(ctx context.Context, {{if $.EmitMethodsWithDBA
func (q *Queries) {{.MethodName}}(ctx context.Context, {{if $.EmitMethodsWithDBArgument}}db DBTX, {{end}}{{if not .Arg.IsEmpty}}{{.Arg.Pair}}, {{end}}opts ...query.ExecuteOption) ([]{{.Ret.DefineType}}, error) {
{{- $dbArg := "q.db" }}{{- if $.EmitMethodsWithDBArgument }}{{- $dbArg = "db" }}{{- end -}}
{{- if .Arg.IsEmpty }}
result, err := {{$dbArg}}.Query(ctx, {{.ConstantName}}, opts...)
result, err := {{$dbArg}}.QueryResultSet(ctx, {{.ConstantName}}, opts...)
{{- else }}
result, err := {{$dbArg}}.Query(ctx, {{.ConstantName}},
append(opts, query.WithParameters(ydb.ParamsFromMap(map[string]any{ {{.Arg.YDBParamMapEntries}} })))...,
result, err := {{$dbArg}}.QueryResultSet(ctx, {{.ConstantName}},
append(opts, {{.Arg.YDBParamsBuilder}})...,
)
{{- end }}
if err != nil {
Expand All @@ -79,32 +79,23 @@ func (q *Queries) {{.MethodName}}(ctx context.Context, {{if $.EmitMethodsWithDBA
{{else}}
var items []{{.Ret.DefineType}}
{{end -}}
for set, err := range result.ResultSets(ctx) {
for row, err := range result.Rows(ctx) {
if err != nil {
{{- if $.WrapErrors}}
return nil, xerrors.WithStackTrace(fmt.Errorf("query {{.MethodName}}: %w", err))
{{- else }}
return nil, xerrors.WithStackTrace(err)
{{- end }}
}
for row, err := range set.Rows(ctx) {
if err != nil {
{{- if $.WrapErrors}}
return nil, xerrors.WithStackTrace(fmt.Errorf("query {{.MethodName}}: %w", err))
{{- else }}
return nil, xerrors.WithStackTrace(err)
{{- end }}
}
var {{.Ret.Name}} {{.Ret.Type}}
if err := row.Scan({{.Ret.Scan}}); err != nil {
{{- if $.WrapErrors}}
return nil, xerrors.WithStackTrace(fmt.Errorf("query {{.MethodName}}: %w", err))
{{- else }}
return nil, xerrors.WithStackTrace(err)
{{- end }}
}
items = append(items, {{.Ret.ReturnName}})
}
var {{.Ret.Name}} {{.Ret.Type}}
if err := row.Scan({{.Ret.Scan}}); err != nil {
{{- if $.WrapErrors}}
return nil, xerrors.WithStackTrace(fmt.Errorf("query {{.MethodName}}: %w", err))
{{- else }}
return nil, xerrors.WithStackTrace(err)
{{- end }}
}
items = append(items, {{.Ret.ReturnName}})
}
if err := result.Close(ctx); err != nil {
{{- if $.WrapErrors}}
Expand All @@ -125,8 +116,8 @@ func (q *Queries) {{.MethodName}}(ctx context.Context, {{if $.EmitMethodsWithDBA
{{- if .Arg.IsEmpty }}
err := {{$dbArg}}.Exec(ctx, {{.ConstantName}}, opts...)
{{- else }}
err := {{$dbArg}}.Exec(ctx, {{.ConstantName}},
append(opts, query.WithParameters(ydb.ParamsFromMap(map[string]any{ {{.Arg.YDBParamMapEntries}} })))...,
err := {{$dbArg}}.Exec(ctx, {{.ConstantName}},
append(opts, {{.Arg.YDBParamsBuilder}})...,
)
{{- end }}
if err != nil {
Expand Down
18 changes: 18 additions & 0 deletions internal/codegen/golang/ydb_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,24 @@ func YDBType(req *plugin.GenerateRequest, options *opts.Options, col *plugin.Col
// return "sql.NullInt64"
return "*int64"

case "json", "jsondocument":
if notNull {
return "string"
}
if emitPointersForNull {
return "*string"
}
return "*string"

Copy link

Copilot AI Sep 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's trailing whitespace on line 162 that should be removed.

Suggested change

Copilot uses AI. Check for mistakes.
case "date", "date32", "datetime", "timestamp", "tzdate", "tztimestamp", "tzdatetime":
if notNull {
return "time.Time"
}
if emitPointersForNull {
return "*time.Time"
}
return "*time.Time"

case "null":
// return "sql.Null"
return "interface{}"
Expand Down
2 changes: 1 addition & 1 deletion internal/engine/ydb/catalog_tests/create_table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func TestCreateTable(t *testing.T) {
{
Name: "amount",
Type: ast.TypeName{
Name: "Decimal",
Name: "decimal",
Names: &ast.List{
Items: []ast.Node{
&ast.Integer{Ival: 22},
Expand Down
2 changes: 1 addition & 1 deletion internal/engine/ydb/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -1278,7 +1278,7 @@ func (c *cc) convertTypeName(n parser.IType_nameContext) *ast.TypeName {
if decimal := n.Type_name_decimal(); decimal != nil {
if integerOrBinds := decimal.AllInteger_or_bind(); len(integerOrBinds) >= 2 {
return &ast.TypeName{
Name: "Decimal",
Name: "decimal",
TypeOid: 0,
Names: &ast.List{
Items: []ast.Node{
Expand Down
Loading