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

📄 build.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 5 页
字号:
  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 */  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(pTable->pSelect);  if( pSel ){    n = pParse->nTab;    sqlite3SrcListAssignCursors(pParse, pSel->pSrc);    pTable->nCol = -1;    pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSel);    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(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);  sqlite3VdbeAddOp(v, OP_Destroy, iTable, iDb);#ifndef SQLITE_OMIT_AUTOVACUUM  /* OP_Destroy pushes an integer onto the stack. 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 "#0" 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 #0 AND rootpage=#0",     pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable);#endif}/*** 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 || sqlite3MallocFailed() ){    goto exit_drop_table;  }  assert( pName->nSrc==1 );  pTab = sqlite3LocateTable(pParse, 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 );#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) ){      if( sqlite3ViewGetColumnNames(pParse, pTab) ){        goto exit_drop_table;      }      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( pTab->readOnly || pTab==db->aDb[iDb].pSchema->pSeqTab ){    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, 0, iDb);#ifndef SQLITE_OMIT_VIRTUALTABLE    if( IsVirtual(pTab) ){      Vdbe *v = sqlite3GetVdbe(pParse);      if( v ){        sqlite3VdbeAddOp(v, OP_VBegin, 0, 0);      }    }#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 );      sqlite3DropTriggerPtr(pParse, pTrigger);      pTrigger = pTrigger->pNext;    }#ifndef SQLITE_OMIT_AUTOINCREMENT    /* Remove any entries of the sqlite_sequence table associated with    ** the table being dropped. This is done before the table is dropped    ** at the btree level, in case the sqlite_sequence table needs to    ** move as a result of the drop (can happen in auto-vacuum mode).    */    if( pTab->autoInc ){      sqlite3NestedParse(pParse,        "DELETE FROM %s.sqlite_sequence WHERE name=%Q",        pDb->zName, pTab->zName      );    }#endif    /* Drop all SQLITE_MASTER table and index entries that refer to the    ** table. The program name loops through the master table and deletes    ** every row that refers to a table of the same name as the one being    ** dropped. Triggers are handled seperately because a trigger can be    ** created in the temp database that refers to a table in another    ** database.    */    sqlite3NestedParse(pParse,         "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",        pDb->zName, SCHEMA_TABLE(iDb), pTab->zName);    if( !isView && !IsVirtual(pTab) ){      destroyTable(pParse, pTab);    }    /* Remove the table entry from SQLite's internal schema and modify    ** the schema cookie.    */    if( IsVirtual(pTab) ){      sqlite3VdbeOp3(v, OP_VDestroy, iDb, 0, pTab->zName, 0);    }    sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0);    sqlite3ChangeCookie(db, v, iDb);  }  sqliteViewResetAll(db, iDb);exit_drop_table:  sqlite3SrcListDelete(pName);}/*** This routine is called to create a new foreign key on the table** currently under construction.  pFromCol determines which columns** in the current table point to the foreign key.  If pFromCol==0 then** connect the key to the last column inserted.  pTo is the name of** the table referred to.  pToCol is a list of tables in the other** pTo table that the foreign key points to.  flags contains all** information about the conflict resolution algorithms specified** in the ON DELETE, ON UPDATE and ON INSERT clauses.**** An FKey structure is created and added to the table currently** under construction in the pParse->pNewTable field.  The new FKey** is not linked into db->aFKey at this point - that does not happen** until sqlite3EndTable().**** The foreign key is set for IMMEDIATE processing.  A subsequent call** to sqlite3DeferForeignKey() might change this to DEFERRED.*/void sqlite3CreateForeignKey(  Parse *pParse,       /* Parsing context */  ExprList *pFromCol,  /* Columns in this table that point to other tabl

⌨️ 快捷键说明

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