Just as a proof of concept, I tried the attached, and it passes
check-world. So if there's anyplace trying to stuff OUTER_VAR and
friends into bitmapsets, it's pretty far off the beaten track.
The main loose ends that'd have to be settled seem to be:
(1) What data type do we want Var.varno to be declared as? In the
previous thread, Robert opined that plain "int" isn't a good choice,
but I'm not sure I agree. There's enough "int" for rangetable indexes
all over the place that it'd be a fool's errand to try to make it
uniformly something different.
(2) Does that datatype change need to propagate anywhere besides
what I touched here? I did not make any effort to search for
other places.
regards, tom lane
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 8fc432bfe1..d44d84804e 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -1098,7 +1098,7 @@ _outVar(StringInfo str, const Var *node)
{
WRITE_NODE_TYPE("VAR");
- WRITE_UINT_FIELD(varno);
+ WRITE_INT_FIELD(varno);
WRITE_INT_FIELD(varattno);
WRITE_OID_FIELD(vartype);
WRITE_INT_FIELD(vartypmod);
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 718fb58e86..ff94c10b8d 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -575,7 +575,7 @@ _readVar(void)
{
READ_LOCALS(Var);
- READ_UINT_FIELD(varno);
+ READ_INT_FIELD(varno);
READ_INT_FIELD(varattno);
READ_OID_FIELD(vartype);
READ_INT_FIELD(vartypmod);
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 42f088ad71..f9267d329e 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -467,16 +467,6 @@ add_rte_to_flat_rtable(PlannerGlobal *glob, RangeTblEntry *rte)
glob->finalrtable = lappend(glob->finalrtable, newrte);
- /*
- * Check for RT index overflow; it's very unlikely, but if it did happen,
- * the executor would get confused by varnos that match the special varno
- * values.
- */
- if (IS_SPECIAL_VARNO(list_length(glob->finalrtable)))
- ereport(ERROR,
- (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
- errmsg("too many range table entries")));
-
/*
* If it's a plain relation RTE, add the table to relationOids.
*
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index d4ce037088..43d8100424 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -168,11 +168,11 @@ typedef struct Expr
* in the planner and doesn't correspond to any simple relation column may
* have varnosyn = varattnosyn = 0.
*/
-#define INNER_VAR 65000 /* reference to inner subplan */
-#define OUTER_VAR 65001 /* reference to outer subplan */
-#define INDEX_VAR 65002 /* reference to index column */
+#define INNER_VAR (-1) /* reference to inner subplan */
+#define OUTER_VAR (-2) /* reference to outer subplan */
+#define INDEX_VAR (-3) /* reference to index column */
-#define IS_SPECIAL_VARNO(varno) ((varno) >= INNER_VAR)
+#define IS_SPECIAL_VARNO(varno) ((varno) < 0)
/* Symbols for the indexes of the special RTE entries in rules */
#define PRS2_OLD_VARNO 1
@@ -181,7 +181,7 @@ typedef struct Expr
typedef struct Var
{
Expr xpr;
- Index varno; /* index of this var's relation in the range
+ int varno; /* index of this var's relation in the range
* table, or INNER_VAR/OUTER_VAR/INDEX_VAR */
AttrNumber varattno; /* attribute number of this var, or zero for
* all attrs ("whole-row Var") */