︙ | | |
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
|
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.168 2004/02/14 16:31:03 drh Exp $
** $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 && pParse->initFlag==0 ){
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
474
475
476
477
478
479
480
481
|
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( pParse->iDb==1 ) isTemp = 1;
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
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
|
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 : pParse->iDb;
if( pTable!=0 && (pTable->iDb==iDb || !pParse->initFlag) ){
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 || !pParse->initFlag) ){
(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
573
574
575
576
577
578
579
580
|
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( !pParse->initFlag && (v = sqliteGetVdbe(pParse))!=0 ){
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
930
931
932
933
934
935
936
937
938
|
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 initFlag==1. When initFlag==1,
** 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
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
|
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 initFlag is 1 it means we are reading the SQL off the
/* 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 pParse->newTnum field. (The page number
** for the table from the db->init.newTnum field. (The page number
** should have been put there by the sqliteOpenCb routine.)
*/
if( pParse->initFlag ){
p->tnum = pParse->newTnum;
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( !pParse->initFlag ){
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
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
|
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, P3_STATIC);
sqliteVdbeChangeP3(v, -1, p->zName, 0);
sqliteVdbeAddOp(v, OP_String, 0, 0);
sqliteVdbeChangeP3(v, -1, p->zName, P3_STATIC);
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
1092
1093
1094
1095
1096
1097
1098
1099
|
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->initFlag ){
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
1570
1571
1572
1573
1574
1575
1576
1577
1578
|
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( pParse->initFlag
&& sqliteFixInit(&sFix, pParse, pParse->iDb, "index", pName)
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
1595
1596
1597
1598
1599
1600
1601
1602
|
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 && pParse->initFlag==0 ){
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
1621
1622
1623
1624
1625
1626
1627
1628
|
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 && !pParse->initFlag ){
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
1657
1658
1659
1660
1661
1662
1663
1664
|
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==pParse->iDb || isTemp );
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
1693
1694
1695
1696
1697
1698
1699
1700
|
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 : pParse->iDb;
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
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
|
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 initFlag is 1 it means we are reading the SQL off the
/* 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 pParse->newTnum field.
** again. Extract the table number from the db->init.newTnum field.
*/
if( pParse->initFlag && pTable!=0 ){
pIndex->tnum = pParse->newTnum;
if( db->init.busy && pTable!=0 ){
pIndex->tnum = db->init.newTnum;
}
/* If the initFlag is 0 then create the index on disk. This
/* 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 initFlag is 0 when the user first enters a CREATE INDEX
** command. The initFlag is 1 when a database is opened and
** 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( pParse->initFlag==0 ){
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, P3_STATIC);
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, P3_STATIC);
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);
|
︙ | | |
︙ | | |
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
|
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.153 2004/02/14 17:35:07 drh Exp $
** $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){
sqliteSetString(pData->pzErrMsg, "malformed database schema", (char*)0);
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;
Parse sParse;
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);
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);
corruptSchema(pData, 0);
return 1;
}
if( argv[3] && argv[3][0] ){
/* Call the parser to process a CREATE TABLE, INDEX or VIEW.
** But because sParse.initFlag is set to 1, no VDBE code is generated
** 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.
*/
memset(&sParse, 0, sizeof(sParse));
sParse.db = pData->db;
sParse.initFlag = 1;
sParse.iDb = atoi(argv[4]);
sParse.newTnum = atoi(argv[2]);
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]);
sParse.useCallback = 1;
sqliteRunParser(&sParse, argv[3], pData->pzErrMsg);
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<pData->db->nDb );
pIndex = sqliteFindIndex(pData->db, argv[1], pData->db->aDb[iDb].zName);
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
191
192
193
194
195
196
197
198
|
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];
Parse sParse;
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
|
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
|
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
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
|
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
*/
memset(&sParse, 0, sizeof(sParse));
sParse.db = db;
sParse.xCallback = sqliteInitCallback;
assert( db->init.busy );
sqliteSafetyOff(db);
sParse.pArg = (void*)&initData;
sParse.initFlag = 1;
sParse.useCallback = 1;
if( iDb==0 ){
sqliteRunParser(&sParse,
rc = sqlite_exec(db,
db->file_format>=2 ? init_script : older_init_script,
pzErrMsg);
sqliteInitCallback, &initData, 0);
}else{
char *zSql = 0;
sqliteSetString(&zSql,
"SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
db->aDb[iDb].zName, "\".sqlite_master", (char*)0);
sqliteRunParser(&sParse, zSql, pzErrMsg);
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);
sParse.rc = SQLITE_NOMEM;
rc = SQLITE_NOMEM;
sqliteResetInternalSchema(db, 0);
}
if( sParse.rc==SQLITE_OK ){
if( rc==SQLITE_OK ){
DbSetProperty(db, iDb, DB_SchemaLoaded);
if( iDb==0 ){
DbSetProperty(db, 1, DB_SchemaLoaded);
}
}else{
sqliteResetInternalSchema(db, iDb);
}
return sParse.rc;
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
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
|
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;
}
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 ){
|
︙ | | |