Skip to content

Commit

Permalink
opt: fix internal error when exploration uncovers null-rejection
Browse files Browse the repository at this point in the history
It is possible for exploration rules to reveal opportunities to
null-reject (simplify) an outer join that were not visible during
normalization. Previously, this would cause an internal error, since
it was assumed null-rejection would never be requested by an expression
that can prove the requested column is non-null. This patch removes the
assertion and instead removes any proven non-null columns from the
requested null-rejection column set. Note that this solution is
orthogonal to improving null-rejection during normalization - one
instance of this is tracked in cockroachdb#100564.

Fixes cockroachdb#100559

Release note (bug fix): Fixed a bug existing since before 22.1 that
could cause an internal error in rare cases for a query with outer joins
that can be simplified to non-outer joins and at least one semi-join.
  • Loading branch information
DrewKimball committed Apr 4, 2023
1 parent cc9e0c6 commit 0a41269
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 3 deletions.
7 changes: 4 additions & 3 deletions pkg/sql/opt/norm/reject_nulls_funcs.go
Expand Up @@ -214,9 +214,10 @@ func DeriveRejectNullCols(in memo.RelExpr, disabledRules intsets.Fast) opt.ColSe
relProps.Rule.RejectNullCols.UnionWith(deriveScanRejectNullCols(in))
}

if relProps.Rule.RejectNullCols.Intersects(relProps.NotNullCols) {
panic(errors.AssertionFailedf("null rejection requested on non-null column"))
}
// Don't attempt to request null-rejection for non-null cols. This can happen
// if normalization failed to null-reject, and then exploration "uncovered"
// the possibility for null-rejection of a column.
relProps.Rule.RejectNullCols.DifferenceWith(relProps.NotNullCols)

return relProps.Rule.RejectNullCols
}
Expand Down
57 changes: 57 additions & 0 deletions pkg/sql/opt/norm/testdata/rules/reject_nulls
Expand Up @@ -1691,3 +1691,60 @@ project
├── 0 [as="?column?":66]
├── '23:43:20-08:00:00' [as="?column?":67]
└── '2026-09-17 11:54:13.000946' [as=col_12038:68]

# Regression test for #100559 - don't panic when exploration uncovers possible
# null-rejection that normalization failed to find.
exec-ddl
CREATE TABLE t0_100559 (c0 INTERVAL);
----

exec-ddl
CREATE TABLE t1_100559 (c0 INTERVAL);
----

exec-ddl
CREATE TABLE t2_100559 (c0 FLOAT);
----

opt
SELECT t1_100559.c0 AS c0 FROM t0_100559, t2_100559
FULL OUTER JOIN t1_100559 ON true
WHERE (
((t0_100559.c0) IN (t1_100559.c0))
AND ((t2_100559.c0) IN (SELECT STDDEV(t2_100559.c0) FROM t2_100559))
);
----
project
├── columns: c0:9!null
└── inner-join (hash)
├── columns: t0_100559.c0:1!null t2_100559.c0:5!null t1_100559.c0:9!null
├── fd: (1)==(9), (9)==(1)
├── right-join (cross)
│ ├── columns: t2_100559.c0:5!null t1_100559.c0:9
│ ├── scan t1_100559
│ │ └── columns: t1_100559.c0:9
│ ├── semi-join (hash)
│ │ ├── columns: t2_100559.c0:5!null
│ │ ├── select
│ │ │ ├── columns: t2_100559.c0:5!null
│ │ │ ├── scan t2_100559
│ │ │ │ └── columns: t2_100559.c0:5
│ │ │ └── filters
│ │ │ └── t2_100559.c0:5 IS NOT NULL [outer=(5), constraints=(/5: (/NULL - ]; tight)]
│ │ ├── scalar-group-by
│ │ │ ├── columns: stddev:17
│ │ │ ├── cardinality: [1 - 1]
│ │ │ ├── key: ()
│ │ │ ├── fd: ()-->(17)
│ │ │ ├── scan t2_100559
│ │ │ │ └── columns: t2_100559.c0:13
│ │ │ └── aggregations
│ │ │ └── std-dev [as=stddev:17, outer=(13)]
│ │ │ └── t2_100559.c0:13
│ │ └── filters
│ │ └── t2_100559.c0:5 = stddev:17 [outer=(5,17), constraints=(/5: (/NULL - ]; /17: (/NULL - ]), fd=(5)==(17), (17)==(5)]
│ └── filters (true)
├── scan t0_100559
│ └── columns: t0_100559.c0:1
└── filters
└── t0_100559.c0:1 = t1_100559.c0:9 [outer=(1,9), constraints=(/1: (/NULL - ]; /9: (/NULL - ]), fd=(1)==(9), (9)==(1)]

0 comments on commit 0a41269

Please sign in to comment.