/* Methods for the fuzzer module */ static int fuzzerConnect( sqlite3 db, object pAux, int argc, string[] argv, out sqlite3_vtab ppVtab, out string pzErr ) { fuzzer_vtab pNew; int n; if (!argv[1].StartsWith("temp", StringComparison.CurrentCultureIgnoreCase)) { pzErr = sqlite3_mprintf("%s virtual tables must be TEMP", argv[0]); ppVtab = null; return(SQLITE_ERROR); } //n = strlen(argv[0]) + 1; pNew = new fuzzer_vtab();//sqlite3_malloc( sizeof(pNew) + n ); //if( pNew==0 ) return SQLITE_NOMEM; //pNew.zClassName = (char*)&pNew[1]; pNew.zClassName = argv[0];//memcpy(pNew.zClassName, argv[0], n); sqlite3_declare_vtab(db, "CREATE TABLE x(word,distance,cFrom,cTo,cost)"); //memset(pNew, 0, sizeof(pNew)); pzErr = ""; ppVtab = pNew; return(SQLITE_OK); }
static int tclvarBestIndex(sqlite3_vtab tab, ref sqlite3_index_info pIdxInfo) { int ii; for (ii = 0; ii < pIdxInfo.nConstraint; ii++) { sqlite3_index_constraint pCons = pIdxInfo.aConstraint[ii]; if (pCons.iColumn == 0 && pCons.usable && pCons.op == SQLITE_INDEX_CONSTRAINT_EQ) { sqlite3_index_constraint_usage pUsage = new sqlite3_index_constraint_usage(); pUsage = pIdxInfo.aConstraintUsage[ii]; pUsage.omit = false; pUsage.argvIndex = 1; return(SQLITE_OK); } } for (ii = 0; ii < pIdxInfo.nConstraint; ii++) { sqlite3_index_constraint pCons = pIdxInfo.aConstraint[ii]; if (pCons.iColumn == 0 && pCons.usable && pCons.op == SQLITE_INDEX_CONSTRAINT_MATCH) { sqlite3_index_constraint_usage pUsage = new sqlite3_index_constraint_usage(); pUsage = pIdxInfo.aConstraintUsage[ii]; pUsage.omit = true; pUsage.argvIndex = 1; return(SQLITE_OK); } } return(SQLITE_OK); }
/* The xDisconnect and xDestroy methods are also the same */ /* ** Open a new tclvar cursor. */ static int tclvarOpen(sqlite3_vtab pVTab, out sqlite3_vtab_cursor ppCursor) { //tclvar_cursor pCur; //pCur = sqlite3MallocZero(sizeof(tclvar_cursor)); //*ppCursor = pCur.base; ppCursor = new tclvar_cursor(); return(SQLITE_OK); }
/* ** External API function used to create a new virtual-table module. */ static int sqlite3_create_module_v2( sqlite3 db, /* Database in which module is registered */ string zName, /* Name assigned to this module */ sqlite3_module pModule, /* The definition of the module */ sqlite3_vtab pAux, /* Context pointer for xCreate/xConnect */ smdxDestroy xDestroy /* Module destructor function */ ) { return(createModule(db, zName, pModule, pAux, xDestroy)); }
/* The xDisconnect and xDestroy methods are also the same */ /* ** Open a new wholenumber cursor. */ static int wholenumberOpen(sqlite3_vtab p, out sqlite3_vtab_cursor ppCursor) { wholenumber_cursor pCur; pCur = new wholenumber_cursor();//sqlite3_malloc( sizeof(*pCur) ); //if ( pCur == null ) // return SQLITE_NOMEM; //memset(pCur, 0, sizeof(*pCur)); ppCursor = pCur;//.base; return(SQLITE_OK); }
/* ** Open a new cursor on the schema table. */ static int schemaOpen(sqlite3_vtab pVTab, out sqlite3_vtab_cursor ppCursor) { int rc = SQLITE_NOMEM; schema_cursor pCur; pCur = new schema_cursor();//pCur = sqlite3_malloc(sizeof(schema_cursor)); //if ( pCur != null ) //{ //memset(pCur, 0, sizeof(schema_cursor)); ppCursor = (sqlite3_vtab_cursor)pCur; rc = SQLITE_OK; //} return(rc); }
/* ** Open a new cursor on the intarray table. */ static int intarrayOpen(sqlite3_vtab pVTab, out sqlite3_vtab_cursor ppCursor) { int rc = SQLITE_NOMEM; intarray_cursor pCur = new intarray_cursor();// //pCur = sqlite3_malloc(sizeof(intarray_cursor)); //if ( pCur != null ) { //memset(pCur, 0, sizeof(intarray_cursor)); ppCursor = (sqlite3_vtab_cursor)pCur; rc = SQLITE_OK; } return(rc); }
/* Methods for the wholenumber module */ static int wholenumberConnect( sqlite3 db, object pAux, int argc, string[] argv, out sqlite3_vtab ppVtab, out string pzErr ) { sqlite3_vtab pNew; pNew = ppVtab = new sqlite3_vtab();//sqlite3_malloc( sizeof(*pNew) ); //if ( pNew == null ) // return SQLITE_NOMEM; sqlite3_declare_vtab( db, "CREATE TABLE x(value)" ); //memset(pNew, 0, sizeof(*pNew)); pzErr = ""; return SQLITE_OK; }
/* Methods for the wholenumber module */ static int wholenumberConnect( sqlite3 db, object pAux, int argc, string[] argv, out sqlite3_vtab ppVtab, out string pzErr ) { sqlite3_vtab pNew; pNew = ppVtab = new sqlite3_vtab();//sqlite3_malloc( sizeof(*pNew) ); //if ( pNew == null ) // return SQLITE_NOMEM; sqlite3_declare_vtab(db, "CREATE TABLE x(value)"); //memset(pNew, 0, sizeof(*pNew)); pzErr = ""; return(SQLITE_OK); }
/* Methods for the tclvar module */ static int tclvarConnect( sqlite3 db, object pAux, int argc, string[] argv, out sqlite3_vtab ppVtab, out string pzErr ){ tclvar_vtab pVtab; string zSchema = "CREATE TABLE whatever(name TEXT, arrayname TEXT, value TEXT)"; pVtab = new tclvar_vtab();//sqlite3MallocZero( sizeof(*pVtab) ); //if( pVtab==0 ) return SQLITE_NOMEM; ppVtab = pVtab;//*ppVtab = pVtab.base; pVtab.interp = (Tcl_Interp)pAux; sqlite3_declare_vtab(db, zSchema); pzErr = ""; return SQLITE_OK; }
/* Methods for the tclvar module */ static int tclvarConnect( sqlite3 db, object pAux, int argc, string[] argv, out sqlite3_vtab ppVtab, out string pzErr ) { tclvar_vtab pVtab; string zSchema = "CREATE TABLE whatever(name TEXT, arrayname TEXT, value TEXT)"; pVtab = new tclvar_vtab(); //sqlite3MallocZero( sizeof(*pVtab) ); //if( pVtab==0 ) return SQLITE_NOMEM; ppVtab = pVtab; //*ppVtab = pVtab.base; pVtab.interp = (Tcl_Interp)pAux; sqlite3_declare_vtab(db, zSchema); pzErr = ""; return(SQLITE_OK); }
/* ** Table constructor for the intarray module. */ static int intarrayCreate( sqlite3 db, /* Database where module is created */ object pAux, /* clientdata for the module */ int argc, /* Number of arguments */ string[] argv, /* Value for all arguments */ out sqlite3_vtab ppVtab, /* Write the new virtual table object here */ out string pzErr /* Put error message text here */ ) { int rc = SQLITE_NOMEM; intarray_vtab pVtab = new intarray_vtab();//sqlite3_malloc(sizeof(intarray_vtab)); if (pVtab != null) { //memset(pVtab, 0, sizeof(intarray_vtab)); pVtab.pContent = (sqlite3_intarray)pAux; rc = sqlite3_declare_vtab(db, "CREATE TABLE x(value INTEGER PRIMARY KEY)"); } ppVtab = (sqlite3_vtab)pVtab; pzErr = ""; return(rc); }
/* ** This function invokes either the xRollback or xCommit method ** of each of the virtual tables in the sqlite3.aVTrans array. The method ** called is identified by the second argument, "offset", which is ** the offset of the method to call in the sqlite3_module structure. ** ** The array is cleared after invoking the callbacks. */ static void callFinaliser(sqlite3 db, int offset) { int i; if (db.aVTrans != null) { for (i = 0; i < db.nVTrans; i++) { VTable pVTab = db.aVTrans[i]; sqlite3_vtab p = pVTab.pVtab; if (p != null) { //int (*x)(sqlite3_vtab ); //x = *(int (*)(sqlite3_vtab ))((char )p.pModule + offset); //if( x ) x(p); if (offset == 0) { if (p.pModule.xCommit != null) { p.pModule.xCommit(p); } } else { if (p.pModule.xRollback != null) { p.pModule.xRollback(p); } } } pVTab.iSavepoint = 0; sqlite3VtabUnlock(pVTab); } sqlite3DbFree(db, ref db.aVTrans); db.nVTrans = 0; db.aVTrans = null; } }
/* ** Invoke the xSync method of all virtual tables in the sqlite3.aVTrans ** array. Return the error code for the first error that occurs, or ** SQLITE_OK if all xSync operations are successful. ** ** Set *pzErrmsg to point to a buffer that should be released using ** sqlite3DbFree() containing an error message, if one is available. */ static int sqlite3VtabSync(sqlite3 db, ref string pzErrmsg) { int i; int rc = SQLITE_OK; VTable[] aVTrans = db.aVTrans; db.aVTrans = null; for (i = 0; rc == SQLITE_OK && i < db.nVTrans; i++) { smdxFunction x;//int (*x)(sqlite3_vtab ); sqlite3_vtab pVtab = aVTrans[i].pVtab; if (pVtab != null && (x = pVtab.pModule.xSync) != null) { rc = x(pVtab); //sqlite3DbFree(db, ref pzErrmsg); pzErrmsg = pVtab.zErrMsg; // sqlite3DbStrDup( db, pVtab.zErrMsg ); pVtab.zErrMsg = null; //sqlite3_free( ref pVtab.zErrMsg ); } } db.aVTrans = aVTrans; return(rc); }
/* ** Open a new fuzzer cursor. */ static int fuzzerOpen(sqlite3_vtab pVTab, out sqlite3_vtab_cursor ppCursor) { fuzzer_vtab p = (fuzzer_vtab)pVTab; fuzzer_cursor pCur; pCur = new fuzzer_cursor();//= sqlite3_malloc( sizeof(pCur) ); ///if( pCur==0 ) return SQLITE_NOMEM; //memset(pCur, 0, sizeof(pCur)); pCur.pVtab = p; ppCursor = pCur; if (p.nCursor == 0 && p.pNewRule != null) { uint i; fuzzer_rule pX; fuzzer_rule[] a = new fuzzer_rule[15]; //for(i=0; i<sizeof(a)/sizeof(a[0]); i++) a[i] = 0; while ((pX = p.pNewRule) != null) { p.pNewRule = pX.pNext; pX.pNext = null; for (i = 0; a[i] != null && i < a.Length; i++)//<sizeof(a)/sizeof(a[0])-1; i++) { pX = fuzzerMergeRules(a[i], pX); a[i] = null; } a[i] = fuzzerMergeRules(a[i], pX); } for (pX = a[0], i = 1; i < a.Length; i++)//sizeof(a)/sizeof(a[0]); i++) { pX = fuzzerMergeRules(a[i], pX); } p.pRule = fuzzerMergeRules(p.pRule, pX); } p.nCursor++; return(SQLITE_OK); }
/* ** Table constructor for the schema module. */ static int schemaCreate( sqlite3 db, object pAux, int argc, string[] argv, out sqlite3_vtab ppVtab, out string pzErr ) { int rc = SQLITE_NOMEM; schema_vtab pVtab = new schema_vtab();//sqlite3_malloc(sizeof(schema_vtab)); if (pVtab != null) { //memset(pVtab, 0, sizeof(schema_vtab)); pVtab.db = db; #if !SQLITE_OMIT_VIRTUALTABLE rc = sqlite3_declare_vtab(db, SCHEMA); #endif } ppVtab = (sqlite3_vtab)pVtab; pzErr = ""; return(rc); }
/* ** Analyse the WHERE condition. */ static int intarrayBestIndex( sqlite3_vtab tab, ref sqlite3_index_info pIdxInfo ) { return SQLITE_OK; }
/* ** Echo virtual table module xOpen method. */ static int echoOpen( sqlite3_vtab pVTab, out sqlite3_vtab_cursor ppCursor ) { echo_cursor pCur; if ( simulateVtabError( (echo_vtab)pVTab, "xOpen" ) != 0 ) { ppCursor = null; return SQLITE_ERROR; } pCur = new echo_cursor();//sqlite3MallocZero( sizeof( echo_cursor ) ); ppCursor = (sqlite3_vtab_cursor)pCur; return ( pCur != null ? SQLITE_OK : SQLITE_NOMEM ); }
/* ** Table constructor for the schema module. */ static int schemaCreate( sqlite3 db, object pAux, int argc, string[] argv, out sqlite3_vtab ppVtab, out string pzErr ) { int rc = SQLITE_NOMEM; schema_vtab pVtab = new schema_vtab();//sqlite3_malloc(sizeof(schema_vtab)); if ( pVtab != null ) { //memset(pVtab, 0, sizeof(schema_vtab)); pVtab.db = db; #if !SQLITE_OMIT_VIRTUALTABLE rc = sqlite3_declare_vtab( db, SCHEMA ); #endif } ppVtab = (sqlite3_vtab)pVtab; pzErr = ""; return rc; }
static int echoRename( sqlite3_vtab vtab, string zNewName ) { int rc = SQLITE_OK; echo_vtab p = (echo_vtab)vtab; if ( simulateVtabError( p, "xRename" ) != 0 ) { return SQLITE_ERROR; } if ( p.isPattern != 0 ) { int nThis = p.zThis.Length; string zSql = sqlite3_mprintf( "ALTER TABLE %s RENAME TO %s%s", p.zTableName, zNewName, p.zTableName.Substring(nThis) ); rc = sqlite3_exec( p.db, zSql, 0, 0, 0 ); //sqlite3_free( zSql ); } return rc; }
/* ** Echo virtual table module xCreate method. */ static int echoCreate( sqlite3 db, object pAux, int argc, string[] argv, out sqlite3_vtab ppVtab, out string pzErr ) { int rc = SQLITE_OK; appendToEchoModule( ( (EchoModule)pAux ).interp, "xCreate" ); rc = echoConstructor( db, pAux, argc, argv, out ppVtab, out pzErr ); /* If there were two arguments passed to the module at the SQL level ** (i.e. "CREATE VIRTUAL TABLE tbl USING echo(arg1, arg2)"), then ** the second argument is used as a table name. Attempt to create ** such a table with a single column, "logmsg". This table will ** be used to log calls to the xUpdate method. It will be deleted ** when the virtual table is DROPed. ** ** Note: The main point of this is to test that we can drop tables ** from within an xDestroy method call. */ if ( rc == SQLITE_OK && argc == 5 ) { string zSql; echo_vtab pVtab = (echo_vtab)ppVtab; pVtab.zLogName = sqlite3_mprintf( "%s", argv[4] ); zSql = sqlite3_mprintf( "CREATE TABLE %Q(logmsg)", pVtab.zLogName ); rc = sqlite3_exec( db, zSql, 0, 0, 0 ); //sqlite3_free(zSql); if ( rc != SQLITE_OK ) { pzErr = sqlite3_mprintf( "%s", sqlite3_errmsg( db ) ); } } if ( ppVtab != null && rc != SQLITE_OK ) { //object obj = ppVtab; //echoDestructor( ref obj ); //obj = null; ppVtab = null; } if ( rc == SQLITE_OK ) { ( (echo_vtab)ppVtab ).inTransaction = 1; } return rc; }
/* Methods for the fuzzer module */ static int fuzzerConnect( sqlite3 db, object pAux, int argc, string[] argv, out sqlite3_vtab ppVtab, out string pzErr ) { fuzzer_vtab pNew; int n; if ( !argv[1].StartsWith( "temp", StringComparison.CurrentCultureIgnoreCase ) ) { pzErr = sqlite3_mprintf( "%s virtual tables must be TEMP", argv[0] ); ppVtab = null; return SQLITE_ERROR; } //n = strlen(argv[0]) + 1; pNew = new fuzzer_vtab();//sqlite3_malloc( sizeof(pNew) + n ); //if( pNew==0 ) return SQLITE_NOMEM; //pNew.zClassName = (char*)&pNew[1]; pNew.zClassName = argv[0];//memcpy(pNew.zClassName, argv[0], n); sqlite3_declare_vtab( db, "CREATE TABLE x(word,distance,cFrom,cTo,cost)" ); //memset(pNew, 0, sizeof(pNew)); pzErr = ""; ppVtab = pNew; return SQLITE_OK; }
static int echoRollback( sqlite3_vtab vtab ) { int rc; echo_vtab pVtab = (echo_vtab)vtab; /* Ticket #3083 - Only call xRollback if we have previously started ** a transaction */ Debug.Assert( pVtab.inTransaction != 0 ); rc = echoTransactionCall( vtab, "xRollback" ); pVtab.inTransaction = 0; return rc; }
/* ** Search for terms of these forms: ** ** (1) value > $value ** (2) value >= $value ** (4) value < $value ** (8) value <= $value ** ** idxNum is an ORed combination of 1 or 2 with 4 or 8. */ static int wholenumberBestIndex( sqlite3_vtab vtab, ref sqlite3_index_info pIdxInfo ) { int i; int idxNum = 0; int argvIdx = 1; int ltIdx = -1; int gtIdx = -1; sqlite3_index_constraint pConstraint; //pConstraint = pIdxInfo.aConstraint; for (i = 0; i < pIdxInfo.nConstraint; i++)//, pConstraint++) { pConstraint = pIdxInfo.aConstraint[i]; if (pConstraint.usable == false) { continue; } if ((idxNum & 3) == 0 && pConstraint.op == SQLITE_INDEX_CONSTRAINT_GT) { idxNum |= 1; ltIdx = i; } if ((idxNum & 3) == 0 && pConstraint.op == SQLITE_INDEX_CONSTRAINT_GE) { idxNum |= 2; ltIdx = i; } if ((idxNum & 12) == 0 && pConstraint.op == SQLITE_INDEX_CONSTRAINT_LT) { idxNum |= 4; gtIdx = i; } if ((idxNum & 12) == 0 && pConstraint.op == SQLITE_INDEX_CONSTRAINT_LE) { idxNum |= 8; gtIdx = i; } } pIdxInfo.idxNum = idxNum; if (ltIdx >= 0) { pIdxInfo.aConstraintUsage[ltIdx].argvIndex = argvIdx++; pIdxInfo.aConstraintUsage[ltIdx].omit = true; } if (gtIdx >= 0) { pIdxInfo.aConstraintUsage[gtIdx].argvIndex = argvIdx; pIdxInfo.aConstraintUsage[gtIdx].omit = true; } if (pIdxInfo.nOrderBy == 1 && pIdxInfo.aOrderBy[0].desc == false ) { pIdxInfo.orderByConsumed = true; } pIdxInfo.estimatedCost = (double)1; return(SQLITE_OK); }
/* ** xBegin, xSync, xCommit and xRollback callbacks for echo module ** virtual tables. Do nothing other than add the name of the callback ** to the $::echo_module Tcl variable. */ static int echoTransactionCall( sqlite3_vtab vtab, string zCall ) { string z; echo_vtab pVtab = (echo_vtab)vtab; z = sqlite3_mprintf( "echo(%s)", pVtab.zTableName ); //if( z==null ) return SQLITE_NOMEM; appendToEchoModule( pVtab.interp, zCall ); appendToEchoModule( pVtab.interp, z ); //sqlite3_free(z); return SQLITE_OK; }
/* The xDisconnect and xDestroy methods are also the same */ /* ** Open a new tclvar cursor. */ static int tclvarOpen( sqlite3_vtab pVTab, out sqlite3_vtab_cursor ppCursor ) { //tclvar_cursor pCur; //pCur = sqlite3MallocZero(sizeof(tclvar_cursor)); //*ppCursor = pCur.base; ppCursor = new tclvar_cursor(); return SQLITE_OK; }
/* ** External API function used to create a new virtual-table module. */ static int sqlite3_create_module_v2( sqlite3 db, /* Database in which module is registered */ string zName, /* Name assigned to this module */ sqlite3_module pModule, /* The definition of the module */ sqlite3_vtab pAux, /* Context pointer for xCreate/xConnect */ smdxDestroy xDestroy /* Module destructor function */ ) { return createModule( db, zName, pModule, pAux, xDestroy ); }
/* ** Search for terms of these forms: ** ** (1) value > $value ** (2) value >= $value ** (4) value < $value ** (8) value <= $value ** ** idxNum is an ORed combination of 1 or 2 with 4 or 8. */ static int wholenumberBestIndex( sqlite3_vtab vtab, ref sqlite3_index_info pIdxInfo ) { int i; int idxNum = 0; int argvIdx = 1; int ltIdx = -1; int gtIdx = -1; sqlite3_index_constraint pConstraint; //pConstraint = pIdxInfo.aConstraint; for ( i = 0; i < pIdxInfo.nConstraint; i++ )//, pConstraint++) { pConstraint = pIdxInfo.aConstraint[i]; if ( pConstraint.usable == false ) continue; if ( ( idxNum & 3 ) == 0 && pConstraint.op == SQLITE_INDEX_CONSTRAINT_GT ) { idxNum |= 1; ltIdx = i; } if ( ( idxNum & 3 ) == 0 && pConstraint.op == SQLITE_INDEX_CONSTRAINT_GE ) { idxNum |= 2; ltIdx = i; } if ( ( idxNum & 12 ) == 0 && pConstraint.op == SQLITE_INDEX_CONSTRAINT_LT ) { idxNum |= 4; gtIdx = i; } if ( ( idxNum & 12 ) == 0 && pConstraint.op == SQLITE_INDEX_CONSTRAINT_LE ) { idxNum |= 8; gtIdx = i; } } pIdxInfo.idxNum = idxNum; if ( ltIdx >= 0 ) { pIdxInfo.aConstraintUsage[ltIdx].argvIndex = argvIdx++; pIdxInfo.aConstraintUsage[ltIdx].omit = true; } if ( gtIdx >= 0 ) { pIdxInfo.aConstraintUsage[gtIdx].argvIndex = argvIdx; pIdxInfo.aConstraintUsage[gtIdx].omit = true; } if ( pIdxInfo.nOrderBy == 1 && pIdxInfo.aOrderBy[0].desc == false ) { pIdxInfo.orderByConsumed = true; } pIdxInfo.estimatedCost = (double)1; return SQLITE_OK; }
static int tclvarBestIndex( sqlite3_vtab tab, ref sqlite3_index_info pIdxInfo ) { int ii; for(ii=0; ii<pIdxInfo.nConstraint; ii++){ sqlite3_index_constraint pCons = pIdxInfo.aConstraint[ii]; if( pCons.iColumn==0 && pCons.usable && pCons.op==SQLITE_INDEX_CONSTRAINT_EQ ){ sqlite3_index_constraint_usage pUsage = new sqlite3_index_constraint_usage(); pUsage = pIdxInfo.aConstraintUsage[ii]; pUsage.omit = false; pUsage.argvIndex = 1; return SQLITE_OK; } } for(ii=0; ii<pIdxInfo.nConstraint; ii++){ sqlite3_index_constraint pCons = pIdxInfo.aConstraint[ii]; if( pCons.iColumn==0 && pCons.usable && pCons.op==SQLITE_INDEX_CONSTRAINT_MATCH ){ sqlite3_index_constraint_usage pUsage = new sqlite3_index_constraint_usage(); pUsage = pIdxInfo.aConstraintUsage[ii]; pUsage.omit = true; pUsage.argvIndex = 1; return SQLITE_OK; } } return SQLITE_OK; }
/* ** Open a new fuzzer cursor. */ static int fuzzerOpen( sqlite3_vtab pVTab, out sqlite3_vtab_cursor ppCursor ) { fuzzer_vtab p = (fuzzer_vtab)pVTab; fuzzer_cursor pCur; pCur = new fuzzer_cursor();//= sqlite3_malloc( sizeof(pCur) ); ///if( pCur==0 ) return SQLITE_NOMEM; //memset(pCur, 0, sizeof(pCur)); pCur.pVtab = p; ppCursor = pCur; if ( p.nCursor == 0 && p.pNewRule != null ) { uint i; fuzzer_rule pX; fuzzer_rule[] a = new fuzzer_rule[15]; //for(i=0; i<sizeof(a)/sizeof(a[0]); i++) a[i] = 0; while ( ( pX = p.pNewRule ) != null ) { p.pNewRule = pX.pNext; pX.pNext = null; for ( i = 0; a[i] != null && i < a.Length; i++ )//<sizeof(a)/sizeof(a[0])-1; i++) { pX = fuzzerMergeRules( a[i], pX ); a[i] = null; } a[i] = fuzzerMergeRules( a[i], pX ); } for ( pX = a[0], i = 1; i < a.Length; i++ )//sizeof(a)/sizeof(a[0]); i++) { pX = fuzzerMergeRules( a[i], pX ); } p.pRule = fuzzerMergeRules( p.pRule, pX ); } p.nCursor++; return SQLITE_OK; }
/// <summary> /// Transfer error message text from an sqlite3_vtab.zErrMsg (text stored /// in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored /// in memory obtained from sqlite3DbMalloc). /// </summary> static void importVtabErrMsg(Vdbe p, sqlite3_vtab pVtab) { sqlite3 db = p.db; sqlite3DbFree(db, ref p.zErrMsg); p.zErrMsg = pVtab.zErrMsg; // sqlite3DbStrDup( db, pVtab.zErrMsg ); //sqlite3_free( pVtab.zErrMsg ); pVtab.zErrMsg = null; }
static int echoSync( sqlite3_vtab vtab ) { int rc; echo_vtab pVtab = (echo_vtab)vtab; Tcl_Interp interp = pVtab.interp; string zVal; /* Ticket #3083 - Only call xSync if we have previously started a ** transaction */ Debug.Assert( pVtab.inTransaction != 0 ); if ( simulateVtabError( pVtab, "xSync" ) != 0 ) { return SQLITE_ERROR; } rc = echoTransactionCall( vtab, "xSync" ); if ( rc == SQLITE_OK ) { /* Check if the $::echo_module_sync_fail variable is defined. If it is, ** and it is set to the name of the real table underlying this virtual ** echo module table, then cause this xSync operation to fail. */ zVal = TCL.Tcl_GetVar( interp, "echo_module_sync_fail", TCL.VarFlag.GLOBAL_ONLY ).ToString(); if ( zVal != "" && 0 == zVal.CompareTo( pVtab.zTableName ) ) { rc = -1; } } return rc; }
/* ** The xUpdate method for echo module virtual tables. ** ** apData[0] apData[1] apData[2..] ** ** INTEGER DELETE ** ** INTEGER NULL (nCol args) UPDATE (do not set rowid) ** INTEGER INTEGER (nCol args) UPDATE (with SET rowid = <arg1>) ** ** NULL NULL (nCol args) INSERT INTO (automatic rowid value) ** NULL INTEGER (nCol args) INSERT (incl. rowid value) ** */ static int echoUpdate( sqlite3_vtab vtab, int nData, sqlite3_value[] apData, out sqlite_int64 pRowid ) { echo_vtab pVtab = (echo_vtab)vtab; sqlite3 db = pVtab.db; int rc = SQLITE_OK; pRowid = 0; sqlite3_stmt pStmt = null; string z = ""; /* SQL statement to execute */ int bindArgZero = 0; /* True to bind apData[0] to sql var no. nData */ int bindArgOne = 0; /* True to bind apData[1] to sql var no. 1 */ int i; /* Counter variable used by for loops */ Debug.Assert( nData == pVtab.nCol + 2 || nData == 1 ); /* Ticket #3083 - make sure we always start a transaction prior to ** making any changes to a virtual table */ Debug.Assert( pVtab.inTransaction != 0 ); if ( simulateVtabError( pVtab, "xUpdate" ) != 0 ) { return SQLITE_ERROR; } /* If apData[0] is an integer and nData>1 then do an UPDATE */ if ( nData > 1 && sqlite3_value_type( apData[0] ) == SQLITE_INTEGER ) { string zSep = " SET"; z = sqlite3_mprintf( "UPDATE %Q", pVtab.zTableName ); //if ( null == z ) //{ // rc = SQLITE_NOMEM; //} bindArgOne = ( apData[1] != null && sqlite3_value_type( apData[1] ) == SQLITE_INTEGER )?1:0; bindArgZero = 1; if ( bindArgOne != 0 ) { string_concat( ref z, " SET rowid=?1 ", 0, ref rc ); zSep = ","; } for ( i = 2; i < nData; i++ ) { if ( apData[i] == null ) continue; string_concat( ref z, sqlite3_mprintf( "%s %Q=?%d", zSep, pVtab.aCol[i - 2], i ), 1, ref rc ); zSep = ","; } string_concat( ref z, sqlite3_mprintf( " WHERE rowid=?%d", nData ), 1, ref rc ); } /* If apData[0] is an integer and nData==1 then do a DELETE */ else if ( nData == 1 && sqlite3_value_type( apData[0] ) == SQLITE_INTEGER ) { z = sqlite3_mprintf( "DELETE FROM %Q WHERE rowid = ?1", pVtab.zTableName ); //if ( null == z ) //{ // rc = SQLITE_NOMEM; //} bindArgZero = 1; } /* If the first argument is NULL and there are more than two args, INSERT */ else if ( nData > 2 && sqlite3_value_type( apData[0] ) == SQLITE_NULL ) { int ii; string zInsert = ""; string zValues = ""; zInsert = sqlite3_mprintf( "INSERT INTO %Q (", pVtab.zTableName ); //if ( null == zInsert ) //{ // rc = SQLITE_NOMEM; //} if ( sqlite3_value_type( apData[1] ) == SQLITE_INTEGER ) { bindArgOne = 1; zValues = sqlite3_mprintf( "?" ); string_concat( ref zInsert, "rowid", 0, ref rc ); } Debug.Assert( ( pVtab.nCol + 2 ) == nData ); for ( ii = 2; ii < nData; ii++ ) { string_concat( ref zInsert, sqlite3_mprintf( "%s%Q", !String.IsNullOrEmpty(zValues) ? ", " : "", pVtab.aCol[ii - 2] ), 1, ref rc ); string_concat( ref zValues, sqlite3_mprintf( "%s?%d", !String.IsNullOrEmpty( zValues ) ? ", " : "", ii ), 1, ref rc ); } string_concat( ref z, zInsert, 1, ref rc ); string_concat( ref z, ") VALUES(", 0, ref rc ); string_concat( ref z, zValues, 1, ref rc ); string_concat( ref z, ")", 0, ref rc ); } /* Anything else is an error */ else { Debug.Assert( false ); return SQLITE_ERROR; } if ( rc == SQLITE_OK ) { rc = sqlite3_prepare( db, z, -1, ref pStmt, 0 ); } Debug.Assert( rc != SQLITE_OK || pStmt != null ); //sqlite3_free(z); if ( rc == SQLITE_OK ) { if ( bindArgZero != 0 ) { sqlite3_bind_value( pStmt, nData, apData[0] ); } if ( bindArgOne != 0 ) { sqlite3_bind_value( pStmt, 1, apData[1] ); } for ( i = 2; i < nData && rc == SQLITE_OK; i++ ) { if ( apData[i] != null ) rc = sqlite3_bind_value( pStmt, i, apData[i] ); } if ( rc == SQLITE_OK ) { sqlite3_step( pStmt ); rc = sqlite3_finalize( pStmt ); } else { sqlite3_finalize( pStmt ); } } if (/* pRowid != 0 && */ rc == SQLITE_OK ) { pRowid = sqlite3_last_insert_rowid( db ); } if ( rc != SQLITE_OK ) { vtab.zErrMsg = sqlite3_mprintf( "echo-vtab-error: %s", sqlite3_errmsg( db ) ); } return rc; }
/* ** Open a new cursor on the schema table. */ static int schemaOpen( sqlite3_vtab pVTab, out sqlite3_vtab_cursor ppCursor ) { int rc = SQLITE_NOMEM; schema_cursor pCur; pCur = new schema_cursor();//pCur = sqlite3_malloc(sizeof(schema_cursor)); //if ( pCur != null ) //{ //memset(pCur, 0, sizeof(schema_cursor)); ppCursor = (sqlite3_vtab_cursor)pCur; rc = SQLITE_OK; //} return rc; }
static int echoBegin( sqlite3_vtab vtab ) { int rc; echo_vtab pVtab = (echo_vtab)vtab; Tcl_Interp interp = pVtab.interp; string zVal; /* Ticket #3083 - do not start a transaction if we are already in ** a transaction */ Debug.Assert( 0 == pVtab.inTransaction ); if ( simulateVtabError( pVtab, "xBegin" ) != 0 ) { return SQLITE_ERROR; } rc = echoTransactionCall( vtab, "xBegin" ); if ( rc == SQLITE_OK ) { /* Check if the $::echo_module_begin_fail variable is defined. If it is, ** and it is set to the name of the real table underlying this virtual ** echo module table, then cause this xSync operation to fail. */ zVal = TCL.Tcl_GetVar( interp, "echo_module_begin_fail", TCL.VarFlag.GLOBAL_ONLY ).ToString(); if ( zVal != null && 0 == zVal.CompareTo( pVtab.zTableName ) ) { rc = SQLITE_ERROR; } } if ( rc == SQLITE_OK ) { pVtab.inTransaction = 1; } return rc; }
/* ** There is no "best-index". This virtual table always does a linear ** scan of the binary VFS log file. */ static int statBestIndex( sqlite3_vtab tab, ref sqlite3_index_info pIdxInfo ) { /* Records are always returned in ascending order of (name, path). ** If this will satisfy the client, set the orderByConsumed flag so that ** SQLite does not do an external sort. */ if ( ( pIdxInfo.nOrderBy == 1 && pIdxInfo.aOrderBy[0].iColumn == 0 && pIdxInfo.aOrderBy[0].desc == false ) || ( pIdxInfo.nOrderBy == 2 && pIdxInfo.aOrderBy[0].iColumn == 0 && pIdxInfo.aOrderBy[0].desc == false && pIdxInfo.aOrderBy[1].iColumn == 1 && pIdxInfo.aOrderBy[1].desc == false ) ) { pIdxInfo.orderByConsumed = true; } pIdxInfo.estimatedCost = 10.0; return SQLITE_OK; }
static int echoCommit( sqlite3_vtab vtab ) { echo_vtab pVtab = (echo_vtab)vtab; int rc; /* Ticket #3083 - Only call xCommit if we have previously started ** a transaction */ Debug.Assert( pVtab.inTransaction != 0 ); if ( simulateVtabError( pVtab, "xCommit" ) != 0 ) { return SQLITE_ERROR; } sqlite3BeginBenignMalloc(); rc = echoTransactionCall( vtab, "xCommit" ); sqlite3EndBenignMalloc(); pVtab.inTransaction = 0; return rc; }
/* ** Open a new statvfs cursor. */ static int statOpen( sqlite3_vtab pVTab, out sqlite3_vtab_cursor ppCursor ) { StatTable pTab = (StatTable)pVTab; StatCursor pCsr; int rc; pCsr = new StatCursor();//(StatCursor )sqlite3_malloc(sizeof(StatCursor)); //memset(pCsr, 0, sizeof(StatCursor)); pCsr.pVtab = pVTab; rc = sqlite3_prepare_v2( pTab.db, "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type" + " UNION ALL " + "SELECT name, rootpage, type FROM sqlite_master WHERE rootpage!=0" + " ORDER BY name", -1, ref pCsr.pStmt, 0 ); if ( rc != SQLITE_OK ) { pCsr = null;//sqlite3_free( pCsr ); ppCursor = null; return rc; } ppCursor = (sqlite3_vtab_cursor)pCsr; return SQLITE_OK; }
/* ** This is the xFindFunction implementation for the echo module. ** SQLite calls this routine when the first argument of a function ** is a column of an echo virtual table. This routine can optionally ** override the implementation of that function. It will choose to ** do so if the function is named "glob", and a TCL command named ** ::echo_glob_overload exists. */ static int echoFindFunction( sqlite3_vtab vtab, int nArg, string zFuncName, ref dxFunc pxFunc, //void (**pxFunc)(sqlite3_context*,int,sqlite3_value), ref object ppArg ) { echo_vtab pVtab = (echo_vtab)vtab; Tcl_Interp interp = pVtab.interp; Tcl_CmdInfo info; if ( !zFuncName.StartsWith( "glob", StringComparison.InvariantCultureIgnoreCase ) ) { return 0; } TCL.Tcl_GetCommandInfo( interp, "::echo_glob_overload", out info ); if ( info ==null) { return 0; } pxFunc = overloadedGlobFunction; ppArg = interp; return 1; }
/* ** Analyse the WHERE condition. */ static int schemaBestIndex(sqlite3_vtab tab, ref sqlite3_index_info pIdxInfo) { return(SQLITE_OK); }
/* ** This function is called to do the work of the xConnect() method - ** to allocate the required in-memory structures for a newly connected ** virtual table. */ static int echoConstructor( sqlite3 db, object pAux, int argc, string[] argv, out sqlite3_vtab ppVtab, out string pzErr ) { int rc; int i; echo_vtab pVtab; pzErr = ""; /* Allocate the sqlite3_vtab/echo_vtab structure itself */ pVtab = new echo_vtab();//sqlite3MallocZero( sizeof(*pVtab) ); //if( null==pVtab ){ // return SQLITE_NOMEM; //} pVtab.interp = ( (EchoModule)pAux ).interp; pVtab.db = db; /* Allocate echo_vtab.zThis */ pVtab.zThis = sqlite3_mprintf( "%s", argv[2] ); //if( null==pVtab.zThis ){ // object obj = ppVtab; // echoDestructor( ref obj ); // obj = null; // return SQLITE_NOMEM; //} /* Allocate echo_vtab.zTableName */ if ( argc > 3 ) { pVtab.zTableName = sqlite3_mprintf( "%s", argv[3] ); dequoteString( ref pVtab.zTableName ); if ( !String.IsNullOrEmpty( pVtab.zTableName ) && pVtab.zTableName[0] == '*' ) { string z = sqlite3_mprintf( "%s%s", argv[2], ( pVtab.zTableName.Substring(1) ) ); //sqlite3_free(pVtab.zTableName); pVtab.zTableName = z; pVtab.isPattern = 1; } //if( null==pVtab.zTableName ){ // object obj = ppVtab; // echoDestructor( ref obj ); // obj = null; // return SQLITE_NOMEM; //} } /* Log the arguments to this function to Tcl var ::echo_module */ for ( i = 0; i < argc; i++ ) { appendToEchoModule( pVtab.interp, argv[i] ); } /* Invoke sqlite3_declare_vtab and set up other members of the echo_vtab ** structure. If an error occurs, delete the sqlite3_vtab structure and ** return an error code. */ rc = echoDeclareVtab( pVtab, db ); if ( rc != SQLITE_OK ) { //object obj = ppVtab; //echoDestructor( ref obj ); //obj = null; ppVtab = null; return rc; } /* Success. Set ppVtab and return */ ppVtab = pVtab;//.base; return SQLITE_OK; }
/* ** Table constructor for the intarray module. */ static int intarrayCreate( sqlite3 db, /* Database where module is created */ object pAux, /* clientdata for the module */ int argc, /* Number of arguments */ string[] argv, /* Value for all arguments */ out sqlite3_vtab ppVtab, /* Write the new virtual table object here */ out string pzErr /* Put error message text here */ ) { int rc = SQLITE_NOMEM; intarray_vtab pVtab = new intarray_vtab();//sqlite3_malloc(sizeof(intarray_vtab)); if ( pVtab != null ) { //memset(pVtab, 0, sizeof(intarray_vtab)); pVtab.pContent = (sqlite3_intarray)pAux; rc = sqlite3_declare_vtab( db, "CREATE TABLE x(value INTEGER PRIMARY KEY)" ); } ppVtab = (sqlite3_vtab)pVtab; pzErr = ""; return rc; }
/* ** Echo virtual table module xConnect method. */ static int echoConnect( sqlite3 db, object pAux, int argc, string[] argv, out sqlite3_vtab ppVtab, out string pzErr ) { appendToEchoModule( ( (EchoModule)pAux ).interp, "xConnect" ); return echoConstructor( db, pAux, argc, argv, out ppVtab, out pzErr ); }
/* ** Open a new cursor on the intarray table. */ static int intarrayOpen( sqlite3_vtab pVTab, out sqlite3_vtab_cursor ppCursor ) { int rc = SQLITE_NOMEM; intarray_cursor pCur = new intarray_cursor();// //pCur = sqlite3_malloc(sizeof(intarray_cursor)); //if ( pCur != null ) { //memset(pCur, 0, sizeof(intarray_cursor)); ppCursor = (sqlite3_vtab_cursor)pCur; rc = SQLITE_OK; } return rc; }
/* ** The echo module implements the subset of query constraints and sort ** orders that may take advantage of SQLite indices on the underlying ** real table. For example, if the real table is declared as: ** ** CREATE TABLE real(a, b, c); ** CREATE INDEX real_index ON real(b); ** ** then the echo module handles WHERE or ORDER BY clauses that refer ** to the column "b", but not "a" or "c". If a multi-column index is ** present, only its left most column is considered. ** ** This xBestIndex method encodes the proposed search strategy as ** an SQL query on the real table underlying the virtual echo module ** table and stores the query in sqlite3_index_info.idxStr. The SQL ** statement is of the form: ** ** SELECT rowid, * FROM <real-table> ?<where-clause>? ?<order-by-clause>? ** ** where the <where-clause> and <order-by-clause> are determined ** by the contents of the structure pointed to by the pIdxInfo argument. */ static int echoBestIndex( sqlite3_vtab vtab, ref sqlite3_index_info pIdxInfo ) { int ii; string zQuery = ""; string zNew; int nArg = 0; string zSep = "WHERE"; echo_vtab pVtab = (echo_vtab)vtab; sqlite3_stmt pStmt = null; Tcl_Interp interp = pVtab.interp; int nRow = 0; int useIdx = 0; int rc = SQLITE_OK; int useCost = 0; double cost = 0; int isIgnoreUsable = 0; if ( TCL.Tcl_GetVar( interp, "echo_module_ignore_usable", (TCL.VarFlag)TCL.TCL_GLOBAL_ONLY ).ToString() != "" ) { isIgnoreUsable = 1; } if ( simulateVtabError( pVtab, "xBestIndex" ) != 0 ) { return SQLITE_ERROR; } /* Determine the number of rows in the table and store this value in local ** variable nRow. The 'estimated-cost' of the scan will be the number of ** rows in the table for a linear scan, or the log (base 2) of the ** number of rows if the proposed scan uses an index. */ if ( TCL.Tcl_GetVar( interp, "echo_module_cost", (TCL.VarFlag)TCL.TCL_GLOBAL_ONLY ).ToString() != "" ) { Double.TryParse( TCL.Tcl_GetVar( interp, "echo_module_cost", (TCL.VarFlag)TCL.TCL_GLOBAL_ONLY ).ToString(), out cost ); useCost = 1; } else { zQuery = sqlite3_mprintf( "SELECT count() FROM %Q", pVtab.zTableName ); //if ( null == zQuery ) //{ // return SQLITE_NOMEM; //} rc = sqlite3_prepare( pVtab.db, zQuery, -1, ref pStmt, 0 ); //sqlite3_free(zQuery); if ( rc != SQLITE_OK ) { return rc; } sqlite3_step( pStmt ); nRow = sqlite3_column_int( pStmt, 0 ); rc = sqlite3_finalize( pStmt ); if ( rc != SQLITE_OK ) { return rc; } } zQuery = sqlite3_mprintf( "SELECT rowid, * FROM %Q", pVtab.zTableName ); //if ( null == zQuery ) //{ // return SQLITE_NOMEM; //} for ( ii = 0; ii < pIdxInfo.nConstraint; ii++ ) { sqlite3_index_constraint pConstraint; sqlite3_index_constraint_usage pUsage; int iCol; pConstraint = pIdxInfo.aConstraint[ii]; pUsage = pIdxInfo.aConstraintUsage[ii]; if ( 0 == isIgnoreUsable && !pConstraint.usable ) continue; iCol = pConstraint.iColumn; if ( iCol < 0 || pVtab.aIndex[iCol] != 0 ) { string zCol; string zOp = ""; useIdx = 1; if ( iCol >= 0 ) { zCol = pVtab.aCol[iCol]; } else { zCol = "rowid"; } switch ( pConstraint.op ) { case SQLITE_INDEX_CONSTRAINT_EQ: zOp = "="; break; case SQLITE_INDEX_CONSTRAINT_LT: zOp = "<"; break; case SQLITE_INDEX_CONSTRAINT_GT: zOp = ">"; break; case SQLITE_INDEX_CONSTRAINT_LE: zOp = "<="; break; case SQLITE_INDEX_CONSTRAINT_GE: zOp = ">="; break; case SQLITE_INDEX_CONSTRAINT_MATCH: zOp = "LIKE"; break; } if ( zOp[0] == 'L' ) { zNew = sqlite3_mprintf( " %s %s LIKE (SELECT '%%'||?||'%%')", zSep, zCol ); } else { zNew = sqlite3_mprintf( " %s %s %s ?", zSep, zCol, zOp ); } string_concat( ref zQuery, zNew, 1, ref rc ); zSep = "AND"; pUsage.argvIndex = ++nArg; pUsage.omit = true; } } /* If there is only one term in the ORDER BY clause, and it is ** on a column that this virtual table has an index for, then consume ** the ORDER BY clause. */ if ( pIdxInfo.nOrderBy == 1 && ( pIdxInfo.aOrderBy[0].iColumn < 0 || pVtab.aIndex[pIdxInfo.aOrderBy[0].iColumn] != 0 ) ) { int iCol = pIdxInfo.aOrderBy[0].iColumn; string zCol; string zDir = pIdxInfo.aOrderBy[0].desc ? "DESC" : "ASC"; if ( iCol >= 0 ) { zCol = pVtab.aCol[iCol]; } else { zCol = "rowid"; } zNew = sqlite3_mprintf( " ORDER BY %s %s", zCol, zDir ); string_concat( ref zQuery, zNew, 1, ref rc ); pIdxInfo.orderByConsumed = true; } appendToEchoModule( pVtab.interp, "xBestIndex" ); ; appendToEchoModule( pVtab.interp, zQuery ); if ( null == zQuery ) { return rc; } pIdxInfo.idxNum = hashString( zQuery ); pIdxInfo.idxStr = zQuery; pIdxInfo.needToFreeIdxStr = 1; if ( useCost != 0 ) { pIdxInfo.estimatedCost = cost; } else if ( useIdx != 0 ) { /* Approximation of log2(nRow). */ for ( ii = 0; ii < ( sizeof( int ) * 8 ); ii++ ) { if ( ( nRow & ( 1 << ii ) ) != 0 ) { pIdxInfo.estimatedCost = (double)ii; } } } else { pIdxInfo.estimatedCost = (double)nRow; } return rc; }
/* The xDisconnect and xDestroy methods are also the same */ /* ** Open a new wholenumber cursor. */ static int wholenumberOpen( sqlite3_vtab p, out sqlite3_vtab_cursor ppCursor ) { wholenumber_cursor pCur; pCur = new wholenumber_cursor();//sqlite3_malloc( sizeof(*pCur) ); //if ( pCur == null ) // return SQLITE_NOMEM; //memset(pCur, 0, sizeof(*pCur)); ppCursor = pCur;//.base; return SQLITE_OK; }