Add the ability to disable constant factoring using sqlite3_test_control().
Add a TCL interface to this new capability and add tests cases to the TCL
test scripts to actually use the new capability.

FossilOrigin-Name: ad8bc68197f2b47435149c3dbc035f4e7210fc76
diff --git a/src/expr.c b/src/expr.c
index 3a6ba9f..b902f45 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -3040,10 +3040,22 @@
 ** Preevaluate constant subexpressions within pExpr and store the
 ** results in registers.  Modify pExpr so that the constant subexpresions
 ** are TK_REGISTER opcodes that refer to the precomputed values.
+**
+** This routine is a no-op if the jump to the cookie-check code has
+** already occur.  Since the cookie-check jump is generated prior to
+** any other serious processing, this check ensures that there is no
+** way to accidently bypass the constant initializations.
+**
+** This routine is also a no-op if the SQLITE_FactorOutConst optimization
+** is disabled via the sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS)
+** interface.  This allows test logic to verify that the same answer is
+** obtained for queries regardless of whether or not constants are
+** precomputed into registers or if they are inserted in-line.
 */
 void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){
   Walker w;
   if( pParse->cookieGoto ) return;
+  if( (pParse->db->flags & SQLITE_FactorOutConst)!=0 ) return;
   w.xExprCallback = evalConstExpr;
   w.xSelectCallback = 0;
   w.pParse = pParse;
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 6e8b768..4f0e08e 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -934,6 +934,7 @@
 #define SQLITE_IndexSearch    0x08        /* Disable indexes for searching */
 #define SQLITE_IndexCover     0x10        /* Disable index covering table */
 #define SQLITE_GroupByOrder   0x20        /* Disable GROUPBY cover of ORDERBY */
+#define SQLITE_FactorOutConst 0x40        /* Disable factoring out constants */
 #define SQLITE_OptMask        0xff        /* Mask of all disablable opts */
 
 /*
diff --git a/src/test1.c b/src/test1.c
index 27834f3..bab7845 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -5318,6 +5318,64 @@
 #endif /* SQLITE_OMIT_EXPLAIN */
 
 /*
+**      optimization_control DB OPT BOOLEAN
+**
+** Enable or disable query optimizations using the sqlite3_test_control()
+** interface.  Disable if BOOLEAN is false and enable if BOOLEAN is true.
+** OPT is the name of the optimization to be disabled.
+*/
+static int optimization_control(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+  int i;
+  sqlite3 *db;
+  const char *zOpt;
+  int onoff;
+  int mask;
+  static const struct {
+    const char *zOptName;
+    int mask;
+  } aOpt[] = {
+    { "all",              SQLITE_OptMask        },
+    { "query-flattener",  SQLITE_QueryFlattener },
+    { "column-cache",     SQLITE_ColumnCache    },
+    { "index-sort",       SQLITE_IndexSort      },
+    { "index-search",     SQLITE_IndexSearch    },
+    { "index-cover",      SQLITE_IndexCover     },
+    { "groupby-order",    SQLITE_GroupByOrder   },
+    { "factor-constants", SQLITE_FactorOutConst },
+  };
+
+  if( objc!=4 ){
+    Tcl_WrongNumArgs(interp, 1, objv, "DB OPT BOOLEAN");
+    return TCL_ERROR;
+  }
+  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
+  if( Tcl_GetBooleanFromObj(interp, objv[3], &onoff) ) return TCL_ERROR;
+  zOpt = Tcl_GetString(objv[2]);
+  for(i=0; i<sizeof(aOpt)/sizeof(aOpt[0]); i++){
+    if( strcmp(zOpt, aOpt[i].zOptName)==0 ){
+      mask = aOpt[i].mask;
+      break;
+    }
+  }
+  if( onoff ) mask = ~mask;
+  if( i>=sizeof(aOpt)/sizeof(aOpt[0]) ){
+    Tcl_AppendResult(interp, "unknown optimization - should be one of:",
+                     (char*)0);
+    for(i=0; i<sizeof(aOpt)/sizeof(aOpt[0]); i++){
+      Tcl_AppendResult(interp, " ", aOpt[i].zOptName);
+    }
+    return TCL_ERROR;
+  }
+  sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, db, mask);
+  return TCL_OK;
+}
+
+/*
 ** Register commands with the TCL interpreter.
 */
 int Sqlitetest1_Init(Tcl_Interp *interp){
@@ -5434,6 +5492,7 @@
      { "save_prng_state",               save_prng_state,    0 },
      { "restore_prng_state",            restore_prng_state, 0 },
      { "reset_prng_state",              reset_prng_state,   0 },
+     { "optimization_control",          optimization_control,0},
      { "tcl_objproc",                   runAsObjProc,       0 },
 
      /* sqlite3_column_*() API */