Enable SELECT query planning tracing when compiled with 
SQLITE_ENABLE_SELECTTRACE and either SQLITE_DEBUG or SQLITE_TEST.

FossilOrigin-Name: cbe0cf9ddf46f0a678c85d49bfa74e3b7712e1a1
diff --git a/src/parse.y b/src/parse.y
index dbc129c..45e6fae 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -459,9 +459,33 @@
 multiselect_op(A) ::= UNION ALL.             {A = TK_ALL;}
 multiselect_op(A) ::= EXCEPT|INTERSECT(OP).  {A = @OP;}
 %endif SQLITE_OMIT_COMPOUND_SELECT
-oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y)
+oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y)
                  groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). {
   A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L.pLimit,L.pOffset);
+#if SELECTTRACE_ENABLED
+  /* Populate the Select.zSelLabel[] string that is used to help with
+  ** query planner debugging, to differentiate between multiple Select
+  ** objects in a complex query.
+  **
+  ** If the SELECT keyword is immediately followed by a C-style comment
+  ** then extract the first few alphanumeric characters from within that
+  ** comment to be the zSelLabel value.  Otherwise, the label is #N where
+  ** is an integer that is incremented with each SELECT statement seen.
+  */
+  if( A!=0 ){
+    const char *z = S.z+6;
+    int i;
+    sqlite3_snprintf(sizeof(A->zSelLabel), A->zSelLabel, "#%d",
+                     ++pParse->nSelect);
+    while( z[0]==' ' ) z++;
+    if( z[0]=='/' && z[1]=='*' ){
+      z += 2;
+      while( z[0]==' ' ) z++;
+      for(i=0; sqlite3Isalnum(z[i]); i++){}
+      sqlite3_snprintf(sizeof(A->zSelLabel), A->zSelLabel, "%.*s", i, z);
+    }
+  }
+#endif /* SELECTRACE_ENABLED */
 }
 oneselect(A) ::= values(X).    {A = X;}
 
diff --git a/src/select.c b/src/select.c
index d3ffaf4..a0f6f35 100644
--- a/src/select.c
+++ b/src/select.c
@@ -15,6 +15,17 @@
 #include "sqliteInt.h"
 
 /*
+** Trace output macros
+*/
+#if SELECTTRACE_ENABLED
+/***/ int sqlite3SelectTrace = 0;
+# define SELECTTRACE(K,X)  if(sqlite3SelectTrace&(K)) sqlite3DebugPrintf X
+#else
+# define SELECTTRACE(K,X)
+#endif
+
+
+/*
 ** An instance of the following object is used to record information about
 ** how to process the DISTINCT keyword, to simplify passing that information
 ** into the selectInnerLoop() routine.
@@ -3355,6 +3366,8 @@
   }
 
   /***** If we reach this point, flattening is permitted. *****/
+  SELECTTRACE(1, ("flatten %s (term %d) into %s\n",
+                   pSub->zSelLabel, iFrom, p->zSelLabel));
 
   /* Authorize the subquery */
   pParse->zAuthContext = pSubitem->zName;
diff --git a/src/shell.c b/src/shell.c
index ec83b13..9745e0f 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -3101,6 +3101,15 @@
     }
   }else
 
+
+#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
+  if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
+    extern int sqlite3SelectTrace;
+    sqlite3SelectTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
+  }else
+#endif
+
+
 #ifdef SQLITE_DEBUG
   /* Undocumented commands for internal testing.  Subject to change
   ** without notice. */
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 75cfeef..2d63228 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -707,6 +707,17 @@
 #endif
 
 /*
+** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not
+** the Select query generator tracing logic is turned on.
+*/
+#if defined(SQLITE_DEBUG) \
+    && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE))
+# define SELECTTRACE_ENABLED 1
+#else
+# define SELECTTRACE_ENABLED 0
+#endif
+
+/*
 ** An instance of the following structure is used to store the busy-handler
 ** callback for a given sqlite handle. 
 **
@@ -2300,6 +2311,9 @@
   u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
   u16 selFlags;          /* Various SF_* values */
   int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
+#if SELECTTRACE_ENABLED
+  char zSelLabel[12];    /* Text in comment following SELECT keyword */
+#endif
   int addrOpenEphm[2];   /* OP_OpenEphem opcodes related to this select */
   u64 nSelectRow;        /* Estimated number of result rows */
   SrcList *pSrc;         /* The FROM clause */
@@ -2558,6 +2572,9 @@
   int regRowid;        /* Register holding rowid of CREATE TABLE entry */
   int regRoot;         /* Register holding root page number for new objects */
   int nMaxArg;         /* Max args passed to user function by sub-program */
+#if SELECTTRACE_ENABLED
+  int nSelect;         /* Number of SELECT statements seen */
+#endif
 #ifndef SQLITE_OMIT_SHARED_CACHE
   int nTableLock;        /* Number of locks in aTableLock */
   TableLock *aTableLock; /* Required table locks for shared-cache mode */