Skip to content

Commit f51a6aa

Browse files
craig[bot]yuzefovichpaulniziolek
committed
148696: logictest: skip upsert_non_metamorphic under race r=yuzefovich a=yuzefovich This test runs a large mutation (6MB in size), and we've seen a couple overload-related failures under race, so let's skip it in that config. Fixes: #148648. Release note: None 148763: opt: normalize non-null x LIKE '%' to true r=michae2 a=paulniziolek #### opt: normalize non-null x LIKE '%' to true This commit adds the NormalizeLikeAny normalization rule, which normalizes `x LIKE '%'` to true when x is non-null. Epic: None Fixes: #144523 Release note (performance improvement): LIKE expressions of the form `x LIKE '%'` are normalized to true if x is non-Null. Co-authored-by: Yahor Yuzefovich <[email protected]> Co-authored-by: Paul Niziolek <[email protected]>
3 parents 263b677 + 551ad63 + 0c848d6 commit f51a6aa

File tree

5 files changed

+92
-28
lines changed

5 files changed

+92
-28
lines changed

pkg/sql/logictest/testdata/logic_test/upsert_non_metamorphic

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# LogicTest: !metamorphic-batch-sizes
22

3+
skip under race
4+
35
# Regression test for UPSERT batching logic not respecting footprint-based
46
# limiting (#102472).
57
statement ok

pkg/sql/opt/norm/general_funcs.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,6 +1527,36 @@ func (c *CustomFuncs) IntConst(d *tree.DInt) opt.ScalarExpr {
15271527
return c.f.ConstructConst(d, types.Int)
15281528
}
15291529

1530+
// StrConst constructs a Const holding a DString.
1531+
func (c *CustomFuncs) StrConst(d *tree.DString) opt.ScalarExpr {
1532+
return c.f.ConstructConst(d, types.String)
1533+
}
1534+
1535+
// StringFromConst extracts a string from a Const expression. It returns the
1536+
// string and a boolean indicating whether the extraction was successful.
1537+
func (c *CustomFuncs) StringFromConst(expr opt.ScalarExpr) (string, bool) {
1538+
if constExpr, ok := expr.(*memo.ConstExpr); ok {
1539+
datum := tree.UnwrapDOidWrapper(constExpr.Value)
1540+
switch d := datum.(type) {
1541+
case *tree.DString:
1542+
return string(*d), true
1543+
case *tree.DCollatedString:
1544+
return d.Contents, true
1545+
}
1546+
}
1547+
return "", false
1548+
}
1549+
1550+
// EqualConstString compares two Const expressions to see if they hold equal string values.
1551+
func (c *CustomFuncs) EqualConstStrings(left, right opt.ScalarExpr) bool {
1552+
leftStr, okLeft := c.StringFromConst(left)
1553+
rightStr, okRight := c.StringFromConst(right)
1554+
if !okLeft || !okRight {
1555+
return false
1556+
}
1557+
return leftStr == rightStr
1558+
}
1559+
15301560
// IsGreaterThan returns true if the first datum compares as greater than the
15311561
// second.
15321562
func (c *CustomFuncs) IsGreaterThan(first, second tree.Datum) bool {

pkg/sql/opt/norm/rules/select.opt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,3 +480,23 @@ $input
480480
)
481481
$remainingFilters
482482
)
483+
484+
# NormalizeLikeAny replaces non-Null x LIKE '%' with true.
485+
[NormalizeLikeAny, Normalize]
486+
(Select
487+
$input:*
488+
$filters:[
489+
...
490+
$item:(FiltersItem
491+
(Like | ILike
492+
$left:* &
493+
(ExprIsNeverNull $left (NotNullCols $input))
494+
$pattern:(Const) &
495+
(EqualConstStrings $pattern (StrConst "%"))
496+
)
497+
)
498+
...
499+
]
500+
)
501+
=>
502+
(Select $input (RemoveFiltersItem $filters $item))

pkg/sql/opt/norm/testdata/rules/select

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2562,3 +2562,21 @@ barrier
25622562
└── filters
25632563
├── alice_has_access:3 [outer=(3), constraints=(/3: [/true - /true]; tight), fd=()-->(3)]
25642564
└── y:2 = 20 [outer=(2), constraints=(/2: [/20 - /20]; tight), fd=()-->(2)]
2565+
2566+
# --------------------------------------------------
2567+
# NormalizeLikeAny
2568+
# --------------------------------------------------
2569+
2570+
exec-ddl
2571+
CREATE TABLE strs_notnull (
2572+
s STRING NOT NULL,
2573+
cs STRING COLLATE en_US NOT NULL,
2574+
name NAME NOT NULL
2575+
)
2576+
----
2577+
2578+
norm expect=NormalizeLikeAny
2579+
SELECT * FROM strs_notnull WHERE s LIKE '%' AND cs LIKE '%' COLLATE en_US AND name LIKE '%'::NAME;
2580+
----
2581+
scan strs_notnull
2582+
└── columns: s:1!null cs:2!null name:3!null

pkg/sql/opt/xform/testdata/external/pgjdbc

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -302,40 +302,34 @@ sort
302302
│ │ │ │ │ │ │ ├── inner-join (hash)
303303
│ │ │ │ │ │ │ │ ├── columns: n.oid:2!null n.nspname:3!null c.oid:7!null c.relname:8!null c.relnamespace:9!null c.relkind:24!null attrelid:44!null attname:45 atttypid:46 attlen:48 attnum:49!null atttypmod:52 a.attnotnull:56 attisdropped:60!null
304304
│ │ │ │ │ │ │ │ ├── fd: ()-->(3,60), (2)==(9), (9)==(2), (7)==(44), (44)==(7)
305-
│ │ │ │ │ │ │ │ ├── inner-join (merge)
306-
│ │ │ │ │ │ │ │ │ ├── columns: c.oid:7!null c.relname:8!null c.relnamespace:9 c.relkind:24!null attrelid:44!null attname:45 atttypid:46 attlen:48 attnum:49!null atttypmod:52 a.attnotnull:56 attisdropped:60!null
307-
│ │ │ │ │ │ │ │ │ ├── left ordering: +44
308-
│ │ │ │ │ │ │ │ │ ├── right ordering: +7
309-
│ │ │ │ │ │ │ │ │ ├── fd: ()-->(60), (7)==(44), (44)==(7)
305+
│ │ │ │ │ │ │ │ ├── select
306+
│ │ │ │ │ │ │ │ │ ├── columns: attrelid:44!null attname:45 atttypid:46 attlen:48 attnum:49!null atttypmod:52 a.attnotnull:56 attisdropped:60!null
307+
│ │ │ │ │ │ │ │ │ ├── fd: ()-->(60)
308+
│ │ │ │ │ │ │ │ │ ├── scan pg_attribute [as=a]
309+
│ │ │ │ │ │ │ │ │ │ └── columns: attrelid:44!null attname:45 atttypid:46 attlen:48 attnum:49 atttypmod:52 a.attnotnull:56 attisdropped:60
310+
│ │ │ │ │ │ │ │ │ └── filters
311+
│ │ │ │ │ │ │ │ │ ├── attnum:49 > 0 [outer=(49), constraints=(/49: [/1 - ]; tight)]
312+
│ │ │ │ │ │ │ │ │ └── NOT attisdropped:60 [outer=(60), constraints=(/60: [/false - /false]; tight), fd=()-->(60)]
313+
│ │ │ │ │ │ │ │ ├── inner-join (hash)
314+
│ │ │ │ │ │ │ │ │ ├── columns: n.oid:2!null n.nspname:3!null c.oid:7!null c.relname:8!null c.relnamespace:9!null c.relkind:24!null
315+
│ │ │ │ │ │ │ │ │ ├── fd: ()-->(3), (2)==(9), (9)==(2)
310316
│ │ │ │ │ │ │ │ │ ├── select
311-
│ │ │ │ │ │ │ │ │ │ ├── columns: attrelid:44!null attname:45 atttypid:46 attlen:48 attnum:49!null atttypmod:52 a.attnotnull:56 attisdropped:60!null
312-
│ │ │ │ │ │ │ │ │ │ ├── fd: ()-->(60)
313-
│ │ │ │ │ │ │ │ │ │ ├── ordering: +44 opt(60) [actual: +44]
314-
│ │ │ │ │ │ │ │ │ │ ├── scan pg_attribute@pg_attribute_attrelid_idx [as=a]
315-
│ │ │ │ │ │ │ │ │ │ │ ├── columns: attrelid:44!null attname:45 atttypid:46 attlen:48 attnum:49 atttypmod:52 a.attnotnull:56 attisdropped:60
316-
│ │ │ │ │ │ │ │ │ │ │ └── ordering: +44
317+
│ │ │ │ │ │ │ │ │ │ ├── columns: c.oid:7!null c.relname:8!null c.relnamespace:9 c.relkind:24!null
318+
│ │ │ │ │ │ │ │ │ │ ├── scan pg_class [as=c]
319+
│ │ │ │ │ │ │ │ │ │ │ └── columns: c.oid:7!null c.relname:8!null c.relnamespace:9 c.relkind:24
317320
│ │ │ │ │ │ │ │ │ │ └── filters
318-
│ │ │ │ │ │ │ │ │ │ ├── attnum:49 > 0 [outer=(49), constraints=(/49: [/1 - ]; tight)]
319-
│ │ │ │ │ │ │ │ │ │ └── NOT attisdropped:60 [outer=(60), constraints=(/60: [/false - /false]; tight), fd=()-->(60)]
321+
│ │ │ │ │ │ │ │ │ │ └── c.relkind:24 IN ('f', 'm', 'p', 'r', 'v') [outer=(24), constraints=(/24: [/'f' - /'f'] [/'m' - /'m'] [/'p' - /'p'] [/'r' - /'r'] [/'v' - /'v']; tight)]
320322
│ │ │ │ │ │ │ │ │ ├── select
321-
│ │ │ │ │ │ │ │ │ │ ├── columns: c.oid:7!null c.relname:8!null c.relnamespace:9 c.relkind:24!null
322-
│ │ │ │ │ │ │ │ │ │ ├── ordering: +7
323-
│ │ │ │ │ │ │ │ │ │ ├── scan pg_class@pg_class_oid_idx [as=c]
324-
│ │ │ │ │ │ │ │ │ │ │ ├── columns: c.oid:7!null c.relname:8!null c.relnamespace:9 c.relkind:24
325-
│ │ │ │ │ │ │ │ │ │ │ └── ordering: +7
323+
│ │ │ │ │ │ │ │ │ │ ├── columns: n.oid:2 n.nspname:3!null
324+
│ │ │ │ │ │ │ │ │ │ ├── fd: ()-->(3)
325+
│ │ │ │ │ │ │ │ │ │ ├── scan pg_namespace [as=n]
326+
│ │ │ │ │ │ │ │ │ │ │ └── columns: n.oid:2 n.nspname:3!null
326327
│ │ │ │ │ │ │ │ │ │ └── filters
327-
│ │ │ │ │ │ │ │ │ │ ├── c.relkind:24 IN ('f', 'm', 'p', 'r', 'v') [outer=(24), constraints=(/24: [/'f' - /'f'] [/'m' - /'m'] [/'p' - /'p'] [/'r' - /'r'] [/'v' - /'v']; tight)]
328-
│ │ │ │ │ │ │ │ │ │ └── c.relname:8 LIKE '%' [outer=(8), constraints=(/8: (/NULL - ])]
329-
│ │ │ │ │ │ │ │ │ └── filters (true)
330-
│ │ │ │ │ │ │ │ ├── select
331-
│ │ │ │ │ │ │ │ │ ├── columns: n.oid:2 n.nspname:3!null
332-
│ │ │ │ │ │ │ │ │ ├── fd: ()-->(3)
333-
│ │ │ │ │ │ │ │ │ ├── scan pg_namespace [as=n]
334-
│ │ │ │ │ │ │ │ │ │ └── columns: n.oid:2 n.nspname:3!null
328+
│ │ │ │ │ │ │ │ │ │ └── n.nspname:3 LIKE 'public' [outer=(3), constraints=(/3: [/'public' - /'public']; tight), fd=()-->(3)]
335329
│ │ │ │ │ │ │ │ │ └── filters
336-
│ │ │ │ │ │ │ │ │ └── n.nspname:3 LIKE 'public' [outer=(3), constraints=(/3: [/'public' - /'public']; tight), fd=()-->(3)]
330+
│ │ │ │ │ │ │ │ │ └── c.relnamespace:9 = n.oid:2 [outer=(2,9), constraints=(/2: (/NULL - ]; /9: (/NULL - ]), fd=(2)==(9), (9)==(2)]
337331
│ │ │ │ │ │ │ │ └── filters
338-
│ │ │ │ │ │ │ │ └── c.relnamespace:9 = n.oid:2 [outer=(2,9), constraints=(/2: (/NULL - ]; /9: (/NULL - ]), fd=(2)==(9), (9)==(2)]
332+
│ │ │ │ │ │ │ │ └── attrelid:44 = c.oid:7 [outer=(7,44), constraints=(/7: (/NULL - ]; /44: (/NULL - ]), fd=(7)==(44), (44)==(7)]
339333
│ │ │ │ │ │ │ └── filters
340334
│ │ │ │ │ │ │ ├── c.oid:7 = crdb_internal.kv_catalog_comments.objoid:110 [outer=(7,110), constraints=(/7: (/NULL - ]; /110: (/NULL - ]), fd=(7)==(110), (110)==(7)]
341335
│ │ │ │ │ │ │ └── attnum:49 = objsubid:118 [outer=(49,118), constraints=(/49: (/NULL - ]; /118: (/NULL - ]), fd=(49)==(118), (118)==(49)]

0 commit comments

Comments
 (0)