Defend against JOINs having more than 32K columns altogether. We cannot
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 5 Apr 2008 01:58:51 +0000 (01:58 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 5 Apr 2008 01:58:51 +0000 (01:58 +0000)
currently support this because we must be able to build Vars referencing
join columns, and varattno is only 16 bits wide.  Perhaps this should be
improved in future, but considering that it never came up before, I'm not
sure the problem is worth much effort.  Per bug #4070 from Marcello
Ceschia.

The problem seems largely academic in 8.0 and 7.4, because they have
(different) O(N^2) performance issues with such wide joins, but
back-patch all the way anyway.

src/backend/parser/parse_relation.c
src/include/access/attnum.h

index 7e41c71de85243a370fb86e6972f1939294f3906..c81613577783dcf65b7329b2617510ecd09b5688 100644 (file)
@@ -1114,6 +1114,16 @@ addRangeTableEntryForJoin(ParseState *pstate,
        Alias      *eref;
        int                     numaliases;
 
+       /*
+        * Fail if join has too many columns --- we must be able to reference
+        * any of the columns with an AttrNumber.
+        */
+       if (list_length(aliasvars) > MaxAttrNumber)
+               ereport(ERROR,
+                               (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+                                errmsg("joins can have at most %d columns",
+                                               MaxAttrNumber)));
+
        rte->rtekind = RTE_JOIN;
        rte->relid = InvalidOid;
        rte->subquery = NULL;
@@ -1374,7 +1384,7 @@ expandRTE(List *rtable, int rtindex, int sublevels_up,
                                                        varnode = makeVar(rtindex,
                                                                                          attnum,
                                                                                          atttypid,
-                                                                                         -1,
+                                                                                         colDef->typename->typmod,
                                                                                          sublevels_up);
 
                                                        *colvars = lappend(*colvars, varnode);
@@ -1715,7 +1725,7 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
                                        ColumnDef  *colDef = list_nth(coldeflist, attnum - 1);
 
                                        *vartype = typenameTypeId(colDef->typename);
-                                       *vartypmod = -1;
+                                       *vartypmod = colDef->typename->typmod;
                                }
                                else
                                {
index 440f297e83a046fe5a9091db0fd6de21541c59f1..951f900c790ada2e9cbdf22f254ea92523e33a46 100644 (file)
@@ -21,6 +21,7 @@
 typedef int16 AttrNumber;
 
 #define InvalidAttrNumber              0
+#define MaxAttrNumber                  32767
 
 /* ----------------
  *             support macros