-C Data\sstructure\scleanup.\s\sRemove\sunused\sfields.\s\sRearrange\sother\sfiles\sfor\ntighter\spacking\sand\sreduced\smemory\susage.
-D 2012-02-02T15:50:17.008
+C For\squeries\sof\sthe\sform\s"SELECT\sp,\smax(q)\sFROM\st1",\sthe\svalue\sof\scolumn\sp\nreturned\sis\sthe\sone\son\sthe\ssame\srow\sthat\sholds\sthe\smaximum\svalue\sof\sq.
+D 2012-02-02T17:35:43.157
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 3f79a373e57c3b92dabf76f40b065e719d31ac34
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/expr.c 00675123e0beec98f999aa4594d2cbe1fec33c1b
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5
-F src/func.c 6261ce00aad9c63cd5b4219249b05683979060e9
+F src/func.c f66c87956c9afc098e1b74612d3c2b38760a41dc
F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b
F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
-F src/select.c b6eec9d11ec5df0d1fd11e8a0eed0fc2d2d96b25
+F src/select.c 232283a2e60d91cbd9a5ddf2f6f7ecf53d590075
F src/shell.c 60d147c2411dd2d79a5151cfb9a068de87c7babe
F src/sqlite.h.in 371c30e4be94b9b0ea6400ed66663fcf8e891eb4
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84
F src/util.c 9e07bd67dfafe9c75b1da78c87ba030cebbb5388
F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa
-F src/vdbe.c 43ea77c83e7f35169328f13b20cc8140bd2cf473
+F src/vdbe.c 40b14dff04692b1ee421db40c67d4921ecf17a9d
F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb
-F src/vdbeInt.h 2e79ce66ff45a01411151957bb2899af680f1560
+F src/vdbeInt.h 0f986e86a4a0afbf52d0402071708f487d1cfc15
F src/vdbeapi.c 3662b6a468a2a4605a15dfab313baa6dff81ad91
F src/vdbeaux.c 7683d772ad638faa4567142438c4594e47f173c4
F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb
F test/e_insert.test 234242b71855af8e8a9b1e141c3533f6d43d8645
F test/e_reindex.test dfedfc32c5a282b0596c6537cbcd4217fbb1a216
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
-F test/e_select.test 6f488c22851c1c280ed74e16a9a1430706a3a8cb
+F test/e_select.test f0aa7a972a336e5e874700915b1f5abd7d63a7e2
F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92
F test/e_update.test dba988a4d079156549a40854074ba4890b0a4577
F test/e_uri.test 6f35b491f80dac005c8144f38b2dfb4d96483596
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P 25df2a7458d025bc00380b4a0893637639f9f0d4
-R d2ba4c243c1dae496337618e0657e24d
+P 0bc594e861ae1142e8c6c83f39b095e1432856bf
+R eff167ee91b10474f283fe35279e92e9
+T *branch * output-minmax-row
+T *sym-output-minmax-row *
+T -sym-trunk *
U drh
-Z ada6e2e4fcf7ab0bc8362d130037dce6
+Z cf65185cbe7093f978d4a185698ec6ea
-0bc594e861ae1142e8c6c83f39b095e1432856bf
\ No newline at end of file
+adb29232b659c5332b6841776372407fcc350b08
\ No newline at end of file
return context->pColl;
}
+/*
+** Indicate that the accumulator load should be skipped on this
+** iteration of the aggregate loop.
+*/
+static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){
+ context->skipFlag = 1;
+}
+
/*
** Implementation of the non-aggregate min() and max() functions
*/
cmp = sqlite3MemCompare(pBest, pArg, pColl);
if( (max && cmp<0) || (!max && cmp>0) ){
sqlite3VdbeMemCopy(pBest, pArg);
+ }else{
+ sqlite3SkipAccumulatorLoad(context);
}
}else{
sqlite3VdbeMemCopy(pBest, pArg);
static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
Vdbe *v = pParse->pVdbe;
int i;
+ int regHit = 0;
+ int addrHitTest = 0;
struct AggInfo_func *pF;
struct AggInfo_col *pC;
if( !pColl ){
pColl = pParse->db->pDfltColl;
}
- sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
+ if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem;
+ sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ);
}
sqlite3VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem,
(void*)pF->pFunc, P4_FUNCDEF);
** Another solution would be to change the OP_SCopy used to copy cached
** values to an OP_Copy.
*/
+ if( regHit ){
+ addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit);
+ }
sqlite3ExprCacheClear(pParse);
for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
sqlite3ExprCode(pParse, pC->pExpr, pC->iMem);
}
pAggInfo->directMode = 0;
sqlite3ExprCacheClear(pParse);
+ if( addrHitTest ){
+ sqlite3VdbeJumpHere(v, addrHitTest);
+ }
}
/*
break;
}
-/* Opcode: CollSeq * * P4
+/* Opcode: CollSeq P1 * * P4
**
** P4 is a pointer to a CollSeq struct. If the next call to a user function
** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will
** be returned. This is used by the built-in min(), max() and nullif()
** functions.
**
+** If P1 is not zero, then it is a register that a subsequent min() or
+** max() aggregate will set to 1 if the current row is not the minimum or
+** maximum. The P1 register is initialized to 0 by this instruction.
+**
** The interface used by the implementation of the aforementioned functions
** to retrieve the collation sequence set by this opcode is not available
** publicly, only to user functions defined in func.c.
*/
case OP_CollSeq: {
assert( pOp->p4type==P4_COLLSEQ );
+ if( pOp->p1 ){
+ sqlite3VdbeMemSetInt64(&aMem[pOp->p1], 0);
+ }
break;
}
ctx.s.db = db;
ctx.isError = 0;
ctx.pColl = 0;
+ ctx.skipFlag = 0;
if( ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
assert( pOp>p->aOp );
assert( pOp[-1].p4type==P4_COLLSEQ );
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
rc = ctx.isError;
}
+ if( ctx.skipFlag ){
+ assert( pOp[-1].opcode==OP_CollSeq );
+ i = pOp[-1].p1;
+ if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
+ }
sqlite3VdbeMemRelease(&ctx.s);
Mem *pMem; /* Memory cell used to store aggregate context */
int isError; /* Error code returned by the function. */
CollSeq *pColl; /* Collating sequence */
+ int skipFlag; /* Skip skip accumulator loading if true */
};
/*
6 "SELECT count(*), * FROM z1" {6 63 born -26}
7 "SELECT max(a), * FROM z1" {63 63 born -26}
- 8 "SELECT *, min(a) FROM z1" {63 born -26 -5}
+ 8 "SELECT *, min(a) FROM z1" {{} 67 quartets -5}
9 "SELECT *,* FROM z1,z2 LIMIT 1" {
51.65 -59.58 belfries {} 21 51.65 -59.58 belfries {} 21