-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sql: add support for REFCURSOR data type
This patch adds support for the `REFCURSOR` type. It is a special type used to hold the name of a cursor for PLpgSQL, although it can be used in other contexts (like function return types or column types). `REFCURSOR` is a string under the hood, and behaves like the `TEXT` data type in most cases. `REFCURSOR` has no casts in the `pg_cast` table; instead, all of its casts are the "IO" string casts. That means that there is an assignment cast from every type to `REFCURSOR`, and an explicit cast from `REFCURSOR` to every other type (except other string types, which are again assignment). See `ContextOriginAutomaticIOConversion` in `cast.go` for more info. This patch also adds `REFCURSOR` to the checks from the previous commit, so that statements with `REFCURSOR` are disallowed unless all nodes are running v23.2. Fixes #111560 Release note (sql change): Added support for the `REFCURSOR` data type. `REFCURSOR` is a special string type that is used to handle cursors. PLpgSQL cursor declarations are required to use a variable of type `REFCURSOR`, and the name of a cursor can be passed to and from a PLpgSQL function or procedure.
- Loading branch information
1 parent
efc6267
commit 3198d3b
Showing
25 changed files
with
881 additions
and
148 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
185 changes: 185 additions & 0 deletions
185
pkg/sql/logictest/testdata/logic_test/mixed_version_refcursor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
# LogicTest: cockroach-go-testserver-upgrade-to-master | ||
|
||
statement ok | ||
CREATE TABLE xy (x INT, y INT); | ||
|
||
# ---------------------------------------------------------------------- | ||
# Test REFCURSOR references with all nodes running old binaries. | ||
# ---------------------------------------------------------------------- | ||
|
||
subtest all_old_cast | ||
|
||
# Cast to REFCURSOR. | ||
statement error pgcode 42704 pq: type \"refcursor\" does not exist | ||
SELECT 'foo'::REFCURSOR; | ||
|
||
# Cast to REFCURSOR using the vectorized engine. | ||
statement error pgcode 42704 pq: type \"refcursor\" does not exist | ||
SELECT 'foo'::REFCURSOR FROM generate_series(1, 100) LIMIT 1; | ||
|
||
subtest all_old_table | ||
|
||
# Table that references REFCURSOR. | ||
statement error pgcode 42704 pq: type \"refcursor\" does not exist | ||
CREATE TABLE t (x REFCURSOR); | ||
|
||
# Add a REFCURSOR column. | ||
statement error pgcode 42704 pq: type \"refcursor\" does not exist | ||
ALTER TABLE xy ADD COLUMN curs REFCURSOR; | ||
|
||
# Alter a column type to REFCURSOR. | ||
statement ok | ||
SET enable_experimental_alter_column_type_general=true; | ||
|
||
statement error pgcode 42704 pq: type \"refcursor\" does not exist | ||
ALTER TABLE xy ALTER COLUMN y TYPE REFCURSOR; | ||
|
||
# Create a partial index that uses the REFCURSOR type. | ||
statement error pgcode 42704 pq: type \"refcursor\" does not exist | ||
CREATE INDEX part ON xy (x) WHERE y::REFCURSOR < 'foo'; | ||
|
||
# Add a check constraint that uses the REFCURSOR type. | ||
statement error pgcode 42704 pq: type \"refcursor\" does not exist | ||
ALTER TABLE xy ADD CONSTRAINT bar CHECK (y::REFCURSOR < 'baz'); | ||
|
||
subtest all_old_type | ||
|
||
# UDT that references REFCURSOR. | ||
statement error pgcode 42704 pq: type \"refcursor\" does not exist | ||
CREATE TYPE typ AS (x INT, y REFCURSOR); | ||
|
||
subtest all_old_function | ||
|
||
# Function that returns REFCURSOR. | ||
statement error pgcode 42704 pq: type \"refcursor\" does not exist | ||
CREATE OR REPLACE FUNCTION f() RETURNS REFCURSOR AS $$ | ||
SELECT 'foo'; | ||
$$ LANGUAGE SQL; | ||
|
||
# Function that takes REFCURSOR argument. | ||
statement error pgcode 42704 pq: type \"refcursor\" does not exist | ||
CREATE OR REPLACE FUNCTION f(curs REFCURSOR) RETURNS STRING AS $$ | ||
SELECT curs; | ||
$$ LANGUAGE SQL; | ||
|
||
# Function that references REFCURSOR internally. | ||
statement error pgcode 42704 pq: type \"refcursor\" does not exist | ||
CREATE OR REPLACE FUNCTION f() RETURNS INT AS $$ | ||
SELECT 'foo'::REFCURSOR; | ||
SELECT 0; | ||
$$ LANGUAGE SQL; | ||
|
||
# Function that returns a composite type with REFCURSOR component. | ||
statement error pgcode 42704 pq: type \"refcursor\" does not exist | ||
CREATE FUNCTION f() RETURNS RECORD AS $$ | ||
SELECT (1, 'foo'::REFCURSOR, true); | ||
$$ LANGUAGE SQL; | ||
|
||
subtest end | ||
|
||
# ---------------------------------------------------------------------- | ||
# Verify that REFCURSOR is not allowed after upgrading the gateway. | ||
# ---------------------------------------------------------------------- | ||
|
||
upgrade 0 | ||
|
||
user root nodeidx=0 | ||
|
||
subtest upgrade_one_cast | ||
|
||
# Cast to REFCURSOR. | ||
statement error pgcode 0A000 pq: refcursor not supported until version 23.2 | ||
SELECT 'foo'::REFCURSOR; | ||
|
||
# Cast to REFCURSOR using the vectorized engine. | ||
statement error pgcode 0A000 pq: refcursor not supported until version 23.2 | ||
SELECT 'foo'::REFCURSOR FROM generate_series(1, 100) LIMIT 1; | ||
|
||
subtest upgrade_one_table | ||
|
||
# Table that references REFCURSOR. | ||
statement error pgcode 0A000 pq: refcursor not supported until version 23.2 | ||
CREATE TABLE t (x REFCURSOR); | ||
|
||
# Add a REFCURSOR column. | ||
statement error pgcode 0A000 pq: refcursor not supported until version 23.2 | ||
ALTER TABLE xy ADD COLUMN curs REFCURSOR; | ||
|
||
# Alter a column type to REFCURSOR. | ||
statement ok | ||
SET enable_experimental_alter_column_type_general=true; | ||
|
||
statement error pgcode 0A000 pq: refcursor not supported until version 23.2 | ||
ALTER TABLE xy ALTER COLUMN y TYPE REFCURSOR; | ||
|
||
# Create a partial index that uses the REFCURSOR type. | ||
statement error pgcode 0A000 pq: refcursor not supported until version 23.2 | ||
CREATE INDEX part ON xy (x) WHERE y::REFCURSOR < 'foo'; | ||
|
||
# Add a check constraint that uses the REFCURSOR type. | ||
statement error pgcode 0A000 pq: refcursor not supported until version 23.2 | ||
ALTER TABLE xy ADD CONSTRAINT bar CHECK (y::REFCURSOR < 'baz'); | ||
|
||
subtest upgrade_one_type | ||
|
||
# UDT that references REFCURSOR. | ||
statement error pgcode 0A000 pq: refcursor not supported until version 23.2 | ||
CREATE TYPE typ AS (x INT, y REFCURSOR); | ||
|
||
subtest upgrade_one_function | ||
|
||
# Function that returns REFCURSOR. | ||
statement error pgcode 0A000 pq: refcursor not supported until version 23.2 | ||
CREATE OR REPLACE FUNCTION f() RETURNS REFCURSOR AS $$ | ||
SELECT 'foo'; | ||
$$ LANGUAGE SQL; | ||
|
||
statement error pgcode 0A000 pq: refcursor not supported until version 23.2 | ||
CREATE OR REPLACE FUNCTION f() RETURNS REFCURSOR AS $$ | ||
BEGIN | ||
RETURN 'foo'; | ||
END | ||
$$ LANGUAGE PLpgSQL; | ||
|
||
# Function that takes REFCURSOR argument. | ||
statement error pgcode 0A000 pq: refcursor not supported until version 23.2 | ||
CREATE OR REPLACE FUNCTION f(curs REFCURSOR) RETURNS INT AS $$ | ||
SELECT 0; | ||
$$ LANGUAGE SQL; | ||
|
||
statement error pgcode 0A000 pq: refcursor not supported until version 23.2 | ||
CREATE OR REPLACE FUNCTION f(curs REFCURSOR) RETURNS INT AS $$ | ||
BEGIN | ||
RETURN 0; | ||
END | ||
$$ LANGUAGE PLpgSQL; | ||
|
||
# Function that references REFCURSOR internally. | ||
statement error pgcode 0A000 pq: refcursor not supported until version 23.2 | ||
CREATE OR REPLACE FUNCTION f() RETURNS INT AS $$ | ||
SELECT 'foo'::REFCURSOR; | ||
SELECT 0; | ||
$$ LANGUAGE SQL; | ||
|
||
statement error pgcode 0A000 pq: refcursor not supported until version 23.2 | ||
CREATE OR REPLACE FUNCTION f() RETURNS INT AS $$ | ||
BEGIN | ||
SELECT 'foo'::REFCURSOR; | ||
RETURN 0; | ||
END | ||
$$ LANGUAGE PLpgSQL; | ||
|
||
# Function that returns a composite type with REFCURSOR component. | ||
statement error pgcode 0A000 pq: refcursor not supported until version 23.2 | ||
CREATE FUNCTION f() RETURNS RECORD AS $$ | ||
SELECT (1, 'foo'::REFCURSOR, true); | ||
$$ LANGUAGE SQL; | ||
|
||
statement error pgcode 0A000 pq: refcursor not supported until version 23.2 | ||
CREATE FUNCTION f() RETURNS RECORD AS $$ | ||
BEGIN | ||
RETURN (1, 'foo'::REFCURSOR, true); | ||
END | ||
$$ LANGUAGE PLpgSQL; | ||
|
||
subtest end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.