From be2540710337b23b722813269af77294188aeee5 Mon Sep 17 00:00:00 2001 From: Max Hawkins Date: Sat, 30 May 2020 12:34:07 -0700 Subject: [PATCH] compiler: temp fix for typecast function parameters In cases where a FuncCall has a TypeCast node as an argument, resolveCatalogRefs would erroneously output two parameters for that argument instead of one. This fix eliminates the duplicate param and allows queries with typecast function args to compile, but it loses track of the argument's connection with the function called. This means the parameters use the generic ColumnN names even when the function has named parameters. A future refactor of resolveCatalogRefs to better address function calls will be necessary to address the name issue. (this only edits the experimental package and does not fix the old dinosql compiler) Closes #520 --- internal/compiler/resolve.go | 8 +++++ .../testdata/func_args_typecast/endtoend.json | 3 ++ .../testdata/func_args_typecast/go/db.go | 29 +++++++++++++++++++ .../testdata/func_args_typecast/go/models.go | 5 ++++ .../func_args_typecast/go/query.sql.go | 24 +++++++++++++++ .../testdata/func_args_typecast/query.sql | 8 +++++ .../testdata/func_args_typecast/sqlc.json | 11 +++++++ 7 files changed, 88 insertions(+) create mode 100644 internal/endtoend/testdata/func_args_typecast/endtoend.json create mode 100644 internal/endtoend/testdata/func_args_typecast/go/db.go create mode 100644 internal/endtoend/testdata/func_args_typecast/go/models.go create mode 100644 internal/endtoend/testdata/func_args_typecast/go/query.sql.go create mode 100644 internal/endtoend/testdata/func_args_typecast/query.sql create mode 100644 internal/endtoend/testdata/func_args_typecast/sqlc.json diff --git a/internal/compiler/resolve.go b/internal/compiler/resolve.go index 57e3fbb8df..803cfcb0e3 100644 --- a/internal/compiler/resolve.go +++ b/internal/compiler/resolve.go @@ -193,6 +193,14 @@ func resolveCatalogRefs(c *catalog.Catalog, rvs []*pg.RangeVar, args []paramRef, if inode.Number != ref.ref.Number { continue } + case *pg.TypeCast: + pr, ok := inode.Arg.(*pg.ParamRef) + if !ok { + continue + } + if pr.Number != ref.ref.Number { + continue + } case *pg.NamedArgExpr: pr, ok := inode.Arg.(*pg.ParamRef) if !ok { diff --git a/internal/endtoend/testdata/func_args_typecast/endtoend.json b/internal/endtoend/testdata/func_args_typecast/endtoend.json new file mode 100644 index 0000000000..e9665ca4a3 --- /dev/null +++ b/internal/endtoend/testdata/func_args_typecast/endtoend.json @@ -0,0 +1,3 @@ +{ + "experimental_parser_only": true +} diff --git a/internal/endtoend/testdata/func_args_typecast/go/db.go b/internal/endtoend/testdata/func_args_typecast/go/db.go new file mode 100644 index 0000000000..6a99519302 --- /dev/null +++ b/internal/endtoend/testdata/func_args_typecast/go/db.go @@ -0,0 +1,29 @@ +// Code generated by sqlc. DO NOT EDIT. + +package querytest + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/internal/endtoend/testdata/func_args_typecast/go/models.go b/internal/endtoend/testdata/func_args_typecast/go/models.go new file mode 100644 index 0000000000..4e2b892600 --- /dev/null +++ b/internal/endtoend/testdata/func_args_typecast/go/models.go @@ -0,0 +1,5 @@ +// Code generated by sqlc. DO NOT EDIT. + +package querytest + +import () diff --git a/internal/endtoend/testdata/func_args_typecast/go/query.sql.go b/internal/endtoend/testdata/func_args_typecast/go/query.sql.go new file mode 100644 index 0000000000..8abb20f8e5 --- /dev/null +++ b/internal/endtoend/testdata/func_args_typecast/go/query.sql.go @@ -0,0 +1,24 @@ +// Code generated by sqlc. DO NOT EDIT. +// source: query.sql + +package querytest + +import ( + "context" +) + +const plusPositionalCast = `-- name: PlusPositionalCast :one +SELECT plus($1, $2::INTEGER) +` + +type PlusPositionalCastParams struct { + A int32 + Column2 int32 +} + +func (q *Queries) PlusPositionalCast(ctx context.Context, arg PlusPositionalCastParams) (int32, error) { + row := q.db.QueryRowContext(ctx, plusPositionalCast, arg.A, arg.Column2) + var plus int32 + err := row.Scan(&plus) + return plus, err +} diff --git a/internal/endtoend/testdata/func_args_typecast/query.sql b/internal/endtoend/testdata/func_args_typecast/query.sql new file mode 100644 index 0000000000..399a5de922 --- /dev/null +++ b/internal/endtoend/testdata/func_args_typecast/query.sql @@ -0,0 +1,8 @@ +CREATE FUNCTION plus(a integer, b integer) RETURNS integer AS $$ + BEGIN + RETURN a + b; + END; +$$ LANGUAGE plpgsql; + +-- name: PlusPositionalCast :one +SELECT plus($1, $2::INTEGER); diff --git a/internal/endtoend/testdata/func_args_typecast/sqlc.json b/internal/endtoend/testdata/func_args_typecast/sqlc.json new file mode 100644 index 0000000000..ac7c2ed829 --- /dev/null +++ b/internal/endtoend/testdata/func_args_typecast/sqlc.json @@ -0,0 +1,11 @@ +{ + "version": "1", + "packages": [ + { + "path": "go", + "name": "querytest", + "schema": "query.sql", + "queries": "query.sql" + } + ] +}