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.