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

Commiteeb3abe

Browse files
committed
Ignore resjunk targetlist entries when matching arguments to
a SubLink with the subplan's targetlist. This fixes a problem seen with,for example, a subselect that uses GROUP BY.
1 parent8c32f99 commiteeb3abe

File tree

1 file changed

+33
-22
lines changed

1 file changed

+33
-22
lines changed

‎src/backend/parser/parse_expr.c

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.49 1999/05/26 12:55:37 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.50 1999/07/11 02:04:19 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -278,7 +278,6 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
278278
SubLink*sublink= (SubLink*)expr;
279279
List*qtrees;
280280
Query*qtree;
281-
List*llist;
282281

283282
pstate->p_hasSubLinks= true;
284283
qtrees=parse_analyze(lcons(sublink->subselect,NIL),pstate);
@@ -293,36 +292,48 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
293292
if (sublink->subLinkType!=EXISTS_SUBLINK)
294293
{
295294
char*op=lfirst(sublink->oper);
296-
List*left_expr=sublink->lefthand;
297-
List*right_expr=((Query*)sublink->subselect)->targetList;
295+
List*left_list=sublink->lefthand;
296+
List*right_list=qtree->targetList;
298297
List*elist;
299298

300-
foreach(llist,left_expr)
301-
lfirst(llist)=transformExpr(pstate,lfirst(llist),precedence);
299+
foreach(elist,left_list)
300+
lfirst(elist)=transformExpr(pstate,lfirst(elist),
301+
precedence);
302302

303-
if (length(left_expr)!=length(right_expr))
304-
elog(ERROR,"parser: Subselect has too many or too few fields.");
305-
306-
if (length(left_expr)>1&&
303+
if (length(left_list)>1&&
307304
strcmp(op,"=")!=0&&strcmp(op,"<>")!=0)
308-
elog(ERROR,"parser: '%s' is not relational operator",op);
305+
elog(ERROR,"parser: '%s' is not relational operator",
306+
op);
309307

310308
sublink->oper=NIL;
311-
foreach(elist,left_expr)
309+
310+
/* Scan subquery's targetlist to find values that will be
311+
* matched against lefthand values. We need to ignore
312+
* resjunk targets, so doing the outer iteration over
313+
* right_list is easier than doing it over left_list.
314+
*/
315+
while (right_list!=NIL)
312316
{
313-
Node*lexpr=lfirst(elist);
314-
Node*rexpr=lfirst(right_expr);
315-
TargetEntry*tent= (TargetEntry*)rexpr;
317+
TargetEntry*tent= (TargetEntry*)lfirst(right_list);
318+
Node*lexpr;
316319
Expr*op_expr;
317320

318-
op_expr=make_op(op,lexpr,tent->expr);
319-
320-
if (op_expr->typeOid!=BOOLOID&&
321-
sublink->subLinkType!=EXPR_SUBLINK)
322-
elog(ERROR,"parser: '%s' must return 'bool' to be used with quantified predicate subquery",op);
323-
sublink->oper=lappend(sublink->oper,op_expr);
324-
right_expr=lnext(right_expr);
321+
if (!tent->resdom->resjunk)
322+
{
323+
if (left_list==NIL)
324+
elog(ERROR,"parser: Subselect has too many fields.");
325+
lexpr=lfirst(left_list);
326+
left_list=lnext(left_list);
327+
op_expr=make_op(op,lexpr,tent->expr);
328+
if (op_expr->typeOid!=BOOLOID&&
329+
sublink->subLinkType!=EXPR_SUBLINK)
330+
elog(ERROR,"parser: '%s' must return 'bool' to be used with quantified predicate subquery",op);
331+
sublink->oper=lappend(sublink->oper,op_expr);
332+
}
333+
right_list=lnext(right_list);
325334
}
335+
if (left_list!=NIL)
336+
elog(ERROR,"parser: Subselect has too few fields.");
326337
}
327338
else
328339
sublink->oper=NIL;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp