Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7393711

Browse files
committed
Improve implementation of CRE-stack-flattening in map_variable_attnos().
I (tgl) objected to the obscure implementation introduced in commit1c497fa. This one seems a bit less action-at-a-distance-y, at theprice of repeating a few lines of code.Improve the comments about what the function is doing, too.Amit Khandekar, whacked around a bit more by meDiscussion:https://postgr.es/m/CAJ3gD9egYTyHUH0nTMxm8-1m3RvdqEbaTyGC-CUNtYf7tKNDaQ@mail.gmail.com
1 parent5229db6 commit7393711

File tree

1 file changed

+55
-46
lines changed

1 file changed

+55
-46
lines changed

‎src/backend/rewrite/rewriteManip.c

Lines changed: 55 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,9 +1203,11 @@ replace_rte_variables_mutator(Node *node,
12031203
* appear in the expression.
12041204
*
12051205
* If the expression tree contains a whole-row Var for the target RTE,
1206-
* *found_whole_row is returned as TRUE. In addition, if to_rowtype is
1207-
* not InvalidOid, we modify the Var's vartype and insert a ConvertRowTypeExpr
1208-
* to map back to the orignal rowtype. Callers that don't provide to_rowtype
1206+
* *found_whole_row is set to TRUE. In addition, if to_rowtype is
1207+
* not InvalidOid, we replace the Var with a Var of that vartype, inserting
1208+
* a ConvertRowTypeExpr to map back to the rowtype expected by the expression.
1209+
* (Therefore, to_rowtype had better be a child rowtype of the rowtype of the
1210+
* RTE we're changing references to.) Callers that don't provide to_rowtype
12091211
* should report an error if *found_row_type is true; we don't do that here
12101212
* because we don't know exactly what wording for the error message would
12111213
* be most appropriate. The caller will be aware of the context.
@@ -1221,10 +1223,8 @@ typedef struct
12211223
intsublevels_up;/* (current) nesting depth */
12221224
constAttrNumber*attno_map;/* map array for user attnos */
12231225
intmap_length;/* number of entries in attno_map[] */
1224-
/* Target type when converting whole-row vars */
1225-
Oidto_rowtype;
1226+
Oidto_rowtype;/* change whole-row Vars to this type */
12261227
bool*found_whole_row;/* output flag */
1227-
boolcoerced_var;/* var is under ConvertRowTypeExpr */
12281228
}map_variable_attnos_context;
12291229

12301230
staticNode*
@@ -1244,7 +1244,8 @@ map_variable_attnos_mutator(Node *node,
12441244
Var*newvar= (Var*)palloc(sizeof(Var));
12451245
intattno=var->varattno;
12461246

1247-
*newvar=*var;
1247+
*newvar=*var;/* initially copy all fields of the Var */
1248+
12481249
if (attno>0)
12491250
{
12501251
/* user-defined column, replace attno */
@@ -1259,39 +1260,29 @@ map_variable_attnos_mutator(Node *node,
12591260
/* whole-row variable, warn caller */
12601261
*(context->found_whole_row)= true;
12611262

1262-
/* If the callers expects us to convert the same, do so. */
1263-
if (OidIsValid(context->to_rowtype))
1263+
/* If the caller expects us to convert the Var, do so. */
1264+
if (OidIsValid(context->to_rowtype)&&
1265+
context->to_rowtype!=var->vartype)
12641266
{
1265-
/* No support for RECORDOID. */
1267+
ConvertRowtypeExpr*r;
1268+
1269+
/* This certainly won't work for a RECORD variable. */
12661270
Assert(var->vartype!=RECORDOID);
12671271

1268-
/* Don't convert unless necessary. */
1269-
if (context->to_rowtype!=var->vartype)
1270-
{
1271-
/* Var itself is converted to the requested type. */
1272-
newvar->vartype=context->to_rowtype;
1273-
1274-
/*
1275-
* If this var is already under a ConvertRowtypeExpr,
1276-
* we don't have to add another one.
1277-
*/
1278-
if (!context->coerced_var)
1279-
{
1280-
ConvertRowtypeExpr*r;
1281-
1282-
/*
1283-
* And a conversion node on top to convert back to
1284-
* the original type.
1285-
*/
1286-
r=makeNode(ConvertRowtypeExpr);
1287-
r->arg= (Expr*)newvar;
1288-
r->resulttype=var->vartype;
1289-
r->convertformat=COERCE_IMPLICIT_CAST;
1290-
r->location=-1;
1291-
1292-
return (Node*)r;
1293-
}
1294-
}
1272+
/* Var itself is changed to the requested type. */
1273+
newvar->vartype=context->to_rowtype;
1274+
1275+
/*
1276+
* Add a conversion node on top to convert back to the
1277+
* original type expected by the expression.
1278+
*/
1279+
r=makeNode(ConvertRowtypeExpr);
1280+
r->arg= (Expr*)newvar;
1281+
r->resulttype=var->vartype;
1282+
r->convertformat=COERCE_IMPLICIT_CAST;
1283+
r->location=-1;
1284+
1285+
return (Node*)r;
12951286
}
12961287
}
12971288
return (Node*)newvar;
@@ -1301,24 +1292,43 @@ map_variable_attnos_mutator(Node *node,
13011292
elseif (IsA(node,ConvertRowtypeExpr))
13021293
{
13031294
ConvertRowtypeExpr*r= (ConvertRowtypeExpr*)node;
1295+
Var*var= (Var*)r->arg;
13041296

13051297
/*
1306-
* If this is coercing a var (which is typical), convert only the var,
1307-
* as against adding another ConvertRowtypeExpr over it.
1298+
* If this is coercing a whole-row Var that we need to convert, then
1299+
* just convert the Var without adding an extra ConvertRowtypeExpr.
1300+
* Effectively we're simplifying var::parenttype::grandparenttype into
1301+
* just var::grandparenttype. This avoids building stacks of CREs if
1302+
* this function is applied repeatedly.
13081303
*/
1309-
if (IsA(r->arg,Var))
1304+
if (IsA(var,Var)&&
1305+
var->varno==context->target_varno&&
1306+
var->varlevelsup==context->sublevels_up&&
1307+
var->varattno==0&&
1308+
OidIsValid(context->to_rowtype)&&
1309+
context->to_rowtype!=var->vartype)
13101310
{
13111311
ConvertRowtypeExpr*newnode;
1312+
Var*newvar= (Var*)palloc(sizeof(Var));
1313+
1314+
/* whole-row variable, warn caller */
1315+
*(context->found_whole_row)= true;
1316+
1317+
*newvar=*var;/* initially copy all fields of the Var */
1318+
1319+
/* This certainly won't work for a RECORD variable. */
1320+
Assert(var->vartype!=RECORDOID);
1321+
1322+
/* Var itself is changed to the requested type. */
1323+
newvar->vartype=context->to_rowtype;
13121324

13131325
newnode= (ConvertRowtypeExpr*)palloc(sizeof(ConvertRowtypeExpr));
1314-
*newnode=*r;
1315-
context->coerced_var= true;
1316-
newnode->arg= (Expr*)map_variable_attnos_mutator((Node*)r->arg,context);
1317-
context->coerced_var= false;
1326+
*newnode=*r;/* initially copy all fields of the CRE */
1327+
newnode->arg= (Expr*)newvar;
13181328

13191329
return (Node*)newnode;
13201330
}
1321-
/*Else fall through the expressiontree mutator */
1331+
/*otherwise fall throughto processthe expressionnormally */
13221332
}
13231333
elseif (IsA(node,Query))
13241334
{
@@ -1351,7 +1361,6 @@ map_variable_attnos(Node *node,
13511361
context.map_length=map_length;
13521362
context.to_rowtype=to_rowtype;
13531363
context.found_whole_row=found_whole_row;
1354-
context.coerced_var= false;
13551364

13561365
*found_whole_row= false;
13571366

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp