Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Eliminate the use of callbacks during schema initialization. (CVS 1242) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
af5c2be4aed1c50f69eb9634cf051a26 |
User & Date: | drh 2004-02-14 23:05:53.000 |
Context
2004-02-14
| ||
23:59 | Eliminate obsolete code associated with the older callback functionality. (CVS 1243) (check-in: 2dbc4593ca user: drh tags: trunk) | |
23:05 | Eliminate the use of callbacks during schema initialization. (CVS 1242) (check-in: af5c2be4ae user: drh tags: trunk) | |
17:35 | Fix problems with malloc-failure handling. (CVS 1241) (check-in: 398bc294c8 user: drh tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
19 20 21 22 23 24 25 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** ** $Id: build.c,v 1.169 2004/02/14 23:05:53 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Check to see if the schema for the database needs ** to be read from the SQLITE_MASTER and SQLITE_TEMP_MASTER tables. ** If it does, then read it. */ void sqliteBeginParse(Parse *pParse, int explainFlag){ sqlite *db = pParse->db; int i; pParse->explain = explainFlag; if((db->flags & SQLITE_Initialized)==0 && db->init.busy==0 ){ int rc = sqliteInit(db, &pParse->zErrMsg); if( rc!=SQLITE_OK ){ pParse->rc = rc; pParse->nErr++; } } for(i=0; i<db->nDb; i++){ |
︙ | ︙ | |||
467 468 469 470 471 472 473 | sqlite *db = pParse->db; Vdbe *v; int iDb; pParse->sFirstToken = *pStart; zName = sqliteTableNameFromToken(pName); if( zName==0 ) return; | | | 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 | sqlite *db = pParse->db; Vdbe *v; int iDb; pParse->sFirstToken = *pStart; zName = sqliteTableNameFromToken(pName); if( zName==0 ) return; if( db->init.iDb==1 ) isTemp = 1; #ifndef SQLITE_OMIT_AUTHORIZATION assert( (isTemp & 1)==isTemp ); { int code; char *zDb = isTemp ? "temp" : "main"; if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){ sqliteFree(zName); |
︙ | ︙ | |||
528 529 530 531 532 533 534 | ** index or table name. Issue an error message if it does. ** ** If we are re-reading the sqlite_master table because of a schema ** change and a new permanent table is found whose name collides with ** an existing temporary table, that is not an error. */ pTable = sqliteFindTable(db, zName, 0); | | | | | 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 | ** index or table name. Issue an error message if it does. ** ** If we are re-reading the sqlite_master table because of a schema ** change and a new permanent table is found whose name collides with ** an existing temporary table, that is not an error. */ pTable = sqliteFindTable(db, zName, 0); iDb = isTemp ? 1 : db->init.iDb; if( pTable!=0 && (pTable->iDb==iDb || !db->init.busy) ){ sqliteSetNString(&pParse->zErrMsg, "table ", 0, pName->z, pName->n, " already exists", 0, 0); sqliteFree(zName); pParse->nErr++; return; } if( (pIdx = sqliteFindIndex(db, zName, 0))!=0 && (pIdx->iDb==0 || !db->init.busy) ){ sqliteSetString(&pParse->zErrMsg, "there is already an index named ", zName, (char*)0); sqliteFree(zName); pParse->nErr++; return; } pTable = sqliteMalloc( sizeof(Table) ); |
︙ | ︙ | |||
566 567 568 569 570 571 572 | ** the SQLITE_MASTER table. Note in particular that we must go ahead ** and allocate the record number for the table entry now. Before any ** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause ** indices to be created and the table record must come before the ** indices. Hence, the record number for the table must be allocated ** now. */ | | | 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 | ** the SQLITE_MASTER table. Note in particular that we must go ahead ** and allocate the record number for the table entry now. Before any ** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause ** indices to be created and the table record must come before the ** indices. Hence, the record number for the table must be allocated ** now. */ if( !db->init.busy && (v = sqliteGetVdbe(pParse))!=0 ){ sqliteBeginWriteOperation(pParse, 0, isTemp); if( !isTemp ){ sqliteVdbeAddOp(v, OP_Integer, db->file_format, 0); sqliteVdbeAddOp(v, OP_SetCookie, 0, 1); } sqliteOpenMasterTable(v, isTemp); sqliteVdbeAddOp(v, OP_NewRecno, 0, 0); |
︙ | ︙ | |||
923 924 925 926 927 928 929 | ** This routine is called to report the final ")" that terminates ** a CREATE TABLE statement. ** ** The table structure that other action routines have been building ** is added to the internal hash tables, assuming no errors have ** occurred. ** | | | | 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 | ** This routine is called to report the final ")" that terminates ** a CREATE TABLE statement. ** ** The table structure that other action routines have been building ** is added to the internal hash tables, assuming no errors have ** occurred. ** ** An entry for the table is made in the master table on disk, unless ** this is a temporary table or db->init.busy==1. When db->init.busy==1 ** it means we are reading the sqlite_master table because we just ** connected to the database or because the sqlite_master table has ** recently changes, so the entry for this table already exists in ** the sqlite_master table. We do not want to create it again. ** ** If the pSelect argument is not NULL, it means that this routine ** was called to create a table generated from a |
︙ | ︙ | |||
957 958 959 960 961 962 963 | p->nCol = pSelTab->nCol; p->aCol = pSelTab->aCol; pSelTab->nCol = 0; pSelTab->aCol = 0; sqliteDeleteTable(0, pSelTab); } | | | | | | | 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 | p->nCol = pSelTab->nCol; p->aCol = pSelTab->aCol; pSelTab->nCol = 0; pSelTab->aCol = 0; sqliteDeleteTable(0, pSelTab); } /* If the db->init.busy is 1 it means we are reading the SQL off the ** "sqlite_master" or "sqlite_temp_master" table on the disk. ** So do not write to the disk again. Extract the root page number ** for the table from the db->init.newTnum field. (The page number ** should have been put there by the sqliteOpenCb routine.) */ if( db->init.busy ){ p->tnum = db->init.newTnum; } /* If not initializing, then create a record for the new table ** in the SQLITE_MASTER table of the database. The record number ** for the new table entry should already be on the stack. ** ** If this is a TEMPORARY table, write the entry into the auxiliary ** file instead of into the main database file. */ if( !db->init.busy ){ int n; Vdbe *v; v = sqliteGetVdbe(pParse); if( v==0 ) return; if( p->pSelect==0 ){ /* A regular table */ |
︙ | ︙ | |||
997 998 999 1000 1001 1002 1003 | sqliteVdbeAddOp(v, OP_String, 0, 0); if( p->pSelect==0 ){ sqliteVdbeChangeP3(v, -1, "table", P3_STATIC); }else{ sqliteVdbeChangeP3(v, -1, "view", P3_STATIC); } sqliteVdbeAddOp(v, OP_String, 0, 0); | | | | 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 | sqliteVdbeAddOp(v, OP_String, 0, 0); if( p->pSelect==0 ){ sqliteVdbeChangeP3(v, -1, "table", P3_STATIC); }else{ sqliteVdbeChangeP3(v, -1, "view", P3_STATIC); } sqliteVdbeAddOp(v, OP_String, 0, 0); sqliteVdbeChangeP3(v, -1, p->zName, 0); sqliteVdbeAddOp(v, OP_String, 0, 0); sqliteVdbeChangeP3(v, -1, p->zName, 0); sqliteVdbeAddOp(v, OP_Dup, 4, 0); sqliteVdbeAddOp(v, OP_String, 0, 0); if( pSelect ){ char *z = createTableStmt(p); n = z ? strlen(z) : 0; sqliteVdbeChangeP3(v, -1, z, n); sqliteFree(z); |
︙ | ︙ | |||
1085 1086 1087 1088 1089 1090 1091 | /* 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 sqlite_exec() call returns. */ p->pSelect = sqliteSelectDup(pSelect); sqliteSelectDelete(pSelect); | | | 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 | /* 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 sqlite_exec() call returns. */ p->pSelect = sqliteSelectDup(pSelect); sqliteSelectDelete(pSelect); if( !pParse->db->init.busy ){ sqliteViewGetColumnNames(pParse, p); } /* Locate the end of the CREATE VIEW statement. Make sEnd point to ** the end. */ sEnd = pParse->sLastToken; |
︙ | ︙ | |||
1563 1564 1565 1566 1567 1568 1569 | int i, j; Token nullId; /* Fake token for an empty ID list */ DbFixer sFix; /* For assigning database names to pTable */ int isTemp; /* True for a temporary index */ sqlite *db = pParse->db; if( pParse->nErr || sqlite_malloc_failed ) goto exit_create_index; | | | | 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 | int i, j; Token nullId; /* Fake token for an empty ID list */ DbFixer sFix; /* For assigning database names to pTable */ int isTemp; /* True for a temporary index */ sqlite *db = pParse->db; if( pParse->nErr || sqlite_malloc_failed ) goto exit_create_index; if( db->init.busy && sqliteFixInit(&sFix, pParse, db->init.iDb, "index", pName) && sqliteFixSrcList(&sFix, pTable) ){ goto exit_create_index; } /* ** Find the table that is to be indexed. Return early if not found. |
︙ | ︙ | |||
1588 1589 1590 1591 1592 1593 1594 | if( pTab==0 || pParse->nErr ) goto exit_create_index; if( pTab->readOnly ){ sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, " may not be indexed", (char*)0); pParse->nErr++; goto exit_create_index; } | | | 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 | if( pTab==0 || pParse->nErr ) goto exit_create_index; if( pTab->readOnly ){ sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, " may not be indexed", (char*)0); pParse->nErr++; goto exit_create_index; } if( pTab->iDb>=2 && db->init.busy==0 ){ sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, " may not have indices added", (char*)0); pParse->nErr++; goto exit_create_index; } if( pTab->pSelect ){ sqliteSetString(&pParse->zErrMsg, "views may not be indexed", (char*)0); |
︙ | ︙ | |||
1614 1615 1616 1617 1618 1619 1620 | ** one of the index names collides with the name of a temporary table or ** index, then we will continue to process this index. ** ** If pName==0 it means that we are ** dealing with a primary key or UNIQUE constraint. We have to invent our ** own name. */ | | | 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 | ** one of the index names collides with the name of a temporary table or ** index, then we will continue to process this index. ** ** If pName==0 it means that we are ** dealing with a primary key or UNIQUE constraint. We have to invent our ** own name. */ if( pName && !db->init.busy ){ Index *pISameName; /* Another index with the same name */ Table *pTSameName; /* A table with same name as the index */ zName = sqliteStrNDup(pName->z, pName->n); if( zName==0 ) goto exit_create_index; if( (pISameName = sqliteFindIndex(db, zName, 0))!=0 ){ sqliteSetString(&pParse->zErrMsg, "index ", zName, " already exists", (char*)0); |
︙ | ︙ | |||
1650 1651 1652 1653 1654 1655 1656 | /* Check for authorization to create an index. */ #ifndef SQLITE_OMIT_AUTHORIZATION { const char *zDb = db->aDb[pTab->iDb].zName; | | | 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 | /* Check for authorization to create an index. */ #ifndef SQLITE_OMIT_AUTHORIZATION { const char *zDb = db->aDb[pTab->iDb].zName; assert( pTab->iDb==db->init.iDb || isTemp ); if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){ goto exit_create_index; } i = SQLITE_CREATE_INDEX; if( isTemp ) i = SQLITE_CREATE_TEMP_INDEX; if( sqliteAuthCheck(pParse, i, zName, pTab->zName, zDb) ){ goto exit_create_index; |
︙ | ︙ | |||
1686 1687 1688 1689 1690 1691 1692 | pIndex->aiColumn = (int*)&pIndex[1]; pIndex->zName = (char*)&pIndex->aiColumn[pList->nId]; strcpy(pIndex->zName, zName); pIndex->pTable = pTab; pIndex->nColumn = pList->nId; pIndex->onError = onError; pIndex->autoIndex = pName==0; | | | 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 | pIndex->aiColumn = (int*)&pIndex[1]; pIndex->zName = (char*)&pIndex->aiColumn[pList->nId]; strcpy(pIndex->zName, zName); pIndex->pTable = pTab; pIndex->nColumn = pList->nId; pIndex->onError = onError; pIndex->autoIndex = pName==0; pIndex->iDb = isTemp ? 1 : db->init.iDb; /* Scan the names of the columns of the table to be indexed and ** load the column indices into the Index structure. Report an error ** if any column is not found. */ for(i=0; i<pList->nId; i++){ for(j=0; j<pTab->nCol; j++){ |
︙ | ︙ | |||
1739 1740 1741 1742 1743 1744 1745 | while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){ pOther = pOther->pNext; } pIndex->pNext = pOther->pNext; pOther->pNext = pIndex; } | | | | | | | | | | | | 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 | while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){ pOther = pOther->pNext; } pIndex->pNext = pOther->pNext; pOther->pNext = pIndex; } /* If the db->init.busy is 1 it means we are reading the SQL off the ** "sqlite_master" table on the disk. So do not write to the disk ** again. Extract the table number from the db->init.newTnum field. */ if( db->init.busy && pTable!=0 ){ pIndex->tnum = db->init.newTnum; } /* If the db->init.busy is 0 then create the index on disk. This ** involves writing the index into the master table and filling in the ** index with the current table contents. ** ** The db->init.busy is 0 when the user first enters a CREATE INDEX ** command. db->init.busy is 1 when a database is opened and ** CREATE INDEX statements are read out of the master table. In ** the latter case the index already exists on disk, which is why ** we don't want to recreate it. ** ** If pTable==0 it means this index is generated as a primary key ** or UNIQUE constraint of a CREATE TABLE statement. Since the table ** has just been created, it contains no data and the index initialization ** step can be skipped. */ else if( db->init.busy==0 ){ int n; Vdbe *v; int lbl1, lbl2; int i; int addr; v = sqliteGetVdbe(pParse); if( v==0 ) goto exit_create_index; if( pTable!=0 ){ sqliteBeginWriteOperation(pParse, 0, isTemp); sqliteOpenMasterTable(v, isTemp); } sqliteVdbeAddOp(v, OP_NewRecno, 0, 0); sqliteVdbeAddOp(v, OP_String, 0, 0); sqliteVdbeChangeP3(v, -1, "index", P3_STATIC); sqliteVdbeAddOp(v, OP_String, 0, 0); sqliteVdbeChangeP3(v, -1, pIndex->zName, strlen(pIndex->zName)); sqliteVdbeAddOp(v, OP_String, 0, 0); sqliteVdbeChangeP3(v, -1, pTab->zName, 0); addr = sqliteVdbeAddOp(v, OP_CreateIndex, 0, isTemp); sqliteVdbeChangeP3(v, addr, (char*)&pIndex->tnum, P3_POINTER); pIndex->tnum = 0; if( pTable ){ sqliteVdbeAddOp(v, OP_Dup, 0, 0); sqliteVdbeAddOp(v, OP_Integer, isTemp, 0); sqliteVdbeAddOp(v, OP_OpenWrite, 1, 0); } addr = sqliteVdbeAddOp(v, OP_String, 0, 0); if( pStart && pEnd ){ n = Addr(pEnd->z) - Addr(pStart->z) + 1; sqliteVdbeChangeP3(v, addr, pStart->z, n); } sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0); sqliteVdbeAddOp(v, OP_PutIntKey, 0, 0); if( pTable ){ sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0); sqliteVdbeAddOp(v, OP_OpenRead, 2, pTab->tnum); sqliteVdbeChangeP3(v, -1, pTab->zName, 0); lbl2 = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_Rewind, 2, lbl2); lbl1 = sqliteVdbeAddOp(v, OP_Recno, 2, 0); for(i=0; i<pIndex->nColumn; i++){ int iCol = pIndex->aiColumn[i]; if( pTab->iPKey==iCol ){ sqliteVdbeAddOp(v, OP_Dup, i, 0); |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | | > < | > | | < | | | > | < | > > > > | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.154 2004/02/14 23:05:53 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** A pointer to this structure is used to communicate information ** from sqliteInit into the sqliteInitCallback. */ typedef struct { sqlite *db; /* The database being initialized */ char **pzErrMsg; /* Error message stored here */ } InitData; /* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. */ static void corruptSchema(InitData *pData, const char *zExtra){ sqliteSetString(pData->pzErrMsg, "malformed database schema", zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0); } /* ** This is the callback routine for the code that initializes the ** database. See sqliteInit() below for additional information. ** ** Each callback contains the following information: ** ** argv[0] = "file-format" or "schema-cookie" or "table" or "index" ** argv[1] = table or index name or meta statement type. ** argv[2] = root page number for table or index. NULL for meta. ** argv[3] = SQL text for a CREATE TABLE or CREATE INDEX statement. ** argv[4] = "1" for temporary files, "0" for main database, "2" or more ** for auxiliary database files. ** */ static int sqliteInitCallback(void *pInit, int argc, char **argv, char **azColName){ InitData *pData = (InitData*)pInit; int nErr = 0; assert( argc==5 ); if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ if( argv[0]==0 ){ corruptSchema(pData, 0); return 1; } switch( argv[0][0] ){ case 'v': case 'i': case 't': { /* CREATE TABLE, CREATE INDEX, or CREATE VIEW statements */ sqlite *db = pData->db; if( argv[2]==0 || argv[4]==0 ){ corruptSchema(pData, 0); return 1; } if( argv[3] && argv[3][0] ){ /* Call the parser to process a CREATE TABLE, INDEX or VIEW. ** But because db->init.busy is set to 1, no VDBE code is generated ** or executed. All the parser does is build the internal data ** structures that describe the table, index, or view. */ char *zErr; assert( db->init.busy ); db->init.iDb = atoi(argv[4]); assert( db->init.iDb>=0 && db->init.iDb<db->nDb ); db->init.newTnum = atoi(argv[2]); if( sqlite_exec(db, argv[3], 0, 0, &zErr) ){ corruptSchema(pData, zErr); sqlite_freemem(zErr); } db->init.iDb = 0; }else{ /* If the SQL column is blank it means this is an index that ** was created to be the PRIMARY KEY or to fulfill a UNIQUE ** constraint for a CREATE TABLE. The index should have already ** been created when we processed the CREATE TABLE. All we have ** to do here is record the root page number for that index. */ int iDb; Index *pIndex; iDb = atoi(argv[4]); assert( iDb>=0 && iDb<db->nDb ); pIndex = sqliteFindIndex(db, argv[1], db->aDb[iDb].zName); if( pIndex==0 || pIndex->tnum!=0 ){ /* This can occur if there exists an index on a TEMP table which ** has the same name as another index on a permanent index. Since ** the permanent table is hidden by the TEMP table, we can also ** safely ignore the index on the permanent table. */ /* Do Nothing */; |
︙ | ︙ | |||
184 185 186 187 188 189 190 | int rc; BtCursor *curMain; int size; Table *pTab; char *azArg[6]; char zDbNum[30]; int meta[SQLITE_N_BTREE_META]; | < | 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | int rc; BtCursor *curMain; int size; Table *pTab; char *azArg[6]; char zDbNum[30]; int meta[SQLITE_N_BTREE_META]; InitData initData; /* ** The master database table has a structure like this */ static char master_schema[] = "CREATE TABLE sqlite_master(\n" |
︙ | ︙ | |||
241 242 243 244 245 246 247 248 249 250 251 252 253 254 | "WHERE type='index'"; assert( iDb>=0 && iDb!=1 && iDb<db->nDb ); /* Construct the schema tables: sqlite_master and sqlite_temp_master */ azArg[0] = "table"; azArg[1] = MASTER_NAME; azArg[2] = "2"; azArg[3] = master_schema; sprintf(zDbNum, "%d", iDb); azArg[4] = zDbNum; azArg[5] = 0; | > | 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | "WHERE type='index'"; assert( iDb>=0 && iDb!=1 && iDb<db->nDb ); /* Construct the schema tables: sqlite_master and sqlite_temp_master */ sqliteSafetyOff(db); azArg[0] = "table"; azArg[1] = MASTER_NAME; azArg[2] = "2"; azArg[3] = master_schema; sprintf(zDbNum, "%d", iDb); azArg[4] = zDbNum; azArg[5] = 0; |
︙ | ︙ | |||
265 266 267 268 269 270 271 272 273 274 275 276 277 278 | azArg[4] = "1"; sqliteInitCallback(&initData, 5, azArg, 0); pTab = sqliteFindTable(db, TEMP_MASTER_NAME, "temp"); if( pTab ){ pTab->readOnly = 1; } } /* Create a cursor to hold the database open */ if( db->aDb[iDb].pBt==0 ) return SQLITE_OK; rc = sqliteBtreeCursor(db->aDb[iDb].pBt, 2, 0, &curMain); if( rc ){ sqliteSetString(pzErrMsg, sqlite_error_string(rc), (char*)0); | > | 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | azArg[4] = "1"; sqliteInitCallback(&initData, 5, azArg, 0); pTab = sqliteFindTable(db, TEMP_MASTER_NAME, "temp"); if( pTab ){ pTab->readOnly = 1; } } sqliteSafetyOn(db); /* Create a cursor to hold the database open */ if( db->aDb[iDb].pBt==0 ) return SQLITE_OK; rc = sqliteBtreeCursor(db->aDb[iDb].pBt, 2, 0, &curMain); if( rc ){ sqliteSetString(pzErrMsg, sqlite_error_string(rc), (char*)0); |
︙ | ︙ | |||
326 327 328 329 330 331 332 | return SQLITE_FORMAT; } sqliteBtreeSetCacheSize(db->aDb[iDb].pBt, db->cache_size); sqliteBtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[4]==0 ? 2 : meta[4]); /* Read the schema information out of the schema tables */ | < | | < < < | < > | > | | | > > > | 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 | return SQLITE_FORMAT; } sqliteBtreeSetCacheSize(db->aDb[iDb].pBt, db->cache_size); sqliteBtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[4]==0 ? 2 : meta[4]); /* Read the schema information out of the schema tables */ assert( db->init.busy ); sqliteSafetyOff(db); if( iDb==0 ){ rc = sqlite_exec(db, db->file_format>=2 ? init_script : older_init_script, sqliteInitCallback, &initData, 0); }else{ char *zSql = 0; sqliteSetString(&zSql, "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"", db->aDb[iDb].zName, "\".sqlite_master", (char*)0); rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0); sqliteFree(zSql); } sqliteSafetyOn(db); sqliteBtreeCloseCursor(curMain); if( sqlite_malloc_failed ){ sqliteSetString(pzErrMsg, "out of memory", (char*)0); rc = SQLITE_NOMEM; sqliteResetInternalSchema(db, 0); } if( rc==SQLITE_OK ){ DbSetProperty(db, iDb, DB_SchemaLoaded); if( iDb==0 ){ DbSetProperty(db, 1, DB_SchemaLoaded); } }else{ sqliteResetInternalSchema(db, iDb); } return rc; } /* ** Initialize all database files - the main database file, the file ** used to store temporary tables, and any additional database files ** created using ATTACH statements. Return a success code. If an ** error occurs, write an error message into *pzErrMsg. ** ** After the database is initialized, the SQLITE_Initialized ** bit is set in the flags field of the sqlite structure. An ** attempt is made to initialize the database as soon as it ** is opened. If that fails (perhaps because another process ** has the sqlite_master table locked) than another attempt ** is made the first time the database is accessed. */ int sqliteInit(sqlite *db, char **pzErrMsg){ int i, rc; if( db->init.busy ) return SQLITE_OK; assert( (db->flags & SQLITE_Initialized)==0 ); rc = SQLITE_OK; db->init.busy = 1; for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ if( DbHasProperty(db, i, DB_SchemaLoaded) ) continue; assert( i!=1 ); /* Should have been initialized together with 0 */ rc = sqliteInitOne(db, i, pzErrMsg); if( rc ){ sqliteResetInternalSchema(db, i); } } db->init.busy = 0; if( rc==SQLITE_OK ){ db->flags |= SQLITE_Initialized; sqliteCommitInternalChanges(db); } /* If the database is in formats 1 or 2, then upgrade it to ** version 3. This will reconstruct all indices. If the |
︙ | ︙ | |||
665 666 667 668 669 670 671 | sqlite_vm **ppVm, /* OUT: The virtual machine */ char **pzErrMsg /* OUT: Write error messages here */ ){ Parse sParse; if( pzErrMsg ) *pzErrMsg = 0; if( sqliteSafetyOn(db) ) goto exec_misuse; | > | | | > | | | | | | | | | | | | | | | | > > | 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 | sqlite_vm **ppVm, /* OUT: The virtual machine */ char **pzErrMsg /* OUT: Write error messages here */ ){ Parse sParse; if( pzErrMsg ) *pzErrMsg = 0; if( sqliteSafetyOn(db) ) goto exec_misuse; if( !db->init.busy ){ if( (db->flags & SQLITE_Initialized)==0 ){ int rc, cnt = 1; while( (rc = sqliteInit(db, pzErrMsg))==SQLITE_BUSY && db->xBusyCallback && db->xBusyCallback(db->pBusyArg, "", cnt++)!=0 ){} if( rc!=SQLITE_OK ){ sqliteStrRealloc(pzErrMsg); sqliteSafetyOff(db); return rc; } if( pzErrMsg ){ sqliteFree(*pzErrMsg); *pzErrMsg = 0; } } if( db->file_format<3 ){ sqliteSafetyOff(db); sqliteSetString(pzErrMsg, "obsolete database file format", (char*)0); return SQLITE_ERROR; } } assert( (db->flags & SQLITE_Initialized)!=0 || db->init.busy ); if( db->pVdbe==0 ){ db->nChange = 0; } memset(&sParse, 0, sizeof(sParse)); sParse.db = db; sParse.useCallback = 0; if( db->xTrace ) db->xTrace(db->pTraceArg, zSql); sqliteRunParser(&sParse, zSql, pzErrMsg); if( sqlite_malloc_failed ){ |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.212 2004/02/14 23:05:53 drh Exp $ */ #include "config.h" #include "sqlite.h" #include "hash.h" #include "vdbe.h" #include "parse.h" #include "btree.h" |
︙ | ︙ | |||
314 315 316 317 318 319 320 321 322 | int nDb; /* Number of backends currently in use */ Db *aDb; /* All backends */ Db aDbStatic[2]; /* Static space for the 2 default backends */ int flags; /* Miscellanous flags. See below */ u8 file_format; /* What file format version is this database? */ u8 safety_level; /* How aggressive at synching data to disk */ u8 want_to_close; /* Close after all VDBEs are deallocated */ int next_cookie; /* Next value of aDb[0].schema_cookie */ int cache_size; /* Number of pages to use in the cache */ | > > < < > > > > > | 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 | int nDb; /* Number of backends currently in use */ Db *aDb; /* All backends */ Db aDbStatic[2]; /* Static space for the 2 default backends */ int flags; /* Miscellanous flags. See below */ u8 file_format; /* What file format version is this database? */ u8 safety_level; /* How aggressive at synching data to disk */ u8 want_to_close; /* Close after all VDBEs are deallocated */ u8 temp_store; /* 1=file, 2=memory, 0=compile-time default */ u8 onError; /* Default conflict algorithm */ int next_cookie; /* Next value of aDb[0].schema_cookie */ int cache_size; /* Number of pages to use in the cache */ int nTable; /* Number of tables in the database */ void *pBusyArg; /* 1st Argument to the busy callback */ int (*xBusyCallback)(void *,const char*,int); /* The busy callback */ void *pCommitArg; /* Argument to xCommitCallback() */ int (*xCommitCallback)(void*);/* Invoked at every commit. */ Hash aFunc; /* All functions that can be in SQL exprs */ int lastRowid; /* ROWID of most recent insert */ int priorNewRowid; /* Last randomly generated ROWID */ int magic; /* Magic number for detect library misuse */ int nChange; /* Number of rows changed */ struct sqliteInitInfo { /* Information used during initialization */ int iDb; /* When back is being initialized */ int newTnum; /* Rootpage of table being initialized */ u8 busy; /* TRUE if currently initializing */ } init; struct Vdbe *pVdbe; /* List of active virtual machines */ void (*xTrace)(void*,const char*); /* Trace function */ void *pTraceArg; /* Argument to the trace function */ #ifndef SQLITE_OMIT_AUTHORIZATION int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); /* Access authorization function */ void *pAuthArg; /* 1st argument to the access auth function */ |
︙ | ︙ | |||
874 875 876 877 878 879 880 | Token sFirstToken; /* The first token parsed */ Token sLastToken; /* The last token parsed */ const char *zTail; /* All SQL text past the last semicolon parsed */ Table *pNewTable; /* A table being constructed by CREATE TABLE */ Vdbe *pVdbe; /* An engine for executing database bytecode */ u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */ u8 explain; /* True if the EXPLAIN flag is found on the query */ | < < < | 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 | Token sFirstToken; /* The first token parsed */ Token sLastToken; /* The last token parsed */ const char *zTail; /* All SQL text past the last semicolon parsed */ Table *pNewTable; /* A table being constructed by CREATE TABLE */ Vdbe *pVdbe; /* An engine for executing database bytecode */ u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */ u8 explain; /* True if the EXPLAIN flag is found on the query */ u8 nameClash; /* A permanent table name clashes with temp table name */ u8 useAgg; /* If true, extract field values from the aggregator ** while generating expressions. Normally false */ u8 useCallback; /* True if callbacks should be used to report results */ int nErr; /* Number of errors seen */ int nTab; /* Number of previously allocated VDBE cursors */ int nMem; /* Number of memory cells used so far */ int nSet; /* Number of sets used so far */ int nAgg; /* Number of aggregate expressions */ int nVar; /* Number of '?' variables seen in the SQL so far */ AggExpr *aAgg; /* An array of aggregate expressions */ |
︙ | ︙ |
Changes to src/trigger.c.
︙ | ︙ | |||
61 62 63 64 65 66 67 | ** 2. the table (or view) does exist in the same database as the trigger. ** 3. that we are not trying to create a trigger on the sqlite_master table ** 4. That we are not trying to create an INSTEAD OF trigger on a table. ** 5. That we are not trying to create a BEFORE or AFTER trigger on a view. */ if( sqlite_malloc_failed ) goto trigger_cleanup; assert( pTableName->nSrc==1 ); | | | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | ** 2. the table (or view) does exist in the same database as the trigger. ** 3. that we are not trying to create a trigger on the sqlite_master table ** 4. That we are not trying to create an INSTEAD OF trigger on a table. ** 5. That we are not trying to create a BEFORE or AFTER trigger on a view. */ if( sqlite_malloc_failed ) goto trigger_cleanup; assert( pTableName->nSrc==1 ); if( db->init.busy && sqliteFixInit(&sFix, pParse, db->init.iDb, "trigger", pName) && sqliteFixSrcList(&sFix, pTableName) ){ goto trigger_cleanup; } tab = sqliteSrcListLookup(pParse, pTableName); if( !tab ){ goto trigger_cleanup; } iDb = isTemp ? 1 : tab->iDb; if( iDb>=2 && !db->init.busy ){ sqliteErrorMsg(pParse, "triggers may not be added to auxiliary " "database %s", db->aDb[tab->iDb].zName); goto trigger_cleanup; } zName = sqliteStrNDup(pName->z, pName->n); sqliteDequote(zName); |
︙ | ︙ | |||
177 178 179 180 181 182 183 | && sqliteFixTriggerStep(&sFix, nt->step_list) ){ goto triggerfinish_cleanup; } /* if we are not initializing, and this trigger is not on a TEMP table, ** build the sqlite_master entry */ | | | 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | && sqliteFixTriggerStep(&sFix, nt->step_list) ){ goto triggerfinish_cleanup; } /* if we are not initializing, and this trigger is not on a TEMP table, ** build the sqlite_master entry */ if( !db->init.busy ){ static VdbeOp insertTrig[] = { { OP_NewRecno, 0, 0, 0 }, { OP_String, 0, 0, "trigger" }, { OP_String, 0, 0, 0 }, /* 2: trigger name */ { OP_String, 0, 0, 0 }, /* 3: table name */ { OP_Integer, 0, 0, 0 }, { OP_String, 0, 0, 0 }, /* 5: SQL */ |
︙ | ︙ |