On 4/8/21 8:13 AM, Tom Lane wrote:
I wrote:
Peter Eisentraut <peter.eisentr...@enterprisedb.com> writes:
Can we move forward with this?
We could just push the change and see what happens. But I was thinking
more in terms of doing that early in the v15 cycle. I remain skeptical
that we need a near-term fix.
To make sure we don't forget, I added an entry to the next CF for this.
Thanks for your efforts.
I tried to dive deeper: replace ROWID_VAR with -4 and explicitly change
types of varnos in the description of functions that can only work with
special varnos.
Use cases of OUTER_VAR looks simple (i guess). Use cases of INNER_VAR is
more complex because of the map_variable_attnos(). It is needed to
analyze how negative value of INNER_VAR can affect on this function.
INDEX_VAR causes potential problem:
in ExecInitForeignScan() and ExecInitForeignScan() we do
tlistvarno = INDEX_VAR;
here tlistvarno has non-negative type.
ROWID_VAR caused two problems in the check-world tests:
set_pathtarget_cost_width():
if (var->varno < root->simple_rel_array_size)
{
RelOptInfo *rel = root->simple_rel_array[var->varno];
...
and
replace_nestloop_params_mutator():
if (!bms_is_member(var->varno, root->curOuterRels))
I skipped this problems to see other weak points, but check-world
couldn't find another.
--
regards,
Andrey Lepikhov
Postgres Professional
>From 6ba9441cc43a2ccf868ca271494bf5b9950692e6 Mon Sep 17 00:00:00 2001
From: Andrey Lepikhov <a.lepik...@postgrespro.ru>
Date: Thu, 8 Apr 2021 08:43:04 +0500
Subject: [PATCH] Remove 64k rangetable limit.
---
src/backend/nodes/bitmapset.c | 1 +
src/backend/nodes/outfuncs.c | 2 +-
src/backend/nodes/readfuncs.c | 2 +-
src/backend/optimizer/path/costsize.c | 3 ++-
src/backend/optimizer/plan/createplan.c | 3 ++-
src/backend/optimizer/plan/setrefs.c | 30 +++++++++----------------
src/include/nodes/primnodes.h | 12 +++++-----
7 files changed, 23 insertions(+), 30 deletions(-)
diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c
index 649478b0d4..c0d50c85da 100644
--- a/src/backend/nodes/bitmapset.c
+++ b/src/backend/nodes/bitmapset.c
@@ -23,6 +23,7 @@
#include "common/hashfn.h"
#include "nodes/bitmapset.h"
#include "nodes/pg_list.h"
+#include "nodes/primnodes.h"
#include "port/pg_bitutils.h"
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 4a8dc2d86d..4c3de615d1 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -1115,7 +1115,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 9924727851..d084eee6ef 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 05686d0194..ac72bddfae 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -5934,7 +5934,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 22f10fa339..defd179bca 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -4809,7 +4809,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 70c0fa07e6..6009eabaf2 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -66,7 +66,7 @@ typedef struct
{
PlannerInfo *root;
indexed_tlist *subplan_itlist;
- Index newvarno;
+ int refvarno;
int rtoffset;
double num_exec;
} fix_upper_expr_context;
@@ -147,7 +147,7 @@ static Var *search_indexed_tlist_for_var(Var *var,
int rtoffset);
static Var *search_indexed_tlist_for_non_var(Expr *node,
indexed_tlist *itlist,
- Index newvarno);
+ int refvarno);
static Var *search_indexed_tlist_for_sortgroupref(Expr *node,
Index sortgroupref,
indexed_tlist *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 refvarno,
int rtoffset, double num_exec);
static Node *fix_upper_expr_mutator(Node *node,
fix_upper_expr_context *context);
@@ -468,16 +468,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.
*
@@ -2503,7 +2493,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 refvarno)
{
TargetEntry *tle;
@@ -2523,7 +2513,7 @@ search_indexed_tlist_for_non_var(Expr *node,
/* Found a matching subplan output expression */
Var *newvar;
- newvar = makeVarFromTargetEntry(newvarno, tle);
+ newvar = makeVarFromTargetEntry(refvarno, tle);
newvar->varnosyn = 0; /* wasn't ever a plain Var */
newvar->varattnosyn = 0;
return newvar;
@@ -2763,7 +2753,7 @@ static Node *
fix_upper_expr(PlannerInfo *root,
Node *node,
indexed_tlist *subplan_itlist,
- Index newvarno,
+ int refvarno,
int rtoffset,
double num_exec)
{
@@ -2771,7 +2761,7 @@ fix_upper_expr(PlannerInfo *root,
context.root = root;
context.subplan_itlist = subplan_itlist;
- context.newvarno = newvarno;
+ context.refvarno = refvarno;
context.rtoffset = rtoffset;
context.num_exec = num_exec;
return fix_upper_expr_mutator(node, &context);
@@ -2790,7 +2780,7 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context)
newvar = search_indexed_tlist_for_var(var,
context->subplan_itlist,
- context->newvarno,
+ context->refvarno,
context->rtoffset);
if (!newvar)
elog(ERROR, "variable not found in subplan target list");
@@ -2805,7 +2795,7 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context)
{
newvar = search_indexed_tlist_for_non_var((Expr *) phv,
context->subplan_itlist,
- context->newvarno);
+ context->refvarno);
if (newvar)
return (Node *) newvar;
}
@@ -2817,7 +2807,7 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context)
{
newvar = search_indexed_tlist_for_non_var((Expr *) node,
context->subplan_itlist,
- context->newvarno);
+ context->refvarno);
if (newvar)
return (Node *) newvar;
}
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index f2ac4e51f1..34effe0f44 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -172,12 +172,12 @@ 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 ROWID_VAR 65003 /* row identity column during planning */
+#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 ROWID_VAR (-4) /* row identity column during planning */
-#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
@@ -186,7 +186,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") */
--
2.25.1