Tweak grammar to use FastAppend rather than lappend when constructing
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 22 Aug 2003 20:34:33 +0000 (20:34 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 22 Aug 2003 20:34:33 +0000 (20:34 +0000)
expr_lists.  This appears to be the only remaining O(N^2) bottleneck
in processing many-way 'x IN (a,b,c,...)' conditions.

src/backend/parser/gram.y
src/include/nodes/pg_list.h

index 89e41f7e6a85fb0ab6915632cc9383542a47573b..f22e2443df05b4405443be5f6f1fc05caa31166e 100644 (file)
@@ -108,6 +108,7 @@ static void doNegateFloat(Value *v);
        DropBehavior            dbehavior;
        OnCommitAction          oncommit;
        List                            *list;
+       FastList                        fastlist;
        Node                            *node;
        Value                           *value;
        ColumnRef                       *columnref;
@@ -6719,8 +6720,18 @@ opt_indirection:
                                { $$ = NIL; }
                ;
 
-expr_list:     a_expr                                                                  { $$ = makeList1($1); }
-                       | expr_list ',' a_expr                                  { $$ = lappend($1, $3); }
+expr_list:     a_expr
+                               {
+                                       FastList *dst = (FastList *) &$$;
+                                       makeFastList1(dst, $1);
+                               }
+                       | expr_list ',' a_expr
+                               {
+                                       FastList *dst = (FastList *) &$$;
+                                       FastList *src = (FastList *) &$1;
+                                       *dst = *src;
+                                       FastAppend(dst, $3);
+                               }
                ;
 
 extract_list:
index 6357cb76aeb1fd4072f0a481654b7b51e3aa6a6d..3a7347606e237f8d721cc31db2d1df91c1b5a91c 100644 (file)
@@ -132,6 +132,9 @@ typedef struct List
  * FastList is an optimization for building large lists.  The conventional
  * way to build a list is repeated lappend() operations, but that is O(N^2)
  * in the number of list items, which gets tedious for large lists.
+ *
+ * Note: there are some hacks in gram.y that rely on the head pointer (the
+ * value-as-list) being the first field.
  */
 typedef struct FastList
 {
@@ -144,6 +147,9 @@ typedef struct FastList
        ( (fl)->head = (l), (fl)->tail = llastnode((fl)->head) )
 #define FastListValue(fl)      ( (fl)->head )
 
+#define makeFastList1(fl, x1)  \
+       ( (fl)->head = (fl)->tail = makeList1(x1) )
+
 
 /*
  * function prototypes in nodes/list.c