summaryrefslogtreecommitdiff
path: root/ext/pdo_sqlite/sqlite/src/insert.c
diff options
context:
space:
mode:
authorMark A. Hershberger <mah@debian.(none)>2009-03-25 00:36:21 -0400
committerMark A. Hershberger <mah@debian.(none)>2009-03-25 00:36:21 -0400
commitd29a4fd2dd3b5d4cf6e80b602544d7b71d794e76 (patch)
treeb38e2e5c6974b9a15f103e5cf884cba9fff90ef4 /ext/pdo_sqlite/sqlite/src/insert.c
parenta88a88d0986a4a32288c102cdbfebd78d7e91d99 (diff)
downloadphp-d29a4fd2dd3b5d4cf6e80b602544d7b71d794e76.tar.gz
Imported Upstream version 5.2.0upstream/5.2.0
Diffstat (limited to 'ext/pdo_sqlite/sqlite/src/insert.c')
-rw-r--r--ext/pdo_sqlite/sqlite/src/insert.c155
1 files changed, 96 insertions, 59 deletions
diff --git a/ext/pdo_sqlite/sqlite/src/insert.c b/ext/pdo_sqlite/sqlite/src/insert.c
index 37f9f4ee5..d4cf74a3d 100644
--- a/ext/pdo_sqlite/sqlite/src/insert.c
+++ b/ext/pdo_sqlite/sqlite/src/insert.c
@@ -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;