/ Check-in [2c274a1a]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:The pragma as eponymous virtual table mechanism now appears to work.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | pragma-as-vtab
Files: files | file ages | folders
SHA1: 2c274a1a7b57ef1208901fbc1d96d39c0d492652
User & Date: drh 2016-12-15 21:11:15
Context
2016-12-15
21:33
Fix the cost estimation in the BestIndex method of the eponymous pragma virtual table implementation. check-in: 7126807a user: drh tags: pragma-as-vtab
21:11
The pragma as eponymous virtual table mechanism now appears to work. check-in: 2c274a1a user: drh tags: pragma-as-vtab
20:59
Code to automatically create eponymous virtual tables for read-only pragmas. Compiles, but does not yet work. check-in: 988a61e8 user: drh tags: pragma-as-vtab
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/pragma.c.

1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
....
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
....
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
....
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
  char cSep = '(';
  StrAccum acc;
  char zBuf[200];

  sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
  sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x");
  for(i=0, j=pPragma->iPragCName; i<pPragma->nPragCName; i++, j++){
    sqlite3StrAccumAppend(&acc, &cSep, 1);
    sqlite3StrAccumAppendAll(&acc, pragCName[j]);
    cSep = ',';
  }
  j = 0;
  if( pPragma->mPragFlg & PragFlg_Result1 ){
    sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN");
    j++;
  }
................................................................................
  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
    if( pConstraint->usable==0 ) continue;
    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
    if( pConstraint->iColumn < pTab->iHidden ) continue;
    j = pConstraint->iColumn - pTab->iHidden;
    assert( j < 2 );
    if( seen[j] ) continue;
    seen[j] = i;
  }
  if( seen[0]==0 ){
    pIdxInfo->estimatedCost = (double)2147483647;
    pIdxInfo->estimatedRows = 2147483647;
    return SQLITE_OK;
  }
  j = seen[0];
  pIdxInfo->aConstraintUsage[j].argvIndex = 1;
  pIdxInfo->aConstraintUsage[j].omit = 1;
  if( seen[1]==0 ) return SQLITE_OK;
  pIdxInfo->estimatedCost = (double)20;
  pIdxInfo->estimatedRows = 20;
  j = seen[1];
  pIdxInfo->aConstraintUsage[j].argvIndex = 2;
  pIdxInfo->aConstraintUsage[j].omit = 1;
  return SQLITE_OK;
}

/* Create a new cursor for the pragma virtual table */
static int pragmaVtabOpen(sqlite3_vtab *pVtab, sqlite3_vtab_cursor **ppCursor){
................................................................................
  for(i=0; i<argc; i++){
    assert( i<ArraySize(pCsr->azArg) );
    pCsr->azArg[i] = sqlite3_mprintf("%s", sqlite3_value_text(argv[i]));
    if( pCsr->azArg[i]==0 ){
      return SQLITE_NOMEM;
    }
  }
  sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_MAX_SQL_LENGTH]);
  sqlite3StrAccumAppendAll(&acc, "PRAGMA ");
  if( pCsr->azArg[1] ){
    sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]);
  }
  sqlite3StrAccumAppendAll(&acc, pTab->pName->zName);
  if( pCsr->azArg[0] ){
    sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]);
................................................................................
Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName){
  const PragmaName *pName;
  assert( sqlite3_strnicmp(zName, "pragma_", 7)==0 );
  pName = pragmaLocate(zName+7);
  if( pName==0 ) return 0;
  if( (pName->mPragFlg & (PragFlg_Result0|PragFlg_Result1))==0 ) return 0;
  assert( sqlite3HashFind(&db->aModule, zName)==0 );
  return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, 0, 0);
}

#endif /* SQLITE_OMIT_VIRTUALTABLE */

#endif /* SQLITE_OMIT_PRAGMA */







|
<







 







|






|





|







 







|







 







|





1995
1996
1997
1998
1999
2000
2001
2002

2003
2004
2005
2006
2007
2008
2009
....
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
....
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
....
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
  char cSep = '(';
  StrAccum acc;
  char zBuf[200];

  sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
  sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x");
  for(i=0, j=pPragma->iPragCName; i<pPragma->nPragCName; i++, j++){
    sqlite3XPrintf(&acc, "%c\"%s\"", cSep, pragCName[j]);

    cSep = ',';
  }
  j = 0;
  if( pPragma->mPragFlg & PragFlg_Result1 ){
    sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN");
    j++;
  }
................................................................................
  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
    if( pConstraint->usable==0 ) continue;
    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
    if( pConstraint->iColumn < pTab->iHidden ) continue;
    j = pConstraint->iColumn - pTab->iHidden;
    assert( j < 2 );
    if( seen[j] ) continue;
    seen[j] = i+1;
  }
  if( seen[0]==0 ){
    pIdxInfo->estimatedCost = (double)2147483647;
    pIdxInfo->estimatedRows = 2147483647;
    return SQLITE_OK;
  }
  j = seen[0]-1;
  pIdxInfo->aConstraintUsage[j].argvIndex = 1;
  pIdxInfo->aConstraintUsage[j].omit = 1;
  if( seen[1]==0 ) return SQLITE_OK;
  pIdxInfo->estimatedCost = (double)20;
  pIdxInfo->estimatedRows = 20;
  j = seen[1]-1;
  pIdxInfo->aConstraintUsage[j].argvIndex = 2;
  pIdxInfo->aConstraintUsage[j].omit = 1;
  return SQLITE_OK;
}

/* Create a new cursor for the pragma virtual table */
static int pragmaVtabOpen(sqlite3_vtab *pVtab, sqlite3_vtab_cursor **ppCursor){
................................................................................
  for(i=0; i<argc; i++){
    assert( i<ArraySize(pCsr->azArg) );
    pCsr->azArg[i] = sqlite3_mprintf("%s", sqlite3_value_text(argv[i]));
    if( pCsr->azArg[i]==0 ){
      return SQLITE_NOMEM;
    }
  }
  sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]);
  sqlite3StrAccumAppendAll(&acc, "PRAGMA ");
  if( pCsr->azArg[1] ){
    sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]);
  }
  sqlite3StrAccumAppendAll(&acc, pTab->pName->zName);
  if( pCsr->azArg[0] ){
    sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]);
................................................................................
Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName){
  const PragmaName *pName;
  assert( sqlite3_strnicmp(zName, "pragma_", 7)==0 );
  pName = pragmaLocate(zName+7);
  if( pName==0 ) return 0;
  if( (pName->mPragFlg & (PragFlg_Result0|PragFlg_Result1))==0 ) return 0;
  assert( sqlite3HashFind(&db->aModule, zName)==0 );
  return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, (void*)pName, 0);
}

#endif /* SQLITE_OMIT_VIRTUALTABLE */

#endif /* SQLITE_OMIT_PRAGMA */