⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 build.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  Token *pName2,     /* The token that holds the name of the view */  Select *pSelect,   /* A SELECT statement that will become the new view */  int isTemp,        /* TRUE for a TEMPORARY view */  int noErr          /* Suppress error messages if VIEW already exists */){  Table *p;  int n;  const unsigned char *z;  Token sEnd;  DbFixer sFix;  Token *pName;  int iDb;  sqlite3 *db = pParse->db;  if( pParse->nVar>0 ){    sqlite3ErrorMsg(pParse, "parameters are not allowed in views");    sqlite3SelectDelete(db, pSelect);    return;  }  sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr);  p = pParse->pNewTable;  if( p==0 || pParse->nErr ){    sqlite3SelectDelete(db, pSelect);    return;  }  sqlite3TwoPartName(pParse, pName1, pName2, &pName);  iDb = sqlite3SchemaToIndex(db, p->pSchema);  if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName)    && sqlite3FixSelect(&sFix, pSelect)  ){    sqlite3SelectDelete(db, pSelect);    return;  }  /* Make a copy of the entire SELECT statement that defines the view.  ** This will force all the Expr.token.z values to be dynamically  ** allocated rather than point to the input string - which means that  ** they will persist after the current sqlite3_exec() call returns.  */  p->pSelect = sqlite3SelectDup(db, pSelect);  sqlite3SelectDelete(db, pSelect);  if( db->mallocFailed ){    return;  }  if( !db->init.busy ){    sqlite3ViewGetColumnNames(pParse, p);  }  /* Locate the end of the CREATE VIEW statement.  Make sEnd point to  ** the end.  */  sEnd = pParse->sLastToken;  if( sEnd.z[0]!=0 && sEnd.z[0]!=';' ){    sEnd.z += sEnd.n;  }  sEnd.n = 0;  n = sEnd.z - pBegin->z;  z = (const unsigned char*)pBegin->z;  while( n>0 && (z[n-1]==';' || isspace(z[n-1])) ){ n--; }  sEnd.z = &z[n-1];  sEnd.n = 1;  /* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */  sqlite3EndTable(pParse, 0, &sEnd, 0);  return;}#endif /* SQLITE_OMIT_VIEW */#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)/*** The Table structure pTable is really a VIEW.  Fill in the names of** the columns of the view in the pTable structure.  Return the number** of errors.  If an error is seen leave an error message in pParse->zErrMsg.*/int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){  Table *pSelTab;   /* A fake table from which we get the result set */  Select *pSel;     /* Copy of the SELECT that implements the view */  int nErr = 0;     /* Number of errors encountered */  int n;            /* Temporarily holds the number of cursors assigned */  sqlite3 *db = pParse->db;  /* Database connection for malloc errors */  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);  assert( pTable );#ifndef SQLITE_OMIT_VIRTUALTABLE  if( sqlite3VtabCallConnect(pParse, pTable) ){    return SQLITE_ERROR;  }  if( IsVirtual(pTable) ) return 0;#endif#ifndef SQLITE_OMIT_VIEW  /* A positive nCol means the columns names for this view are  ** already known.  */  if( pTable->nCol>0 ) return 0;  /* A negative nCol is a special marker meaning that we are currently  ** trying to compute the column names.  If we enter this routine with  ** a negative nCol, it means two or more views form a loop, like this:  **  **     CREATE VIEW one AS SELECT * FROM two;  **     CREATE VIEW two AS SELECT * FROM one;  **  ** Actually, this error is caught previously and so the following test  ** should always fail.  But we will leave it in place just to be safe.  */  if( pTable->nCol<0 ){    sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName);    return 1;  }  assert( pTable->nCol>=0 );  /* If we get this far, it means we need to compute the table names.  ** Note that the call to sqlite3ResultSetOfSelect() will expand any  ** "*" elements in the results set of the view and will assign cursors  ** to the elements of the FROM clause.  But we do not want these changes  ** to be permanent.  So the computation is done on a copy of the SELECT  ** statement that defines the view.  */  assert( pTable->pSelect );  pSel = sqlite3SelectDup(db, pTable->pSelect);  if( pSel ){    n = pParse->nTab;    sqlite3SrcListAssignCursors(pParse, pSel->pSrc);    pTable->nCol = -1;#ifndef SQLITE_OMIT_AUTHORIZATION    xAuth = db->xAuth;    db->xAuth = 0;    pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);    db->xAuth = xAuth;#else    pSelTab = sqlite3ResultSetOfSelect(pParse, pSel);#endif    pParse->nTab = n;    if( pSelTab ){      assert( pTable->aCol==0 );      pTable->nCol = pSelTab->nCol;      pTable->aCol = pSelTab->aCol;      pSelTab->nCol = 0;      pSelTab->aCol = 0;      sqlite3DeleteTable(pSelTab);      pTable->pSchema->flags |= DB_UnresetViews;    }else{      pTable->nCol = 0;      nErr++;    }    sqlite3SelectDelete(db, pSel);  } else {    nErr++;  }#endif /* SQLITE_OMIT_VIEW */  return nErr;  }#endif /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */#ifndef SQLITE_OMIT_VIEW/*** Clear the column names from every VIEW in database idx.*/static void sqliteViewResetAll(sqlite3 *db, int idx){  HashElem *i;  if( !DbHasProperty(db, idx, DB_UnresetViews) ) return;  for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){    Table *pTab = sqliteHashData(i);    if( pTab->pSelect ){      sqliteResetColumnNames(pTab);    }  }  DbClearProperty(db, idx, DB_UnresetViews);}#else# define sqliteViewResetAll(A,B)#endif /* SQLITE_OMIT_VIEW *//*** This function is called by the VDBE to adjust the internal schema** used by SQLite when the btree layer moves a table root page. The** root-page of a table or index in database iDb has changed from iFrom** to iTo.**** Ticket #1728:  The symbol table might still contain information** on tables and/or indices that are the process of being deleted.** If you are unlucky, one of those deleted indices or tables might** have the same rootpage number as the real table or index that is** being moved.  So we cannot stop searching after the first match ** because the first match might be for one of the deleted indices** or tables and not the table/index that is actually being moved.** We must continue looping until all tables and indices with** rootpage==iFrom have been converted to have a rootpage of iTo** in order to be certain that we got the right one.*/#ifndef SQLITE_OMIT_AUTOVACUUMvoid sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){  HashElem *pElem;  Hash *pHash;  pHash = &pDb->pSchema->tblHash;  for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){    Table *pTab = sqliteHashData(pElem);    if( pTab->tnum==iFrom ){      pTab->tnum = iTo;    }  }  pHash = &pDb->pSchema->idxHash;  for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){    Index *pIdx = sqliteHashData(pElem);    if( pIdx->tnum==iFrom ){      pIdx->tnum = iTo;    }  }}#endif/*** Write code to erase the table with root-page iTable from database iDb.** Also write code to modify the sqlite_master table and internal schema** if a root-page of another table is moved by the btree-layer whilst** erasing iTable (this can happen with an auto-vacuum database).*/ static void destroyRootPage(Parse *pParse, int iTable, int iDb){  Vdbe *v = sqlite3GetVdbe(pParse);  int r1 = sqlite3GetTempReg(pParse);  sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);#ifndef SQLITE_OMIT_AUTOVACUUM  /* OP_Destroy stores an in integer r1. If this integer  ** is non-zero, then it is the root page number of a table moved to  ** location iTable. The following code modifies the sqlite_master table to  ** reflect this.  **  ** The "#%d" in the SQL is a special constant that means whatever value  ** is on the top of the stack.  See sqlite3RegisterExpr().  */  sqlite3NestedParse(pParse,      "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d",     pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable, r1, r1);#endif  sqlite3ReleaseTempReg(pParse, r1);}/*** Write VDBE code to erase table pTab and all associated indices on disk.** Code to update the sqlite_master tables and internal schema definitions** in case a root-page belonging to another table is moved by the btree layer** is also added (this can happen with an auto-vacuum database).*/static void destroyTable(Parse *pParse, Table *pTab){#ifdef SQLITE_OMIT_AUTOVACUUM  Index *pIdx;  int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);  destroyRootPage(pParse, pTab->tnum, iDb);  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){    destroyRootPage(pParse, pIdx->tnum, iDb);  }#else  /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM  ** is not defined), then it is important to call OP_Destroy on the  ** table and index root-pages in order, starting with the numerically   ** largest root-page number. This guarantees that none of the root-pages  ** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the  ** following were coded:  **  ** OP_Destroy 4 0  ** ...  ** OP_Destroy 5 0  **  ** and root page 5 happened to be the largest root-page number in the  ** database, then root page 5 would be moved to page 4 by the   ** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit  ** a free-list page.  */  int iTab = pTab->tnum;  int iDestroyed = 0;  while( 1 ){    Index *pIdx;    int iLargest = 0;    if( iDestroyed==0 || iTab<iDestroyed ){      iLargest = iTab;    }    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){      int iIdx = pIdx->tnum;      assert( pIdx->pSchema==pTab->pSchema );      if( (iDestroyed==0 || (iIdx<iDestroyed)) && iIdx>iLargest ){        iLargest = iIdx;      }    }    if( iLargest==0 ){      return;    }else{      int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);      destroyRootPage(pParse, iLargest, iDb);      iDestroyed = iLargest;    }  }#endif}/*** This routine is called to do the work of a DROP TABLE statement.** pName is the name of the table to be dropped.*/void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){  Table *pTab;  Vdbe *v;  sqlite3 *db = pParse->db;  int iDb;  if( pParse->nErr || db->mallocFailed ){    goto exit_drop_table;  }  assert( pName->nSrc==1 );  pTab = sqlite3LocateTable(pParse, isView,                             pName->a[0].zName, pName->a[0].zDatabase);  if( pTab==0 ){    if( noErr ){      sqlite3ErrorClear(pParse);    }    goto exit_drop_table;  }  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);  assert( iDb>=0 && iDb<db->nDb );  /* If pTab is a virtual table, call ViewGetColumnNames() to ensure  ** it is initialized.  */  if( IsVirtual(pTab) && sqlite3ViewGetColumnNames(pParse, pTab) ){    goto exit_drop_table;  }#ifndef SQLITE_OMIT_AUTHORIZATION  {    int code;    const char *zTab = SCHEMA_TABLE(iDb);    const char *zDb = db->aDb[iDb].zName;    const char *zArg2 = 0;    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){      goto exit_drop_table;    }    if( isView ){      if( !OMIT_TEMPDB && iDb==1 ){        code = SQLITE_DROP_TEMP_VIEW;      }else{        code = SQLITE_DROP_VIEW;      }#ifndef SQLITE_OMIT_VIRTUALTABLE    }else if( IsVirtual(pTab) ){      code = SQLITE_DROP_VTABLE;      zArg2 = pTab->pMod->zName;#endif    }else{      if( !OMIT_TEMPDB && iDb==1 ){        code = SQLITE_DROP_TEMP_TABLE;      }else{        code = SQLITE_DROP_TABLE;      }    }    if( sqlite3AuthCheck(pParse, code, pTab->zName, zArg2, zDb) ){      goto exit_drop_table;    }    if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){      goto exit_drop_table;    }  }#endif  if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){    sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);    goto exit_drop_table;  }#ifndef SQLITE_OMIT_VIEW  /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used  ** on a table.  */  if( isView && pTab->pSelect==0 ){    sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName);    goto exit_drop_table;  }  if( !isView && pTab->pSelect ){    sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName);    goto exit_drop_table;  }#endif  /* Generate code to remove the table from the master table  ** on disk.  */  v = sqlite3GetVdbe(pParse);  if( v ){    Trigger *pTrigger;    Db *pDb = &db->aDb[iDb];    sqlite3BeginWriteOperation(pParse, 1, iDb);#ifndef SQLITE_OMIT_VIRTUALTABLE    if( IsVirtual(pTab) ){      Vdbe *v = sqlite3GetVdbe(pParse);      if( v ){        sqlite3VdbeAddOp0(v, OP_VBegin);      }    }#endif    /* Drop all triggers associated with the table being dropped. Code    ** is generated to remove entries from sqlite_master and/or    ** sqlite_temp_master if required.    */    pTrigger = pTab->pTrigger;    while( pTrigger ){      assert( pTrigger->pSchema==pTab->pSchema ||           pTrigger->pSchema==db->aDb[1].pSchema 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -