| Index: third_party/sqlite/src/src/func.c
|
| diff --git a/third_party/sqlite/src/src/func.c b/third_party/sqlite/src/src/func.c
|
| index 2b31af216d0d3a4bd401f6902cafbcead07e87fb..ed6a1e809f11035cf5d6ff3b2d5d0312304228e3 100644
|
| --- a/third_party/sqlite/src/src/func.c
|
| +++ b/third_party/sqlite/src/src/func.c
|
| @@ -117,7 +117,10 @@ static void lengthFunc(
|
| }
|
|
|
| /*
|
| -** Implementation of the abs() function
|
| +** Implementation of the abs() function.
|
| +**
|
| +** IMP: R-23979-26855 The abs(X) function returns the absolute value of
|
| +** the numeric argument X.
|
| */
|
| static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
|
| assert( argc==1 );
|
| @@ -127,6 +130,9 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
|
| i64 iVal = sqlite3_value_int64(argv[0]);
|
| if( iVal<0 ){
|
| if( (iVal<<1)==0 ){
|
| + /* IMP: R-35460-15084 If X is the integer -9223372036854775807 then
|
| + ** abs(X) throws an integer overflow error since there is no
|
| + ** equivalent positive 64-bit two complement value. */
|
| sqlite3_result_error(context, "integer overflow", -1);
|
| return;
|
| }
|
| @@ -136,10 +142,16 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
|
| break;
|
| }
|
| case SQLITE_NULL: {
|
| + /* IMP: R-37434-19929 Abs(X) returns NULL if X is NULL. */
|
| sqlite3_result_null(context);
|
| break;
|
| }
|
| default: {
|
| + /* Because sqlite3_value_double() returns 0.0 if the argument is not
|
| + ** something that can be converted into a number, we have:
|
| + ** IMP: R-57326-31541 Abs(X) return 0.0 if X is a string or blob that
|
| + ** cannot be converted to a numeric value.
|
| + */
|
| double rVal = sqlite3_value_double(argv[0]);
|
| if( rVal<0 ) rVal = -rVal;
|
| sqlite3_result_double(context, rVal);
|
| @@ -157,6 +169,8 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
|
| ** If x is a blob, then we count bytes.
|
| **
|
| ** If p1 is negative, then we begin abs(p1) from the end of x[].
|
| +**
|
| +** If p2 is negative, return the p2 characters preceeding p1.
|
| */
|
| static void substrFunc(
|
| sqlite3_context *context,
|
| @@ -177,6 +191,7 @@ static void substrFunc(
|
| return;
|
| }
|
| p0type = sqlite3_value_type(argv[0]);
|
| + p1 = sqlite3_value_int(argv[1]);
|
| if( p0type==SQLITE_BLOB ){
|
| len = sqlite3_value_bytes(argv[0]);
|
| z = sqlite3_value_blob(argv[0]);
|
| @@ -186,11 +201,12 @@ static void substrFunc(
|
| z = sqlite3_value_text(argv[0]);
|
| if( z==0 ) return;
|
| len = 0;
|
| - for(z2=z; *z2; len++){
|
| - SQLITE_SKIP_UTF8(z2);
|
| + if( p1<0 ){
|
| + for(z2=z; *z2; len++){
|
| + SQLITE_SKIP_UTF8(z2);
|
| + }
|
| }
|
| }
|
| - p1 = sqlite3_value_int(argv[1]);
|
| if( argc==3 ){
|
| p2 = sqlite3_value_int(argv[2]);
|
| if( p2<0 ){
|
| @@ -220,10 +236,6 @@ static void substrFunc(
|
| }
|
| }
|
| assert( p1>=0 && p2>=0 );
|
| - if( p1+p2>len ){
|
| - p2 = len-p1;
|
| - if( p2<0 ) p2 = 0;
|
| - }
|
| if( p0type!=SQLITE_BLOB ){
|
| while( *z && p1 ){
|
| SQLITE_SKIP_UTF8(z);
|
| @@ -234,6 +246,10 @@ static void substrFunc(
|
| }
|
| sqlite3_result_text(context, (char*)z, (int)(z2-z), SQLITE_TRANSIENT);
|
| }else{
|
| + if( p1+p2>len ){
|
| + p2 = len-p1;
|
| + if( p2<0 ) p2 = 0;
|
| + }
|
| sqlite3_result_blob(context, (char*)&z[p1], (int)p2, SQLITE_TRANSIENT);
|
| }
|
| }
|
| @@ -255,14 +271,24 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
|
| }
|
| if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
|
| r = sqlite3_value_double(argv[0]);
|
| - zBuf = sqlite3_mprintf("%.*f",n,r);
|
| - if( zBuf==0 ){
|
| - sqlite3_result_error_nomem(context);
|
| + /* If Y==0 and X will fit in a 64-bit int,
|
| + ** handle the rounding directly,
|
| + ** otherwise use printf.
|
| + */
|
| + if( n==0 && r>=0 && r<LARGEST_INT64-1 ){
|
| + r = (double)((sqlite_int64)(r+0.5));
|
| + }else if( n==0 && r<0 && (-r)<LARGEST_INT64-1 ){
|
| + r = -(double)((sqlite_int64)((-r)+0.5));
|
| }else{
|
| - sqlite3AtoF(zBuf, &r);
|
| + zBuf = sqlite3_mprintf("%.*f",n,r);
|
| + if( zBuf==0 ){
|
| + sqlite3_result_error_nomem(context);
|
| + return;
|
| + }
|
| + sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8);
|
| sqlite3_free(zBuf);
|
| - sqlite3_result_double(context, r);
|
| }
|
| + sqlite3_result_double(context, r);
|
| }
|
| #endif
|
|
|
| @@ -335,6 +361,14 @@ static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
|
| }
|
| }
|
|
|
| +
|
| +#if 0 /* This function is never used. */
|
| +/*
|
| +** The COALESCE() and IFNULL() functions used to be implemented as shown
|
| +** here. But now they are implemented as VDBE code so that unused arguments
|
| +** do not have to be computed. This legacy implementation is retained as
|
| +** comment.
|
| +*/
|
| /*
|
| ** Implementation of the IFNULL(), NVL(), and COALESCE() functions.
|
| ** All three do the same thing. They return the first non-NULL
|
| @@ -353,6 +387,8 @@ static void ifnullFunc(
|
| }
|
| }
|
| }
|
| +#endif /* NOT USED */
|
| +#define ifnullFunc versionFunc /* Substitute function - never called */
|
|
|
| /*
|
| ** Implementation of random(). Return a random integer.
|
| @@ -414,12 +450,18 @@ static void last_insert_rowid(
|
| ){
|
| sqlite3 *db = sqlite3_context_db_handle(context);
|
| UNUSED_PARAMETER2(NotUsed, NotUsed2);
|
| + /* IMP: R-51513-12026 The last_insert_rowid() SQL function is a
|
| + ** wrapper around the sqlite3_last_insert_rowid() C/C++ interface
|
| + ** function. */
|
| sqlite3_result_int64(context, sqlite3_last_insert_rowid(db));
|
| }
|
|
|
| /*
|
| -** Implementation of the changes() SQL function. The return value is the
|
| -** same as the sqlite3_changes() API function.
|
| +** Implementation of the changes() SQL function.
|
| +**
|
| +** IMP: R-62073-11209 The changes() SQL function is a wrapper
|
| +** around the sqlite3_changes() C/C++ function and hence follows the same
|
| +** rules for counting changes.
|
| */
|
| static void changes(
|
| sqlite3_context *context,
|
| @@ -442,6 +484,8 @@ static void total_changes(
|
| ){
|
| sqlite3 *db = sqlite3_context_db_handle(context);
|
| UNUSED_PARAMETER2(NotUsed, NotUsed2);
|
| + /* IMP: R-52756-41993 This function is a wrapper around the
|
| + ** sqlite3_total_changes() C/C++ interface. */
|
| sqlite3_result_int(context, sqlite3_total_changes(db));
|
| }
|
|
|
| @@ -709,7 +753,9 @@ static void versionFunc(
|
| sqlite3_value **NotUsed2
|
| ){
|
| UNUSED_PARAMETER2(NotUsed, NotUsed2);
|
| - sqlite3_result_text(context, sqlite3_version, -1, SQLITE_STATIC);
|
| + /* IMP: R-48699-48617 This function is an SQL wrapper around the
|
| + ** sqlite3_libversion() C-interface. */
|
| + sqlite3_result_text(context, sqlite3_libversion(), -1, SQLITE_STATIC);
|
| }
|
|
|
| /*
|
| @@ -723,9 +769,57 @@ static void sourceidFunc(
|
| sqlite3_value **NotUsed2
|
| ){
|
| UNUSED_PARAMETER2(NotUsed, NotUsed2);
|
| - sqlite3_result_text(context, SQLITE_SOURCE_ID, -1, SQLITE_STATIC);
|
| + /* IMP: R-24470-31136 This function is an SQL wrapper around the
|
| + ** sqlite3_sourceid() C interface. */
|
| + sqlite3_result_text(context, sqlite3_sourceid(), -1, SQLITE_STATIC);
|
| }
|
|
|
| +/*
|
| +** Implementation of the sqlite_compileoption_used() function.
|
| +** The result is an integer that identifies if the compiler option
|
| +** was used to build SQLite.
|
| +*/
|
| +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
|
| +static void compileoptionusedFunc(
|
| + sqlite3_context *context,
|
| + int argc,
|
| + sqlite3_value **argv
|
| +){
|
| + const char *zOptName;
|
| + assert( argc==1 );
|
| + UNUSED_PARAMETER(argc);
|
| + /* IMP: R-39564-36305 The sqlite_compileoption_used() SQL
|
| + ** function is a wrapper around the sqlite3_compileoption_used() C/C++
|
| + ** function.
|
| + */
|
| + if( (zOptName = (const char*)sqlite3_value_text(argv[0]))!=0 ){
|
| + sqlite3_result_int(context, sqlite3_compileoption_used(zOptName));
|
| + }
|
| +}
|
| +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
|
| +
|
| +/*
|
| +** Implementation of the sqlite_compileoption_get() function.
|
| +** The result is a string that identifies the compiler options
|
| +** used to build SQLite.
|
| +*/
|
| +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
|
| +static void compileoptiongetFunc(
|
| + sqlite3_context *context,
|
| + int argc,
|
| + sqlite3_value **argv
|
| +){
|
| + int n;
|
| + assert( argc==1 );
|
| + UNUSED_PARAMETER(argc);
|
| + /* IMP: R-04922-24076 The sqlite_compileoption_get() SQL function
|
| + ** is a wrapper around the sqlite3_compileoption_get() C/C++ function.
|
| + */
|
| + n = sqlite3_value_int(argv[0]);
|
| + sqlite3_result_text(context, sqlite3_compileoption_get(n), -1, SQLITE_STATIC);
|
| +}
|
| +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
|
| +
|
| /* Array for converting from half-bytes (nybbles) into ASCII hex
|
| ** digits. */
|
| static const char hexdigits[] = {
|
| @@ -852,7 +946,7 @@ static void zeroblobFunc(
|
| if( n>db->aLimit[SQLITE_LIMIT_LENGTH] ){
|
| sqlite3_result_error_toobig(context);
|
| }else{
|
| - sqlite3_result_zeroblob(context, (int)n);
|
| + sqlite3_result_zeroblob(context, (int)n); /* IMP: R-00293-64994 */
|
| }
|
| }
|
|
|
| @@ -919,14 +1013,14 @@ static void replaceFunc(
|
| testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] );
|
| if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
|
| sqlite3_result_error_toobig(context);
|
| - sqlite3DbFree(db, zOut);
|
| + sqlite3_free(zOut);
|
| return;
|
| }
|
| zOld = zOut;
|
| zOut = sqlite3_realloc(zOut, (int)nOut);
|
| if( zOut==0 ){
|
| sqlite3_result_error_nomem(context);
|
| - sqlite3DbFree(db, zOld);
|
| + sqlite3_free(zOld);
|
| return;
|
| }
|
| memcpy(&zOut[j], zRep, nRep);
|
| @@ -1027,9 +1121,16 @@ static void trimFunc(
|
| }
|
|
|
|
|
| +/* IMP: R-25361-16150 This function is omitted from SQLite by default. It
|
| +** is only available if the SQLITE_SOUNDEX compile-time option is used
|
| +** when SQLite is built.
|
| +*/
|
| #ifdef SQLITE_SOUNDEX
|
| /*
|
| ** Compute the soundex encoding of a word.
|
| +**
|
| +** IMP: R-59782-00072 The soundex(X) function returns a string that is the
|
| +** soundex encoding of the string X.
|
| */
|
| static void soundexFunc(
|
| sqlite3_context *context,
|
| @@ -1073,10 +1174,12 @@ static void soundexFunc(
|
| zResult[j] = 0;
|
| sqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT);
|
| }else{
|
| + /* IMP: R-64894-50321 The string "?000" is returned if the argument
|
| + ** is NULL or contains no ASCII alphabetic characters. */
|
| sqlite3_result_text(context, "?000", 4, SQLITE_STATIC);
|
| }
|
| }
|
| -#endif
|
| +#endif /* SQLITE_SOUNDEX */
|
|
|
| #ifndef SQLITE_OMIT_LOAD_EXTENSION
|
| /*
|
| @@ -1136,13 +1239,8 @@ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
|
| if( type==SQLITE_INTEGER ){
|
| i64 v = sqlite3_value_int64(argv[0]);
|
| p->rSum += v;
|
| - if( (p->approx|p->overflow)==0 ){
|
| - i64 iNewSum = p->iSum + v;
|
| - int s1 = (int)(p->iSum >> (sizeof(i64)*8-1));
|
| - int s2 = (int)(v >> (sizeof(i64)*8-1));
|
| - int s3 = (int)(iNewSum >> (sizeof(i64)*8-1));
|
| - p->overflow = ((s1&s2&~s3) | (~s1&~s2&s3))?1:0;
|
| - p->iSum = iNewSum;
|
| + if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){
|
| + p->overflow = 1;
|
| }
|
| }else{
|
| p->rSum += sqlite3_value_double(argv[0]);
|
| @@ -1278,7 +1376,7 @@ static void groupConcatStep(
|
| if( pAccum ){
|
| sqlite3 *db = sqlite3_context_db_handle(context);
|
| int firstTerm = pAccum->useMalloc==0;
|
| - pAccum->useMalloc = 1;
|
| + pAccum->useMalloc = 2;
|
| pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
|
| if( !firstTerm ){
|
| if( argc==2 ){
|
| @@ -1311,20 +1409,15 @@ static void groupConcatFinalize(sqlite3_context *context){
|
| }
|
|
|
| /*
|
| -** This function registered all of the above C functions as SQL
|
| -** functions. This should be the only routine in this file with
|
| -** external linkage.
|
| +** This routine does per-connection function registration. Most
|
| +** of the built-in functions above are part of the global function set.
|
| +** This routine only deals with those that are not global.
|
| */
|
| void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
|
| -#ifndef SQLITE_OMIT_ALTERTABLE
|
| - sqlite3AlterFunctions(db);
|
| -#endif
|
| - if( !db->mallocFailed ){
|
| - int rc = sqlite3_overload_function(db, "MATCH", 2);
|
| - assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
|
| - if( rc==SQLITE_NOMEM ){
|
| - db->mallocFailed = 1;
|
| - }
|
| + int rc = sqlite3_overload_function(db, "MATCH", 2);
|
| + assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
|
| + if( rc==SQLITE_NOMEM ){
|
| + db->mallocFailed = 1;
|
| }
|
| }
|
|
|
| @@ -1352,10 +1445,10 @@ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
|
| }else{
|
| pInfo = (struct compareInfo*)&likeInfoNorm;
|
| }
|
| - sqlite3CreateFunc(db, "like", 2, SQLITE_ANY, pInfo, likeFunc, 0, 0);
|
| - sqlite3CreateFunc(db, "like", 3, SQLITE_ANY, pInfo, likeFunc, 0, 0);
|
| - sqlite3CreateFunc(db, "glob", 2, SQLITE_ANY,
|
| - (struct compareInfo*)&globInfo, likeFunc, 0,0);
|
| + sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
|
| + sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
|
| + sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8,
|
| + (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0);
|
| setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
|
| setLikeOptFlag(db, "like",
|
| caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
|
| @@ -1437,15 +1530,21 @@ void sqlite3RegisterGlobalFunctions(void){
|
| FUNCTION(upper, 1, 0, 0, upperFunc ),
|
| FUNCTION(lower, 1, 0, 0, lowerFunc ),
|
| FUNCTION(coalesce, 1, 0, 0, 0 ),
|
| - FUNCTION(coalesce, -1, 0, 0, ifnullFunc ),
|
| FUNCTION(coalesce, 0, 0, 0, 0 ),
|
| +/* FUNCTION(coalesce, -1, 0, 0, ifnullFunc ), */
|
| + {-1,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"coalesce",0,0},
|
| FUNCTION(hex, 1, 0, 0, hexFunc ),
|
| - FUNCTION(ifnull, 2, 0, 1, ifnullFunc ),
|
| +/* FUNCTION(ifnull, 2, 0, 0, ifnullFunc ), */
|
| + {2,SQLITE_UTF8,SQLITE_FUNC_COALESCE,0,0,ifnullFunc,0,0,"ifnull",0,0},
|
| FUNCTION(random, 0, 0, 0, randomFunc ),
|
| FUNCTION(randomblob, 1, 0, 0, randomBlob ),
|
| FUNCTION(nullif, 2, 0, 1, nullifFunc ),
|
| FUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
|
| FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
|
| +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
|
| + FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
|
| + FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
|
| +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
|
| FUNCTION(quote, 1, 0, 0, quoteFunc ),
|
| FUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
|
| FUNCTION(changes, 0, 0, 0, changes ),
|
| @@ -1463,7 +1562,7 @@ void sqlite3RegisterGlobalFunctions(void){
|
| AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ),
|
| AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ),
|
| /* AGGREGATE(count, 0, 0, 0, countStep, countFinalize ), */
|
| - {0,SQLITE_UTF8,SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0},
|
| + {0,SQLITE_UTF8,SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0,0},
|
| AGGREGATE(count, 1, 0, 0, countStep, countFinalize ),
|
| AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize),
|
| AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize),
|
| @@ -1486,4 +1585,7 @@ void sqlite3RegisterGlobalFunctions(void){
|
| sqlite3FuncDefInsert(pHash, &aFunc[i]);
|
| }
|
| sqlite3RegisterDateTimeFunctions();
|
| +#ifndef SQLITE_OMIT_ALTERTABLE
|
| + sqlite3AlterFunctions();
|
| +#endif
|
| }
|
|
|