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

Commit01911c9

Browse files
committed
Repair list-vs-node confusion that resulted in failure for INNER JOIN ON.
Make it behave correctly when there are more than two tables beingjoined, also. Update regression test expected outputs.
1 parent4624b84 commit01911c9

File tree

3 files changed

+75
-58
lines changed

3 files changed

+75
-58
lines changed

‎src/backend/parser/parse_clause.c

Lines changed: 45 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.59 2000/04/1217:15:26 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.60 2000/05/1201:33:54 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -41,8 +41,8 @@ static List *addTargetToSortList(TargetEntry *tle, List *sortlist,
4141
staticboolexprIsInSortList(Node*expr,List*sortList,List*targetList);
4242

4343
#ifndefDISABLE_OUTER_JOINS
44-
staticNode*transformUsingClause(ParseState*pstate,List*using,List*left,List*right);
45-
44+
staticList*transformUsingClause(ParseState*pstate,List*using,
45+
List*left,List*right);
4646
#endif
4747

4848

@@ -94,32 +94,33 @@ setTargetTable(ParseState *pstate, char *relname)
9494
}
9595

9696

97-
Node*
98-
mergeInnerJoinQuals(ParseState*pstate,Node*clause);
99-
100-
Node*
97+
staticNode*
10198
mergeInnerJoinQuals(ParseState*pstate,Node*clause)
10299
{
103-
A_Expr*expr= (A_Expr*)pstate->p_join_quals;
100+
List*jquals;
104101

105-
if (expr==NULL)
106-
returnclause;
107-
108-
if (clause!=NULL)
102+
foreach(jquals,pstate->p_join_quals)
109103
{
110-
A_Expr*a=makeNode(A_Expr);
104+
Node*jqual= (Node*)lfirst(jquals);
105+
106+
if (clause==NULL)
107+
clause=jqual;
108+
else
109+
{
110+
A_Expr*a=makeNode(A_Expr);
111111

112-
a->oper=AND;
113-
a->opname=NULL;
114-
a->lexpr= (Node*)expr;
115-
a->rexpr=clause;
116-
expr=a;
112+
a->oper=AND;
113+
a->opname=NULL;
114+
a->lexpr=clause;
115+
a->rexpr=jqual;
116+
clause= (Node*)a;
117+
}
117118
}
118119

119-
/* Make sure that we don'tdo this twice... */
120-
pstate->p_join_quals=NULL;
120+
/* Make sure that we don'tadd same quals twice... */
121+
pstate->p_join_quals=NIL;
121122

122-
return(Node*)expr;
123+
returnclause;
123124
}/* mergeInnerJoinQuals() */
124125

125126
/*
@@ -131,7 +132,7 @@ transformWhereClause(ParseState *pstate, Node *clause)
131132
{
132133
Node*qual;
133134

134-
if (pstate->p_join_quals!=NULL)
135+
if (pstate->p_join_quals!=NIL)
135136
clause=mergeInnerJoinQuals(pstate,clause);
136137

137138
if (clause==NULL)
@@ -275,21 +276,22 @@ ExpandAttrs(Attr *attr)
275276

276277
/* transformUsingClause()
277278
* Take an ON or USING clause from a join expression and expand if necessary.
279+
* Result is an implicitly-ANDed list of untransformed qualification clauses.
278280
*/
279-
staticNode*
280-
transformUsingClause(ParseState*pstate,List*usingList,List*leftList,List*rightList)
281+
staticList*
282+
transformUsingClause(ParseState*pstate,List*usingList,
283+
List*leftList,List*rightList)
281284
{
282-
A_Expr*expr=NULL;
285+
List*result=NIL;
283286
List*using;
284287

285288
foreach(using,usingList)
286289
{
287-
List*col;
288-
A_Expr*e;
289-
290290
Attr*uattr=lfirst(using);
291291
Attr*lattr=NULL,
292292
*rattr=NULL;
293+
List*col;
294+
A_Expr*e;
293295

294296
/*
295297
* find the first instances of this column in the shape list and
@@ -324,22 +326,11 @@ transformUsingClause(ParseState *pstate, List *usingList, List *leftList, List *
324326
e->lexpr= (Node*)lattr;
325327
e->rexpr= (Node*)rattr;
326328

327-
if (expr!=NULL)
328-
{
329-
A_Expr*a=makeNode(A_Expr);
330-
331-
a->oper=AND;
332-
a->opname=NULL;
333-
a->lexpr= (Node*)expr;
334-
a->rexpr= (Node*)e;
335-
expr=a;
336-
}
337-
else
338-
expr=e;
329+
result=lappend(result,e);
339330
}
340331

341-
return((Node*)transformExpr(pstate, (Node*)expr,EXPR_COLUMN_FIRST));
342-
}/*transformUsiongClause() */
332+
returnresult;
333+
}/*transformUsingClause() */
343334

344335
#endif
345336

@@ -632,7 +623,7 @@ parseFromClause(ParseState *pstate, List *frmList)
632623

633624
printf("JOIN/USING input quals are %s\n",nodeToString(j->quals));
634625

635-
j->quals=(List*)transformUsingClause(pstate,shape,l_cols,r_cols);
626+
j->quals=transformUsingClause(pstate,shape,l_cols,r_cols);
636627

637628
printf("JOIN/USING transformed quals are %s\n",nodeToString(j->quals));
638629

@@ -650,7 +641,12 @@ parseFromClause(ParseState *pstate, List *frmList)
650641
else
651642
j->quals= (List*)lcons(j->quals,NIL);
652643

653-
pstate->p_join_quals= (Node*)j->quals;
644+
/* listCopy may not be needed here --- will j->quals list
645+
* be used again anywhere? The #ifdef'd code below may need
646+
* it, if it ever gets used...
647+
*/
648+
pstate->p_join_quals=nconc(pstate->p_join_quals,
649+
listCopy(j->quals));
654650

655651
#if0
656652
if (qual==NULL)
@@ -660,11 +656,13 @@ parseFromClause(ParseState *pstate, List *frmList)
660656
#endif
661657

662658
#if0
659+
/* XXX this code is WRONG because j->quals is a List
660+
* not a simple expression. Perhaps *qual
661+
* ought also to be a List and we append to it,
662+
* similarly to the way p_join_quals is handled above?
663+
*/
663664
if (*qual==NULL)
664665
{
665-
#endif
666-
667-
#if0
668666
/* merge qualified join clauses... */
669667
if (j->quals!=NULL)
670668
{
@@ -682,9 +680,6 @@ parseFromClause(ParseState *pstate, List *frmList)
682680
else
683681
*qual= (Node*)j->quals;
684682
}
685-
#endif
686-
687-
#if0
688683
}
689684
else
690685
{

‎src/include/parser/parse_node.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: parse_node.h,v 1.19 2000/04/1217:16:45 momjian Exp $
9+
* $Id: parse_node.h,v 1.20 2000/05/1201:33:52 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -17,9 +17,10 @@
1717
#include"utils/rel.h"
1818

1919
/* State information used during parse analysis
20-
* p_join_quals is a list of qualification expressions
21-
* found in the FROM clause. Needs to be available later
22-
* to merge with other qualifiers from the WHERE clause.
20+
* p_join_quals is a list of untransformed qualification expressions
21+
* (implicitly ANDed together) found in the FROM clause.
22+
* Needs to be available later to merge with other qualifiers from the
23+
* WHERE clause.
2324
*/
2425
typedefstructParseState
2526
{
@@ -36,7 +37,7 @@ typedef struct ParseState
3637
RangeTblEntry*p_target_rangetblentry;
3738
List*p_shape;
3839
List*p_alias;
39-
Node*p_join_quals;
40+
List*p_join_quals;
4041
}ParseState;
4142

4243
externParseState*make_parsestate(ParseState*parentParseState);

‎src/test/regress/expected/join.out

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,10 +274,22 @@ SELECT '' AS "xxx", *
274274
--
275275
SELECT '' AS "xxx", *
276276
FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i);
277-
ERROR: transformExpr: does not know how to transform node 501 (internal error)
277+
xxx | i | j | t | i | k
278+
-----+---+---+-------+---+----
279+
| 1 | 3 | one | 1 | -1
280+
| 2 | 2 | two | 2 | 2
281+
| 2 | 2 | two | 2 | 4
282+
| 3 | 1 | three | 3 | -3
283+
(4 rows)
284+
278285
SELECT '' AS "xxx", *
279286
FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.k);
280-
ERROR: transformExpr: does not know how to transform node 501 (internal error)
287+
xxx | i | j | t | i | k
288+
-----+---+---+------+---+---
289+
| 2 | 2 | two | 2 | 2
290+
| 4 | 0 | four | 2 | 4
291+
(2 rows)
292+
281293
SELECT '' AS "xxx", *
282294
FROM J1_TBL CROSS JOIN J2_TBL;
283295
xxx | i | j | t | i | k
@@ -305,7 +317,16 @@ SELECT '' AS "xxx", *
305317
--
306318
SELECT '' AS "xxx", *
307319
FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i <= J2_TBL.k);
308-
ERROR: transformExpr: does not know how to transform node 501 (internal error)
320+
xxx | i | j | t | i | k
321+
-----+---+---+-------+---+---
322+
| 1 | 3 | one | 2 | 2
323+
| 2 | 2 | two | 2 | 2
324+
| 1 | 3 | one | 2 | 4
325+
| 2 | 2 | two | 2 | 4
326+
| 3 | 1 | three | 2 | 4
327+
| 4 | 0 | four | 2 | 4
328+
(6 rows)
329+
309330
--
310331
-- Outer joins
311332
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp