-C Fix\sa\stypon\sin\smain.mk.
-D 2018-06-11T11:19:35.512
+C Fix\shandling\sof\swindow\sframes\scontaining\snegative\snumber\sof\srows.\se.g.\s"ROWS\sx\nPRECEDING\sAND\sy\sPRECEDING"\swhere\s(x<y).
+D 2018-06-11T18:16:51.622
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in 498b77b89a8cb42f2ee20fcd6317f279a45c0d6ff40d27825f94b69884c09bbe
F src/prepare.c e966ecc97c3671ff0e96227c8c877b83f2d33ea371ee190bbf1698b36b5605c0
F src/printf.c 7f6f3cba8e0c49c19e30a1ff4e9aeda6e06814dcbad4b664a69e1b6cb6e7e365
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
-F src/resolve.c da9b85ec0e1a05384134cece5747a90b8da1fc5750f4705c7812d2294ca20cec
+F src/resolve.c 03791a761ede3a2cd71dffb92aa760d728122dbbdbf26010813da3edd01cb431
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
F src/select.c 0b0ce29bd7b8a7232e6f7602ddb447caa954a1fc476ff5e23ce1e5aaa6a0e0ed
F src/shell.c.in 4d0ddf10c403710d241bf920163dcf032c21119aebb61e70840942c0eafecdf9
F src/whereInt.h b90ef9b9707ef750eab2a7a080c48fb4900315033274689def32d0cf5a81ebe4
F src/wherecode.c 3317f2b083a66d3e65a03edf316ade4ccb0a99c9956273282ebb579b95d4ba96
F src/whereexpr.c 6f022d6cc9daf56495f191b199352f783aff5cf268ba136b4d8cea3fb62d8c7d
-F src/window.c 72c08229b59a447db5ffb8e87680105549465df502092e0e24f9451e6b082031
+F src/window.c 0519e5a03ebbcf22ab692410d4b25f28cc2d0e4e37e6288ca1eb0820276d67ba
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc
-F test/window1.test 6c648f3fa79b29ef114c4e73ae8adefae70e4d3aae4cc36a3318ab237b64e9c5
+F test/window1.test 94c626fe8d9eced3e3d5ef0a2106209904daba77d549aafde09eba1db8e98c3e
F test/window2.tcl 0983de5eade5eeda49469244799d5331bfe3199fca3f6c6d2a836aa08f4fba1b
F test/window2.test 79747b2edde4ad424e0752b27529aedc86e91f3d8d88846fa17ff0cb67f65086
F test/window3.tcl 654d61d73e10db089b22514d498bb23ec310f720c0f4b5f69f67fda83d672048
F test/window3.test 41727668ee31d2ba50f78efcb5bf1bda2c5cffd889aa65243511004669d1ac25
-F test/window4.tcl e459eb2fe561d7731008a80d071e2d995c3554706de764c9f456f54357e70316
-F test/window4.test 207ab5e54ba0fec5e1157d136489b615a0e88dc8f9fb81cd77e11f20d2ddd72e
+F test/window4.tcl bfea0c4f65dff22568032ae3a0cf3be0910c4160314e5ac3f895eca11b068cb1
+F test/window4.test ca7c63f27604a0eb432cab1673da75498c69d66b9093ef80a5d4c7287b95906b
F test/with1.test 58475190cd8caaeebea8cfeb2a264ec97a0c492b8ffe9ad20cefbb23df462f96
F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab
F test/with3.test 5e8ce2c585170bbbc0544e2a01a4941fa0be173ba5265e5c92eb588cd99a232d
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 16db73842ade5eb0fe02f257b91d1c7b41d830d3f17f8638b8fbaed309d9a852
-R 96748b81a5c5c17387af91f1f0c0dfa1
+P e74f86f271d6ab1ecd17c1ee63ab2aa0885ca56624be7382872f04d46c48ed86
+R a123bfa3a94ae6460114239fab9e1170
U dan
-Z 83b8eb197a3e3709547b1acd87361cc8
+Z 6b49a0a9a9265834682b1c9c02ee1753
-e74f86f271d6ab1ecd17c1ee63ab2aa0885ca56624be7382872f04d46c48ed86
\ No newline at end of file
+b6d9c7eda853420ae46a05bd432711e8bf9ebaa448c7d90ccfc0bcc338a87706
\ No newline at end of file
NC_IdxExpr|NC_PartIdx);
}
}
- if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
- || (pExpr->pWin && (pNC->ncFlags & NC_AllowWin)==0)
+
+ if( is_agg==0 && pExpr->pWin ){
+ sqlite3ErrorMsg(pParse,
+ "%.*s() may not be used as a window function", nId, zId
+ );
+ pNC->nErr++;
+ }else if(
+ (is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
+ || (is_agg && (pDef->funcFlags & SQLITE_FUNC_WINDOW) && !pExpr->pWin)
+ || (is_agg && pExpr->pWin && (pNC->ncFlags & NC_AllowWin)==0)
){
- const char *zType = pExpr->pWin ? "window" : "aggregate";
- sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId);
+ const char *zType;
+ if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->pWin ){
+ zType = "window";
+ }else{
+ zType = "aggregate";
+ }
+ sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()", zType, nId,zId);
pNC->nErr++;
is_agg = 0;
}else if( no_such_func && pParse->db->init.busy==0
/*
+** 2018 May 08
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
/* If this is "ROWS <expr1> FOLLOWING AND ROWS <expr2> FOLLOWING", do:
**
+ ** if( regEnd<regStart ){
+ ** // The frame always consists of 0 rows
+ ** regStart = regSize;
+ ** }
** regEnd = regEnd - regStart;
*/
if( pMWin->pEnd && pMWin->pStart && pMWin->eStart==TK_FOLLOWING ){
assert( pMWin->eEnd==TK_FOLLOWING );
+ sqlite3VdbeAddOp3(v, OP_Ge, regStart, sqlite3VdbeCurrentAddr(v)+2, regEnd);
+ sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd);
}
+ if( pMWin->pEnd && pMWin->pStart && pMWin->eEnd==TK_PRECEDING ){
+ assert( pMWin->eStart==TK_PRECEDING );
+ sqlite3VdbeAddOp3(v, OP_Le, regStart, sqlite3VdbeCurrentAddr(v)+3, regEnd);
+ sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
+ sqlite3VdbeAddOp2(v, OP_Copy, regSize, regEnd);
+ }
+
/* Initialize the accumulator register for each window function to NULL */
regArg = windowInitAccum(pParse, pMWin);
Window *pMWin = p->pWin;
Window *pWin;
+ /*
+ ** Call windowCodeRowExprStep() for all window modes *except*:
+ **
+ ** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+ ** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
+ ** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
+ ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
+ */
if( (pMWin->eType==TK_ROWS
&& (pMWin->eStart!=TK_UNBOUNDED||pMWin->eEnd!=TK_CURRENT||!pMWin->pOrderBy))
|| (pMWin->eStart==TK_CURRENT&&pMWin->eEnd==TK_UNBOUNDED&&pMWin->pOrderBy)
return;
}
+ /*
+ ** Call windowCodeCacheStep() if there is a window function that requires
+ ** that the entire partition be cached in a temp table before any rows
+ ** are returned.
+ */
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
FuncDef *pFunc = pWin->pFunc;
if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE)
a 1 1 a 2 2 a 3 3 a 4 4 a 5 5 a 6 6 a 7 7
}
-do_catchsql_test 3.5 {
+do_catchsql_test 6.3 {
SELECT x, lag(x) FILTER (WHERE (x%2)=0) OVER w FROM t1
WINDOW w AS (ORDER BY x)
} {1 {FILTER clause may only be used with aggregate window functions}}
+
+#-------------------------------------------------------------------------
+# Attempt to use a window function as an aggregate. And other errors.
+#
+reset_db
+do_execsql_test 7.0 {
+ CREATE TABLE t1(x, y);
+ INSERT INTO t1 VALUES(1, 2);
+ INSERT INTO t1 VALUES(3, 4);
+ INSERT INTO t1 VALUES(5, 6);
+ INSERT INTO t1 VALUES(7, 8);
+ INSERT INTO t1 VALUES(9, 10);
+}
+
+do_catchsql_test 7.1.1 {
+ SELECT nth_value(x, 1) FROM t1;
+} {1 {misuse of window function nth_value()}}
+do_catchsql_test 7.1.2 {
+ SELECT * FROM t1 WHERE nth_value(x, 1) OVER (ORDER BY y);
+} {1 {misuse of window function nth_value()}}
+do_catchsql_test 7.1.3 {
+ SELECT count(*) FROM t1 GROUP BY y HAVING nth_value(x, 1) OVER (ORDER BY y);
+} {1 {misuse of window function nth_value()}}
+do_catchsql_test 7.1.4 {
+ SELECT count(*) FROM t1 GROUP BY nth_value(x, 1) OVER (ORDER BY y);
+} {1 {misuse of window function nth_value()}}
+do_catchsql_test 7.1.5 {
+ SELECT count(*) FROM t1 LIMIT nth_value(x, 1) OVER (ORDER BY y);
+} {1 {no such column: x}}
+do_catchsql_test 7.1.6 {
+ SELECT trim(x) OVER (ORDER BY y) FROM t1;
+} {1 {trim() may not be used as a window function}}
+
finish_test
+
WINDOW w AS (ORDER BY a)
}
+execsql_test 3.5.1 {
+ SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 2 PRECEDING)
+ FROM t5
+}
+execsql_test 3.5.2 {
+ SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
+ FROM t5
+}
+execsql_test 3.5.3 {
+ SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 0 PRECEDING AND 0 PRECEDING)
+ FROM t5
+}
+
+execsql_test 3.6.1 {
+ SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 1 FOLLOWING)
+ FROM t5
+}
+execsql_test 3.6.2 {
+ SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING)
+ FROM t5
+}
+execsql_test 3.6.3 {
+ SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 0 FOLLOWING AND 0 FOLLOWING)
+ FROM t5
+}
+
finish_test
ORDER BY a;
} {1 1 5 2 2 4 3 3 3 4 4 2 5 5 1}
-explain_i {
- SELECT a, max(a) FILTER (WHERE (a%2)=0) OVER w FROM t5
- WINDOW w AS (ORDER BY a)
- }
- breakpoint
do_execsql_test 3.4 {
SELECT a, max(a) FILTER (WHERE (a%2)=0) OVER w FROM t5
WINDOW w AS (ORDER BY a)
} {1 {} 2 2 3 2 4 4 5 4}
+do_execsql_test 3.5.1 {
+ SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 2 PRECEDING)
+ FROM t5
+} {1 {} 2 {} 3 {} 4 {} 5 {}}
+
+do_execsql_test 3.5.2 {
+ SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING)
+ FROM t5
+} {1 {} 2 one 3 two 4 three 5 four}
+
+do_execsql_test 3.5.3 {
+ SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 0 PRECEDING AND 0 PRECEDING)
+ FROM t5
+} {1 one 2 two 3 three 4 four 5 five}
+
+do_execsql_test 3.6.1 {
+ SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 2 FOLLOWING AND 1 FOLLOWING)
+ FROM t5
+} {1 {} 2 {} 3 {} 4 {} 5 {}}
+
+do_execsql_test 3.6.2 {
+ SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING)
+ FROM t5
+} {1 two 2 three 3 four 4 five 5 {}}
+
+do_execsql_test 3.6.3 {
+ SELECT a, max(c) OVER (ORDER BY a ROWS BETWEEN 0 FOLLOWING AND 0 FOLLOWING)
+ FROM t5
+} {1 one 2 two 3 three 4 four 5 five}
+
finish_test