⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 func.c

📁 sqlite的最新源码 This ZIP archive contains preprocessed C code for the SQLite library as individual sour
💻 C
📖 第 1 页 / 共 3 页
字号:
      while( nIn>0 ){        int len;        for(i=0; i<nChar; i++){          len = aLen[i];          if( len<=nIn && memcmp(&zIn[nIn-len],azChar[i],len)==0 ) break;        }        if( i>=nChar ) break;        nIn -= len;      }    }    if( zCharSet ){      sqlite3_free(azChar);    }  }  sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT);}#ifdef SQLITE_SOUNDEX/*** Compute the soundex encoding of a word.*/static void soundexFunc(  sqlite3_context *context,  int argc,  sqlite3_value **argv){  char zResult[8];  const u8 *zIn;  int i, j;  static const unsigned char iCode[] = {    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,    1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,    0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,    1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,  };  assert( argc==1 );  zIn = (u8*)sqlite3_value_text(argv[0]);  if( zIn==0 ) zIn = (u8*)"";  for(i=0; zIn[i] && !isalpha(zIn[i]); i++){}  if( zIn[i] ){    u8 prevcode = iCode[zIn[i]&0x7f];    zResult[0] = toupper(zIn[i]);    for(j=1; j<4 && zIn[i]; i++){      int code = iCode[zIn[i]&0x7f];      if( code>0 ){        if( code!=prevcode ){          prevcode = code;          zResult[j++] = code + '0';        }      }else{        prevcode = 0;      }    }    while( j<4 ){      zResult[j++] = '0';    }    zResult[j] = 0;    sqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT);  }else{    sqlite3_result_text(context, "?000", 4, SQLITE_STATIC);  }}#endif#ifndef SQLITE_OMIT_LOAD_EXTENSION/*** A function that loads a shared-library extension then returns NULL.*/static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){  const char *zFile = (const char *)sqlite3_value_text(argv[0]);  const char *zProc;  sqlite3 *db = sqlite3_context_db_handle(context);  char *zErrMsg = 0;  if( argc==2 ){    zProc = (const char *)sqlite3_value_text(argv[1]);  }else{    zProc = 0;  }  if( zFile && sqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){    sqlite3_result_error(context, zErrMsg, -1);    sqlite3_free(zErrMsg);  }}#endif/*** An instance of the following structure holds the context of a** sum() or avg() aggregate computation.*/typedef struct SumCtx SumCtx;struct SumCtx {  double rSum;      /* Floating point sum */  i64 iSum;         /* Integer sum */     i64 cnt;          /* Number of elements summed */  u8 overflow;      /* True if integer overflow seen */  u8 approx;        /* True if non-integer value was input to the sum */};/*** Routines used to compute the sum, average, and total.**** The SUM() function follows the (broken) SQL standard which means** that it returns NULL if it sums over no inputs.  TOTAL returns** 0.0 in that case.  In addition, TOTAL always returns a float where** SUM might return an integer if it never encounters a floating point** value.  TOTAL never fails, but SUM might through an exception if** it overflows an integer.*/static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){  SumCtx *p;  int type;  assert( argc==1 );  UNUSED_PARAMETER(argc);  p = sqlite3_aggregate_context(context, sizeof(*p));  type = sqlite3_value_numeric_type(argv[0]);  if( p && type!=SQLITE_NULL ){    p->cnt++;    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 = p->iSum >> (sizeof(i64)*8-1);        int s2 = v       >> (sizeof(i64)*8-1);        int s3 = iNewSum >> (sizeof(i64)*8-1);        p->overflow = (s1&s2&~s3) | (~s1&~s2&s3);        p->iSum = iNewSum;      }    }else{      p->rSum += sqlite3_value_double(argv[0]);      p->approx = 1;    }  }}static void sumFinalize(sqlite3_context *context){  SumCtx *p;  p = sqlite3_aggregate_context(context, 0);  if( p && p->cnt>0 ){    if( p->overflow ){      sqlite3_result_error(context,"integer overflow",-1);    }else if( p->approx ){      sqlite3_result_double(context, p->rSum);    }else{      sqlite3_result_int64(context, p->iSum);    }  }}static void avgFinalize(sqlite3_context *context){  SumCtx *p;  p = sqlite3_aggregate_context(context, 0);  if( p && p->cnt>0 ){    sqlite3_result_double(context, p->rSum/(double)p->cnt);  }}static void totalFinalize(sqlite3_context *context){  SumCtx *p;  p = sqlite3_aggregate_context(context, 0);  sqlite3_result_double(context, p ? p->rSum : 0.0);}/*** The following structure keeps track of state information for the** count() aggregate function.*/typedef struct CountCtx CountCtx;struct CountCtx {  i64 n;};/*** Routines to implement the count() aggregate function.*/static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){  CountCtx *p;  p = sqlite3_aggregate_context(context, sizeof(*p));  if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){    p->n++;  }}   static void countFinalize(sqlite3_context *context){  CountCtx *p;  p = sqlite3_aggregate_context(context, 0);  sqlite3_result_int64(context, p ? p->n : 0);}/*** Routines to implement min() and max() aggregate functions.*/static void minmaxStep(  sqlite3_context *context,   int NotUsed,   sqlite3_value **argv){  Mem *pArg  = (Mem *)argv[0];  Mem *pBest;  UNUSED_PARAMETER(NotUsed);  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;  pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));  if( !pBest ) return;  if( pBest->flags ){    int max;    int cmp;    CollSeq *pColl = sqlite3GetFuncCollSeq(context);    /* This step function is used for both the min() and max() aggregates,    ** the only difference between the two being that the sense of the    ** comparison is inverted. For the max() aggregate, the    ** sqlite3_user_data() function returns (void *)-1. For min() it    ** returns (void *)db, where db is the sqlite3* database pointer.    ** Therefore the next statement sets variable 'max' to 1 for the max()    ** aggregate, or 0 for min().    */    max = sqlite3_user_data(context)!=0;    cmp = sqlite3MemCompare(pBest, pArg, pColl);    if( (max && cmp<0) || (!max && cmp>0) ){      sqlite3VdbeMemCopy(pBest, pArg);    }  }else{    sqlite3VdbeMemCopy(pBest, pArg);  }}static void minMaxFinalize(sqlite3_context *context){  sqlite3_value *pRes;  pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);  if( pRes ){    if( pRes->flags ){      sqlite3_result_value(context, pRes);    }    sqlite3VdbeMemRelease(pRes);  }}/*** group_concat(EXPR, ?SEPARATOR?)*/static void groupConcatStep(  sqlite3_context *context,  int argc,  sqlite3_value **argv){  const char *zVal;  StrAccum *pAccum;  const char *zSep;  int nVal, nSep, i;  if( argc==0 || sqlite3_value_type(argv[0])==SQLITE_NULL ) return;  pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));  if( pAccum ){    sqlite3 *db = sqlite3_context_db_handle(context);    pAccum->useMalloc = 1;    pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];    if( pAccum->nChar ){      if( argc>1 ){        zSep = (char*)sqlite3_value_text(argv[argc-1]);        nSep = sqlite3_value_bytes(argv[argc-1]);      }else{        zSep = ",";        nSep = 1;      }      sqlite3StrAccumAppend(pAccum, zSep, nSep);    }    i = 0;    do{      zVal = (char*)sqlite3_value_text(argv[i]);      nVal = sqlite3_value_bytes(argv[i]);      sqlite3StrAccumAppend(pAccum, zVal, nVal);      i++;    }while( i<argc-1 );  }}static void groupConcatFinalize(sqlite3_context *context){  StrAccum *pAccum;  pAccum = sqlite3_aggregate_context(context, 0);  if( pAccum ){    if( pAccum->tooBig ){      sqlite3_result_error_toobig(context);    }else if( pAccum->mallocFailed ){      sqlite3_result_error_nomem(context);    }else{          sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1,                           sqlite3_free);    }  }}/*** This function registered all of the above C functions as SQL** functions.  This should be the only routine in this file with** external linkage.*/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;    }  }#ifdef SQLITE_SSE  (void)sqlite3SseFunctions(db);#endif}/*** Set the LIKEOPT flag on the 2-argument function with the given name.*/static void setLikeOptFlag(sqlite3 *db, const char *zName, int flagVal){  FuncDef *pDef;  pDef = sqlite3FindFunction(db, zName, strlen(zName), 2, SQLITE_UTF8, 0);  if( pDef ){    pDef->flags = flagVal;  }}/*** 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;  }  sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0);  sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0);  sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8,       (struct compareInfo*)&globInfo, likeFunc, 0,0);  setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);  setLikeOptFlag(db, "like",       caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_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, int *pIsNocase, char *aWc){  FuncDef *pDef;  if( pExpr->op!=TK_FUNCTION || !pExpr->pList ){    return 0;  }  if( pExpr->pList->nExpr!=2 ){    return 0;  }  pDef = sqlite3FindFunction(db, (char*)pExpr->token.z, pExpr->token.n, 2,                             SQLITE_UTF8, 0);  if( pDef==0 || (pDef->flags & SQLITE_FUNC_LIKE)==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 );  *pIsNocase = (pDef->flags & SQLITE_FUNC_CASE)==0;  return 1;}/*** All all of the FuncDef structures in the aBuiltinFunc[] array above** to the global function hash table.  This occurs at start-time (as** a consequence of calling sqlite3_initialize()).**** After this routine runs*/void sqlite3RegisterGlobalFunctions(void){  /*  ** The following array holds FuncDef structures for all of the functions  ** defined in this file.  **  ** The array cannot be constant since changes are made to the  ** FuncDef.pHash elements at start-time.  The elements of this array  ** are read-only after initialization is complete.  */  static SQLITE_WSD FuncDef aBuiltinFunc[] = {    FUNCTION(ltrim,              1, 1, 0, trimFunc         ),    FUNCTION(ltrim,              2, 1, 0, trimFunc         ),    FUNCTION(rtrim,              1, 2, 0, trimFunc         ),    FUNCTION(rtrim,              2, 2, 0, trimFunc         ),    FUNCTION(trim,               1, 3, 0, trimFunc         ),    FUNCTION(trim,               2, 3, 0, trimFunc         ),    FUNCTION(min,               -1, 0, 1, minmaxFunc       ),    FUNCTION(min,                0, 0, 1, 0                ),    AGGREGATE(min,               1, 0, 1, minmaxStep,      minMaxFinalize ),    FUNCTION(max,               -1, 1, 1, minmaxFunc       ),    FUNCTION(max,                0, 1, 1, 0                ),    AGGREGATE(max,               1, 1, 1, minmaxStep,      minMaxFinalize ),    FUNCTION(typeof,             1, 0, 0, typeofFunc       ),    FUNCTION(length,             1, 0, 0, lengthFunc       ),    FUNCTION(substr,             2, 0, 0, substrFunc       ),    FUNCTION(substr,             3, 0, 0, substrFunc       ),    FUNCTION(abs,                1, 0, 0, absFunc          ),    FUNCTION(round,              1, 0, 0, roundFunc        ),    FUNCTION(round,              2, 0, 0, roundFunc        ),    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(hex,                1, 0, 0, hexFunc          ),    FUNCTION(ifnull,             2, 0, 1, ifnullFunc       ),    FUNCTION(random,            -1, 0, 0, randomFunc       ),    FUNCTION(randomblob,         1, 0, 0, randomBlob       ),    FUNCTION(nullif,             2, 0, 1, nullifFunc       ),    FUNCTION(sqlite_version,     0, 0, 0, versionFunc      ),    FUNCTION(quote,              1, 0, 0, quoteFunc        ),    FUNCTION(last_insert_rowid,  0, 0, 0, last_insert_rowid),    FUNCTION(changes,            0, 0, 0, changes          ),    FUNCTION(total_changes,      0, 0, 0, total_changes    ),    FUNCTION(replace,            3, 0, 0, replaceFunc      ),    FUNCTION(zeroblob,           1, 0, 0, zeroblobFunc     ),  #ifdef SQLITE_SOUNDEX    FUNCTION(soundex,            1, 0, 0, soundexFunc      ),  #endif  #ifndef SQLITE_OMIT_LOAD_EXTENSION    FUNCTION(load_extension,     1, 0, 0, loadExt          ),    FUNCTION(load_extension,     2, 0, 0, loadExt          ),  #endif    AGGREGATE(sum,               1, 0, 0, sumStep,         sumFinalize    ),    AGGREGATE(total,             1, 0, 0, sumStep,         totalFinalize    ),    AGGREGATE(avg,               1, 0, 0, sumStep,         avgFinalize    ),    AGGREGATE(count,             0, 0, 0, countStep,       countFinalize  ),    AGGREGATE(count,             1, 0, 0, countStep,       countFinalize  ),    AGGREGATE(group_concat,     -1, 0, 0, groupConcatStep, groupConcatFinalize),      LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),  #ifdef SQLITE_CASE_SENSITIVE_LIKE    LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),    LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),  #else    LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),    LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),  #endif  };  int i;  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aBuiltinFunc);  for(i=0; i<ArraySize(aBuiltinFunc); i++){    sqlite3FuncDefInsert(pHash, &aFunc[i]);  }  sqlite3RegisterDateTimeFunctions();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -