Commit d71571c
committed
fix: ResultSet SSO corruption + materializing-op caps + merge-agg schema check
Second batch of fixes from the codebase review. 1059/1096 tests pass
(0 failures, 37 skipped require Docker), 14 new tests added.
1. ResultSet.own_string: SSO use-after-free in owned_strings vector
This was the actual root cause of the garbled output the user observed
in the bare-metal benchmarks (SELECT * FROM users showing pointer-like
IDs and corrupted text columns). The diagnosis the agent gave -- about
line 711 in mysql_server.cpp -- was wrong; the real bug lives here.
owned_strings was std::vector<std::string>. own_string() emplace_back'd
a std::string and returned a StringRef pointing at the new entry's
c_str(). For short strings using SSO, the character data lives INSIDE
the std::string object itself, so when the vector reallocated and
move-constructed each std::string at a new heap address, every
previously-handed-out StringRef became a dangling pointer to freed
memory. Long strings happened to survive (their character buffer
stays at the same heap address through the move) but short strings
like "Alice", "Eng", "Sales" were silently corrupted.
Fix: switch to std::deque<std::string>. push_back on a deque does
not move existing elements, so element addresses (and thus c_str()
pointers) remain valid for the lifetime of the deque.
Verified: I temporarily reverted to std::vector<std::string> with the
new tests in place; the regression tests fail with corrupted data,
exactly matching the production symptom. Restored the deque fix and
the tests pass cleanly.
2. MergeAggregateOperator: validate per-row schema matches what
DistributedPlanner promised
The merge expected exactly [group_key_count] + [merge_op_count]
columns per partial-aggregate row. A schema drift between what the
planner built and what the shard returned would silently truncate or
misalign the merge, producing wrong aggregate results. Now we throw
a clear runtime_error on the first row that doesn't match.
3. Hard row caps on materializing operators (engine_limits.h)
Sort, Aggregate, HashJoin, NestedLoopJoin, Distinct, SetOp, Window
now cap their materialized state at kDefaultMaxOperatorRows
(10 million, overridable at compile time via SQL_ENGINE_MAX_OPERATOR_ROWS).
This converts a "process killed by OOM" failure into a clean
std::runtime_error with the offending operator name. Not a substitute
for spill-to-disk, but it stops a runaway query from taking down the
engine.
Verified-not-a-bug:
- Correlated subqueries: the agent claimed "scaffolding without wiring",
but PlanExecutor::setup_subquery_executor DOES wire the correlated
callback, expression_eval DOES pass the outer resolver through, and
filter_op/project_op DO consult outer_resolver_ on cache miss.
Existing CorrelatedSubqueryExists / Scalar / Avg tests already pass.
Added 2 new tests covering correlated NOT EXISTS and correlated IN
with arithmetic on outer columns -- both pass.
New tests:
- tests/test_result_set.cpp: 4 tests pinning down the deque invariant
for short strings, long strings, mixed sizes, and Value::str_val
round-trip after many subsequent push_backs.
- tests/test_operators.cpp: 3 MergeAggregate schema-validation tests
(matching schema, too few cols, too many cols) and 3 engine_limits
helper tests (throws at limit, allows below, error message).
- tests/test_subquery.cpp: 2 new correlated subquery tests
(NOT EXISTS, IN with outer column reference + arithmetic).1 parent 9982885 commit d71571c
14 files changed
Lines changed: 437 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
83 | | - | |
| 83 | + | |
| 84 | + | |
84 | 85 | | |
85 | 86 | | |
86 | 87 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
44 | 45 | | |
45 | 46 | | |
46 | 47 | | |
| 48 | + | |
| 49 | + | |
47 | 50 | | |
48 | 51 | | |
49 | 52 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
| |||
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
23 | 28 | | |
24 | 29 | | |
25 | 30 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
| |||
50 | 51 | | |
51 | 52 | | |
52 | 53 | | |
| 54 | + | |
53 | 55 | | |
| 56 | + | |
| 57 | + | |
54 | 58 | | |
55 | 59 | | |
| 60 | + | |
56 | 61 | | |
57 | 62 | | |
58 | 63 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
| |||
46 | 47 | | |
47 | 48 | | |
48 | 49 | | |
| 50 | + | |
| 51 | + | |
49 | 52 | | |
50 | 53 | | |
51 | 54 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | | - | |
| 14 | + | |
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| |||
169 | 169 | | |
170 | 170 | | |
171 | 171 | | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
172 | 181 | | |
173 | 182 | | |
174 | 183 | | |
| |||
189 | 198 | | |
190 | 199 | | |
191 | 200 | | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
192 | 221 | | |
193 | 222 | | |
194 | 223 | | |
| |||
214 | 243 | | |
215 | 244 | | |
216 | 245 | | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
217 | 249 | | |
218 | 250 | | |
219 | | - | |
220 | 251 | | |
221 | 252 | | |
222 | 253 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
46 | 47 | | |
47 | 48 | | |
48 | 49 | | |
| 50 | + | |
49 | 51 | | |
50 | 52 | | |
51 | 53 | | |
| |||
68 | 70 | | |
69 | 71 | | |
70 | 72 | | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
71 | 76 | | |
72 | 77 | | |
73 | 78 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
33 | 34 | | |
34 | 35 | | |
35 | 36 | | |
| 37 | + | |
| 38 | + | |
36 | 39 | | |
37 | 40 | | |
38 | 41 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
44 | 45 | | |
45 | 46 | | |
46 | 47 | | |
| 48 | + | |
47 | 49 | | |
48 | 50 | | |
49 | 51 | | |
| |||
0 commit comments