Skip to content

Commit b2513c6

Browse files
committed
sql: use metamorphic defaults for optimizer testing knobs in logictest
Wire testing_optimizer_cost_perturbation and testing_optimizer_disable_rule_probability into logictest via metamorphic constants, matching other logictest fuzzing knobs and the settings used by costfuzz and unoptimized-query-oracle. Metamorphic values are opt-in via COCKROACH_LOGIC_TEST_OPTIMIZER_METAMORPHIC so normal CI logictest runs keep deterministic query plans. Execbuilder and SQLite logic tests disable perturbations via TestServerArgs. Implementation notes: - metamorphicDisableOptRuleProbability: choices {0, 0.5, 1.0} - metamorphicOptimizerCostPerturbation: choices {0, 0.1, 1.0}, where 0.1 mirrors the mild-perturbation range used by costfuzz and 1.0 stress-tests extreme plan changes. - DisableOptimizerPerturbations is emitted by the generate-logictest template only when ForceProductionValues is absent; all execbuilder configs already set ForceProductionValues which short-circuits the knob helper to (0, 0), making the field redundant there. - The `if disableProb == 0` guard preserves explicit non-zero CLI flag values; a comment documents the edge case where the metamorphic constant itself picks 0 (no-op assignment). To exercise locally: COCKROACH_LOGIC_TEST_OPTIMIZER_METAMORPHIC=true \ ./dev test pkg/sql/logictest/tests/local -f TestLogic_select Fixes #93825 Release note: None
1 parent b852382 commit b2513c6

21 files changed

Lines changed: 99 additions & 24 deletions

File tree

pkg/cmd/generate-logictest/templates.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ func runExecBuildLogicTest(t *testing.T, file string) {
4242
ForceProductionValues: true,{{end}}
4343
// Disable the direct scans in order to keep the output of EXPLAIN (VEC)
4444
// deterministic.
45-
DisableDirectColumnarScans: true,
45+
DisableDirectColumnarScans: true,{{ if not .ForceProductionValues }}
46+
// ForceProductionValues is not set for this config, so we must
47+
// explicitly disable optimizer perturbations to keep EXPLAIN output
48+
// deterministic when COCKROACH_LOGIC_TEST_OPTIMIZER_METAMORPHIC is set.
49+
DisableOptimizerPerturbations: true,{{end}}
4650
}
4751
logictest.RunLogicTest(t, serverArgs, configIdx, filepath.Join(execBuildLogicTestDir, file))
4852
}
@@ -65,7 +69,8 @@ func runSqliteLogicTest(t *testing.T, file string) {
6569
DisableUseMVCCRangeTombstonesForPointDeletes: true,
6670
// Some sqlite tests with very low bytes limit value are too slow, so
6771
// ensure 3 KiB lower bound.
68-
BatchBytesLimitLowerBound: 3 << 10, // 3 KiB
72+
BatchBytesLimitLowerBound: 3 << 10, // 3 KiB
73+
DisableOptimizerPerturbations: true,
6974
}
7075
logictest.RunLogicTest(t, serverArgs, configIdx, filepath.Join(sqliteLogicTestDir, file))
7176
}
@@ -188,7 +193,8 @@ func TestLogic_tmp(t *testing.T) {
188193
{{- if .ExecBuildLogicTest }}
189194
glob = filepath.Join(execBuildLogicTestDir, "_*")
190195
serverArgs := logictest.TestServerArgs{
191-
DisableWorkmemRandomization: true,
196+
DisableWorkmemRandomization: true,
197+
DisableOptimizerPerturbations: true,
192198
}
193199
logictest.RunLogicTests(t, serverArgs, configIdx, glob)
194200
{{- end }}

pkg/sql/logictest/logic.go

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,24 @@ var (
600600
)
601601
sqlfmtLen = flag.Int("line-length", tree.DefaultPrettyCfg().LineWidth,
602602
"target line length when using -rewrite-sql")
603+
604+
// metamorphicDisableOptRuleProbability and metamorphicOptimizerCostPerturbation
605+
// mirror the testing_optimizer_cost_perturbation and
606+
// testing_optimizer_disable_rule_probability session settings used by costfuzz and
607+
// unoptimized-query-oracle. They are only applied when
608+
// COCKROACH_LOGIC_TEST_OPTIMIZER_METAMORPHIC=true so that logictest files with
609+
// fixed query plans are not perturbed during normal CI runs.
610+
metamorphicDisableOptRuleProbability = metamorphic.ConstantWithTestChoice(
611+
"logictest-disable-opt-rule-probability", float64(0), float64(0.5), float64(1.0))
612+
// metamorphicOptimizerCostPerturbation mirrors the range used by costfuzz
613+
// (see testing_optimizer_cost_perturbation). 0.1 exercises mild plan
614+
// variation while 1.0 stress-tests extreme perturbations.
615+
metamorphicOptimizerCostPerturbation = metamorphic.ConstantWithTestChoice(
616+
"logictest-optimizer-cost-perturbation", float64(0), float64(0.1), float64(1.0))
617+
618+
logicTestOptimizerMetamorphicEnabled = envutil.EnvOrDefaultBool(
619+
"COCKROACH_LOGIC_TEST_OPTIMIZER_METAMORPHIC", false)
620+
603621
disableOptRuleProbability = flag.Float64(
604622
"disable-opt-rule-probability", 0,
605623
"disable transformation rules in the cost-based optimizer with the given probability.")
@@ -1638,12 +1656,15 @@ func (t *logicTest) newCluster(
16381656
return st
16391657
}
16401658
setSQLTestingKnobs := func(knobs *base.TestingKnobs) {
1659+
disableProb, costPerturb := optimizerTestingKnobValues(
1660+
serverArgs, *disableOptRuleProbability, *optimizerCostPerturbation,
1661+
)
16411662
knobs.SQLEvalContext = &eval.TestingKnobs{
16421663
AssertBinaryExprReturnTypes: true,
16431664
AssertUnaryExprReturnTypes: true,
16441665
AssertFuncExprReturnTypes: true,
1645-
DisableOptimizerRuleProbability: *disableOptRuleProbability,
1646-
OptimizerCostPerturbation: *optimizerCostPerturbation,
1666+
DisableOptimizerRuleProbability: disableProb,
1667+
OptimizerCostPerturbation: costPerturb,
16471668
ForceProductionValues: serverArgs.ForceProductionValues,
16481669
UnsafeOverride: func() *bool {
16491670
v := t.allowUnsafe.Load()
@@ -4850,6 +4871,35 @@ type TestServerArgs struct {
48504871
BatchBytesLimitLowerBound int64
48514872
// If set, sql.distsql.direct_columnar_scans.enabled is set to false.
48524873
DisableDirectColumnarScans bool
4874+
// If set, testing optimizer perturbation knobs are forced to 0. This is
4875+
// needed for tests with fixed query plans in expected output (e.g. EXPLAIN
4876+
// tests and SQLite logic tests).
4877+
DisableOptimizerPerturbations bool
4878+
}
4879+
4880+
func optimizerTestingKnobValues(
4881+
serverArgs TestServerArgs, disableFlag, costFlag float64,
4882+
) (disableProb, costPerturb float64) {
4883+
disableProb = disableFlag
4884+
costPerturb = costFlag
4885+
if serverArgs.ForceProductionValues || serverArgs.DisableOptimizerPerturbations {
4886+
return 0, 0
4887+
}
4888+
if logicTestOptimizerMetamorphicEnabled {
4889+
// Only apply the metamorphic constant when no explicit non-zero value
4890+
// was passed via the command-line flag. This lets callers override the
4891+
// metamorphic behaviour (e.g. -disable-opt-rule-probability=0.3) while
4892+
// still getting metamorphic defaults in unattended runs. Note: the
4893+
// metamorphic constant itself may be 0 (one of its valid choices), in
4894+
// which case the assignment is a no-op.
4895+
if disableProb == 0 {
4896+
disableProb = metamorphicDisableOptRuleProbability
4897+
}
4898+
if costPerturb == 0 {
4899+
costPerturb = metamorphicOptimizerCostPerturbation
4900+
}
4901+
}
4902+
return disableProb, costPerturb
48534903
}
48544904

48554905
// RunLogicTests runs logic tests for all files matching the given glob.

pkg/sql/opt/exec/execbuilder/tests/3node-tenant-multiregion/generated_test.go

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/sql/opt/exec/execbuilder/tests/3node-tenant/generated_test.go

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/sql/opt/exec/execbuilder/tests/5node/generated_test.go

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/sql/opt/exec/execbuilder/tests/local-read-committed/generated_test.go

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/sql/opt/exec/execbuilder/tests/local/generated_test.go

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/sql/opt/exec/execbuilder/tests/multiregion-9node-3region-3azs/generated_test.go

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/sql/sqlitelogictest/tests/3node-tenant/generated_test.go

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/sql/sqlitelogictest/tests/fakedist-disk/generated_test.go

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)