Skip to content

types: give REFCURSOR its own type family#111906

Merged
craig[bot] merged 4 commits intocockroachdb:masterfrom
DrewKimball:refcursor-family
Oct 7, 2023
Merged

types: give REFCURSOR its own type family#111906
craig[bot] merged 4 commits intocockroachdb:masterfrom
DrewKimball:refcursor-family

Conversation

@DrewKimball
Copy link
Copy Markdown
Collaborator

@DrewKimball DrewKimball commented Oct 6, 2023

plpgsql: prepare cursor name generation for REFCURSOR type family

This patch removes the case statement that checks whether a cursor
name is NULL before calling into plpgsql_gen_cursor_name because the
builtin already checks whether the argument is NULL, and REFCURSOR
will (correctly) not support comparisons after we add a new type family
for it. The return type for the call to plpgsql_gen_cursor_name is
also changed from String to Refcursor.

Informs #111560

Release note: None

tree: add REFCURSOR to the list of parsable string types

This patch adds the new REFCURSOR data type to the list of types that
a string constant can have. This will allow constant values to avoid
an explicit cast to REFCURSOR in cases when the context expects a
REFCURSOR, e.g. inserting into a REFCURSOR column or calling a
routine with a REFCURSOR parameter. Example:

CREATE FUNCTION f(curs REFCURSOR) RETURNS REFCURSOR AS $$
  SELECT curs;
$$ LANGUAGE SQL;

-- This cast was necessary before:
SELECT f('foo'::REFCURSOR);

-- Now this works:
SELECT f('foo');

Informs #111560

Release note: None

types: give REFCURSOR its own type family

Previously, REFCURSOR shared a type family with the string-like types.
However, since it can't be implicitly casted to and from string types in
all cases, it needs to have its own family (since types within a family
must be compatible). This patch adds the new RefCursorFamily, and
follows the example of the PG_LSN type in plumbing it throughout the
SQL layer.

Informs #111560

Release note: None

tree: disallow and test comparison operators for REFCURSOR

The REFCURSOR data type does not support comparisons apart from a
few edge cases like 'foo'::REFCURSOR IS NULL. Example:

postgres=# SELECT 'foo'::REFCURSOR = 'foo'::REFCURSOR;
ERROR:  operator does not exist: refcursor = refcursor

The previous commit that added the RefCursorFamily type family already
effectively removed support for most comparisons; this commit also
prevents the IS / IS DISTINCT FROM variants from being used on a
REFCURSOR expression. Note that postgres supports a few cases with
NULL as mentioned above. However, this case seems unimportant, so I
leave it as a TODO for now.

This commit also adds tests for various comparisons involving REFCURSOR.

Informs #111560

Release note: None

@DrewKimball DrewKimball requested review from a team as code owners October 6, 2023 12:22
@DrewKimball DrewKimball requested a review from a team October 6, 2023 12:22
@DrewKimball DrewKimball requested a review from a team as a code owner October 6, 2023 12:22
@DrewKimball DrewKimball requested review from cucaroach and jayshrivastava and removed request for a team October 6, 2023 12:22
@cockroach-teamcity
Copy link
Copy Markdown
Member

This change is Reviewable

@DrewKimball DrewKimball requested review from a team, mgartner and rharding6373 and removed request for a team and jayshrivastava October 6, 2023 12:23
@DrewKimball
Copy link
Copy Markdown
Collaborator Author

The first commit is #111884.

Copy link
Copy Markdown
Member

@yuzefovich yuzefovich left a comment

Choose a reason for hiding this comment

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

Reviewed 8 of 27 files at r2, 2 of 3 files at r3, all commit messages.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @cucaroach, @DrewKimball, @mgartner, and @rharding6373)


pkg/sql/sem/tree/parse_string.go line 73 at r2 (raw file):

		d, err = ParseDPGLSN(s)
	case types.RefCursorFamily:
		return NewDRefCursor(s), false, nil

nit: in this method we don't return from within the switch stmt, so I wouldn't do it for consistency here too.

Copy link
Copy Markdown
Collaborator Author

@DrewKimball DrewKimball left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @cucaroach, @mgartner, @rharding6373, and @yuzefovich)


pkg/sql/sem/tree/parse_string.go line 73 at r2 (raw file):

Previously, yuzefovich (Yahor Yuzefovich) wrote…

nit: in this method we don't return from within the switch stmt, so I wouldn't do it for consistency here too.

Done.

@rharding6373
Copy link
Copy Markdown
Collaborator

From the tests it looks like there are a few places where the refcursor family is missing or built-in functions haven't been updated to return the new type. Pinging to bring this to your attention in case it isn't something you're looking into already.

Copy link
Copy Markdown
Collaborator

@michae2 michae2 left a comment

Choose a reason for hiding this comment

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

Reviewed 30 of 30 files at r6.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @cucaroach, @DrewKimball, @mgartner, @rharding6373, and @yuzefovich)


pkg/util/parquet/testutils.go line 366 at r6 (raw file):

		// REFCURSOR is implemented using DOidWrapper.
		if wrapper.Oid != oid.T_refcursor {
			return unwrapDatum(wrapper.Wrapped)

Why is REFCURSOR implemented using DOidWrapper?

Copy link
Copy Markdown
Collaborator Author

@DrewKimball DrewKimball left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @cucaroach, @mgartner, @michae2, @rharding6373, and @yuzefovich)


pkg/util/parquet/testutils.go line 366 at r6 (raw file):

Previously, michae2 (Michael Erickson) wrote…

Why is REFCURSOR implemented using DOidWrapper?

REFCURSOR behaves just like a string; the main difference is that it can't be freely casted the way string types can, and that behavior is encoded by the type rather than the underlying datum.

Copy link
Copy Markdown
Collaborator Author

@DrewKimball DrewKimball left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @cucaroach, @mgartner, @michae2, @rharding6373, and @yuzefovich)


pkg/util/parquet/testutils.go line 366 at r6 (raw file):

Previously, DrewKimball (Drew Kimball) wrote…

REFCURSOR behaves just like a string; the main difference is that it can't be freely casted the way string types can, and that behavior is encoded by the type rather than the underlying datum.

DOidWrapper lets us share the implementation for the datum while also being able to specify type-specific behavior. Up until now it's only been used to change how a type's name is displayed, but it was intended to be usable for other behavio changes as well.

This patch removes the case statement that checks whether a cursor
name is NULL before calling into `plpgsql_gen_cursor_name` because the
builtin already checks whether the argument is NULL, and `REFCURSOR`
will (correctly) not support comparisons after we add a new type family
for it. The return type for the call to `plpgsql_gen_cursor_name` is
also changed from `String` to `Refcursor`.

Informs cockroachdb#111560

Release note: None
This patch adds the new `REFCURSOR` data type to the list of types that
a string constant can have. This will allow constant values to avoid
an explicit cast to `REFCURSOR` in cases when the context expects a
`REFCURSOR`, e.g. inserting into a `REFCURSOR` column or calling a
routine with a `REFCURSOR` parameter. Example:
```
CREATE FUNCTION f(curs REFCURSOR) RETURNS REFCURSOR AS $$
  SELECT curs;
$$ LANGUAGE SQL;

-- This cast was necessary before:
SELECT f('foo'::REFCURSOR);

-- Now this works:
SELECT f('foo');
```

Informs cockroachdb#111560

Release note: None
@DrewKimball
Copy link
Copy Markdown
Collaborator Author

I've moved the commit to allow parsing REFCURSOR constants before the one to add the type family; this decreases the number of test changes that had to be made between commits.

I also added a commit to remove the check for NULL cursor name before calling plpgsql_gen_cursor_name, since plpgsql_gen_cursor_name already handles that case and REFCURSOR doesn't support comparison operators.

Previously, REFCURSOR shared a type family with the string-like types.
However, since it can't be implicitly casted to and from string types in
all cases, it needs to have its own family (since types within a family
must be compatible). This patch adds the new `RefCursorFamily`, and
follows the example of the PG_LSN type in plumbing it throughout the
SQL layer.

Informs cockroachdb#111560

Release note: None
The `REFCURSOR` data type does not support comparisons apart from a
few edge cases like `'foo'::REFCURSOR IS NULL`. Example:
```
postgres=# SELECT 'foo'::REFCURSOR = 'foo'::REFCURSOR;
ERROR:  operator does not exist: refcursor = refcursor
```
The previous commit that added the `RefCursorFamily` type family already
effectively removed support for most comparisons; this commit also
prevents the `IS / IS DISTINCT FROM` variants from being used on a
`REFCURSOR` expression. Note that postgres supports a few cases with
`NULL` as mentioned above. However, this case seems unimportant, so I
leave it as a TODO for now.

This commit also adds tests for various comparisons involving `REFCURSOR`.

Informs cockroachdb#111560

Release note: None
Copy link
Copy Markdown
Collaborator

@michae2 michae2 left a comment

Choose a reason for hiding this comment

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

:lgtm: Very nice.

(Don't forget to update the PR description to match the new commit order.)

Reviewed 38 of 38 files at r9, 35 of 35 files at r10, 33 of 37 files at r11, 3 of 5 files at r12, 3 of 3 files at r13, 2 of 2 files at r14, all commit messages.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @cucaroach, @mgartner, and @rharding6373)


pkg/util/parquet/testutils.go line 366 at r6 (raw file):

Previously, DrewKimball (Drew Kimball) wrote…

DOidWrapper lets us share the implementation for the datum while also being able to specify type-specific behavior. Up until now it's only been used to change how a type's name is displayed, but it was intended to be usable for other behavio changes as well.

Thanks!

@DrewKimball
Copy link
Copy Markdown
Collaborator Author

TFTR!

bors r+

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Oct 7, 2023

Build succeeded:

@craig craig bot merged commit 630553f into cockroachdb:master Oct 7, 2023
@DrewKimball DrewKimball deleted the refcursor-family branch October 7, 2023 11:26
jayshrivastava added a commit to jayshrivastava/cockroach that referenced this pull request Oct 19, 2023
Previously, not unwrap datums read from parquet files before
comparing. Now, we do. Previously, we didn't need to (all datums
were unwrapped), but cockroachdb#111906 added a new decoder which may return an
OID-wrapped datum.

We do not need to preserve OID wrappers etc when reading parquet
files in tests because we do not store that information in the parquet
files. Testing that OID wrappers match before and after is unecessary.

Additionally, we used to skip unwrapping `REFCURSOR` datums before
comparing. For the same reason as above, we can just unwrap them.

Release note: None
Epic: None
jayshrivastava added a commit to jayshrivastava/cockroach that referenced this pull request Oct 19, 2023
Previously, we did not unwrap datums read from parquet files before
comparing. Now, we do. Before cockroachdb#111906, we didn't need to, but now we
do because that patch added a new decoder which may return an
OID-wrapped datum.

We do not need to preserve OID wrappers etc when reading parquet
files in tests because we do not store that information in the parquet
files. Testing that OID wrappers match before and after is unecessary.

Additionally, we used to skip unwrapping `REFCURSOR` datums before
comparing. For the same reason as above, we can just unwrap them.

This change also fixes the `validateDatum` function in exporter
tests. It previously did not unwrap array contents. Now it does.

Release note: None
Epic: None
Closes: cockroachdb#112561

 Please enter the commit message for your changes. Lines starting
craig bot pushed a commit that referenced this pull request Oct 19, 2023
112653: nightlies: add script for stress-engflow nightly r=rail a=rickystewart

Epic: CRDB-8308
Release note: None

112687: release: verify version.txt in Pick SHA r=celiala a=rail

Previously, we did not verify the contents of the version.txt file as a part of the Pick SHA step. In case the guessed version doesn't match the contents of the file, we have to delay the release by many hours to allow CI automation work.

This PR adds a check in the Pick SHA step to verify the version.

Fixes: RE-438
Release note: None
Release justification: release automation changes

112689: streamclient: bump test size r=rail a=rickystewart

This is routinely timing out in the EngFlow continuous test. Maybe when it's working on remote execution it will be quicker and we can bump this back down to `small`.

Epic: CRDB-8308
Release note: None

112693: parquet: unwrap datums better r=jayshrivastava a=jayshrivastava

Previously, we did not unwrap datums read from parquet files before
comparing. Now, we do. Before #111906, we didn't need to, but now we
do because that patch added a new decoder which may return an
OID-wrapped datum.

We do not need to preserve OID wrappers etc when reading parquet
files in tests because we do not store that information in the parquet
files. Testing that OID wrappers match before and after is unecessary.

Additionally, we used to skip unwrapping `REFCURSOR` datums before
comparing. For the same reason as above, we can just unwrap them.

This change also fixes the `validateDatum` function in exporter
tests. It previously did not unwrap array contents. Now it does.

Release note: None
Epic: None
Closes: #112561

112704: zonepb: add expected/actual values to validation errors r=rafiss a=rafiss

This will make it slightly easier to debug errors where this validation fails.

informs #111299
Release note: None

Co-authored-by: Ricky Stewart <ricky@cockroachlabs.com>
Co-authored-by: Rail Aliiev <rail@iqchoice.com>
Co-authored-by: Jayant Shrivastava <jayants@cockroachlabs.com>
Co-authored-by: Rafi Shamim <rafi@cockroachlabs.com>
blathers-crl bot pushed a commit that referenced this pull request Oct 19, 2023
Previously, we did not unwrap datums read from parquet files before
comparing. Now, we do. Before #111906, we didn't need to, but now we
do because that patch added a new decoder which may return an
OID-wrapped datum.

We do not need to preserve OID wrappers etc when reading parquet
files in tests because we do not store that information in the parquet
files. Testing that OID wrappers match before and after is unecessary.

Additionally, we used to skip unwrapping `REFCURSOR` datums before
comparing. For the same reason as above, we can just unwrap them.

This change also fixes the `validateDatum` function in exporter
tests. It previously did not unwrap array contents. Now it does.

Release note: None
Epic: None
Closes: #112561

 Please enter the commit message for your changes. Lines starting
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants