Skip to content

Commit

Permalink
sql: disallow star expressions in UDF bodies
Browse files Browse the repository at this point in the history
This commit disallows star expressions in UDF bodies (see the release
note below). It also fixes an error message returned when trying to
create a view that references non-existent columns that incorrectly
mentioned star expressions.

Fixes cockroachdb#86070

Release note (sql change): Star expressions, e.g., `SELECT * FROM ...`
are no longer allowed in statements in user-defined functions. They were
allowed in early betas of v22.2 from v22.2.0-beta.1 to v22.2.0-beta.4,
but have been disallowed because they do not behave correctly.
Issue cockroachdb#90080 tracks re-enabling star expressions in UDFs.
  • Loading branch information
mgartner committed Oct 18, 2022
1 parent 1c02afc commit d0a5b85
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 17 deletions.
41 changes: 30 additions & 11 deletions pkg/sql/logictest/testdata/logic_test/udf
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,26 @@ CREATE FUNCTION c(i INT, j INT) RETURNS INT LANGUAGE SQL AS 'SELECT i - j'
statement error column \"j\" does not exist
CREATE FUNCTION err(i INT) RETURNS INT LANGUAGE SQL AS 'SELECT j'

statement error column \"j\" does not exist
CREATE FUNCTION err(i INT) RETURNS INT LANGUAGE SQL AS 'SELECT * FROM ab WHERE a = j'
statement error pgcode 42703 column \"j\" does not exist
CREATE FUNCTION err(i INT) RETURNS INT LANGUAGE SQL AS 'SELECT a FROM ab WHERE a = j'

statement error pgcode 0A000 functions do not currently support \* expressions
CREATE FUNCTION err(i INT) RETURNS ab LANGUAGE SQL AS 'SELECT * FROM ab'

statement error pgcode 0A000 functions do not currently support \* expressions
CREATE FUNCTION err(i INT) RETURNS ab LANGUAGE SQL AS 'SELECT ab.* FROM ab'

statement error pgcode 0A000 functions do not currently support \* expressions
CREATE FUNCTION err(i INT) RETURNS ab LANGUAGE SQL AS $$
SELECT 1;
SELECT * FROM ab;
$$

statement error pgcode 0A000 functions do not currently support \* expressions
CREATE FUNCTION err(i INT) RETURNS INT LANGUAGE SQL AS $$
SELECT * FROM ab;
SELECT 1;
$$

statement ok
CREATE FUNCTION d(i INT2) RETURNS INT4 LANGUAGE SQL AS 'SELECT i'
Expand Down Expand Up @@ -2403,15 +2421,16 @@ SELECT imp(), (1,2,'a')::imp = imp(), pg_typeof(imp())
----
(1,2,a) true imp

statement ok
CREATE FUNCTION imp_star() RETURNS imp LANGUAGE SQL AS $$
SELECT * FROM imp
$$

query TBT
SELECT imp_star(), (1,2,'a')::imp = imp_star(), pg_typeof(imp_star())
----
(1,2,a) true imp
# TODO(#90080): Allow star expressions in UDFs.
# statement ok
# CREATE FUNCTION imp_star() RETURNS imp LANGUAGE SQL AS $$
# SELECT * FROM imp
# $$
#
# query TBT
# SELECT imp_star(), (1,2,'a')::imp = imp_star(), pg_typeof(imp_star())
# ----
# (1,2,a) true imp

statement ok
INSERT INTO imp VALUES (100, 200, 'z')
Expand Down
7 changes: 6 additions & 1 deletion pkg/sql/logictest/testdata/logic_test/views
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ CREATE VIEW v6 (x, y) AS SELECT a, b FROM v1
statement ok
CREATE VIEW v7 (x, y) AS SELECT a, b FROM v1 ORDER BY a DESC LIMIT 2

statement error pgcode 42703 column \"j\" does not exist
CREATE VIEW err AS SELECT j FROM t

statement error pgcode 42703 column \"j\" does not exist
CREATE VIEW err AS SELECT a FROM t WHERE a = j

query II colnames,rowsort
SELECT * FROM v1
----
Expand Down Expand Up @@ -1492,4 +1498,3 @@ SELECT * FROM v;

statement ok
SET DATABASE = test;

7 changes: 4 additions & 3 deletions pkg/sql/opt/optbuilder/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,10 @@ func (b *Builder) resolveColRef(e tree.Expr, inScope *scope) tree.TypedExpr {
if resolveErr != nil {
// It may be a reference to a table, e.g. SELECT tbl FROM tbl.
// Attempt to resolve as a TupleStar. We do not attempt to resolve
// as a TupleStar if we are inside a view definition because views
// do not support * expressions.
if !b.insideViewDef && sqlerrors.IsUndefinedColumnError(resolveErr) {
// as a TupleStar if we are inside a view or function definition
// because views and functions do not support * expressions.
if !b.insideViewDef && !b.insideFuncDef &&
sqlerrors.IsUndefinedColumnError(resolveErr) {
return func() tree.TypedExpr {
defer wrapColTupleStarPanic(resolveErr)
return inScope.resolveType(columnNameAsTupleStar(colName), types.Any)
Expand Down
7 changes: 6 additions & 1 deletion pkg/sql/opt/optbuilder/scope.go
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,12 @@ func (s *scope) VisitPre(expr tree.Expr) (recurse bool, newExpr tree.Expr) {
case *tree.ColumnItem:
colI, resolveErr := colinfo.ResolveColumnItem(s.builder.ctx, s, t)
if resolveErr != nil {
if sqlerrors.IsUndefinedColumnError(resolveErr) {
// It may be a reference to a table, e.g. SELECT tbl FROM tbl.
// Attempt to resolve as a TupleStar. We do not attempt to resolve
// as a TupleStar if we are inside a view or function definition
// because views and functions do not support * expressions.
if !s.builder.insideViewDef && !s.builder.insideFuncDef &&
sqlerrors.IsUndefinedColumnError(resolveErr) {
// Attempt to resolve as columnname.*, which allows items
// such as SELECT row_to_json(tbl_name) FROM tbl_name to work.
return func() (bool, tree.Expr) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/sql/opt/optbuilder/testdata/create_function
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ create-function
build
CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT * FROM ab $$
----
error (42P13): return type mismatch in function declared to return int
error (0A000): unimplemented: functions do not currently support * expressions

build
CREATE FUNCTION f() RETURNS INT LANGUAGE SQL BEGIN ATOMIC SELECT 1; END;
Expand Down
3 changes: 3 additions & 0 deletions pkg/sql/opt/optbuilder/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ func (b *Builder) expandStar(
if b.insideViewDef {
panic(unimplemented.NewWithIssue(10028, "views do not currently support * expressions"))
}
if b.insideFuncDef {
panic(unimplemented.NewWithIssue(90080, "functions do not currently support * expressions"))
}
switch t := expr.(type) {
case *tree.TupleStar:
texpr := inScope.resolveType(t.Expr, types.Any)
Expand Down

0 comments on commit d0a5b85

Please sign in to comment.