-C Remove\sdebugging\slogic\saccidently\sincluded\sin\sthe\sprevious\scheck-in.
-D 2015-03-13T00:11:09.762
+C Extra\stests\sfor\scommit\s[0f250957].
+D 2015-03-13T08:31:54.154
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 88a3e6261286db378fdffa1124cad11b3c05f5bb
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c 81712116e826b0089bb221b018929536b2b5406f
F src/table.c e7a09215315a978057fb42c640f890160dbcc45e
-F src/tclsqlite.c b290774586f022e16e04ba8ed2f0b8edd86b5b77
+F src/tclsqlite.c fa72a7c5278662357c105ba7925c1d0972506ff9
F src/test1.c 90fbedce75330d48d99eadb7d5f4223e86969585
F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d
F src/test3.c 64d2afdd68feac1bb5e2ffb8226c8c639f798622
F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
-F src/test_func.c 14e543ae4d905ee31dc322b2f8d31bfac1769d45
+F src/test_func.c f1ac201465472e76a73e2f3695c3553c63e7322a
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32
F src/test_intarray.c 6c610a21ab8edde85a3a2c7f2b069244ecf4d834
F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75
F src/vdbeaux.c 97911edb61074b871ec4aa2d6bb779071643dee5
F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90
-F src/vdbemem.c d52fa9f3bcf75d27d7b7846d81ee7898829c763d
+F src/vdbemem.c 78aef62d0298e15485cb5a429c912c9c3ed054b8
F src/vdbesort.c 6d64c5448b64851b99931ede980addc3af70d5e2
F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
F src/vtab.c 699f2b8d509cfe379c33dde33827875d5b030e01
F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93
F test/analyzeD.test 08f9d0bee4e118a66fff3a32d02dbe0ee0a2b594
F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d
-F test/analyzeF.test 299a47183c648d8ad92671f313def8fd7cb09875
+F test/analyzeF.test 7ccd7a04f7d3061bde1a8a4dacc4792edccf6bf2
F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b
F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b
F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7
F test/mallocH.test 79b65aed612c9b3ed2dcdaa727c85895fd1bfbdb
F test/mallocI.test a88c2b9627c8506bf4703d8397420043a786cdb6
F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e
-F test/mallocK.test 223cc80c870c80d4a9c2014e94133efdf0123f82
+F test/mallocK.test da01dcdd316767b8356741f8d33a23a06a23def5
F test/mallocL.test 252ddc7eb4fbf75364eab17b938816085ff1fc17
F test/malloc_common.tcl 3663f9001ce3e29bbaa9677ffe15cd468e3ec7e3
F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
F test/table.test 06271d61eb13871490d38168433c1ef3dd82bb2a
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
-F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43
+F test/tclsqlite.test 7fb866443c7deceed22b63948ccd6f76b52ad054
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 3ac1f6a3cf1a8fd3ab1ca96b2564c13c4b8d2234
-R f96af88025cc91d1b5a757f614ed39bf
-U drh
-Z e7218e6f8a6b14017f98ae01eb2e9668
+P 2887fb38ffc28712c34028cd38db2b7993d864eb
+R b89c9ce97b230db0ae63022a487b40cc
+U dan
+Z ccca41f9c448bc442b12b8c9fe5620ec
-2887fb38ffc28712c34028cd38db2b7993d864eb
\ No newline at end of file
+5aa522dcb9bfa18d49683f7cc889516984e2bcd2
\ No newline at end of file
}
/*
- ** $db function NAME [-argcount N] SCRIPT
+ ** $db function NAME [-argcount N] [-deterministic] SCRIPT
**
** Create a new SQL function called NAME. Whenever that function is
** called, invoke SCRIPT to evaluate the function.
*/
case DB_FUNCTION: {
+ int flags = SQLITE_UTF8;
SqlFunc *pFunc;
Tcl_Obj *pScript;
char *zName;
int nArg = -1;
- if( objc==6 ){
- const char *z = Tcl_GetString(objv[3]);
+ int i;
+ if( objc<4 ){
+ Tcl_WrongNumArgs(interp, 2, objv, "NAME ?SWITCHES? SCRIPT");
+ return TCL_ERROR;
+ }
+ for(i=3; i<(objc-1); i++){
+ const char *z = Tcl_GetString(objv[i]);
int n = strlen30(z);
if( n>2 && strncmp(z, "-argcount",n)==0 ){
- if( Tcl_GetIntFromObj(interp, objv[4], &nArg) ) return TCL_ERROR;
+ if( i==(objc-2) ){
+ Tcl_AppendResult(interp, "option requires an argument: ", z, 0);
+ return TCL_ERROR;
+ }
+ if( Tcl_GetIntFromObj(interp, objv[i+1], &nArg) ) return TCL_ERROR;
if( nArg<0 ){
Tcl_AppendResult(interp, "number of arguments must be non-negative",
(char*)0);
return TCL_ERROR;
}
+ i++;
+ }else
+ if( n>2 && strncmp(z, "-deterministic",n)==0 ){
+ flags |= SQLITE_DETERMINISTIC;
+ }else{
+ Tcl_AppendResult(interp, "bad option \"", z,
+ "\": must be -argcount or -deterministic", 0
+ );
+ return TCL_ERROR;
}
- pScript = objv[5];
- }else if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "NAME [-argcount N] SCRIPT");
- return TCL_ERROR;
- }else{
- pScript = objv[3];
}
+
+ pScript = objv[objc-1];
zName = Tcl_GetStringFromObj(objv[2], 0);
pFunc = findSqlFunc(pDb, zName);
if( pFunc==0 ) return TCL_ERROR;
pFunc->pScript = pScript;
Tcl_IncrRefCount(pScript);
pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript);
- rc = sqlite3_create_function(pDb->db, zName, nArg, SQLITE_UTF8,
+ rc = sqlite3_create_function(pDb->db, zName, nArg, flags,
pFunc, tclSqlFunc, 0, 0);
if( rc!=SQLITE_OK ){
rc = TCL_ERROR;
Tcl_DecrRefCount(pRet);
}
+/*
+** The implementation of scalar SQL function "test_zeroblob()". This is
+** similar to the built-in zeroblob() function, except that it does not
+** check that the integer parameter is within range before passing it
+** to sqlite3_result_zeroblob().
+*/
+static void test_zeroblob(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ int nZero = sqlite3_value_int(argv[0]);
+ sqlite3_result_zeroblob(context, nZero);
+}
static int registerTestFunctions(sqlite3 *db){
static const struct {
char *zName;
signed char nArg;
- unsigned char eTextRep; /* 1: UTF-16. 0: UTF-8 */
+ unsigned int eTextRep; /* 1: UTF-16. 0: UTF-8 */
void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
} aFuncs[] = {
{ "randstr", 2, SQLITE_UTF8, randStr },
{ "real2hex", 1, SQLITE_UTF8, real2hex},
{ "test_decode", 1, SQLITE_UTF8, test_decode},
{ "test_extract", 2, SQLITE_UTF8, test_extract},
+ { "test_zeroblob", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, test_zeroblob},
};
int i;
goto value_from_function_out;
}
+ assert( pCtx->pParse->rc==SQLITE_OK );
memset(&ctx, 0, sizeof(ctx));
ctx.pOut = pVal;
ctx.pFunc = pFunc;
if( ctx.isError ){
rc = ctx.isError;
sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal));
- pCtx->pParse->rc = rc;
}else{
sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8);
assert( rc==SQLITE_OK );
rc = sqlite3VdbeChangeEncoding(pVal, enc);
if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){
rc = SQLITE_TOOBIG;
+ pCtx->pParse->nErr++;
}
}
+ pCtx->pParse->rc = rc;
value_from_function_out:
if( rc!=SQLITE_OK ){
do_eqp_test 1.$tn "SELECT * FROM t1 WHERE $where" $res
}
+# Test that functions that do not exist - "func()" - do not cause an error.
+#
do_catchsql_test 2.1 {
SELECT * FROM t1 WHERE x = substr('145', 2, 1) AND y = func(1, 2, 3)
} {1 {no such function: func}}
} {1 {no such function: func}}
+# Check that functions that accept zero arguments do not cause problems.
+#
+proc ret {x} { return $x }
+
+db func det4 -deterministic [list ret 4]
+db func nondet4 [list ret 4]
+db func det19 -deterministic [list ret 19]
+db func nondet19 [list ret 19]
+
+foreach {tn where idx} {
+ 1 "x = det4() AND y = det19()" {t1x (x=?)}
+ 2 "x = det19() AND y = det4()" {t1y (y=?)}
+
+ 3 "x = nondet4() AND y = nondet19()" {t1y (y=?)}
+ 4 "x = nondet19() AND y = nondet4()" {t1y (y=?)}
+} {
+ set res "0 0 0 {SEARCH TABLE t1 USING INDEX $idx}"
+ do_eqp_test 3.$tn "SELECT * FROM t1 WHERE $where" $res
+}
+
+
+execsql { DELETE FROM t1 }
+
+proc throw_error {err} { error $err }
+db func error -deterministic throw_error
+do_catchsql_test 4.1 {
+ SELECT * FROM t1 WHERE x = error('error one') AND y = 4;
+} {1 {error one}}
+
+do_catchsql_test 4.2 {
+ SELECT * FROM t1 WHERE x = zeroblob(2000000000) AND y = 4;
+} {1 {string or blob too big}}
+
+sqlite3_limit db SQLITE_LIMIT_LENGTH 1000000
+proc dstr {} { return [string repeat x 1100000] }
+db func dstr -deterministic dstr
+do_catchsql_test 4.3 {
+ SELECT * FROM t1 WHERE x = dstr() AND y = 11;
+} {1 {string or blob too big}}
+
+do_catchsql_test 4.4 {
+ SELECT * FROM t1 WHERE x = test_zeroblob(1100000) AND y = 4;
+} {1 {string or blob too big}}
+
+
finish_test
+
+
faultsim_test_result [list 0 {}]
}
+reset_db
+
+proc isqrt {i} { expr { int(sqrt($i)) } }
+db func isqrt isqrt
+
+do_execsql_test 8.0 {
+ PRAGMA encoding = 'utf-16';
+ CREATE TABLE x2(x TEXT, y TEXT);
+ WITH data(i) AS (
+ SELECT 1 UNION ALL SELECT i+1 FROM data
+ )
+ INSERT INTO x2 SELECT isqrt(i), isqrt(i) FROM data LIMIT 400;
+ CREATE INDEX x2x ON x2(x);
+ CREATE INDEX x2y ON x2(y);
+ ANALYZE;
+ DELETE FROM x2;
+}
+
+proc str {a} { return $a }
+db func str -deterministic str
+
+do_faultsim_test 8 -faults oom* -body {
+ execsql { SELECT * FROM x2 WHERE x = str('19') AND y = str('4') }
+} -test {
+ faultsim_test_result [list 0 {}]
+}
+
finish_test
do_test tcl-1.15 {
set v [catch {db function} msg]
lappend v $msg
-} {1 {wrong # args: should be "db function NAME [-argcount N] SCRIPT"}}
+} {1 {wrong # args: should be "db function NAME ?SWITCHES? SCRIPT"}}
do_test tcl-1.16 {
set v [catch {db last_insert_rowid xyz} msg]
lappend v $msg