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)
278278SubLink * sublink = (SubLink * )expr ;
279279List * qtrees ;
280280Query * qtree ;
281- List * llist ;
282281
283282pstate -> p_hasSubLinks = true;
284283qtrees = parse_analyze (lcons (sublink -> subselect ,NIL ),pstate );
@@ -293,36 +292,48 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
293292if (sublink -> subLinkType != EXISTS_SUBLINK )
294293{
295294char * 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 ;
298297List * 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 &&
307304strcmp (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
310308sublink -> 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 ;
316319Expr * 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}
327338else
328339sublink -> oper = NIL ;