Skip to content

Replace ExplodeExpression with a table function over an ExplodeValue - #4816

Open
g31pranjal wants to merge 31 commits into
mainfrom
apple/g31pranjal/unnested/explode-value
Open

g31pranjal wants to merge 31 commits into
mainfrom
apple/g31pranjal/unnested/explode-value

Conversation

@g31pranjal

@g31pranjal g31pranjal commented Nov 1, 2026 •

Copy link
Copy Markdown
Member

Replaces ExplodeExpression with a TableFunctionExpression over an ExplodeValue, so that every explode in the Cascades planner is a streaming value that produces an (element, ordinal) struct per element. Builds on #4819, which added ExplodeValue, InExplodeSource and their serialization.

Changes

  • ExplodeExpression and ImplementExplodeRule are removed. IN predicates, oneOfThem, fan-out key expressions, UnnestedRecordType expansion and SQL unnesting and VALUES all create a TableFunctionExpression(ExplodeValue). Elements are read with ExplodeValue.elementValue (_0), ordinals with ExplodeValue.ordinalValue (_1).
  • Order: an explode preserves its order only where the ordinal is read: UnnestedRecordType expansion and SQL AT. Any other explode may be reordered.
  • IN predicates: InComparisonToExplodeRule explodes only an IN over a value comparison whose element type is resolved. An IN over a literal list or a parameter stays a predicate.
  • IN-join and IN-union: the rules turn a quantifier over an explode into an InExplodeSource. A sorted source is the explode sorted(...), which is only possible for an explode that does not preserve its order, and only establishes the order of a value compared to the element itself.
  • Index matching: the expansion of a fan-out key expression pulls up the fields of the exploded element followed by the ordinal, so that a query's select over the same explode lines up with the candidate.
  • Compensation (as in Build a match candidate from an index defined on an unnested record type #4641): a match of several for-each quantifiers may still be used if only its result value needs compensation. This keeps covering plans over indexes on unnested record types, which match the whole join.

Plan hashes of plans with explodes change, and the expected plans, hashes and planner metrics in the tests and yaml-tests are updated accordingly.

@g31pranjal g31pranjal added the enhancement New feature or request label Nov 1, 2026
@g31pranjal
g31pranjal force-pushed the apple/g31pranjal/unnested/explode-value branch from 324d296 to ac94ca6 Compare November 1, 2026 23:47
@g31pranjal
g31pranjal changed the base branch from main to apple/g31pranjal/unnested/explode-value-serialization November 2, 2026 11:27
@g31pranjal
g31pranjal force-pushed the apple/g31pranjal/unnested/explode-value branch from ac94ca6 to fcf5662 Compare November 2, 2026 11:28
g31pranjal added a commit that referenced this pull request Nov 2, 2026
…essages (#4631)

Makes `MessageHelpers.deepCopyMessage()` match the fields of the source
and target descriptors by position rather than by field number.

## Problem

A record type read off a descriptor keeps the descriptor's field
numbers, which may skip, while a type built up field by field (e.g. by
`Type.maximumType()` for the element type of a multi-row `VALUES` list)
is numbered by position. Two descriptors of the same structure can
therefore number the same field differently, and a copy that matches
fields by number writes a value into the wrong field. For a table whose
proto is numbered `first_name=1, <2 skipped>, last_name=3, id=4`,
`last_name` ends up in `id`:

```
IllegalArgumentException: Wrong object type used with protocol message reflection.
Field number: 3, field java type: LONG, value type: java.lang.String
```

## Changes

- **`deepCopyMessage()`** matches fields by position. The target
descriptor may have additional trailing fields, such as the
pseudo-fields of a record type.
- Tests in `MessageHelperTests` cover nested records, enums, repeated
and nullable repeated records, and a target with pseudo-fields.

The defect is latent on `main`. It shows up once every explode wraps its
elements in a record constructor, as in #4816, where
`skipped-field-number-proto.yamsql` and `field-index-tests-proto.yamsql`
fail without this fix.
@g31pranjal
g31pranjal force-pushed the apple/g31pranjal/unnested/explode-value-serialization branch from c8f9e16 to c83eeb6 Compare November 2, 2026 17:43
@g31pranjal
g31pranjal force-pushed the apple/g31pranjal/unnested/explode-value branch from fcf5662 to 4189a88 Compare November 2, 2026 17:43
@g31pranjal
g31pranjal force-pushed the apple/g31pranjal/unnested/explode-value-serialization branch from c83eeb6 to c631a7f Compare November 3, 2026 15:35
@g31pranjal
g31pranjal force-pushed the apple/g31pranjal/unnested/explode-value branch from 4189a88 to 6dcaba7 Compare November 3, 2026 15:35
@g31pranjal
g31pranjal marked this pull request as ready for review November 3, 2026 16:09
@g31pranjal
g31pranjal force-pushed the apple/g31pranjal/unnested/explode-value branch from 6dcaba7 to 5c132ff Compare November 3, 2026 16:25
alecgrieser pushed a commit that referenced this pull request Nov 3, 2026
Registers `PushInJoinThroughFetchRule` for
`RecordQueryInComparandJoinPlan`, as it already is for
`RecordQueryInValuesJoinPlan` and `RecordQueryInParameterJoinPlan`. The
rule turns `InJoin(Fetch(inner))` into `Fetch(InJoin(inner))`.

SQL `IN` predicates are planned as in-joins over an `InComparandSource`,
so their plans can now run the in-join over a covering index scan and
fetch the records above it. For example, in
`join-with-order-by-tests.yamsql`:

```
before: [IN arrayDistinct(promote(@c21 AS ARRAY(LONG))) SORTED] | INJOIN q0 -> { ISCAN(t1$a1_a2 [EQUALS q0]) } | FLATMAP q1 -> { ... }
after:  [IN arrayDistinct(promote(@c21 AS ARRAY(LONG))) SORTED] | INJOIN q0 -> { COVERING(t1$a1_a2 [EQUALS q0] -> [a1: KEY:[0], a2: KEY:[1], id: KEY:[2]]) } | FETCH | FLATMAP q1 -> { ... }
```

## Plan changes

- `join-with-order-by-tests.yamsql` (4 queries) and
`join-tests-outer.yamsql:460`: the in-join runs over a covering index
scan, and the records are fetched above it.
- `join-tests.yamsql:399`: the join order flips, and the in-join over
`emp` now drives the lookup of `dept`. Both sides are primary-key
lookups.
- Planner metrics change in `array-join-at`, `in-predicate`,
`join-tests`, `join-tests-outer`, `join-with-order-by-tests`,
`right-deep-plan-tests` and `versions-tests`. No results change.
- `PreparedStatementTests.prepareInListOfTuple` asserted the order of
the rows of a query without `ORDER BY`, which changes with the new plan.
It now checks the set of rows, as #4816 does.

#4816 plans every IN predicate as an in-join over an `InExplodeSource`,
which is a comparand source, and registers this rule too. The changes it
lists as not yet accepted (`join-tests.yamsql:332`,
`join-tests-outer.yamsql:456` and `right-deep-plan-tests.yamsql:37`)
come from this rule.
@g31pranjal
g31pranjal force-pushed the apple/g31pranjal/unnested/explode-value branch from 6dbf12e to 6f6655b Compare November 4, 2026 11:48
@g31pranjal
g31pranjal force-pushed the apple/g31pranjal/unnested/explode-value-serialization branch from 633179c to cc0725d Compare November 5, 2026 00:25
@g31pranjal
g31pranjal force-pushed the apple/g31pranjal/unnested/explode-value branch 2 times, most recently from ab7ea75 to 3d877a9 Compare November 5, 2026 00:47
@g31pranjal
g31pranjal force-pushed the apple/g31pranjal/unnested/explode-value-serialization branch from 48fef87 to 1492507 Compare November 5, 2026 09:32
@g31pranjal
g31pranjal force-pushed the apple/g31pranjal/unnested/explode-value branch from 3d877a9 to 8277791 Compare November 5, 2026 09:32
@g31pranjal
g31pranjal force-pushed the apple/g31pranjal/unnested/explode-value-serialization branch from 1492507 to fee82ec Compare November 5, 2026 11:34
@g31pranjal
g31pranjal force-pushed the apple/g31pranjal/unnested/explode-value branch from 8277791 to 14b2dfe Compare November 5, 2026 11:34
g31pranjal added a commit that referenced this pull request Nov 5, 2026
Ports 37 `fdb-record-layer-core` record query tests to the yamsql suite
under `yaml-tests/src/test/resources/cascades-query-tests/`. A
trimmed-down version of #4588 holding only these tests.

These are the tests whose `IN` source (a `LiteralValue` list or a named
parameter) is no longer compatible with the Cascades run of the JUnit
test after #4816, so their Cascades coverage moves to SQL. The JUnit
tests stay in place, are marked with `// SQL Port status: (#4843) …`,
and skip the Cascades run via
`Assumptions.assumeFalse(useCascadesPlanner)` (`FDBInQueryTest`) or are
restricted to the old planner.

## What is in the PR

- 17 yamsql files (84 queries) plus the shared
`includes/simple-record-100.yamsql`, registered in `CascadesQueryTests`.
Metrics are generated for every file.
- `MIGRATION.md` (per-method state) and `README.md`, cut down to these
three classes.
- `SQL Port status` / `SQL Port` comments on all 37 JUnit tests.

## How the `IN` source is ported

| Core test uses | Port |
|---|---|
| literal list (`ListComparison`), or `ConstantObjectValue` | `IN (…)`
literal list. `AstNormalizer` lifts every literal into a
`ConstantObjectValue`, so both are the same SQL |
| named parameter (`ParameterComparison`, `equalsParameter`) | parameter
injection, `in !! !in {[…]} !!` / `= !! 0 !!`, in a separate test block
with `statement_type: prepared` (named `<file>-prepared`) |

Every query has its own test: nothing is shared between two tests, and
each `reverse` / `p` / `str_list` / ordering variant is its own query.
The remaining parameterizations (`InAsOrUnionMode`,
`omitPrimaryKeyInOrdering`, `replans`, `normalizeNestedFields`,
`attemptFailedInJoinAsUnionMaxSize`) are planner or old-planner settings
with no SQL surface and collapse. `LIMIT` is not supported in SQL, so
`testInWithLimit` pages with `maxRows: 3`. Where a variant needs its own
schema (`dropNumValue3Index`), it has its own file.

## The 37 tests

`qN` is the position among the executed queries in the file; the
`-prepared` block follows the literal one.

### `FDBInQueryTest` (31)

| Test | IN source in core | yamsql (queries) | State |
|---|---|---|---|
| `testInQueryNoIndex` | literal `(0, 2)`, residual filter | in-query q1
| ported |
| `testInQueryNoIndexWithParameter` | parameter `valuesThree`, residual
filter | in-query q10 (prepared) | ported |
| `testInQueryIndex` | literal `(1, 2, 4)`, forward and reverse |
in-query q2-q3 | ported |
| `testInQueryIndexSorted` | literal `(1, 4, 2)` (out of order), forward
and reverse | in-query q4-q5 | ported |
| `testInQueryCoveringIndex` | literal `(1, 2, 4)`, forward and reverse,
covering | in-query q6-q7 | ported |
| `testInQueryIndexSortedDifferently` | literal `(1, 4, 2)`, sorted on
another column, forward and reverse | in-query q8-q9 | ported |
| `testInQueryParameter` | parameter `valueThrees`, no sort | in-query
q11 (prepared) | ported |
| `testInQuerySortedByParameter` | parameter `valueThrees`, forward and
reverse | in-query q12-q13 (prepared) | ported |
| `testInQueryParameter2` | parameter `valueThrees` +
`equalsParameter("p")`, p = 0..4, forward and reverse |
in-query-multi-index q1-q10 (prepared) | ported |
| `testInQueryParameter2UsingCoveringIndexScans` | same, covering |
in-query-multi-index q11-q20 (prepared) | ported |
| `testInQueryParameterBad` | parameter bound to a non-list | none | not
portable: a SQL IN list is always a list |
| `testListInQuerySortedWithExtraUnorderedColumns` | literal `(1, 2,
4)`, forward and reverse | in-query-sorted-extra-unordered-columns q1-q2
| ported |
| `testParameterizedInQuerySortedWithExtraUnorderedColumns` | parameter
list + `equalsParameter`, forward and reverse |
in-query-sorted-extra-unordered-columns q3-q4 (prepared) | ported |
| `inQueryWithSortBySecondFieldOfCompoundIndex` | literal `(1, 4, 2)` |
in-query-compound-index q1 | ported |
| `inQueryWithSortAndRangePredicateOnSecondFieldOfCompoundIndex` |
literal `(1, 4, 2)` + range | in-query-compound-index q2 | ported |
| `inQueryWithSortAndParameter` | parameter `inList` + range |
in-query-compound-index q3 (prepared) | ported |
| `testInWithNesting` | literal, 4 strings, nested field |
in-query-header q1 | ported |
| `testMultipleInQueryIndex` | two literals (`rec_no`, `path`) |
in-query-header q2 | ported |
| `testMultipleInQueryIndexSorted` | two literals, index order requested
| in-query-header q3 | ported |
| `testInWithLimit` | literal `ls`, returned-row limit | in-query-header
q4 (`maxRows: 3`) | ported |
| `testInWithContinuation` | literal `ls`, continuations |
in-query-header q5 (`maxRows: 1`) | ported |
| `testInQueryOr` | literal `(903, 905, 901)` OR a range | in-query-or
q1 | ported |
| `testInQueryOrDifferentCondition` | literal `(2, 0)` OR a range,
residual filter | in-query-or q2 | ported |
| `testInQueryOrMultipleIndexes` | literal `(1, 3)` OR another index |
in-query-or q3 | ported |
| `testInUnionWithNonSargable` | literal `(1, 3, 5, 7, 9)`, residual
filter | in-query-or q4 | ported |
| `testInQueryEmptyList` | empty literal list | in-query-or q5
(prepared; `in ()` does not parse) | ported |
| `testInQueryOrOverlap` | two overlapping literals |
in-query-or-overlap q1 | ported |
| `testInQueryOrCompound` | literal `(1, 3)` in OR in AND |
in-query-or-compound q1 | ported |
| `testInUnionWithSomeSargable` | parameters `nv2_list`, `str_list` |
in-query-union-sargable q1-q3 (prepared) | ported |
| `testInUnionWithIntersectionOnTwoPredicates` | parameters `nv2_list`,
`str_list`; `dropNumValue3Index` changes the schema |
in-query-union-intersection q1-q3, in-query-union-intersection-no-nv3
q1-q3 (prepared) | ported |
| `enumIn` | literal list of enum values | none | deferred: needs
`CREATE TYPE AS ENUM` |

### `FDBPermutedMinMaxQueryTest` (4)

Each is parameterized over `InComparisonCase`: `byLiteral` and
`byConstantObjectValue` are the literal block, `byParameter` is the
`-prepared` block.

| Test | yamsql (queries) | State |
|---|---|---|
| `selectMaxWithInOrderByMax` | permuted-min-max q1-q3 literal, q4-q6
prepared | ported |
| `testMaxWithInAndDupes` | permuted-min-max-num-value-2 q1 literal, q2
prepared | ported |
| `testSortedMaxWithInOnRepeater` | permuted-min-max-repeater q1-q2
literal, q3-q4 prepared | ported |
| `testMaxUniqueByStr2And3WithDifferentOrderingKeys` |
permuted-min-max-ordering-keys q1-q4 literal, q5-q8 prepared (one per
ordering key) | ported |

### `FDBSimpleQueryGraphTest` (2)

| Test | IN source in core | yamsql (queries) | State |
|---|---|---|---|
| `testSimpleExistentialPredicateOnSimpleIndex` | parameter `t`;
`inComparison` flips `EQUALS` / `IN` | simple-query-graph-tag-index q1
(`=`), q2 (`IN`), prepared | ported |
| `testEqualityAndSimpleExistentialPredicate` | parameters on `name` and
`t` | simple-query-graph-name-tag-index q1 (prepared) | ported |

Totals: 35 ported, 1 not portable (`testInQueryParameterBad`), 1
deferred (`enumIn`).

## Notes

- Expectations are generated against current `main`, so plans carry the
covering-scan-plus-fetch shape from #4830.
- Plan-shape divergence from the JUnit plans: for the extra-columns
tests the in-union comparison key has three values instead of four, and
SQL always emits a `MAP` above a covering scan. This is documented in
the header of `in-query-sorted-extra-unordered-columns.yamsql`.
@g31pranjal
g31pranjal force-pushed the apple/g31pranjal/unnested/explode-value-serialization branch 2 times, most recently from 80ac3f9 to 30f79e7 Compare November 6, 2026 00:07
@g31pranjal
g31pranjal force-pushed the apple/g31pranjal/unnested/explode-value branch from 14b2dfe to 1f13218 Compare November 6, 2026 00:11
@g31pranjal
g31pranjal requested a review from normen662 November 6, 2026 23:10
The explains of the plain explodes now read `TF explode(..)` and navigate `_._0`, and the
planner metrics moved with them. The nested repeated exists query keeps its covering scan
expectation, as the plan it now gets is a regression to be fixed separately.
The in-join plans keep the shape they have on main, with the element read as `q0._0`.
…nsion

The explode quantifier now flows an (element) struct, so pulling up its flowed columns gave one
opaque column per level where a query's select over the same explodes flows the fields of each
element. The pulled-up query result then was a projection out of that pair and needed a result
compensation, which a join match cannot take, so the covering scan of an index over nested
repeated fields was lost. Pull up the element's fields instead, as before the explode flowed a
struct, and restore the planner metrics that the regression had changed.
The IN list of the left join over the null-supplying side is planned with the explode as the outer
side of the join with dept. The two orders tie on every cost tiebreaker, and the plan hash that
decides between them moved with the explode's representation.
…eir explode matchers

The ported FDBInQueryTest tests no longer run under Cascades, so their Cascades
assertions, and the matchers for literal and parameter explodes only they used,
are unreachable.
Only an IN over a value comparison is turned into an explode. The other INs stay
predicates, so the in-join and in-union rules need not special-case literal and
parameter collections.
Its only use was in a test that aborts before planning, so restore main's
inParameterJoinPlan there.
@g31pranjal
g31pranjal force-pushed the apple/g31pranjal/unnested/explode-value branch from fdb616e to 4aa5ec2 Compare November 10, 2026 16:17
@github-actions

Copy link
Copy Markdown

📊 Metrics Diff Analysis Report

Summary

  • New queries: 0
  • Dropped queries: 0
  • Plan changed + metrics changed: 11
  • Plan unchanged + metrics changed: 4
ℹ️ About this analysis

This automated analysis compares query planner metrics between the base branch and this PR. It categorizes changes into:

  • New queries: Queries added in this PR
  • Dropped queries: Queries removed in this PR. These should be reviewed to ensure we are not losing coverage.
  • Plan changed + metrics changed: The query plan has changed along with planner metrics.
  • Metrics only changed: Same plan but different metrics

The last category in particular may indicate planner regressions that should be investigated.

Plan and Metrics Changed

These queries experienced both plan and metrics changes. This generally indicates that there was some planner change
that means the planning for this query may be substantially different. Some amount of query plan metrics change is expected,
but the reviewer should still validate that these changes are not excessive.

Total: 11 queries

Statistical Summary (Plan and Metrics Changed)

task_count:

  • Average change: -5.0
  • Average regression: +7.7
  • Median change: -4
  • Median regression: +6
  • Standard deviation: 9.5
  • Standard deviation of regressions: 2.4
  • Range: -20 to +11
  • Range of regressions: +6 to +11
  • Queries changed: 11
  • Queries regressed: 3

task_count % change distribution (11 queries, bin = 2%):

     Range                                  n
----------  ------------------------------  ---
[-8%, -6%)  ████                            1
[-6%, -4%)                                  0
[-4%, -2%)                                  0
[-2%, +0%)  ██████████████████████████████  7
[+0%, +2%)  ████                            1
[+2%, +4%)                                  0
[+4%, +6%)  █████████                       2

transform_count:

  • Average change: -1.8
  • Average regression: +1.0
  • Median change: -2
  • Median regression: +1
  • Standard deviation: 1.6
  • Standard deviation of regressions: 0.0
  • Range: -5 to +1
  • Range of regressions: +1 to +1
  • Queries changed: 8
  • Queries regressed: 1

transform_count % change distribution (8 queries, bin = 2%):

     Range                                  n
----------  ------------------------------  ---
[-8%, -6%)  ███████████████████████         3
[-6%, -4%)                                  0
[-4%, -2%)                                  0
[-2%, +0%)  ██████████████████████████████  4
[+0%, +2%)  ████████                        1

transform_yield_count:

  • Average change: -1.0
  • Average regression: +1.0
  • Median change: -1
  • Median regression: +1
  • Standard deviation: 1.0
  • Standard deviation of regressions: 0.0
  • Range: -2 to +1
  • Range of regressions: +1 to +1
  • Queries changed: 6
  • Queries regressed: 1

transform_yield_count % change distribution (6 queries, bin = 2%):

       Range                                  n
------------  ------------------------------  ---
[-12%, -10%)  ████████                        1
 [-10%, -8%)                                  0
  [-8%, -6%)                                  0
  [-6%, -4%)                                  0
  [-4%, -2%)                                  0
  [-2%, +0%)  ██████████████████████████████  4
  [+0%, +2%)  ████████                        1

insert_new_count:

  • Average change: -0.9
  • Average regression: +1.0
  • Median change: -1
  • Median regression: +1
  • Standard deviation: 1.9
  • Standard deviation of regressions: 0.0
  • Range: -5 to +1
  • Range of regressions: +1 to +1
  • Queries changed: 8
  • Queries regressed: 3

insert_new_count % change distribution (8 queries, bin = 2%):

       Range                                  n
------------  ------------------------------  ---
[-20%, -18%)  ████████                        1
[-18%, -16%)                                  0
[-16%, -14%)                                  0
[-14%, -12%)                                  0
[-12%, -10%)                                  0
 [-10%, -8%)                                  0
  [-8%, -6%)                                  0
  [-6%, -4%)                                  0
  [-4%, -2%)                                  0
  [-2%, +0%)  ██████████████████████████████  4
  [+0%, +2%)  ████████                        1
  [+2%, +4%)                                  0
  [+4%, +6%)                                  0
  [+6%, +8%)                                  0
 [+8%, +10%)                                  0
[+10%, +12%)                                  0
[+12%, +14%)  ███████████████                 2

There were no queries with significant regressions detected.

Minor Changes (Plan and Metrics Changed)

In addition, there were 11 queries with minor changes.

Only Metrics Changed

These queries experienced only metrics changes without any plan changes. If these metrics have substantially changed,
then a planner change has been made which affects planner performance but does not correlate with any new outcomes,
which could indicate a regression.

Total: 4 queries

Statistical Summary (Only Metrics Changed)

task_count:

  • Average change: -173.8
  • Average regression: +11.0
  • Median change: +11
  • Median regression: +11
  • Standard deviation: 225.8
  • Standard deviation of regressions: 0.0
  • Range: -542 to +11
  • Range of regressions: +11 to +11
  • Queries changed: 4
  • Queries regressed: 2

task_count % change distribution (4 queries, bin = 2%):

       Range                                  n
------------  ------------------------------  ---
[-52%, -50%)  ███████████████                 1
[-50%, -48%)                                  0
[-48%, -46%)                                  0
[-46%, -44%)                                  0
[-44%, -42%)                                  0
[-42%, -40%)                                  0
[-40%, -38%)                                  0
[-38%, -36%)                                  0
[-36%, -34%)                                  0
[-34%, -32%)                                  0
[-32%, -30%)                                  0
[-30%, -28%)                                  0
[-28%, -26%)                                  0
[-26%, -24%)                                  0
[-24%, -22%)                                  0
[-22%, -20%)                                  0
[-20%, -18%)  ███████████████                 1
[-18%, -16%)                                  0
[-16%, -14%)                                  0
[-14%, -12%)                                  0
[-12%, -10%)                                  0
 [-10%, -8%)                                  0
  [-8%, -6%)                                  0
  [-6%, -4%)                                  0
  [-4%, -2%)                                  0
  [-2%, +0%)                                  0
  [+0%, +2%)  ██████████████████████████████  2

transform_count:

  • Average change: -52.3
  • Average regression: +1.0
  • Median change: +1
  • Median regression: +1
  • Standard deviation: 63.3
  • Standard deviation of regressions: 0.0
  • Range: -154 to +1
  • Range of regressions: +1 to +1
  • Queries changed: 4
  • Queries regressed: 2

transform_count % change distribution (4 queries, bin = 2%):

       Range                                  n
------------  ------------------------------  ---
[-56%, -54%)  ███████████████                 1
[-54%, -52%)                                  0
[-52%, -50%)                                  0
[-50%, -48%)                                  0
[-48%, -46%)                                  0
[-46%, -44%)                                  0
[-44%, -42%)                                  0
[-42%, -40%)                                  0
[-40%, -38%)                                  0
[-38%, -36%)                                  0
[-36%, -34%)                                  0
[-34%, -32%)                                  0
[-32%, -30%)                                  0
[-30%, -28%)                                  0
[-28%, -26%)                                  0
[-26%, -24%)                                  0
[-24%, -22%)                                  0
[-22%, -20%)                                  0
[-20%, -18%)                                  0
[-18%, -16%)  ███████████████                 1
[-16%, -14%)                                  0
[-14%, -12%)                                  0
[-12%, -10%)                                  0
 [-10%, -8%)                                  0
  [-8%, -6%)                                  0
  [-6%, -4%)                                  0
  [-4%, -2%)                                  0
  [-2%, +0%)                                  0
  [+0%, +2%)  ██████████████████████████████  2

transform_yield_count:

  • Average change: -25.5
  • Median change: -9
  • Standard deviation: 16.5
  • Range: -42 to -9
  • Queries changed: 2
  • No regressions! 🎉

insert_new_count:

  • Average change: -28.5
  • Average regression: +1.0
  • Median change: +1
  • Median regression: +1
  • Standard deviation: 39.4
  • Standard deviation of regressions: 0.0
  • Range: -95 to +1
  • Range of regressions: +1 to +1
  • Queries changed: 4
  • Queries regressed: 2

insert_new_count % change distribution (4 queries, bin = 2%):

       Range                                  n
------------  ------------------------------  ---
[-62%, -60%)  ███████████████                 1
[-60%, -58%)                                  0
[-58%, -56%)                                  0
[-56%, -54%)                                  0
[-54%, -52%)                                  0
[-52%, -50%)                                  0
[-50%, -48%)                                  0
[-48%, -46%)                                  0
[-46%, -44%)                                  0
[-44%, -42%)                                  0
[-42%, -40%)                                  0
[-40%, -38%)                                  0
[-38%, -36%)                                  0
[-36%, -34%)                                  0
[-34%, -32%)                                  0
[-32%, -30%)                                  0
[-30%, -28%)                                  0
[-28%, -26%)                                  0
[-26%, -24%)                                  0
[-24%, -22%)  ███████████████                 1
[-22%, -20%)                                  0
[-20%, -18%)                                  0
[-18%, -16%)                                  0
[-16%, -14%)                                  0
[-14%, -12%)                                  0
[-12%, -10%)                                  0
 [-10%, -8%)                                  0
  [-8%, -6%)                                  0
  [-6%, -4%)                                  0
  [-4%, -2%)                                  0
  [-2%, +0%)                                  0
  [+0%, +2%)  ██████████████████████████████  2

insert_reused_count:

  • Average change: -3.0
  • Median change: -3
  • Standard deviation: 0.0
  • Range: -3 to -3
  • Queries changed: 1
  • No regressions! 🎉

There were no queries with significant regressions detected.

Minor Changes (Only Metrics Changed)

In addition, there were 4 queries with minor changes.

This branch has not been deployed

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

Labels

DO NOT MERGE do not merge enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant