optbuilder: fix schema-qualified REGCLASS cast failing in UDFs#167679
optbuilder: fix schema-qualified REGCLASS cast failing in UDFs#167679ikristina wants to merge 1 commit intocockroachdb:masterfrom
Conversation
|
Merging to
After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here |
|
Thank you for contributing to CockroachDB. Please ensure you have followed the guidelines for creating a PR. My owl senses detect your PR is good for review. Please keep an eye out for any test failures in CI. 🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is dev-inf. |
⚪ Sysbench [SQL, 3node, oltp_read_write]
Reproducebenchdiff binaries: mkdir -p benchdiff/f00b89c/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/f00b89c2e50e1f6809d214d2957e6d5ec96f3da1/bin/pkg_sql_tests benchdiff/f00b89c/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/f00b89c/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
mkdir -p benchdiff/9d2a41d/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/9d2a41d63b95f4c84c58e4391c868f25d0c4b950/bin/pkg_sql_tests benchdiff/9d2a41d/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/9d2a41d/bin/1058449141/cockroachdb_cockroach_pkg_sql_testsbenchdiff command: # NB: for best (most stable) results, also add a suitable `--benchtime` that
# results in ~1s to ~5s of benchmark runs. For example, if ops average ~3ms, a
# benchtime of `1000x` is appropriate.
#
# Some benchmarks (in particular BenchmarkSysbench) output additional memory
# profiles covering only the execution (excluding the setup/teardown) - those
# should be preferred for analysis since they more closely correspond to what's
# reported as B/op and alloc/op.
benchdiff --run=^BenchmarkSysbench/SQL/3node/oltp_read_write$ --old=9d2a41d --new=f00b89c --memprofile ./pkg/sql/tests⚪ Sysbench [KV, 3node, oltp_read_only]
Reproducebenchdiff binaries: mkdir -p benchdiff/f00b89c/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/f00b89c2e50e1f6809d214d2957e6d5ec96f3da1/bin/pkg_sql_tests benchdiff/f00b89c/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/f00b89c/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
mkdir -p benchdiff/9d2a41d/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/9d2a41d63b95f4c84c58e4391c868f25d0c4b950/bin/pkg_sql_tests benchdiff/9d2a41d/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/9d2a41d/bin/1058449141/cockroachdb_cockroach_pkg_sql_testsbenchdiff command: # NB: for best (most stable) results, also add a suitable `--benchtime` that
# results in ~1s to ~5s of benchmark runs. For example, if ops average ~3ms, a
# benchtime of `1000x` is appropriate.
#
# Some benchmarks (in particular BenchmarkSysbench) output additional memory
# profiles covering only the execution (excluding the setup/teardown) - those
# should be preferred for analysis since they more closely correspond to what's
# reported as B/op and alloc/op.
benchdiff --run=^BenchmarkSysbench/KV/3node/oltp_read_only$ --old=9d2a41d --new=f00b89c --memprofile ./pkg/sql/tests🔴 Sysbench [KV, 3node, oltp_write_only]
Reproducebenchdiff binaries: mkdir -p benchdiff/f00b89c/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/f00b89c2e50e1f6809d214d2957e6d5ec96f3da1/bin/pkg_sql_tests benchdiff/f00b89c/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/f00b89c/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
mkdir -p benchdiff/9d2a41d/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/9d2a41d63b95f4c84c58e4391c868f25d0c4b950/bin/pkg_sql_tests benchdiff/9d2a41d/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/9d2a41d/bin/1058449141/cockroachdb_cockroach_pkg_sql_testsbenchdiff command: # NB: for best (most stable) results, also add a suitable `--benchtime` that
# results in ~1s to ~5s of benchmark runs. For example, if ops average ~3ms, a
# benchtime of `1000x` is appropriate.
#
# Some benchmarks (in particular BenchmarkSysbench) output additional memory
# profiles covering only the execution (excluding the setup/teardown) - those
# should be preferred for analysis since they more closely correspond to what's
# reported as B/op and alloc/op.
benchdiff --run=^BenchmarkSysbench/KV/3node/oltp_write_only$ --old=9d2a41d --new=f00b89c --memprofile ./pkg/sql/testsArtifactsdownload: mkdir -p new
gcloud storage cp gs://cockroach-microbench-ci/artifacts/f00b89c2e50e1f6809d214d2957e6d5ec96f3da1/24057425385-2/\* new/
mkdir -p old
gcloud storage cp gs://cockroach-microbench-ci/artifacts/9d2a41d63b95f4c84c58e4391c868f25d0c4b950/24057425385-2/\* old/built with commit: f00b89c2e50e1f6809d214d2957e6d5ec96f3da1 |
ZhouXing19
left a comment
There was a problem hiding this comment.
LGTM, thanks for writing this up! Just one nit comment.
@ZhouXing19 reviewed 2 files and all commit messages, and made 2 comments.
Reviewable status:complete! 0 of 0 LGTMs obtained (waiting on ikristina and mw5h).
pkg/sql/logictest/testdata/logic_test/udf_regressions line 837 at r1 (raw file):
SELECT sc_62227.next_id_sql() ---- 2
nit: might worth adding a test case where we directly use the oid as the source of the cast. e.g.:
# The oid might change as the test evolve / under different configuration, thus we store it in a variable "seqoid".
let $seqoid
SELECT 'sc_62227.myseq'::REGCLASS::OID;
statement ok
CREATE OR REPLACE FUNCTION sc_62227.next_id()
RETURNS INT
LANGUAGE plpgsql
AS $$
DECLARE
v INT;
BEGIN
SELECT nextval($seqoid::REGCLASS) INTO v;
RETURN v;
END;
$$;
query TT
SHOW CREATE FUNCTION sc_62227.next_id;
----
f00b89c to
5a4fdf7
Compare
|
Thank you for updating your pull request. My owl senses detect your PR is good for review. Please keep an eye out for any test failures in CI. 🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is dev-inf. |
|
Hi, is there anything I can do to fix the failing pipeline? |
|
Hi @ikristina, try rebasing on master and pushing again. That should fix things. |
When building a UDF or view, maybeTrackRegclassDependenciesForViews evaluates any constant REGCLASS expression to record the referenced data source as a schema dependency. The previous implementation resolved the data source by converting the evaluated datum to a string via DOid.String(), then constructing an unqualified table name from it. The root cause is that ParseDOid stores only the bare object name in DOid.name when creating the datum (e.g. "myseq" instead of "sc.myseq"). The schema is used to resolve the OID correctly, but is then discarded from the name field. DOid.String() therefore returns only the bare object name, and constructing an unqualified table name from it fails when the object's schema is not in the search path — at CREATE FUNCTION time, not at call time. The fix bypasses the lossy name entirely by asserting the evaluated datum to *tree.DOid and calling ResolveDataSourceByID with the numeric OID directly, which is always correct regardless of schema. This bug affects both PL/pgSQL and SQL UDFs since both languages go through finishBuildScalar, which calls this function. The function is also refactored to use early returns instead of nested if blocks, reducing indentation depth. Resolves: cockroachdb#167057 Epic: CRDB-62227 Release note (bug fix): Fixed a bug where creating a PL/pgSQL or SQL user-defined function that references a schema-qualified sequence or table via a REGCLASS cast (e.g. nextval('sc.myseq'::REGCLASS)) would fail with "relation does not exist" at CREATE FUNCTION time when the object's schema was not in the search path.
5a4fdf7 to
f287c90
Compare
When building a UDF or view,
maybeTrackRegclassDependenciesForViewsevaluates any constantREGCLASSexpression to record the referenced data source as a schema dependency. The previous implementation resolved the data source by converting the evaluated datum to a string viaDOid.String(), then constructing an unqualified table name from it.The root cause is that
ParseDOidstores only the bare object name inDOid.name(pkg/sql/sem/eval/parse_doid.go:189-206) when creating the datum (e.g. "myseq" instead of "sc.myseq"). The schema is used to resolve theOIDcorrectly, but is then discarded from the name field.DOid.String()therefore returns only the bare object name, and constructing an unqualified table name from it fails when the object's schema is not in the search path - atCREATE FUNCTIONtime, not at call time.The fix bypasses the lossy name entirely by asserting the evaluated datum to
*tree.DOidand callingResolveDataSourceByIDwith the numericOIDdirectly, which is always correct regardless of schema. This bug affects bothPL/pgSQLandSQLUDFs since both languages go throughfinishBuildScalar, which calls this function.The function is also refactored to use early returns instead of nested
ifblocks, reducing indentation depth.Resolves: #167057
Epic: CRDB-62227
Release note (bug fix): Fixed a bug where creating a PL/pgSQL or SQL user-defined function that references a schema-qualified sequence or table via a REGCLASS cast (e.g.
nextval('sc.myseq'::REGCLASS)) would fail with "relation does not exist" at CREATE FUNCTION time when the object's schema was not in the search path.