aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/build.c45
-rw-r--r--src/main.c101
-rw-r--r--src/select.c4
-rw-r--r--src/sqliteInt.h3
-rw-r--r--src/vdbe.c9
-rw-r--r--src/where.c3
6 files changed, 104 insertions, 61 deletions
diff --git a/src/build.c b/src/build.c
index 2d452d8ce..14d8793fa 100644
--- a/src/build.c
+++ b/src/build.c
@@ -33,7 +33,7 @@
** COPY
** VACUUM
**
-** $Id: build.c,v 1.30 2001/09/13 14:46:10 drh Exp $
+** $Id: build.c,v 1.31 2001/09/13 16:18:54 drh Exp $
*/
#include "sqliteInt.h"
@@ -461,6 +461,14 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){
db->flags |= SQLITE_InternChanges;
}
+ /* If the initFlag 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.
+ */
+ if( pParse->initFlag ){
+ p->tnum = pParse->newTnum;
+ }
+
/* If not initializing, then create the table on disk.
*/
if( !pParse->initFlag ){
@@ -472,7 +480,7 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){
{ OP_CreateTable, 0, 0, 0},
{ OP_String, 0, 0, 0}, /* 5 */
{ OP_String, 0, 0, 0}, /* 6 */
- { OP_MakeRecord, 4, 0, 0},
+ { OP_MakeRecord, 5, 0, 0},
{ OP_Put, 0, 0, 0},
};
int n, base;
@@ -538,15 +546,16 @@ void sqliteDropTable(Parse *pParse, Token *pName){
if( v ){
static VdbeOp dropTable[] = {
{ OP_Open, 0, 2, 0},
- { OP_String, 0, 0, 0}, /* 1 */
- { OP_Next, 0, ADDR(9), 0}, /* 2 */
+ { OP_Rewind, 0, 0, 0},
+ { OP_String, 0, 0, 0}, /* 2 */
+ { OP_Next, 0, ADDR(10), 0}, /* 3 */
{ OP_Dup, 0, 0, 0},
{ OP_Column, 0, 3, 0},
- { OP_Ne, 0, ADDR(2), 0},
+ { OP_Ne, 0, ADDR(3), 0},
{ OP_Recno, 0, 0, 0},
{ OP_Delete, 0, 0, 0},
- { OP_Goto, 0, ADDR(2), 0},
- { OP_Destroy, 0, 0, 0}, /* 9 */
+ { OP_Goto, 0, ADDR(3), 0},
+ { OP_Destroy, 0, 0, 0}, /* 10 */
{ OP_Close, 0, 0, 0},
};
Index *pIdx;
@@ -554,7 +563,7 @@ void sqliteDropTable(Parse *pParse, Token *pName){
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
}
base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable);
- sqliteVdbeChangeP1(v, base+9, pTable->tnum);
+ sqliteVdbeChangeP1(v, base+10, pTable->tnum);
for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){
sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, 0, 0, 0);
}
@@ -694,6 +703,14 @@ void sqliteCreateIndex(
db->flags |= SQLITE_InternChanges;
}
+ /* If the initFlag 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.
+ */
+ if( pParse->initFlag ){
+ pIndex->tnum = pParse->newTnum;
+ }
+
/* If the initFlag 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.
@@ -740,6 +757,7 @@ void sqliteCreateIndex(
}
lbl1 = sqliteVdbeMakeLabel(v);
lbl2 = sqliteVdbeMakeLabel(v);
+ sqliteVdbeAddOp(v, OP_Rewind, 0, 0, 0, 0);
sqliteVdbeAddOp(v, OP_Next, 0, lbl2, 0, lbl1);
sqliteVdbeAddOp(v, OP_Recno, 0, 0, 0, 0);
for(i=0; i<pIndex->nColumn; i++){
@@ -795,14 +813,15 @@ void sqliteDropIndex(Parse *pParse, Token *pName){
if( v ){
static VdbeOp dropIndex[] = {
{ OP_Open, 0, 2, 0},
- { OP_String, 0, 0, 0}, /* 1 */
- { OP_Next, 0, ADDR(8), 0}, /* 2 */
+ { OP_Rewind, 0, 0, 0},
+ { OP_String, 0, 0, 0}, /* 2 */
+ { OP_Next, 0, ADDR(9), 0}, /* 3 */
{ OP_Dup, 0, 0, 0},
{ OP_Column, 0, 1, 0},
- { OP_Ne, 0, ADDR(2), 0},
+ { OP_Ne, 0, ADDR(3), 0},
{ OP_Recno, 0, 0, 0},
{ OP_Delete, 0, 0, 0},
- { OP_Destroy, 0, 0, 0}, /* 8 */
+ { OP_Destroy, 0, 0, 0}, /* 9 */
{ OP_Close, 0, 0, 0},
};
int base;
@@ -811,7 +830,7 @@ void sqliteDropIndex(Parse *pParse, Token *pName){
sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
}
base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex);
- sqliteVdbeChangeP1(v, base+8, pIndex->tnum);
+ sqliteVdbeChangeP1(v, base+9, pIndex->tnum);
if( (db->flags & SQLITE_InTrans)==0 ){
sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
}
diff --git a/src/main.c b/src/main.c
index 2301915f4..8704149c9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -26,7 +26,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.32 2001/09/13 15:21:32 drh Exp $
+** $Id: main.c,v 1.33 2001/09/13 16:18:54 drh Exp $
*/
#include "sqliteInt.h"
#if defined(HAVE_USLEEP) && HAVE_USLEEP
@@ -35,32 +35,40 @@
/*
** This is the callback routine for the code that initializes the
-** database. Each callback contains text of a CREATE TABLE or
-** CREATE INDEX statement that must be parsed to yield the internal
-** structures that describe the tables.
+** database. Each callback contains the following information:
+**
+** argv[0] = "meta" or "table" or "index"
+** argv[1] = table or index name
+** argv[2] = root page number for table or index
+** argv[3] = SQL create statement for the table or index
**
-** This callback is also called with argc==2 when there is meta
-** information in the sqlite_master file. The meta information is
-** contained in argv[1]. Typical meta information is the file format
-** version.
*/
static int sqliteOpenCb(void *pDb, int argc, char **argv, char **azColName){
sqlite *db = (sqlite*)pDb;
Parse sParse;
- int nErr;
+ int nErr = 0;
- if( argc==2 ){
- if( sscanf(argv[1],"file format %d",&db->file_format)==1 ){
- return 0;
+ assert( argc==4 );
+ switch( argv[0][0] ){
+ case 'm': { /* Meta information */
+ sscanf(argv[1],"file format %d",&db->file_format);
+ break;
+ }
+ case 'i':
+ case 't': { /* CREATE TABLE and CREATE INDEX statements */
+ memset(&sParse, 0, sizeof(sParse));
+ sParse.db = db;
+ sParse.initFlag = 1;
+ sParse.newTnum = atoi(argv[2]);
+ nErr = sqliteRunParser(&sParse, argv[3], 0);
+ break;
+ }
+ default: {
+ /* This can not happen! */
+ nErr = 1;
+ assert( nErr==0 );
}
- /* Unknown meta information. Ignore it. */
- return 0;
}
- if( argc!=1 ) return 0;
- memset(&sParse, 0, sizeof(sParse));
- sParse.db = db;
- sParse.initFlag = 1;
- nErr = sqliteRunParser(&sParse, argv[0], 0);
return nErr;
}
@@ -129,31 +137,40 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){
*/
static VdbeOp initProg[] = {
{ OP_Open, 0, 2, 0},
- { OP_Next, 0, 9, 0}, /* 1 */
+ { OP_Rewind, 0, 0, 0},
+ { OP_Next, 0, 12, 0}, /* 2 */
{ OP_Column, 0, 0, 0},
{ OP_String, 0, 0, "meta"},
- { OP_Ne, 0, 1, 0},
+ { OP_Ne, 0, 2, 0},
{ OP_Column, 0, 0, 0},
+ { OP_Column, 0, 1, 0},
+ { OP_Column, 0, 2, 0},
{ OP_Column, 0, 4, 0},
- { OP_Callback, 2, 0, 0},
- { OP_Goto, 0, 1, 0},
- { OP_Rewind, 0, 0, 0}, /* 9 */
- { OP_Next, 0, 17, 0}, /* 10 */
+ { OP_Callback, 4, 0, 0},
+ { OP_Goto, 0, 2, 0},
+ { OP_Rewind, 0, 0, 0}, /* 12 */
+ { OP_Next, 0, 23, 0}, /* 13 */
{ OP_Column, 0, 0, 0},
{ OP_String, 0, 0, "table"},
- { OP_Ne, 0, 10, 0},
+ { OP_Ne, 0, 13, 0},
+ { OP_Column, 0, 0, 0},
+ { OP_Column, 0, 1, 0},
+ { OP_Column, 0, 2, 0},
{ OP_Column, 0, 4, 0},
- { OP_Callback, 1, 0, 0},
- { OP_Goto, 0, 10, 0},
- { OP_Rewind, 0, 0, 0}, /* 17 */
- { OP_Next, 0, 25, 0}, /* 18 */
+ { OP_Callback, 4, 0, 0},
+ { OP_Goto, 0, 13, 0},
+ { OP_Rewind, 0, 0, 0}, /* 23 */
+ { OP_Next, 0, 34, 0}, /* 24 */
{ OP_Column, 0, 0, 0},
{ OP_String, 0, 0, "index"},
- { OP_Ne, 0, 18, 0},
+ { OP_Ne, 0, 24, 0},
+ { OP_Column, 0, 0, 0},
+ { OP_Column, 0, 1, 0},
+ { OP_Column, 0, 2, 0},
{ OP_Column, 0, 4, 0},
- { OP_Callback, 1, 0, 0},
- { OP_Goto, 0, 18, 0},
- { OP_Close, 2, 0, 0}, /* 25 */
+ { OP_Callback, 4, 0, 0},
+ { OP_Goto, 0, 24, 0},
+ { OP_Close, 0, 0, 0}, /* 34 */
{ OP_Halt, 0, 0, 0},
};
@@ -169,20 +186,22 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){
rc = sqliteVdbeExec(vdbe, sqliteOpenCb, db, pzErrMsg,
db->pBusyArg, db->xBusyCallback);
sqliteVdbeDelete(vdbe);
- if( rc==SQLITE_OK && db->file_format<2 && db->nTable>0 ){
- sqliteSetString(pzErrMsg, "obsolete file format", 0);
+ if( rc==SQLITE_OK && db->file_format>1 && db->nTable>0 ){
+ sqliteSetString(pzErrMsg, "unsupported file format", 0);
rc = SQLITE_ERROR;
}
if( rc==SQLITE_OK ){
Table *pTab;
- char *azArg[2];
- azArg[0] = master_schema;
- azArg[1] = 0;
- sqliteOpenCb(db, 1, azArg, 0);
+ char *azArg[5];
+ azArg[0] = "table";
+ azArg[1] = MASTER_NAME;
+ azArg[2] = "2";
+ azArg[3] = master_schema;
+ azArg[4] = 0;
+ sqliteOpenCb(db, 4, azArg, 0);
pTab = sqliteFindTable(db, MASTER_NAME);
if( pTab ){
pTab->readOnly = 1;
- pTab->tnum = 2;
}
db->flags |= SQLITE_Initialized;
sqliteCommitInternalChanges(db);
diff --git a/src/select.c b/src/select.c
index ea29e1251..e0e38a1e3 100644
--- a/src/select.c
+++ b/src/select.c
@@ -24,7 +24,7 @@
** This file contains C code routines that are called by the parser
** to handle SELECT statements.
**
-** $Id: select.c,v 1.33 2001/09/13 14:46:10 drh Exp $
+** $Id: select.c,v 1.34 2001/09/13 16:18:54 drh Exp $
*/
#include "sqliteInt.h"
@@ -549,6 +549,7 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
if( p->pOrderBy ){
sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0);
}
+ sqliteVdbeAddOp(v, OP_Rewind, unionTab, 0, 0, 0);
iBreak = sqliteVdbeMakeLabel(v);
iCont = sqliteVdbeAddOp(v, OP_Next, unionTab, iBreak, 0, 0);
rc = selectInnerLoop(pParse, 0, unionTab, p->pEList->nExpr,
@@ -601,6 +602,7 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
if( p->pOrderBy ){
sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0);
}
+ sqliteVdbeAddOp(v, OP_Rewind, tab1, 0, 0, 0);
iBreak = sqliteVdbeMakeLabel(v);
iCont = sqliteVdbeAddOp(v, OP_Next, tab1, iBreak, 0, 0);
sqliteVdbeAddOp(v, OP_FullKey, tab1, 0, 0, 0);
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index bc4a1125b..71d1e0294 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -23,7 +23,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.44 2001/09/13 14:46:10 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.45 2001/09/13 16:18:54 drh Exp $
*/
#include "sqlite.h"
#include "vdbe.h"
@@ -359,6 +359,7 @@ struct Parse {
int colNamesSet; /* TRUE after OP_ColumnCount has been issued to pVdbe */
int explain; /* True if the EXPLAIN flag is found on the query */
int initFlag; /* True if reparsing CREATE TABLEs */
+ int newTnum; /* Table number to use when reparsing CREATE TABLEs */
int nErr; /* Number of errors seen */
int nTab; /* Number of previously allocated cursors */
int nMem; /* Number of memory cells used so far */
diff --git a/src/vdbe.c b/src/vdbe.c
index ba47f1b36..1133c1886 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -41,7 +41,7 @@
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
-** $Id: vdbe.c,v 1.62 2001/09/13 15:21:32 drh Exp $
+** $Id: vdbe.c,v 1.63 2001/09/13 16:18:54 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@@ -1798,11 +1798,11 @@ case OP_MakeRecord: {
j = 0;
addr = sizeof(int)*nField;
for(i=p->tos-nField+1; i<=p->tos; i++){
+ memcpy(&zNewRecord[j], (char*)&addr, sizeof(int));
+ j += sizeof(int);
if( (aStack[i].flags & STK_Null)==0 ){
addr += aStack[i].n;
}
- memcpy(&zNewRecord[j], (char*)&addr, sizeof(int));
- j += sizeof(int);
}
for(i=p->tos-nField+1; i<=p->tos; i++){
if( (aStack[i].flags & STK_Null)==0 ){
@@ -2300,7 +2300,7 @@ case OP_KeyAsData: {
case OP_Column: {
int amt, offset, nCol, payloadSize;
int aHdr[10];
- const int mxHdr = sizeof(aHdr)/sizeof(aHdr[0]);
+ static const int mxHdr = sizeof(aHdr)/sizeof(aHdr[0]);
int i = pOp->p1;
int p2 = pOp->p2;
int tos = ++p->tos;
@@ -2338,6 +2338,7 @@ case OP_Column: {
if( p2+1<mxHdr ){
(*xRead)(pCrsr, 0, sizeof(aHdr[0])*(p2+2), (char*)aHdr);
nCol = aHdr[0];
+ nCol /= sizeof(int);
offset = aHdr[p2];
if( p2 == nCol-1 ){
amt = payloadSize - offset;
diff --git a/src/where.c b/src/where.c
index 33cb3897d..91ffa143e 100644
--- a/src/where.c
+++ b/src/where.c
@@ -25,7 +25,7 @@
** the WHERE clause of SQL statements. Also found here are subroutines
** to generate VDBE code to evaluate expressions.
**
-** $Id: where.c,v 1.17 2001/09/13 14:46:11 drh Exp $
+** $Id: where.c,v 1.18 2001/09/13 16:18:55 drh Exp $
*/
#include "sqliteInt.h"
@@ -358,6 +358,7 @@ WhereInfo *sqliteWhereBegin(
/* Case 2: There was no usable index. We must do a complete
** scan of the table.
*/
+ sqliteVdbeAddOp(v, OP_Rewind, base+idx, 0, 0, 0);
cont = sqliteVdbeMakeLabel(v);
sqliteVdbeAddOp(v, OP_Next, base+idx, brk, 0, cont);
haveKey = 0;