diff options
author | Ilia Alshanetsky <iliaa@php.net> | 2005-08-28 16:57:01 +0000 |
---|---|---|
committer | Ilia Alshanetsky <iliaa@php.net> | 2005-08-28 16:57:01 +0000 |
commit | bb3801714270de37f05383214aadfb09006113ea (patch) | |
tree | 2549f7b9f0563bb3e88cc95f80ce1692d3e89f69 /ext/pdo_sqlite/sqlite/src/func.c | |
parent | 4509fb9d5d9bc423e34f6a944191b6309e9d0b74 (diff) | |
download | php-git-bb3801714270de37f05383214aadfb09006113ea.tar.gz |
Upgrade sqlite lib to 3.2.5
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/func.c')
-rw-r--r-- | ext/pdo_sqlite/sqlite/src/func.c | 140 |
1 files changed, 101 insertions, 39 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/func.c b/ext/pdo_sqlite/sqlite/src/func.c index 92b8625fc6..326d98eef6 100644 --- a/ext/pdo_sqlite/sqlite/src/func.c +++ b/ext/pdo_sqlite/sqlite/src/func.c @@ -26,6 +26,9 @@ #include "vdbeInt.h" #include "os.h" +/* +** Return the collating function associated with a function. +*/ static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){ return context->pColl; } @@ -78,6 +81,7 @@ static void typeofFunc( sqlite3_result_text(context, z, -1, SQLITE_STATIC); } + /* ** Implementation of the length() function */ @@ -183,7 +187,7 @@ static void substrFunc( static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ int n = 0; double r; - char zBuf[100]; + char zBuf[500]; /* larger than the %f representation of the largest double */ assert( argc==1 || argc==2 ); if( argc==2 ){ if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return; @@ -193,7 +197,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ } if( SQLITE_NULL==sqlite3_value_type(argv[0]) ) return; r = sqlite3_value_double(argv[0]); - sprintf(zBuf,"%.*f",n,r); + sqlite3_snprintf(sizeof(zBuf),zBuf,"%.*f",n,r); sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); } @@ -307,8 +311,14 @@ struct compareInfo { u8 matchSet; u8 noCase; }; + static const struct compareInfo globInfo = { '*', '?', '[', 0 }; -static const struct compareInfo likeInfo = { '%', '_', 0, 1 }; +/* The correct SQL-92 behavior is for the LIKE operator to ignore +** case. Thus 'a' LIKE 'A' would be true. */ +static const struct compareInfo likeInfoNorm = { '%', '_', 0, 1 }; +/* If SQLITE_CASE_SENSITIVE_LIKE is defined, then the LIKE operator +** is case sensitive causing 'a' LIKE 'A' to be false */ +static const struct compareInfo likeInfoAlt = { '%', '_', 0, 0 }; /* ** X is a pointer to the first byte of a UTF-8 character. Increment @@ -450,6 +460,15 @@ static int patternCompare( return *zString==0; } +/* +** Count the number of times that the LIKE operator (or GLOB which is +** just a variation of LIKE) gets called. This is used for testing +** only. +*/ +#ifdef SQLITE_TEST +int sqlite3_like_count = 0; +#endif + /* ** Implementation of the like() SQL function. This function implements @@ -460,8 +479,8 @@ static int patternCompare( ** ** is implemented as like(B,A). ** -** If the pointer retrieved by via a call to sqlite3_user_data() is -** not NULL, then this function uses UTF-16. Otherwise UTF-8. +** This same function (with a different compareInfo structure) computes +** the GLOB operator. */ static void likeFunc( sqlite3_context *context, @@ -484,24 +503,11 @@ static void likeFunc( escape = sqlite3ReadUtf8(zEsc); } if( zA && zB ){ - sqlite3_result_int(context, patternCompare(zA, zB, &likeInfo, escape)); - } -} - -/* -** Implementation of the glob() SQL function. This function implements -** the build-in GLOB operator. The first argument to the function is the -** string and the second argument is the pattern. So, the SQL statements: -** -** A GLOB B -** -** is implemented as glob(B,A). -*/ -static void globFunc(sqlite3_context *context, int arg, sqlite3_value **argv){ - const unsigned char *zA = sqlite3_value_text(argv[0]); - const unsigned char *zB = sqlite3_value_text(argv[1]); - if( zA && zB ){ - sqlite3_result_int(context, patternCompare(zA, zB, &globInfo, 0)); + struct compareInfo *pInfo = sqlite3_user_data(context); +#ifdef SQLITE_TEST + sqlite3_like_count++; +#endif + sqlite3_result_int(context, patternCompare(zA, zB, pInfo, escape)); } } @@ -877,16 +883,6 @@ static void countFinalize(sqlite3_context *context){ } /* -** This function tracks state information for the min() and max() -** aggregate functions. -*/ -typedef struct MinMaxCtx MinMaxCtx; -struct MinMaxCtx { - char *z; /* The best so far */ - char zBuf[28]; /* Space that can be used for storage */ -}; - -/* ** Routines to implement min() and max() aggregate functions. */ static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv){ @@ -962,9 +958,6 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ { "coalesce", 1, 0, SQLITE_UTF8, 0, 0 }, { "ifnull", 2, 0, SQLITE_UTF8, 1, ifnullFunc }, { "random", -1, 0, SQLITE_UTF8, 0, randomFunc }, - { "like", 2, 0, SQLITE_UTF8, 0, likeFunc }, - { "like", 3, 0, SQLITE_UTF8, 0, likeFunc }, - { "glob", 2, 0, SQLITE_UTF8, 0, globFunc }, { "nullif", 2, 0, SQLITE_UTF8, 1, nullifFunc }, { "sqlite_version", 0, 0, SQLITE_UTF8, 0, versionFunc}, { "quote", 1, 0, SQLITE_UTF8, 0, quoteFunc }, @@ -1036,8 +1029,77 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ } sqlite3RegisterDateTimeFunctions(db); #ifdef SQLITE_SSE - { - sqlite3SseFunctions(db); - } + sqlite3SseFunctions(db); +#endif +#ifdef SQLITE_CASE_SENSITIVE_LIKE + sqlite3RegisterLikeFunctions(db, 1); +#else + sqlite3RegisterLikeFunctions(db, 0); #endif } + +/* +** Set the LIKEOPT flag on the 2-argument function with the given name. +*/ +static void setLikeOptFlag(sqlite3 *db, const char *zName){ + FuncDef *pDef; + pDef = sqlite3FindFunction(db, zName, strlen(zName), 2, SQLITE_UTF8, 0); + if( pDef ){ + pDef->flags = SQLITE_FUNC_LIKEOPT; + } +} + +/* +** Register the built-in LIKE and GLOB functions. The caseSensitive +** parameter determines whether or not the LIKE operator is case +** sensitive. GLOB is always case sensitive. +*/ +void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ + struct compareInfo *pInfo; + if( caseSensitive ){ + pInfo = (struct compareInfo*)&likeInfoAlt; + }else{ + pInfo = (struct compareInfo*)&likeInfoNorm; + } + sqlite3_create_function(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0); + sqlite3_create_function(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0); + sqlite3_create_function(db, "glob", 2, SQLITE_UTF8, + (struct compareInfo*)&globInfo, likeFunc, 0,0); + setLikeOptFlag(db, "glob"); + if( caseSensitive ){ + setLikeOptFlag(db, "like"); + } +} + +/* +** pExpr points to an expression which implements a function. If +** it is appropriate to apply the LIKE optimization to that function +** then set aWc[0] through aWc[2] to the wildcard characters and +** return TRUE. If the function is not a LIKE-style function then +** return FALSE. +*/ +int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, char *aWc){ + FuncDef *pDef; + if( pExpr->op!=TK_FUNCTION ){ + return 0; + } + if( pExpr->pList->nExpr!=2 ){ + return 0; + } + pDef = sqlite3FindFunction(db, pExpr->token.z, pExpr->token.n, 2, + SQLITE_UTF8, 0); + if( pDef==0 || (pDef->flags & SQLITE_FUNC_LIKEOPT)==0 ){ + return 0; + } + + /* The memcpy() statement assumes that the wildcard characters are + ** the first three statements in the compareInfo structure. The + ** asserts() that follow verify that assumption + */ + memcpy(aWc, pDef->pUserData, 3); + assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll ); + assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne ); + assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet ); + + return 1; +} |