瀏覽代碼

Added custom function "bytes" that return the number of bytes instead of characters

mingodad 9 年之前
父節點
當前提交
f683aecef3
共有 1 個文件被更改,包括 60 次插入32 次删除
  1. 60 32
      SquiLu-ext/sqlite3.c

+ 60 - 32
SquiLu-ext/sqlite3.c

@@ -104180,7 +104180,7 @@ 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
 ** IMP: R-23979-26855 The abs(X) function returns the absolute value of
-** the numeric argument X. 
+** the numeric argument X.
 */
 */
 static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
 static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
   assert( argc==1 );
   assert( argc==1 );
@@ -104197,7 +104197,7 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
           return;
           return;
         }
         }
         iVal = -iVal;
         iVal = -iVal;
-      } 
+      }
       sqlite3_result_int64(context, iVal);
       sqlite3_result_int64(context, iVal);
       break;
       break;
     }
     }
@@ -104467,7 +104467,7 @@ static void broundFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
         case 6: dec_factor = LITDBL(1000000.0); break;
         case 6: dec_factor = LITDBL(1000000.0); break;
         default: dec_factor = pow(10, udec_places);
         default: dec_factor = pow(10, udec_places);
     }
     }
-    
+
     tmp = num * dec_factor;
     tmp = num * dec_factor;
     itmp = floor(tmp + (neg ? LITDBL(-0.5) : LITDBL(0.5)));
     itmp = floor(tmp + (neg ? LITDBL(-0.5) : LITDBL(0.5)));
     // Handle rounding of .5 in a special manner
     // Handle rounding of .5 in a special manner
@@ -104561,7 +104561,7 @@ static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
 #define noopFunc versionFunc   /* Substitute function - never called */
 #define noopFunc versionFunc   /* Substitute function - never called */
 
 
 /*
 /*
-** Implementation of random().  Return a random integer.  
+** Implementation of random().  Return a random integer.
 */
 */
 static void randomFunc(
 static void randomFunc(
   sqlite3_context *context,
   sqlite3_context *context,
@@ -104572,11 +104572,11 @@ static void randomFunc(
   UNUSED_PARAMETER2(NotUsed, NotUsed2);
   UNUSED_PARAMETER2(NotUsed, NotUsed2);
   sqlite3_randomness(sizeof(r), &r);
   sqlite3_randomness(sizeof(r), &r);
   if( r<0 ){
   if( r<0 ){
-    /* We need to prevent a random number of 0x8000000000000000 
+    /* We need to prevent a random number of 0x8000000000000000
     ** (or -9223372036854775808) since when you do abs() of that
     ** (or -9223372036854775808) since when you do abs() of that
     ** number of you get the same value back again.  To do this
     ** number of you get the same value back again.  To do this
     ** in a way that is testable, mask the sign bit off of negative
     ** in a way that is testable, mask the sign bit off of negative
-    ** values, resulting in a positive value.  Then take the 
+    ** values, resulting in a positive value.  Then take the
     ** 2s complement of that positive value.  The end result can
     ** 2s complement of that positive value.  The end result can
     ** therefore be no less than -9223372036854775807.
     ** therefore be no less than -9223372036854775807.
     */
     */
@@ -104614,8 +104614,8 @@ static void randomBlob(
 ** value is the same as the sqlite3_last_insert_rowid() API function.
 ** value is the same as the sqlite3_last_insert_rowid() API function.
 */
 */
 static void last_insert_rowid(
 static void last_insert_rowid(
-  sqlite3_context *context, 
-  int NotUsed, 
+  sqlite3_context *context,
+  int NotUsed,
   sqlite3_value **NotUsed2
   sqlite3_value **NotUsed2
 ){
 ){
   sqlite3 *db = sqlite3_context_db_handle(context);
   sqlite3 *db = sqlite3_context_db_handle(context);
@@ -104713,7 +104713,7 @@ static const struct compareInfo likeInfoAlt = { '%', '_',   0, 0 };
 ** it the last character in the list.
 ** it the last character in the list.
 **
 **
 ** Like matching rules:
 ** Like matching rules:
-** 
+**
 **      '%'       Matches any sequence of zero or more characters
 **      '%'       Matches any sequence of zero or more characters
 **
 **
 ***     '_'       Matches any one character
 ***     '_'       Matches any one character
@@ -104736,7 +104736,7 @@ static int patternCompare(
   u32 matchAll = pInfo->matchAll;  /* "*" or "%" */
   u32 matchAll = pInfo->matchAll;  /* "*" or "%" */
   u8 noCase = pInfo->noCase;       /* True if uppercase==lowercase */
   u8 noCase = pInfo->noCase;       /* True if uppercase==lowercase */
   const u8 *zEscaped = 0;          /* One past the last escaped input char */
   const u8 *zEscaped = 0;          /* One past the last escaped input char */
-  
+
   while( (c = Utf8Read(zPattern))!=0 ){
   while( (c = Utf8Read(zPattern))!=0 ){
     if( c==matchAll ){  /* Match "*" */
     if( c==matchAll ){  /* Match "*" */
       /* Skip over multiple "*" characters in the pattern.  If there
       /* Skip over multiple "*" characters in the pattern.  If there
@@ -104881,8 +104881,8 @@ SQLITE_API int sqlite3_like_count = 0;
 ** the GLOB operator.
 ** the GLOB operator.
 */
 */
 static void likeFunc(
 static void likeFunc(
-  sqlite3_context *context, 
-  int argc, 
+  sqlite3_context *context,
+  int argc,
   sqlite3_value **argv
   sqlite3_value **argv
 ){
 ){
   const unsigned char *zA, *zB;
   const unsigned char *zA, *zB;
@@ -104924,7 +104924,7 @@ static void likeFunc(
     const unsigned char *zEsc = sqlite3_value_text(argv[2]);
     const unsigned char *zEsc = sqlite3_value_text(argv[2]);
     if( zEsc==0 ) return;
     if( zEsc==0 ) return;
     if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){
     if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){
-      sqlite3_result_error(context, 
+      sqlite3_result_error(context,
           "ESCAPE expression must be a single character", -1);
           "ESCAPE expression must be a single character", -1);
       return;
       return;
     }
     }
@@ -105028,8 +105028,8 @@ static void compileoptionusedFunc(
 #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
 #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
 
 
 /*
 /*
-** Implementation of the sqlite_compileoption_get() function. 
-** The result is a string that identifies the compiler options 
+** Implementation of the sqlite_compileoption_get() function.
+** The result is a string that identifies the compiler options
 ** used to build SQLite.
 ** used to build SQLite.
 */
 */
 #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
 #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
@@ -105053,7 +105053,7 @@ static void compileoptiongetFunc(
 ** digits. */
 ** digits. */
 static const char hexdigits[] = {
 static const char hexdigits[] = {
   '0', '1', '2', '3', '4', '5', '6', '7',
   '0', '1', '2', '3', '4', '5', '6', '7',
-  '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' 
+  '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
 };
 };
 
 
 /*
 /*
@@ -105088,7 +105088,7 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
       char const *zBlob = sqlite3_value_blob(argv[0]);
       char const *zBlob = sqlite3_value_blob(argv[0]);
       int nBlob = sqlite3_value_bytes(argv[0]);
       int nBlob = sqlite3_value_bytes(argv[0]);
       assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */
       assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */
-      zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4); 
+      zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4);
       if( zText ){
       if( zText ){
         int i;
         int i;
         for(i=0; i<nBlob; i++){
         for(i=0; i<nBlob; i++){
@@ -105137,7 +105137,7 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
 
 
 /*
 /*
 ** The unicode() function.  Return the integer unicode code-point value
 ** The unicode() function.  Return the integer unicode code-point value
-** for the first character of the input string. 
+** for the first character of the input string.
 */
 */
 static void unicodeFunc(
 static void unicodeFunc(
   sqlite3_context *context,
   sqlite3_context *context,
@@ -105291,7 +105291,7 @@ static void replaceFunc(
   if( zOut==0 ){
   if( zOut==0 ){
     return;
     return;
   }
   }
-  loopLimit = nStr - nPattern;  
+  loopLimit = nStr - nPattern;
   for(i=j=0; i<=loopLimit; i++){
   for(i=j=0; i<=loopLimit; i++){
     if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
     if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
       zOut[j++] = zStr[i];
       zOut[j++] = zStr[i];
@@ -105440,7 +105440,7 @@ static void unknownFunc(
 ** Compute the soundex encoding of a word.
 ** Compute the soundex encoding of a word.
 **
 **
 ** IMP: R-59782-00072 The soundex(X) function returns a string that is the
 ** IMP: R-59782-00072 The soundex(X) function returns a string that is the
-** soundex encoding of the string X. 
+** soundex encoding of the string X.
 */
 */
 static void soundexFunc(
 static void soundexFunc(
   sqlite3_context *context,
   sqlite3_context *context,
@@ -105529,7 +105529,7 @@ static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){
 typedef struct SumCtx SumCtx;
 typedef struct SumCtx SumCtx;
 struct SumCtx {
 struct SumCtx {
   sqlite_double rSum;      /* Floating point sum */
   sqlite_double rSum;      /* Floating point sum */
-  i64 iSum;         /* Integer sum */   
+  i64 iSum;         /* Integer sum */
   i64 cnt;          /* Number of elements summed */
   i64 cnt;          /* Number of elements summed */
   u8 overflow;      /* True if integer overflow seen */
   u8 overflow;      /* True if integer overflow seen */
   u8 approx;        /* True if non-integer value was input to the sum */
   u8 approx;        /* True if non-integer value was input to the sum */
@@ -105614,13 +105614,13 @@ static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
 
 
 #ifndef SQLITE_OMIT_DEPRECATED
 #ifndef SQLITE_OMIT_DEPRECATED
   /* The sqlite3_aggregate_count() function is deprecated.  But just to make
   /* The sqlite3_aggregate_count() function is deprecated.  But just to make
-  ** sure it still operates correctly, verify that its count agrees with our 
+  ** sure it still operates correctly, verify that its count agrees with our
   ** internal count when using count(*) and when the total count can be
   ** internal count when using count(*) and when the total count can be
   ** expressed as a 32-bit integer. */
   ** expressed as a 32-bit integer. */
   assert( argc==1 || p==0 || p->n>0x7fffffff
   assert( argc==1 || p==0 || p->n>0x7fffffff
           || p->n==sqlite3_aggregate_count(context) );
           || p->n==sqlite3_aggregate_count(context) );
 #endif
 #endif
-}   
+}
 static void countFinalize(sqlite3_context *context){
 static void countFinalize(sqlite3_context *context){
   CountCtx *p;
   CountCtx *p;
   p = sqlite3_aggregate_context(context, 0);
   p = sqlite3_aggregate_context(context, 0);
@@ -105631,8 +105631,8 @@ static void countFinalize(sqlite3_context *context){
 ** Routines to implement min() and max() aggregate functions.
 ** Routines to implement min() and max() aggregate functions.
 */
 */
 static void minmaxStep(
 static void minmaxStep(
-  sqlite3_context *context, 
-  int NotUsed, 
+  sqlite3_context *context,
+  int NotUsed,
   sqlite3_value **argv
   sqlite3_value **argv
 ){
 ){
   Mem *pArg  = (Mem *)argv[0];
   Mem *pArg  = (Mem *)argv[0];
@@ -105722,8 +105722,8 @@ static void groupConcatFinalize(sqlite3_context *context){
       sqlite3_result_error_toobig(context);
       sqlite3_result_error_toobig(context);
     }else if( pAccum->accError==STRACCUM_NOMEM ){
     }else if( pAccum->accError==STRACCUM_NOMEM ){
       sqlite3_result_error_nomem(context);
       sqlite3_result_error_nomem(context);
-    }else{    
-      sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, 
+    }else{
+      sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1,
                           sqlite3_free);
                           sqlite3_free);
     }
     }
   }
   }
@@ -105767,10 +105767,10 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive)
   }
   }
   sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 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, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
-  sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, 
+  sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8,
       (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0);
       (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0);
   setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
   setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
-  setLikeOptFlag(db, "like", 
+  setLikeOptFlag(db, "like",
       caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
       caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
 }
 }
 
 
@@ -105788,8 +105788,8 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive)
 */
 */
 SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
 SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
   FuncDef *pDef;
   FuncDef *pDef;
-  if( pExpr->op!=TK_FUNCTION 
-   || !pExpr->x.pList 
+  if( pExpr->op!=TK_FUNCTION
+   || !pExpr->x.pList
    || pExpr->x.pList->nExpr!=2
    || pExpr->x.pList->nExpr!=2
   ){
   ){
     return 0;
     return 0;
@@ -105812,6 +105812,33 @@ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocas
   return 1;
   return 1;
 }
 }
 
 
+/*
+** Implementation of the bytes() function
+*/
+static void bytesFunc(
+  sqlite3_context *context,
+  int argc,
+  sqlite3_value **argv
+){
+  int len;
+
+  assert( argc==1 );
+  UNUSED_PARAMETER(argc);
+  switch( sqlite3_value_type(argv[0]) ){
+    case SQLITE_TEXT:
+    case SQLITE_BLOB:
+    case SQLITE_INTEGER:
+    case SQLITE_FLOAT: {
+      sqlite3_result_int(context, sqlite3_value_bytes(argv[0]));
+      break;
+    }
+    default: {
+      sqlite3_result_null(context);
+      break;
+    }
+  }
+}
+
 /*
 /*
 ** All of the FuncDef structures in the aBuiltinFunc[] array above
 ** All of the FuncDef structures in the aBuiltinFunc[] array above
 ** to the global function hash table.  This occurs at start-time (as
 ** to the global function hash table.  This occurs at start-time (as
@@ -105864,6 +105891,7 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
                                           SQLITE_FUNC_MINMAX ),
                                           SQLITE_FUNC_MINMAX ),
     FUNCTION2(typeof,            1, 0, 0, typeofFunc,  SQLITE_FUNC_TYPEOF),
     FUNCTION2(typeof,            1, 0, 0, typeofFunc,  SQLITE_FUNC_TYPEOF),
     FUNCTION2(length,            1, 0, 0, lengthFunc,  SQLITE_FUNC_LENGTH),
     FUNCTION2(length,            1, 0, 0, lengthFunc,  SQLITE_FUNC_LENGTH),
+    FUNCTION2(bytes,             1, 0, 0, bytesFunc,  SQLITE_FUNC_LENGTH),
     FUNCTION(instr,              2, 0, 0, instrFunc        ),
     FUNCTION(instr,              2, 0, 0, instrFunc        ),
     FUNCTION(printf,            -1, 0, 0, printfFunc       ),
     FUNCTION(printf,            -1, 0, 0, printfFunc       ),
     FUNCTION(unicode,            1, 0, 0, unicodeFunc      ),
     FUNCTION(unicode,            1, 0, 0, unicodeFunc      ),
@@ -105901,7 +105929,7 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
     AGGREGATE(count,             1, 0, 0, countStep,       countFinalize  ),
     AGGREGATE(count,             1, 0, 0, countStep,       countFinalize  ),
     AGGREGATE(group_concat,      1, 0, 0, groupConcatStep, groupConcatFinalize),
     AGGREGATE(group_concat,      1, 0, 0, groupConcatStep, groupConcatFinalize),
     AGGREGATE(group_concat,      2, 0, 0, groupConcatStep, groupConcatFinalize),
     AGGREGATE(group_concat,      2, 0, 0, groupConcatStep, groupConcatFinalize),
-  
+
     LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
     LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
 #ifdef SQLITE_CASE_SENSITIVE_LIKE
 #ifdef SQLITE_CASE_SENSITIVE_LIKE
     LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
     LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),