diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 25a4235dbd9..46212a77c64 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -44,7 +44,7 @@ /* GUC parameters */ bool Transform_null_equals = false; -bool or_transform_limit = false; +bool enable_or_transformation = false; static Node *transformExprRecurse(ParseState *pstate, Node *expr); @@ -108,7 +108,7 @@ typedef struct OrClauseGroupEntry List *consts; Oid scalar_type; Oid opno; - Expr *expr; + Node *expr; } OrClauseGroupEntry; static int @@ -189,16 +189,16 @@ transformBoolExprOr(ParseState *pstate, BoolExpr *expr_orig) HASH_ELEM | HASH_FUNCTION | HASH_COMPARE); /* If this is not an 'OR' expression, skip the transformation */ - if (expr_orig->boolop != OR_EXPR || !or_transform_limit || len_ors == 1 || !or_group_htab) + if (expr_orig->boolop != OR_EXPR || !enable_or_transformation || len_ors == 1 || !or_group_htab) return transformBoolExpr(pstate, (BoolExpr *) expr_orig); foreach(lc, expr_orig->args) { Node *arg = lfirst(lc); - Node *orqual; - Node *const_expr; - Node *nconst_expr; - OrClauseGroupEntry *gentry; + Node *orqual = NULL; + Node *const_expr = NULL; + Node *nconst_expr = NULL; + OrClauseGroupEntry *gentry = NULL; bool found; char *str; @@ -270,7 +270,7 @@ transformBoolExprOr(ParseState *pstate, BoolExpr *expr_orig) gentry = hash_search(or_group_htab, &str, HASH_ENTER, &found); gentry->node = nconst_expr; gentry->consts = list_make1(const_expr); - gentry->expr = (Expr *) orqual; + gentry->expr = orqual; gentry->hash_leftvar_key = str; } @@ -283,7 +283,6 @@ transformBoolExprOr(ParseState *pstate, BoolExpr *expr_orig) * transformed bool expression. */ hash_destroy(or_group_htab); - list_free(or_list); return (Node *) makeBoolExpr(OR_EXPR, or_list, expr_orig->location); } else @@ -345,9 +344,9 @@ transformBoolExprOr(ParseState *pstate, BoolExpr *expr_orig) * OK: coerce all the right-hand non-Var inputs to the common * type and build an ArrayExpr for them. */ - List *aexprs; - ArrayExpr *newa; - ScalarArrayOpExpr *saopexpr; + List *aexprs = NIL; + ArrayExpr *newa = NULL; + ScalarArrayOpExpr *saopexpr = NULL; ListCell *l; aexprs = NIL; diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index 54fd09abde7..3411f023df8 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -1049,12 +1049,12 @@ struct config_bool ConfigureNamesBool[] = NULL, NULL, NULL }, { - {"or_transform_limit", PGC_USERSET, QUERY_TUNING_OTHER, + {"enable_or_transformation", PGC_USERSET, QUERY_TUNING_OTHER, gettext_noop("Transform a sequence of OR clauses to an IN expression."), gettext_noop("The planner will replace clauses like 'x=c1 OR x=c2 .." "to the clause 'x IN (c1,c2,...)'") }, - &or_transform_limit, + &enable_or_transformation, false, NULL, NULL, NULL }, diff --git a/src/include/parser/parse_expr.h b/src/include/parser/parse_expr.h index 7a6943c116c..3a87de02859 100644 --- a/src/include/parser/parse_expr.h +++ b/src/include/parser/parse_expr.h @@ -17,7 +17,7 @@ /* GUC parameters */ extern PGDLLIMPORT bool Transform_null_equals; -extern PGDLLIMPORT bool or_transform_limit; +extern PGDLLIMPORT bool enable_or_transformation; extern Node *transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind); diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out index 29c2bc6a2b2..dbc8bc3bed0 100644 --- a/src/test/regress/expected/create_index.out +++ b/src/test/regress/expected/create_index.out @@ -1883,7 +1883,7 @@ SELECT count(*) FROM tenk1 10 (1 row) -SET or_transform_limit = on; +SET enable_or_transformation = on; EXPLAIN (COSTS OFF) SELECT * FROM tenk1 WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42); @@ -1997,7 +1997,7 @@ SELECT count(*) FROM tenk1 10 (1 row) -RESET or_transform_limit; +RESET enable_or_transformation; -- -- Check behavior with duplicate index column contents -- diff --git a/src/test/regress/expected/guc.out b/src/test/regress/expected/guc.out index c052b113eea..0f2b1b16200 100644 --- a/src/test/regress/expected/guc.out +++ b/src/test/regress/expected/guc.out @@ -861,7 +861,7 @@ SELECT name FROM tab_settings_flags name --------------------------- default_statistics_target - or_transform_limit + enable_or_transformation (2 rows) -- Runtime-computed GUCs should be part of the preset category. diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out index 97b4964812e..d969b31e3e3 100644 --- a/src/test/regress/expected/join.out +++ b/src/test/regress/expected/join.out @@ -4207,7 +4207,7 @@ select * from tenk1 a join tenk1 b on Index Cond: (unique2 = 7) (19 rows) -SET or_transform_limit = on; +SET enable_or_transformation = on; explain (costs off) select * from tenk1 a join tenk1 b on (a.unique1 = 1 and b.unique1 = 2) or @@ -4256,7 +4256,7 @@ select * from tenk1 a join tenk1 b on Index Cond: (unique1 = 3) (15 rows) -RESET or_transform_limit; +RESET enable_or_transformation; -- -- test placement of movable quals in a parameterized join tree -- diff --git a/src/test/regress/expected/partition_prune.out b/src/test/regress/expected/partition_prune.out index 1789d3c1fd7..fe815417c13 100644 --- a/src/test/regress/expected/partition_prune.out +++ b/src/test/regress/expected/partition_prune.out @@ -101,7 +101,7 @@ explain (costs off) select * from lp where a is not null and (a = 'a' or a = 'c' Filter: ((a IS NOT NULL) AND ((a = 'a'::bpchar) OR (a = 'c'::bpchar))) (5 rows) -SET or_transform_limit = on; +SET enable_or_transformation = on; explain (costs off) select * from lp where a = 'a' or a = 'c'; QUERY PLAN ----------------------------------------------- @@ -122,7 +122,7 @@ explain (costs off) select * from lp where a is not null and (a = 'a' or a = 'c' Filter: ((a IS NOT NULL) AND (a = ANY ('{a,c}'::bpchar[]))) (5 rows) -RESET or_transform_limit; +RESET enable_or_transformation; explain (costs off) select * from lp where a <> 'g'; QUERY PLAN ------------------------------------ @@ -693,7 +693,7 @@ explain (costs off) select * from rlp where (a = 1 and a = 3) or (a > 1 and a = Filter: (((a = 1) AND (a = 3)) OR ((a > 1) AND (a = 15))) (11 rows) -SET or_transform_limit = on; +SET enable_or_transformation = on; explain (costs off) select * from rlp where a = 1 or a = 7; QUERY PLAN ------------------------------------------ @@ -706,29 +706,29 @@ explain (costs off) select * from rlp where a = 1 or b = 'ab'; ------------------------------------------------------- Append -> Seq Scan on rlp1 rlp_1 - Filter: ((a = 1) OR ((b)::text = 'ab'::text)) + Filter: (((b)::text = 'ab'::text) OR (a = 1)) -> Seq Scan on rlp2 rlp_2 - Filter: ((a = 1) OR ((b)::text = 'ab'::text)) + Filter: (((b)::text = 'ab'::text) OR (a = 1)) -> Seq Scan on rlp3abcd rlp_3 - Filter: ((a = 1) OR ((b)::text = 'ab'::text)) + Filter: (((b)::text = 'ab'::text) OR (a = 1)) -> Seq Scan on rlp4_1 rlp_4 - Filter: ((a = 1) OR ((b)::text = 'ab'::text)) + Filter: (((b)::text = 'ab'::text) OR (a = 1)) -> Seq Scan on rlp4_2 rlp_5 - Filter: ((a = 1) OR ((b)::text = 'ab'::text)) + Filter: (((b)::text = 'ab'::text) OR (a = 1)) -> Seq Scan on rlp4_default rlp_6 - Filter: ((a = 1) OR ((b)::text = 'ab'::text)) + Filter: (((b)::text = 'ab'::text) OR (a = 1)) -> Seq Scan on rlp5_1 rlp_7 - Filter: ((a = 1) OR ((b)::text = 'ab'::text)) + Filter: (((b)::text = 'ab'::text) OR (a = 1)) -> Seq Scan on rlp5_default rlp_8 - Filter: ((a = 1) OR ((b)::text = 'ab'::text)) + Filter: (((b)::text = 'ab'::text) OR (a = 1)) -> Seq Scan on rlp_default_10 rlp_9 - Filter: ((a = 1) OR ((b)::text = 'ab'::text)) + Filter: (((b)::text = 'ab'::text) OR (a = 1)) -> Seq Scan on rlp_default_30 rlp_10 - Filter: ((a = 1) OR ((b)::text = 'ab'::text)) + Filter: (((b)::text = 'ab'::text) OR (a = 1)) -> Seq Scan on rlp_default_null rlp_11 - Filter: ((a = 1) OR ((b)::text = 'ab'::text)) + Filter: (((b)::text = 'ab'::text) OR (a = 1)) -> Seq Scan on rlp_default_default rlp_12 - Filter: ((a = 1) OR ((b)::text = 'ab'::text)) + Filter: (((b)::text = 'ab'::text) OR (a = 1)) (25 rows) explain (costs off) select * from rlp where a > 20 and a < 27; @@ -849,7 +849,7 @@ explain (costs off) select * from rlp where (a = 1 and a = 3) or (a > 1 and a = Filter: (((a = 1) AND (a = 3)) OR ((a > 1) AND (a = 15))) (11 rows) -RESET or_transform_limit; +RESET enable_or_transformation; -- multi-column keys create table mc3p (a int, b int, c int) partition by range (a, abs(b), c); create table mc3p_default partition of mc3p default; diff --git a/src/test/regress/expected/sysviews.out b/src/test/regress/expected/sysviews.out index 271313ebf86..8a380c29a4c 100644 --- a/src/test/regress/expected/sysviews.out +++ b/src/test/regress/expected/sysviews.out @@ -123,6 +123,7 @@ select name, setting from pg_settings where name like 'enable%'; enable_memoize | on enable_mergejoin | on enable_nestloop | on + enable_or_transformation | off enable_parallel_append | on enable_parallel_hash | on enable_partition_pruning | on diff --git a/src/test/regress/expected/tidscan.out b/src/test/regress/expected/tidscan.out index 8a31e2e670d..be4d88200b6 100644 --- a/src/test/regress/expected/tidscan.out +++ b/src/test/regress/expected/tidscan.out @@ -56,7 +56,7 @@ SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid; (0,2) | 2 (2 rows) -SET or_transform_limit = on; +SET enable_or_transformation = on; EXPLAIN (COSTS OFF) SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid; QUERY PLAN @@ -72,7 +72,7 @@ SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid; (0,2) | 2 (2 rows) -RESET or_transform_limit; +RESET enable_or_transformation; -- ctid = ScalarArrayOp - implemented as tidscan EXPLAIN (COSTS OFF) SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[]); diff --git a/src/test/regress/sql/create_index.sql b/src/test/regress/sql/create_index.sql index a709b2c1abc..48bb1bc0a0a 100644 --- a/src/test/regress/sql/create_index.sql +++ b/src/test/regress/sql/create_index.sql @@ -737,7 +737,7 @@ SELECT count(*) FROM tenk1 SELECT count(*) FROM tenk1 WHERE hundred = 42 AND (thousand = 42 OR thousand = 99); -SET or_transform_limit = on; +SET enable_or_transformation = on; EXPLAIN (COSTS OFF) SELECT * FROM tenk1 WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42); @@ -767,7 +767,7 @@ SELECT count(*) FROM tenk1 WHERE hundred = 42 AND (thousand = 42 OR thousand = 41 OR thousand = 99 AND tenthous = 2); SELECT count(*) FROM tenk1 WHERE hundred = 42 AND (thousand = 42 OR thousand = 41 OR thousand = 99 AND tenthous = 2); -RESET or_transform_limit; +RESET enable_or_transformation; -- -- Check behavior with duplicate index column contents diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql index d95663b9c30..3d072cce498 100644 --- a/src/test/regress/sql/join.sql +++ b/src/test/regress/sql/join.sql @@ -1396,7 +1396,7 @@ explain (costs off) select * from tenk1 a join tenk1 b on (a.unique1 = 1 and b.unique1 = 2) or ((a.unique2 = 3 or a.unique2 = 7) and b.hundred = 4); -SET or_transform_limit = on; +SET enable_or_transformation = on; explain (costs off) select * from tenk1 a join tenk1 b on (a.unique1 = 1 and b.unique1 = 2) or @@ -1405,7 +1405,7 @@ explain (costs off) select * from tenk1 a join tenk1 b on (a.unique1 < 20 or a.unique1 = 3 or a.unique1 = 1 and b.unique1 = 2) or ((a.unique2 = 3 or a.unique2 = 7) and b.hundred = 4); -RESET or_transform_limit; +RESET enable_or_transformation; -- -- test placement of movable quals in a parameterized join tree diff --git a/src/test/regress/sql/partition_prune.sql b/src/test/regress/sql/partition_prune.sql index 88709910592..1e270ae9c06 100644 --- a/src/test/regress/sql/partition_prune.sql +++ b/src/test/regress/sql/partition_prune.sql @@ -22,10 +22,10 @@ explain (costs off) select * from lp where a is null; explain (costs off) select * from lp where a = 'a' or a = 'c'; explain (costs off) select * from lp where a is not null and (a = 'a' or a = 'c'); -SET or_transform_limit = on; +SET enable_or_transformation = on; explain (costs off) select * from lp where a = 'a' or a = 'c'; explain (costs off) select * from lp where a is not null and (a = 'a' or a = 'c'); -RESET or_transform_limit; +RESET enable_or_transformation; explain (costs off) select * from lp where a <> 'g'; explain (costs off) select * from lp where a <> 'a' and a <> 'd'; @@ -106,7 +106,7 @@ explain (costs off) select * from rlp where a = 1 and a = 3; /* empty */ explain (costs off) select * from rlp where (a = 1 and a = 3) or (a > 1 and a = 15); -SET or_transform_limit = on; +SET enable_or_transformation = on; explain (costs off) select * from rlp where a = 1 or a = 7; explain (costs off) select * from rlp where a = 1 or b = 'ab'; explain (costs off) select * from rlp where a > 20 and a < 27; @@ -119,7 +119,7 @@ explain (costs off) select * from rlp where a > 1 and a = 10; /* only default */ explain (costs off) select * from rlp where a > 1 and a >=15; /* rlp3 onwards, including default */ explain (costs off) select * from rlp where a = 1 and a = 3; /* empty */ explain (costs off) select * from rlp where (a = 1 and a = 3) or (a > 1 and a = 15); -RESET or_transform_limit; +RESET enable_or_transformation; -- multi-column keys create table mc3p (a int, b int, c int) partition by range (a, abs(b), c); diff --git a/src/test/regress/sql/tidscan.sql b/src/test/regress/sql/tidscan.sql index c735e219589..0499bedb9eb 100644 --- a/src/test/regress/sql/tidscan.sql +++ b/src/test/regress/sql/tidscan.sql @@ -22,11 +22,11 @@ EXPLAIN (COSTS OFF) SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid; SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid; -SET or_transform_limit = on; +SET enable_or_transformation = on; EXPLAIN (COSTS OFF) SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid; SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid; -RESET or_transform_limit; +RESET enable_or_transformation; -- ctid = ScalarArrayOp - implemented as tidscan EXPLAIN (COSTS OFF)