MFB: Upgraded libsqlite in pdo_sqlite to 3.3.7

This commit is contained in:
Ilia Alshanetsky 2006-08-14 16:35:23 +00:00
parent 3717342c9f
commit 5c01690d9b
83 changed files with 17303 additions and 7927 deletions

View file

@ -23,10 +23,11 @@
**
** Character Column affinity
** ------------------------------
** 'n' NUMERIC
** 'i' INTEGER
** 't' TEXT
** 'o' NONE
** 'a' TEXT
** 'b' NONE
** 'c' NUMERIC
** 'd' INTEGER
** 'e' REAL
*/
void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
if( !pIdx->zColAff ){
@ -61,10 +62,11 @@ void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
**
** Character Column affinity
** ------------------------------
** 'n' NUMERIC
** 'i' INTEGER
** 't' TEXT
** 'o' NONE
** 'a' TEXT
** 'b' NONE
** 'c' NUMERIC
** 'd' INTEGER
** 'e' REAL
*/
void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){
/* The first time a column affinity string for a particular table
@ -102,15 +104,15 @@ void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){
**
** No checking is done for sub-selects that are part of expressions.
*/
static int selectReadsTable(Select *p, int iDb, int iTab){
static int selectReadsTable(Select *p, Schema *pSchema, int iTab){
int i;
struct SrcList_item *pItem;
if( p->pSrc==0 ) return 0;
for(i=0, pItem=p->pSrc->a; i<p->pSrc->nSrc; i++, pItem++){
if( pItem->pSelect ){
if( selectReadsTable(pItem->pSelect, iDb, iTab) ) return 1;
if( selectReadsTable(pItem->pSelect, pSchema, iTab) ) return 1;
}else{
if( pItem->pTab->iDb==iDb && pItem->pTab->tnum==iTab ) return 1;
if( pItem->pTab->pSchema==pSchema && pItem->pTab->tnum==iTab ) return 1;
}
}
return 0;
@ -212,6 +214,7 @@ void sqlite3Insert(
int newIdx = -1; /* Cursor for the NEW table */
Db *pDb; /* The database containing table being inserted into */
int counterMem = 0; /* Memory cell holding AUTOINCREMENT counter */
int iDb;
#ifndef SQLITE_OMIT_TRIGGER
int isView; /* True if attempting to insert into a view */
@ -219,10 +222,12 @@ void sqlite3Insert(
#endif
#ifndef SQLITE_OMIT_AUTOINCREMENT
int counterRowid; /* Memory cell holding rowid of autoinc counter */
int counterRowid = 0; /* Memory cell holding rowid of autoinc counter */
#endif
if( pParse->nErr || sqlite3_malloc_failed ) goto insert_cleanup;
if( pParse->nErr || sqlite3MallocFailed() ){
goto insert_cleanup;
}
db = pParse->db;
/* Locate the table into which we will be inserting new information.
@ -234,8 +239,9 @@ void sqlite3Insert(
if( pTab==0 ){
goto insert_cleanup;
}
assert( pTab->iDb<db->nDb );
pDb = &db->aDb[pTab->iDb];
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( iDb<db->nDb );
pDb = &db->aDb[iDb];
zDb = pDb->zName;
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
goto insert_cleanup;
@ -263,27 +269,22 @@ void sqlite3Insert(
if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){
goto insert_cleanup;
}
if( pTab==0 ) goto insert_cleanup;
assert( pTab!=0 );
/* If pTab is really a view, make sure it has been initialized.
** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual
** module table).
*/
if( isView && sqlite3ViewGetColumnNames(pParse, pTab) ){
if( sqlite3ViewGetColumnNames(pParse, pTab) ){
goto insert_cleanup;
}
/* Ensure all required collation sequences are available. */
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( sqlite3CheckIndexCollSeq(pParse, pIdx) ){
goto insert_cleanup;
}
}
/* Allocate a VDBE
*/
v = sqlite3GetVdbe(pParse);
if( v==0 ) goto insert_cleanup;
if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
sqlite3BeginWriteOperation(pParse, pSelect || triggers_exist, pTab->iDb);
sqlite3BeginWriteOperation(pParse, pSelect || triggers_exist, iDb);
/* if there are row triggers, allocate a temp table for new.* references. */
if( triggers_exist ){
@ -298,22 +299,20 @@ void sqlite3Insert(
*/
if( pTab->autoInc ){
int iCur = pParse->nTab;
int base = sqlite3VdbeCurrentAddr(v);
int addr = sqlite3VdbeCurrentAddr(v);
counterRowid = pParse->nMem++;
counterMem = pParse->nMem++;
sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pDb->pSeqTab->tnum);
sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, 2);
sqlite3VdbeAddOp(v, OP_Rewind, iCur, base+13);
sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
sqlite3VdbeAddOp(v, OP_Rewind, iCur, addr+13);
sqlite3VdbeAddOp(v, OP_Column, iCur, 0);
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
sqlite3VdbeAddOp(v, OP_Ne, 28417, base+12);
sqlite3VdbeAddOp(v, OP_Ne, 0x100, addr+12);
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
sqlite3VdbeAddOp(v, OP_MemStore, counterRowid, 1);
sqlite3VdbeAddOp(v, OP_Column, iCur, 1);
sqlite3VdbeAddOp(v, OP_MemStore, counterMem, 1);
sqlite3VdbeAddOp(v, OP_Goto, 0, base+13);
sqlite3VdbeAddOp(v, OP_Next, iCur, base+4);
sqlite3VdbeAddOp(v, OP_Goto, 0, addr+13);
sqlite3VdbeAddOp(v, OP_Next, iCur, addr+4);
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
}
#endif /* SQLITE_OMIT_AUTOINCREMENT */
@ -336,7 +335,9 @@ void sqlite3Insert(
/* Resolve the expressions in the SELECT statement and execute it. */
rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock,0,0,0,0);
if( rc || pParse->nErr || sqlite3_malloc_failed ) goto insert_cleanup;
if( rc || pParse->nErr || sqlite3MallocFailed() ){
goto insert_cleanup;
}
iCleanup = sqlite3VdbeMakeLabel(v);
sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup);
@ -351,7 +352,7 @@ void sqlite3Insert(
** of the tables being read by the SELECT statement. Also use a
** temp table in the case of row triggers.
*/
if( triggers_exist || selectReadsTable(pSelect, pTab->iDb, pTab->tnum) ){
if( triggers_exist || selectReadsTable(pSelect,pTab->pSchema,pTab->tnum) ){
useTempTable = 1;
}
@ -362,7 +363,6 @@ void sqlite3Insert(
srcTab = pParse->nTab++;
sqlite3VdbeResolveLabel(v, iInsertBlock);
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
sqlite3TableAffinityStr(v, pTab);
sqlite3VdbeAddOp(v, OP_NewRowid, srcTab, 0);
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
sqlite3VdbeAddOp(v, OP_Insert, srcTab, 0);
@ -373,7 +373,7 @@ void sqlite3Insert(
** back up and execute the SELECT code above.
*/
sqlite3VdbeJumpHere(v, iInitCode);
sqlite3VdbeAddOp(v, OP_OpenVirtual, srcTab, 0);
sqlite3VdbeAddOp(v, OP_OpenEphemeral, srcTab, 0);
sqlite3VdbeAddOp(v, OP_SetNumColumns, srcTab, nColumn);
sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop);
sqlite3VdbeResolveLabel(v, iCleanup);
@ -569,6 +569,10 @@ void sqlite3Insert(
** case the record number is the same as that column.
*/
if( !isView ){
if( IsVirtual(pTab) ){
/* The row that the VUpdate opcode will delete: none */
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
}
if( keyColumn>=0 ){
if( useTempTable ){
sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn);
@ -584,6 +588,8 @@ void sqlite3Insert(
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
}else if( IsVirtual(pTab) ){
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
}else{
sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
}
@ -626,16 +632,25 @@ void sqlite3Insert(
/* Generate code to check constraints and generate index keys and
** do the insertion.
*/
sqlite3GenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0,
0, onError, endOfLoop);
sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0,
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pTab) ){
pParse->pVirtualLock = pTab;
sqlite3VdbeOp3(v, OP_VUpdate, 1, pTab->nCol+2,
(const char*)pTab->pVtab, P3_VTAB);
}else
#endif
{
sqlite3GenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0,
0, onError, endOfLoop);
sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0,
(triggers_exist & TRIGGER_AFTER)!=0 ? newIdx : -1);
}
}
/* Update the count of rows that are inserted
*/
if( (db->flags & SQLITE_CountRows)!=0 ){
sqlite3VdbeAddOp(v, OP_MemIncr, iCntMem, 0);
sqlite3VdbeAddOp(v, OP_MemIncr, 1, iCntMem);
}
if( triggers_exist ){
@ -667,7 +682,7 @@ void sqlite3Insert(
sqlite3VdbeResolveLabel(v, iCleanup);
}
if( !triggers_exist ){
if( !triggers_exist && !IsVirtual(pTab) ){
/* Close all tables opened */
sqlite3VdbeAddOp(v, OP_Close, base, 0);
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
@ -682,12 +697,10 @@ void sqlite3Insert(
*/
if( pTab->autoInc ){
int iCur = pParse->nTab;
int base = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
sqlite3VdbeAddOp(v, OP_OpenWrite, iCur, pDb->pSeqTab->tnum);
sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, 2);
int addr = sqlite3VdbeCurrentAddr(v);
sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
sqlite3VdbeAddOp(v, OP_MemLoad, counterRowid, 0);
sqlite3VdbeAddOp(v, OP_NotNull, -1, base+7);
sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+7);
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
sqlite3VdbeAddOp(v, OP_NewRowid, iCur, 0);
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
@ -707,7 +720,7 @@ void sqlite3Insert(
sqlite3VdbeAddOp(v, OP_MemLoad, iCntMem, 0);
sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, "rows inserted", P3_STATIC);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", P3_STATIC);
}
insert_cleanup:
@ -870,7 +883,24 @@ void sqlite3GenerateConstraintChecks(
/* Test all CHECK constraints
*/
/**** TBD ****/
#ifndef SQLITE_OMIT_CHECK
if( pTab->pCheck && (pParse->db->flags & SQLITE_IgnoreChecks)==0 ){
int allOk = sqlite3VdbeMakeLabel(v);
assert( pParse->ckOffset==0 );
pParse->ckOffset = nCol;
sqlite3ExprIfTrue(pParse, pTab->pCheck, allOk, 1);
assert( pParse->ckOffset==nCol );
pParse->ckOffset = 0;
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
if( onError==OE_Ignore || onError==OE_Replace ){
sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0);
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
}else{
sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
}
sqlite3VdbeResolveLabel(v, allOk);
}
#endif /* !defined(SQLITE_OMIT_CHECK) */
/* If we have an INTEGER PRIMARY KEY, make sure the primary key
** of the new record does not previously exist. Except, if this
@ -904,7 +934,7 @@ void sqlite3GenerateConstraintChecks(
break;
}
case OE_Replace: {
sqlite3GenerateRowIndexDelete(pParse->db, v, pTab, base, 0);
sqlite3GenerateRowIndexDelete(v, pTab, base, 0);
if( isUpdate ){
sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRowids, 1);
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
@ -1067,9 +1097,13 @@ void sqlite3CompleteInsertion(
if( pParse->nested ){
pik_flags = 0;
}else{
pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID));
pik_flags = OPFLAG_NCHANGE;
pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID);
}
sqlite3VdbeAddOp(v, OP_Insert, base, pik_flags);
if( !pParse->nested ){
sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
}
if( isUpdate && rowidChng ){
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
@ -1088,18 +1122,21 @@ void sqlite3OpenTableAndIndices(
int op /* OP_OpenRead or OP_OpenWrite */
){
int i;
int iDb;
Index *pIdx;
Vdbe *v = sqlite3GetVdbe(pParse);
Vdbe *v;
if( IsVirtual(pTab) ) return;
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
VdbeComment((v, "# %s", pTab->zName));
sqlite3VdbeAddOp(v, op, base, pTab->tnum);
sqlite3VdbeAddOp(v, OP_SetNumColumns, base, pTab->nCol);
sqlite3OpenTable(pParse, base, iDb, pTab, op);
for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
assert( pIdx->pSchema==pTab->pSchema );
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
VdbeComment((v, "# %s", pIdx->zName));
sqlite3VdbeOp3(v, op, i+base, pIdx->tnum,
(char*)&pIdx->keyInfo, P3_KEYINFO);
sqlite3VdbeOp3(v, op, i+base, pIdx->tnum, (char*)pKey, P3_KEYINFO_HANDOFF);
}
if( pParse->nTab<=base+i ){
pParse->nTab = base+i;