Skip to content

sql/opt: unbounded constant folding of string || during planning can OOM #173720

Description

@yuzefovich

Describe the problem

Constant folding of string || (concat) during normalization has no size cap.
EvalConcatOp / EvalConcatStringOp perform a bare concat, and the folded
datum is interned unconditionally with no limit. While each repeat() operand
is capped at 128 MiB, the || that combines them is not, so chaining a handful
of compact repeat() calls folds — at planning time — to an arbitrarily large
interned string (plus left-fold intermediates) on the plain Go heap, which is
not covered by --max-sql-memory.

Because repeat('x', 100000000) expresses a 100 MB operand in ~26 bytes of SQL,
the SQL text needed to OOM is tiny. EXPLAIN alone triggers it (no execution);
wrapping in length(...) keeps the giant value out of the result set but the
folder still materializes it.

To Reproduce

On a node limited to ~2GB (e.g. cockroach demo under a 2GB cgroup, or with
GOMEMLIMIT=1100000000 --max-sql-memory=512MiB --cache=512MiB), run this
171-byte statement:

EXPLAIN SELECT length(
  repeat('x',100000000) || repeat('x',100000000) || repeat('x',100000000) ||
  repeat('x',100000000) || repeat('x',100000000) || repeat('x',100000000));

The folded constant is O(N × 128 MiB) for N operands while the SQL is
O(N × ~26 bytes).

Observed

  • 3 operands: completes, ~1.4GB peak RSS.
  • 6 operands (171 bytes of SQL): heap grows past 2GB, OOM-killed during
    EXPLAIN within a few seconds.

Environment

  • CockroachDB v26.4.0-alpha (master), CCL, cockroach demo single node.
  • Client: cockroach sql.

Code reference

EvalConcatOp / EvalConcatStringOp in pkg/sql/sem/eval/binary_op.go;
folding gated by canFoldOperator and interned by ConstructConstVal in
pkg/sql/opt/norm/fold_constants_funcs.go.

Jira issue: CRDB-67027

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-sql-optimizerSQL logical planning and optimizations.C-bugCode not up to spec/doc, specs & docs deemed correct. Solution expected to change code/behavior.O-agentFiled by an AI agent; usually the result of a human/agent investigation sessionT-sql-queriesSQL Queries Teambranch-masterFailures and bugs on the master branch.

    Type

    No type

    Projects

    Status
    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions