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 |
} |