summaryrefslogtreecommitdiff
path: root/ext/pdo_sqlite/sqlite/src/func.c
diff options
context:
space:
mode:
authorIlia Alshanetsky <iliaa@php.net>2005-08-28 16:57:01 +0000
committerIlia Alshanetsky <iliaa@php.net>2005-08-28 16:57:01 +0000
commitbb3801714270de37f05383214aadfb09006113ea (patch)
tree2549f7b9f0563bb3e88cc95f80ce1692d3e89f69 /ext/pdo_sqlite/sqlite/src/func.c
parent4509fb9d5d9bc423e34f6a944191b6309e9d0b74 (diff)
downloadphp-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.c140
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;
+}