Skip to content

Commit e3ec3c0

Browse files
committed
Remove arbitrary 64K-or-so limit on rangetable size.
Up to now the size of a query's rangetable has been limited by the constants INNER_VAR et al, which mustn't be equal to any real rangetable index. 65000 doubtless seemed like enough for anybody, and it still is orders of magnitude larger than the number of joins we can realistically handle. However, we need a rangetable entry for each child partition that is (or might be) processed by a query. Queries with a few thousand partitions are getting more realistic, so that the day when that limit becomes a problem is in sight, even if it's not here yet. Hence, let's raise the limit. Rather than just increase the values of INNER_VAR et al, this patch adopts the approach of making them small negative values, so that rangetables could theoretically become as long as INT_MAX. The bulk of the patch is concerned with changing Var.varno and some related variables from "Index" (unsigned int) to plain "int". This is basically cosmetic, with little actual effect other than to help debuggers print their values nicely. As such, I've only bothered with changing places that could actually see INNER_VAR et al, which the parser and most of the planner don't. We do have to be careful in places that are performing less/greater comparisons on varnos, but there are very few such places, other than the IS_SPECIAL_VARNO macro itself. A notable side effect of this patch is that while it used to be possible to add INNER_VAR et al to a Bitmapset, that will now draw an error. I don't see any likelihood that it wouldn't be a bug to include these fake varnos in a bitmapset of real varnos, so I think this is all to the good. Although this touches outfuncs/readfuncs, I don't think a catversion bump is required, since stored rules would never contain Vars with these fake varnos. Andrey Lepikhov and Tom Lane, after a suggestion by Peter Eisentraut Discussion: https://postgr.es/m/43c7f2f5-1e27-27aa-8c65-c91859d15190@postgrespro.ru
1 parent 6fe0eb9 commit e3ec3c0

File tree

15 files changed

+48
-57
lines changed

15 files changed

+48
-57
lines changed

src/backend/executor/execScan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ ExecAssignScanProjectionInfo(ScanState *node)
282282
* As above, but caller can specify varno expected in Vars in the tlist.
283283
*/
284284
void
285-
ExecAssignScanProjectionInfoWithVarno(ScanState *node, Index varno)
285+
ExecAssignScanProjectionInfoWithVarno(ScanState *node, int varno)
286286
{
287287
TupleDesc tupdesc = node->ss_ScanTupleSlot->tts_tupleDescriptor;
288288

src/backend/executor/execUtils.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
#include "utils/typcache.h"
6666

6767

68-
static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc);
68+
static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, int varno, TupleDesc tupdesc);
6969
static void ShutdownExprContext(ExprContext *econtext, bool isCommit);
7070

7171

@@ -553,7 +553,7 @@ ExecAssignProjectionInfo(PlanState *planstate,
553553
*/
554554
void
555555
ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc,
556-
Index varno)
556+
int varno)
557557
{
558558
if (tlist_matches_tupdesc(planstate,
559559
planstate->plan->targetlist,
@@ -579,7 +579,7 @@ ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc,
579579
}
580580

581581
static bool
582-
tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
582+
tlist_matches_tupdesc(PlanState *ps, List *tlist, int varno, TupleDesc tupdesc)
583583
{
584584
int numattrs = tupdesc->natts;
585585
int attrno;

src/backend/executor/nodeCustom.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
3131
CustomScanState *css;
3232
Relation scan_rel = NULL;
3333
Index scanrelid = cscan->scan.scanrelid;
34-
Index tlistvarno;
34+
int tlistvarno;
3535

3636
/*
3737
* Allocate the CustomScanState object. We let the custom scan provider

src/backend/executor/nodeForeignscan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags)
138138
ForeignScanState *scanstate;
139139
Relation currentRelation = NULL;
140140
Index scanrelid = node->scan.scanrelid;
141-
Index tlistvarno;
141+
int tlistvarno;
142142
FdwRoutine *fdwroutine;
143143

144144
/* check for unsupported flags */

src/backend/nodes/makefuncs.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ makeSimpleA_Expr(A_Expr_Kind kind, char *name,
6363
* creates a Var node
6464
*/
6565
Var *
66-
makeVar(Index varno,
66+
makeVar(int varno,
6767
AttrNumber varattno,
6868
Oid vartype,
6969
int32 vartypmod,
@@ -85,7 +85,7 @@ makeVar(Index varno,
8585
* them, but just initialize them to the given varno/varattno. This
8686
* reduces code clutter and chance of error for most callers.
8787
*/
88-
var->varnosyn = varno;
88+
var->varnosyn = (Index) varno;
8989
var->varattnosyn = varattno;
9090

9191
/* Likewise, we just set location to "unknown" here */
@@ -100,7 +100,7 @@ makeVar(Index varno,
100100
* TargetEntry
101101
*/
102102
Var *
103-
makeVarFromTargetEntry(Index varno,
103+
makeVarFromTargetEntry(int varno,
104104
TargetEntry *tle)
105105
{
106106
return makeVar(varno,
@@ -131,7 +131,7 @@ makeVarFromTargetEntry(Index varno,
131131
*/
132132
Var *
133133
makeWholeRowVar(RangeTblEntry *rte,
134-
Index varno,
134+
int varno,
135135
Index varlevelsup,
136136
bool allowScalar)
137137
{

src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1123,7 +1123,7 @@ _outVar(StringInfo str, const Var *node)
11231123
{
11241124
WRITE_NODE_TYPE("VAR");
11251125

1126-
WRITE_UINT_FIELD(varno);
1126+
WRITE_INT_FIELD(varno);
11271127
WRITE_INT_FIELD(varattno);
11281128
WRITE_OID_FIELD(vartype);
11291129
WRITE_INT_FIELD(vartypmod);

src/backend/nodes/readfuncs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ _readVar(void)
577577
{
578578
READ_LOCALS(Var);
579579

580-
READ_UINT_FIELD(varno);
580+
READ_INT_FIELD(varno);
581581
READ_INT_FIELD(varattno);
582582
READ_OID_FIELD(vartype);
583583
READ_INT_FIELD(vartypmod);

src/backend/optimizer/path/costsize.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5961,7 +5961,8 @@ set_pathtarget_cost_width(PlannerInfo *root, PathTarget *target)
59615961
Assert(var->varlevelsup == 0);
59625962

59635963
/* Try to get data from RelOptInfo cache */
5964-
if (var->varno < root->simple_rel_array_size)
5964+
if (!IS_SPECIAL_VARNO(var->varno) &&
5965+
var->varno < root->simple_rel_array_size)
59655966
{
59665967
RelOptInfo *rel = root->simple_rel_array[var->varno];
59675968

src/backend/optimizer/plan/createplan.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4805,7 +4805,8 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
48054805
/* Upper-level Vars should be long gone at this point */
48064806
Assert(var->varlevelsup == 0);
48074807
/* If not to be replaced, we can just return the Var unmodified */
4808-
if (!bms_is_member(var->varno, root->curOuterRels))
4808+
if (IS_SPECIAL_VARNO(var->varno) ||
4809+
!bms_is_member(var->varno, root->curOuterRels))
48094810
return node;
48104811
/* Replace the Var with a nestloop Param */
48114812
return (Node *) replace_nestloop_param_var(root, var);

src/backend/optimizer/plan/setrefs.c

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
typedef struct
3333
{
34-
Index varno; /* RT index of Var */
34+
int varno; /* RT index of Var */
3535
AttrNumber varattno; /* attr number of Var */
3636
AttrNumber resno; /* TLE position of Var */
3737
} tlist_vinfo;
@@ -66,7 +66,7 @@ typedef struct
6666
{
6767
PlannerInfo *root;
6868
indexed_tlist *subplan_itlist;
69-
Index newvarno;
69+
int newvarno;
7070
int rtoffset;
7171
double num_exec;
7272
} fix_upper_expr_context;
@@ -143,15 +143,15 @@ static void set_dummy_tlist_references(Plan *plan, int rtoffset);
143143
static indexed_tlist *build_tlist_index(List *tlist);
144144
static Var *search_indexed_tlist_for_var(Var *var,
145145
indexed_tlist *itlist,
146-
Index newvarno,
146+
int newvarno,
147147
int rtoffset);
148148
static Var *search_indexed_tlist_for_non_var(Expr *node,
149149
indexed_tlist *itlist,
150-
Index newvarno);
150+
int newvarno);
151151
static Var *search_indexed_tlist_for_sortgroupref(Expr *node,
152152
Index sortgroupref,
153153
indexed_tlist *itlist,
154-
Index newvarno);
154+
int newvarno);
155155
static List *fix_join_expr(PlannerInfo *root,
156156
List *clauses,
157157
indexed_tlist *outer_itlist,
@@ -163,7 +163,7 @@ static Node *fix_join_expr_mutator(Node *node,
163163
static Node *fix_upper_expr(PlannerInfo *root,
164164
Node *node,
165165
indexed_tlist *subplan_itlist,
166-
Index newvarno,
166+
int newvarno,
167167
int rtoffset, double num_exec);
168168
static Node *fix_upper_expr_mutator(Node *node,
169169
fix_upper_expr_context *context);
@@ -505,16 +505,6 @@ add_rte_to_flat_rtable(PlannerGlobal *glob, RangeTblEntry *rte)
505505

506506
glob->finalrtable = lappend(glob->finalrtable, newrte);
507507

508-
/*
509-
* Check for RT index overflow; it's very unlikely, but if it did happen,
510-
* the executor would get confused by varnos that match the special varno
511-
* values.
512-
*/
513-
if (IS_SPECIAL_VARNO(list_length(glob->finalrtable)))
514-
ereport(ERROR,
515-
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
516-
errmsg("too many range table entries")));
517-
518508
/*
519509
* If it's a plain relation RTE, add the table to relationOids.
520510
*
@@ -1947,10 +1937,8 @@ fix_scan_expr_mutator(Node *node, fix_scan_expr_context *context)
19471937
{
19481938
CurrentOfExpr *cexpr = (CurrentOfExpr *) copyObject(node);
19491939

1950-
Assert(cexpr->cvarno != INNER_VAR);
1951-
Assert(cexpr->cvarno != OUTER_VAR);
1952-
if (!IS_SPECIAL_VARNO(cexpr->cvarno))
1953-
cexpr->cvarno += context->rtoffset;
1940+
Assert(!IS_SPECIAL_VARNO(cexpr->cvarno));
1941+
cexpr->cvarno += context->rtoffset;
19541942
return (Node *) cexpr;
19551943
}
19561944
if (IsA(node, PlaceHolderVar))
@@ -2447,7 +2435,7 @@ build_tlist_index(List *tlist)
24472435
* (so nothing other than Vars and PlaceHolderVars can be matched).
24482436
*/
24492437
static indexed_tlist *
2450-
build_tlist_index_other_vars(List *tlist, Index ignore_rel)
2438+
build_tlist_index_other_vars(List *tlist, int ignore_rel)
24512439
{
24522440
indexed_tlist *itlist;
24532441
tlist_vinfo *vinfo;
@@ -2499,9 +2487,9 @@ build_tlist_index_other_vars(List *tlist, Index ignore_rel)
24992487
*/
25002488
static Var *
25012489
search_indexed_tlist_for_var(Var *var, indexed_tlist *itlist,
2502-
Index newvarno, int rtoffset)
2490+
int newvarno, int rtoffset)
25032491
{
2504-
Index varno = var->varno;
2492+
int varno = var->varno;
25052493
AttrNumber varattno = var->varattno;
25062494
tlist_vinfo *vinfo;
25072495
int i;
@@ -2539,7 +2527,7 @@ search_indexed_tlist_for_var(Var *var, indexed_tlist *itlist,
25392527
*/
25402528
static Var *
25412529
search_indexed_tlist_for_non_var(Expr *node,
2542-
indexed_tlist *itlist, Index newvarno)
2530+
indexed_tlist *itlist, int newvarno)
25432531
{
25442532
TargetEntry *tle;
25452533

@@ -2581,7 +2569,7 @@ static Var *
25812569
search_indexed_tlist_for_sortgroupref(Expr *node,
25822570
Index sortgroupref,
25832571
indexed_tlist *itlist,
2584-
Index newvarno)
2572+
int newvarno)
25852573
{
25862574
ListCell *lc;
25872575

@@ -2799,7 +2787,7 @@ static Node *
27992787
fix_upper_expr(PlannerInfo *root,
28002788
Node *node,
28012789
indexed_tlist *subplan_itlist,
2802-
Index newvarno,
2790+
int newvarno,
28032791
int rtoffset,
28042792
double num_exec)
28052793
{

src/backend/optimizer/prep/prepjointree.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ static Node *pull_up_simple_union_all(PlannerInfo *root, Node *jtnode,
8080
static void pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root,
8181
int parentRTindex, Query *setOpQuery,
8282
int childRToffset);
83-
static void make_setop_translation_list(Query *query, Index newvarno,
83+
static void make_setop_translation_list(Query *query, int newvarno,
8484
AppendRelInfo *appinfo);
8585
static bool is_simple_subquery(PlannerInfo *root, Query *subquery,
8686
RangeTblEntry *rte,
@@ -1372,7 +1372,7 @@ pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root, int parentRTindex,
13721372
* Also create the rather trivial reverse-translation array.
13731373
*/
13741374
static void
1375-
make_setop_translation_list(Query *query, Index newvarno,
1375+
make_setop_translation_list(Query *query, int newvarno,
13761376
AppendRelInfo *appinfo)
13771377
{
13781378
List *vars = NIL;

src/backend/utils/adt/ruleutils.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6949,7 +6949,7 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
69496949
AttrNumber attnum;
69506950
int netlevelsup;
69516951
deparse_namespace *dpns;
6952-
Index varno;
6952+
int varno;
69536953
AttrNumber varattno;
69546954
deparse_columns *colinfo;
69556955
char *refname;
@@ -6995,7 +6995,7 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
69956995
*/
69966996
if (context->appendparents && dpns->appendrels)
69976997
{
6998-
Index pvarno = varno;
6998+
int pvarno = varno;
69996999
AttrNumber pvarattno = varattno;
70007000
AppendRelInfo *appinfo = dpns->appendrels[pvarno];
70017001
bool found = false;
@@ -7305,7 +7305,7 @@ get_name_for_var_field(Var *var, int fieldno,
73057305
AttrNumber attnum;
73067306
int netlevelsup;
73077307
deparse_namespace *dpns;
7308-
Index varno;
7308+
int varno;
73097309
AttrNumber varattno;
73107310
TupleDesc tupleDesc;
73117311
Node *expr;

src/include/executor/executor.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ typedef bool (*ExecScanRecheckMtd) (ScanState *node, TupleTableSlot *slot);
459459
extern TupleTableSlot *ExecScan(ScanState *node, ExecScanAccessMtd accessMtd,
460460
ExecScanRecheckMtd recheckMtd);
461461
extern void ExecAssignScanProjectionInfo(ScanState *node);
462-
extern void ExecAssignScanProjectionInfoWithVarno(ScanState *node, Index varno);
462+
extern void ExecAssignScanProjectionInfoWithVarno(ScanState *node, int varno);
463463
extern void ExecScanReScan(ScanState *node);
464464

465465
/*
@@ -552,7 +552,7 @@ extern const TupleTableSlotOps *ExecGetResultSlotOps(PlanState *planstate,
552552
extern void ExecAssignProjectionInfo(PlanState *planstate,
553553
TupleDesc inputDesc);
554554
extern void ExecConditionalAssignProjectionInfo(PlanState *planstate,
555-
TupleDesc inputDesc, Index varno);
555+
TupleDesc inputDesc, int varno);
556556
extern void ExecFreeExprContext(PlanState *planstate);
557557
extern void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc);
558558
extern void ExecCreateScanSlotFromOuterPlan(EState *estate,

src/include/nodes/makefuncs.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,18 @@ extern A_Expr *makeA_Expr(A_Expr_Kind kind, List *name,
2424
extern A_Expr *makeSimpleA_Expr(A_Expr_Kind kind, char *name,
2525
Node *lexpr, Node *rexpr, int location);
2626

27-
extern Var *makeVar(Index varno,
27+
extern Var *makeVar(int varno,
2828
AttrNumber varattno,
2929
Oid vartype,
3030
int32 vartypmod,
3131
Oid varcollid,
3232
Index varlevelsup);
3333

34-
extern Var *makeVarFromTargetEntry(Index varno,
34+
extern Var *makeVarFromTargetEntry(int varno,
3535
TargetEntry *tle);
3636

3737
extern Var *makeWholeRowVar(RangeTblEntry *rte,
38-
Index varno,
38+
int varno,
3939
Index varlevelsup,
4040
bool allowScalar);
4141

src/include/nodes/primnodes.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,12 @@ typedef struct Expr
172172
* in the planner and doesn't correspond to any simple relation column may
173173
* have varnosyn = varattnosyn = 0.
174174
*/
175-
#define INNER_VAR 65000 /* reference to inner subplan */
176-
#define OUTER_VAR 65001 /* reference to outer subplan */
177-
#define INDEX_VAR 65002 /* reference to index column */
178-
#define ROWID_VAR 65003 /* row identity column during planning */
175+
#define INNER_VAR (-1) /* reference to inner subplan */
176+
#define OUTER_VAR (-2) /* reference to outer subplan */
177+
#define INDEX_VAR (-3) /* reference to index column */
178+
#define ROWID_VAR (-4) /* row identity column during planning */
179179

180-
#define IS_SPECIAL_VARNO(varno) ((varno) >= INNER_VAR)
180+
#define IS_SPECIAL_VARNO(varno) ((int) (varno) < 0)
181181

182182
/* Symbols for the indexes of the special RTE entries in rules */
183183
#define PRS2_OLD_VARNO 1
@@ -186,8 +186,8 @@ typedef struct Expr
186186
typedef struct Var
187187
{
188188
Expr xpr;
189-
Index varno; /* index of this var's relation in the range
190-
* table, or INNER_VAR/OUTER_VAR/INDEX_VAR */
189+
int varno; /* index of this var's relation in the range
190+
* table, or INNER_VAR/OUTER_VAR/etc */
191191
AttrNumber varattno; /* attribute number of this var, or zero for
192192
* all attrs ("whole-row Var") */
193193
Oid vartype; /* pg_type OID for the type of this var */
@@ -1351,6 +1351,7 @@ typedef struct SetToDefault
13511351
* of the target relation being constrained; this aids placing the expression
13521352
* correctly during planning. We can assume however that its "levelsup" is
13531353
* always zero, due to the syntactic constraints on where it can appear.
1354+
* Also, cvarno will always be a true RT index, never INNER_VAR etc.
13541355
*
13551356
* The referenced cursor can be represented either as a hardwired string
13561357
* or as a reference to a run-time parameter of type REFCURSOR. The latter

0 commit comments

Comments
 (0)