⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 insert.c

📁 sqlite的最新源码 This ZIP archive contains preprocessed C code for the SQLite library as individual sour
💻 C
📖 第 1 页 / 共 5 页
字号:
/*** 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 + -