]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Remove code that is no longer used.
authordrh <>
Fri, 23 Jan 2026 16:07:51 +0000 (16:07 +0000)
committerdrh <>
Fri, 23 Jan 2026 16:07:51 +0000 (16:07 +0000)
FossilOrigin-Name: 8d7f91e07b0c7573f94fddd64f39671e608969764615bd7f5c060e7ee7540bc6

manifest
manifest.uuid
src/expr.c
src/select.c
src/sqliteInt.h

index 3ea4b993bbf8bb078e1109647b86cb1b1c03c57d..e42e6f6938fccd54486327bc63f92b21cb89705e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Continuing\swork\stoward\susing\ssort-and-merge\sfor\sUNION.
-D 2026-01-23T14:37:08.819
+C Remove\scode\sthat\sis\sno\slonger\sused.
+D 2026-01-23T16:07:51.599
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -689,7 +689,7 @@ F src/date.c e19e0cfff9a41bfdd884c655755f6f00bca4c1a22272b56e0dd6667b7ea893a2
 F src/dbpage.c c9ea81c11727f27e02874611e92773e68e2a90a875ef2404b084564c235fd91f
 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
 F src/delete.c e020dde34838369e2f0eff75f25c44a4e56a41262593f7c48d1223689d674e4d
-F src/expr.c 252e62742f5bb01517377c93057b6040ab954034ec3dde4d6fc583565d859a9c
+F src/expr.c bc9d20cc2301d61e172c1880431ba74ea5b6119880b6bbf96cf50c1b6ec7ae56
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c c065da737307a29e4d240ac727758dbf4102cb3218a1f651eb689b6a6fa12531
 F src/func.c efbcfe7cb7fc92fe5299c9aaa141075eb60d2108253e99bc235384ed6a90d937
@@ -738,12 +738,12 @@ F src/printf.c b1b29b5e58e1530d5daeee5963d3c318d8ab2d7e38437580e28755753e0c1ded
 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c 47aa7fdc9ec4c19b103ac5e79d7887d30119b5675309facf5eed1118391c868b
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
-F src/select.c 99d3bf20c1f7035c0c8eabdfad86d7239d4670e253d183a3ad62baf642503df5
+F src/select.c 584a8669fad6bd2494333fb9c24206d95839155732da53a5d34b1fe0034b991f
 F src/shell.c.in e8818572acd50464bc00426fe0d755e98239f73d531437c3dc7721d1fecb1231
 F src/sqlite.h.in d463dcdd67d4865991cd62dc8d3f678086b38365593861f77c09c3401551d59f
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
 F src/sqlite3ext.h f590cd8cb4c36fc727632c9b5fbbafc85f7efe2c6890f9958d7e711dc26ec01e
-F src/sqliteInt.h 71a2ae85d45c6cda8571bab66a6ab86b36a439a82c8a712681e6a99c381ab79b
+F src/sqliteInt.h 0dfb8205a791fd5bb723bae2031b05300422c43937904d9c3ea951a65b28908b
 F src/sqliteLimit.h 904a3f520362c7065c18165aaabd504fb13cc1b76cb411f38bd41ac219e4af1e
 F src/status.c 7565d63a79aa2f326339a24a0461a60096d0bd2bce711fefb50b5c89335f3592
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -2193,8 +2193,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P bdf4d6a9398266c98a0d4ad3c60b431cd498bfa80add3e81d717c687634c2602
-R 917664d469853cc469980a3c06f2d7e0
+P 94bf43634bbb1fd8e67235b8be0d9744cca1e364ab3cceecca4528e7b78780d1
+R 2a55fd7d366f0f4038cb2fcdad2f4726
 U drh
-Z dc45dae74764f0f3e185e346f4a688ed
+Z 4d98cdeeda3f34de774c8063318689f1
 # Remove this line to create a well-formed Fossil manifest.
index 2478e5386d223da1b580d5dab0de55a02ff85f7a..e52384c47e474d4d55a94cb408eb53df82a8a0c4 100644 (file)
@@ -1 +1 @@
-94bf43634bbb1fd8e67235b8be0d9744cca1e364ab3cceecca4528e7b78780d1
+8d7f91e07b0c7573f94fddd64f39671e608969764615bd7f5c060e7ee7540bc6
index 198467deaca72248ecce2b665040e4193e0db7b9..f9a23abfb6745c80cf3fbd10f7f7c5e278c528d6 100644 (file)
@@ -1979,8 +1979,7 @@ Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int flags){
     pNew->iLimit = 0;
     pNew->iOffset = 0;
     pNew->selFlags = p->selFlags & ~(u32)SF_UsesEphemeral;
-    pNew->addrOpenEphm[0] = -1;
-    pNew->addrOpenEphm[1] = -1;
+    pNew->addrOpenEphm = -1;
     pNew->nSelectRow = p->nSelectRow;
     pNew->pWith = sqlite3WithDup(db, p->pWith);
 #ifndef SQLITE_OMIT_WINDOWFUNC
index d8b50706a328ce6fe76a4c46531bad081795e73c..72bcb29a78c3f6e44de7385c8b6d1faf5b27f455 100644 (file)
@@ -151,8 +151,7 @@ Select *sqlite3SelectNew(
   pNew->iLimit = 0;
   pNew->iOffset = 0;
   pNew->selId = ++pParse->nSelect;
-  pNew->addrOpenEphm[0] = -1;
-  pNew->addrOpenEphm[1] = -1;
+  pNew->addrOpenEphm = -1;
   pNew->nSelectRow = 0;
   if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, SZ_SRCLIST_1);
   pNew->pSrc = pSrc;
@@ -1300,29 +1299,6 @@ static void selectInnerLoop(
   }
 
   switch( eDest ){
-    /* In this mode, write each query result to the key of the temporary
-    ** table iParm.
-    */
-#ifndef SQLITE_OMIT_COMPOUND_SELECT
-    case SRT_Union: {
-      int r1;
-      r1 = sqlite3GetTempReg(pParse);
-      sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1);
-      sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol);
-      sqlite3ReleaseTempReg(pParse, r1);
-      break;
-    }
-
-    /* Construct a record from the query result, but instead of
-    ** saving that record, use it as a key to delete elements from
-    ** the temporary table iParm.
-    */
-    case SRT_Except: {
-      sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nResultCol);
-      break;
-    }
-#endif /* SQLITE_OMIT_COMPOUND_SELECT */
-
     /* Store the result as data using a unique key.
     */
     case SRT_Fifo:
@@ -2753,7 +2729,7 @@ static void generateWithRecursiveQuery(
   }
   VdbeComment((v, "Queue table"));
   if( iDistinct ){
-    p->addrOpenEphm[0] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iDistinct, 0);
+    p->addrOpenEphm = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iDistinct, 0);
     p->selFlags |= SF_UsesEphemeral;
   }
 
@@ -2983,7 +2959,7 @@ static int multiSelect(
   */
   if( p->pOrderBy ){
     return multiSelectOrderBy(pParse, p, pDest);
-  }else if( p->op!=TK_ALL && (p->selFlags & SF_NoMerge)==0 ){
+  }else if( p->op!=TK_ALL ){
     Expr *pOne = sqlite3ExprInt32(db, 1);
     p->pOrderBy = sqlite3ExprListAppend(pParse, 0, pOne);
     if( pParse->nErr ) goto multi_select_end;
@@ -2991,6 +2967,8 @@ static int multiSelect(
     p->pOrderBy->a[0].u.x.iOrderByCol = 1;
     return multiSelectOrderBy(pParse, p, pDest);
   }else{
+    int addr = 0;
+    int nLimit = 0;  /* Initialize to suppress harmless compiler warning */
 
 #ifndef SQLITE_OMIT_EXPLAIN
     if( pPrior->pPrior==0 ){
@@ -2998,252 +2976,50 @@ static int multiSelect(
       ExplainQueryPlan((pParse, 1, "LEFT-MOST SUBQUERY"));
     }
 #endif
-
-    /* Generate code for the left and right SELECT statements.
-    */
-    switch( p->op ){
-      case TK_ALL: {
-        int addr = 0;
-        int nLimit = 0;  /* Initialize to suppress harmless compiler warning */
-        assert( !pPrior->pLimit );
-        pPrior->iLimit = p->iLimit;
-        pPrior->iOffset = p->iOffset;
-        pPrior->pLimit = sqlite3ExprDup(db, p->pLimit, 0);
-        TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL left...\n"));
-        rc = sqlite3Select(pParse, pPrior, &dest);
-        sqlite3ExprDelete(db, pPrior->pLimit);
-        pPrior->pLimit = 0;
-        if( rc ){
-          goto multi_select_end;
-        }
-        p->pPrior = 0;
-        p->iLimit = pPrior->iLimit;
-        p->iOffset = pPrior->iOffset;
-        if( p->iLimit ){
-          addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
-          VdbeComment((v, "Jump ahead if LIMIT reached"));
-          if( p->iOffset ){
-            sqlite3VdbeAddOp3(v, OP_OffsetLimit,
-                              p->iLimit, p->iOffset+1, p->iOffset);
-          }
-        }
-        ExplainQueryPlan((pParse, 1, "UNION ALL"));
-        TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL right...\n"));
-        rc = sqlite3Select(pParse, p, &dest);
-        testcase( rc!=SQLITE_OK );
-        pDelete = p->pPrior;
-        p->pPrior = pPrior;
-        p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
-        if( p->pLimit
-         && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit, pParse)
-         && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit)
-        ){
-          p->nSelectRow = sqlite3LogEst((u64)nLimit);
-        }
-        if( addr ){
-          sqlite3VdbeJumpHere(v, addr);
-        }
-        break;
-      }
-      case TK_EXCEPT:
-      case TK_UNION: {
-        int unionTab;    /* Cursor number of the temp table holding result */
-        u8 op = 0;       /* One of the SRT_ operations to apply to self */
-        int priorOp;     /* The SRT_ operation to apply to prior selects */
-        Expr *pLimit;    /* Saved values of p->nLimit  */
-        int addr;
-        int emptyBypass = 0;   /* IfEmpty opcode to bypass RHS */
-        SelectDest uniondest;
-
-        testcase( p->op==TK_EXCEPT );
-        testcase( p->op==TK_UNION );
-        priorOp = SRT_Union;
-        if( dest.eDest==priorOp ){
-          /* We can reuse a temporary table generated by a SELECT to our
-          ** right.
-          */
-          assert( p->pLimit==0 );      /* Not allowed on leftward elements */
-          unionTab = dest.iSDParm;
-        }else{
-          /* We will need to create our own temporary table to hold the
-          ** intermediate results.
-          */
-          unionTab = pParse->nTab++;
-          assert( p->pOrderBy==0 );
-          addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
-          assert( p->addrOpenEphm[0] == -1 );
-          p->addrOpenEphm[0] = addr;
-          findRightmost(p)->selFlags |= SF_UsesEphemeral;
-          assert( p->pEList );
-        }
-         
-        /* Code the SELECT statements to our left
-        */
-        assert( !pPrior->pOrderBy );
-        sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
-        TREETRACE(0x200, pParse, p, ("multiSelect EXCEPT/UNION left...\n"));
-        rc = sqlite3Select(pParse, pPrior, &uniondest);
-        if( rc ){
-          goto multi_select_end;
-        }
-        /* Code the current SELECT statement
-        */
-        if( p->op==TK_EXCEPT ){
-          op = SRT_Except;
-          emptyBypass = sqlite3VdbeAddOp1(v, OP_IfEmpty, unionTab);
-          VdbeCoverage(v);
-        }else{
-          assert( p->op==TK_UNION );
-          op = SRT_Union;
-        }
-        p->pPrior = 0;
-        pLimit = p->pLimit;
-        p->pLimit = 0;
-        uniondest.eDest = op;
-        ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
-                          sqlite3SelectOpName(p->op)));
-        TREETRACE(0x200, pParse, p, ("multiSelect EXCEPT/UNION right...\n"));
-        rc = sqlite3Select(pParse, p, &uniondest);
-        testcase( rc!=SQLITE_OK );
-        assert( p->pOrderBy==0 );
-        pDelete = p->pPrior;
-        p->pPrior = pPrior;
-        p->pOrderBy = 0;
-        if( p->op==TK_UNION ){
-          p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
-        }
-        if( emptyBypass ) sqlite3VdbeJumpHere(v, emptyBypass);
-        sqlite3ExprDelete(db, p->pLimit);
-        p->pLimit = pLimit;
-        p->iLimit = 0;
-        p->iOffset = 0;
-        /* Convert the data in the temporary table into whatever form
-        ** it is that we currently need.
-        */
-        assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
-        assert( p->pEList || db->mallocFailed );
-        if( dest.eDest!=priorOp && db->mallocFailed==0 ){
-          int iCont, iBreak, iStart;
-          iBreak = sqlite3VdbeMakeLabel(pParse);
-          iCont = sqlite3VdbeMakeLabel(pParse);
-          computeLimitRegisters(pParse, p, iBreak);
-          sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
-          iStart = sqlite3VdbeCurrentAddr(v);
-          selectInnerLoop(pParse, p, unionTab,
-                          0, 0, &dest, iCont, iBreak);
-          sqlite3VdbeResolveLabel(v, iCont);
-          sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
-          sqlite3VdbeResolveLabel(v, iBreak);
-          sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
-        }
-        break;
-      }
-      default: assert( p->op==TK_INTERSECT ); {
-        int tab1, tab2;
-        int iCont, iBreak, iStart;
-        Expr *pLimit;
-        int addr, iLimit, iOffset;
-        SelectDest intersectdest;
-        int r1;
-        int emptyBypass;
-        /* INTERSECT is different from the others since it requires
-        ** two temporary tables.  Hence it has its own case.  Begin
-        ** by allocating the tables we will need.
-        */
-        tab1 = pParse->nTab++;
-        tab2 = pParse->nTab++;
-        assert( p->pOrderBy==0 );
-        addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
-        assert( p->addrOpenEphm[0] == -1 );
-        p->addrOpenEphm[0] = addr;
-        findRightmost(p)->selFlags |= SF_UsesEphemeral;
-        assert( p->pEList );
-        /* Code the SELECTs to our left into temporary table "tab1".
-        */
-        sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
-        TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT left...\n"));
-        rc = sqlite3Select(pParse, pPrior, &intersectdest);
-        if( rc ){
-          goto multi_select_end;
-        }
-
-        /* Initialize LIMIT counters before checking to see if the LHS
-        ** is empty, in case the jump is taken */
-        iBreak = sqlite3VdbeMakeLabel(pParse);
-        computeLimitRegisters(pParse, p, iBreak);
-        emptyBypass = sqlite3VdbeAddOp1(v, OP_IfEmpty, tab1); VdbeCoverage(v);
-        /* Code the current SELECT into temporary table "tab2"
-        */
-        addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0);
-        assert( p->addrOpenEphm[1] == -1 );
-        p->addrOpenEphm[1] = addr;
-
-        /* Disable prior SELECTs and the LIMIT counters during the computation
-        ** of the RHS select */
-        pLimit = p->pLimit;
-        iLimit = p->iLimit;
-        iOffset = p->iOffset;
-        p->pPrior = 0;
-        p->pLimit = 0;
-        p->iLimit = 0;
-        p->iOffset = 0;
-
-        intersectdest.iSDParm = tab2;
-        ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
-                          sqlite3SelectOpName(p->op)));
-        TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT right...\n"));
-        rc = sqlite3Select(pParse, p, &intersectdest);
-        testcase( rc!=SQLITE_OK );
-        pDelete = p->pPrior;
-        p->pPrior = pPrior;
-        if( p->nSelectRow>pPrior->nSelectRow ){
-          p->nSelectRow = pPrior->nSelectRow;
-        }
-        sqlite3ExprDelete(db, p->pLimit);
-
-        /* Reinstate the LIMIT counters prior to running the final intersect */
-        p->pLimit = pLimit;
-        p->iLimit = iLimit;
-        p->iOffset = iOffset;
-        /* Generate code to take the intersection of the two temporary
-        ** tables.
-        */
-        if( rc ) break;
-        assert( p->pEList );
-        sqlite3VdbeAddOp1(v, OP_Rewind, tab1);
-        r1 = sqlite3GetTempReg(pParse);
-        iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
-        iCont = sqlite3VdbeMakeLabel(pParse);
-        sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
-        VdbeCoverage(v);
-        sqlite3ReleaseTempReg(pParse, r1);
-        selectInnerLoop(pParse, p, tab1,
-                        0, 0, &dest, iCont, iBreak);
-        sqlite3VdbeResolveLabel(v, iCont);
-        sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
-        sqlite3VdbeResolveLabel(v, iBreak);
-        sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
-        sqlite3VdbeJumpHere(v, emptyBypass);
-        sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
-        break;
-      }
+    assert( !pPrior->pLimit );
+    pPrior->iLimit = p->iLimit;
+    pPrior->iOffset = p->iOffset;
+    pPrior->pLimit = sqlite3ExprDup(db, p->pLimit, 0);
+    TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL left...\n"));
+    rc = sqlite3Select(pParse, pPrior, &dest);
+    sqlite3ExprDelete(db, pPrior->pLimit);
+    pPrior->pLimit = 0;
+    if( rc ){
+      goto multi_select_end;
     }
-  #ifndef SQLITE_OMIT_EXPLAIN
-    if( p->pNext==0 ){
-      ExplainQueryPlanPop(pParse);
+    p->pPrior = 0;
+    p->iLimit = pPrior->iLimit;
+    p->iOffset = pPrior->iOffset;
+    if( p->iLimit ){
+      addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
+      VdbeComment((v, "Jump ahead if LIMIT reached"));
+      if( p->iOffset ){
+        sqlite3VdbeAddOp3(v, OP_OffsetLimit,
+                          p->iLimit, p->iOffset+1, p->iOffset);
+      }
+    }
+    ExplainQueryPlan((pParse, 1, "UNION ALL"));
+    TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL right...\n"));
+    rc = sqlite3Select(pParse, p, &dest);
+    testcase( rc!=SQLITE_OK );
+    pDelete = p->pPrior;
+    p->pPrior = pPrior;
+    p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
+    if( p->pLimit
+     && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit, pParse)
+     && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit)
+    ){
+      p->nSelectRow = sqlite3LogEst((u64)nLimit);
+    }
+    if( addr ){
+      sqlite3VdbeJumpHere(v, addr);
     }
-  #endif
   }
+#ifndef SQLITE_OMIT_EXPLAIN
+  if( p->pNext==0 ){
+    ExplainQueryPlanPop(pParse);
+  }
+#endif
   if( pParse->nErr ) goto multi_select_end;
  
   /* Compute collating sequences used by
@@ -3278,18 +3054,12 @@ static int multiSelect(
     }
 
     for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
-      for(i=0; i<2; i++){
-        int addr = pLoop->addrOpenEphm[i];
-        if( addr<0 ){
-          /* If [0] is unused then [1] is also unused.  So we can
-          ** always safely abort as soon as the first unused slot is found */
-          assert( pLoop->addrOpenEphm[1]<0 );
-          break;
-        }
+      int addr = pLoop->addrOpenEphm;
+      if( addr>=0 ){
         sqlite3VdbeChangeP2(v, addr, nCol);
         sqlite3VdbeChangeP4(v, addr, (char*)sqlite3KeyInfoRef(pKeyInfo),
                             P4_KEYINFO);
-        pLoop->addrOpenEphm[i] = -1;
+        pLoop->addrOpenEphm = -1;
       }
     }
     sqlite3KeyInfoUnref(pKeyInfo);
@@ -3499,7 +3269,7 @@ static int generateOutputSubroutine(
       r1 = sqlite3GetTempReg(pParse);
       r2 = sqlite3GetTempRange(pParse, nKey+2);
       r3 = r2+nKey+1;
-      if( pDest->eDest==SRT_DistQueue ){
+      if( NEVER(pDest->eDest==SRT_DistQueue) ){
         /* If the destination is DistQueue, then cursor (iParm+1) is open
         ** on a second ephemeral index that holds all values every previously
         ** added to the queue. */
@@ -3527,22 +3297,21 @@ static int generateOutputSubroutine(
     }
 #endif /* SQLITE_OMIT_CTE */
 
-    /*
-    ** For SRT_Output, results are stored in a sequence of registers. 
-    ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to
-    ** return the next row of result.
-    */
-    case SRT_Output: {
-      sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst);
+    /* Ignore the output */
+    case SRT_Discard: {
       break;
     }
 
-
     /* If none of the above, then the result destination must be
-    ** SRT_Discard.  Ignore the results.
+    ** SRT_Output.
+    **
+    ** For SRT_Output, results are stored in a sequence of registers. 
+    ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to
+    ** return the next row of result.
     */
     default: {
-      assert( pDest->eDest==SRT_Discard );
+      assert( pDest->eDest==SRT_Output );
+      sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst);
       break;
     }
   }
@@ -7835,8 +7604,7 @@ int sqlite3Select(
   assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue );
   assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue );
   if( IgnorableDistinct(pDest) ){
-    assert(pDest->eDest==SRT_Exists     || pDest->eDest==SRT_Union ||
-           pDest->eDest==SRT_Except     || pDest->eDest==SRT_Discard ||
+    assert(pDest->eDest==SRT_Exists     || pDest->eDest==SRT_Discard ||
            pDest->eDest==SRT_DistQueue  || pDest->eDest==SRT_DistFifo );
     /* All of these destinations are also able to ignore the ORDER BY clause */
     if( p->pOrderBy ){
index 924925ff669380a51af8510eb41759776e87bdc9..f44b0c94c56af3d18a6468fd975da81dfdf80b42 100644 (file)
@@ -3589,15 +3589,12 @@ struct Upsert {
 ** See the header comment on the computeLimitRegisters() routine for a
 ** detailed description of the meaning of the iLimit and iOffset fields.
 **
-** addrOpenEphm[] entries contain the address of OP_OpenEphemeral opcodes.
-** These addresses must be stored so that we can go back and fill in
+** addrOpenEphm entries contain the address of an OP_OpenEphemeral opcode.
+** This address must be stored so that we can go back and fill in
 ** the P4_KEYINFO and P2 parameters later.  Neither the KeyInfo nor
 ** the number of columns in P2 can be computed at the same time
 ** as the OP_OpenEphm instruction is coded because not
 ** enough information about the compound query is known at that point.
-** The KeyInfo for addrOpenTran[0] and [1] contains collating sequences
-** for the result set.  The KeyInfo for addrOpenEphm[2] contains collating
-** sequences for the ORDER BY clause.
 */
 struct Select {
   u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
@@ -3605,7 +3602,7 @@ struct Select {
   u32 selFlags;          /* Various SF_* values */
   int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
   u32 selId;             /* Unique identifier number for this SELECT */
-  int addrOpenEphm[2];   /* OP_OpenEphem opcodes related to this select */
+  int addrOpenEphm;      /* OP_OpenEphem opcodes related to this select */
   ExprList *pEList;      /* The fields of the result */
   SrcList *pSrc;         /* The FROM clause */
   Expr *pWhere;          /* The WHERE clause */
@@ -3647,7 +3644,7 @@ struct Select {
 #define SF_MinMaxAgg     0x0001000 /* Aggregate containing min() or max() */
 #define SF_Recursive     0x0002000 /* The recursive part of a recursive CTE */
 #define SF_FixedLimit    0x0004000 /* nSelectRow set by a constant LIMIT */
-#define SF_NoMerge       0x0008000 /* Don't use merge to compute compounds */
+/*                       0x0008000 // available for reuse */
 #define SF_Converted     0x0010000 /* By convertCompoundSelectToSubquery() */
 #define SF_IncludeHidden 0x0020000 /* Include hidden columns in output */
 #define SF_ComplexResult 0x0040000 /* Result contains subquery or function */
@@ -3674,11 +3671,6 @@ struct Select {
 ** by one of the following macros.  The "SRT" prefix means "SELECT Result
 ** Type".
 **
-**     SRT_Union       Store results as a key in a temporary index
-**                     identified by pDest->iSDParm.
-**
-**     SRT_Except      Remove results from the temporary index pDest->iSDParm.
-**
 **     SRT_Exists      Store a 1 in memory cell pDest->iSDParm if the result
 **                     set is not empty.
 **
@@ -3742,30 +3734,28 @@ struct Select {
 **                     table. (pDest->iSDParm) is the number of key columns in
 **                     each index record in this case.
 */
-#define SRT_Union        1  /* Store result as keys in an index */
-#define SRT_Except       2  /* Remove result from a UNION index */
-#define SRT_Exists       3  /* Store 1 if the result is not empty */
-#define SRT_Discard      4  /* Do not save the results anywhere */
-#define SRT_DistFifo     5  /* Like SRT_Fifo, but unique results only */
-#define SRT_DistQueue    6  /* Like SRT_Queue, but unique results only */
+#define SRT_Exists       1  /* Store 1 if the result is not empty */
+#define SRT_Discard      2  /* Do not save the results anywhere */
+#define SRT_DistFifo     3  /* Like SRT_Fifo, but unique results only */
+#define SRT_DistQueue    4  /* Like SRT_Queue, but unique results only */
 
 /* The DISTINCT clause is ignored for all of the above.  Not that
 ** IgnorableDistinct() implies IgnorableOrderby() */
 #define IgnorableDistinct(X) ((X->eDest)<=SRT_DistQueue)
 
-#define SRT_Queue        7  /* Store result in an queue */
-#define SRT_Fifo         8  /* Store result as data with an automatic rowid */
+#define SRT_Queue        5  /* Store result in an queue */
+#define SRT_Fifo         6  /* Store result as data with an automatic rowid */
 
 /* The ORDER BY clause is ignored for all of the above */
 #define IgnorableOrderby(X) ((X->eDest)<=SRT_Fifo)
 
-#define SRT_Output       9  /* Output each row of result */
-#define SRT_Mem         10  /* Store result in a memory cell */
-#define SRT_Set         11  /* Store results as keys in an index */
-#define SRT_EphemTab    12  /* Create transient tab and store like SRT_Table */
-#define SRT_Coroutine   13  /* Generate a single row of result */
-#define SRT_Table       14  /* Store result as data with an automatic rowid */
-#define SRT_Upfrom      15  /* Store result as data with rowid */
+#define SRT_Output       7  /* Output each row of result */
+#define SRT_Mem          8  /* Store result in a memory cell */
+#define SRT_Set          9  /* Store results as keys in an index */
+#define SRT_EphemTab    10  /* Create transient tab and store like SRT_Table */
+#define SRT_Coroutine   11  /* Generate a single row of result */
+#define SRT_Table       12  /* Store result as data with an automatic rowid */
+#define SRT_Upfrom      13  /* Store result as data with rowid */
 
 /*
 ** An instance of this object describes where to put of the results of