]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Use separate opcodes, OP_AggValue and OP_AggInverse, for the new callbacks
authordrh <drh@noemail.net>
Thu, 5 Jul 2018 21:22:57 +0000 (21:22 +0000)
committerdrh <drh@noemail.net>
Thu, 5 Jul 2018 21:22:57 +0000 (21:22 +0000)
associated with Window Functions, for improved readability of EXPLAIN
output.

FossilOrigin-Name: fa6538050938ffeb042fbee31512514d6d3ace514b2a3dfd8365bbeb13f35a78

manifest
manifest.uuid
src/select.c
src/vdbe.c
src/vdbemem.c
src/window.c

index 4120e948c7ae158329a1cbd3199337b149a6b744..18c9d3f286627e7c621cadc4d2f7dd245a582de4 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Update\sthe\srecipe\sfor\sresetting\sa\sdatabase\susing\nSQLITE_DBCONFIG_RESET_DATABASE.
-D 2018-07-05T20:33:06.498
+C Use\sseparate\sopcodes,\sOP_AggValue\sand\sOP_AggInverse,\sfor\sthe\snew\scallbacks\nassociated\swith\sWindow\sFunctions,\sfor\simproved\sreadability\sof\sEXPLAIN\noutput.
+D 2018-07-05T21:22:57.019
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in 0a3a6c81e6fcb969ff9106e882f0a08547014ba463cb6beca4c4efaecc924ee6
@@ -495,7 +495,7 @@ F src/printf.c 7f6f3cba8e0c49c19e30a1ff4e9aeda6e06814dcbad4b664a69e1b6cb6e7e365
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c 1f965d00b4c26b7eb886b90c687069f5db0d05157dbc1ca406fe88e990eac671
 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
-F src/select.c 82aa95aa1cfeadef5ecae1126afff1efca64c49050bbf7116425a8a1d4fc5e6c
+F src/select.c 7b7c67731f87df39150e6218468d5672c260fd48ec808454609725aea9831236
 F src/shell.c.in f1c79c537117ee61317a5ed85cdbcb854998cd690eb34ab803779358a2ace780
 F src/sqlite.h.in 36f0b3f88241863530f4b7e57e673e19311dd609ec4edad83b23291928cdf853
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
@@ -566,13 +566,13 @@ F src/upsert.c 47edd408cc73f8d3c00a140550d1ad180b407c146285947969dd09874802bf88
 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
 F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
 F src/vacuum.c 36e7d21a20c0bf6ef4ef7c399d192b5239410b7c4d3c1070fba4e30810d0b855
-F src/vdbe.c ff748307932fac5a5a983a20a4d8805aff7b0f310ca58cff4051df96d34a4dc8
+F src/vdbe.c 4e2768e83fd5b705b6244855818ae40178be2edf4288a45c625c03a9f755711b
 F src/vdbe.h 847735b3e083285aa225d2bf1fe97107a0a2b8942c80d643cdb764990705820d
 F src/vdbeInt.h 6b5cbd338dc9aaad343fb11b455e47463b0474d9f79710f50e647158941146e0
 F src/vdbeapi.c e35f813312b0f6e8e2835b357f121e0d1da6d3013bac3e367fe4efd518e7a2ec
 F src/vdbeaux.c c2d65c763b0811afe409e02e9d0d1f300c6e97892474fc94eec3da71955cd418
 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
-F src/vdbemem.c 87b48c0bd68041a61fb3f4e18a1a696f5339d65e572d288a266a602a01863f1a
+F src/vdbemem.c a699a1d7ccc3f94cdff69ddf35d5f7540dbf52ca44cf040eda3c87520e67858c
 F src/vdbesort.c 731a09e5cb9e96b70c394c1b7cf3860fbe84acca7682e178615eb941a3a0ef2f
 F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392
 F src/vtab.c 10ea07dec111de6fb0a4fc87a7ffa4c65fdc088a19dbfaf7d6f2b128f2e8eb7b
@@ -584,7 +584,7 @@ F src/where.c 0bcbf9e191ca07f9ea2008aa80e70ded46bcdffd26560c83397da501f00aece6
 F src/whereInt.h b90ef9b9707ef750eab2a7a080c48fb4900315033274689def32d0cf5a81ebe4
 F src/wherecode.c 3317f2b083a66d3e65a03edf316ade4ccb0a99c9956273282ebb579b95d4ba96
 F src/whereexpr.c 571618c67a3eb5ce0f1158c2792c1aee9b4a4a264392fc4fb1b35467f80abf9a
-F src/window.c 00df6e1bb85b5f4d07259303316277e8725edaaa01f156a395ce09a2f253656c
+F src/window.c 518274012188475ca02fb8444b1752a046c88a1cde6d1fd86a8e824cbb4b80f6
 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -1745,7 +1745,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 916cdc83f5a45e0b6f61c52ff5fde70d54bcd0dfaa4a32f9ac709fe0ddbb480b
-R 4aa4673d5a1ac5d12f944b181e29c4b8
-U dan
-Z fd87c0385603b862065c7e2db5d589f9
+P c43dd23fb00f7e0b6274de435d8e31f6a4cb74c3e86e8313a5098ff089e27574
+R f2e41b301a67b8d68998feae87995b75
+U drh
+Z 9251af3e39fe07a55b8965f4ce7c14d4
index 6735d443e2b26503095c5d97a85f59ac954d2740..8ba4b52f868bf5d07181ef1eaaaf0de850bc6a77 100644 (file)
@@ -1 +1 @@
-c43dd23fb00f7e0b6274de435d8e31f6a4cb74c3e86e8313a5098ff089e27574
\ No newline at end of file
+fa6538050938ffeb042fbee31512514d6d3ace514b2a3dfd8365bbeb13f35a78
\ No newline at end of file
index a3fa9359d8d6f9ba1013f5e318abd193cf491633..c51bd1db02d9fd6c988d9763c8663704d4867a43 100644 (file)
@@ -5187,7 +5187,7 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
       if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem;
       sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ);
     }
-    sqlite3VdbeAddOp3(v, OP_AggStep0, 0, regAgg, pF->iMem);
+    sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, pF->iMem);
     sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
     sqlite3VdbeChangeP5(v, (u8)nArg);
     sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg);
index 2b449b94667b41466dfffb0336e8b59f676d3cc7..33cacda2a02898abd52543a6290c966e4e2fb315 100644 (file)
@@ -6288,18 +6288,29 @@ case OP_DecrJumpZero: {      /* jump, in1 */
 }
 
 
-/* Opcode: AggStep0 P1 P2 P3 P4 P5
+/* Opcode: AggStep * P2 P3 P4 P5
 ** Synopsis: accum=r[P3] step(r[P2@P5])
 **
-** Execute the xStep (if P1==0) or xInverse (if P1!=0) function for an
-** aggregate.  The function has P5 arguments.  P4 is a pointer to the 
+** Execute the xStep function for an aggregate.
+** The function has P5 arguments.  P4 is a pointer to the 
 ** FuncDef structure that specifies the function.  Register P3 is the
 ** accumulator.
 **
 ** The P5 arguments are taken from register P2 and its
 ** successors.
 */
-/* Opcode: AggStep P1 P2 P3 P4 P5
+/* Opcode: AggInverse * P2 P3 P4 P5
+** Synopsis: accum=r[P3] inverse(r[P2@P5])
+**
+** Execute the xInverse function for an aggregate.
+** The function has P5 arguments.  P4 is a pointer to the 
+** FuncDef structure that specifies the function.  Register P3 is the
+** accumulator.
+**
+** The P5 arguments are taken from register P2 and its
+** successors.
+*/
+/* Opcode: AggStep1 P1 P2 P3 P4 P5
 ** Synopsis: accum=r[P3] step(r[P2@P5])
 **
 ** Execute the xStep (if P1==0) or xInverse (if P1!=0) function for an
@@ -6316,7 +6327,8 @@ case OP_DecrJumpZero: {      /* jump, in1 */
 ** sqlite3_context only happens once, instead of on each call to the
 ** step function.
 */
-case OP_AggStep0: {
+case OP_AggInverse:
+case OP_AggStep: {
   int n;
   sqlite3_context *pCtx;
 
@@ -6339,10 +6351,11 @@ case OP_AggStep0: {
   pCtx->argc = n;
   pOp->p4type = P4_FUNCCTX;
   pOp->p4.pCtx = pCtx;
-  pOp->opcode = OP_AggStep;
+  assert( pOp->p1==(pOp->opcode==OP_AggInverse) );
+  pOp->opcode = OP_AggStep1;
   /* Fall through into OP_AggStep */
 }
-case OP_AggStep: {
+case OP_AggStep1: {
   int i;
   sqlite3_context *pCtx;
   Mem *pMem;
@@ -6399,13 +6412,12 @@ case OP_AggStep: {
   break;
 }
 
-/* Opcode: AggFinal P1 P2 P3 P4 *
+/* Opcode: AggFinal P1 P2 * P4 *
 ** Synopsis: accum=r[P1] N=P2
 **
 ** P1 is the memory location that is the accumulator for an aggregate
-** or window function. If P3 is zero, then execute the finalizer function 
-** for an aggregate and store the result in P1. Or, if P3 is non-zero,
-** invoke the xValue() function and store the result in register P3.
+** or window function.  Execute the finalizer function 
+** for an aggregate and store the result in P1.
 **
 ** P2 is the number of arguments that the step function takes and
 ** P4 is a pointer to the FuncDef for this function.  The P2
@@ -6414,9 +6426,23 @@ case OP_AggStep: {
 ** P4 argument is only needed for the case where
 ** the step function was not previously called.
 */
+/* Opcode: AggValue * P2 P3 P4 *
+** Synopsis: r[P3]=value N=P2
+**
+** Invoke the xValue() function and store the result in register P3.
+**
+** P2 is the number of arguments that the step function takes and
+** P4 is a pointer to the FuncDef for this function.  The P2
+** argument is not used by this opcode.  It is only there to disambiguate
+** functions that can take varying numbers of arguments.  The
+** P4 argument is only needed for the case where
+** the step function was not previously called.
+*/
+case OP_AggValue:
 case OP_AggFinal: {
   Mem *pMem;
   assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
+  assert( pOp->p3==0 || pOp->opcode==OP_AggValue );
   pMem = &aMem[pOp->p1];
   assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
 #ifndef SQLITE_OMIT_WINDOWFUNC
@@ -6425,7 +6451,9 @@ case OP_AggFinal: {
     pMem = &aMem[pOp->p3];
   }else
 #endif
-  rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
+  {
+    rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
+  }
   
   if( rc ){
     sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
index dc0a3f970282911be5ae808a841788f04e7a12b0..d0d52ce41cac341f9e05079ac0a3dfa2ac31fc38 100644 (file)
@@ -435,6 +435,7 @@ int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){
   memset(&t, 0, sizeof(t));
   t.flags = MEM_Null;
   t.db = pAccum->db;
+  sqlite3VdbeMemSetNull(pOut);
   ctx.pOut = pOut;
   ctx.pMem = pAccum;
   ctx.pFunc = pFunc;
index 87cb0cea0d105c129e8e780d2cdf3786bdc20ff7..751e17d2aa220529c2b9d07a95dbb92aeb37f1f1 100644 (file)
@@ -988,7 +988,7 @@ static int windowArgCount(Window *pWin){
 ** the first register in an array of registers guaranteed to be large
 ** enough to hold the array of arguments for each function. In this case
 ** the arguments are extracted from the current row of csr into the
-** array of registers before invoking OP_AggStep.
+** array of registers before invoking OP_AggStep or OP_AggInverse
 **
 ** Or, if csr is less than zero, then the array of registers at reg is
 ** already populated with all columns from the current row of the sub-query.
@@ -1076,7 +1076,8 @@ static void windowAggStep(
         pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
         sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
       }
-      sqlite3VdbeAddOp3(v, OP_AggStep0, bInverse, regArg, pWin->regAccum);
+      sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, 
+                        bInverse, regArg, pWin->regAccum);
       sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
       sqlite3VdbeChangeP5(v, (u8)nArg);
       if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
@@ -1108,16 +1109,15 @@ static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){
       }
     }else if( pWin->regApp ){
     }else{
-      if( bFinal==0 ){
-        sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
-      }
-      sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin));
-      sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
       if( bFinal ){
+        sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin));
+        sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
         sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
         sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
       }else{
-        sqlite3VdbeChangeP3(v, -1, pWin->regResult);
+        sqlite3VdbeAddOp3(v, OP_AggValue, pWin->regAccum, windowArgCount(pWin),
+                             pWin->regResult);
+        sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
       }
     }
   }
@@ -1273,7 +1273,7 @@ static void windowReturnOneRow(
 **     regCtr--;
 **     windowReturnOneRow()
 **     if( bInverse ){
-**       AggStep (xInverse)
+**       AggInverse
 **     }
 **     Next (Window.iEphCsr)
 **   }
@@ -1367,7 +1367,7 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){
 **         Gosub addrGosub
 **         Next(csr)                // if EOF goto flush_partition_done
 **         if( (regStart--)<=0 ){
-**           AggStep (csrStart, xInverse)
+**           AggInverse (csrStart)
 **           Next(csrStart)
 **         }
 **       }
@@ -1395,7 +1395,7 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){
 **       Gosub addrGosub
 **       Next(csr)                     // if EOF goto flush_partition_done
 **       if( (regStart--)<=0 ){
-**         AggStep (csrStart, xInverse)
+**         AggInverse (csrStart)
 **         Next(csrStart)
 **       }
 **     }
@@ -1418,7 +1418,7 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){
 **         if( new peer ) break;
 **       }
 **       while( (regPeer--)>0 ){
-**         AggStep (csrStart, xInverse)
+**         AggInverse (csrStart)
 **         Next(csrStart)
 **       }
 **     }
@@ -1435,7 +1435,7 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){
 **         Gosub addrGosub
 **         Next(csr)              // if EOF goto flush_partition_done
 **       }
-**       AggStep (csrStart, xInverse)
+**       AggInverse (csrStart)
 **       Next (csrStart)
 **     }
 **
@@ -1451,7 +1451,7 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){
 **     Gosub addrGosub
 **     Next(csr)                  // if EOF goto flush_partition_done
 **     if( (regStart--)<=0 ){
-**       AggStep (csr2, xInverse)
+**       AggInverse (csr2)
 **       Next (csr2)
 **     }
 **
@@ -1682,7 +1682,7 @@ static void windowCodeRowExprStep(
 **
 **         for(i=0; i<ctr; i++){
 **           Gosub addrGosub
-**           AggStep (xInverse, iEphCsr)
+**           AggInverse (iEphCsr)
 **           Next iEphCsr
 **         }
 **
@@ -1715,7 +1715,7 @@ static void windowCodeRowExprStep(
 **         AggFinal (xValue)
 **         for(i=0; i<ctr; i++){
 **           Gosub addrGosub
-**           AggStep (xInverse, iEphCsr)
+**           AggInverse (iEphCsr)
 **           Next iEphCsr
 **         }
 **         Integer ctr 0