示例#1
0
        /* 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);
        }
示例#2
0
        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);
        }
示例#3
0
/* 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);
        }
示例#4
0
 /*
 ** 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));
 }
示例#5
0
        /* 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);
        }
示例#6
0
        /*
        ** 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);
        }
示例#7
0
        /*
        ** 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;
 }
示例#9
0
        /* 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;
}
示例#11
0
/* 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);
        }
示例#12
0
        /*
        ** 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);
        }
示例#13
0
        /*
        ** 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;
            }
        }
示例#14
0
        /*
        ** 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);
        }
示例#15
0
        /*
        ** 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);
        }
示例#16
0
        /*
        ** 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);
        }
示例#17
0
 /*
 ** Analyse the WHERE condition.
 */
 static int intarrayBestIndex( sqlite3_vtab tab, ref sqlite3_index_info pIdxInfo )
 {
   return SQLITE_OK;
 }
示例#18
0
 /* 
 ** 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;
    }
示例#20
0
    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;
    }
示例#21
0
    /* 
    ** 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;
    }
示例#22
0
 /* 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;
 }
示例#23
0
    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;
    }
示例#24
0
        /*
        ** 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);
        }
示例#25
0
 /*
 ** 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;
}
示例#27
0
 /*
 ** 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;
}
示例#30
0
 /*
 ** 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;
 }
示例#31
0
文件: vdbe_c.cs 项目: jcwmoore/athena
		/// <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;
		}
示例#32
0
    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;
    }
示例#33
0
    /*
    ** 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;
 }
示例#35
0
    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;
    }
示例#36
0
    /*
    ** 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;
    }
示例#37
0
    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;
    }
示例#38
0
    /*
    ** 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;
    }
示例#39
0
 /*
 ** 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;
 }
示例#40
0
 /*
 ** Analyse the WHERE condition.
 */
 static int schemaBestIndex(sqlite3_vtab tab, ref sqlite3_index_info pIdxInfo)
 {
     return(SQLITE_OK);
 }
示例#41
0
    /*
    ** 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;
    }
示例#42
0
    /*
    ** 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;
    }
示例#43
0
 /* 
 ** 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 );
 }
示例#44
0
 /*
 ** 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;
 }
示例#45
0
    /*
    ** 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;
    }