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

builtins: pg_get_constraintdef broken during DROP CONSTRAINT in txn #75825

Closed
otan opened this issue Feb 1, 2022 · 4 comments · Fixed by #76381
Closed

builtins: pg_get_constraintdef broken during DROP CONSTRAINT in txn #75825

otan opened this issue Feb 1, 2022 · 4 comments · Fixed by #76381
Assignees
Labels
A-tools-activerecord C-bug Code not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior. T-sql-foundations SQL Foundations Team (formerly SQL Schema + SQL Sessions)

Comments

@otan
Copy link
Contributor

otan commented Feb 1, 2022

This is a new failure introduced between 4d6d79d...7897f24, so my guess is 617d300 is the cause of the regression.

The following should not error:

BEGIN;
create table tbl (price int, quantity int);
alter table tbl add constraint quan_check check (quantity > 0);
alter table tbl add constraint pr_check check (price > 0);

SELECT conname, pg_get_constraintdef(c.oid) AS constraintdef, c.convalidated AS valid
            FROM pg_constraint c
            JOIN pg_class t ON c.conrelid = t.oid
            WHERE c.contype = 'c'
              AND t.relname = 'tbl'; -- this query beforehand  is required to trigger the error; without it everything is fine
alter table tbl drop constraint quan_check;
SELECT conname, pg_get_constraintdef(c.oid) AS constraintdef, c.convalidated AS valid
            FROM pg_constraint c
            JOIN pg_class t ON c.conrelid = t.oid
            WHERE c.contype = 'c'
              AND t.relname = 'tbl'; -- this fails
COMMIT;

example output:

[email protected]:26257/defaultdb> BEGIN;
create table tbl (price int, quantity int);
alter table tbl add constraint quan_check check (quantity > 0);
alter table tbl add constraint pr_check check (price > 0);

SELECT conname, pg_get_constraintdef(c.oid) AS constraintdef, c.convalidated AS valid
            FROM pg_constraint c
            JOIN pg_class t ON c.conrelid = t.oid
            WHERE c.contype = 'c'
              AND t.relname = 'tbl'; 
alter table tbl drop constraint quan_check;
SELECT conname, pg_get_constraintdef(c.oid) AS constraintdef, c.convalidated AS valid
            FROM pg_constraint c
            JOIN pg_class t ON c.conrelid = t.oid
            WHERE c.contype = 'c'
              AND t.relname = 'tbl';
COMMIT;
BEGIN


Time: 0ms total (execution 0ms / network 0ms)

CREATE TABLE


Time: 3ms total (execution 3ms / network 0ms)

ALTER TABLE


Time: 12ms total (execution 12ms / network 0ms)

ALTER TABLE


Time: 9ms total (execution 9ms / network 0ms)

   conname   |     constraintdef      | valid
-------------+------------------------+--------
  pr_check   | CHECK ((price > 0))    | true
  quan_check | CHECK ((quantity > 0)) | true
(2 rows)


Time: 11ms total (execution 11ms / network 0ms)

ALTER TABLE


Time: 2ms total (execution 2ms / network 0ms)

ERROR: pg_get_constraintdef(): unknown constraint (OID=1220880198)
SQLSTATE: 22023
ROLLBACK


Time: 2ms total (execution 1ms / network 2ms)

pg_get_constraintdef:

func makePGGetConstraintDef(argTypes tree.ArgTypes) tree.Overload {
return tree.Overload{
Types: argTypes,
ReturnType: tree.FixedReturnType(types.String),
Fn: func(ctx *tree.EvalContext, args tree.Datums) (tree.Datum, error) {
r, err := ctx.Planner.QueryRowEx(
ctx.Ctx(), "pg_get_constraintdef",
ctx.Txn,
sessiondata.NoSessionDataOverride,
"SELECT condef FROM pg_catalog.pg_constraint WHERE oid=$1", args[0])
if err != nil {
return nil, err
}
if len(r) == 0 {
return nil, pgerror.Newf(pgcode.InvalidParameterValue, "unknown constraint (OID=%s)", args[0])
}
return r[0], nil
},
Info: notUsableInfo,
Volatility: tree.VolatilityStable,

Refs #68363 (comment)

@blathers-crl
Copy link

blathers-crl bot commented Feb 1, 2022

Hi @otan, please add a C-ategory label to your issue. Check out the label system docs.

While you're here, please consider adding an A- label to help keep our repository tidy.

🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is otan.

@blathers-crl blathers-crl bot added the T-sql-schema-deprecated Use T-sql-foundations instead label Feb 1, 2022
@ajwerner
Copy link
Contributor

ajwerner commented Feb 1, 2022

In #69008 we changed where we decide to reset the complete set of descriptors. I'm not totally sure I picked up on that subtle detail. We use to do it when we did a write. The idea was that's when we'd invalidate the set. @postamar changed it to be on read, which I sort of get, but I don't totally get.

tc.kv.releaseAllDescriptors()

The idea being that you've got to check things out before you check them in, but I don't know, it doesn't seem to work here. I will note that new descriptors we avoid the whole descs collection. I don't know why that is.

@postamar
Copy link
Contributor

postamar commented Feb 8, 2022

@fqazi I understand you've got a fix in the works, related to the random schema changer somehow. Feel free to re-triage this if this issue assignment doesn't make sense.

@fqazi
Copy link
Collaborator

fqazi commented Feb 8, 2022

I'll split it off and put up a pull request for it, I have it with the randomized schema changer fixes.

fqazi added a commit to fqazi/cockroach that referenced this issue Feb 10, 2022
Fixes: cockroachdb#75825

Previously, when an uncommitted descriptor was added
to a descriptor collection, we would not reset the cache of
all immutable descriptors (used by some crdb_internal functions).
This was inadequate because this could result in
incorrect results from crdb_internal tables which returned
information related to constraints, columns. To address this,
this patch will reset the descriptor cache for all
fetched descriptors when an uncommitted descriptor is
added into the collection.

Release note: None
craig bot pushed a commit that referenced this issue Feb 11, 2022
76381: sql: stale descriptor state could be observed in crdb_internal tables r=fqazi a=fqazi

Fixes: #75825

Previously, when an uncommitted descriptor was added
to a descriptor collection, we would not reset the cache of
all immutable descriptors (used by some crdb_internal functions).
This was inadequate because this could result in
incorrect results from crdb_internal tables which returned
information related to constraints, columns. To address this,
this patch will reset the descriptor cache for all
fetched descriptors when an uncommitted descriptor is
added into the collection.

Release note: None

Co-authored-by: Faizan Qazi <[email protected]>
@craig craig bot closed this as completed in bb0d19e Feb 11, 2022
@rafiss rafiss added A-tools-activerecord C-bug Code not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior. labels Feb 11, 2022
fqazi added a commit to fqazi/cockroach that referenced this issue Feb 14, 2022
Fixes: cockroachdb#75825

Previously, when an uncommitted descriptor was added
to a descriptor collection, we would not reset the cache of
all immutable descriptors (used by some crdb_internal functions).
This was inadequate because this could result in
incorrect results from crdb_internal tables which returned
information related to constraints, columns. To address this,
this patch will reset the descriptor cache for all
fetched descriptors when an uncommitted descriptor is
added into the collection.

Release note (bug fix): Certain crdb_internal tables could return incorrect
information due to cached table descriptor information.
RajivTS pushed a commit to RajivTS/cockroach that referenced this issue Mar 6, 2022
Fixes: cockroachdb#75825

Previously, when an uncommitted descriptor was added
to a descriptor collection, we would not reset the cache of
all immutable descriptors (used by some crdb_internal functions).
This was inadequate because this could result in
incorrect results from crdb_internal tables which returned
information related to constraints, columns. To address this,
this patch will reset the descriptor cache for all
fetched descriptors when an uncommitted descriptor is
added into the collection.

Release note: None
@exalate-issue-sync exalate-issue-sync bot added T-sql-foundations SQL Foundations Team (formerly SQL Schema + SQL Sessions) and removed T-sql-schema-deprecated Use T-sql-foundations instead labels May 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tools-activerecord C-bug Code not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior. T-sql-foundations SQL Foundations Team (formerly SQL Schema + SQL Sessions)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants