-
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
db31fb4
commit 4f5726a
Showing
24 changed files
with
766 additions
and
146 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
146 changes: 146 additions & 0 deletions
146
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,146 @@ | ||
# 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. | ||
# ---------------------------------------------------------------------- | ||
|
||
# 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; | ||
|
||
# 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'); | ||
|
||
# UDT that references REFCURSOR. | ||
statement error pgcode 42704 pq: type \"refcursor\" does not exist | ||
CREATE TYPE typ AS (x INT, y REFCURSOR); | ||
|
||
# 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; | ||
|
||
# ---------------------------------------------------------------------- | ||
# Verify that REFCURSOR is not allowed after upgrading the gateway. | ||
# ---------------------------------------------------------------------- | ||
|
||
upgrade 0 | ||
|
||
user root nodeidx=0 | ||
|
||
# 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; | ||
|
||
# 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'); | ||
|
||
# UDT that references REFCURSOR. | ||
statement error pgcode 0A000 pq: refcursor not supported until version 23.2 | ||
CREATE TYPE typ AS (x INT, y REFCURSOR); | ||
|
||
# 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; |
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,181 @@ | ||
statement ok | ||
CREATE TABLE xy (x INT, y INT); | ||
|
||
# Cast to REFCURSOR. | ||
query T | ||
SELECT 'foo'::REFCURSOR; | ||
---- | ||
foo | ||
|
||
# Cast to REFCURSOR using the vectorized engine. | ||
query T | ||
SELECT 'foo'::REFCURSOR FROM generate_series(1, 100) LIMIT 1; | ||
---- | ||
foo | ||
|
||
# Table that references REFCURSOR. | ||
statement ok | ||
CREATE TABLE t (x REFCURSOR); | ||
|
||
# Add a REFCURSOR column. | ||
statement ok | ||
ALTER TABLE xy ADD COLUMN curs REFCURSOR; | ||
|
||
statement ok | ||
INSERT INTO xy VALUES (1, 2, 'foo'); | ||
|
||
query IIT | ||
SELECT * FROM xy; | ||
---- | ||
1 2 foo | ||
|
||
# Alter a column type to REFCURSOR. | ||
statement ok | ||
DROP TABLE IF EXISTS xy; | ||
CREATE TABLE xy (x INT, y INT); | ||
SET enable_experimental_alter_column_type_general=true; | ||
|
||
statement ok | ||
ALTER TABLE xy ALTER COLUMN y TYPE REFCURSOR; | ||
|
||
statement ok | ||
INSERT INTO xy VALUES (1, 'bar'); | ||
|
||
query IT | ||
SELECT * FROM xy; | ||
---- | ||
1 bar | ||
|
||
statement ok | ||
DROP TABLE IF EXISTS xy; | ||
CREATE TABLE xy (x INT, y INT); | ||
INSERT INTO xy VALUES (1, 2); | ||
INSERT INTO xy VALUES (3, 4); | ||
|
||
# Create a partial index that uses the REFCURSOR type. | ||
statement ok | ||
CREATE INDEX part ON xy (x) WHERE y::REFCURSOR < '3'; | ||
|
||
query II | ||
SELECT * FROM xy@part WHERE y::REFCURSOR < '3'; | ||
---- | ||
1 2 | ||
|
||
statement ok | ||
DROP TABLE IF EXISTS xy; | ||
CREATE TABLE xy (x INT, y INT); | ||
INSERT INTO xy VALUES (1, 2); | ||
|
||
# Add a check constraint that uses the REFCURSOR type. | ||
statement ok | ||
ALTER TABLE xy ADD CONSTRAINT bar CHECK (y::REFCURSOR < 'baz'); | ||
|
||
query II | ||
SELECT * FROM xy; | ||
---- | ||
1 2 | ||
|
||
# UDT that references REFCURSOR. | ||
statement ok | ||
CREATE TYPE typ AS (x INT, y REFCURSOR); | ||
|
||
query T | ||
SELECT (100, 'bar')::typ; | ||
---- | ||
(100,bar) | ||
|
||
# Function that returns REFCURSOR. | ||
statement ok | ||
CREATE FUNCTION f() RETURNS REFCURSOR AS $$ | ||
SELECT 'foo'; | ||
$$ LANGUAGE SQL; | ||
|
||
query T | ||
SELECT f(); | ||
---- | ||
foo | ||
|
||
statement ok | ||
DROP FUNCTION f; | ||
|
||
statement ok | ||
CREATE FUNCTION f() RETURNS REFCURSOR AS $$ | ||
BEGIN | ||
RETURN 'foo'; | ||
END | ||
$$ LANGUAGE PLpgSQL; | ||
|
||
query T | ||
SELECT f(); | ||
---- | ||
foo | ||
|
||
statement ok | ||
DROP FUNCTION f; | ||
|
||
# Function that takes REFCURSOR argument. | ||
statement ok | ||
CREATE FUNCTION f(curs REFCURSOR) RETURNS INT AS $$ | ||
SELECT 0; | ||
$$ LANGUAGE SQL; | ||
|
||
query I | ||
SELECT f('foo'); | ||
---- | ||
0 | ||
|
||
statement ok | ||
DROP FUNCTION f; | ||
|
||
statement ok | ||
CREATE FUNCTION f(curs REFCURSOR) RETURNS INT AS $$ | ||
BEGIN | ||
RETURN 0; | ||
END | ||
$$ LANGUAGE PLpgSQL; | ||
|
||
query I | ||
SELECT f('foo'); | ||
---- | ||
0 | ||
|
||
statement ok | ||
DROP FUNCTION f; | ||
|
||
# Function that references REFCURSOR internally. | ||
statement ok | ||
CREATE FUNCTION f() RETURNS INT AS $$ | ||
SELECT 'foo'::REFCURSOR; | ||
SELECT 0; | ||
$$ LANGUAGE SQL; | ||
|
||
query I | ||
SELECT f(); | ||
---- | ||
0 | ||
|
||
statement ok | ||
DROP FUNCTION f; | ||
|
||
statement ok | ||
CREATE FUNCTION f() RETURNS INT AS $$ | ||
BEGIN | ||
SELECT 'foo'::REFCURSOR; | ||
RETURN 0; | ||
END | ||
$$ LANGUAGE PLpgSQL; | ||
|
||
query I | ||
SELECT f(); | ||
---- | ||
0 | ||
|
||
# TODO(drewk): REFCURSOR should not support collation. | ||
query T | ||
SELECT 'foo'::REFCURSOR COLLATE en; | ||
---- | ||
foo | ||
|
||
# REFCURSOR does not have a width. | ||
statement error pgcode 42601 syntax error | ||
SELECT 'foo'::REFCURSOR(2); |
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
7 changes: 7 additions & 0 deletions
7
pkg/sql/logictest/tests/cockroach-go-testserver-upgrade-to-master/generated_test.go
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.