Upgrade bundled library to 2.8.14 + misc fixes

(http://www.sqlite.org/cvstrac/chngview?cn=1742)
This commit is contained in:
Wez Furlong 2004-07-10 12:27:51 +00:00
parent cd732f1a3f
commit e563b4eafa
43 changed files with 5953 additions and 5559 deletions

View file

@ -38,7 +38,7 @@ 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;
@ -54,17 +54,6 @@ void sqliteBeginParse(Parse *pParse, int explainFlag){
pParse->nVar = 0;
}
/*
** This is a fake callback procedure used when sqlite_exec() is
** invoked with a NULL callback pointer. If we pass a NULL callback
** pointer into sqliteVdbeExec() it will return at every OP_Callback,
** which we do not want it to do. So we substitute a pointer to this
** procedure in place of the NULL.
*/
static int fakeCallback(void *NotUsed, int n, char **az1, char **az2){
return 0;
}
/*
** This routine is called after a single SQL statement has been
** parsed and we want to execute the VDBE code to implement
@ -76,36 +65,20 @@ static int fakeCallback(void *NotUsed, int n, char **az1, char **az2){
** no VDBE code was generated.
*/
void sqliteExec(Parse *pParse){
int rc = SQLITE_OK;
sqlite *db = pParse->db;
Vdbe *v = pParse->pVdbe;
int (*xCallback)(void*,int,char**,char**);
if( v==0 && (v = sqliteGetVdbe(pParse))!=0 ){
sqliteVdbeAddOp(v, OP_Halt, 0, 0);
}
if( sqlite_malloc_failed ) return;
xCallback = pParse->xCallback;
if( xCallback==0 && pParse->useCallback ) xCallback = fakeCallback;
if( v && pParse->nErr==0 ){
FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
sqliteVdbeTrace(v, trace);
sqliteVdbeMakeReady(v, pParse->nVar, xCallback, pParse->pArg,
pParse->explain);
if( pParse->useCallback ){
if( pParse->explain ){
rc = sqliteVdbeList(v);
db->next_cookie = db->aDb[0].schema_cookie;
}else{
sqliteVdbeExec(v);
}
rc = sqliteVdbeFinalize(v, &pParse->zErrMsg);
if( rc ) pParse->nErr++;
pParse->pVdbe = 0;
pParse->rc = rc;
if( rc ) pParse->nErr++;
}else{
pParse->rc = pParse->nErr ? SQLITE_ERROR : SQLITE_DONE;
}
sqliteVdbeMakeReady(v, pParse->nVar, pParse->explain);
pParse->rc = pParse->nErr ? SQLITE_ERROR : SQLITE_DONE;
pParse->colNamesSet = 0;
}else if( pParse->useCallback==0 ){
}else if( pParse->rc==SQLITE_OK ){
pParse->rc = SQLITE_ERROR;
}
pParse->nTab = 0;
@ -240,7 +213,7 @@ void sqliteUnlinkAndDeleteIndex(sqlite *db, Index *pIndex){
**
** If iDb<=0 then reset the internal schema tables for all database
** files. If iDb>=2 then reset the internal schema for only the
** single file indicates.
** single file indicated.
*/
void sqliteResetInternalSchema(sqlite *db, int iDb){
HashElem *pElem;
@ -280,10 +253,18 @@ void sqliteResetInternalSchema(sqlite *db, int iDb){
** schema hash tables and therefore do not have to make any changes
** to any of those tables.
*/
for(i=0; i<db->nDb; i++){
struct Db *pDb = &db->aDb[i];
if( pDb->pBt==0 ){
if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux);
pDb->pAux = 0;
}
}
for(i=j=2; i<db->nDb; i++){
if( db->aDb[i].pBt==0 ){
sqliteFree(db->aDb[i].zName);
db->aDb[i].zName = 0;
struct Db *pDb = &db->aDb[i];
if( pDb->pBt==0 ){
sqliteFree(pDb->zName);
pDb->zName = 0;
continue;
}
if( j<i ){
@ -456,7 +437,7 @@ void sqliteStartTable(
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 );
{
@ -493,17 +474,16 @@ void sqliteStartTable(
if( isTemp && db->aDb[1].pBt==0 && !pParse->explain ){
int rc = sqliteBtreeFactory(db, 0, 0, MAX_PAGES, &db->aDb[1].pBt);
if( rc!=SQLITE_OK ){
sqliteSetString(&pParse->zErrMsg, "unable to open a temporary database "
"file for storing temporary tables", (char*)0);
sqliteErrorMsg(pParse, "unable to open a temporary database "
"file for storing temporary tables");
pParse->nErr++;
return;
}
if( db->flags & SQLITE_InTrans ){
rc = sqliteBtreeBeginTrans(db->aDb[1].pBt);
if( rc!=SQLITE_OK ){
sqliteSetNString(&pParse->zErrMsg, "unable to get a write lock on "
"the temporary database file", 0);
pParse->nErr++;
sqliteErrorMsg(pParse, "unable to get a write lock on "
"the temporary database file");
return;
}
}
@ -517,20 +497,16 @@ void sqliteStartTable(
** 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) ){
sqliteSetNString(&pParse->zErrMsg, "table ", 0, pName->z, pName->n,
" already exists", 0, 0);
iDb = isTemp ? 1 : db->init.iDb;
if( pTable!=0 && (pTable->iDb==iDb || !db->init.busy) ){
sqliteErrorMsg(pParse, "table %T already exists", pName);
sqliteFree(zName);
pParse->nErr++;
return;
}
if( (pIdx = sqliteFindIndex(db, zName, 0))!=0 &&
(pIdx->iDb==0 || !pParse->initFlag) ){
sqliteSetString(&pParse->zErrMsg, "there is already an index named ",
zName, (char*)0);
(pIdx->iDb==0 || !db->init.busy) ){
sqliteErrorMsg(pParse, "there is already an index named %s", zName);
sqliteFree(zName);
pParse->nErr++;
return;
}
pTable = sqliteMalloc( sizeof(Table) );
@ -555,7 +531,7 @@ void sqliteStartTable(
** 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);
@ -588,8 +564,7 @@ void sqliteAddColumn(Parse *pParse, Token *pName){
sqliteDequote(z);
for(i=0; i<p->nCol; i++){
if( sqliteStrICmp(z, p->aCol[i].zName)==0 ){
sqliteSetString(&pParse->zErrMsg, "duplicate column name: ", z, (char*)0);
pParse->nErr++;
sqliteErrorMsg(pParse, "duplicate column name: %s", z);
sqliteFree(z);
return;
}
@ -708,9 +683,8 @@ void sqliteAddPrimaryKey(Parse *pParse, IdList *pList, int onError){
int iCol = -1, i;
if( pTab==0 ) goto primary_key_exit;
if( pTab->hasPrimKey ){
sqliteSetString(&pParse->zErrMsg, "table \"", pTab->zName,
"\" has more than one primary key", (char*)0);
pParse->nErr++;
sqliteErrorMsg(pParse,
"table \"%s\" has more than one primary key", pTab->zName);
goto primary_key_exit;
}
pTab->hasPrimKey = 1;
@ -753,34 +727,16 @@ primary_key_exit:
*/
int sqliteCollateType(const char *zType, int nType){
int i;
for(i=0; i<nType-1; i++){
switch( zType[i] ){
case 'b':
case 'B': {
if( i<nType-3 && sqliteStrNICmp(&zType[i],"blob",4)==0 ){
return SQLITE_SO_TEXT;
}
break;
}
case 'c':
case 'C': {
if( i<nType-3 && (sqliteStrNICmp(&zType[i],"char",4)==0 ||
sqliteStrNICmp(&zType[i],"clob",4)==0)
){
return SQLITE_SO_TEXT;
}
break;
}
case 'x':
case 'X': {
if( i>=2 && sqliteStrNICmp(&zType[i-2],"text",4)==0 ){
return SQLITE_SO_TEXT;
}
break;
}
default: {
break;
}
for(i=0; i<nType-3; i++){
int c = *(zType++) | 0x60;
if( (c=='b' || c=='c') && sqliteStrNICmp(zType, "lob", 3)==0 ){
return SQLITE_SO_TEXT;
}
if( c=='c' && sqliteStrNICmp(zType, "har", 3)==0 ){
return SQLITE_SO_TEXT;
}
if( c=='t' && sqliteStrNICmp(zType, "ext", 3)==0 ){
return SQLITE_SO_TEXT;
}
}
return SQLITE_SO_NUM;
@ -819,7 +775,9 @@ void sqliteAddCollateType(Parse *pParse, int collType){
*/
void sqliteChangeCookie(sqlite *db, Vdbe *v){
if( db->next_cookie==db->aDb[0].schema_cookie ){
db->next_cookie = db->aDb[0].schema_cookie + sqliteRandomByte() + 1;
unsigned char r;
sqliteRandomness(1, &r);
db->next_cookie = db->aDb[0].schema_cookie + r + 1;
db->flags |= SQLITE_InternChanges;
sqliteVdbeAddOp(v, OP_Integer, db->next_cookie, 0);
sqliteVdbeAddOp(v, OP_SetCookie, 0, 0);
@ -910,8 +868,8 @@ static char *createTableStmt(Table *p){
** 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
@ -944,14 +902,14 @@ void sqliteEndTable(Parse *pParse, Token *pEnd, Select *pSelect){
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
@ -961,7 +919,7 @@ void sqliteEndTable(Parse *pParse, Token *pEnd, Select *pSelect){
** 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;
@ -969,24 +927,16 @@ void sqliteEndTable(Parse *pParse, Token *pEnd, Select *pSelect){
if( v==0 ) return;
if( p->pSelect==0 ){
/* A regular table */
sqliteVdbeAddOp(v, OP_CreateTable, 0, p->iDb);
sqliteVdbeChangeP3(v, -1, (char *)&p->tnum, P3_POINTER);
sqliteVdbeOp3(v, OP_CreateTable, 0, p->iDb, (char*)&p->tnum, P3_POINTER);
}else{
/* A view */
sqliteVdbeAddOp(v, OP_Integer, 0, 0);
}
p->tnum = 0;
sqliteVdbeAddOp(v, OP_Pull, 1, 0);
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);
sqliteVdbeAddOp(v, OP_String, 0, 0);
sqliteVdbeChangeP3(v, -1, p->zName, P3_STATIC);
sqliteVdbeOp3(v, OP_String, 0, 0, p->pSelect==0?"table":"view", P3_STATIC);
sqliteVdbeOp3(v, OP_String, 0, 0, p->zName, 0);
sqliteVdbeOp3(v, OP_String, 0, 0, p->zName, 0);
sqliteVdbeAddOp(v, OP_Dup, 4, 0);
sqliteVdbeAddOp(v, OP_String, 0, 0);
if( pSelect ){
@ -1072,7 +1022,7 @@ void sqliteCreateView(
*/
p->pSelect = sqliteSelectDup(pSelect);
sqliteSelectDelete(pSelect);
if( !pParse->initFlag ){
if( !pParse->db->init.busy ){
sqliteViewGetColumnNames(pParse, p);
}
@ -1084,7 +1034,7 @@ void sqliteCreateView(
sEnd.z += sEnd.n;
}
sEnd.n = 0;
n = (char *) sEnd.z - (char *) pBegin->z;
n = sEnd.z - pBegin->z;
z = pBegin->z;
while( n>0 && (z[n-1]==';' || isspace(z[n-1])) ){ n--; }
sEnd.z = &z[n-1];
@ -1098,7 +1048,7 @@ void sqliteCreateView(
/*
** 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 pPare->zErrMsg.
** of errors. If an error is seen leave an error message in pParse->zErrMsg.
*/
int sqliteViewGetColumnNames(Parse *pParse, Table *pTable){
ExprList *pEList;
@ -1124,9 +1074,7 @@ int sqliteViewGetColumnNames(Parse *pParse, Table *pTable){
** should always fail. But we will leave it in place just to be safe.
*/
if( pTable->nCol<0 ){
sqliteSetString(&pParse->zErrMsg, "view ", pTable->zName,
" is circularly defined", (char*)0);
pParse->nErr++;
sqliteErrorMsg(pParse, "view %s is circularly defined", pTable->zName);
return 1;
}
@ -1176,12 +1124,12 @@ int sqliteViewGetColumnNames(Parse *pParse, Table *pTable){
*/
static void sqliteViewResetColumnNames(Table *pTable){
int i;
if( pTable==0 || pTable->pSelect==0 ) return;
if( pTable->nCol==0 ) return;
for(i=0; i<pTable->nCol; i++){
sqliteFree(pTable->aCol[i].zName);
sqliteFree(pTable->aCol[i].zDflt);
sqliteFree(pTable->aCol[i].zType);
Column *pCol;
assert( pTable!=0 && pTable->pSelect!=0 );
for(i=0, pCol=pTable->aCol; i<pTable->nCol; i++, pCol++){
sqliteFree(pCol->zName);
sqliteFree(pCol->zDflt);
sqliteFree(pCol->zType);
}
sqliteFree(pTable->aCol);
pTable->aCol = 0;
@ -1215,9 +1163,7 @@ Table *sqliteTableFromToken(Parse *pParse, Token *pTok){
pTab = sqliteFindTable(pParse->db, zName, 0);
sqliteFree(zName);
if( pTab==0 ){
sqliteSetNString(&pParse->zErrMsg, "no such table: ", 0,
pTok->z, pTok->n, 0);
pParse->nErr++;
sqliteErrorMsg(pParse, "no such table: %T", pTok);
}
return pTab;
}
@ -1268,21 +1214,16 @@ void sqliteDropTable(Parse *pParse, Token *pName, int isView){
}
#endif
if( pTable->readOnly ){
sqliteSetString(&pParse->zErrMsg, "table ", pTable->zName,
" may not be dropped", (char*)0);
sqliteErrorMsg(pParse, "table %s may not be dropped", pTable->zName);
pParse->nErr++;
return;
}
if( isView && pTable->pSelect==0 ){
sqliteSetString(&pParse->zErrMsg, "use DROP TABLE to delete table ",
pTable->zName, (char*)0);
pParse->nErr++;
sqliteErrorMsg(pParse, "use DROP TABLE to delete table %s", pTable->zName);
return;
}
if( !isView && pTable->pSelect ){
sqliteSetString(&pParse->zErrMsg, "use DROP VIEW to delete view ",
pTable->zName, (char*)0);
pParse->nErr++;
sqliteErrorMsg(pParse, "use DROP VIEW to delete view %s", pTable->zName);
return;
}
@ -1291,7 +1232,7 @@ void sqliteDropTable(Parse *pParse, Token *pName, int isView){
*/
v = sqliteGetVdbe(pParse);
if( v ){
static VdbeOp dropTable[] = {
static VdbeOpList dropTable[] = {
{ OP_Rewind, 0, ADDR(8), 0},
{ OP_String, 0, 0, 0}, /* 1 */
{ OP_MemStore, 1, 1, 0},
@ -1425,19 +1366,16 @@ void sqliteCreateForeignKey(
int iCol = p->nCol-1;
if( iCol<0 ) goto fk_end;
if( pToCol && pToCol->nId!=1 ){
sqliteSetNString(&pParse->zErrMsg, "foreign key on ", -1,
p->aCol[iCol].zName, -1,
" should reference only one column of table ", -1,
pTo->z, pTo->n, 0);
pParse->nErr++;
sqliteErrorMsg(pParse, "foreign key on %s"
" should reference only one column of table %T",
p->aCol[iCol].zName, pTo);
goto fk_end;
}
nCol = 1;
}else if( pToCol && pToCol->nId!=pFromCol->nId ){
sqliteSetString(&pParse->zErrMsg,
sqliteErrorMsg(pParse,
"number of columns in foreign key does not match the number of "
"columns in the referenced table", (char*)0);
pParse->nErr++;
"columns in the referenced table");
goto fk_end;
}else{
nCol = pFromCol->nId;
@ -1473,9 +1411,9 @@ void sqliteCreateForeignKey(
}
}
if( j>=p->nCol ){
sqliteSetString(&pParse->zErrMsg, "unknown column \"",
pFromCol->a[i].zName, "\" in foreign key definition", (char*)0);
pParse->nErr++;
sqliteErrorMsg(pParse,
"unknown column \"%s\" in foreign key definition",
pFromCol->a[i].zName);
goto fk_end;
}
}
@ -1550,8 +1488,8 @@ void sqliteCreateIndex(
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;
@ -1570,20 +1508,15 @@ void sqliteCreateIndex(
}
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++;
sqliteErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
goto exit_create_index;
}
if( pTab->iDb>=2 && pParse->initFlag==0 ){
sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName,
" may not have indices added", (char*)0);
pParse->nErr++;
if( pTab->iDb>=2 && db->init.busy==0 ){
sqliteErrorMsg(pParse, "table %s may not have indices added", pTab->zName);
goto exit_create_index;
}
if( pTab->pSelect ){
sqliteSetString(&pParse->zErrMsg, "views may not be indexed", (char*)0);
pParse->nErr++;
sqliteErrorMsg(pParse, "views may not be indexed");
goto exit_create_index;
}
isTemp = pTab->iDb==1;
@ -1601,21 +1534,17 @@ void sqliteCreateIndex(
** 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);
pParse->nErr++;
sqliteErrorMsg(pParse, "index %s already exists", zName);
goto exit_create_index;
}
if( (pTSameName = sqliteFindTable(db, zName, 0))!=0 ){
sqliteSetString(&pParse->zErrMsg, "there is already a table named ",
zName, (char*)0);
pParse->nErr++;
sqliteErrorMsg(pParse, "there is already a table named %s", zName);
goto exit_create_index;
}
}else if( pName==0 ){
@ -1637,7 +1566,7 @@ void sqliteCreateIndex(
{
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;
}
@ -1673,7 +1602,7 @@ void sqliteCreateIndex(
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
@ -1684,9 +1613,8 @@ void sqliteCreateIndex(
if( sqliteStrICmp(pList->a[i].zName, pTab->aCol[j].zName)==0 ) break;
}
if( j>=pTab->nCol ){
sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName,
" has no column named ", pList->a[i].zName, (char*)0);
pParse->nErr++;
sqliteErrorMsg(pParse, "table %s has no column named %s",
pTab->zName, pList->a[i].zName);
sqliteFree(pIndex);
goto exit_create_index;
}
@ -1726,20 +1654,20 @@ void sqliteCreateIndex(
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.
@ -1749,7 +1677,7 @@ void sqliteCreateIndex(
** 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;
@ -1763,19 +1691,17 @@ void sqliteCreateIndex(
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, P3_STATIC);
sqliteVdbeAddOp(v, OP_String, 0, 0);
sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
addr = sqliteVdbeAddOp(v, OP_CreateIndex, 0, isTemp);
sqliteVdbeChangeP3(v, addr, (char*)&pIndex->tnum, P3_POINTER);
sqliteVdbeOp3(v, OP_String, 0, 0, "index", P3_STATIC);
sqliteVdbeOp3(v, OP_String, 0, 0, pIndex->zName, 0);
sqliteVdbeOp3(v, OP_String, 0, 0, pTab->zName, 0);
sqliteVdbeOp3(v, OP_CreateIndex, 0, isTemp,(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);
sqliteVdbeCode(v,
OP_Dup, 0, 0,
OP_Integer, isTemp, 0,
OP_OpenWrite, 1, 0,
0);
}
addr = sqliteVdbeAddOp(v, OP_String, 0, 0);
if( pStart && pEnd ){
@ -1786,8 +1712,7 @@ void sqliteCreateIndex(
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);
sqliteVdbeOp3(v, OP_OpenRead, 2, pTab->tnum, pTab->zName, 0);
lbl2 = sqliteVdbeMakeLabel(v);
sqliteVdbeAddOp(v, OP_Rewind, 2, lbl2);
lbl1 = sqliteVdbeAddOp(v, OP_Recno, 2, 0);
@ -1801,8 +1726,8 @@ void sqliteCreateIndex(
}
sqliteVdbeAddOp(v, OP_MakeIdxKey, pIndex->nColumn, 0);
if( db->file_format>=4 ) sqliteAddIdxKeyType(v, pIndex);
sqliteVdbeAddOp(v, OP_IdxPut, 1, pIndex->onError!=OE_None);
sqliteVdbeChangeP3(v, -1, "indexed columns are not unique", P3_STATIC);
sqliteVdbeOp3(v, OP_IdxPut, 1, pIndex->onError!=OE_None,
"indexed columns are not unique", P3_STATIC);
sqliteVdbeAddOp(v, OP_Next, 2, lbl1);
sqliteVdbeResolveLabel(v, lbl2);
sqliteVdbeAddOp(v, OP_Close, 2, 0);
@ -1870,7 +1795,7 @@ void sqliteDropIndex(Parse *pParse, SrcList *pName){
/* Generate code to remove the index and from the master table */
v = sqliteGetVdbe(pParse);
if( v ){
static VdbeOp dropIndex[] = {
static VdbeOpList dropIndex[] = {
{ OP_Rewind, 0, ADDR(9), 0},
{ OP_String, 0, 0, 0}, /* 1 */
{ OP_MemStore, 1, 1, 0},
@ -2102,8 +2027,10 @@ void sqliteBeginTransaction(Parse *pParse, int onError){
return;
}
sqliteBeginWriteOperation(pParse, 0, 0);
db->flags |= SQLITE_InTrans;
db->onError = onError;
if( !pParse->explain ){
db->flags |= SQLITE_InTrans;
db->onError = onError;
}
}
/*
@ -2119,9 +2046,13 @@ void sqliteCommitTransaction(Parse *pParse){
sqliteErrorMsg(pParse, "cannot commit - no transaction is active");
return;
}
db->flags &= ~SQLITE_InTrans;
if( !pParse->explain ){
db->flags &= ~SQLITE_InTrans;
}
sqliteEndWriteOperation(pParse);
db->onError = OE_Default;
if( !pParse->explain ){
db->onError = OE_Default;
}
}
/*
@ -2142,8 +2073,10 @@ void sqliteRollbackTransaction(Parse *pParse){
if( v ){
sqliteVdbeAddOp(v, OP_Rollback, 0, 0);
}
db->flags &= ~SQLITE_InTrans;
db->onError = OE_Default;
if( !pParse->explain ){
db->flags &= ~SQLITE_InTrans;
db->onError = OE_Default;
}
}
/*