Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sql: do not type-check subqueries outside of optbuilder #106868

Merged
merged 1 commit into from
Jul 17, 2023
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
14 changes: 14 additions & 0 deletions pkg/sql/create_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,20 @@ func serializeUserDefinedTypes(
default:
return true, expr, nil
}
// We cannot type-check subqueries without using optbuilder, and there
// is no need to because we only need to rewrite string values that are
// directly cast to enums. For example, we must rewrite the 'foo' in:
//
// SELECT 'foo'::myenum
//
// We don't need to rewrite the 'foo' in the query below, which can be
// corrupted by renaming the 'foo' value in the myenum type.
//
// SELECT (SELECT 'foo')::myenum
//
if _, ok := innerExpr.(*tree.Subquery); ok {
return true, expr, nil
}
// semaCtx may be nil if this is a virtual view being created at
// init time.
var typeResolver tree.TypeReferenceResolver
Expand Down
27 changes: 27 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/udf
Original file line number Diff line number Diff line change
Expand Up @@ -3619,3 +3619,30 @@ CREATE FUNCTION public.func104242_not_null()
$$

subtest end

# Regression test for #105259. Do not type-check subqueries in UDFs outside
# optbuilder. Doing so can cause internal errors.
subtest regression_105259

statement ok
CREATE TYPE e105259 AS ENUM ('foo');

statement ok
CREATE FUNCTION f() RETURNS VOID LANGUAGE SQL AS $$
SELECT (SELECT 'foo')::e105259;
SELECT NULL;
$$

query T
SELECT f()
----
NULL

statement ok
ALTER TYPE e105259 RENAME VALUE 'foo' TO 'bar'

# Renaming the enum value corrupts the UDF. This is expected behavior.
statement error pgcode 22P02 invalid input value for enum e105259: "foo"
SELECT f()
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: add a subtest end. (and also in the next file)


subtest end
31 changes: 31 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/views
Original file line number Diff line number Diff line change
Expand Up @@ -1829,6 +1829,8 @@ CREATE VIEW pg_comedies AS
statement error pq: cannot drop columns from view
CREATE OR REPLACE VIEW comedies AS SELECT ARRAY[films.*]::string FROM films;

subtest end

subtest circular_dependency

statement ok
Expand Down Expand Up @@ -1863,6 +1865,8 @@ DROP VIEW cd_v1;
statement ok
DROP VIEW cd_v1 CASCADE;

subtest end

# Regression test for #104927. Correctly resolve table references in views as
# TupleStars.
subtest regression_104927
Expand Down Expand Up @@ -1893,3 +1897,30 @@ query T
SELECT * FROM v104927
----
[{"i": 1, "s": "foo"}]

subtest end

# Regression test for #105259. Do not type-check subqueries in views outside
# optbuilder. Doing so can cause internal errors.
subtest regression_105259

statement ok
CREATE TYPE e105259 AS ENUM ('foo');

statement ok
CREATE VIEW v105259 AS
SELECT (SELECT 'foo')::e105259

query T
SELECT * FROM v105259
----
foo

statement ok
ALTER TYPE e105259 RENAME VALUE 'foo' TO 'bar'

# Renaming the enum value corrupts the view. This is expected behavior.
statement error pgcode 22P02 invalid input value for enum e105259: "foo"
SELECT * FROM v105259

subtest end
14 changes: 14 additions & 0 deletions pkg/sql/schemachanger/scbuild/builder_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -1570,6 +1570,20 @@ func (b *builderState) serializeUserDefinedTypes(queryStr string) string {
default:
return true, expr, nil
}
// We cannot type-check subqueries without using optbuilder, and there
// is no need to because we only need to rewrite string values that are
// directly cast to enums. For example, we must rewrite the 'foo' in:
//
// SELECT 'foo'::myenum
//
// We don't need to rewrite the 'foo' in the query below, which can be
// corrupted by renaming the 'foo' value in the myenum type.
//
// SELECT (SELECT 'foo')::myenum
//
if _, ok := innerExpr.(*tree.Subquery); ok {
return true, expr, nil
}
var typ *types.T
typ, err = tree.ResolveType(b.ctx, typRef, b.semaCtx.TypeResolver)
if err != nil {
Expand Down