summaryrefslogtreecommitdiff
path: root/ext/pdo_sqlite/sqlite/src/func.c
diff options
context:
space:
mode:
authorIlia Alshanetsky <iliaa@php.net>2007-04-09 16:35:11 +0000
committerIlia Alshanetsky <iliaa@php.net>2007-04-09 16:35:11 +0000
commiteb8d30f9122748c70fab74445205011a58c5988e (patch)
tree1e6df4121f0eaad252f608a1f95076c345f59d5b /ext/pdo_sqlite/sqlite/src/func.c
parent857f992cd3c64d6338e221a6decfd4a94e6a1b08 (diff)
downloadphp-git-eb8d30f9122748c70fab74445205011a58c5988e.tar.gz
Upgrade libsqlite 3 inside PDO sqlite to version 3.3.15
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/func.c')
-rw-r--r--ext/pdo_sqlite/sqlite/src/func.c163
1 files changed, 138 insertions, 25 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/func.c b/ext/pdo_sqlite/sqlite/src/func.c
index 455bd2beb0..567a4fbff8 100644
--- a/ext/pdo_sqlite/sqlite/src/func.c
+++ b/ext/pdo_sqlite/sqlite/src/func.c
@@ -668,6 +668,114 @@ static void hexFunc(
sqlite3_result_text(context, zHex, n*2, sqlite3_free);
}
+/*
+** The replace() function. Three arguments are all strings: call
+** them A, B, and C. The result is also a string which is derived
+** from A by replacing every occurance of B with C. The match
+** must be exact. Collating sequences are not used.
+*/
+static void replaceFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const unsigned char *zStr; /* The input string A */
+ const unsigned char *zPattern; /* The pattern string B */
+ const unsigned char *zRep; /* The replacement string C */
+ unsigned char *zOut; /* The output */
+ int nStr; /* Size of zStr */
+ int nPattern; /* Size of zPattern */
+ int nRep; /* Size of zRep */
+ int nOut; /* Maximum size of zOut */
+ int loopLimit; /* Last zStr[] that might match zPattern[] */
+ int i, j; /* Loop counters */
+
+ assert( argc==3 );
+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ||
+ sqlite3_value_type(argv[1])==SQLITE_NULL ||
+ sqlite3_value_type(argv[2])==SQLITE_NULL ){
+ return;
+ }
+ zStr = sqlite3_value_text(argv[0]);
+ nStr = sqlite3_value_bytes(argv[0]);
+ zPattern = sqlite3_value_text(argv[1]);
+ nPattern = sqlite3_value_bytes(argv[1]);
+ zRep = sqlite3_value_text(argv[2]);
+ nRep = sqlite3_value_bytes(argv[2]);
+ if( nPattern>=nRep ){
+ nOut = nStr;
+ }else{
+ nOut = (nStr/nPattern + 1)*nRep;
+ }
+ zOut = sqlite3_malloc(nOut+1);
+ if( zOut==0 ) return;
+ loopLimit = nStr - nPattern;
+ for(i=j=0; i<=loopLimit; i++){
+ if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
+ zOut[j++] = zStr[i];
+ }else{
+ memcpy(&zOut[j], zRep, nRep);
+ j += nRep;
+ i += nPattern-1;
+ }
+ }
+ memcpy(&zOut[j], &zStr[i], nStr-i);
+ j += nStr - i;
+ assert( j<=nOut );
+ zOut[j] = 0;
+ sqlite3_result_text(context, (char*)zOut, j, sqlite3_free);
+}
+
+/*
+** Implementation of the TRIM(), LTRIM(), and RTRIM() functions.
+** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both.
+*/
+static void trimFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const unsigned char *zIn; /* Input string */
+ const unsigned char *zCharSet; /* Set of characters to trim */
+ int nIn; /* Number of bytes in input */
+ int flags;
+ int i;
+ unsigned char cFirst, cNext;
+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
+ return;
+ }
+ zIn = sqlite3_value_text(argv[0]);
+ nIn = sqlite3_value_bytes(argv[0]);
+ if( argc==1 ){
+ static const unsigned char zSpace[] = " ";
+ zCharSet = zSpace;
+ }else if( sqlite3_value_type(argv[1])==SQLITE_NULL ){
+ return;
+ }else{
+ zCharSet = sqlite3_value_text(argv[1]);
+ }
+ cFirst = zCharSet[0];
+ if( cFirst ){
+ flags = (int)sqlite3_user_data(context);
+ if( flags & 1 ){
+ for(; nIn>0; nIn--, zIn++){
+ if( cFirst==zIn[0] ) continue;
+ for(i=1; zCharSet[i] && zCharSet[i]!=zIn[0]; i++){}
+ if( zCharSet[i]==0 ) break;
+ }
+ }
+ if( flags & 2 ){
+ for(; nIn>0; nIn--){
+ cNext = zIn[nIn-1];
+ if( cFirst==cNext ) continue;
+ for(i=1; zCharSet[i] && zCharSet[i]!=cNext; i++){}
+ if( zCharSet[i]==0 ) break;
+ }
+ }
+ }
+ sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT);
+}
+
#ifdef SQLITE_SOUNDEX
/*
** Compute the soundex encoding of a word.
@@ -1019,7 +1127,7 @@ static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv)
** Therefore the next statement sets variable 'max' to 1 for the max()
** aggregate, or 0 for min().
*/
- max = ((sqlite3_user_data(context)==(void *)-1)?1:0);
+ max = sqlite3_user_data(context)!=0;
cmp = sqlite3MemCompare(pBest, pArg, pColl);
if( (max && cmp<0) || (!max && cmp>0) ){
sqlite3VdbeMemCopy(pBest, pArg);
@@ -1049,15 +1157,15 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
static const struct {
char *zName;
signed char nArg;
- u8 argType; /* 0: none. 1: db 2: (-1) */
+ u8 argType; /* ff: db 1: 0, 2: 1, 3: 2,... N: N-1. */
u8 eTextRep; /* 1: UTF-16. 0: UTF-8 */
u8 needCollSeq;
void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
} aFuncs[] = {
{ "min", -1, 0, SQLITE_UTF8, 1, minmaxFunc },
{ "min", 0, 0, SQLITE_UTF8, 1, 0 },
- { "max", -1, 2, SQLITE_UTF8, 1, minmaxFunc },
- { "max", 0, 2, SQLITE_UTF8, 1, 0 },
+ { "max", -1, 1, SQLITE_UTF8, 1, minmaxFunc },
+ { "max", 0, 1, SQLITE_UTF8, 1, 0 },
{ "typeof", 1, 0, SQLITE_UTF8, 0, typeofFunc },
{ "length", 1, 0, SQLITE_UTF8, 0, lengthFunc },
{ "substr", 3, 0, SQLITE_UTF8, 0, substrFunc },
@@ -1079,22 +1187,29 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
{ "nullif", 2, 0, SQLITE_UTF8, 1, nullifFunc },
{ "sqlite_version", 0, 0, SQLITE_UTF8, 0, versionFunc},
{ "quote", 1, 0, SQLITE_UTF8, 0, quoteFunc },
- { "last_insert_rowid", 0, 1, SQLITE_UTF8, 0, last_insert_rowid },
- { "changes", 0, 1, SQLITE_UTF8, 0, changes },
- { "total_changes", 0, 1, SQLITE_UTF8, 0, total_changes },
+ { "last_insert_rowid", 0, 0xff, SQLITE_UTF8, 0, last_insert_rowid },
+ { "changes", 0, 0xff, SQLITE_UTF8, 0, changes },
+ { "total_changes", 0, 0xff, SQLITE_UTF8, 0, total_changes },
+ { "replace", 3, 0, SQLITE_UTF8, 0, replaceFunc },
+ { "ltrim", 1, 1, SQLITE_UTF8, 0, trimFunc },
+ { "ltrim", 2, 1, SQLITE_UTF8, 0, trimFunc },
+ { "rtrim", 1, 2, SQLITE_UTF8, 0, trimFunc },
+ { "rtrim", 2, 2, SQLITE_UTF8, 0, trimFunc },
+ { "trim", 1, 3, SQLITE_UTF8, 0, trimFunc },
+ { "trim", 2, 3, SQLITE_UTF8, 0, trimFunc },
#ifdef SQLITE_SOUNDEX
- { "soundex", 1, 0, SQLITE_UTF8, 0, soundexFunc},
+ { "soundex", 1, 0, SQLITE_UTF8, 0, soundexFunc},
#endif
#ifndef SQLITE_OMIT_LOAD_EXTENSION
- { "load_extension", 1, 1, SQLITE_UTF8, 0, loadExt },
- { "load_extension", 2, 1, SQLITE_UTF8, 0, loadExt },
+ { "load_extension", 1, 0xff, SQLITE_UTF8, 0, loadExt },
+ { "load_extension", 2, 0xff, SQLITE_UTF8, 0, loadExt },
#endif
#ifdef SQLITE_TEST
- { "randstr", 2, 0, SQLITE_UTF8, 0, randStr },
- { "test_destructor", 1, 1, SQLITE_UTF8, 0, test_destructor},
- { "test_destructor_count", 0, 0, SQLITE_UTF8, 0, test_destructor_count},
- { "test_auxdata", -1, 0, SQLITE_UTF8, 0, test_auxdata},
- { "test_error", 1, 0, SQLITE_UTF8, 0, test_error},
+ { "randstr", 2, 0, SQLITE_UTF8, 0, randStr },
+ { "test_destructor", 1, 0xff, SQLITE_UTF8, 0, test_destructor},
+ { "test_destructor_count", 0, 0, SQLITE_UTF8, 0, test_destructor_count},
+ { "test_auxdata", -1, 0, SQLITE_UTF8, 0, test_auxdata},
+ { "test_error", 1, 0, SQLITE_UTF8, 0, test_error},
#endif
};
static const struct {
@@ -1106,7 +1221,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
void (*xFinalize)(sqlite3_context*);
} aAggs[] = {
{ "min", 1, 0, 1, minmaxStep, minMaxFinalize },
- { "max", 1, 2, 1, minmaxStep, minMaxFinalize },
+ { "max", 1, 1, 1, minmaxStep, minMaxFinalize },
{ "sum", 1, 0, 0, sumStep, sumFinalize },
{ "total", 1, 0, 0, sumStep, totalFinalize },
{ "avg", 1, 0, 0, sumStep, avgFinalize },
@@ -1116,10 +1231,12 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
int i;
for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
- void *pArg = 0;
- switch( aFuncs[i].argType ){
- case 1: pArg = db; break;
- case 2: pArg = (void *)(-1); break;
+ void *pArg;
+ u8 argType = aFuncs[i].argType;
+ if( argType==0xff ){
+ pArg = db;
+ }else{
+ pArg = (void*)(int)argType;
}
sqlite3CreateFunc(db, aFuncs[i].zName, aFuncs[i].nArg,
aFuncs[i].eTextRep, pArg, aFuncs[i].xFunc, 0, 0);
@@ -1138,11 +1255,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
sqlite3AttachFunctions(db);
#endif
for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
- void *pArg = 0;
- switch( aAggs[i].argType ){
- case 1: pArg = db; break;
- case 2: pArg = (void *)(-1); break;
- }
+ void *pArg = (void*)(int)aAggs[i].argType;
sqlite3CreateFunc(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8,
pArg, 0, aAggs[i].xStep, aAggs[i].xFinalize);
if( aAggs[i].needCollSeq ){