-C Document\sthe\srules\sfor\swhen\san\ssqlite3_blob\sobject\sexpires.\s(CVS\s5313)
-D 2008-06-26T15:04:58
+C Fix\shandling\sof\s"x\sIN\s(...)"\sand\s"x\sNOT\sIN\s(...)"\sexpressions\swhen\sthe\sset\scontains\san\sSQL\sNULL\svalue.\s(CVS\s5314)
+D 2008-06-26T18:04:03
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 325dfac0a0dd1cb4d975f1ace6453157892e6042
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c
F src/date.c e841168e5520bbbb2a1cbcdce7531d8b23017b4d
F src/delete.c d3fc5987f2eb88f7b9549d58a5dfea079a83fe8b
-F src/expr.c 1a8fbd3dfc531fa8ec51319a0bdef014e28c0fdd
+F src/expr.c edcc8a30453f63fe9eab3a3d714589f44f875d8d
F src/fault.c 3638519d1e0b82bccfafcb9f5ff491918b28f8e1
F src/func.c 1e7d9569570134ac0771a00382d9d4b41c4aa052
F src/global.c 2304cfa3288763bd2fed10caf8c6fbaa2b383f4e
F src/prepare.c aba51dad52308e3d9d2074d8ff4e612e7f1cab51
F src/printf.c 8b063da9dcde26b7c500a01444b718d86f21bc6e
F src/random.c 5c754319d38abdd6acd74601ee0105504adc508a
-F src/select.c 79f60dc4a7e90bb907c7a2cca42f45276d1ead99
+F src/select.c e27de53be426254e1b75690c9c99482bb1431b79
F src/shell.c 479807b87f0409289eec4a776cd6ae56d30544b1
F src/sqlite.h.in 2b9e8de3378101ad8ec8de98e3679ad5c2f39427
F src/sqlite3ext.h f162a72daef5ebf8b211fe8c0ec96e85d22fbf9b
-F src/sqliteInt.h 5ed69fd1affa577a47ce01baa42ee94f22f45ed7
+F src/sqliteInt.h 969acf22dbe79075e486074a8ffdc1e2fc2b8b1f
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
F src/status.c 6cb10377992505bd69f1ca1d75c1240a65f25a58
F src/table.c 1fa8f8113ac9cbc09ae4801c6d2a7f0af82c5822
F src/utf.c 8c94fa10efc78c2568d08d436acc59df4df7191b
F src/util.c 920d6d5dfdf25f7b85d2093705d8716f9b387e3b
F src/vacuum.c 14eb21b480924d87e791cd8ab6fb35ac563243ef
-F src/vdbe.c c0daf1d1fb4c3c79805004969d5d036f3d2381f8
+F src/vdbe.c b1528683ff7ca1faf017db5ebedbc403e92d009b
F src/vdbe.h c46155c221418bea29ee3a749d5950fcf85a70e2
F src/vdbeInt.h 30535c1d30ba1b5fb58d8f0e1d1261af976558aa
F src/vdbeapi.c a7c6b8db324cf7eccff32de871dea36aa305c994
F src/vdbefifo.c c46dae1194e4277bf007144d7e5b0c0b1c24f136
F src/vdbemem.c a39a822e6ae61c4cab4a512df4a315888b206911
F src/vtab.c 2096c03ec5540a43c8c73a8f43407dfd3549a982
-F src/where.c 767db25b4b92a5e0a6f1b75ba40abf377b65a212
+F src/where.c 6a22ceb86d774c4428ac53196f721bb14e6cbdfa
F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/all.test ed6849e7a425620d5d4388409f3b15901b5bc2e7
F test/fuzz_malloc.test 166b58dfd77cc04f6afeeaef0cfc1087abf134d1
F test/hook.test e17d4ed2843ba4ef9b234aa63e6f056bf88f9a19
F test/icu.test e6bfae7f625c88fd14df6f540fe835bdfc1e4329
-F test/in.test ca4ea8ac1077f5221055fcb66969892612632ef7
+F test/in.test b35fc31caf26647cc4243c3af8ad29e45ed8776f
F test/in2.test b1f447f4f0f67e9f83ff931e7e2e30873f9ea055
F test/in3.test dc62b080ed79898121c61c91118b4d1e111f1438
F test/incrblob.test 4455fffd08b2f9418a9257e18b135d72273eff3e
-F test/incrblob2.test a1db17c1f70bdbf9cae8415fb500df511569306a
+F test/incrblob2.test c9aad1e11f7726d8c49e66f2a1ecc2d04f9f6861
F test/incrblob_err.test a3e3d9442d2993e8a449e791db4001d11a2f683f
F test/incrvacuum.test 1a2b0bddc76629afeb41e3d8ea3e4563982d16b9
F test/incrvacuum2.test 46ef65f377e3937cfd1ba66e818309dab46f590d
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P 1e3b8308021107d983d2152663f62b369cca091d
-R 5972f13e602e13f1fa109add837cf301
-U drh
-Z 6e75d867f7857f56f8d906b33d9926f0
+P e1de2287fd9b067f687cb8b427786b878af6c5b7
+R 01ffd027189ad04179892df9936c6090
+U danielk1977
+Z c4dcbe6b5c0897a85aa2b72a88c7084f
-e1de2287fd9b067f687cb8b427786b878af6c5b7
\ No newline at end of file
+d45a97be71fa61ab4a692bd807ab762130f7f5b9
\ No newline at end of file
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
-** $Id: expr.c,v 1.376 2008/06/24 12:46:31 drh Exp $
+** $Id: expr.c,v 1.377 2008/06/26 18:04:03 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
**
** SELECT <column> FROM <table>
**
-** If the mustBeUnique parameter is false, the structure will be used
-** for fast set membership tests. In this case an epheremal table must
-** be used unless <column> is an INTEGER PRIMARY KEY or an index can
-** be found with <column> as its left-most column.
-**
-** If mustBeUnique is true, then the structure will be used to iterate
+** If prNotFound parameter is 0, then the structure will be used to iterate
** through the set members, skipping any duplicates. In this case an
** epheremal table must be used unless the selected <column> is guaranteed
** to be unique - either because it is an INTEGER PRIMARY KEY or it
** is unique by virtue of a constraint or implicit index.
+**
+** If the prNotFound parameter is not 0, then the structure will be used
+** for fast set membership tests. In this case an epheremal table must
+** be used unless <column> is an INTEGER PRIMARY KEY or an index can
+** be found with <column> as its left-most column.
+**
+** When the structure is being used for set membership tests, the user
+** needs to know whether or not the structure contains an SQL NULL
+** value in order to correctly evaluate expressions like "X IN (Y, Z)".
+** If there is a chance that the structure may contain a NULL value at
+** runtime, then a register is allocated and the register number written
+** to *prNotFound. If there is no chance that the structure contains a
+** NULL value, then *prNotFound is left unchanged.
+**
+** If a register is allocated and its location stored in *prNotFound, then
+** its initial value is NULL. If the structure does not remain constant
+** for the duration of the query (i.e. the set is a correlated sub-select),
+** the value of the allocated register is reset to NULL each time the
+** structure is repopulated. This allows the caller to use vdbe code
+** equivalent to the following:
+**
+** if( register==NULL ){
+** has_null = <test if data structure contains null>
+** register = 1
+** }
+**
+** in order to avoid running the <test if data structure contains null>
+** test more often than is necessary.
*/
#ifndef SQLITE_OMIT_SUBQUERY
-int sqlite3FindInIndex(Parse *pParse, Expr *pX, int mustBeUnique){
+int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
Select *p;
int eType = 0;
int iTab = pParse->nTab++;
+ int mustBeUnique = !prNotFound;
/* The follwing if(...) expression is true if the SELECT is of the
** simple form:
eType = IN_INDEX_INDEX;
sqlite3VdbeJumpHere(v, iAddr);
+ if( prNotFound && !pTab->aCol[iCol].notNull ){
+ *prNotFound = ++pParse->nMem;
+ }
}
}
}
}
if( eType==0 ){
- sqlite3CodeSubselect(pParse, pX);
+ int rMayHaveNull = 0;
+ if( prNotFound ){
+ *prNotFound = rMayHaveNull = ++pParse->nMem;
+ }
+ sqlite3CodeSubselect(pParse, pX, rMayHaveNull);
eType = IN_INDEX_EPH;
}else{
pX->iTable = iTab;
** operator or subquery.
*/
#ifndef SQLITE_OMIT_SUBQUERY
-void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
+void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr, int rMayHaveNull){
int testAddr = 0; /* One-time test address */
Vdbe *v = sqlite3GetVdbe(pParse);
if( v==0 ) return;
KeyInfo keyInfo;
int addr; /* Address of OP_OpenEphemeral instruction */
+ if( rMayHaveNull ){
+ sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull);
+ }
+
affinity = sqlite3ExprAffinity(pExpr->pLeft);
/* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
testcase( op==TK_EXISTS );
testcase( op==TK_SELECT );
if( pExpr->iColumn==0 ){
- sqlite3CodeSubselect(pParse, pExpr);
+ sqlite3CodeSubselect(pParse, pExpr, 0);
}
inReg = pExpr->iColumn;
break;
}
case TK_IN: {
+ int rNotFound = 0;
+ int rMayHaveNull = 0;
int j1, j2, j3, j4, j5;
char affinity;
int eType;
- eType = sqlite3FindInIndex(pParse, pExpr, 0);
+ eType = sqlite3FindInIndex(pParse, pExpr, &rMayHaveNull);
+ if( rMayHaveNull ){
+ rNotFound = ++pParse->nMem;
+ }
/* Figure out the affinity to use to create a key from the results
** of the expression. affinityStr stores a static string suitable for
j5 = sqlite3VdbeAddOp0(v, OP_Goto);
sqlite3VdbeJumpHere(v, j3);
sqlite3VdbeJumpHere(v, j4);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, target);
}else{
r2 = regFree2 = sqlite3GetTempReg(pParse);
+
+ /* Create a record and test for set membership. If the set contains
+ ** the value, then jump to the end of the test code. The target
+ ** register still contains the true (1) value written to it earlier.
+ */
sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1);
sqlite3ExprCacheAffinityChange(pParse, r1, 1);
j5 = sqlite3VdbeAddOp3(v, OP_Found, pExpr->iTable, 0, r2);
+
+ /* If the set membership test fails, then the result of the
+ ** "x IN (...)" expression must be either 0 or NULL. If the set
+ ** contains no NULL values, then the result is 0. If the set
+ ** contains one or more NULL values, then the result of the
+ ** expression is also NULL.
+ */
+ if( rNotFound==0 ){
+ /* This branch runs if it is known at compile time (now) that
+ ** the set contains no NULL values. This happens as the result
+ ** of a "NOT NULL" constraint in the database schema. No need
+ ** to test the data structure at runtime in this case.
+ */
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, target);
+ }else{
+ /* This block populates the rNotFound register with either NULL
+ ** or 0 (an integer value). If the data structure contains one
+ ** or more NULLs, then set rNotFound to NULL. Otherwise, set it
+ ** to 0. If register rMayHaveNull is already set to some value
+ ** other than NULL, then the test has already been run and
+ ** rNotFound is already populated.
+ */
+ j3 = sqlite3VdbeAddOp1(v, OP_NotNull, rMayHaveNull);
+ sqlite3VdbeAddOp2(v, OP_Null, 0, rNotFound);
+ sqlite3VdbeAddOp2(v, OP_Integer, 1, rMayHaveNull);
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, rNotFound, 1, r2, 0, 1);
+ j4 = sqlite3VdbeAddOp3(v, OP_Found, pExpr->iTable, 0, r2);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, rNotFound);
+ sqlite3VdbeJumpHere(v, j4);
+ sqlite3VdbeJumpHere(v, j3);
+
+ /* Copy the value of register rNotFound (which is either NULL or 0)
+ ** into the target register. This will be the result of the
+ ** expression.
+ */
+ sqlite3VdbeAddOp2(v, OP_Copy, rNotFound, target);
+ }
}
- sqlite3VdbeAddOp2(v, OP_AddImm, target, -1);
sqlite3VdbeJumpHere(v, j2);
sqlite3VdbeJumpHere(v, j5);
break;
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
-** $Id: select.c,v 1.436 2008/06/25 00:12:41 drh Exp $
+** $Id: select.c,v 1.437 2008/06/26 18:04:03 danielk1977 Exp $
*/
#include "sqliteInt.h"
int addr2;
assert( nColumn==1 );
- addr2 = sqlite3VdbeAddOp1(v, OP_IsNull, regResult);
p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity);
if( pOrderBy ){
/* At first glance you would think we could optimize out the
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
sqlite3ReleaseTempReg(pParse, r1);
}
- sqlite3VdbeJumpHere(v, addr2);
break;
}
}
#ifndef SQLITE_OMIT_SUBQUERY
case SRT_Set: {
- int j1;
assert( nColumn==1 );
- j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regRow);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1);
sqlite3ExprCacheAffinityChange(pParse, regRow, 1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid);
- sqlite3VdbeJumpHere(v, j1);
break;
}
case SRT_Mem: {
case SRT_Set: {
int addr2, r1;
assert( pIn->nMem==1 );
- addr2 = sqlite3VdbeAddOp1(v, OP_IsNull, pIn->iMem);
p->affinity =
sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity);
r1 = sqlite3GetTempReg(pParse);
sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, 1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iParm, r1);
sqlite3ReleaseTempReg(pParse, r1);
- sqlite3VdbeJumpHere(v, addr2);
break;
}
**
** SRT_Mem Store first result in memory cell pDest->iParm
**
-** SRT_Set Store non-null results as keys of table pDest->iParm.
+** SRT_Set Store results as keys of table pDest->iParm.
** Apply the affinity pDest->affinity before storing them.
**
** SRT_Union Store results as a key in a temporary table pDest->iParm.
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.731 2008/06/26 10:54:12 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.732 2008/06/26 18:04:03 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
#define SRT_Callback 5 /* Invoke a callback with each row of result */
#define SRT_Mem 6 /* Store result in a memory cell */
-#define SRT_Set 7 /* Store non-null results as keys in an index */
+#define SRT_Set 7 /* Store results as keys in an index */
#define SRT_Table 8 /* Store result as data with an automatic rowid */
#define SRT_EphemTab 9 /* Create transient tab and store like SRT_Table */
#define SRT_Coroutine 10 /* Generate a single row of result */
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*);
-void sqlite3CodeSubselect(Parse *, Expr *);
+void sqlite3CodeSubselect(Parse *, Expr *, int);
int sqlite3SelectResolve(Parse *, Select *, NameContext *);
void sqlite3ColumnDefault(Vdbe *, Table *, int);
void sqlite3AlterFinishAddColumn(Parse *, Token *);
#define IN_INDEX_ROWID 1
#define IN_INDEX_EPH 2
#define IN_INDEX_INDEX 3
-int sqlite3FindInIndex(Parse *, Expr *, int);
+int sqlite3FindInIndex(Parse *, Expr *, int*);
#ifdef SQLITE_ENABLE_ATOMIC_WRITE
int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
-** $Id: vdbe.c,v 1.755 2008/06/25 00:12:41 drh Exp $
+** $Id: vdbe.c,v 1.756 2008/06/26 18:04:03 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
/* Opcode: AddImm P1 P2 * * *
**
-** Add the constant P2 the value in register P1.
+** Add the constant P2 to the value in register P1.
** The result is always an integer.
**
** To force any register to be an integer, just add 0.
** so is applicable. Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
-** $Id: where.c,v 1.310 2008/06/25 02:47:57 drh Exp $
+** $Id: where.c,v 1.311 2008/06/26 18:04:03 danielk1977 Exp $
*/
#include "sqliteInt.h"
assert( pX->op==TK_IN );
iReg = iTarget;
- eType = sqlite3FindInIndex(pParse, pX, 1);
+ eType = sqlite3FindInIndex(pParse, pX, 0);
iTab = pX->iTable;
sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
VdbeComment((v, "%.*s", pX->span.n, pX->span.z));
# This file implements regression tests for SQLite library. The
# focus of this file is testing the IN and BETWEEN operator.
#
-# $Id: in.test,v 1.20 2008/06/24 12:46:31 drh Exp $
+# $Id: in.test,v 1.21 2008/06/26 18:04:03 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
}
} {1 {SELECTs to the left and right of INTERSECT do not have the same number of result columns}}
+
+#------------------------------------------------------------------------
+# The following tests check that NULL is handled correctly when it
+# appears as part of a set of values on the right-hand side of an
+# IN or NOT IN operator.
+#
+# When it appears in such a set, NULL is handled as an "unknown value".
+# If, because of the unknown value in the set, the result of the expression
+# cannot be determined, then it itself evaluates to NULL.
+#
+
+# Warm body test to demonstrate the principles being tested:
+#
+do_test in-13.1 {
+ db nullvalue "null"
+ execsql { SELECT
+ 1 IN (NULL, 1, 2), -- The value 1 is a member of the set, return true.
+ 3 IN (NULL, 1, 2), -- Ambiguous, return NULL.
+ 1 NOT IN (NULL, 1, 2), -- The value 1 is a member of the set, return false.
+ 3 NOT IN (NULL, 1, 2) -- Ambiguous, return NULL.
+ }
+} {1 null 0 null}
+
+do_test in-13.2 {
+ execsql {
+ CREATE TABLE t7(a, b, c NOT NULL);
+ INSERT INTO t7 VALUES(1, 1, 1);
+ INSERT INTO t7 VALUES(2, 2, 2);
+ INSERT INTO t7 VALUES(3, 3, 3);
+ INSERT INTO t7 VALUES(NULL, 4, 4);
+ INSERT INTO t7 VALUES(NULL, 5, 5);
+ }
+} {}
+
+do_test in-13.3 {
+ execsql { SELECT 2 IN (SELECT a FROM t7) }
+} {1}
+do_test in-13.4 {
+ execsql { SELECT 6 IN (SELECT a FROM t7) }
+} {null}
+
+do_test in-13.5 {
+ execsql { SELECT 2 IN (SELECT b FROM t7) }
+} {1}
+do_test in-13.6 {
+ execsql { SELECT 6 IN (SELECT b FROM t7) }
+} {0}
+
+do_test in-13.7 {
+ execsql { SELECT 2 IN (SELECT c FROM t7) }
+} {1}
+do_test in-13.8 {
+ execsql { SELECT 6 IN (SELECT c FROM t7) }
+} {0}
+
+do_test in-13.9 {
+ execsql {
+ SELECT
+ 2 NOT IN (SELECT a FROM t7),
+ 6 NOT IN (SELECT a FROM t7),
+ 2 NOT IN (SELECT b FROM t7),
+ 6 NOT IN (SELECT b FROM t7),
+ 2 NOT IN (SELECT c FROM t7),
+ 6 NOT IN (SELECT c FROM t7)
+ }
+} {0 null 0 1 0 1}
+
+do_test in-13.10 {
+ execsql {
+ SELECT b IN (
+ SELECT inside.a
+ FROM t7 AS inside
+ WHERE inside.b BETWEEN outside.b+1 AND outside.b+2
+ )
+ FROM t7 AS outside ORDER BY b;
+ }
+} {0 null null null 0}
+
+do_test in-13.11 {
+ execsql {
+ SELECT b NOT IN (
+ SELECT inside.a
+ FROM t7 AS inside
+ WHERE inside.b BETWEEN outside.b+1 AND outside.b+2
+ )
+ FROM t7 AS outside ORDER BY b;
+ }
+} {1 null null null 1}
+
+do_test in-13.12 {
+ execsql {
+ CREATE INDEX i1 ON t7(a);
+ CREATE INDEX i2 ON t7(b);
+ CREATE INDEX i3 ON t7(c);
+ }
+ execsql {
+ SELECT
+ 2 IN (SELECT a FROM t7),
+ 6 IN (SELECT a FROM t7),
+ 2 IN (SELECT b FROM t7),
+ 6 IN (SELECT b FROM t7),
+ 2 IN (SELECT c FROM t7),
+ 6 IN (SELECT c FROM t7)
+ }
+} {1 null 1 0 1 0}
+
+do_test in-13.13 {
+ execsql {
+ SELECT
+ 2 NOT IN (SELECT a FROM t7),
+ 6 NOT IN (SELECT a FROM t7),
+ 2 NOT IN (SELECT b FROM t7),
+ 6 NOT IN (SELECT b FROM t7),
+ 2 NOT IN (SELECT c FROM t7),
+ 6 NOT IN (SELECT c FROM t7)
+ }
+} {0 null 0 1 0 1}
+
+do_test in-13.14 {
+ execsql {
+ BEGIN TRANSACTION;
+ CREATE TABLE a(id INTEGER);
+ INSERT INTO a VALUES(1);
+ INSERT INTO a VALUES(2);
+ INSERT INTO a VALUES(3);
+ CREATE TABLE b(id INTEGER);
+ INSERT INTO b VALUES(NULL);
+ INSERT INTO b VALUES(3);
+ INSERT INTO b VALUES(4);
+ INSERT INTO b VALUES(5);
+ COMMIT;
+ SELECT * FROM a WHERE id NOT IN (SELECT id FROM b);
+ }
+} {}
+do_test in-13.14 {
+ execsql {
+ CREATE INDEX i5 ON b(id);
+ SELECT * FROM a WHERE id NOT IN (SELECT id FROM b);
+ }
+} {}
+
+
+do_test in-13.X {
+ db nullvalue ""
+} {}
+
finish_test
# Test that it is possible to have two open blob handles on a single
# blob object.
#
-# $Id: incrblob2.test,v 1.6 2008/06/25 14:31:53 drh Exp $
+# $Id: incrblob2.test,v 1.7 2008/06/26 18:04:03 danielk1977 Exp $
#
set testdir [file dirname $argv0]
close $h
} {}
+#do_test incrblob2-8.5 {
+ #execsql BEGIN
+ #db eval {SELECT * FROM t2} {
+ #execsql "DROP TABLE t2"
+ #}
+#} {}
+
finish_test