summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorTom Lane2021-09-15 18:11:21 +0000
committerTom Lane2021-09-15 18:11:21 +0000
commite3ec3c00d85bd2844ffddee83df2bd67c4f8297f (patch)
treeccf15898e3a216cf10ec5710d3b741e597d3989f /src/backend
parent6fe0eb963d3894ae9b0b6e151083887b664d45a3 (diff)
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
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/executor/execScan.c2
-rw-r--r--src/backend/executor/execUtils.c6
-rw-r--r--src/backend/executor/nodeCustom.c2
-rw-r--r--src/backend/executor/nodeForeignscan.c2
-rw-r--r--src/backend/nodes/makefuncs.c8
-rw-r--r--src/backend/nodes/outfuncs.c2
-rw-r--r--src/backend/nodes/readfuncs.c2
-rw-r--r--src/backend/optimizer/path/costsize.c3
-rw-r--r--src/backend/optimizer/plan/createplan.c3
-rw-r--r--src/backend/optimizer/plan/setrefs.c40
-rw-r--r--src/backend/optimizer/prep/prepjointree.c4
-rw-r--r--src/backend/utils/adt/ruleutils.c6
12 files changed, 35 insertions, 45 deletions
diff --git a/src/backend/executor/execScan.c b/src/backend/executor/execScan.c
index 69ab34573ec..9f1d8b6d1e9 100644
--- a/src/backend/executor/execScan.c
+++ b/src/backend/executor/execScan.c
@@ -282,7 +282,7 @@ ExecAssignScanProjectionInfo(ScanState *node)
* As above, but caller can specify varno expected in Vars in the tlist.
*/
void
-ExecAssignScanProjectionInfoWithVarno(ScanState *node, Index varno)
+ExecAssignScanProjectionInfoWithVarno(ScanState *node, int varno)
{
TupleDesc tupdesc = node->ss_ScanTupleSlot->tts_tupleDescriptor;
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index ad11392b99d..4ab1302313f 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -65,7 +65,7 @@
#include "utils/typcache.h"
-static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc);
+static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, int varno, TupleDesc tupdesc);
static void ShutdownExprContext(ExprContext *econtext, bool isCommit);
@@ -553,7 +553,7 @@ ExecAssignProjectionInfo(PlanState *planstate,
*/
void
ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc,
- Index varno)
+ int varno)
{
if (tlist_matches_tupdesc(planstate,
planstate->plan->targetlist,
@@ -579,7 +579,7 @@ ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc,
}
static bool
-tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
+tlist_matches_tupdesc(PlanState *ps, List *tlist, int varno, TupleDesc tupdesc)
{
int numattrs = tupdesc->natts;
int attrno;
diff --git a/src/backend/executor/nodeCustom.c b/src/backend/executor/nodeCustom.c
index c82060e6d1a..1dfa53c3819 100644
--- a/src/backend/executor/nodeCustom.c
+++ b/src/backend/executor/nodeCustom.c
@@ -31,7 +31,7 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
CustomScanState *css;
Relation scan_rel = NULL;
Index scanrelid = cscan->scan.scanrelid;
- Index tlistvarno;
+ int tlistvarno;
/*
* Allocate the CustomScanState object. We let the custom scan provider
diff --git a/src/backend/executor/nodeForeignscan.c b/src/backend/executor/nodeForeignscan.c
index 1abd906b169..0a549afcc09 100644
--- a/src/backend/executor/nodeForeignscan.c
+++ b/src/backend/executor/nodeForeignscan.c
@@ -138,7 +138,7 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags)
ForeignScanState *scanstate;
Relation currentRelation = NULL;
Index scanrelid = node->scan.scanrelid;
- Index tlistvarno;
+ int tlistvarno;
FdwRoutine *fdwroutine;
/* check for unsupported flags */
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index 01c110cd2fc..7d1a01d1ed6 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -63,7 +63,7 @@ makeSimpleA_Expr(A_Expr_Kind kind, char *name,
* creates a Var node
*/
Var *
-makeVar(Index varno,
+makeVar(int varno,
AttrNumber varattno,
Oid vartype,
int32 vartypmod,
@@ -85,7 +85,7 @@ makeVar(Index varno,
* them, but just initialize them to the given varno/varattno. This
* reduces code clutter and chance of error for most callers.
*/
- var->varnosyn = varno;
+ var->varnosyn = (Index) varno;
var->varattnosyn = varattno;
/* Likewise, we just set location to "unknown" here */
@@ -100,7 +100,7 @@ makeVar(Index varno,
* TargetEntry
*/
Var *
-makeVarFromTargetEntry(Index varno,
+makeVarFromTargetEntry(int varno,
TargetEntry *tle)
{
return makeVar(varno,
@@ -131,7 +131,7 @@ makeVarFromTargetEntry(Index varno,
*/
Var *
makeWholeRowVar(RangeTblEntry *rte,
- Index varno,
+ int varno,
Index varlevelsup,
bool allowScalar)
{
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 6b290737a6d..2e5ed77e189 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -1123,7 +1123,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 01aee85bd45..abf08b7a2f3 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -577,7 +577,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/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 1fd53b40bb0..1e4d404f024 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -5961,7 +5961,8 @@ set_pathtarget_cost_width(PlannerInfo *root, PathTarget *target)
Assert(var->varlevelsup == 0);
/* Try to get data from RelOptInfo cache */
- if (var->varno < root->simple_rel_array_size)
+ if (!IS_SPECIAL_VARNO(var->varno) &&
+ var->varno < root->simple_rel_array_size)
{
RelOptInfo *rel = root->simple_rel_array[var->varno];
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index a5f6d678ccd..3dc0176a516 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -4805,7 +4805,8 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
/* Upper-level Vars should be long gone at this point */
Assert(var->varlevelsup == 0);
/* If not to be replaced, we can just return the Var unmodified */
- if (!bms_is_member(var->varno, root->curOuterRels))
+ if (IS_SPECIAL_VARNO(var->varno) ||
+ !bms_is_member(var->varno, root->curOuterRels))
return node;
/* Replace the Var with a nestloop Param */
return (Node *) replace_nestloop_param_var(root, var);
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 3d23a2e5ac7..6ccec759bd2 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -31,7 +31,7 @@
typedef struct
{
- Index varno; /* RT index of Var */
+ int varno; /* RT index of Var */
AttrNumber varattno; /* attr number of Var */
AttrNumber resno; /* TLE position of Var */
} tlist_vinfo;
@@ -66,7 +66,7 @@ typedef struct
{
PlannerInfo *root;
indexed_tlist *subplan_itlist;
- Index newvarno;
+ int newvarno;
int rtoffset;
double num_exec;
} fix_upper_expr_context;
@@ -143,15 +143,15 @@ static void set_dummy_tlist_references(Plan *plan, int rtoffset);
static indexed_tlist *build_tlist_index(List *tlist);
static Var *search_indexed_tlist_for_var(Var *var,
indexed_tlist *itlist,
- Index newvarno,
+ int newvarno,
int rtoffset);
static Var *search_indexed_tlist_for_non_var(Expr *node,
indexed_tlist *itlist,
- Index newvarno);
+ int newvarno);
static Var *search_indexed_tlist_for_sortgroupref(Expr *node,
Index sortgroupref,
indexed_tlist *itlist,
- Index newvarno);
+ int newvarno);
static List *fix_join_expr(PlannerInfo *root,
List *clauses,
indexed_tlist *outer_itlist,
@@ -163,7 +163,7 @@ static Node *fix_join_expr_mutator(Node *node,
static Node *fix_upper_expr(PlannerInfo *root,
Node *node,
indexed_tlist *subplan_itlist,
- Index newvarno,
+ int newvarno,
int rtoffset, double num_exec);
static Node *fix_upper_expr_mutator(Node *node,
fix_upper_expr_context *context);
@@ -506,16 +506,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.
*
* We do this even though the RTE might be unreferenced in the plan tree;
@@ -1947,10 +1937,8 @@ fix_scan_expr_mutator(Node *node, fix_scan_expr_context *context)
{
CurrentOfExpr *cexpr = (CurrentOfExpr *) copyObject(node);
- Assert(cexpr->cvarno != INNER_VAR);
- Assert(cexpr->cvarno != OUTER_VAR);
- if (!IS_SPECIAL_VARNO(cexpr->cvarno))
- cexpr->cvarno += context->rtoffset;
+ Assert(!IS_SPECIAL_VARNO(cexpr->cvarno));
+ cexpr->cvarno += context->rtoffset;
return (Node *) cexpr;
}
if (IsA(node, PlaceHolderVar))
@@ -2447,7 +2435,7 @@ build_tlist_index(List *tlist)
* (so nothing other than Vars and PlaceHolderVars can be matched).
*/
static indexed_tlist *
-build_tlist_index_other_vars(List *tlist, Index ignore_rel)
+build_tlist_index_other_vars(List *tlist, int ignore_rel)
{
indexed_tlist *itlist;
tlist_vinfo *vinfo;
@@ -2499,9 +2487,9 @@ build_tlist_index_other_vars(List *tlist, Index ignore_rel)
*/
static Var *
search_indexed_tlist_for_var(Var *var, indexed_tlist *itlist,
- Index newvarno, int rtoffset)
+ int newvarno, int rtoffset)
{
- Index varno = var->varno;
+ int varno = var->varno;
AttrNumber varattno = var->varattno;
tlist_vinfo *vinfo;
int i;
@@ -2539,7 +2527,7 @@ search_indexed_tlist_for_var(Var *var, indexed_tlist *itlist,
*/
static Var *
search_indexed_tlist_for_non_var(Expr *node,
- indexed_tlist *itlist, Index newvarno)
+ indexed_tlist *itlist, int newvarno)
{
TargetEntry *tle;
@@ -2581,7 +2569,7 @@ static Var *
search_indexed_tlist_for_sortgroupref(Expr *node,
Index sortgroupref,
indexed_tlist *itlist,
- Index newvarno)
+ int newvarno)
{
ListCell *lc;
@@ -2799,7 +2787,7 @@ static Node *
fix_upper_expr(PlannerInfo *root,
Node *node,
indexed_tlist *subplan_itlist,
- Index newvarno,
+ int newvarno,
int rtoffset,
double num_exec)
{
diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c
index 224c5153b15..387a35e1122 100644
--- a/src/backend/optimizer/prep/prepjointree.c
+++ b/src/backend/optimizer/prep/prepjointree.c
@@ -80,7 +80,7 @@ static Node *pull_up_simple_union_all(PlannerInfo *root, Node *jtnode,
static void pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root,
int parentRTindex, Query *setOpQuery,
int childRToffset);
-static void make_setop_translation_list(Query *query, Index newvarno,
+static void make_setop_translation_list(Query *query, int newvarno,
AppendRelInfo *appinfo);
static bool is_simple_subquery(PlannerInfo *root, Query *subquery,
RangeTblEntry *rte,
@@ -1372,7 +1372,7 @@ pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root, int parentRTindex,
* Also create the rather trivial reverse-translation array.
*/
static void
-make_setop_translation_list(Query *query, Index newvarno,
+make_setop_translation_list(Query *query, int newvarno,
AppendRelInfo *appinfo)
{
List *vars = NIL;
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index ccd2835c222..b932a83827f 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -6949,7 +6949,7 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
AttrNumber attnum;
int netlevelsup;
deparse_namespace *dpns;
- Index varno;
+ int varno;
AttrNumber varattno;
deparse_columns *colinfo;
char *refname;
@@ -6995,7 +6995,7 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
*/
if (context->appendparents && dpns->appendrels)
{
- Index pvarno = varno;
+ int pvarno = varno;
AttrNumber pvarattno = varattno;
AppendRelInfo *appinfo = dpns->appendrels[pvarno];
bool found = false;
@@ -7305,7 +7305,7 @@ get_name_for_var_field(Var *var, int fieldno,
AttrNumber attnum;
int netlevelsup;
deparse_namespace *dpns;
- Index varno;
+ int varno;
AttrNumber varattno;
TupleDesc tupleDesc;
Node *expr;