]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Comment improvements to on the distinct-agg optimization. Show a line in
authordrh <>
Wed, 24 Mar 2021 19:44:01 +0000 (19:44 +0000)
committerdrh <>
Wed, 24 Mar 2021 19:44:01 +0000 (19:44 +0000)
the EQP output when using an ephemeral table to implement DISTINCT on an
aggregate.

FossilOrigin-Name: 037ca79e6032ca962b4f6182187bc12a7d91170d73630c8cd6fb191d2c183ee4

manifest
manifest.uuid
src/select.c
test/distinct.test

index d4587fd8b374e3a25b08aaef33608f797ea93941..0413a9b465b93c3e4a1202753cccd61083e9e8fd 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Improvements\sto\sdistinct\saggregates\ssuch\sthat\sthey\scan\ssometimes\savoid\nusing\san\sephermeral\stable\sto\stest\sfor\sduplicates\sif\sthe\scolumn\sthat\sis\ndistinct\sis\spart\sof\san\sindex.
-D 2021-03-24T17:28:11.642
+C Comment\simprovements\sto\son\sthe\sdistinct-agg\soptimization.\s\sShow\sa\sline\sin\nthe\sEQP\soutput\swhen\susing\san\sephemeral\stable\sto\simplement\sDISTINCT\son\san\naggregate.
+D 2021-03-24T19:44:01.340
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -542,7 +542,7 @@ F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c d95db73d3e6a5c689e5f6604b4d2521350e45f2a0f0f84f5a2dc2bfee56580a0
 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
-F src/select.c 9109ca4a3179eb46770e10c04f01fd226751ccf0caeea8db58000e3371f9fa21
+F src/select.c 22b0309a334e683cb453bfb16ca5cd423bfebc16b3360fe424707baf900b5919
 F src/shell.c.in dcce260883836c9b58847505fbccce8d5546af925046f7dacd9443e922ece036
 F src/sqlite.h.in 3426a080ea1f222a73e3bd91e7eacbd30570a0117c03d42c6dde606f33e5e318
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
@@ -843,7 +843,7 @@ F test/descidx1.test edc8adee58d491b06c7157c50364eaf1c3605c9c19f8093cb1ea2b6184f
 F test/descidx2.test a0ba347037ff3b811f4c6ceca5fd0f9d5d72e74e59f2d9de346a9d2f6ad78298
 F test/descidx3.test 953c831df7ea219c73826dfbf2f6ee02d95040725aa88ccb4fa43d1a1999b926
 F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
-F test/distinct.test e7d0cf371944dd0cbedff86420744e2f1ea2b528156451c97eb6ff41a99b9236
+F test/distinct.test eefe5a8e47fcb761aaa745838e355ab28586f9f75786a1c098016881344b2a5e
 F test/distinct2.test cd1d15a4a2abf579298f7161e821ed50c0119136fe0424db85c52cf0adc230d1
 F test/distinctagg.test fd74c3783700f1d99c67a5d906bba97fb6650f4559f3ea7b1873f793ffc601c9
 F test/e_blobbytes.test 439a945953b35cb6948a552edaec4dc31fd70a05
@@ -1911,8 +1911,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 26b005a95e4f3e378e3bc40f57321ffbab72b6fc990d13b56b3121990d325f63 0817cf2ec08fdefd3c1d41790df7b5d6d490767757b44bb0229694023c8e40fc
-R 299a3406efa01e76d5f6f5a54ae9efc6
-T +closed 0817cf2ec08fdefd3c1d41790df7b5d6d490767757b44bb0229694023c8e40fc
+P ef4ac0ddd297bbd38351410c5a387e1628561b3f1bec9e4c2c9d76fbe29f955a
+R dcb5dee51b0acb34e00007490cfee341
 U drh
-Z 8f54305fe91515917058141910a21763
+Z c32591fb9c8184cbc930f8b40bd7a719
index f3b8f4366208cf2a6164934c3b7d4e0aab0cf51b..3e4f52ae9178350d522bff5a743a65719294b273 100644 (file)
@@ -1 +1 @@
-ef4ac0ddd297bbd38351410c5a387e1628561b3f1bec9e4c2c9d76fbe29f955a
\ No newline at end of file
+037ca79e6032ca962b4f6182187bc12a7d91170d73630c8cd6fb191d2c183ee4
\ No newline at end of file
index b94efd5f3d6ac06fb019ff15a623856725505a6e..e7ae01aca7171e14ac061af638e18f746dadd939 100644 (file)
@@ -748,6 +748,9 @@ static void codeOffset(
 ** as follows:
 **
 **   WHERE_DISTINCT_UNORDERED/WHERE_DISTINCT_NOOP:
+**     Build an ephemeral table that contains all entries seen before and
+**     skip entries which have been seen before.
+**
 **     Parameter iTab is the cursor number of an ephemeral table that must
 **     be opened before the VM code generated by this routine is executed.
 **     The ephemeral cursor table is queried for a record identical to the
@@ -758,20 +761,21 @@ static void codeOffset(
 **     The returned value in this case is a copy of parameter iTab.
 **
 **   WHERE_DISTINCT_ORDERED:
-**     In this case rows are being delivered sorted order sorted. The ephermal
-**     table is not required in this case. Instead, the current set of 
-**     registers are compared to previous row. If they match, the new row
+**     In this case rows are being delivered sorted order. The ephermal
+**     table is not required. Instead, the current set of values
+**     is compared against previous row. If they match, the new row
 **     is not distinct and control jumps to VM address addrRepeat. Otherwise,
 **     the VM program proceeds with processing the new row.
 **
 **     The returned value in this case is the register number of the first
 **     in an array of registers used to store the previous result row so that
-**     it can be compared to the next. The caller must ensure that this cell
-**     is initialized to NULL and has the "clear" flag set.
+**     it can be compared to the next. The caller must ensure that this
+**     register is initialized to NULL.  (The fixDistinctOpenEph() routine
+**     will take care of this initialization.)
 **
 **   WHERE_DISTINCT_UNIQUE:
 **     In this case it has already been determined that the rows are distinct.
-**     No special action is required. The return value is always zero.
+**     No special action is required. The return value is zero.
 **
 ** Parameter pEList is the list of expressions used to generated the 
 ** contents of each row. It is used by this routine to determine (a) 
@@ -841,25 +845,27 @@ static int codeDistinct(
 }
 
 /*
-** A call to this function must be made for each call to codeDistinct().
-** Parameter is passed the value returned by that call to codeDistinct(),
-** and iOpenEphAddr the address of the instruction used to open the
-** ephemeral table (that may be) used by codeDistinct().
+** This routine runs after codeDistinct().  It makes necessary
+** adjustments to the OP_OpenEphemeral opcode that the codeDistinct()
+** routine made use of.  This processing must be done separately since
+** sometimes codeDistinct is called before the OP_OpenEphemeral is actually
+** laid down.
 **
-** Argument eTnctType is passed the strategy to be used for any DISTINCT
-** operation, as returned by sqlite3WhereIsDistinct(). If the strategy
-** is WHERE_DISTINCT_NOOP or WHERE_DISTINCT_UNORDERED, this function is
-** a no-op. Otherwise:
+** WHERE_DISTINCT_NOOP:
+** WHERE_DISTINCT_UNORDERED:
 **
-**   WHERE_DISTINCT_UNIQUE:
-**     In this case the ephemeral table is not required. So instruction
-**     iOpenEphAddr is replaced by an OP_Noop.
+**     No adjustments necessary.  This function is a no-op.
 **
-**   WHERE_DISTINCT_ORDERED:
-**     In this case the ephemeral table is not required. The instruction
-**     iOpenEphAddr is replaced by an OP_Null instruction to set register
-**     iVal to a NULL value with the "clear" flag set (see comments above
-**     codeDistinct() for details).
+** WHERE_DISTINCT_UNIQUE:
+**
+**     The ephemeral table is not needed.  So change the
+**     OP_OpenEphemeral opcode into an OP_Noop.
+**
+** WHERE_DISTINCT_ORDERED:
+**
+**     The ephemeral table is not needed.  But we do need register
+**     iVal to be initialized to NULL.  So change the OP_OpenEphemeral
+**     into an OP_Null on the iVal register.
 */
 static void fixDistinctOpenEph(
   Parse *pParse,     /* Parsing and code generating context */
@@ -870,6 +876,9 @@ static void fixDistinctOpenEph(
   if( eTnctType==WHERE_DISTINCT_UNIQUE || eTnctType==WHERE_DISTINCT_ORDERED ){
     Vdbe *v = pParse->pVdbe;
     sqlite3VdbeChangeToNoop(v, iOpenEphAddr);
+    if( sqlite3VdbeGetOp(v, iOpenEphAddr+1)->opcode==OP_Explain ){
+      sqlite3VdbeChangeToNoop(v, iOpenEphAddr+1);
+    }
     if( eTnctType==WHERE_DISTINCT_ORDERED ){
       /* Change the OP_OpenEphemeral to an OP_Null that sets the MEM_Cleared 
       ** bit on the first register of the previous value.  This will cause the
@@ -5714,6 +5723,8 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
         KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pE->x.pList,0,0);
         pFunc->iDistAddr = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, 
             pFunc->iDistinct, 0, 0, (char*)pKeyInfo, P4_KEYINFO);
+        ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s(DISTINCT)",
+                          pFunc->pFunc->zName));
       }
     }
   }
index f6f3c6cdce8ff548ec6ffe8e424f18ef240e1770..19da4fd61c3b7b7533439aefff31bdc603291b14 100644 (file)
@@ -30,12 +30,11 @@ proc is_distinct_noop {sql} {
   set program1 [list]
   set program2 [list]
   db eval "EXPLAIN $sql1" {
-    if {$opcode != "Noop"} { lappend program1 $opcode }
+    if {$opcode != "Noop" && $opcode != "Explain"} { lappend program1 $opcode }
   }
   db eval "EXPLAIN $sql2" {
-    if {$opcode != "Noop"} { lappend program2 $opcode }
+    if {$opcode != "Noop" && $opcode != "Explain"} { lappend program2 $opcode }
   }
-
   return [expr {$program1==$program2}]
 }