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

udf: select * in a udf combined with edited table can cause crashes #86070

Closed
jordanlewis opened this issue Aug 12, 2022 · 7 comments · Fixed by #90085
Closed

udf: select * in a udf combined with edited table can cause crashes #86070

jordanlewis opened this issue Aug 12, 2022 · 7 comments · Fixed by #90085
Assignees
Labels
A-sql-routine UDFs and Stored Procedures branch-release-22.2 Used to mark GA and release blockers, technical advisories, and bugs for 22.2 C-bug Code not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior. release-blocker Indicates a release-blocker. Use with branch-release-2x.x label to denote which branch is blocked. T-sql-queries SQL Queries Team

Comments

@jordanlewis
Copy link
Member

jordanlewis commented Aug 12, 2022

It's possible to use SELECT * within a UDF, which seems to cause issues after editing the table that's being SELECT *'d from. In other contexts we just ban SELECT *.

[email protected]:26257/defaultdb> create table t (a int);
CREATE TABLE
[email protected]:26257/defaultdb> create function f() returns int language sql as 'select * from t';
CREATE FUNCTION
[email protected]:26257/defaultdb> alter table t add column b int; 
ALTER TABLE
[email protected]:26257/defaultdb> select f();
   f
--------
  NULL
(1 row)
[email protected]:26257/defaultdb> insert into t values(1);
INSERT 0 1
[email protected]:26257/defaultdb> select f();
*
* ERROR: a SQL panic has occurred while executing the following statement:
* SELECT f()
*
*
* ERROR: a panic has occurred!
* runtime error: index out of range [1] with length 1
* (1) attached stack trace
*   -- stack trace:
*   | github.com/cockroachdb/cockroach/pkg/sql.(*Server).ServeConn.func1
*   |   github.com/cockroachdb/cockroach/pkg/sql/conn_executor.go:806
*   | [...repeated from below...]
* Wraps: (2) while executing: SELECT f()
* Wraps: (3) attached stack trace
*   -- stack trace:
*   | github.com/cockroachdb/cockroach/pkg/sql.(*Server).ServeConn.func1
*   |   github.com/cockroachdb/cockroach/pkg/sql/conn_executor.go:806
*   | runtime.gopanic
*   |   GOROOT/src/runtime/panic.go:838
*   | github.com/cockroachdb/cockroach/pkg/sql/colexecerror.CatchVectorizedRuntimeError.func1
*   |   github.com/cockroachdb/cockroach/pkg/sql/colexecerror/error.go:58
*   | runtime.gopanic
*   |   GOROOT/src/runtime/panic.go:838
*   | runtime.goPanicIndex
*   |   GOROOT/src/runtime/panic.go:89
*   | github.com/cockroachdb/cockroach/pkg/sql.(*rowContainerHelper).AddRow
*   |   github.com/cockroachdb/cockroach/pkg/sql/buffer_util.go:90
*   | github.com/cockroachdb/cockroach/pkg/sql.(*RowResultWriter).AddRow
*   |   github.com/cockroachdb/cockroach/pkg/sql/distsql_running.go:908
*   | github.com/cockroachdb/cockroach/pkg/sql.(*DistSQLReceiver).Push
*   |   github.com/cockroachdb/cockroach/pkg/sql/distsql_running.go:1241
*   | github.com/cockroachdb/cockroach/pkg/sql/execinfra.Run
*   |   github.com/cockroachdb/cockroach/pkg/sql/execinfra/base.go:189
*   | github.com/cockroachdb/cockroach/pkg/sql/execinfra.(*ProcessorBaseNoHelper).Run
*   |   github.com/cockroachdb/cockroach/pkg/sql/execinfra/processorsbase.go:722

For the record, the equivalent sequence in Postgres does this:

jordan=> select f();
ERROR:  return type mismatch in function declared to return integer
DETAIL:  Final statement must return exactly one column.
CONTEXT:  SQL function "f" during startup

Jira issue: CRDB-18552

@jordanlewis jordanlewis added C-bug Code not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior. A-sql-routine UDFs and Stored Procedures labels Aug 12, 2022
@chengxiong-ruan
Copy link
Contributor

This is a good catch and interesting...In postgres if you use their early binding syntax, it still works:

postgres=# create table tt(a int);
CREATE TABLE

postgres=# create function ff() returns int language sql
postgres-# begin atomic
postgres-# select * from tt;
postgres-# end;
CREATE FUNCTION

postgres=# alter table tt add column b int;
ALTER TABLE

postgres=# insert into tt values (2,1);
INSERT 0 1

postgres=# select ff();
 ff
----
  2
(1 row)

I'm confused what should we do here for the long term. I think in the short term we should prevent the function from being broken. Either disallow the table from being mutated, or we should revalidate the function body when doing the type checking to throw out a better error.

@chengxiong-ruan
Copy link
Contributor

This is also a good corner case to consider when we're going to design function body rewritting.

@ajwerner
Copy link
Contributor

postgres resolves the * at definition time when early binding -- or, like we do for views, disallow them for this release and come back and attack that in 23.1 for both features.

SELECT n.nspname AS schema
      ,proname AS fname
      ,proargnames AS args
      ,t.typname AS return_type
      ,d.description
      ,pg_get_functiondef(p.oid) as definition
--      ,CASE WHEN NOT p.proisagg THEN pg_get_functiondef(p.oid)
--            ELSE 'pg_get_functiondef() can''t be used with aggregate functions'
--       END as definition
  FROM pg_proc p
  JOIN pg_type t
    ON p.prorettype = t.oid
  LEFT OUTER
  JOIN pg_description d
    ON p.oid = d.objoid
  LEFT OUTER
  JOIN pg_namespace n
    ON n.oid = p.pronamespace
 WHERE NOT p.prokind = 'a' and p.proname = 'f';
 schema | fname | args | return_type | description |                   definition                   
--------+-------+------+-------------+-------------+------------------------------------------------
 public | f     | {i}  | int4        |             | CREATE OR REPLACE FUNCTION public.f(i integer)+
        |       |      |             |             |  RETURNS integer                              +
        |       |      |             |             |  LANGUAGE sql                                 +
        |       |      |             |             |  IMMUTABLE                                    +
        |       |      |             |             | BEGIN ATOMIC                                  +
        |       |      |             |             |  SELECT t.i                                   +
        |       |      |             |             |     FROM sc.t                                 +
        |       |      |             |             |    WHERE (f.i > t.i);                         +
        |       |      |             |             | END                                           +
        |       |      |             |             | 

@chengxiong-ruan
Copy link
Contributor

Interestingly we don't support * expression in views. I think @mgartner enabled it recently for UDF. But yeah, I agree that we can make it simple in 22.2.

@blathers-crl blathers-crl bot added the T-sql-queries SQL Queries Team label Aug 23, 2022
@mgartner
Copy link
Collaborator

I'm planning on trying to fix this for 22.2.

@mgartner mgartner added release-blocker Indicates a release-blocker. Use with branch-release-2x.x label to denote which branch is blocked. branch-release-22.2 Used to mark GA and release blockers, technical advisories, and bugs for 22.2 branch-release-22.2.0 labels Oct 11, 2022
@mgartner
Copy link
Collaborator

Labelling as a release blocker. A fix to prevent node crashes in this case should be trivial.

@ajwerner
Copy link
Contributor

I think we can disable support for the * for this release and it would be okay. Postgres in views and in the eagerly resolved form of UDFs turns the * into column names at creation time. I think we should do that.

mgartner added a commit to mgartner/cockroach that referenced this issue Oct 17, 2022
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.
mgartner added a commit to mgartner/cockroach that referenced this issue Oct 17, 2022
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.
craig bot pushed a commit that referenced this issue Oct 18, 2022
90085: sql: disallow star expressions in UDF bodies r=mgartner a=mgartner

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 #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 #90080 tracks re-enabling star expressions in UDFs.


Co-authored-by: Marcus Gartner <[email protected]>
@craig craig bot closed this as completed in d0a5b85 Oct 18, 2022
blathers-crl bot pushed a commit that referenced this issue Oct 18, 2022
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 #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 #90080 tracks re-enabling star expressions in UDFs.
blathers-crl bot pushed a commit that referenced this issue Oct 18, 2022
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 #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 #90080 tracks re-enabling star expressions in UDFs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-sql-routine UDFs and Stored Procedures branch-release-22.2 Used to mark GA and release blockers, technical advisories, and bugs for 22.2 C-bug Code not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior. release-blocker Indicates a release-blocker. Use with branch-release-2x.x label to denote which branch is blocked. T-sql-queries SQL Queries Team
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

5 participants