Skip to content

fix: rebind prepared numeric runtime types - #27466

Draft
ck89119 wants to merge 14 commits into
matrixorigin:mainfrom
ck89119:issue-25408-runtime-main
Draft

fix: rebind prepared numeric runtime types#27466
ck89119 wants to merge 14 commits into
matrixorigin:mainfrom
ck89119:issue-25408-runtime-main

Conversation

@ck89119

@ck89119 ck89119 commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

What type of PR is this?

  • API-change
  • BUG
  • Improvement
  • Documentation
  • Feature
  • Test and CI
  • Code Refactoring

Which issue(s) this PR fixes:

issue #25408

What this PR does / why we need it:

This is the second of three scoped changes for prepared runtime parameter handling. PR #27329 fixed only LIMIT/OFFSET; this PR fixes runtime numeric rebinding and producer-to-consumer type lineage. Type-signature compile-cache reuse remains a separate follow-up.

Previously, SQL EXECUTE ... USING did not pass user-variable runtime types into the specialization path used by COM_STMT. Even when an immediate numeric expression was rebound, derived tables, set operations, aggregates, windows, scalar subqueries, DML consumers, and CTAS schemas could retain the prepare-time physical type. That caused invalid casts, wrong overloads, stale vector layouts, panics, and incorrect persisted values.

This change:

  • preserves the runtime type, width, and scale of SQL-level execute parameters and runs text and binary executions through the same isolated specialization path;
  • refreshes logical and physical type lineage across projections, derived tables, set operations, aggregates, windows, scalar subqueries, DML consumers, and CTAS schemas;
  • restores planner-generated numeric coercions before rebinding nested expressions while keeping explicit SQL casts and assignment casts as semantic boundaries;
  • evaluates string-backed values in numeric consumers through the approximate DOUBLE domain, while keeping string predicates such as concat(v, '') = ? in the string domain;
  • keeps the cached canonical prepared plan immutable so values from one execution cannot freeze unrelated parameters in later executions.

Regression coverage includes SQL PREPARE and COM_STMT, integer/unsigned/DECIMAL/FLOAT/DOUBLE/BOOL/string domains, 65-digit integers, 30-digit decimals, scientific notation and underflow, nested expressions, derived tables, UNION, aggregate/window/scalar-subquery consumers, DISTINCT aggregates, UPDATE/DELETE, BIT assignment provenance, explicit casts, REGEXP direction, and CTAS value/schema consistency.

Validation:

  • mo-cgo-test ./pkg/sql/plan -count=1
  • mo-cgo-test ./pkg/frontend -count=1
  • mo-cgo-test ./pkg/tests/issues -run '^TestIssue25408PreparedRuntimeNumericRebind$' -count=1
  • golangci-lint run -c .golangci.yml ./pkg/sql/plan ./pkg/frontend ./pkg/tests/issues (0 issues)

@ck89119

ck89119 commented Aug 23, 2026

Copy link
Copy Markdown
Contributor Author

Dependency and combined-path acceptance after PR #27483:

PR #27483 should land first because it owns the DECIMAL common-domain behavior and overlaps with this PR in base_binder.go, visit_plan_rule.go, utils.go, constant_fold.go, and computation_wrapper.go. After it lands, merge the resulting main into this branch and reuse that common-domain decision instead of retaining an independent exact-predicate whitelist.

The combined #27483 + #27466 head must validate this SQL PREPARE regression:

CREATE TABLE t (
  id INT PRIMARY KEY,
  d DECIMAL(20,4)
);
INSERT INTO t VALUES
  (1, 9007199254740992.0000),
  (2, 9007199254740992.0001),
  (3, 9007199254740993.0000);

PREPARE q FROM 'SELECT id FROM t WHERE d BETWEEN ? AND ? ORDER BY id';
SET @lo = '9007199254740992.0001';
SET @hi = '9007199254740992.0001';
EXECUTE q USING @lo, @hi;

Expected: 2.

On current PR #27466 head 1181297077afd7fb9de428a54e5cf8bbe1759add, this returns 1,2,3 because BETWEEN is excluded from the fixed-exact predicate classification and the string bounds are converted through FLOAT64. The same witness returned 2 on base 6ff9be9646a6ac43e05ba3063de27b2248bbac62.

This is intentionally an acceptance requirement for PR #27466 after merging #27483, not additional scope for PR #27483.

The exact BIGINT UNSIGNED / BIT(64) prepared-comparison work owned by this PR is tracked separately in #27492.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/bug Something isn't working kind/test-ci size/XXL Denotes a PR that changes 2000+ lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants