Em qua., 28 de jun. de 2023 às 18:45, Tomas Vondra <
tomas.von...@enterprisedb.com> escreveu:

> On 6/27/23 20:55, Ranier Vilela wrote:
> > Hi,
> >
> >>I finished writing the code patch for transformation "Or" expressions to
> >>"Any" expressions. I didn't see any problems in regression tests, even
> >>when I changed the constant at which the minimum or expression is
> >>replaced by any at 0. I ran my patch on sqlancer and so far the code has
> >>never fallen.
> > Thanks for working on this.
> >
> > I took the liberty of making some modifications to the patch.
> > I didn't compile or test it.
> > Please feel free to use them.
> >
>
> I don't want to be rude, but this doesn't seem very helpful.
>
Sorry, It was not my intention to cause interruptions.


> - You made some changes, but you don't even attempt to explain what you
> changed or why you changed it.
>
1. Reduce scope
2. Eliminate unnecessary variables
3. Eliminate unnecessary expressions


>
> - You haven't even tried to compile the code, nor tested it. If it
> happens to compile, wow could others even know it actually behaves the
> way you wanted?
>
Attached v2 with make check pass all tests.
Ubuntu 64 bits
gcc 64 bits


> - You responded in a way that breaks the original thread, so it's not
> clear which message you're responding to.
>
It was a pretty busy day.

Sorry for the noise, I hope I was of some help.

regards,
Ranier Vilela

P.S.
0001-Replace-clause-X-N1-OR-X-N2-.-with-X-ANY-N1-N2-on.patch fails with 4
tests.
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 346fd272b6..74c256258d 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -95,6 +95,291 @@ static Expr *make_distinct_op(ParseState *pstate, List 
*opname,
 static Node *make_nulltest_from_distinct(ParseState *pstate,
                                                                                
 A_Expr *distincta, Node *arg);
 
+typedef struct OrClauseGroupEntry
+{
+       Node               *node;
+       List               *consts;
+       Oid                             scalar_type;
+       Oid                             opno;
+       Expr               *expr;
+} OrClauseGroupEntry;
+
+static int const_transform_or_limit = 0;
+
+static Node *
+transformBoolExprOr(ParseState *pstate, Expr *expr_orig)
+{
+       List               *or_list = NIL;
+       List               *groups_list = NIL;
+       ListCell           *lc_eargs;
+       Node               *result;
+       BoolExpr           *expr;
+       const char         *opname;
+       bool                    change_apply = false;
+       bool                    or_statement;
+
+       Assert(IsA(expr, BoolExpr));
+
+       expr = (BoolExpr *) expr_orig;
+       if (list_length(expr->args) < const_transform_or_limit)
+               return transformBoolExpr(pstate, (BoolExpr *)expr_orig);
+
+       /* If this is not expression "Or", then will do it the old way. */
+       switch (expr->boolop)
+       {
+               case AND_EXPR:
+                       opname = "AND";
+                       break;
+               case OR_EXPR:
+                       return transformBoolExpr(pstate, (BoolExpr *)expr_orig);
+                       break;
+               case NOT_EXPR:
+                       opname = "NOT";
+                       break;
+               default:
+                       elog(ERROR, "unrecognized boolop: %d", (int) 
expr->boolop);
+                       opname = NULL;          /* keep compiler quiet */
+                       break;
+       }
+
+       /*
+               * NOTE:
+               * It is an OR-clause. So, rinfo->orclause is a BoolExpr node, 
contains
+               * a list of sub-restrictinfo args, and rinfo->clause - which is 
the
+               * same expression, made from bare clauses. To not break 
selectivity
+               * caches and other optimizations, use both:
+               * - use rinfos from orclause if no transformation needed
+               * - use  bare quals from rinfo->clause in the case of 
transformation,
+               * to create new RestrictInfo: in this case we have no options 
to avoid
+               * selectivity estimation procedure.
+               */
+       or_statement = false;
+       expr = (BoolExpr *)copyObject(expr_orig);
+       foreach(lc_eargs, expr->args)
+       {
+               A_Expr                     *arg = (A_Expr *) lfirst(lc_eargs);
+               Node                       *bare_orarg;
+               Node                       *const_expr;
+               Node                       *non_const_expr;
+               ListCell                   *lc_groups;
+               OrClauseGroupEntry *gentry;
+               bool                            allow_transformation;
+
+               /*
+                * The first step: checking that the expression consists only 
of equality.
+                * We can only do this here, while arg is still row data type, 
namely A_Expr.
+                * After applying transformExprRecurce, we already know that it 
will be OpExr type,
+                * but checking the expression for equality is already becoming 
impossible for us.
+                * Sometimes we have the chance to devide expression into the 
groups on
+                * equality and inequality. This is possible if all list items 
are not at the
+                * same level of a single BoolExpr expression, otherwise all of 
them cannot be converted.
+                */
+
+               if (!arg)
+                       break;
+
+               allow_transformation = (
+                                       arg->type == T_A_Expr && (arg)->kind == 
AEXPR_OP &&
+                                                           
list_length((arg)->name) >=1 && strcmp(strVal(linitial((arg)->name)), "=") == 0
+                                                          );
+
+
+               bare_orarg = transformExprRecurse(pstate, (Node *)arg);
+               bare_orarg = coerce_to_boolean(pstate, bare_orarg, opname);
+
+               /*
+                * The next step: transform all the inputs, and detect whether 
any contain
+                * Vars.
+                */
+               if (!allow_transformation || !bare_orarg || !IsA(bare_orarg, 
OpExpr) || !contain_vars_of_level(bare_orarg, 0))
+               {
+                       /* Again, it's not the expr we can transform */
+                       or_list = lappend(or_list, bare_orarg);
+                       continue;
+               }
+
+               /*
+                * Get pointers to constant and expression sides of the clause
+                */
+               non_const_expr = get_leftop(bare_orarg);
+               const_expr = get_rightop(bare_orarg);
+
+               /*
+                       * At this point we definitely have a transformable 
clause.
+                       * Classify it and add into specific group of clauses, 
or create new
+                       * group.
+                       * TODO: to manage complexity in the case of many 
different clauses
+                       * (X1=C1) OR (X2=C2 OR) ... (XN = CN) we could invent 
something
+                       * like a hash table (htab key ???).
+                       */
+               foreach(lc_groups, groups_list)
+               {
+                       OrClauseGroupEntry *v = (OrClauseGroupEntry *) 
lfirst(lc_groups);
+
+                       Assert(v->node != NULL);
+
+                       if (equal(v->node, non_const_expr))
+                       {
+                               v->consts = lappend(v->consts, const_expr);
+                               non_const_expr = NULL;
+                               break;
+                       }
+               }
+
+               if (non_const_expr == NULL)
+                       /*
+                               * The clause classified successfully and added 
into existed
+                               * clause group.
+                               */
+                       continue;
+
+               /* New clause group needed */
+               gentry = palloc(sizeof(OrClauseGroupEntry));
+               gentry->node = non_const_expr;
+               gentry->consts = list_make1(const_expr);
+               gentry->opno = ((OpExpr *)bare_orarg)->opno;
+               gentry->expr = (Expr *)bare_orarg;
+               groups_list = lappend(groups_list,  (void *) gentry);
+       }
+
+       if (groups_list == NIL)
+       {
+               /*
+               * No any transformations possible with this rinfo, just add 
itself
+               * to the list and go further.
+               */
+               list_free(or_list);
+
+               return transformBoolExpr(pstate, (BoolExpr *)expr_orig);
+       }
+       else
+       {
+               ListCell           *lc_args;
+
+               /* Let's convert each group of clauses to an IN operation. */
+
+               /*
+               * Go through the list of groups and convert each, where number 
of
+               * consts more than 1. trivial groups move to OR-list again
+               */
+
+               foreach(lc_args, groups_list)
+               {
+                       OrClauseGroupEntry *gentry = (OrClauseGroupEntry *) 
lfirst(lc_args);
+                       List                       *allexprs;
+                       Oid                                 scalar_type;
+
+                       Assert(list_length(gentry->consts) > 0);
+
+                       if (list_length(gentry->consts) == 1)
+                       {
+                               /*
+                                * Only one element in the class. Return rinfo 
into the BoolExpr
+                                * args list unchanged.
+                                */
+                               list_free(gentry->consts);
+                               or_list = lappend(or_list, gentry->expr);
+                               continue;
+                       }
+
+                       /*
+                        * Do the transformation. It's been a long way ;)
+                        *
+                        * First of all, try to select a common type for the 
array elements.  Note that
+                        * since the LHS' type is first in the list, it will be 
preferred when
+                        * there is doubt (eg, when all the RHS items are 
unknown literals).
+                        *
+                        * Note: use list_concat here not lcons, to avoid 
damaging rnonvars.
+                        *
+                        * As a source of insides, use make_scalar_array_op()
+                        */
+                       allexprs = list_concat(list_make1(gentry->node), 
gentry->consts);
+                       scalar_type = select_common_type(NULL, allexprs, NULL, 
NULL);
+                       
+                       if (OidIsValid(scalar_type) &&
+                               scalar_type != RECORDOID &&
+                               verify_common_type(scalar_type, allexprs))
+                       {
+                               /*
+                                * 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;
+                               ListCell *l;
+
+                               aexprs = NIL;
+
+                               foreach(l, gentry->consts)
+                               {
+                                       Node       *rexpr = (Node *) lfirst(l);
+
+                                       rexpr = coerce_to_common_type(pstate, 
rexpr,
+                                                                               
                scalar_type,
+                                                                               
                "IN");
+                                       aexprs = lappend(aexprs, rexpr);
+                               }
+
+                               newa = makeNode(ArrayExpr);
+                               /* array_collid will be set by parse_collate.c 
*/
+                               newa->element_typeid = scalar_type;
+                               newa->array_typeid = 
get_array_type(scalar_type);
+                               newa->multidims = false;
+                               newa->elements = aexprs;
+                               newa->location = -1; /* Position of the new 
clause is undefined */
+
+                               saopexpr = (ScalarArrayOpExpr 
*)make_scalar_array_op(pstate,
+                                                                               
                   list_make1(makeString((char *) "=")),
+                                                                               
                   true,
+                                                                               
                   gentry->node,
+                                                                               
                   (Node *) newa,
+                                                                               
                   -1); /* Position of the new clause is undefined */
+
+                               /*
+                               * TODO: here we can try to coerce the array to 
a Const and find
+                               * hash func instead of linear search (see 
50e17ad281b).
+                               * convert_saop_to_hashed_saop((Node *) 
saopexpr);
+                               * We don't have to do this anymore, do we?
+                               */
+
+                               or_list = lappend(or_list, (void *) saopexpr);
+                               change_apply = true;
+                       }
+                       else
+                       {
+                               list_free(gentry->consts);
+                               or_list = lappend(or_list, gentry->expr);
+                               continue;
+                       }
+               }
+
+               if (!change_apply)
+               {
+                       or_statement = false;
+               }
+               list_free_deep(groups_list);
+       }
+
+       if (or_statement)
+       {
+               /* One more trick: assemble correct clause */
+               expr = list_length(or_list) > 1 ? makeBoolExpr(OR_EXPR, 
list_copy(or_list), -1) : linitial(or_list);
+               result = (Node *)expr;
+       }
+       /*
+        * There was no reasons to create a new expresion, so
+        * run the original BoolExpr conversion with using
+        * transformBoolExpr function
+        */
+       else
+       {
+               result = transformBoolExpr(pstate, (BoolExpr *)expr_orig);
+       }
+       list_free(or_list);
+
+       return result;
+}
 
 /*
  * transformExpr -
@@ -208,7 +493,7 @@ transformExprRecurse(ParseState *pstate, Node *expr)
                        }
 
                case T_BoolExpr:
-                       result = transformBoolExpr(pstate, (BoolExpr *) expr);
+                       result = (Node *)transformBoolExprOr(pstate, (Expr 
*)expr);
                        break;
 
                case T_FuncCall:
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 260854747b..01918e6aea 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -1630,6 +1630,7 @@ NumericSumAccum
 NumericVar
 OM_uint32
 OP
+OrClauseGroupEntry
 OSAPerGroupState
 OSAPerQueryState
 OSInfo
ok 1         - test_setup                                318 ms
# parallel group (20 tests):  varchar char name int2 txid oid boolean uuid int4 
text pg_lsn money float4 regproc float8 bit enum int8 numeric rangetypes
ok 2         + boolean                                    72 ms
ok 3         + char                                       31 ms
ok 4         + name                                       36 ms
ok 5         + varchar                                    30 ms
ok 6         + text                                       82 ms
ok 7         + int2                                       64 ms
ok 8         + int4                                       79 ms
ok 9         + int8                                      141 ms
ok 10        + oid                                        69 ms
ok 11        + float4                                     92 ms
ok 12        + float8                                    101 ms
ok 13        + bit                                       121 ms
ok 14        + numeric                                   438 ms
ok 15        + txid                                       62 ms
ok 16        + uuid                                       74 ms
ok 17        + enum                                      134 ms
ok 18        + money                                      87 ms
ok 19        + rangetypes                                554 ms
ok 20        + pg_lsn                                     79 ms
ok 21        + regproc                                    98 ms
# parallel group (20 tests):  md5 lseg circle timetz point numerology path 
macaddr time macaddr8 line date inet interval strings polygon multirangetypes 
box timestamp timestamptz
ok 22        + strings                                   194 ms
ok 23        + md5                                        23 ms
ok 24        + numerology                                 76 ms
ok 25        + point                                      74 ms
ok 26        + lseg                                       26 ms
ok 27        + line                                       90 ms
ok 28        + box                                       334 ms
ok 29        + path                                       85 ms
ok 30        + polygon                                   288 ms
ok 31        + circle                                     33 ms
ok 32        + date                                      107 ms
ok 33        + time                                       84 ms
ok 34        + timetz                                     44 ms
ok 35        + timestamp                                 386 ms
ok 36        + timestamptz                               423 ms
ok 37        + interval                                  137 ms
ok 38        + inet                                      114 ms
ok 39        + macaddr                                    82 ms
ok 40        + macaddr8                                   85 ms
ok 41        + multirangetypes                           328 ms
# parallel group (12 tests):  unicode comments xid misc_sanity expressions 
tstypes mvcc horology type_sanity geometry opr_sanity regex
ok 42        + geometry                                  176 ms
ok 43        + horology                                  134 ms
ok 44        + tstypes                                   108 ms
ok 45        + regex                                     572 ms
ok 46        + type_sanity                               157 ms
ok 47        + opr_sanity                                417 ms
ok 48        + misc_sanity                                52 ms
ok 49        + comments                                   46 ms
ok 50        + expressions                                76 ms
ok 51        + unicode                                    21 ms
ok 52        + xid                                        50 ms
ok 53        + mvcc                                      128 ms
# parallel group (5 tests):  copyselect copydml copy insert_conflict insert
ok 54        + copy                                       84 ms
ok 55        + copyselect                                 36 ms
ok 56        + copydml                                    40 ms
ok 57        + insert                                    349 ms
ok 58        + insert_conflict                           159 ms
# parallel group (7 tests):  create_function_c create_operator create_type 
create_schema create_misc create_procedure create_table
ok 59        + create_function_c                          15 ms
ok 60        + create_misc                                63 ms
ok 61        + create_operator                            33 ms
ok 62        + create_procedure                           68 ms
ok 63        + create_table                              422 ms
ok 64        + create_type                                51 ms
ok 65        + create_schema                              59 ms
# parallel group (5 tests):  index_including index_including_gist create_view 
create_index_spgist create_index
not ok 66    + create_index                              871 ms
ok 67        + create_index_spgist                       626 ms
ok 68        + create_view                               407 ms
ok 69        + index_including                           191 ms
ok 70        + index_including_gist                      357 ms
# parallel group (16 tests):  create_cast create_aggregate hash_func 
drop_if_exists roleattributes select typed_table errors create_function_sql 
create_am constraints vacuum infinite_recurse updatable_views inherit triggers
ok 71        + create_aggregate                           77 ms
ok 72        + create_function_sql                       185 ms
ok 73        + create_cast                                29 ms
ok 74        + constraints                               242 ms
ok 75        + triggers                                 1110 ms
ok 76        + select                                    118 ms
ok 77        + inherit                                   827 ms
ok 78        + typed_table                               128 ms
ok 79        + vacuum                                    507 ms
ok 80        + drop_if_exists                            107 ms
ok 81        + updatable_views                           734 ms
ok 82        + roleattributes                            116 ms
ok 83        + create_am                                 224 ms
ok 84        + hash_func                                 104 ms
ok 85        + errors                                    149 ms
ok 86        + infinite_recurse                          519 ms
ok 87        - sanity_check                              123 ms
# parallel group (20 tests):  select_distinct_on select_having delete 
select_implicit random case namespace prepared_xacts select_into 
select_distinct transactions portals union subselect arrays update hash_index 
join aggregates btree_index
ok 88        + select_into                               218 ms
ok 89        + select_distinct                           305 ms
ok 90        + select_distinct_on                         58 ms
ok 91        + select_implicit                            62 ms
ok 92        + select_having                              57 ms
ok 93        + subselect                                 459 ms
ok 94        + union                                     390 ms
ok 95        + case                                      110 ms
not ok 96    + join                                      893 ms
ok 97        + aggregates                                941 ms
ok 98        + transactions                              344 ms
ok 99        + random                                     77 ms
ok 100       + portals                                   351 ms
ok 101       + arrays                                    533 ms
ok 102       + btree_index                              2071 ms
ok 103       + hash_index                                848 ms
ok 104       + update                                    623 ms
ok 105       + delete                                     54 ms
ok 106       + namespace                                 107 ms
ok 107       + prepared_xacts                            169 ms
# parallel group (20 tests):  init_privs security_label drop_operator 
tablesample lock object_address replica_identity password collate groupingsets 
identity matview generated rowsecurity spgist gin gist brin join_hash privileges
ok 108       + brin                                     1933 ms
ok 109       + gin                                      1259 ms
ok 110       + gist                                     1401 ms
ok 111       + spgist                                   1136 ms
ok 112       + privileges                               2243 ms
ok 113       + init_privs                                 60 ms
ok 114       + security_label                             75 ms
ok 115       + collate                                   441 ms
ok 116       + matview                                   817 ms
ok 117       + lock                                      237 ms
ok 118       + replica_identity                          393 ms
ok 119       + rowsecurity                              1037 ms
ok 120       + object_address                            283 ms
ok 121       + tablesample                               183 ms
ok 122       + groupingsets                              577 ms
ok 123       + drop_operator                             147 ms
ok 124       + password                                  409 ms
ok 125       + identity                                  590 ms
ok 126       + generated                                 958 ms
ok 127       + join_hash                                1938 ms
# parallel group (2 tests):  brin_bloom brin_multi
ok 128       + brin_bloom                                102 ms
ok 129       + brin_multi                                240 ms
# parallel group (16 tests):  async collate.icu.utf8 dbsize alter_operator tid 
tsrf tidrangescan tidscan create_role sysviews alter_generic misc_functions 
misc incremental_sort merge create_table_like
ok 130       + create_table_like                         358 ms
ok 131       + alter_generic                             150 ms
ok 132       + alter_operator                             38 ms
ok 133       + misc                                      198 ms
ok 134       + async                                      16 ms
ok 135       + dbsize                                     34 ms
ok 136       + merge                                     299 ms
ok 137       + misc_functions                            172 ms
ok 138       + sysviews                                  132 ms
ok 139       + tsrf                                       65 ms
ok 140       + tid                                        55 ms
ok 141       + tidscan                                    97 ms
ok 142       + tidrangescan                               90 ms
ok 143       + collate.icu.utf8                           17 ms
ok 144       + incremental_sort                          220 ms
ok 145       + create_role                               103 ms
# parallel group (7 tests):  collate.windows.win1252 collate.linux.utf8 amutils 
psql_crosstab rules psql stats_ext
ok 146       + rules                                     387 ms
ok 147       + psql                                      434 ms
ok 148       + psql_crosstab                              42 ms
ok 149       + amutils                                    23 ms
not ok 150   + stats_ext                                1818 ms
ok 151       + collate.linux.utf8                         16 ms
ok 152       + collate.windows.win1252                    15 ms
ok 153       - select_parallel                           855 ms
ok 154       - write_parallel                             92 ms
ok 155       - vacuum_parallel                           129 ms
# parallel group (2 tests):  subscription publication
ok 156       + publication                               410 ms
ok 157       + subscription                               61 ms
# parallel group (17 tests):  portals_p2 advisory_lock combocid tsdicts xmlmap 
dependency guc functional_deps equivclass select_views window bitmapops tsearch 
cluster indirect_toast foreign_data foreign_key
ok 158       + select_views                              272 ms
ok 159       + portals_p2                                 60 ms
ok 160       + foreign_key                              1234 ms
ok 161       + cluster                                   532 ms
ok 162       + dependency                                183 ms
ok 163       + guc                                       196 ms
ok 164       + bitmapops                                 505 ms
ok 165       + combocid                                  113 ms
ok 166       + tsearch                                   508 ms
ok 167       + tsdicts                                   132 ms
ok 168       + foreign_data                              724 ms
ok 169       + window                                    394 ms
ok 170       + xmlmap                                    174 ms
ok 171       + functional_deps                           225 ms
ok 172       + advisory_lock                              75 ms
ok 173       + indirect_toast                            661 ms
ok 174       + equivclass                                228 ms
# parallel group (7 tests):  jsonpath_encoding json_encoding jsonpath sqljson 
jsonb_jsonpath json jsonb
ok 175       + json                                      135 ms
ok 176       + jsonb                                     314 ms
ok 177       + json_encoding                              21 ms
ok 178       + jsonpath                                   51 ms
ok 179       + jsonpath_encoding                          17 ms
ok 180       + jsonb_jsonpath                            113 ms
ok 181       + sqljson                                    72 ms
# parallel group (18 tests):  limit prepare returning plancache conversion temp 
xml copy2 rowtypes sequence polymorphism truncate with domain rangefuncs 
largeobject plpgsql alter_table
ok 182       + plancache                                 198 ms
ok 183       + limit                                     103 ms
ok 184       + plpgsql                                   832 ms
ok 185       + copy2                                     343 ms
ok 186       + temp                                      256 ms
ok 187       + domain                                    449 ms
ok 188       + rangefuncs                                463 ms
ok 189       + prepare                                   125 ms
ok 190       + conversion                                221 ms
ok 191       + truncate                                  417 ms
ok 192       + alter_table                              1638 ms
ok 193       + sequence                                  381 ms
ok 194       + polymorphism                              404 ms
ok 195       + rowtypes                                  345 ms
ok 196       + returning                                 146 ms
ok 197       + largeobject                               480 ms
ok 198       + with                                      431 ms
ok 199       + xml                                       283 ms
# parallel group (12 tests):  hash_part reloptions explain partition_info 
memoize compression stats partition_prune indexing partition_join 
partition_aggregate tuplesort
ok 200       + partition_join                           1088 ms
not ok 201   + partition_prune                           972 ms
ok 202       + reloptions                                114 ms
ok 203       + hash_part                                  66 ms
ok 204       + indexing                                 1025 ms
ok 205       + partition_aggregate                      1109 ms
ok 206       + partition_info                            141 ms
ok 207       + tuplesort                                1518 ms
ok 208       + explain                                   114 ms
ok 209       + compression                               209 ms
ok 210       + memoize                                   200 ms
ok 211       + stats                                     959 ms
# parallel group (2 tests):  event_trigger oidjoins
ok 212       + event_trigger                             124 ms
ok 213       + oidjoins                                  235 ms
ok 214       - fast_default                              156 ms
ok 215       - tablespace                                364 ms
1..215
# 4 of 215 tests failed.
# The differences that caused some tests to fail can be viewed in the file 
"/usr/src/postgres_or/src/test/regress/regression.diffs".
# A copy of the test summary that you see above is saved in the file 
"/usr/src/postgres_or/src/test/regress/regression.out".
make[1]: *** [GNUmakefile:118: check] Erro 1
make[1]: Saindo do diretório '/usr/src/postgres_or/src/test/regress'
make: *** [GNUmakefile:69: check] Erro 2

Reply via email to