Use of the CROSS keyword in a join prevents table reordering. Ticket #1414. (CVS 2683)
FossilOrigin-Name: 415b8b24629aa12756d8285c094b5f85d8a8e532
diff --git a/src/select.c b/src/select.c
index c43f1aa..da7c2ab 100644
--- a/src/select.c
+++ b/src/select.c
@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
-** $Id: select.c,v 1.266 2005/09/08 12:57:28 drh Exp $
+** $Id: select.c,v 1.267 2005/09/10 15:28:09 drh Exp $
*/
#include "sqliteInt.h"
@@ -73,6 +73,7 @@
** in terms of the following bit values:
**
** JT_INNER
+** JT_CROSS
** JT_OUTER
** JT_NATURAL
** JT_LEFT
@@ -98,7 +99,7 @@
{ "full", 4, JT_LEFT|JT_RIGHT|JT_OUTER },
{ "outer", 5, JT_OUTER },
{ "inner", 5, JT_INNER },
- { "cross", 5, JT_INNER },
+ { "cross", 5, JT_INNER|JT_CROSS },
};
int i, j;
apAll[0] = pA;
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index b212f24..e33d115 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.413 2005/09/09 01:33:19 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.414 2005/09/10 15:28:09 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -999,11 +999,12 @@
** Permitted values of the SrcList.a.jointype field
*/
#define JT_INNER 0x0001 /* Any kind of inner or cross join */
-#define JT_NATURAL 0x0002 /* True for a "natural" join */
-#define JT_LEFT 0x0004 /* Left outer join */
-#define JT_RIGHT 0x0008 /* Right outer join */
-#define JT_OUTER 0x0010 /* The "OUTER" keyword is present */
-#define JT_ERROR 0x0020 /* unknown or unsupported join type */
+#define JT_CROSS 0x0002 /* Explicit use of the CROSS keyword */
+#define JT_NATURAL 0x0004 /* True for a "natural" join */
+#define JT_LEFT 0x0008 /* Left outer join */
+#define JT_RIGHT 0x0010 /* Right outer join */
+#define JT_OUTER 0x0020 /* The "OUTER" keyword is present */
+#define JT_ERROR 0x0040 /* unknown or unsupported join type */
/*
** For each nested loop in a WHERE clause implementation, the WhereInfo
diff --git a/src/where.c b/src/where.c
index 1c2007b..50ef5d6 100644
--- a/src/where.c
+++ b/src/where.c
@@ -16,7 +16,7 @@
** so is applicable. Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
-** $Id: where.c,v 1.169 2005/09/08 14:17:20 drh Exp $
+** $Id: where.c,v 1.170 2005/09/10 15:28:09 drh Exp $
*/
#include "sqliteInt.h"
@@ -1425,6 +1425,7 @@
pTabItem = pTabList->a;
pLevel = pWInfo->a;
andFlags = ~0;
+ TRACE(("*** Optimizer Start ***\n"));
for(i=iFrom=0, pLevel=pWInfo->a; i<pTabList->nSrc; i++, pLevel++){
Index *pIdx; /* Index for FROM table at pTabItem */
int flags; /* Flags asssociated with pIdx */
@@ -1454,12 +1455,14 @@
bestNEq = nEq;
bestJ = j;
}
- if( (pTabItem->jointype & JT_LEFT)!=0
- || (j>0 && (pTabItem[-1].jointype & JT_LEFT)!=0)
+ if( (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0
+ || (j>0 && (pTabItem[-1].jointype & (JT_LEFT|JT_CROSS))!=0)
){
break;
}
}
+ TRACE(("*** Optimizer choose table %d for loop %d\n", bestJ,
+ pLevel-pWInfo->a));
if( (bestFlags & WHERE_ORDERBY)!=0 ){
*ppOrderBy = 0;
}
@@ -1477,6 +1480,7 @@
notReady &= ~getMask(&maskSet, pTabList->a[bestJ].iCursor);
pLevel->iFrom = bestJ;
}
+ TRACE(("*** Optimizer Finished ***\n"));
/* If the total query only selects a single row, then the ORDER BY
** clause is irrelevant.