void sqlite_ext_uid(sqlite3_context *db, int row, sqlite3_value **value) { char *uid = malloc(256); char *chars = "0123456789abcdefghijklmnopqrstuvwxyz"; int max_length = 8; if ( uid == NULL ) { sqlite3_result_error_nomem(db); return; } if ( value != NULL && value[0] != NULL ) { int type = sqlite3_value_numeric_type(value[0]); if ( type == SQLITE_INTEGER ) { max_length = sqlite3_value_int(value[0]); if ( max_length > 256 ) { sqlite3_result_error_nomem(db); } } } sqlite_ext_uid_randomizer(chars, max_length, uid); sqlite3_result_text(db, uid, strlen(uid), sqlite_ext_uid_destroy); return; }
extern void pg_string_agg_step(sqlite3_context *context, int argc, sqlite3_value **argv) { STRING_AGG_CONTEXT_T *ctx; char *s; int slen; char *sep; int seplen; _ksu_null_if_null_param(argc, argv); if (sqlite3_value_type(argv[0]) == SQLITE_BLOB) { slen = sqlite3_value_bytes(argv[0]); seplen = sqlite3_value_bytes(argv[1]); s = (char *)sqlite3_value_text(argv[0]); sep = (char *)sqlite3_value_text(argv[1]); } else { s = (char *)sqlite3_value_text(argv[0]); sep = (char *)sqlite3_value_text(argv[1]); slen = strlen(s); seplen = strlen(sep); } ctx = (STRING_AGG_CONTEXT_T *)sqlite3_aggregate_context(context, sizeof(STRING_AGG_CONTEXT_T)); if (ctx) { if (ctx->sz == 0) { if ((ctx->aggr = (char *)sqlite3_malloc((1 + (slen+seplen)/CHUNK) * CHUNK)) == (char *)NULL) { sqlite3_result_error_nomem(context); return; } ctx->sz = (1 + (slen+seplen)/CHUNK) * CHUNK; memcpy(ctx->aggr, s, slen); ctx->len = slen; } else { if ((ctx->len + seplen + slen) > ctx->sz) { if ((ctx->aggr = (char *)sqlite3_realloc(ctx->aggr, ctx->sz + (1 + (slen+seplen)/CHUNK) * CHUNK)) == (char *)NULL) { sqlite3_result_error_nomem(context); return; } ctx->sz += (1 + (slen+seplen)/CHUNK) * CHUNK; } memcpy(&(ctx->aggr[ctx->len]), sep, seplen); ctx->len += seplen; memcpy(&(ctx->aggr[ctx->len]), s, slen); ctx->len += slen; } } }
extern void my_load_file(sqlite3_context * context, int argc, sqlite3_value ** argv) { struct stat statbuf; char *fname; unsigned char *blob; FILE *fp; size_t nread; _ksu_null_if_null_param(argc, argv); fname = (char *)sqlite3_value_text(argv[0]); if (stat((const char *)fname, &statbuf) == -1) { sqlite3_result_null(context); return; } if ((blob = (unsigned char *)sqlite3_malloc((int)statbuf.st_size)) == (unsigned char *)NULL) { sqlite3_result_error_nomem(context); return; } if ((fp = fopen(fname, "r")) != (FILE *)NULL) { nread = fread((void *)blob, sizeof(unsigned char), (size_t)statbuf.st_size, fp); fclose(fp); sqlite3_result_blob(context, (const void *)blob, (int)nread, sqlite3_free); } else { sqlite3_free(blob); sqlite3_result_null(context); } }
/* ** The implementation of the sqlite_record() function. This function accepts ** a single argument of any type. The return value is a formatted database ** record (a blob) containing the argument value. ** ** This is used to convert the value stored in the 'sample' column of the ** sqlite_stat3 table to the record format SQLite uses internally. */ static void recordFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ const int file_format = 1; int iSerial; /* Serial type */ int nSerial; /* Bytes of space for iSerial as varint */ int nVal; /* Bytes of space required for argv[0] */ int nRet; sqlite3 *db; u8 *aRet; UNUSED_PARAMETER( argc ); iSerial = sqlite3VdbeSerialType(argv[0], file_format); nSerial = sqlite3VarintLen(iSerial); nVal = sqlite3VdbeSerialTypeLen(iSerial); db = sqlite3_context_db_handle(context); nRet = 1 + nSerial + nVal; aRet = sqlite3DbMallocRaw(db, nRet); if( aRet==0 ){ sqlite3_result_error_nomem(context); }else{ aRet[0] = nSerial+1; sqlite3PutVarint(&aRet[1], iSerial); sqlite3VdbeSerialPut(&aRet[1+nSerial], nVal, argv[0], file_format); sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT); sqlite3DbFree(db, aRet); } }
/* ** Implementation of the eval(X) and eval(X,Y) SQL functions. ** ** Evaluate the SQL text in X. Return the results, using string ** Y as the separator. If Y is omitted, use a single space character. */ static void sqlEvalFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ const char *zSql; sqlite3 *db; char *zErr = 0; int rc; struct EvalResult x; memset(&x, 0, sizeof(x)); x.zSep = " "; zSql = (const char*)sqlite3_value_text(argv[0]); if( zSql==0 ) return; if( argc>1 ){ x.zSep = (const char*)sqlite3_value_text(argv[1]); if( x.zSep==0 ) return; } x.szSep = (int)strlen(x.zSep); db = sqlite3_context_db_handle(context); rc = sqlite3_exec(db, zSql, callback, &x, &zErr); if( rc!=SQLITE_OK ){ sqlite3_result_error(context, zErr, -1); sqlite3_free(zErr); }else if( x.zSep==0 ){ sqlite3_result_error_nomem(context); sqlite3_free(x.z); }else{ sqlite3_result_text(context, x.z, (int)x.nUsed, sqlite3_free); } }
extern void pg_to_hex(sqlite3_context * context, int argc, sqlite3_value ** argv) { unsigned long long n; long long signedn; char *result; if (ksu_prm_ok(context, argc, argv, "to_hex", KSU_PRM_INT)) { signedn = (long long)sqlite3_value_int64(argv[0]); n = (unsigned long long)signedn; if (signedn < 0) { signedn *= -1; } result = (char *)sqlite3_malloc(1 + 2 * sizeof(n)); if (result == (char *)NULL) { sqlite3_result_error_nomem(context); return; } if (signedn > INT_MAX) { (void)sprintf(result, "%llx", n); } else { (void)sprintf(result, "%x", (unsigned int)n); } sqlite3_result_text(context, result, -1, sqlite3_free); } }
/* ** Allocate nByte bytes of space using sqlite3_malloc(). If the ** allocation fails, call sqlite3_result_error_nomem() to notify ** the database handle that malloc() has failed. */ static void *testContextMalloc(sqlite3_context *context, int nByte){ char *z = sqlite3_malloc(nByte); if( !z && nByte>0 ){ sqlite3_result_error_nomem(context); } return z; }
/* * The BFileFullPathFunc() SQL function returns full path of a BFile */ static void BFileFullPathFunc( sqlite3_context *context, int argc, sqlite3_value **argv) { int rc; sqlite3 *db; int loc_size; char *pLoc, *full_path; assert(context != NULL && argc == 1 && argv != NULL); loc_size = sqlite3_value_bytes(argv[0]); if (loc_size == 0) { sqlite3_result_null(context); return; } pLoc = (char *)sqlite3_value_text(argv[0]); db = (sqlite3 *)sqlite3_user_data(context); rc = get_full_path(db, pLoc, loc_size, &full_path); if (rc) { if (rc == SQLITE_NOMEM) sqlite3_result_error_nomem(context); else sqlite3_result_error(context, "internal error", -1); return; } sqlite3_result_text(context, full_path, strlen(full_path), sqlite3_free); }
static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ int n = 0; double r; char *zBuf; assert( argc==1 || argc==2 ); if( argc==2 ){ if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return; n = sqlite3_value_int(argv[1]); if( n>30 ) n = 30; if( n<0 ) n = 0; } if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; r = sqlite3_value_double(argv[0]); /* If Y==0 and X will fit in a 64-bit int, ** handle the rounding directly, ** otherwise use printf. */ if( n==0 && r>=0 && r<LARGEST_INT64-1 ){ r = (double)((sqlite_int64)(r+0.5)); }else if( n==0 && r<0 && (-r)<LARGEST_INT64-1 ){ r = -(double)((sqlite_int64)((-r)+0.5)); }else{ zBuf = sqlite3_mprintf("%.*f",n,r); if( zBuf==0 ){ sqlite3_result_error_nomem(context); return; } sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8); sqlite3_free(zBuf); } sqlite3_result_double(context, r); }
/* * Doesn't exactly behaves as the PostgreSQL version as a \ * leaves sqlite completely cold. Serves, however, the * same purpose, which is making data extracted from the * database usable in a statement. */ extern void pg_quote_literal(sqlite3_context * context, int argc, sqlite3_value ** argv) { int len; char *str; char *result = (char *)NULL; int resultsz; int i; int j; _ksu_null_if_null_param(argc, argv); len = sqlite3_value_bytes(argv[0]); str = (char *)sqlite3_value_blob(argv[0]); if ((result = (char *)sqlite3_malloc(len + SAFETY_MARGIN + 1)) == (char *)NULL) { sqlite3_result_error_nomem(context); return; } resultsz = len + SAFETY_MARGIN; *result = '\''; j = 1; for (i = 0; i < len; i++) { switch (str[i]) { case '\'': // Escape quote result[j++] = '\''; break; default : break; } result[j++] = str[i]; if (j >= resultsz - 2) { // Time to realloc if ((result = (char *)sqlite3_realloc(result, resultsz + SAFETY_MARGIN + 1)) == (char *)NULL) { sqlite3_result_error_nomem(context); return; } resultsz += SAFETY_MARGIN; } } result[j++] = '\''; sqlite3_result_text(context, result, j, sqlite3_free); }
static Fts5MatchinfoCtx *fts5MatchinfoNew( const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ Fts5Context *pFts, /* First arg to pass to pApi functions */ sqlite3_context *pCtx, /* Context for returning error message */ const char *zArg /* Matchinfo flag string */ ){ Fts5MatchinfoCtx *p; int nCol; int nPhrase; int i; int nInt; int nByte; int rc; nCol = pApi->xColumnCount(pFts); nPhrase = pApi->xPhraseCount(pFts); nInt = 0; for(i=0; zArg[i]; i++){ int n = fts5MatchinfoFlagsize(nCol, nPhrase, zArg[i]); if( n<0 ){ char *zErr = sqlite3_mprintf("unrecognized matchinfo flag: %c", zArg[i]); sqlite3_result_error(pCtx, zErr, -1); sqlite3_free(zErr); return 0; } nInt += n; } nByte = sizeof(Fts5MatchinfoCtx) /* The struct itself */ + sizeof(u32) * nInt /* The p->aRet[] array */ + (i+1); /* The p->zArg string */ p = (Fts5MatchinfoCtx*)sqlite3_malloc(nByte); if( p==0 ){ sqlite3_result_error_nomem(pCtx); return 0; } memset(p, 0, nByte); p->nCol = nCol; p->nPhrase = nPhrase; p->aRet = (u32*)&p[1]; p->nRet = nInt; p->zArg = (char*)&p->aRet[nInt]; memcpy(p->zArg, zArg, i); rc = fts5MatchinfoIter(pApi, pFts, p, fts5MatchinfoGlobalCb); if( rc!=SQLITE_OK ){ sqlite3_result_error_code(pCtx, rc); sqlite3_free(p); p = 0; } return p; }
ikptr ik_sqlite3_result_error_nomem (ikptr s_context, ikpcb * pcb) { #ifdef HAVE_SQLITE3_RESULT_ERROR_NOMEM sqlite3_context * context = IK_SQLITE_CONTEXT(s_context); sqlite3_result_error_nomem(context); return IK_VOID_OBJECT; #else feature_failure(__func__); #endif }
/* ** Implementations of scalar functions for case mapping - upper() and ** lower(). Function upper() converts its input to upper-case (ABC). ** Function lower() converts to lower-case (abc). ** ** ICU provides two types of case mapping, "general" case mapping and ** "language specific". Refer to ICU documentation for the differences ** between the two. ** ** To utilise "general" case mapping, the upper() or lower() scalar ** functions are invoked with one argument: ** ** upper('ABC') -> 'abc' ** lower('abc') -> 'ABC' ** ** To access ICU "language specific" case mapping, upper() or lower() ** should be invoked with two arguments. The second argument is the name ** of the locale to use. Passing an empty string ("") or SQL NULL value ** as the second argument is the same as invoking the 1 argument version ** of upper() or lower(). ** ** lower('I', 'en_us') -> 'i' ** lower('I', 'tr_tr') -> '\u131' (small dotless i) ** ** http://www.icu-project.org/userguide/posix.html#case_mappings */ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ const UChar *zInput; /* Pointer to input string */ UChar *zOutput = 0; /* Pointer to output buffer */ int nInput; /* Size of utf-16 input string in bytes */ int nOut; /* Size of output buffer in bytes */ int cnt; int bToUpper; /* True for toupper(), false for tolower() */ UErrorCode status; const char *zLocale = 0; assert(nArg==1 || nArg==2); bToUpper = (sqlite3_user_data(p)!=0); if( nArg==2 ){ zLocale = (const char *)sqlite3_value_text(apArg[1]); } zInput = sqlite3_value_text16(apArg[0]); if( !zInput ){ return; } nOut = nInput = sqlite3_value_bytes16(apArg[0]); if( nOut==0 ){ sqlite3_result_text16(p, "", 0, SQLITE_STATIC); return; } for(cnt=0; cnt<2; cnt++){ UChar *zNew = sqlite3_realloc(zOutput, nOut); if( zNew==0 ){ sqlite3_free(zOutput); sqlite3_result_error_nomem(p); return; } zOutput = zNew; status = U_ZERO_ERROR; if( bToUpper ){ nOut = 2*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); }else{ nOut = 2*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status); } if( U_SUCCESS(status) ){ sqlite3_result_text16(p, zOutput, nOut, xFree); }else if( status==U_BUFFER_OVERFLOW_ERROR ){ assert( cnt==0 ); continue; }else{ icuFunctionError(p, bToUpper ? "u_strToUpper" : "u_strToLower", status); } return; } assert( 0 ); /* Unreachable */ }
/* ** Allocate nByte bytes of space using sqlite3_malloc(). If the ** allocation fails, call sqlite3_result_error_nomem() to notify ** the database handle that malloc() has failed. */ static void *contextMalloc(sqlite3_context *context, i64 nByte){ char *z; if( nByte>sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH] ){ sqlite3_result_error_toobig(context); z = 0; }else{ z = sqlite3Malloc(nByte); if( !z && nByte>0 ){ sqlite3_result_error_nomem(context); } } return z; }
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); } } }
void lsqlite3lib_xfinal_callback(sqlite3_context* ctx) { func* f = (func*)sqlite3_user_data(ctx); conn* c = f->c; int* ref = sqlite3_aggregate_context(ctx, sizeof(int)); if(!ref) sqlite3_result_error_nomem(ctx); lua_rawgeti(c->L, LUA_REGISTRYINDEX, c->ref); lua_rawgeti(c->L, -1, IDX_FUNCTION_TABLE); lua_pushstring(c->L, f->func_name); lua_rawget(c->L, -2); lua_rawgeti(c->L, -1, IDX_FUNC_XFINAL); lua_rawgeti(c->L, LUA_REGISTRYINDEX, *ref); lua_call(c->L, 1, 1); if(*ref != 0) { luaL_unref(c->L, LUA_REGISTRYINDEX, *ref); *ref = 0; } switch(lua_type(c->L, -1)) { case LUA_TBOOLEAN: sqlite3_result_int(ctx, lua_tointeger(c->L, -1)); break; case LUA_TNUMBER: if(luaL_checknumber(c->L, -1) - luaL_checklong(c->L, -1) > 0) { sqlite3_result_double(ctx, lua_tonumber(c->L, -1)); } else { sqlite3_result_int(ctx, lua_tointeger(c->L, -1)); } break; case LUA_TSTRING: { const char* ret = lua_tostring(c->L, -1); sqlite3_result_text(ctx, ret, strlen(ret), SQLITE_TRANSIENT); break; } case LUA_TNIL: default: sqlite3_result_null(ctx); break; } lua_pop(c->L, 2); }
void lsqlite3lib_xstep_callback(sqlite3_context* ctx,int n, sqlite3_value** value) { int i; func* f = (func*)sqlite3_user_data(ctx); conn* c = f->c; int* ref = sqlite3_aggregate_context(ctx, sizeof(int)); if(!ref) sqlite3_result_error_nomem(ctx); if(*ref == 0) { lua_newtable(c->L); *ref = luaL_ref(c->L, LUA_REGISTRYINDEX); } lua_rawgeti(c->L, LUA_REGISTRYINDEX, c->ref); lua_rawgeti(c->L, -1, IDX_FUNCTION_TABLE); lua_pushstring(c->L, f->func_name); lua_rawget(c->L, -2); lua_rawgeti(c->L, -1, IDX_FUNC_XSTEP); lua_createtable(c->L, n, 0); for(i = 0; i < n; i++) { lua_pushinteger(c->L, i + 1); switch(sqlite3_value_type(*(value+i))) { case SQLITE_INTEGER: lua_pushinteger(c->L, sqlite3_value_int(*(value+i))); break; case SQLITE_FLOAT: lua_pushnumber(c->L, sqlite3_value_double(*(value+i))); break; case SQLITE3_TEXT: lua_pushstring(c->L, (const char*)sqlite3_value_text(*(value+i))); break; case SQLITE_BLOB: case SQLITE_NULL: default: lua_pushnil(c->L); break; } lua_rawset(c->L, -3); } lua_rawgeti(c->L, LUA_REGISTRYINDEX, *ref); lua_call(c->L, 2, 0); }
/* ** Allocate nByte bytes of space using sqlite3_malloc(). If the ** allocation fails, call sqlite3_result_error_nomem() to notify ** the database handle that malloc() has failed and return NULL. ** If nByte is larger than the maximum string or blob length, then ** raise an SQLITE_TOOBIG exception and return NULL. */ static void *contextMalloc(sqlite3_context *context, i64 nByte){ char *z; sqlite3 *db = sqlite3_context_db_handle(context); assert( nByte>0 ); testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] ); testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH]+1 ); if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ sqlite3_result_error_toobig(context); z = 0; }else{ z = sqlite3Malloc((int)nByte); if( !z ){ sqlite3_result_error_nomem(context); } } return z; }
/* * The BFileNameFunc() SQL function returns locator of a BFile. */ static void BFileNameFunc( sqlite3_context *context, int argc, sqlite3_value **argv) { int dir_alias_size, filename_size, n; char *locator, *pLoc; assert(context != NULL && argc == 2 && argv != NULL); dir_alias_size = sqlite3_value_bytes(argv[0]); filename_size = sqlite3_value_bytes(argv[1]); if (filename_size == 0) { sqlite3_result_null(context); return; } n = strlen(BFILE_PREFIX) + 2 * sizeof(char) + dir_alias_size + filename_size; locator = (char *)sqlite3_malloc(n); if (locator == NULL) { sqlite3_result_error_nomem(context); return; } /* prefix to avoid be converted to number */ pLoc = locator; memcpy(pLoc, BFILE_PREFIX, strlen(BFILE_PREFIX)); pLoc += strlen(BFILE_PREFIX); *pLoc = dir_alias_size & 0xff; *(pLoc + 1) = (dir_alias_size >> 8) & 0xff; pLoc += 2 * sizeof(char); memcpy(pLoc, (char *)sqlite3_value_text(argv[0]), dir_alias_size); pLoc += dir_alias_size; memcpy(pLoc, (char *)sqlite3_value_text(argv[1]), filename_size); sqlite3_result_blob(context, locator, n, SQLITE_TRANSIENT); }
static void testHexToUtf16le( sqlite3_context *pCtx, int nArg, sqlite3_value **argv ){ int n; const char *zIn; char *zOut; assert( nArg==1 ); n = sqlite3_value_bytes(argv[0]); zIn = (const char*)sqlite3_value_text(argv[0]); zOut = sqlite3_malloc( n/2 ); if( zOut==0 ){ sqlite3_result_error_nomem(pCtx); }else{ testHexToBin(zIn, zOut); sqlite3_result_text16le(pCtx, zOut, n/2, sqlite3_free); } }
/* ** Implementation of the counter(X) function. If X is an integer ** constant, then the first invocation will return X. The second X+1. ** and so forth. Can be used (for example) to provide a sequence number ** in a result set. */ static void counterFunc( sqlite3_context *pCtx, /* Function context */ int nArg, /* Number of function arguments */ sqlite3_value **argv /* Values for all function arguments */ ){ int *pCounter = (int*)sqlite3_get_auxdata(pCtx, 0); if( pCounter==0 ){ pCounter = sqlite3_malloc( sizeof(*pCounter) ); if( pCounter==0 ){ sqlite3_result_error_nomem(pCtx); return; } *pCounter = sqlite3_value_int(argv[0]); sqlite3_set_auxdata(pCtx, 0, pCounter, sqlite3_free); }else{ ++*pCounter; } sqlite3_result_int(pCtx, *pCounter); }
/* * Get File size of a BFILE */ static void BFileSizeFunc( sqlite3_context *context, int argc, sqlite3_value **argv) { int rc; sqlite3 *db; int loc_size; off_t size; char *pLoc, *full_path; assert(context != NULL && argc == 1 && argv != NULL); full_path = NULL; loc_size = sqlite3_value_bytes(argv[0]); if (loc_size <= strlen(BFILE_PREFIX)) { sqlite3_result_int(context, -1); return; } db = (sqlite3 *)sqlite3_user_data(context); pLoc = (char *)sqlite3_value_text(argv[0]); assert(db != NULL && pLoc != NULL); rc = get_full_path(db, pLoc, loc_size, &full_path); if (rc) { if (rc == SQLITE_NOMEM) sqlite3_result_error_nomem(context); else sqlite3_result_error(context, "internal error", -1); return; } /* check existence, if not exits at at set size as -1 */ if (access(full_path, F_OK)) sqlite3_result_int(context, -1); else if (__bfile_get_size(full_path, &size) == SQLITE_OK) sqlite3_result_int(context, size); else sqlite3_result_error(context, "internal error", -1); sqlite3_free(full_path); }
extern void my_space(sqlite3_context * context, int argc, sqlite3_value ** argv) { int len; char *sp; _ksu_null_if_null_param(argc, argv); len = my_value_int(argv[0], 0); if (len) { if ((sp = (char *)sqlite3_malloc(len)) == (char *)NULL) { sqlite3_result_error_nomem(context); return; } (void)memset(sp, ' ', len); sqlite3_result_text(context, sp, len, sqlite3_free); } else { sqlite3_result_text(context, "", -1, SQLITE_STATIC); } }
/* ** CSV virtual table module xColumn method. */ static int csvColumn(sqlite3_vtab_cursor *pVtabCursor, sqlite3_context *ctx, int i){ CSV *pCSV = (CSV *)pVtabCursor->pVtab; if( i<0 || i>=pCSV->nCol ){ sqlite3_result_null( ctx ); }else{ // TODO SQLite uses dynamic typing... const char *col = pCSV->aCols[i]; if( !col ){ sqlite3_result_null( ctx ); }else if( pCSV->aEscapedQuotes[i] ){ char *z; int nByte = (int)(strlen(col) - pCSV->aEscapedQuotes[i] + 1); if( nByte>sqlite3_limit(pCSV->db, SQLITE_LIMIT_LENGTH, -1) ){ sqlite3_result_error_toobig( ctx ); z = 0; }else{ z = sqlite3_malloc( nByte ); if( !z ){ sqlite3_result_error_nomem( ctx ); } } if( z ){ int j,k; for(j=0, k=0; col[j]; j++){ z[k++] = col[j]; if( col[j]=='\"' ){ /* unescape quote */ j++; } } z[k] = 0; sqlite3_result_text( ctx, z, k, sqlite3_free ); // FIXME sqlite3_result_int64/double } }else{ sqlite3_result_text( ctx, col, -1, SQLITE_TRANSIENT ); // FIXME sqlite3_result_int64/double } } return SQLITE_OK; }
static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ int n = 0; double r; char *zBuf; assert( argc==1 || argc==2 ); if( argc==2 ){ if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return; n = sqlite3_value_int(argv[1]); if( n>30 ) n = 30; if( n<0 ) n = 0; } if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; r = sqlite3_value_double(argv[0]); zBuf = sqlite3_mprintf("%.*f",n,r); if( zBuf==0 ){ sqlite3_result_error_nomem(context); }else{ sqlite3AtoF(zBuf, &r); sqlite3_free(zBuf); sqlite3_result_double(context, r); } }
/* ** strftime( FORMAT, TIMESTRING, MOD, MOD, ...) ** ** Return a string described by FORMAT. Conversions as follows: ** ** %d day of month ** %f ** fractional seconds SS.SSS ** %H hour 00-24 ** %j day of year 000-366 ** %J ** julian day number ** %m month 01-12 ** %M minute 00-59 ** %s seconds since 1970-01-01 ** %S seconds 00-59 ** %w day of week 0-6 sunday==0 ** %W week of year 00-53 ** %Y year 0000-9999 ** %% % */ static void strftimeFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ DateTime x; u64 n; size_t i,j; char *z; sqlite3 *db; const char *zFmt; char zBuf[100]; if( argc==0 ) return; zFmt = (const char*)sqlite3_value_text(argv[0]); if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return; db = sqlite3_context_db_handle(context); for(i=0, n=1; zFmt[i]; i++, n++){ if( zFmt[i]=='%' ){ switch( zFmt[i+1] ){ case 'd': case 'H': case 'm': case 'M': case 'S': case 'W': n++; /* fall thru */ case 'w': case '%': break; case 'f': n += 8; break; case 'j': n += 3; break; case 'Y': n += 8; break; case 's': case 'J': n += 50; break; default: return; /* ERROR. return a NULL */ } i++; } } testcase( n==sizeof(zBuf)-1 ); testcase( n==sizeof(zBuf) ); testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 ); testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ); if( n<sizeof(zBuf) ){ z = zBuf; }else if( n>(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){ sqlite3_result_error_toobig(context); return; }else{ z = sqlite3DbMallocRawNN(db, (int)n); if( z==0 ){ sqlite3_result_error_nomem(context); return; } } computeJD(&x); computeYMD_HMS(&x); for(i=j=0; zFmt[i]; i++){ if( zFmt[i]!='%' ){ z[j++] = zFmt[i]; }else{ i++; switch( zFmt[i] ){ case 'd': sqlite3_snprintf(3, &z[j],"%02d",x.D); j+=2; break; case 'f': { double s = x.s; if( s>59.999 ) s = 59.999; sqlite3_snprintf(7, &z[j],"%06.3f", s); j += sqlite3Strlen30(&z[j]); break; } case 'H': sqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break; case 'W': /* Fall thru */ case 'j': { int nDay; /* Number of days since 1st day of year */ DateTime y = x; y.validJD = 0; y.M = 1; y.D = 1; computeJD(&y); nDay = (int)((x.iJD-y.iJD+43200000)/86400000); if( zFmt[i]=='W' ){ int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */ wd = (int)(((x.iJD+43200000)/86400000)%7); sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7); j += 2; }else{ sqlite3_snprintf(4, &z[j],"%03d",nDay+1); j += 3; } break; } case 'J': { sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0); j+=sqlite3Strlen30(&z[j]); break; } case 'm': sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break; case 'M': sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break; case 's': { sqlite3_snprintf(30,&z[j],"%lld", (i64)(x.iJD/1000 - 21086676*(i64)10000)); j += sqlite3Strlen30(&z[j]); break; } case 'S': sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break; case 'w': { z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0'; break; } case 'Y': { sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=sqlite3Strlen30(&z[j]); break; } default: z[j++] = '%'; break; } } } z[j] = 0; sqlite3_result_text(context, z, -1, z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC); }
extern void pg_age(sqlite3_context *context, int argc, sqlite3_value **argv) { struct tm age; struct tm beg; struct tm tmbuff; struct tm *bp; struct tm *bigger; struct tm *smaller; time_t currTime; double seconds; char *rp; int rplen; char buff[BUFF_LEN]; char *arg1; char *arg2; _ksu_check_arg_cnt(argc, 1, 2, "age"); if (ksu_prm_ok(context, argc, argv, "age", KSU_PRM_DATETIME, KSU_PRM_DATETIME)) { (void)memset(&age, 0, sizeof(struct tm)); arg1 = (char *)sqlite3_value_text(argv[0]); if ((sscanf(arg1, "%d-%d-%d %d:%d:%d", &age.tm_year, &age.tm_mon, &age.tm_mday, &age.tm_hour, &age.tm_min, &age.tm_sec) < 3)) { ksu_err_msg(context, KSU_ERR_ARG_N_NOT_DATETIME, 1, "age"); return; } age.tm_mon -= 1; age.tm_year -= 1900; if (argc == 1) { time(&currTime); if (currTime != -1) { bp = localtime_r(&currTime, &tmbuff); if (bp) { bp->tm_hour = 0; bp->tm_min = 0; bp->tm_sec = 0; bp->tm_gmtoff = 0; bp->tm_isdst = 0; seconds = currTime - mktime(&age); if (seconds > 0) { bigger = bp; smaller = &age; } else { bigger = &age; smaller = bp; } } else { // Not expected sqlite3_result_null(context); return; } } else { // Not expected sqlite3_result_null(context); return; } } else { (void)memset(&beg, 0, sizeof(struct tm)); arg2 = (char *)sqlite3_value_text(argv[1]); if ((sscanf(arg2, "%d-%d-%d %d:%d:%d", &beg.tm_year, &beg.tm_mon, &beg.tm_mday, &beg.tm_hour, &beg.tm_min, &beg.tm_sec) < 3)) { ksu_err_msg(context, KSU_ERR_ARG_N_NOT_DATETIME, 2, "age"); return; } beg.tm_mon -= 1; beg.tm_year -= 1900; seconds = mktime(&age) - mktime(&beg); if (seconds > 0) { bigger = &age; smaller = &beg; } else { bigger = &beg; smaller = &age; } bp = &age; } findDifference(bigger, smaller); if ((rp = (char *)sqlite3_malloc(AGE_LEN)) == NULL) { sqlite3_result_error_nomem(context); return; } rp[0] = '\0'; rplen = 0; if (bigger->tm_year) { snprintf(buff, BUFF_LEN, "%s%d years", (bigger == bp ? "" : "-"), bigger->tm_year); strncat(rp, buff, AGE_LEN - rplen); rplen = strlen(rp); } if (bigger->tm_mon) { snprintf(buff, BUFF_LEN, "%s%s%d mons", (rplen ? " " : ""), (bigger == bp ? "" : "-"), bigger->tm_mon); strncat(rp, buff, AGE_LEN - rplen); rplen = strlen(rp); } if (bigger->tm_mday) { snprintf(buff, BUFF_LEN, "%s%s%d days", (rplen ? " " : ""), (bigger == bp ? "" : "-"), bigger->tm_mday); strncat(rp, buff, AGE_LEN - rplen); } sqlite3_result_text(context, rp, -1, 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 */ i64 nOut; /* Maximum size of zOut */ int loopLimit; /* Last zStr[] that might match zPattern[] */ int i, j; /* Loop counters */ assert( argc==3 ); UNUSED_PARAMETER(argc); zStr = sqlite3_value_text(argv[0]); if( zStr==0 ) return; nStr = sqlite3_value_bytes(argv[0]); assert( zStr==sqlite3_value_text(argv[0]) ); /* No encoding change */ zPattern = sqlite3_value_text(argv[1]); if( zPattern==0 ){ assert( sqlite3_value_type(argv[1])==SQLITE_NULL || sqlite3_context_db_handle(context)->mallocFailed ); return; } if( zPattern[0]==0 ){ assert( sqlite3_value_type(argv[1])!=SQLITE_NULL ); sqlite3_result_value(context, argv[0]); return; } nPattern = sqlite3_value_bytes(argv[1]); assert( zPattern==sqlite3_value_text(argv[1]) ); /* No encoding change */ zRep = sqlite3_value_text(argv[2]); if( zRep==0 ) return; nRep = sqlite3_value_bytes(argv[2]); assert( zRep==sqlite3_value_text(argv[2]) ); nOut = nStr + 1; assert( nOut<SQLITE_MAX_LENGTH ); zOut = contextMalloc(context, (i64)nOut); 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{ u8 *zOld; sqlite3 *db = sqlite3_context_db_handle(context); nOut += nRep - nPattern; testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] ); testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] ); if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ sqlite3_result_error_toobig(context); sqlite3DbFree(db, zOut); return; } zOld = zOut; zOut = sqlite3_realloc(zOut, (int)nOut); if( zOut==0 ){ sqlite3_result_error_nomem(context); sqlite3DbFree(db, zOld); return; } memcpy(&zOut[j], zRep, nRep); j += nRep; i += nPattern-1; } } assert( j+nStr-i+1==nOut ); 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); }
/* ** This is the implementation of a scalar SQL function used to test the ** expression parser. It should be called as follows: ** ** fts3_exprtest(<tokenizer>, <expr>, <column 1>, ...); ** ** The first argument, <tokenizer>, is the name of the fts3 tokenizer used ** to parse the query expression (see README.tokenizers). The second argument ** is the query expression to parse. Each subsequent argument is the name ** of a column of the fts3 table that the query expression may refer to. ** For example: ** ** SELECT fts3_exprtest('simple', 'Bill col2:Bloggs', 'col1', 'col2'); */ static void fts3ExprTest( sqlite3_context *context, int argc, sqlite3_value **argv ){ sqlite3_tokenizer_module const *pModule = 0; sqlite3_tokenizer *pTokenizer = 0; int rc; char **azCol = 0; const char *zExpr; int nExpr; int nCol; int ii; Fts3Expr *pExpr; char *zBuf = 0; sqlite3 *db = sqlite3_context_db_handle(context); if( argc<3 ){ sqlite3_result_error(context, "Usage: fts3_exprtest(tokenizer, expr, col1, ...", -1 ); return; } rc = queryTestTokenizer(db, (const char *)sqlite3_value_text(argv[0]), &pModule); if( rc==SQLITE_NOMEM ){ sqlite3_result_error_nomem(context); goto exprtest_out; }else if( !pModule ){ sqlite3_result_error(context, "No such tokenizer module", -1); goto exprtest_out; } rc = pModule->xCreate(0, 0, &pTokenizer); assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); if( rc==SQLITE_NOMEM ){ sqlite3_result_error_nomem(context); goto exprtest_out; } pTokenizer->pModule = pModule; zExpr = (const char *)sqlite3_value_text(argv[1]); nExpr = sqlite3_value_bytes(argv[1]); nCol = argc-2; azCol = (char **)sqlite3_malloc(nCol*sizeof(char *)); if( !azCol ){ sqlite3_result_error_nomem(context); goto exprtest_out; } for(ii=0; ii<nCol; ii++){ azCol[ii] = (char *)sqlite3_value_text(argv[ii+2]); } rc = sqlite3Fts3ExprParse( pTokenizer, azCol, nCol, nCol, zExpr, nExpr, &pExpr ); if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){ sqlite3_result_error(context, "Error parsing expression", -1); }else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){ sqlite3_result_error_nomem(context); }else{ sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); sqlite3_free(zBuf); } sqlite3Fts3ExprFree(pExpr); exprtest_out: if( pModule && pTokenizer ){ rc = pModule->xDestroy(pTokenizer); } sqlite3_free(azCol); }
void context::result_error_nomem() { sqlite3_result_error_nomem(handle); }