Index: VERSION
==================================================================
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
-3.30.0
+3.30.1
Index: configure
==================================================================
--- configure
+++ configure
@@ -1,8 +1,8 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for sqlite 3.30.0.
+# Generated by GNU Autoconf 2.69 for sqlite 3.30.1.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
@@ -724,12 +724,12 @@
MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
-PACKAGE_VERSION='3.30.0'
-PACKAGE_STRING='sqlite 3.30.0'
+PACKAGE_VERSION='3.30.1'
+PACKAGE_STRING='sqlite 3.30.1'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
# Factoring default headers for most tests.
ac_includes_default="\
@@ -1464,11 +1464,11 @@
#
if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures sqlite 3.30.0 to adapt to many kinds of systems.
+\`configure' configures sqlite 3.30.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE. See below for descriptions of some of the useful variables.
@@ -1529,11 +1529,11 @@
_ACEOF
fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of sqlite 3.30.0:";;
+ short | recursive ) echo "Configuration of sqlite 3.30.1:";;
esac
cat <<\_ACEOF
Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
@@ -1655,11 +1655,11 @@
fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-sqlite configure 3.30.0
+sqlite configure 3.30.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
@@ -2074,11 +2074,11 @@
} # ac_fn_c_check_header_mongrel
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by sqlite $as_me 3.30.0, which was
+It was created by sqlite $as_me 3.30.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
_ACEOF
@@ -12230,11 +12230,11 @@
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by sqlite $as_me 3.30.0, which was
+This file was extended by sqlite $as_me 3.30.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
CONFIG_LINKS = $CONFIG_LINKS
@@ -12296,11 +12296,11 @@
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-sqlite config.status 3.30.0
+sqlite config.status 3.30.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
Index: ext/fts5/test/fts5misc.test
==================================================================
--- ext/fts5/test/fts5misc.test
+++ ext/fts5/test/fts5misc.test
@@ -56,8 +56,56 @@
do_catchsql_test 1.3.3 {
SELECT a FROM t1
WHERE rank = (SELECT highlight(t1, 4, '', '') FROM t1('*reads'));
} {1 {no such cursor: 1}}
+
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test 2.0 {
+ CREATE TABLE t0(c0);
+ CREATE VIRTUAL TABLE vt0 USING fts5(c0);
+}
+do_execsql_test 2.1.1 {
+ BEGIN TRANSACTION;
+ INSERT INTO vt0(c0) VALUES ('xyz');
+}
+do_execsql_test 2.1.2 {
+ ALTER TABLE t0 ADD COLUMN c5;
+}
+do_execsql_test 2.1.3 {
+ INSERT INTO vt0(vt0) VALUES('integrity-check');
+}
+do_execsql_test 2.1.4 {
+ INSERT INTO vt0(c0) VALUES ('abc');
+ COMMIT
+}
+do_execsql_test 2.1.5 {
+ INSERT INTO vt0(vt0) VALUES('integrity-check');
+}
+
+reset_db
+do_execsql_test 2.2.1 {
+ CREATE TABLE t0(c0);
+ CREATE VIRTUAL TABLE vt0 USING fts5(c0);
+ BEGIN TRANSACTION;
+ INSERT INTO vt0(c0) VALUES ('xyz');
+}
+
+breakpoint
+do_execsql_test 2.2.2 {
+ ALTER TABLE t0 RENAME TO t1;
+}
+do_execsql_test 2.2.3 {
+ INSERT INTO vt0(vt0) VALUES('integrity-check');
+}
+do_execsql_test 2.2.4 {
+ INSERT INTO vt0(c0) VALUES ('abc');
+ COMMIT;
+}
+do_execsql_test 2.2.5 {
+ INSERT INTO vt0(vt0) VALUES('integrity-check');
+}
+
finish_test
Index: src/alter.c
==================================================================
--- src/alter.c
+++ src/alter.c
@@ -433,10 +433,11 @@
}
if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
goto exit_begin_add_column;
}
+ sqlite3MayAbort(pParse);
assert( pTab->addColOffset>0 );
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
/* Put a copy of the Table struct in Parse.pNewTable for the
** sqlite3AddColumn() function and friends to modify. But modify
Index: src/expr.c
==================================================================
--- src/expr.c
+++ src/expr.c
@@ -5144,18 +5144,20 @@
case TK_IS:
case TK_OR:
case TK_CASE:
case TK_IN:
case TK_FUNCTION:
+ case TK_TRUTH:
testcase( pExpr->op==TK_ISNOT );
testcase( pExpr->op==TK_ISNULL );
testcase( pExpr->op==TK_NOTNULL );
testcase( pExpr->op==TK_IS );
testcase( pExpr->op==TK_OR );
testcase( pExpr->op==TK_CASE );
testcase( pExpr->op==TK_IN );
testcase( pExpr->op==TK_FUNCTION );
+ testcase( pExpr->op==TK_TRUTH );
return WRC_Prune;
case TK_COLUMN:
if( pWalker->u.iCur==pExpr->iTable ){
pWalker->eCode = 1;
return WRC_Abort;
Index: src/select.c
==================================================================
--- src/select.c
+++ src/select.c
@@ -98,13 +98,13 @@
sqlite3ExprDelete(db, p->pLimit);
#ifndef SQLITE_OMIT_WINDOWFUNC
if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){
sqlite3WindowListDelete(db, p->pWinDefn);
}
-#endif
- if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
assert( p->pWin==0 );
+#endif
+ if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
if( bFree ) sqlite3DbFreeNN(db, p);
p = pPrior;
bFree = 1;
}
}
@@ -3501,10 +3501,18 @@
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
substSelect(pSubst, pExpr->x.pSelect, 1);
}else{
substExprList(pSubst, pExpr->x.pList);
}
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( ExprHasProperty(pExpr, EP_WinFunc) ){
+ Window *pWin = pExpr->y.pWin;
+ pWin->pFilter = substExpr(pSubst, pWin->pFilter);
+ substExprList(pSubst, pWin->pPartition);
+ substExprList(pSubst, pWin->pOrderBy);
+ }
+#endif
}
return pExpr;
}
static void substExprList(
SubstContext *pSubst, /* Description of the substitution */
Index: src/sqliteInt.h
==================================================================
--- src/sqliteInt.h
+++ src/sqliteInt.h
@@ -2603,13 +2603,17 @@
/*
** True if the expression passed as an argument was a function with
** an OVER() clause (a window function).
*/
-#define IsWindowFunc(p) ( \
+#ifdef SQLITE_OMIT_WINDOWFUNC
+# define IsWindowFunc(p) 0
+#else
+# define IsWindowFunc(p) ( \
ExprHasProperty((p), EP_WinFunc) && p->y.pWin->eFrmType!=TK_FILTER \
-)
+ )
+#endif
/*
** A list of expressions. Each expression may optionally have a
** name. An expr/name combination can be used in several ways, such
** as the list of "expr AS ID" fields following a "SELECT" or in the
Index: src/vdbe.c
==================================================================
--- src/vdbe.c
+++ src/vdbe.c
@@ -4536,27 +4536,31 @@
u64 iKey;
pIn3 = &aMem[pOp->p3];
testcase( pIn3->flags & MEM_Int );
testcase( pIn3->flags & MEM_IntReal );
+ testcase( pIn3->flags & MEM_Real );
+ testcase( (pIn3->flags & (MEM_Str|MEM_Int))==MEM_Str );
if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){
- /* Make sure pIn3->u.i contains a valid integer representation of
- ** the key value, but do not change the datatype of the register, as
- ** other parts of the perpared statement might be depending on the
- ** current datatype. */
- u16 origFlags = pIn3->flags;
- int isNotInt;
- applyAffinity(pIn3, SQLITE_AFF_NUMERIC, encoding);
- isNotInt = (pIn3->flags & MEM_Int)==0;
- pIn3->flags = origFlags;
- if( isNotInt ) goto jump_to_p2;
+ /* If pIn3->u.i does not contain an integer, compute iKey as the
+ ** integer value of pIn3. Jump to P2 if pIn3 cannot be converted
+ ** into an integer without loss of information. Take care to avoid
+ ** changing the datatype of pIn3, however, as it is used by other
+ ** parts of the prepared statement. */
+ Mem x = pIn3[0];
+ applyAffinity(&x, SQLITE_AFF_NUMERIC, encoding);
+ if( (x.flags & MEM_Int)==0 ) goto jump_to_p2;
+ iKey = x.u.i;
+ goto notExistsWithKey;
}
/* Fall through into OP_NotExists */
case OP_NotExists: /* jump, in3 */
pIn3 = &aMem[pOp->p3];
assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid );
assert( pOp->p1>=0 && pOp->p1nCursor );
+ iKey = pIn3->u.i;
+notExistsWithKey:
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
#ifdef SQLITE_DEBUG
if( pOp->opcode==OP_SeekRowid ) pC->seekOp = OP_SeekRowid;
#endif
@@ -4563,11 +4567,10 @@
assert( pC->isTable );
assert( pC->eCurType==CURTYPE_BTREE );
pCrsr = pC->uc.pCursor;
assert( pCrsr!=0 );
res = 0;
- iKey = pIn3->u.i;
rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
assert( rc==SQLITE_OK || res==0 );
pC->movetoTarget = iKey; /* Used by OP_Delete */
pC->nullRow = 0;
pC->cacheStatus = CACHE_STALE;
Index: src/vdbeaux.c
==================================================================
--- src/vdbeaux.c
+++ src/vdbeaux.c
@@ -640,11 +640,11 @@
while( (pOp = opIterNext(&sIter))!=0 ){
int opcode = pOp->opcode;
if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
|| opcode==OP_VDestroy
- || (opcode==OP_Function0 && pOp->p4.pFunc->funcFlags&SQLITE_FUNC_INTERNAL)
+ || (opcode==OP_ParseSchema && pOp->p4.z==0)
|| ((opcode==OP_Halt || opcode==OP_HaltIfNull)
&& ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort))
){
hasAbort = 1;
break;
Index: test/filter1.test
==================================================================
--- test/filter1.test
+++ test/filter1.test
@@ -161,8 +161,28 @@
SELECT a, avg(c) FILTER (WHERE b!=1) AS h FROM t1 GROUP BY a ORDER BY avg(c);
} {c 2.0 a 10.0 b 5.0}
do_execsql_test 4.4 {
SELECT a, avg(c) FILTER (WHERE b!=1) FROM t1 GROUP BY a ORDER BY 2
} {c 2.0 b 5.0 a 10.0}
+
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test 5.0 {
+ CREATE TABLE t1(a, b);
+ INSERT INTO t1 VALUES(1, 2);
+ INSERT INTO t1 VALUES(1, 3);
+}
+
+do_execsql_test 5.1 {
+ SELECT count(*) FILTER (WHERE b>2) FROM (SELECT * FROM t1)
+} {1}
+
+do_execsql_test 5.2 {
+ SELECT count(*) FILTER (WHERE b>2) OVER () FROM (SELECT * FROM t1)
+} {1 1}
+
+do_execsql_test 5.3 {
+ SELECT count(*) FILTER (WHERE b>2) OVER (ORDER BY b) FROM (SELECT * FROM t1)
+} {0 1}
finish_test
Index: test/join.test
==================================================================
--- test/join.test
+++ test/join.test
@@ -881,7 +881,29 @@
} {1 1 1 1}
do_execsql_test join-17.110 {
SELECT * FROM t1 LEFT JOIN (SELECT abs(1)+2 AS y FROM t1) ON x
WHERE NOT(y='a');
} {1 3 1 3}
+
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test join-18.1 {
+ CREATE TABLE t0(a);
+ CREATE TABLE t1(b);
+ CREATE VIEW v0 AS SELECT a FROM t1 LEFT JOIN t0;
+ INSERT INTO t1 VALUES (1);
+} {}
+
+do_execsql_test join-18.2 {
+ SELECT * FROM v0 WHERE NOT(v0.a IS FALSE);
+} {{}}
+
+do_execsql_test join-18.3 {
+ SELECT * FROM t1 LEFT JOIN t0 WHERE NOT(a IS FALSE);
+} {1 {}}
+
+do_execsql_test join-18.4 {
+ SELECT NOT(v0.a IS FALSE) FROM v0
+} {1}
finish_test
+
Index: test/window1.test
==================================================================
--- test/window1.test
+++ test/window1.test
@@ -1187,7 +1187,51 @@
WINDOW win1 AS (ORDER BY a GROUPS BETWEEN 4 PRECEDING AND 1 FOLLOWING
EXCLUDE CURRENT ROW),
win2 AS (PARTITION BY b ORDER BY a),
win3 AS (win2 RANGE BETWEEN 5.2 PRECEDING AND true PRECEDING );
} {1 1}
+
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test 31.1 {
+ CREATE TABLE t1(a, b);
+ CREATE TABLE t2(c, d);
+ CREATE TABLE t3(e, f);
+
+ INSERT INTO t1 VALUES(1, 1);
+ INSERT INTO t2 VALUES(1, 1);
+ INSERT INTO t3 VALUES(1, 1);
+}
+
+do_execsql_test 31.2 {
+ SELECT d IN (SELECT sum(c) OVER (ORDER BY e+c) FROM t3) FROM (
+ SELECT * FROM t2
+ );
+} {1}
+
+do_execsql_test 31.3 {
+ SELECT d IN (SELECT sum(c) OVER (PARTITION BY d ORDER BY e+c) FROM t3) FROM (
+ SELECT * FROM t2
+ );
+} {1}
+
+do_catchsql_test 31.3 {
+ SELECT d IN (
+ SELECT sum(c) OVER ( ROWS BETWEEN d FOLLOWING AND UNBOUNDED FOLLOWING)
+ FROM t3
+ )
+ FROM (
+ SELECT * FROM t2
+ );
+} {1 {frame starting offset must be a non-negative integer}}
+
+do_catchsql_test 31.3 {
+ SELECT d IN (
+ SELECT sum(c) OVER ( ROWS BETWEEN CURRENT ROW AND c FOLLOWING)
+ FROM t3
+ )
+ FROM (
+ SELECT * FROM t2
+ );
+} {1 {frame ending offset must be a non-negative integer}}
finish_test