Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Allow the SQLITE_DETERMINISTIC flag to be ORed into the preferred text encoding of application-defined functions, to mark the function as deterministic. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
5716fc2341ddd8cf64139e7168597f86 |
User & Date: | drh 2013-12-14 13:44:22.886 |
Context
2013-12-17
| ||
16:10 | Add the printf() SQL function. (check-in: a1bb62f91a user: drh tags: trunk) | |
15:03 | Add the printf() SQL function. (check-in: 6db7052eee user: drh tags: printf-sql-function) | |
2013-12-14
| ||
18:24 | Merge in all recent preformance enhancements from trunk. (check-in: 32477642d7 user: drh tags: sessions) | |
13:44 | Allow the SQLITE_DETERMINISTIC flag to be ORed into the preferred text encoding of application-defined functions, to mark the function as deterministic. (check-in: 5716fc2341 user: drh tags: trunk) | |
2013-12-13
| ||
20:45 | Performance optimizations in the pager_write() routine of pager.c. (check-in: bc5febef92 user: drh tags: trunk) | |
Changes
Changes to src/callback.c.
︙ | ︙ | |||
353 354 355 356 357 358 359 | FuncDef *p; /* Iterator variable */ FuncDef *pBest = 0; /* Best match found so far */ int bestScore = 0; /* Score of best match */ int h; /* Hash value */ assert( nArg>=(-2) ); assert( nArg>=(-1) || createFlag==0 ); | < | 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | FuncDef *p; /* Iterator variable */ FuncDef *pBest = 0; /* Best match found so far */ int bestScore = 0; /* Score of best match */ int h; /* Hash value */ assert( nArg>=(-2) ); assert( nArg>=(-1) || createFlag==0 ); h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a); /* First search for a match amongst the application-defined functions. */ p = functionSearch(&db->aFunc, h, zName, nName); while( p ){ int score = matchQuality(p, nArg, enc); |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 | void (*xFunc)(sqlite3_context*,int,sqlite3_value **), void (*xStep)(sqlite3_context*,int,sqlite3_value **), void (*xFinal)(sqlite3_context*), FuncDestructor *pDestructor ){ FuncDef *p; int nName; assert( sqlite3_mutex_held(db->mutex) ); if( zFunctionName==0 || (xFunc && (xFinal || xStep)) || (!xFunc && (xFinal && !xStep)) || (!xFunc && (!xFinal && xStep)) || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) || (255<(nName = sqlite3Strlen30( zFunctionName))) ){ return SQLITE_MISUSE_BKPT; } #ifndef SQLITE_OMIT_UTF16 /* If SQLITE_UTF16 is specified as the encoding type, transform this ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. ** ** If SQLITE_ANY is specified, add three versions of the function ** to the hash table. */ if( enc==SQLITE_UTF16 ){ enc = SQLITE_UTF16NATIVE; }else if( enc==SQLITE_ANY ){ int rc; | > > > > > | | | 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 | void (*xFunc)(sqlite3_context*,int,sqlite3_value **), void (*xStep)(sqlite3_context*,int,sqlite3_value **), void (*xFinal)(sqlite3_context*), FuncDestructor *pDestructor ){ FuncDef *p; int nName; int extraFlags; assert( sqlite3_mutex_held(db->mutex) ); if( zFunctionName==0 || (xFunc && (xFinal || xStep)) || (!xFunc && (xFinal && !xStep)) || (!xFunc && (!xFinal && xStep)) || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) || (255<(nName = sqlite3Strlen30( zFunctionName))) ){ return SQLITE_MISUSE_BKPT; } assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); extraFlags = enc & SQLITE_DETERMINISTIC; enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); #ifndef SQLITE_OMIT_UTF16 /* If SQLITE_UTF16 is specified as the encoding type, transform this ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. ** ** If SQLITE_ANY is specified, add three versions of the function ** to the hash table. */ if( enc==SQLITE_UTF16 ){ enc = SQLITE_UTF16NATIVE; }else if( enc==SQLITE_ANY ){ int rc; rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags, pUserData, xFunc, xStep, xFinal, pDestructor); if( rc==SQLITE_OK ){ rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags, pUserData, xFunc, xStep, xFinal, pDestructor); } if( rc!=SQLITE_OK ){ return rc; } enc = SQLITE_UTF16BE; } |
︙ | ︙ | |||
1435 1436 1437 1438 1439 1440 1441 | ** being replaced invoke the destructor function here. */ functionDestroy(db, p); if( pDestructor ){ pDestructor->nRef++; } p->pDestructor = pDestructor; | | > | 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 | ** being replaced invoke the destructor function here. */ functionDestroy(db, p); if( pDestructor ){ pDestructor->nRef++; } p->pDestructor = pDestructor; p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags; testcase( p->funcFlags & SQLITE_DETERMINISTIC ); p->xFunc = xFunc; p->xStep = xStep; p->xFinalize = xFinal; p->pUserData = pUserData; p->nArg = (u16)nArg; return SQLITE_OK; } |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
3973 3974 3975 3976 3977 3978 3979 | ** aggregate may take any number of arguments between 0 and the limit ** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third ** parameter is less than -1 or greater than 127 then the behavior is ** undefined. ** ** ^The fourth parameter, eTextRep, specifies what ** [SQLITE_UTF8 | text encoding] this SQL function prefers for | > | > | < | > | > < > | > > > > > > | 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 | ** aggregate may take any number of arguments between 0 and the limit ** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third ** parameter is less than -1 or greater than 127 then the behavior is ** undefined. ** ** ^The fourth parameter, eTextRep, specifies what ** [SQLITE_UTF8 | text encoding] this SQL function prefers for ** its parameters. The application should set this parameter to ** [SQLITE_UTF16LE] if the function implementation invokes ** [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the ** implementation invokes [sqlite3_value_text16be()] on an input, or ** [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8] ** otherwise. ^The same SQL function may be registered multiple times using ** different preferred text encodings, with different implementations for ** each encoding. ** ^When multiple implementations of the same function are available, SQLite ** will pick the one that involves the least amount of data conversion. ** ** ^The fourth parameter may optionally be ORed with [SQLITE_DETERMINISTIC] ** to signal that the function will always return the same result given ** the same inputs within a single SQL statement. Most SQL functions are ** deterministic. The built-in [random()] SQL function is an example of a ** function that is not deterministic. The SQLite query planner is able to ** perform additional optimizations on deterministic functions, so use ** of the [SQLITE_DETERMINISTIC] flag is recommended where possible. ** ** ^(The fifth parameter is an arbitrary pointer. The implementation of the ** function can gain access to this pointer using [sqlite3_user_data()].)^ ** ** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are ** pointers to C-language functions that implement the SQL function or ** aggregate. ^A scalar SQL function requires an implementation of the xFunc |
︙ | ︙ | |||
4067 4068 4069 4070 4071 4072 4073 | ** These constant define integer codes that represent the various ** text encodings supported by SQLite. */ #define SQLITE_UTF8 1 #define SQLITE_UTF16LE 2 #define SQLITE_UTF16BE 3 #define SQLITE_UTF16 4 /* Use native byte order */ | | > > > > > > > > > > | 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 | ** These constant define integer codes that represent the various ** text encodings supported by SQLite. */ #define SQLITE_UTF8 1 #define SQLITE_UTF16LE 2 #define SQLITE_UTF16BE 3 #define SQLITE_UTF16 4 /* Use native byte order */ #define SQLITE_ANY 5 /* Deprecated */ #define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ /* ** CAPI3REF: Function Flags ** ** These constants may be ORed together with the ** [SQLITE_UTF8 | preferred text encoding] as the fourth argument ** to [sqlite3_create_function()], [sqlite3_create_function16()], or ** [sqlite3_create_function_v2()]. */ #define SQLITE_DETERMINISTIC 0x800 /* ** CAPI3REF: Deprecated Functions ** DEPRECATED ** ** These functions are [deprecated]. In order to maintain ** backwards compatibility with older code, these functions continue ** to be supported. However, new applications should avoid |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
938 939 940 941 942 943 944 | p2 = (const void*)sqlite3_value_blob(argv[0]); }else{ return; } sqlite3_result_int(context, p1!=p2); } | > > > > > > > > > > > | > | | 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 | p2 = (const void*)sqlite3_value_blob(argv[0]); }else{ return; } sqlite3_result_int(context, p1!=p2); } /* ** This SQL function returns a different answer each time it is called, even if ** the arguments are the same. */ static void nondeterministicFunction( sqlite3_context *context, int argc, sqlite3_value **argv ){ static int cnt = 0; sqlite3_result_int(context, cnt++); } /* ** Usage: sqlite3_create_function DB ** ** Call the sqlite3_create_function API on the given database in order ** to create a function named "x_coalesce". This function does the same thing ** as the "coalesce" function. This function also registers an SQL function ** named "x_sqlite_exec" that invokes sqlite3_exec(). Invoking sqlite3_exec() ** in this way is illegal recursion and should raise an SQLITE_MISUSE error. ** The effect is similar to trying to use the same database connection from |
︙ | ︙ | |||
969 970 971 972 973 974 975 | if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0); return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; | | | | | | > > > > > > > > > > > > > | 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 | if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0); return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_UTF8, 0, t1_ifnullFunc, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "hex8", 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0, hex8Func, 0, 0); } #ifndef SQLITE_OMIT_UTF16 if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "hex16", 1, SQLITE_UTF16 | SQLITE_DETERMINISTIC, 0, hex16Func, 0, 0); } #endif if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "tkt2213func", 1, SQLITE_ANY, 0, tkt2213Function, 0, 0); } if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "pointer_change", 4, SQLITE_ANY, 0, ptrChngFunction, 0, 0); } /* Functions counter1() and counter2() have the same implementation - they ** both return an ascending integer with each call. But counter1() is marked ** as non-deterministic and counter2() is marked as deterministic. */ if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "counter1", -1, SQLITE_UTF8, 0, nondeterministicFunction, 0, 0); } if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "counter2", -1, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, nondeterministicFunction, 0, 0); } #ifndef SQLITE_OMIT_UTF16 /* Use the sqlite3_create_function16() API here. Mainly for fun, but also ** because it is not tested anywhere else. */ if( rc==SQLITE_OK ){ const void *zUtf16; sqlite3_value *pVal; |
︙ | ︙ |
Changes to test/func5.test.
1 2 3 4 5 6 7 8 9 10 11 | # 2013-11-21 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #************************************************************************* # | < | < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | # 2013-11-21 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #************************************************************************* # # Testing of function factoring and the SQLITE_DETERMINISTIC flag. # set testdir [file dirname $argv0] source $testdir/tester.tcl # Verify that constant string expressions that get factored into initializing # code are not reused between function parameters and other values in the # VDBE program, as the function might have changed the encoding. # do_execsql_test func5-1.1 { PRAGMA encoding=UTF16le; CREATE TABLE t1(x,a,b,c); INSERT INTO t1 VALUES(1,'ab','cd',1); INSERT INTO t1 VALUES(2,'gh','ef',5); INSERT INTO t1 VALUES(3,'pqr','fuzzy',99); INSERT INTO t1 VALUES(4,'abcdefg','xy',22); INSERT INTO t1 VALUES(5,'shoe','mayer',2953); SELECT x FROM t1 WHERE c=instr('abcdefg',b) OR a='abcdefg' ORDER BY +x; } {2 4} do_execsql_test func5-1.2 { SELECT x FROM t1 WHERE a='abcdefg' OR c=instr('abcdefg',b) ORDER BY +x; } {2 4} # Verify that SQLITE_DETERMINISTIC functions get factored out of the # evaluation loop whereas non-deterministic functions do not. counter1() # is marked as non-deterministic and so is not factored out of the loop, # and it really is non-deterministic, returning a different result each # time. But counter2() is marked as deterministic, so it does get factored # out of the loop. counter2() has the same implementation as counter1(), # returning a different result on each invocation, but because it is # only invoked once outside of the loop, it appears to return the same # result multiple times. # do_execsql_test func5-2.1 { CREATE TABLE t2(x,y); INSERT INTO t2 VALUES(1,2),(3,4),(5,6),(7,8); SELECT x, y FROM t2 WHERE x+5=5+x ORDER BY +x; } {1 2 3 4 5 6 7 8} sqlite3_create_function db do_execsql_test func5-2.2 { SELECT x, y FROM t2 WHERE x+counter1('hello')=counter1('hello')+x ORDER BY +x; } {} do_execsql_test func5-2.3 { SELECT x, y FROM t2 WHERE x+counter2('hello')=counter2('hello')+x ORDER BY +x; } {1 2 3 4 5 6 7 8} finish_test |