📄 insert.c
字号:
/*** 2001 September 15**** The author disclaims copyright to this source code. In place of** a legal notice, here is a blessing:**** May you do good and not evil.** May you find forgiveness for yourself and forgive others.** May you share freely, never taking more than you give.***************************************************************************** This file contains C code routines that are called by the parser** to handle INSERT statements in SQLite.**** $Id: insert.c,v 1.253 2008/11/19 09:05:27 danielk1977 Exp $*/#include "sqliteInt.h"/*** Set P4 of the most recently inserted opcode to a column affinity** string for index pIdx. A column affinity string has one character** for each column in the table, according to the affinity of the column:**** Character Column affinity** ------------------------------** 'a' TEXT** 'b' NONE** 'c' NUMERIC** 'd' INTEGER** 'e' REAL**** An extra 'b' is appended to the end of the string to cover the** rowid that appears as the last column in every index.*/void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ if( !pIdx->zColAff ){ /* The first time a column affinity string for a particular index is ** required, it is allocated and populated here. It is then stored as ** a member of the Index structure for subsequent use. ** ** The column affinity string will eventually be deleted by ** sqliteDeleteIndex() when the Index structure itself is cleaned ** up. */ int n; Table *pTab = pIdx->pTable; sqlite3 *db = sqlite3VdbeDb(v); pIdx->zColAff = (char *)sqlite3Malloc(pIdx->nColumn+2); if( !pIdx->zColAff ){ db->mallocFailed = 1; return; } for(n=0; n<pIdx->nColumn; n++){ pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity; } pIdx->zColAff[n++] = SQLITE_AFF_NONE; pIdx->zColAff[n] = 0; } sqlite3VdbeChangeP4(v, -1, pIdx->zColAff, 0);}/*** Set P4 of the most recently inserted opcode to a column affinity** string for table pTab. A column affinity string has one character** for each column indexed by the index, according to the affinity of the** column:**** Character Column affinity** ------------------------------** '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 ** is required, it is allocated and populated here. It is then ** stored as a member of the Table structure for subsequent use. ** ** The column affinity string will eventually be deleted by ** sqlite3DeleteTable() when the Table structure itself is cleaned up. */ if( !pTab->zColAff ){ char *zColAff; int i; sqlite3 *db = sqlite3VdbeDb(v); zColAff = (char *)sqlite3Malloc(pTab->nCol+1); if( !zColAff ){ db->mallocFailed = 1; return; } for(i=0; i<pTab->nCol; i++){ zColAff[i] = pTab->aCol[i].affinity; } zColAff[pTab->nCol] = '\0'; pTab->zColAff = zColAff; } sqlite3VdbeChangeP4(v, -1, pTab->zColAff, 0);}/*** Return non-zero if the table pTab in database iDb or any of its indices** have been opened at any point in the VDBE program beginning at location** iStartAddr throught the end of the program. This is used to see if ** a statement of the form "INSERT INTO <iDb, pTab> SELECT ..." can ** run without using temporary table for the results of the SELECT. */static int readsTable(Vdbe *v, int iStartAddr, int iDb, Table *pTab){ int i; int iEnd = sqlite3VdbeCurrentAddr(v); for(i=iStartAddr; i<iEnd; i++){ VdbeOp *pOp = sqlite3VdbeGetOp(v, i); assert( pOp!=0 ); if( pOp->opcode==OP_OpenRead && pOp->p3==iDb ){ Index *pIndex; int tnum = pOp->p2; if( tnum==pTab->tnum ){ return 1; } for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ if( tnum==pIndex->tnum ){ return 1; } } }#ifndef SQLITE_OMIT_VIRTUALTABLE if( pOp->opcode==OP_VOpen && pOp->p4.pVtab==pTab->pVtab ){ assert( pOp->p4.pVtab!=0 ); assert( pOp->p4type==P4_VTAB ); return 1; }#endif } return 0;}#ifndef SQLITE_OMIT_AUTOINCREMENT/*** Write out code to initialize the autoincrement logic. This code** looks up the current autoincrement value in the sqlite_sequence** table and stores that value in a register. Code generated by** autoIncStep() will keep that register holding the largest** rowid value. Code generated by autoIncEnd() will write the new** largest value of the counter back into the sqlite_sequence table.**** This routine returns the index of the mem[] cell that contains** the maximum rowid counter.**** Three consecutive registers are allocated by this routine. The** first two hold the name of the target table and the maximum rowid ** inserted into the target table, respectively.** The third holds the rowid in sqlite_sequence where we will** write back the revised maximum rowid. This routine returns the** index of the second of these three registers.*/static int autoIncBegin( Parse *pParse, /* Parsing context */ int iDb, /* Index of the database holding pTab */ Table *pTab /* The table we are writing to */){ int memId = 0; /* Register holding maximum rowid */ if( pTab->tabFlags & TF_Autoincrement ){ Vdbe *v = pParse->pVdbe; Db *pDb = &pParse->db->aDb[iDb]; int iCur = pParse->nTab; int addr; /* Address of the top of the loop */ assert( v ); pParse->nMem++; /* Holds name of table */ memId = ++pParse->nMem; pParse->nMem++; sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenRead); addr = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, pTab->zName, 0); sqlite3VdbeAddOp2(v, OP_Rewind, iCur, addr+9); sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, memId); sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId); sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); sqlite3VdbeAddOp2(v, OP_Rowid, iCur, memId+1); sqlite3VdbeAddOp3(v, OP_Column, iCur, 1, memId); sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+9); sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+2); sqlite3VdbeAddOp2(v, OP_Integer, 0, memId); sqlite3VdbeAddOp2(v, OP_Close, iCur, 0); } return memId;}/*** Update the maximum rowid for an autoincrement calculation.**** This routine should be called when the top of the stack holds a** new rowid that is about to be inserted. If that new rowid is** larger than the maximum rowid in the memId memory cell, then the** memory cell is updated. The stack is unchanged.*/static void autoIncStep(Parse *pParse, int memId, int regRowid){ if( memId>0 ){ sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, regRowid); }}/*** After doing one or more inserts, the maximum rowid is stored** in reg[memId]. Generate code to write this value back into the** the sqlite_sequence table.*/static void autoIncEnd( Parse *pParse, /* The parsing context */ int iDb, /* Index of the database holding pTab */ Table *pTab, /* Table we are inserting into */ int memId /* Memory cell holding the maximum rowid */){ if( pTab->tabFlags & TF_Autoincrement ){ int iCur = pParse->nTab; Vdbe *v = pParse->pVdbe; Db *pDb = &pParse->db->aDb[iDb]; int j1; int iRec = ++pParse->nMem; /* Memory cell used for record */ assert( v ); sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); sqlite3VdbeAddOp2(v, OP_NewRowid, iCur, memId+1); sqlite3VdbeJumpHere(v, j1); sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec); sqlite3VdbeAddOp3(v, OP_Insert, iCur, iRec, memId+1); sqlite3VdbeChangeP5(v, OPFLAG_APPEND); sqlite3VdbeAddOp1(v, OP_Close, iCur); }}#else/*** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines** above are all no-ops*/# define autoIncBegin(A,B,C) (0)# define autoIncStep(A,B,C)# define autoIncEnd(A,B,C,D)#endif /* SQLITE_OMIT_AUTOINCREMENT *//* Forward declaration */static int xferOptimization( Parse *pParse, /* Parser context */ Table *pDest, /* The table we are inserting into */ Select *pSelect, /* A SELECT statement to use as the data source */ int onError, /* How to handle constraint errors */ int iDbDest /* The database of pDest */);/*** This routine is call to handle SQL of the following forms:**** insert into TABLE (IDLIST) values(EXPRLIST)** insert into TABLE (IDLIST) select**** The IDLIST following the table name is always optional. If omitted,** then a list of all columns for the table is substituted. The IDLIST** appears in the pColumn parameter. pColumn is NULL if IDLIST is omitted.**** The pList parameter holds EXPRLIST in the first form of the INSERT** statement above, and pSelect is NULL. For the second form, pList is** NULL and pSelect is a pointer to the select statement used to generate** data for the insert.**** The code generated follows one of four templates. For a simple** select with data coming from a VALUES clause, the code executes** once straight down through. Pseudo-code follows (we call this** the "1st template"):**** open write cursor to <table> and its indices** puts VALUES clause expressions onto the stack** write the resulting record into <table>** cleanup**** The three remaining templates assume the statement is of the form**** INSERT INTO <table> SELECT ...**** If the SELECT clause is of the restricted form "SELECT * FROM <table2>" -** in other words if the SELECT pulls all columns from a single table** and there is no WHERE or LIMIT or GROUP BY or ORDER BY clauses, and** if <table2> and <table1> are distinct tables but have identical** schemas, including all the same indices, then a special optimization** is invoked that copies raw records from <table2> over to <table1>.** See the xferOptimization() function for the implementation of this** template. This is the 2nd template.**** open a write cursor to <table>** open read cursor on <table2>** transfer all records in <table2> over to <table>** close cursors** foreach index on <table>** open a write cursor on the <table> index** open a read cursor on the corresponding <table2> index** transfer all records from the read to the write cursors** close cursors** end foreach**** The 3rd template is for when the second template does not apply** and the SELECT clause does not read from <table> at any time.** The generated code follows this template:**** EOF <- 0** X <- A** goto B** A: setup for the SELECT** loop over the rows in the SELECT** load values into registers R..R+n** yield X** end loop** cleanup after the SELECT** EOF <- 1** yield X** goto A** B: open write cursor to <table> and its indices** C: yield X** if EOF goto D** insert the select result into <table> from R..R+n** goto C** D: cleanup**** The 4th template is used if the insert statement takes its** values from a SELECT but the data is being inserted into a table** that is also read as part of the SELECT. In the third form,** we have to use a intermediate table to store the results of** the select. The template is like this:**** EOF <- 0** X <- A** goto B** A: setup for the SELECT** loop over the tables in the SELECT** load value into register R..R+n** yield X** end loop** cleanup after the SELECT** EOF <- 1** yield X** halt-error** B: open temp table** L: yield X
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -