Skip to content

Commit b204d10

Browse files
committed
Executor no longer cares about mergejoinop, mergerightorder, mergeleftorder,
so remove them from MergeJoin node. Hack together a partial solution for commuted mergejoin operators --- yesterday a mergejoin int4 = int8 would crash if the planner decided to commute it, today it works. The planner's representation of mergejoins really needs a rewrite though. Also, further testing of mergejoin ops in opr_sanity regress test.
1 parent d077c61 commit b204d10

File tree

10 files changed

+156
-95
lines changed

10 files changed

+156
-95
lines changed

src/backend/nodes/copyfuncs.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.74 1999/02/22 19:55:42 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.75 1999/03/01 00:10:30 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -326,16 +326,6 @@ _copyMergeJoin(MergeJoin *from)
326326
*/
327327
Node_Copy(from, newnode, mergeclauses);
328328

329-
newnode->mergejoinop = from->mergejoinop;
330-
331-
newnode->mergerightorder = (Oid *) palloc(sizeof(Oid) * 2);
332-
newnode->mergerightorder[0] = from->mergerightorder[0];
333-
newnode->mergerightorder[1] = 0;
334-
335-
newnode->mergeleftorder = (Oid *) palloc(sizeof(Oid) * 2);
336-
newnode->mergeleftorder[0] = from->mergeleftorder[0];
337-
newnode->mergeleftorder[1] = 0;
338-
339329
return newnode;
340330
}
341331

src/backend/nodes/freefuncs.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.14 1999/02/22 19:55:42 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.15 1999/03/01 00:10:31 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -267,9 +267,6 @@ _freeMergeJoin(MergeJoin *node)
267267
*/
268268
freeObject(node->mergeclauses);
269269

270-
pfree(node->mergerightorder);
271-
pfree(node->mergeleftorder);
272-
273270
pfree(node);
274271
}
275272

src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* Copyright (c) 1994, Regents of the University of California
77
*
8-
* $Id: outfuncs.c,v 1.76 1999/02/23 08:01:47 thomas Exp $
8+
* $Id: outfuncs.c,v 1.77 1999/03/01 00:10:31 tgl Exp $
99
*
1010
* NOTES
1111
* Every (plan) node in POSTGRES has an associated "out" routine which
@@ -371,12 +371,6 @@ _outMergeJoin(StringInfo str, MergeJoin *node)
371371

372372
appendStringInfo(str, " :mergeclauses ");
373373
_outNode(str, node->mergeclauses);
374-
375-
appendStringInfo(str,
376-
" :mergejoinop %u :mergerightorder %u :mergeleftorder %u ",
377-
node->mergejoinop,
378-
node->mergerightorder,
379-
node->mergeleftorder);
380374
}
381375

382376
/*

src/backend/nodes/readfuncs.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.59 1999/02/18 00:49:15 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.60 1999/03/01 00:10:31 tgl Exp $
1111
*
1212
* NOTES
1313
* Most of the read functions for plan nodes are tested. (In fact, they
@@ -426,10 +426,6 @@ _readMergeJoin()
426426
token = lsptok(NULL, &length); /* eat :mergeclauses */
427427
local_node->mergeclauses = nodeRead(true); /* now read it */
428428

429-
token = lsptok(NULL, &length); /* eat :mergejoinop */
430-
token = lsptok(NULL, &length); /* get mergejoinop */
431-
local_node->mergejoinop = atol(token);
432-
433429
return local_node;
434430
}
435431

src/backend/optimizer/path/mergeutils.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/mergeutils.c,v 1.19 1999/02/15 03:22:06 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/mergeutils.c,v 1.20 1999/03/01 00:10:32 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -27,6 +27,14 @@
2727
* it within a mergeinfo node containing other clause nodes with the same
2828
* mergejoin ordering.
2929
*
30+
* XXX This is completely braindead: there is no reason anymore to segregate
31+
* mergejoin clauses by join operator, since the executor can handle mergejoin
32+
* clause sets with different operators in them. Instead, we ought to be
33+
* building a MergeInfo for each potentially useful ordering of the input
34+
* relations. But right now the optimizer's internal data structures do not
35+
* support that (MergeInfo can only store one MergeOrder for a set of clauses).
36+
* Something to fix next time...
37+
*
3038
* 'restrictinfo_list' is the list of restrictinfo nodes
3139
* 'inner_relid' is the relid of the inner join relation
3240
*
@@ -38,7 +46,7 @@ group_clauses_by_order(List *restrictinfo_list,
3846
int inner_relid)
3947
{
4048
List *mergeinfo_list = NIL;
41-
List *xrestrictinfo = NIL;
49+
List *xrestrictinfo;
4250

4351
foreach(xrestrictinfo, restrictinfo_list)
4452
{
@@ -84,10 +92,10 @@ group_clauses_by_order(List *restrictinfo_list,
8492
mergeinfo_list);
8593
}
8694

87-
((JoinMethod *) xmergeinfo)->clauses = lcons(clause,
88-
((JoinMethod *) xmergeinfo)->clauses);
89-
((JoinMethod *) xmergeinfo)->jmkeys = lcons(jmkeys,
90-
((JoinMethod *) xmergeinfo)->jmkeys);
95+
xmergeinfo->jmethod.clauses = lcons(clause,
96+
xmergeinfo->jmethod.clauses);
97+
xmergeinfo->jmethod.jmkeys = lcons(jmkeys,
98+
xmergeinfo->jmethod.jmkeys);
9199
}
92100
}
93101
return mergeinfo_list;

src/backend/optimizer/plan/createplan.c

Lines changed: 73 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.49 1999/02/21 03:48:45 scrappy Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.50 1999/03/01 00:10:33 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -44,6 +44,8 @@
4444
#define NONAME_MATERIAL 2
4545

4646
static List *switch_outer(List *clauses);
47+
static Oid *generate_merge_input_sortorder(List *pathkeys,
48+
MergeOrder *mergeorder);
4749
static Scan *create_scan_node(Path *best_path, List *tlist);
4850
static Join *create_join_node(JoinPath *best_path, List *tlist);
4951
static SeqScan *create_seqscan_node(Path *best_path, List *tlist,
@@ -70,8 +72,7 @@ static HashJoin *make_hashjoin(List *tlist, List *qpqual,
7072
List *hashclauses, Plan *lefttree, Plan *righttree);
7173
static Hash *make_hash(List *tlist, Var *hashkey, Plan *lefttree);
7274
static MergeJoin *make_mergejoin(List *tlist, List *qpqual,
73-
List *mergeclauses, Oid opcode, Oid *rightorder,
74-
Oid *leftorder, Plan *righttree, Plan *lefttree);
75+
List *mergeclauses, Plan *righttree, Plan *lefttree);
7576
static Material *make_material(List *tlist, Oid nonameid, Plan *lefttree,
7677
int keycount);
7778

@@ -505,9 +506,6 @@ create_mergejoin_node(MergePath *best_path,
505506
{
506507
List *qpqual,
507508
*mergeclauses;
508-
RegProcedure opcode;
509-
Oid *outer_order,
510-
*inner_order;
511509
MergeJoin *join_node;
512510

513511

@@ -528,50 +526,43 @@ create_mergejoin_node(MergePath *best_path,
528526
outer_tlist,
529527
inner_tlist));
530528

531-
opcode = get_opcode((best_path->jpath.path.pathorder->ord.merge)->join_operator);
532-
533-
outer_order = (Oid *) palloc(sizeof(Oid) * 2);
534-
outer_order[0] = (best_path->jpath.path.pathorder->ord.merge)->left_operator;
535-
outer_order[1] = 0;
536-
537-
inner_order = (Oid *) palloc(sizeof(Oid) * 2);
538-
inner_order[0] = (best_path->jpath.path.pathorder->ord.merge)->right_operator;
539-
inner_order[1] = 0;
540-
541529
/*
542530
* Create explicit sort paths for the outer and inner join paths if
543531
* necessary. The sort cost was already accounted for in the path.
544532
*/
545533
if (best_path->outersortkeys)
546534
{
535+
Oid *outer_order = generate_merge_input_sortorder(
536+
best_path->outersortkeys,
537+
best_path->jpath.path.pathorder->ord.merge);
547538
Noname *sorted_outer_node = make_noname(outer_tlist,
548-
best_path->outersortkeys,
549-
outer_order,
550-
outer_node,
551-
NONAME_SORT);
539+
best_path->outersortkeys,
540+
outer_order,
541+
outer_node,
542+
NONAME_SORT);
552543

553544
sorted_outer_node->plan.cost = outer_node->cost;
554545
outer_node = (Plan *) sorted_outer_node;
555546
}
556547

557548
if (best_path->innersortkeys)
558549
{
550+
Oid *inner_order = generate_merge_input_sortorder(
551+
best_path->innersortkeys,
552+
best_path->jpath.path.pathorder->ord.merge);
559553
Noname *sorted_inner_node = make_noname(inner_tlist,
560554
best_path->innersortkeys,
561555
inner_order,
562556
inner_node,
563557
NONAME_SORT);
564558

565-
sorted_inner_node->plan.cost = outer_node->cost;
559+
sorted_inner_node->plan.cost = outer_node->cost; /* XXX not inner_node? */
566560
inner_node = (Plan *) sorted_inner_node;
567561
}
568562

569563
join_node = make_mergejoin(tlist,
570564
qpqual,
571565
mergeclauses,
572-
opcode,
573-
inner_order,
574-
outer_order,
575566
inner_node,
576567
outer_node);
577568

@@ -662,7 +653,7 @@ fix_indxqual_references(Node *clause, Path *index_path)
662653
pos++;
663654
}
664655
}
665-
newclause = copyObject((Node *) clause);
656+
newclause = copyObject(clause);
666657
((Var *) newclause)->varattno = pos + 1;
667658
return newclause;
668659
}
@@ -760,35 +751,39 @@ fix_indxqual_references(Node *clause, Path *index_path)
760751
* switch_outer
761752
* Given a list of merge clauses, rearranges the elements within the
762753
* clauses so the outer join variable is on the left and the inner is on
763-
* the right.
764-
*
765-
* Returns the rearranged list ?
766-
*
767-
* XXX Shouldn't the operator be commuted?!
754+
* the right. The original list is not touched; a modified list
755+
* is returned.
768756
*/
769757
static List *
770758
switch_outer(List *clauses)
771759
{
772760
List *t_list = NIL;
773-
Expr *temp = NULL;
774-
List *i = NIL;
761+
Expr *temp;
762+
List *i;
775763
Expr *clause;
776764
Node *op;
777765

778766
foreach(i, clauses)
779767
{
780768
clause = lfirst(i);
769+
Assert(is_opclause((Node*) clause));
781770
op = (Node *) get_rightop(clause);
782771
Assert(op != (Node*) NULL);
783772
if (IsA(op, ArrayRef))
784773
op = ((ArrayRef *) op)->refexpr;
785774
Assert(IsA(op, Var));
786775
if (var_is_outer((Var *) op))
787776
{
777+
/* Duplicate just enough of the structure to allow commuting
778+
* the clause without changing the original list. Could use
779+
* copyObject, but a complete deep copy is overkill.
780+
*/
788781
temp = make_clause(clause->opType, clause->oper,
789-
lcons(get_rightop(clause),
790-
lcons(get_leftop(clause),
782+
lcons(get_leftop(clause),
783+
lcons(get_rightop(clause),
791784
NIL)));
785+
/* Commute it --- note this modifies the temp node in-place. */
786+
CommuteClause((Node *) temp);
792787
t_list = lappend(t_list, temp);
793788
}
794789
else
@@ -797,6 +792,45 @@ switch_outer(List *clauses)
797792
return t_list;
798793
}
799794

795+
/*
796+
* generate_merge_input_sortorder
797+
*
798+
* Generate the list of sort ops needed to sort one of the input paths for
799+
* a merge. We may have to use either left or right sortop for each item,
800+
* since the original mergejoin clause may or may not have been commuted
801+
* (compare switch_outer above).
802+
*
803+
* XXX This is largely a crock. It works only because group_clauses_by_order
804+
* only groups together mergejoin clauses that have identical MergeOrder info,
805+
* which means we can safely use a single MergeOrder input to deal with all
806+
* the data. There should be a more general data structure that allows coping
807+
* with groups of mergejoin clauses that have different join operators.
808+
*/
809+
static Oid *
810+
generate_merge_input_sortorder(List *pathkeys, MergeOrder *mergeorder)
811+
{
812+
int listlength = length(pathkeys);
813+
Oid *result = (Oid*) palloc(sizeof(Oid) * (listlength+1));
814+
Oid *nextsortop = result;
815+
List *p;
816+
817+
foreach(p, pathkeys)
818+
{
819+
Var *pkey = (Var*) lfirst((List*) lfirst(p));
820+
Assert(IsA(pkey, Var));
821+
if (pkey->vartype == mergeorder->left_type)
822+
*nextsortop++ = mergeorder->left_operator;
823+
else if (pkey->vartype == mergeorder->right_type)
824+
*nextsortop++ = mergeorder->right_operator;
825+
else
826+
elog(ERROR,
827+
"generate_merge_input_sortorder: can't handle data type %d",
828+
pkey->vartype);
829+
}
830+
*nextsortop++ = InvalidOid;
831+
return result;
832+
}
833+
800834
/*
801835
* set_noname_tlist_operators
802836
* Sets the key and keyop fields of resdom nodes in a target list.
@@ -806,18 +840,16 @@ switch_outer(List *clauses)
806840
* corresponding to vars in the target list that are to
807841
* be sorted or hashed
808842
* 'operators' is the corresponding list of N sort or hash operators
809-
* 'keyno' is the first key number
810-
* XXX - keyno ? doesn't exist - jeff
811843
*
812-
* Returns the modified target list.
844+
* Returns the modified-in-place target list.
813845
*/
814846
static List *
815847
set_noname_tlist_operators(List *tlist, List *pathkeys, Oid *operators)
816848
{
817-
Node *pathkey = NULL;
818849
int keyno = 1;
819-
Resdom *resdom = (Resdom *) NULL;
820-
List *i = NIL;
850+
Node *pathkey;
851+
Resdom *resdom;
852+
List *i;
821853

822854
foreach(i, pathkeys)
823855
{
@@ -828,12 +860,9 @@ set_noname_tlist_operators(List *tlist, List *pathkeys, Oid *operators)
828860
/*
829861
* Order the resdom pathkey and replace the operator OID for each
830862
* key with the regproc OID.
831-
*
832-
* XXX Note that the optimizer only generates merge joins with 1
833-
* operator (see create_mergejoin_node) - ay 2/95
834863
*/
835864
resdom->reskey = keyno;
836-
resdom->reskeyop = get_opcode(operators[0]);
865+
resdom->reskeyop = get_opcode(operators[keyno-1]);
837866
}
838867
keyno += 1;
839868
}
@@ -1024,9 +1053,6 @@ static MergeJoin *
10241053
make_mergejoin(List *tlist,
10251054
List *qpqual,
10261055
List *mergeclauses,
1027-
Oid opcode,
1028-
Oid *rightorder,
1029-
Oid *leftorder,
10301056
Plan *righttree,
10311057
Plan *lefttree)
10321058
{
@@ -1041,9 +1067,6 @@ make_mergejoin(List *tlist,
10411067
plan->lefttree = lefttree;
10421068
plan->righttree = righttree;
10431069
node->mergeclauses = mergeclauses;
1044-
node->mergejoinop = opcode;
1045-
node->mergerightorder = rightorder;
1046-
node->mergeleftorder = leftorder;
10471070

10481071
return node;
10491072
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy