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") */