OSDN Git Service

Fix planner to make a reasonable assumption about the amount of memory space
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 14 Aug 2010 15:47:21 +0000 (15:47 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 14 Aug 2010 15:47:21 +0000 (15:47 +0000)
used by array_agg(), string_agg(), and similar aggregate functions that use
"internal" as their transition datatype.  The previous coding thought this
took *no* extra space, since "internal" is pass-by-value; but actually these
aggregates typically consume a great deal of space.  Per bug #5608 from
Itagaki Takahiro, and fix suggestion from Hitoshi Harada.

Back-patch to 8.4, where array_agg was introduced.

src/backend/optimizer/util/clauses.c

index f6a943f..8486516 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.287 2010/03/19 22:54:41 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.287.4.1 2010/08/14 15:47:21 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -549,6 +549,18 @@ count_agg_clauses_walker(Node *node, AggClauseCounts *counts)
 
                        counts->transitionSpace += avgwidth + 2 * sizeof(void *);
                }
+               else if (aggtranstype == INTERNALOID)
+               {
+                       /*
+                        * INTERNAL transition type is a special case: although INTERNAL
+                        * is pass-by-value, it's almost certainly being used as a pointer
+                        * to some large data structure.  We assume usage of
+                        * ALLOCSET_DEFAULT_INITSIZE, which is a good guess if the data is
+                        * being kept in a private memory context, as is done by
+                        * array_agg() for instance.
+                        */
+                       counts->transitionSpace += ALLOCSET_DEFAULT_INITSIZE;
+               }
 
                /*
                 * Complain if the aggregate's arguments contain any aggregates;