8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.78 2006/03/05 15:58:26 momjian Exp $
11
+ * $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.79 2006/03/17 19:38:12 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -948,9 +948,6 @@ ExecMergeJoin(MergeJoinState *node)
948
948
* now we get the next inner tuple, if any. If there's none,
949
949
* advance to next outer tuple (which may be able to join to
950
950
* previously marked tuples).
951
- *
952
- * If we find one but it cannot join to anything, stay in
953
- * NEXTINNER state to fetch the next one.
954
951
*/
955
952
innerTupleSlot = ExecProcNode (innerPlan );
956
953
node -> mj_InnerTupleSlot = innerTupleSlot ;
@@ -963,8 +960,17 @@ ExecMergeJoin(MergeJoinState *node)
963
960
break ;
964
961
}
965
962
963
+ /*
964
+ * Load up the new inner tuple's comparison values. If we
965
+ * see that it contains a NULL and hence can't match any
966
+ * outer tuple, we can skip the comparison and assume the
967
+ * new tuple is greater than current outer.
968
+ */
966
969
if (!MJEvalInnerValues (node , innerTupleSlot ))
967
- break ; /* stay in NEXTINNER state */
970
+ {
971
+ node -> mj_JoinState = EXEC_MJ_NEXTOUTER ;
972
+ break ;
973
+ }
968
974
969
975
/*
970
976
* Test the new inner tuple to see if it matches outer.
@@ -1054,15 +1060,15 @@ ExecMergeJoin(MergeJoinState *node)
1054
1060
}
1055
1061
1056
1062
/* Compute join values and check for unmatchability */
1057
- if (! MJEvalOuterValues (node ))
1063
+ if (MJEvalOuterValues (node ))
1058
1064
{
1059
- /* Stay in same state to fetch next outer tuple */
1060
- node -> mj_JoinState = EXEC_MJ_NEXTOUTER ;
1065
+ /* Go test the new tuple against the marked tuple */
1066
+ node -> mj_JoinState = EXEC_MJ_TESTOUTER ;
1061
1067
}
1062
1068
else
1063
1069
{
1064
- /* Go test the tuple */
1065
- node -> mj_JoinState = EXEC_MJ_TESTOUTER ;
1070
+ /* Can't match, so fetch next outer tuple */
1071
+ node -> mj_JoinState = EXEC_MJ_NEXTOUTER ;
1066
1072
}
1067
1073
break ;
1068
1074
@@ -1071,7 +1077,7 @@ ExecMergeJoin(MergeJoinState *node)
1071
1077
* tuple satisfy the merge clause then we know we have
1072
1078
* duplicates in the outer scan so we have to restore the
1073
1079
* inner scan to the marked tuple and proceed to join the
1074
- * new outer tuples with the inner tuples.
1080
+ * new outer tuple with the inner tuples.
1075
1081
*
1076
1082
* This is the case when
1077
1083
* outer inner
@@ -1105,8 +1111,9 @@ ExecMergeJoin(MergeJoinState *node)
1105
1111
MJ_printf ("ExecMergeJoin: EXEC_MJ_TESTOUTER\n" );
1106
1112
1107
1113
/*
1108
- * here we must compare the outer tuple with the marked inner
1109
- * tuple
1114
+ * Here we must compare the outer tuple with the marked inner
1115
+ * tuple. (We can ignore the result of MJEvalInnerValues,
1116
+ * since the marked inner tuple is certainly matchable.)
1110
1117
*/
1111
1118
innerTupleSlot = node -> mj_MarkedTupleSlot ;
1112
1119
(void ) MJEvalInnerValues (node , innerTupleSlot );
@@ -1179,10 +1186,19 @@ ExecMergeJoin(MergeJoinState *node)
1179
1186
}
1180
1187
1181
1188
/* reload comparison data for current inner */
1182
- (void ) MJEvalInnerValues (node , innerTupleSlot );
1183
-
1184
- /* continue on to skip outer tuples */
1185
- node -> mj_JoinState = EXEC_MJ_SKIP_TEST ;
1189
+ if (MJEvalInnerValues (node , innerTupleSlot ))
1190
+ {
1191
+ /* proceed to compare it to the current outer */
1192
+ node -> mj_JoinState = EXEC_MJ_SKIP_TEST ;
1193
+ }
1194
+ else
1195
+ {
1196
+ /*
1197
+ * current inner can't possibly match any outer;
1198
+ * better to advance the inner scan than the outer.
1199
+ */
1200
+ node -> mj_JoinState = EXEC_MJ_SKIPINNER_ADVANCE ;
1201
+ }
1186
1202
}
1187
1203
break ;
1188
1204
@@ -1293,15 +1309,16 @@ ExecMergeJoin(MergeJoinState *node)
1293
1309
}
1294
1310
1295
1311
/* Compute join values and check for unmatchability */
1296
- if (! MJEvalOuterValues (node ))
1312
+ if (MJEvalOuterValues (node ))
1297
1313
{
1298
- /* Stay in same state to fetch next outer tuple */
1314
+ /* Go test the new tuple against the current inner */
1315
+ node -> mj_JoinState = EXEC_MJ_SKIP_TEST ;
1316
+ }
1317
+ else
1318
+ {
1319
+ /* Can't match, so fetch next outer tuple */
1299
1320
node -> mj_JoinState = EXEC_MJ_SKIPOUTER_ADVANCE ;
1300
- break ;
1301
1321
}
1302
-
1303
- /* Test the new tuple against the current inner */
1304
- node -> mj_JoinState = EXEC_MJ_SKIP_TEST ;
1305
1322
break ;
1306
1323
1307
1324
/*
@@ -1356,15 +1373,19 @@ ExecMergeJoin(MergeJoinState *node)
1356
1373
}
1357
1374
1358
1375
/* Compute join values and check for unmatchability */
1359
- if (! MJEvalInnerValues (node , innerTupleSlot ))
1376
+ if (MJEvalInnerValues (node , innerTupleSlot ))
1360
1377
{
1361
- /* Stay in same state to fetch next inner tuple */
1378
+ /* proceed to compare it to the current outer */
1379
+ node -> mj_JoinState = EXEC_MJ_SKIP_TEST ;
1380
+ }
1381
+ else
1382
+ {
1383
+ /*
1384
+ * current inner can't possibly match any outer;
1385
+ * better to advance the inner scan than the outer.
1386
+ */
1362
1387
node -> mj_JoinState = EXEC_MJ_SKIPINNER_ADVANCE ;
1363
- break ;
1364
1388
}
1365
-
1366
- /* Test the new tuple against the current outer */
1367
- node -> mj_JoinState = EXEC_MJ_SKIP_TEST ;
1368
1389
break ;
1369
1390
1370
1391
/*
0 commit comments