sql: support statement hint in routine body with SQL language#164365
sql: support statement hint in routine body with SQL language#164365ZhouXing19 wants to merge 1 commit intocockroachdb:masterfrom
Conversation
|
🚫 This pull request was requested to be canceled by @ZhouXing19, so it was removed from the merge queue. See more details here.
|
|
It looks like your PR touches production code but doesn't add or edit any test code. Did you consider adding tests to your PR? 🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is dev-inf. |
informs: cockroachdb#164365 This commit is to ensure statements within routines defined by SQL languagedo respect hint injections. Release note: TBD
dc68ee0 to
57c2c51
Compare
informs: cockroachdb#164365 This commit is to ensure statements within routines defined by SQL languagedo respect hint injections. Release note: TBD
6ed0315 to
23a4be2
Compare
informs: cockroachdb#164365 This commit is to ensure statements within routines defined by SQL languagedo respect hint injections. Note that the routines written in PLpgSQL language are not covered in this commit. Release note (bug fix): ensure statements within routines body defined by SQL languagedo respect hint injections.
23a4be2 to
1a98520
Compare
informs: cockroachdb#164365 This commit is to ensure statements within routines defined by SQL language respect hint injections. Note that the routines written in PLpgSQL language are not covered in this commit. Release note (bug fix): ensure statements within routines body defined by SQL language respect hint injections.
1a98520 to
a1b61f0
Compare
DrewKimball
left a comment
There was a problem hiding this comment.
@DrewKimball reviewed 7 files and all commit messages, and made 2 comments.
Reviewable status:complete! 0 of 0 LGTMs obtained (waiting on michae2 and ZhouXing19).
pkg/sql/opt/optbuilder/routine.go line 466 at r1 (raw file):
body[i] = stmtScope.expr bodyProps[i] = stmtScope.makePhysicalProps() bodyASTs[i] = maybeHintedStmt
I think this will cause statement stats to be recorded for the hinted AST fingerprint, which I'm not sure we want. At least, we don't do that for connExecutor-level SQL statements.
pkg/sql/opt_catalog.go line 490 at r1 (raw file):
return ast } stmtHints, hintIDs := hintCache.MaybeGetStatementHints(ctx, fingerprint, fmtFlags)
I think there's a problem here - the hint IDs need to be tracked on the opt.Metadata, or else (once I get the fix in #162057 merged) cached plans with routines will not be invalidated after a statement in the routine is hinted (or un-hinted). I think at least in the longer term we should:
- Change
Metadata.SetHintIDstoMetadata.AddHintIDs. - Instead of calling
SetHintIDsup at theconnExecutorlevel, call them in the optbuilder forbuildStmtAtRootWithScope, or some similar central location.
If we do that, every top-level statement will apply hints and also register the IDs of those hints with the metadata. Although, there might be some places where we don't want to apply hints, like formatting the body statements of a newly-created routine to be stored in the descriptor.
This might be a heavier lift than we need to just support routine statement hints, so if you see an easier way to solve this for now, feel free to go with that.
a1b61f0 to
f885c3c
Compare
informs: cockroachdb#164365 This commit is to ensure statements within routines defined by SQL language respect hint injections. Note that the routines written in PLpgSQL language are not covered in this commit. Release note (bug fix): ensure statements within routines body defined by SQL language respect hint injections.
|
Your pull request contains more than 1000 changes. It is strongly encouraged to split big PRs into smaller chunks. 🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is dev-inf. |
ZhouXing19
left a comment
There was a problem hiding this comment.
@ZhouXing19 made 2 comments.
Reviewable status:complete! 0 of 0 LGTMs obtained (waiting on DrewKimball and michae2).
pkg/sql/opt_catalog.go line 490 at r1 (raw file):
Previously, DrewKimball (Drew Kimball) wrote…
I think there's a problem here - the hint IDs need to be tracked on the
opt.Metadata, or else (once I get the fix in #162057 merged) cached plans with routines will not be invalidated after a statement in the routine is hinted (or un-hinted). I think at least in the longer term we should:
- Change
Metadata.SetHintIDstoMetadata.AddHintIDs.- Instead of calling
SetHintIDsup at theconnExecutorlevel, call them in the optbuilder forbuildStmtAtRootWithScope, or some similar central location.If we do that, every top-level statement will apply hints and also register the IDs of those hints with the metadata. Although, there might be some places where we don't want to apply hints, like formatting the body statements of a newly-created routine to be stored in the descriptor.
This might be a heavier lift than we need to just support routine statement hints, so if you see an easier way to solve this for now, feel free to go with that.
Added the second commit for the hint cache generation idea that was discussed offline.
pkg/sql/opt/optbuilder/routine.go line 466 at r1 (raw file):
Previously, DrewKimball (Drew Kimball) wrote…
I think this will cause statement stats to be recorded for the hinted AST fingerprint, which I'm not sure we want. At least, we don't do that for connExecutor-level SQL statements.
Reverted. Though I'm curious, should we record statement stats for the hinted AST somewhere in the future? It feels like useful...
informs: cockroachdb#164365 This commit is to ensure statements within routines defined by SQL language respect hint injections. Note that the routines written in PLpgSQL language are not covered in this commit. Release note (bug fix): ensure statements within routines body defined by SQL language respect hint injections.
f885c3c to
313bbdd
Compare
| // recorded generation stale, and the staleness check in | ||
| // CheckDependencies will invalidate the cached plan on the next | ||
| // execution. | ||
| b.factory.Metadata().SetHintCacheGeneration(b.evalCtx.Planner.GetHintCacheGeneration()) |
There was a problem hiding this comment.
I don't think loading the generation from the cache here is correct, since it could mean we get a later generation than the one for which hints were actually loaded. I think we should probably just use the same generation recorded in the DependencyDigest in the opt.Metadata.
There was a problem hiding this comment.
Hmm, I'm not sure if we want to reuse DependencyDigest.HintsGeneration. 3 reasons:
- When we're building the routine for the first time,
md.digest.depDigestis zeroed out -- the digest is only populated later, at the end of a successfulCheckDependencies. - Regarding the concern about getting "a later generation than the one for which hints were actually loaded": the ordering is, I think, actually the safe direction.
b.evalCtx.Planner.GetHintCacheGeneration()is called before the loop that callsTryRewriteWithStmtHints, so if the cache advances between the read and the hint loading, the recorded generation (N) is earlier than the hints actually used (from N+1). On the next stale check,current_gen (N+1) != recorded_gen (N) -> memo stale -> plan rebuilt. This is a conservative false positive (unnecessary invalidation), never a false negative (missed invalidation). - My understanding is that
depDigest.HintsGenerationandhintCacheGenerationInRoutinesactually serve independent purposes and are written at different stages. The former is a global cache generation snapshot, is written when checking the staleness of memo and used as a fast-path digest comparison that gates all further checks. The latter is written while building the routine.
I also considered if we should have a depDigest.HintsGenerationInRoutines rather than metadata.hintCacheGenerationInRoutines, but my concern is that seems like DependencyDigest is set in an atomic manner (?). So if we still want to set the generation for routines when building the memo, I doubt if it should live with the existing fields.
Sorry for the lengthy response and happy to change this if I'm missing something — just wanted to walk through the reasoning to make sure we're on the same page.
There was a problem hiding this comment.
Thanks for the explanation. I didn't consider (1) and (3) - those are good reasons to track the generation separately from the digest. WRT (2), I think it's still not correct because we could build multiple routines, in which case we might advance the stored generation after grabbing hints for a routine we built earlier. On way to solve this might be to store the hint cache generation unconditionally at the top level in connExecutor, and then only check it if there are >0 routine deps.
There was a problem hiding this comment.
Good point, I didn't think of the case where multiple routines being built in one statement. and storing the generation unconditionally at connExecutor makes sense to me.
313bbdd to
c8911e8
Compare
⚪ Sysbench [SQL, 3node, oltp_read_write]
Reproducebenchdiff binaries: mkdir -p benchdiff/c8911e8/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/c8911e8a814e27e3de5bdae1301e9cca65d8c3d8/bin/pkg_sql_tests benchdiff/c8911e8/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/c8911e8/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
mkdir -p benchdiff/e904df3/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/e904df395706e7e5941eb928130504fa0d5feda1/bin/pkg_sql_tests benchdiff/e904df3/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/e904df3/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=e904df3 --new=c8911e8 --memprofile ./pkg/sql/tests⚪ Sysbench [KV, 3node, oltp_read_only]
Reproducebenchdiff binaries: mkdir -p benchdiff/c8911e8/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/c8911e8a814e27e3de5bdae1301e9cca65d8c3d8/bin/pkg_sql_tests benchdiff/c8911e8/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/c8911e8/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
mkdir -p benchdiff/e904df3/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/e904df395706e7e5941eb928130504fa0d5feda1/bin/pkg_sql_tests benchdiff/e904df3/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/e904df3/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=e904df3 --new=c8911e8 --memprofile ./pkg/sql/tests🔴 Sysbench [KV, 3node, oltp_write_only]
Reproducebenchdiff binaries: mkdir -p benchdiff/c8911e8/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/c8911e8a814e27e3de5bdae1301e9cca65d8c3d8/bin/pkg_sql_tests benchdiff/c8911e8/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/c8911e8/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
mkdir -p benchdiff/e904df3/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/e904df395706e7e5941eb928130504fa0d5feda1/bin/pkg_sql_tests benchdiff/e904df3/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/e904df3/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=e904df3 --new=c8911e8 --memprofile ./pkg/sql/testsArtifactsdownload: mkdir -p new
gcloud storage cp gs://cockroach-microbench-ci/artifacts/c8911e8a814e27e3de5bdae1301e9cca65d8c3d8/22775235526-1/\* new/
mkdir -p old
gcloud storage cp gs://cockroach-microbench-ci/artifacts/e904df395706e7e5941eb928130504fa0d5feda1/22775235526-1/\* old/built with commit: c8911e8a814e27e3de5bdae1301e9cca65d8c3d8 |
|
Thanks for the heads up! I'll drop the second commit (hint cache generation invalidation) from this PR and just keep the first one (hint support in routine bodies). The cache invalidation logic depends on #162057 for meaningful testing — without routine plan caching, plans are always rebuilt, so there's nothing to invalidate. I'll put it up as a separate PR once #162057 lands. |
informs: cockroachdb#164365 This commit is to ensure statements within routines defined by SQL language respect hint injections. Note that the routines written in PLpgSQL language are not covered in this commit. Release note (bug fix): ensure statements within routines body defined by SQL language respect hint injections.
c8911e8 to
f18f3fc
Compare
DrewKimball
left a comment
There was a problem hiding this comment.
@DrewKimball reviewed 16 files and all commit messages, and made 1 comment.
Reviewable status:complete! 1 of 0 LGTMs obtained (waiting on michae2 and ZhouXing19).
⚪ Sysbench [SQL, 3node, oltp_read_write]
Reproducebenchdiff binaries: mkdir -p benchdiff/f18f3fc/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/f18f3fc6ce446eefee2e0bfac50960d7bc2b291c/bin/pkg_sql_tests benchdiff/f18f3fc/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/f18f3fc/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
mkdir -p benchdiff/748defa/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/748defa603da84ae946cc7b8e16222cc404ff44e/bin/pkg_sql_tests benchdiff/748defa/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/748defa/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=748defa --new=f18f3fc --memprofile ./pkg/sql/tests⚪ Sysbench [KV, 3node, oltp_read_only]
Reproducebenchdiff binaries: mkdir -p benchdiff/f18f3fc/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/f18f3fc6ce446eefee2e0bfac50960d7bc2b291c/bin/pkg_sql_tests benchdiff/f18f3fc/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/f18f3fc/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
mkdir -p benchdiff/748defa/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/748defa603da84ae946cc7b8e16222cc404ff44e/bin/pkg_sql_tests benchdiff/748defa/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/748defa/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=748defa --new=f18f3fc --memprofile ./pkg/sql/tests⚪ Sysbench [KV, 3node, oltp_write_only]
Reproducebenchdiff binaries: mkdir -p benchdiff/f18f3fc/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/f18f3fc6ce446eefee2e0bfac50960d7bc2b291c/bin/pkg_sql_tests benchdiff/f18f3fc/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/f18f3fc/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
mkdir -p benchdiff/748defa/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/748defa603da84ae946cc7b8e16222cc404ff44e/bin/pkg_sql_tests benchdiff/748defa/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/748defa/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=748defa --new=f18f3fc --memprofile ./pkg/sql/testsArtifactsdownload: mkdir -p new
gcloud storage cp gs://cockroach-microbench-ci/artifacts/f18f3fc6ce446eefee2e0bfac50960d7bc2b291c/22783039261-1/\* new/
mkdir -p old
gcloud storage cp gs://cockroach-microbench-ci/artifacts/748defa603da84ae946cc7b8e16222cc404ff44e/22783039261-1/\* old/built with commit: f18f3fc6ce446eefee2e0bfac50960d7bc2b291c |
informs: cockroachdb#164365 This commit is to ensure statements within routines defined by SQL language respect hint injections. Note that the routines written in PLpgSQL language are not covered in this commit. Release note (bug fix): ensure statements within routines body defined by SQL language respect hint injections.
f18f3fc to
01f2702
Compare
⚪ Sysbench [SQL, 3node, oltp_read_write]
Reproducebenchdiff binaries: mkdir -p benchdiff/01f2702/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/01f2702e3c9a64013ea3e210c9741418c67f6aec/bin/pkg_sql_tests benchdiff/01f2702/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/01f2702/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
mkdir -p benchdiff/7ca1f2b/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/7ca1f2bf5201bf4d60844ff404a9eb788296179d/bin/pkg_sql_tests benchdiff/7ca1f2b/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/7ca1f2b/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=7ca1f2b --new=01f2702 --memprofile ./pkg/sql/tests⚪ Sysbench [KV, 3node, oltp_read_only]
Reproducebenchdiff binaries: mkdir -p benchdiff/01f2702/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/01f2702e3c9a64013ea3e210c9741418c67f6aec/bin/pkg_sql_tests benchdiff/01f2702/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/01f2702/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
mkdir -p benchdiff/7ca1f2b/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/7ca1f2bf5201bf4d60844ff404a9eb788296179d/bin/pkg_sql_tests benchdiff/7ca1f2b/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/7ca1f2b/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=7ca1f2b --new=01f2702 --memprofile ./pkg/sql/tests⚪ Sysbench [KV, 3node, oltp_write_only]
Reproducebenchdiff binaries: mkdir -p benchdiff/01f2702/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/01f2702e3c9a64013ea3e210c9741418c67f6aec/bin/pkg_sql_tests benchdiff/01f2702/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/01f2702/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
mkdir -p benchdiff/7ca1f2b/bin/1058449141
gcloud storage cp gs://cockroach-microbench-ci/builds/7ca1f2bf5201bf4d60844ff404a9eb788296179d/bin/pkg_sql_tests benchdiff/7ca1f2b/bin/1058449141/cockroachdb_cockroach_pkg_sql_tests
chmod +x benchdiff/7ca1f2b/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=7ca1f2b --new=01f2702 --memprofile ./pkg/sql/testsArtifactsdownload: mkdir -p new
gcloud storage cp gs://cockroach-microbench-ci/artifacts/01f2702e3c9a64013ea3e210c9741418c67f6aec/22784728158-1/\* new/
mkdir -p old
gcloud storage cp gs://cockroach-microbench-ci/artifacts/7ca1f2bf5201bf4d60844ff404a9eb788296179d/22784728158-1/\* old/built with commit: 01f2702e3c9a64013ea3e210c9741418c67f6aec |
|
TFTR! /trunk merge |
michae2
left a comment
There was a problem hiding this comment.
Nice job! But there's a problem.
@michae2 reviewed 7 files and all commit messages, and made 3 comments.
Reviewable status:complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on DrewKimball and ZhouXing19).
pkg/sql/opt/optbuilder/routine.go line 457 at r13 (raw file):
hintStmtFingerprint := tree.FormatStatementHideConstants(stmts[i].AST, fmtFlags) maybeHintedStmt := b.catalog.TryRewriteWithStmtHints(b.ctx, hintStmtFingerprint, stmts[i].AST, fmtFlags) stmtScope := b.buildStmtAtRootWithScope(maybeHintedStmt, nil /* desiredTypes */, bodyScope)
There's a problem here: we need to be able to fall back to the original AST if we get an error during optimization of the rewritten AST. This is because we can't guarantee the hint will always be satisfied by the optimizer.
The normal code path does this in two places in plan_opt, where it tries optimizing twice, once with the rewritten AST and once with the original AST if the rewritten AST didn't work. Here's one of those spots (notice the two calls to makeOptimizerPlanInternal):
Lines 293 to 318 in 7ca1f2b
For routines, I'm not quite sure where we call Optimize(), but we might need to build two stmtScopes here... or change this field to a closure that we could invoke again if the call to Optimize() failed.
pkg/sql/opt/optbuilder/routine.go line 472 at r13 (raw file):
bodyTags[i] = "" } else { bodyTags[i] = maybeHintedStmt.StatementTag()
nit: I would continue to use the tag from the original AST (this is also what conn executor does).
|
/trunk cancel |
DrewKimball
left a comment
There was a problem hiding this comment.
@DrewKimball made 1 comment.
Reviewable status:complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on michae2 and ZhouXing19).
pkg/sql/opt/optbuilder/routine.go line 457 at r13 (raw file):
Previously, michae2 (Michael Erickson) wrote…
There's a problem here: we need to be able to fall back to the original AST if we get an error during optimization of the rewritten AST. This is because we can't guarantee the hint will always be satisfied by the optimizer.
The normal code path does this in two places in plan_opt, where it tries optimizing twice, once with the rewritten AST and once with the original AST if the rewritten AST didn't work. Here's one of those spots (notice the two calls to makeOptimizerPlanInternal):
Lines 293 to 318 in 7ca1f2b
For routines, I'm not quite sure where we call Optimize(), but we might need to build two stmtScopes here... or change this field to a closure that we could invoke again if the call to Optimize() failed.
Hm, that's tricky. Optimize() could happen when the main query is optimized if the routine is inlined, or else it'll happen during execution when the routine is called with concrete arguments supplied. So maybe we need to:
- Disable inlining if there are hints (oof), and:
- store both the hinted and unhinted built+normalized body statement so that when planning the body statement we can fall back to the original if there's an error.
|
[notes from project meeting]
|
|
[weekly meeting]
|
Extract the body-building loop from buildRoutine into a separate buildSQLRoutineBodyStmts method. This is a pure refactor with no behavioral change; it prepares for a follow-up that defers SQL routine body building from plan time to execution time, where this method will be called from a different code path. Informs cockroachdb#164365 Release note: None Co-Authored-By: roachdev-claude <roachdev-claude-bot@cockroachlabs.com>
Extract the body-building loop from buildRoutine into a separate buildSQLRoutineBodyStmts method. This is a pure refactor with no behavioral change; it prepares for a follow-up that defers SQL routine body building from plan time to execution time, where this method will be called from a different code path. Informs cockroachdb#164365 Release note: None Co-Authored-By: roachdev-claude <roachdev-claude-bot@cockroachlabs.com>
Extract the body-building loop from buildRoutine into a separate buildSQLRoutineBodyStmts method. This is a pure refactor with no behavioral change; it prepares for a follow-up that defers SQL routine body building from plan time to execution time, where this method will be called from a different code path. Informs cockroachdb#164365 Release note: None Co-Authored-By: roachdev-claude <roachdev-claude-bot@cockroachlabs.com>
informs: #162627
This commit is to ensure statements within routines defined by SQL
language respect hint injections.
Note that the routines written in PLpgSQL language are not covered in
this commit.
Release note (bug fix): ensure statements within routines body defined by SQL
language respect hint injections.