static void function_rank (sqlite3_context *context, int argc, sqlite3_value *argv[]) { guint *matchinfo, *weights; gdouble rank = 0; gint i, n_columns; if (argc != 2) { sqlite3_result_error(context, "wrong number of arguments to function rank()", -1); return; } matchinfo = (unsigned int *) sqlite3_value_blob (argv[0]); weights = (unsigned int *) sqlite3_value_blob (argv[1]); n_columns = matchinfo[0]; for (i = 0; i < n_columns; i++) { if (matchinfo[i + 1] != 0) { rank += (gdouble) weights[i]; } } sqlite3_result_double(context, rank); }
void __SQLite3ExtMathSin(sqlite3_context *context, int argc, sqlite3_value **argv) { if (argc == 1 && sqlite3_value_type(argv[0]) != SQLITE_NULL) { sqlite3_result_double(context, sin(sqlite3_value_double(argv[0]))); } else { sqlite3_result_null(context); } }
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); } }
SQLITE_EXTENSION_INIT1 /* ** returns */ static void rank(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal) { int *aMatchinfo; int nCol; int nPhrase; int iPhrase; double score = 0.0; aMatchinfo = (int *)sqlite3_value_blob(apVal[0]); nPhrase = aMatchinfo[0]; nCol = aMatchinfo[1]; // do a simple count on string match for(iPhrase=0; iPhrase<nPhrase; iPhrase++) { int iCol; int *aPhraseinfo = &aMatchinfo[2 + iPhrase*nCol*3]; for(iCol=0; iCol<nCol; iCol++){ int nHitCount = aPhraseinfo[3*iCol]; int nGlobalHitCount = aPhraseinfo[3*iCol+1]; double weight = sqlite3_value_double(apVal[iCol+1]); if( nHitCount>0 ){ score += ((double)nHitCount / (double)nGlobalHitCount) * weight; } } } sqlite3_result_double(pCtx, score); return; }
/* wrapper for Levenshtein string comparison */ void levenshtein_wrapper(sqlite3_context *ctx, int n_values, sqlite3_value **value) { // check for NULL values, return NULL if any of the input strings is NULL if(sqlite3_value_type(value[0]) == SQLITE_NULL || sqlite3_value_type(value[1]) == SQLITE_NULL) { sqlite3_result_null(ctx); return; } const unsigned char *str1 = sqlite3_value_text(value[0]); const unsigned char *str2 = sqlite3_value_text(value[1]); #ifdef DEBUG Rprintf("String 1: %s\n", str1); Rprintf("String 2: %s\n", str2); #endif double result; int editDistance; editDistance = levenshtein_internal(str1, str2, 1, 1, 1); /* Only the string metric based on the edit distance is used in this package, therefore transform right here */ result = 1.0 - (double) editDistance / (double) max(strlen(str1), strlen(str2)); #ifdef DEBUG Rprintf("Ergebnis des Stringvergleichs: %f\n", result); #endif sqlite3_result_double(ctx, result); }
static void distanceFunc(sqlite3_context *context, int argc, sqlite3_value **argv) { // check that we have four arguments (lat1, lon1, lat2, lon2) assert(argc == 4); // check that all four arguments are non-null if (sqlite3_value_type(argv[0]) == SQLITE_NULL || sqlite3_value_type(argv[1]) == SQLITE_NULL || sqlite3_value_type(argv[2]) == SQLITE_NULL || sqlite3_value_type(argv[3]) == SQLITE_NULL) { sqlite3_result_null(context); return; } // get the four argument values double lat1 = sqlite3_value_double(argv[0]); double lon1 = sqlite3_value_double(argv[1]); double lat2 = sqlite3_value_double(argv[2]); double lon2 = sqlite3_value_double(argv[3]); // convert lat1 and lat2 into radians now, to avoid doing it twice below double lat1rad = DEG2RAD(lat1); double lat2rad = DEG2RAD(lat2); // apply the spherical law of cosines to our latitudes and longitudes, and set the result appropriately // 6378.1 is the approximate radius of the earth in kilometres sqlite3_result_double(context, acos(sin(lat1rad) * sin(lat2rad) + cos(lat1rad) * cos(lat2rad) * cos(DEG2RAD(lon2) - DEG2RAD(lon1))) * 6378.1); }
static void sqlite3_do_callback(sqlite3_context *context, CVarRef callback, int argc, sqlite3_value **argv, bool is_agg) { Array params = Array::Create(); php_sqlite3_agg_context *agg_context = NULL; if (is_agg) { agg_context = (php_sqlite3_agg_context *)sqlite3_aggregate_context (context, sizeof(php_sqlite3_agg_context)); params.append(ref(agg_context->context)); params.append(agg_context->row_count); } for (int i = 0; i < argc; i++) { params.append(get_value(argv[i])); } Variant ret = f_call_user_func_array(callback, params); if (!is_agg || !argv) { /* only set the sqlite return value if we are a scalar function, * or if we are finalizing an aggregate */ if (ret.isInteger()) { sqlite3_result_int(context, ret.toInt64()); } else if (ret.isNull()) { sqlite3_result_null(context); } else if (ret.isDouble()) { sqlite3_result_double(context, ret.toDouble()); } else { String sret = ret.toString(); sqlite3_result_text(context, sret.data(), sret.size(), SQLITE_TRANSIENT); } } else { /* we're stepping in an aggregate; the return value goes into * the context */ agg_context->context = ret; } }
static int sqlite_callback_return(Value v, sqlite3_context *ctx) { const RefNode *r_type = fs->Value_type(v); if (r_type == fs->cls_int) { int err = FALSE; int64_t i64 = fs->Value_int64(v, &err); if (err) { fs->throw_errorf(mod_sqlite, "SQLiteError", "'INTEGER' out of range (-2^63 - 2^63-1)"); return FALSE; } sqlite3_result_int64(ctx, i64); } else if (r_type == fs->cls_bool) { int i32 = Value_bool(v); sqlite3_result_int(ctx, i32); } else if (r_type == fs->cls_float) { double dval = Value_float2(v); sqlite3_result_double(ctx, dval); } else if (r_type == fs->cls_str) { RefStr *s = Value_vp(v); sqlite3_result_text(ctx, s->c, s->size, SQLITE_TRANSIENT); } else if (r_type == fs->cls_bytes) { RefStr *s = Value_vp(v); sqlite3_result_blob(ctx, s->c, s->size, SQLITE_TRANSIENT); } else if (r_type == fs->cls_null) { sqlite3_result_null(ctx); } else { fs->throw_errorf(fs->mod_lang, "TypeError", "Bool, Int, Float, Str, Bytes or Null required but %n", r_type); return FALSE; } return TRUE; }
int convertRResult(SEXP ans, sqlite3_context *context) { switch(TYPEOF(ans)) { case INTSXP: sqlite3_result_int(context, INTEGER(ans)[0]); break; case REALSXP: sqlite3_result_double(context, REAL(ans)[0]); break; case STRSXP: { const char *str = CHAR(STRING_ELT(ans, 0)); sqlite3_result_text(context, str, -1, SQLITE_TRANSIENT); break; } // Add more default: PROBLEM "Unhandled conversion of result of UDF from R to SQLite" WARN; break; } return(0); }
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); }
/* ** Implementation of the abs() function */ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ assert( argc==1 ); switch( sqlite3_value_type(argv[0]) ){ case SQLITE_INTEGER: { i64 iVal = sqlite3_value_int64(argv[0]); if( iVal<0 ){ if( (iVal<<1)==0 ){ sqlite3_result_error(context, "integer overflow", -1); return; } iVal = -iVal; } sqlite3_result_int64(context, iVal); break; } case SQLITE_NULL: { sqlite3_result_null(context); break; } default: { double rVal = sqlite3_value_double(argv[0]); if( rVal<0 ) rVal = -rVal; sqlite3_result_double(context, rVal); break; } } }
static void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result) { switch(TYPE(result)) { case T_NIL: sqlite3_result_null(ctx); break; case T_FIXNUM: sqlite3_result_int64(ctx, (sqlite3_int64)FIX2LONG(result)); break; case T_BIGNUM: #if SIZEOF_LONG < 8 if (RBIGNUM_LEN(result) * SIZEOF_BDIGITS <= 8) { sqlite3_result_int64(ctx, NUM2LL(result)); break; } #endif case T_FLOAT: sqlite3_result_double(ctx, NUM2DBL(result)); break; case T_STRING: sqlite3_result_text( ctx, (const char *)StringValuePtr(result), (int)RSTRING_LEN(result), SQLITE_TRANSIENT ); break; default: rb_raise(rb_eRuntimeError, "can't return %s", rb_class2name(CLASS_OF(result))); } }
int xColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int col) { BaseCursor *pCur = (BaseCursor *)cur; const auto *pVtab = (VirtualTable *)cur->pVtab; if (col >= static_cast<int>(pVtab->content->columns.size())) { // Requested column index greater than column set size. return SQLITE_ERROR; } const auto &column_name = pVtab->content->columns[col].first; const auto &type = pVtab->content->columns[col].second; if (pCur->row >= pCur->data.size()) { // Request row index greater than row set size. return SQLITE_ERROR; } // Attempt to cast each xFilter-populated row/column to the SQLite type. const auto &value = pCur->data[pCur->row][column_name]; if (pCur->data[pCur->row].count(column_name) == 0) { // Missing content. VLOG(1) << "Error " << column_name << " is empty"; sqlite3_result_null(ctx); } else if (type == TEXT_TYPE) { sqlite3_result_text(ctx, value.c_str(), value.size(), SQLITE_STATIC); } else if (type == INTEGER_TYPE) { long afinite; if (!safeStrtol(value, 10, afinite) || afinite < INT_MIN || afinite > INT_MAX) { VLOG(1) << "Error casting " << column_name << " (" << value << ") to INTEGER"; sqlite3_result_null(ctx); } else { sqlite3_result_int(ctx, (int)afinite); } } else if (type == BIGINT_TYPE || type == UNSIGNED_BIGINT_TYPE) { long long afinite; if (!safeStrtoll(value, 10, afinite)) { VLOG(1) << "Error casting " << column_name << " (" << value << ") to BIGINT"; sqlite3_result_null(ctx); } else { sqlite3_result_int64(ctx, afinite); } } else if (type == DOUBLE_TYPE) { char *end = nullptr; double afinite = strtod(value.c_str(), &end); if (end == nullptr || end == value.c_str() || *end != '\0') { afinite = 0; VLOG(1) << "Error casting " << column_name << " (" << value << ") to DOUBLE"; sqlite3_result_null(ctx); } else { sqlite3_result_double(ctx, afinite); } } else { LOG(ERROR) << "Error unknown column type " << column_name; } return SQLITE_OK; }
/* ** The cube() SQL function returns the cube of its input value. */ static void cubeFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ double r = sqlite3_value_double(argv[0]); sqlite3_result_double(context, r*r*r); }
SQLITE_EXTENSION_INIT1 static void halfFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ sqlite3_result_double(context, 0.5*sqlite3_value_double(argv[0])); }
/* ** Implementation of bm25() function. */ static void fts5Bm25Function( const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ Fts5Context *pFts, /* First arg to pass to pApi functions */ sqlite3_context *pCtx, /* Context for returning result/error */ int nVal, /* Number of values in apVal[] array */ sqlite3_value **apVal /* Array of trailing arguments */ ){ const double k1 = 1.2; /* Constant "k1" from BM25 formula */ const double b = 0.75; /* Constant "b" from BM25 formula */ int rc = SQLITE_OK; /* Error code */ double score = 0.0; /* SQL function return value */ Fts5Bm25Data *pData; /* Values allocated/calculated once only */ int i; /* Iterator variable */ int nInst = 0; /* Value returned by xInstCount() */ double D = 0.0; /* Total number of tokens in row */ double *aFreq = 0; /* Array of phrase freq. for current row */ /* Calculate the phrase frequency (symbol "f(qi,D)" in the documentation) ** for each phrase in the query for the current row. */ rc = fts5Bm25GetData(pApi, pFts, &pData); if( rc==SQLITE_OK ){ aFreq = pData->aFreq; memset(aFreq, 0, sizeof(double) * pData->nPhrase); rc = pApi->xInstCount(pFts, &nInst); } for(i=0; rc==SQLITE_OK && i<nInst; i++){ int ip; int ic; int io; rc = pApi->xInst(pFts, i, &ip, &ic, &io); if( rc==SQLITE_OK ){ double w = (nVal > ic) ? sqlite3_value_double(apVal[ic]) : 1.0; aFreq[ip] += w; } } /* Figure out the total size of the current row in tokens. */ if( rc==SQLITE_OK ){ int nTok; rc = pApi->xColumnSize(pFts, -1, &nTok); D = (double)nTok; } /* Determine the BM25 score for the current row. */ for(i=0; rc==SQLITE_OK && i<pData->nPhrase; i++){ score += pData->aIDF[i] * ( ( aFreq[i] * (k1 + 1.0) ) / ( aFreq[i] + k1 * (1 - b + b * D / pData->avgdl) ) ); } /* If no error has occurred, return the calculated score. Otherwise, ** throw an SQL exception. */ if( rc==SQLITE_OK ){ sqlite3_result_double(pCtx, -1.0 * score); }else{ sqlite3_result_error_code(pCtx, rc); } }
/* * rank_func -- * Sqlite user defined function for ranking the documents. * For each phrase of the query, it computes the tf and idf and adds them over. * It computes the final rank, by multiplying tf and idf together. * Weight of term t for document d = (term frequency of t in d * * inverse document frequency of t) * * Term Frequency of term t in document d = Number of times t occurs in d / * Number of times t appears in all * documents * * Inverse document frequency of t = log(Total number of documents / * Number of documents in which t occurs) */ static void rank_func(sqlite3_context *pctx, int nval, sqlite3_value **apval) { inverse_document_frequency *idf = sqlite3_user_data(pctx); double tf = 0.0; const unsigned int *matchinfo; int ncol; int nphrase; int iphrase; int ndoc; int doclen = 0; const double k = 3.75; /* Check that the number of arguments passed to this function is correct. */ assert(nval == 1); matchinfo = (const unsigned int *) sqlite3_value_blob(apval[0]); nphrase = matchinfo[0]; ncol = matchinfo[1]; ndoc = matchinfo[2 + 3 * ncol * nphrase + ncol]; for (iphrase = 0; iphrase < nphrase; iphrase++) { int icol; const unsigned int *phraseinfo = &matchinfo[2 + ncol+ iphrase * ncol * 3]; for(icol = 1; icol < ncol; icol++) { /* nhitcount: number of times the current phrase occurs in the current * column in the current document. * nglobalhitcount: number of times current phrase occurs in the current * column in all documents. * ndocshitcount: number of documents in which the current phrase * occurs in the current column at least once. */ int nhitcount = phraseinfo[3 * icol]; int nglobalhitcount = phraseinfo[3 * icol + 1]; int ndocshitcount = phraseinfo[3 * icol + 2]; doclen = matchinfo[2 + icol ]; double weight = col_weights[icol - 1]; if (idf->status == 0 && ndocshitcount) idf->value += log(((double)ndoc / ndocshitcount))* weight; /* Dividing the tf by document length to normalize the effect of * longer documents. */ if (nglobalhitcount > 0 && nhitcount) tf += (((double)nhitcount * weight) / (nglobalhitcount * doclen)); } } idf->status = 1; /* Final score = (tf * idf)/ ( k + tf) * Dividing by k+ tf further normalizes the weight leading to better * results. * The value of k is experimental */ double score = (tf * idf->value/ ( k + tf)) ; sqlite3_result_double(pctx, score); return; }
static int vtxt_column (sqlite3_vtab_cursor * pCursor, sqlite3_context * pContext, int column) { /* fetching value for the Nth column */ int nCol = 1; int i; char buf[4096]; int type; const char *value; VirtualTextCursorPtr cursor = (VirtualTextCursorPtr) pCursor; gaiaTextReaderPtr text = cursor->pVtab->reader; if (column == 0) { /* the ROWNO column */ sqlite3_result_int (pContext, cursor->current_row); return SQLITE_OK; } if (text->current_line_ready == 0) return SQLITE_ERROR; for (i = 0; i < text->max_fields; i++) { if (nCol == column) { if (!gaiaTextReaderFetchField (text, i, &type, &value)) sqlite3_result_null (pContext); else { if (type == VRTTXT_INTEGER) { strcpy (buf, value); text_clean_integer (buf); #if defined(_WIN32) || defined(__MINGW32__) /* CAVEAT - M$ runtime has non-standard functions for 64 bits */ sqlite3_result_int64 (pContext, _atoi64 (buf)); #else sqlite3_result_int64 (pContext, atoll (buf)); #endif } else if (type == VRTTXT_DOUBLE) { strcpy (buf, value); text_clean_double (buf); sqlite3_result_double (pContext, atof (buf)); } else if (type == VRTTXT_TEXT) sqlite3_result_text (pContext, value, strlen (value), free); else sqlite3_result_null (pContext); } } nCol++; } return SQLITE_OK; }
static void OGR2SQLITE_ogr_geocode_set_result(sqlite3_context* pContext, OGRLayerH hLayer, const char* pszField) { if( hLayer == NULL ) sqlite3_result_null (pContext); else { OGRLayer* poLayer = (OGRLayer*)hLayer; OGRFeatureDefn* poFDefn = poLayer->GetLayerDefn(); OGRFeature* poFeature = poLayer->GetNextFeature(); int nIdx = -1; if( poFeature == NULL ) sqlite3_result_null (pContext); else if( strcmp(pszField, "geometry") == 0 && poFeature->GetGeometryRef() != NULL ) { GByte* pabyGeomBLOB = NULL; int nGeomBLOBLen = 0; if( OGRSQLiteLayer::ExportSpatiaLiteGeometry( poFeature->GetGeometryRef(), 4326, wkbNDR, FALSE, FALSE, FALSE, &pabyGeomBLOB, &nGeomBLOBLen ) != CE_None ) { sqlite3_result_null (pContext); } else { sqlite3_result_blob (pContext, pabyGeomBLOB, nGeomBLOBLen, CPLFree); } } else if( (nIdx = poFDefn->GetFieldIndex(pszField)) >= 0 && poFeature->IsFieldSet(nIdx) ) { OGRFieldType eType = poFDefn->GetFieldDefn(nIdx)->GetType(); if( eType == OFTInteger ) sqlite3_result_int(pContext, poFeature->GetFieldAsInteger(nIdx)); else if( eType == OFTInteger64 ) sqlite3_result_int64(pContext, poFeature->GetFieldAsInteger64(nIdx)); else if( eType == OFTReal ) sqlite3_result_double(pContext, poFeature->GetFieldAsDouble(nIdx)); else sqlite3_result_text(pContext, poFeature->GetFieldAsString(nIdx), -1, SQLITE_TRANSIENT); } else sqlite3_result_null (pContext); delete poFeature; OGRGeocodeFreeResult(hLayer); } }
extern void ora_sinh(sqlite3_context * context, int argc, sqlite3_value ** argv) { double number; if (ksu_prm_ok(context, argc, argv, "sinh", KSU_PRM_NUMERIC)) { number = sqlite3_value_double(argv[0]); sqlite3_result_double(context, sinh(number)); } }
static void calculateDistance(sqlite3_context *ctx, int argc, sqlite3_value **argv) { double distance = 0; double lat1 = radians(sqlite3_value_double(argv[0])); double lon1 = radians(sqlite3_value_double(argv[1])); double lat2 = radians(sqlite3_value_double(argv[2])); double lon2 = radians(sqlite3_value_double(argv[3])); distance = acos( sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(lon2 - lon1) ); distance = (distance < 0 ? distance + M_PI : distance ) * EARTH_RADIUS; sqlite3_result_double(ctx, distance); }
/* * Returns the tangent of the first argument. */ extern void ora_tan(sqlite3_context * context, int argc, sqlite3_value ** argv) { double val; if (ksu_prm_ok(context, argc, argv, "tan", KSU_PRM_NUMERIC)) { val = sqlite3_value_double(argv[0]); sqlite3_result_double(context, tan(val)); } }
static void sumFinalize(sqlite3_context *context){ SumCtx *p; p = sqlite3_aggregate_context(context, 0); if( p && p->cnt>0 ){ if( p->approx ){ sqlite3_result_double(context, p->sum); }else{ sqlite3_result_int64(context, (i64)p->sum); } } }
/* ** julianday( TIMESTRING, MOD, MOD, ...) ** ** Return the julian day number of the date specified in the arguments */ static void juliandayFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ DateTime x; if( isDate(context, argc, argv, &x)==0 ){ computeJD(&x); sqlite3_result_double(context, x.iJD/86400000.0); } }
ikptr ik_sqlite3_result_double (ikptr s_context, ikptr s_retval, ikpcb * pcb) { #ifdef HAVE_SQLITE3_RESULT_DOUBLE sqlite3_context * context = IK_SQLITE_CONTEXT(s_context); double retval = IK_FLONUM_DATA(s_retval); sqlite3_result_double(context, retval); return IK_VOID_OBJECT; #else feature_failure(__func__); #endif }
SQLITE_EXTENSION_INIT1 /* ** The half() SQL function returns half of its input value. */ static void halfFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ sqlite3_result_double(context, 0.5*sqlite3_value_double(argv[0])); }
/* * ** SQLite user defined function to use with matchinfo() to calculate the * ** relevancy of an FTS match. The value returned is the relevancy score * ** (a real value greater than or equal to zero). A larger value indicates * ** a more relevant document. * ** * ** The overall relevancy returned is the sum of the relevancies of each * ** column value in the FTS table. The relevancy of a column value is the * ** sum of the following for each reportable phrase in the FTS query: * ** * ** (<hit count> / <global hit count>) * <column weight> * ** * ** where <hit count> is the number of instances of the phrase in the * ** column value of the current row and <global hit count> is the number * ** of instances of the phrase in the same column of all rows in the FTS * ** table. The <column weight> is a weighting factor assigned to each * ** column by the caller (see below). * ** * ** The first argument to this function must be the return value of the FTS * ** matchinfo() function. Following this must be one argument for each column * ** of the FTS table containing a numeric weight factor for the corresponding * ** column. Example: * ** * ** CREATE VIRTUAL TABLE documents USING fts3(title, content) * ** * ** The following query returns the docids of documents that match the full-text * ** query <query> sorted from most to least relevant. When calculating * ** relevance, query term instances in the 'title' column are given twice the * ** weighting of those in the 'content' column. * ** * ** SELECT docid FROM documents * ** WHERE documents MATCH <query> * ** ORDER BY rank(matchinfo(documents), 1.0, 0.5) DESC * */ static void rank(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal) { int *aMatchinfo; /* Return value of matchinfo() */ int nCol; /* Number of columns in the table */ int nPhrase; /* Number of phrases in the query */ int iPhrase; /* Current phrase */ double score = 0.0; /* Value to return */ //assert( sizeof(int)==4 ); /* Check that the number of arguments passed to this function is correct. * ** If not, jump to wrong_number_args. Set aMatchinfo to point to the array * ** of unsigned integer values returned by FTS function matchinfo. Set * ** nPhrase to contain the number of reportable phrases in the users full-text * ** query, and nCol to the number of columns in the table. * */ //if ( nVal<1 ) goto wrong_number_args; //aMatchinfo = (unsigned int *)sqlite3_value_blob(apVal[0]); aMatchinfo = (int *)sqlite3_value_blob(apVal[0]); nPhrase = aMatchinfo[0]; nCol = aMatchinfo[1]; //if( nVal!=(1+nCol) ) goto wrong_number_args; /* Iterate through each phrase in the users query. */ for(iPhrase=0; iPhrase<nPhrase; iPhrase++){ int iCol; /* Current column */ /* Now iterate through each column in the users query. For each column, * ** increment the relevancy score by: * ** * ** (<hit count> / <global hit count>) * <column weight> * ** * ** aPhraseinfo[] points to the start of the data for phrase iPhrase. So * ** the hit count and global hit counts for each column are found in * ** aPhraseinfo[iCol*3] and aPhraseinfo[iCol*3+1], respectively. * */ int *aPhraseinfo = &aMatchinfo[2 + iPhrase*nCol*3]; for(iCol=0; iCol<nCol; iCol++){ int nHitCount = aPhraseinfo[3*iCol]; int nGlobalHitCount = aPhraseinfo[3*iCol+1]; double weight = sqlite3_value_double(apVal[iCol+1]); if( nHitCount>0 ){ score += ((double)nHitCount / (double)nGlobalHitCount) * weight; } } } sqlite3_result_double(pCtx, score); return; }
static int vdbf_column (sqlite3_vtab_cursor * pCursor, sqlite3_context * pContext, int column) { /* fetching value for the Nth column */ int nCol = 1; gaiaDbfFieldPtr pFld; VirtualDbfCursorPtr cursor = (VirtualDbfCursorPtr) pCursor; if (column == 0) { /* the PRIMARY KEY column */ sqlite3_result_int (pContext, cursor->current_row); return SQLITE_OK; } pFld = cursor->pVtab->dbf->Dbf->First; while (pFld) { /* column values */ if (nCol == column) { if (!(pFld->Value)) sqlite3_result_null (pContext); else { switch (pFld->Value->Type) { case GAIA_INT_VALUE: sqlite3_result_int64 (pContext, pFld->Value->IntValue); break; case GAIA_DOUBLE_VALUE: sqlite3_result_double (pContext, pFld->Value->DblValue); break; case GAIA_TEXT_VALUE: sqlite3_result_text (pContext, pFld->Value->TxtValue, strlen (pFld->Value->TxtValue), SQLITE_STATIC); break; default: sqlite3_result_null (pContext); break; } } break; } nCol++; pFld = pFld->Next; } return SQLITE_OK; }
SQLITE_EXTENSION_INIT1 /* ** The sqr() SQL function returns the square of its input value. */ static void sqrFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ double r = sqlite3_value_double(argv[0]); sqlite3_result_double(context, r*r); }
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); } } }