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

Commitb09fc7c

Browse files
committed
Ensure that whole-row junk Vars are always of composite type.
The EvalPlanQual machinery assumes that whole-row Vars generated for theoutputs of non-table RTEs will be of composite types. However, for thecase where the RTE is a function call returning a scalar type, we weredoing the wrong thing, as a result of sharing code with a parser casewhere the function's scalar output is wanted. (Or at least, that's whatthat case has done historically; it does seem a bit inconsistent.)To fix, extend makeWholeRowVar's API so that it can support both use-cases.This fixes Belinda Cussen's report of crashes during concurrent executionof UPDATEs involving joins to the result of UNNEST() --- in READ COMMITTEDmode, we'd run the EvalPlanQual machinery after a conflicting row updatecommits, and it was expecting to get a HeapTuple not a scalar datum fromthe "wholerowN" variable referencing the function RTE.Back-patch to 9.0 where the current EvalPlanQual implementation appeared.In 9.1 and up, this patch also fixes failure to attach the correctcollation to the Var generated for a scalar-result case. An example:regression=# select upper(x.*) from textcat('ab', 'cd') x;ERROR: could not determine which collation to use for upper() function
1 parent87b0dcf commitb09fc7c

File tree

4 files changed

+35
-25
lines changed

4 files changed

+35
-25
lines changed

‎src/backend/nodes/makefuncs.c

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,17 @@ makeVar(Index varno,
101101
* with error cases, but it's not worth changing now.) The vartype indicates
102102
* a rowtype; either a named composite type, or RECORD. This function
103103
* encapsulates the logic for determining the correct rowtype OID to use.
104+
*
105+
* If allowScalar is true, then for the case where the RTE is a function
106+
* returning a non-composite result type, we produce a normal Var referencing
107+
* the function's result directly, instead of the single-column composite
108+
* value that the whole-row notation might otherwise suggest.
104109
*/
105110
Var*
106111
makeWholeRowVar(RangeTblEntry*rte,
107112
Indexvarno,
108-
Indexvarlevelsup)
113+
Indexvarlevelsup,
114+
boolallowScalar)
109115
{
110116
Var*result;
111117
Oidtoid;
@@ -135,37 +141,32 @@ makeWholeRowVar(RangeTblEntry *rte,
135141
-1,
136142
varlevelsup);
137143
}
138-
else
144+
elseif (allowScalar)
139145
{
140-
/*
141-
* func returns scalar; instead of making a whole-row Var,
142-
* just reference the function's scalar output. (XXX this
143-
* seems a tad inconsistent, especially if "f.*" was
144-
* explicitly written ...)
145-
*/
146+
/* func returns scalar; just return its output as-is */
146147
result=makeVar(varno,
147148
1,
148149
toid,
149150
-1,
150151
varlevelsup);
151152
}
152-
break;
153-
caseRTE_VALUES:
154-
toid=RECORDOID;
155-
/* returns composite; same as relation case */
156-
result=makeVar(varno,
157-
InvalidAttrNumber,
158-
toid,
159-
-1,
160-
varlevelsup);
153+
else
154+
{
155+
/* func returns scalar, but we want a composite result */
156+
result=makeVar(varno,
157+
InvalidAttrNumber,
158+
RECORDOID,
159+
-1,
160+
varlevelsup);
161+
}
161162
break;
162163
default:
163164

164165
/*
165-
* RTE is a joinorsubselect.We represent this as a whole-row
166-
* Var of RECORD type.(Note that in most cases the Var will be
167-
* expanded to a RowExpr during planning, but that is not our
168-
* concern here.)
166+
* RTE is a join, subselect,orVALUES.We represent this as a
167+
*whole-rowVar of RECORD type.(Note that in most cases the Var
168+
*will beexpanded to a RowExpr during planning, but that is not
169+
*ourconcern here.)
169170
*/
170171
result=makeVar(varno,
171172
InvalidAttrNumber,

‎src/backend/optimizer/prep/preptlist.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ preprocess_targetlist(PlannerInfo *root, List *tlist)
160160
/* Not a table, so we need the whole row as a junk var */
161161
var=makeWholeRowVar(rt_fetch(rc->rti,range_table),
162162
rc->rti,
163-
0);
163+
0,
164+
false);
164165
snprintf(resname,sizeof(resname),"wholerow%u",rc->rowmarkId);
165166
tle=makeTargetEntry((Expr*)var,
166167
list_length(tlist)+1,

‎src/backend/parser/parse_expr.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2029,8 +2029,15 @@ transformWholeRowRef(ParseState *pstate, RangeTblEntry *rte, int location)
20292029
/* Find the RTE's rangetable location */
20302030
vnum=RTERangeTablePosn(pstate,rte,&sublevels_up);
20312031

2032-
/* Build the appropriate referencing node */
2033-
result=makeWholeRowVar(rte,vnum,sublevels_up);
2032+
/*
2033+
* Build the appropriate referencing node. Note that if the RTE is a
2034+
* function returning scalar, we create just a plain reference to the
2035+
* function value, not a composite containing a single column. This is
2036+
* pretty inconsistent at first sight, but it's what we've done
2037+
* historically. One argument for it is that "rel" and "rel.*" mean the
2038+
* same thing for composite relations, so why not for scalar functions...
2039+
*/
2040+
result=makeWholeRowVar(rte,vnum,sublevels_up, true);
20342041

20352042
/* location is not filled in by makeWholeRowVar */
20362043
result->location=location;

‎src/include/nodes/makefuncs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ extern Var *makeVar(Index varno,
3131

3232
externVar*makeWholeRowVar(RangeTblEntry*rte,
3333
Indexvarno,
34-
Indexvarlevelsup);
34+
Indexvarlevelsup,
35+
boolallowScalar);
3536

3637
externTargetEntry*makeTargetEntry(Expr*expr,
3738
AttrNumberresno,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp