Skip to content

Commit 246256a

Browse files
Nikita Glukhovl-wang
authored andcommitted
Part 2: Pass field accessors to generic subscripting
Field accessors are represented as String nodes in refupperexprs for distinguishing from ordinary text subscripts which can be needed for correct EXPLAIN. Strings node is no longer a valid expression nodes, so added special handling for them in walkers in nodeFuncs etc.
1 parent e511885 commit 246256a

File tree

4 files changed

+121
-27
lines changed

4 files changed

+121
-27
lines changed

src/backend/executor/execExpr.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3328,9 +3328,15 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref,
33283328
{
33293329
sbsrefstate->upperprovided[i] = true;
33303330
/* Each subscript is evaluated into appropriate array entry */
3331-
ExecInitExprRec(e, state,
3332-
&sbsrefstate->upperindex[i],
3333-
&sbsrefstate->upperindexnull[i]);
3331+
if (IsA(e, String))
3332+
{
3333+
sbsrefstate->upperindex[i] = CStringGetTextDatum(strVal(e));
3334+
sbsrefstate->upperindexnull[i] = false;
3335+
}
3336+
else
3337+
ExecInitExprRec(e, state,
3338+
&sbsrefstate->upperindex[i],
3339+
&sbsrefstate->upperindexnull[i]);
33343340
}
33353341
i++;
33363342
}
@@ -3351,9 +3357,15 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref,
33513357
{
33523358
sbsrefstate->lowerprovided[i] = true;
33533359
/* Each subscript is evaluated into appropriate array entry */
3354-
ExecInitExprRec(e, state,
3355-
&sbsrefstate->lowerindex[i],
3356-
&sbsrefstate->lowerindexnull[i]);
3360+
if (IsA(e, String))
3361+
{
3362+
sbsrefstate->lowerindex[i] = CStringGetTextDatum(strVal(e));
3363+
sbsrefstate->lowerindexnull[i] = false;
3364+
}
3365+
else
3366+
ExecInitExprRec(e, state,
3367+
&sbsrefstate->lowerindex[i],
3368+
&sbsrefstate->lowerindexnull[i]);
33573369
}
33583370
i++;
33593371
}

src/backend/nodes/nodeFuncs.c

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2182,12 +2182,28 @@ expression_tree_walker_impl(Node *node,
21822182
case T_SubscriptingRef:
21832183
{
21842184
SubscriptingRef *sbsref = (SubscriptingRef *) node;
2185+
ListCell *lc;
2186+
2187+
/*
2188+
* Recurse directly for upper/lower container index lists,
2189+
* skipping String subscripts used for dot notation.
2190+
*/
2191+
foreach(lc, sbsref->refupperindexpr)
2192+
{
2193+
Node *expr = lfirst(lc);
2194+
2195+
if (expr && !IsA(expr, String) && WALK(expr))
2196+
return true;
2197+
}
2198+
2199+
foreach(lc, sbsref->reflowerindexpr)
2200+
{
2201+
Node *expr = lfirst(lc);
2202+
2203+
if (expr && !IsA(expr, String) && WALK(expr))
2204+
return true;
2205+
}
21852206

2186-
/* recurse directly for upper/lower container index lists */
2187-
if (LIST_WALK(sbsref->refupperindexpr))
2188-
return true;
2189-
if (LIST_WALK(sbsref->reflowerindexpr))
2190-
return true;
21912207
/* walker must see the refexpr and refassgnexpr, however */
21922208
if (WALK(sbsref->refexpr))
21932209
return true;
@@ -3082,12 +3098,51 @@ expression_tree_mutator_impl(Node *node,
30823098
{
30833099
SubscriptingRef *sbsref = (SubscriptingRef *) node;
30843100
SubscriptingRef *newnode;
3101+
ListCell *lc;
3102+
List *exprs = NIL;
30853103

30863104
FLATCOPY(newnode, sbsref, SubscriptingRef);
3087-
MUTATE(newnode->refupperindexpr, sbsref->refupperindexpr,
3088-
List *);
3089-
MUTATE(newnode->reflowerindexpr, sbsref->reflowerindexpr,
3090-
List *);
3105+
3106+
foreach(lc, sbsref->refupperindexpr)
3107+
{
3108+
Node *expr = lfirst(lc);
3109+
3110+
if (expr && IsA(expr, String))
3111+
{
3112+
String *str;
3113+
3114+
FLATCOPY(str, expr, String);
3115+
expr = (Node *) str;
3116+
}
3117+
else
3118+
expr = mutator(expr, context);
3119+
3120+
exprs = lappend(exprs, expr);
3121+
}
3122+
3123+
newnode->refupperindexpr = exprs;
3124+
3125+
exprs = NIL;
3126+
3127+
foreach(lc, sbsref->reflowerindexpr)
3128+
{
3129+
Node *expr = lfirst(lc);
3130+
3131+
if (expr && IsA(expr, String))
3132+
{
3133+
String *str;
3134+
3135+
FLATCOPY(str, expr, String);
3136+
expr = (Node *) str;
3137+
}
3138+
else
3139+
expr = mutator(expr, context);
3140+
3141+
exprs = lappend(exprs, expr);
3142+
}
3143+
3144+
newnode->reflowerindexpr = exprs;
3145+
30913146
MUTATE(newnode->refexpr, sbsref->refexpr,
30923147
Expr *);
30933148
MUTATE(newnode->refassgnexpr, sbsref->refassgnexpr,

src/backend/parser/parse_collate.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -680,11 +680,25 @@ assign_collations_walker(Node *node, assign_collations_context *context)
680680
* contribute anything.)
681681
*/
682682
SubscriptingRef *sbsref = (SubscriptingRef *) node;
683+
ListCell *lc;
684+
685+
/* skip String subscripts used for dot notation */
686+
foreach(lc, sbsref->refupperindexpr)
687+
{
688+
Node *expr = lfirst(lc);
689+
690+
if (expr && !IsA(expr, String))
691+
assign_expr_collations(context->pstate, expr);
692+
}
693+
694+
foreach(lc, sbsref->reflowerindexpr)
695+
{
696+
Node *expr = lfirst(lc);
697+
698+
if (expr && !IsA(expr, String))
699+
assign_expr_collations(context->pstate, expr);
700+
}
683701

684-
assign_expr_collations(context->pstate,
685-
(Node *) sbsref->refupperindexpr);
686-
assign_expr_collations(context->pstate,
687-
(Node *) sbsref->reflowerindexpr);
688702
(void) assign_collations_walker((Node *) sbsref->refexpr,
689703
&loccontext);
690704
(void) assign_collations_walker((Node *) sbsref->refassgnexpr,

src/backend/utils/adt/ruleutils.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "nodes/makefuncs.h"
4848
#include "nodes/nodeFuncs.h"
4949
#include "nodes/pathnodes.h"
50+
#include "nodes/subscripting.h"
5051
#include "optimizer/optimizer.h"
5152
#include "parser/parse_agg.h"
5253
#include "parser/parse_func.h"
@@ -12916,17 +12917,29 @@ printSubscripts(SubscriptingRef *sbsref, deparse_context *context)
1291612917
lowlist_item = list_head(sbsref->reflowerindexpr); /* could be NULL */
1291712918
foreach(uplist_item, sbsref->refupperindexpr)
1291812919
{
12919-
appendStringInfoChar(buf, '[');
12920-
if (lowlist_item)
12920+
Node *up = (Node *) lfirst(uplist_item);
12921+
12922+
if (IsA(up, String))
12923+
{
12924+
appendStringInfoChar(buf, '.');
12925+
appendStringInfoString(buf, quote_identifier(strVal(up)));
12926+
}
12927+
else
1292112928
{
12929+
appendStringInfoChar(buf, '[');
12930+
if (lowlist_item)
12931+
{
12932+
/* If subexpression is NULL, get_rule_expr prints nothing */
12933+
get_rule_expr((Node *) lfirst(lowlist_item), context, false);
12934+
appendStringInfoChar(buf, ':');
12935+
}
1292212936
/* If subexpression is NULL, get_rule_expr prints nothing */
12923-
get_rule_expr((Node *) lfirst(lowlist_item), context, false);
12924-
appendStringInfoChar(buf, ':');
12925-
lowlist_item = lnext(sbsref->reflowerindexpr, lowlist_item);
12937+
get_rule_expr((Node *) lfirst(uplist_item), context, false);
12938+
appendStringInfoChar(buf, ']');
1292612939
}
12927-
/* If subexpression is NULL, get_rule_expr prints nothing */
12928-
get_rule_expr((Node *) lfirst(uplist_item), context, false);
12929-
appendStringInfoChar(buf, ']');
12940+
12941+
if (lowlist_item)
12942+
lowlist_item = lnext(sbsref->reflowerindexpr, lowlist_item);
1293012943
}
1293112944
}
1293212945

0 commit comments

Comments
 (0)