diff --git a/pkg/sql/opt/optbuilder/scope.go b/pkg/sql/opt/optbuilder/scope.go index 2904a8a97875..fb35c29ba52d 100644 --- a/pkg/sql/opt/optbuilder/scope.go +++ b/pkg/sql/opt/optbuilder/scope.go @@ -1079,10 +1079,14 @@ func (s *scope) VisitPre(expr tree.Expr) (recurse bool, newExpr tree.Expr) { } // 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) { - defer wrapColTupleStarPanic(resolveErr) - return s.VisitPre(columnNameAsTupleStar(string(t.ColumnName))) - }() + // Qualified column references such as t1.t1 must not fall back to + // whole-row tuple expansion; retain the resolver error instead. + if t.TableName == nil || t.TableName.Object() == "" { + return func() (bool, tree.Expr) { + defer wrapColTupleStarPanic(resolveErr) + return s.VisitPre(columnNameAsTupleStar(string(t.ColumnName))) + }() + } } if sqlerrors.IsUndefinedRelationError(resolveErr) && t.TableName.Object() != "" { // If we are inside a PL/pgSQL routine and the prefix names a diff --git a/pkg/sql/opt/optbuilder/testdata/qualified-whole-row b/pkg/sql/opt/optbuilder/testdata/qualified-whole-row new file mode 100644 index 000000000000..c95d90594fe1 --- /dev/null +++ b/pkg/sql/opt/optbuilder/testdata/qualified-whole-row @@ -0,0 +1,42 @@ +exec-ddl +CREATE TABLE t1(f1 INT) +---- + +exec-ddl +CREATE TABLE t2(f1 INT) +---- + +build +SELECT t1.t1 FROM t1 +---- +error (42703): column "t1.t1" does not exist + +build +SELECT a.a FROM t1 AS a +---- +error (42703): column "a.a" does not exist + +build +SELECT * FROM t1 WHERE t1.t2 = 1 +---- +error (42703): column "t1.t2" does not exist + +build +SELECT t1.t2 FROM t1, t2 +---- +error (42703): column "t1.t2" does not exist + +build +WITH c AS (SELECT 1 AS x) SELECT c.y FROM c +---- +error (42703): column "c.y" does not exist + +build +SELECT d.y FROM (SELECT 1 AS x) AS d +---- +error (42703): column "d.y" does not exist + +build +SELECT (SELECT o.t2 FROM t1) FROM t1 AS o +---- +error (42703): column "o.t2" does not exist