1cce7d176Sdrh /* 2cce7d176Sdrh ** Copyright (c) 1999, 2000 D. Richard Hipp 3cce7d176Sdrh ** 4cce7d176Sdrh ** This program is free software; you can redistribute it and/or 5cce7d176Sdrh ** modify it under the terms of the GNU General Public 6cce7d176Sdrh ** License as published by the Free Software Foundation; either 7cce7d176Sdrh ** version 2 of the License, or (at your option) any later version. 8cce7d176Sdrh ** 9cce7d176Sdrh ** This program is distributed in the hope that it will be useful, 10cce7d176Sdrh ** but WITHOUT ANY WARRANTY; without even the implied warranty of 11cce7d176Sdrh ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12cce7d176Sdrh ** General Public License for more details. 13cce7d176Sdrh ** 14cce7d176Sdrh ** You should have received a copy of the GNU General Public 15cce7d176Sdrh ** License along with this library; if not, write to the 16cce7d176Sdrh ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17cce7d176Sdrh ** Boston, MA 02111-1307, USA. 18cce7d176Sdrh ** 19cce7d176Sdrh ** Author contact information: 20cce7d176Sdrh ** [email protected] 21cce7d176Sdrh ** http://www.hwaci.com/drh/ 22cce7d176Sdrh ** 23cce7d176Sdrh ************************************************************************* 24cce7d176Sdrh ** This file contains C code routines that are called by the parser 25cce7d176Sdrh ** to handle INSERT statements. 26cce7d176Sdrh ** 27*50e5dadfSdrh ** $Id: insert.c,v 1.17 2001/09/15 00:57:29 drh Exp $ 28cce7d176Sdrh */ 29cce7d176Sdrh #include "sqliteInt.h" 30cce7d176Sdrh 31cce7d176Sdrh /* 321ccde15dSdrh ** This routine is call to handle SQL of the following forms: 33cce7d176Sdrh ** 34cce7d176Sdrh ** insert into TABLE (IDLIST) values(EXPRLIST) 351ccde15dSdrh ** insert into TABLE (IDLIST) select 36cce7d176Sdrh ** 371ccde15dSdrh ** The IDLIST following the table name is always optional. If omitted, 381ccde15dSdrh ** then a list of all columns for the table is substituted. The IDLIST 39967e8b73Sdrh ** appears in the pColumn parameter. pColumn is NULL if IDLIST is omitted. 401ccde15dSdrh ** 411ccde15dSdrh ** The pList parameter holds EXPRLIST in the first form of the INSERT 421ccde15dSdrh ** statement above, and pSelect is NULL. For the second form, pList is 431ccde15dSdrh ** NULL and pSelect is a pointer to the select statement used to generate 441ccde15dSdrh ** data for the insert. 45cce7d176Sdrh */ 46cce7d176Sdrh void sqliteInsert( 47cce7d176Sdrh Parse *pParse, /* Parser context */ 48cce7d176Sdrh Token *pTableName, /* Name of table into which we are inserting */ 49cce7d176Sdrh ExprList *pList, /* List of values to be inserted */ 505974a30fSdrh Select *pSelect, /* A SELECT statement to use as the data source */ 51967e8b73Sdrh IdList *pColumn /* Column names corresponding to IDLIST. */ 52cce7d176Sdrh ){ 535974a30fSdrh Table *pTab; /* The table to insert into */ 545974a30fSdrh char *zTab; /* Name of the table into which we are inserting */ 555974a30fSdrh int i, j, idx; /* Loop counters */ 565974a30fSdrh Vdbe *v; /* Generate code into this virtual machine */ 575974a30fSdrh Index *pIdx; /* For looping over indices of the table */ 585974a30fSdrh int srcTab; /* Date comes from this temporary cursor if >=0 */ 59967e8b73Sdrh int nColumn; /* Number of columns in the data */ 605974a30fSdrh int base; /* First available cursor */ 615974a30fSdrh int iCont, iBreak; /* Beginning and end of the loop over srcTab */ 62cce7d176Sdrh 63daffd0e5Sdrh if( pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup; 64daffd0e5Sdrh 651ccde15dSdrh /* Locate the table into which we will be inserting new information. 661ccde15dSdrh */ 67cce7d176Sdrh zTab = sqliteTableNameFromToken(pTableName); 68daffd0e5Sdrh if( zTab==0 ) goto insert_cleanup; 69cce7d176Sdrh pTab = sqliteFindTable(pParse->db, zTab); 70cce7d176Sdrh sqliteFree(zTab); 71cce7d176Sdrh if( pTab==0 ){ 72cce7d176Sdrh sqliteSetNString(&pParse->zErrMsg, "no such table: ", 0, 73cce7d176Sdrh pTableName->z, pTableName->n, 0); 74cce7d176Sdrh pParse->nErr++; 75cce7d176Sdrh goto insert_cleanup; 76cce7d176Sdrh } 77cce7d176Sdrh if( pTab->readOnly ){ 78cce7d176Sdrh sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, 79cce7d176Sdrh " may not be modified", 0); 80cce7d176Sdrh pParse->nErr++; 81cce7d176Sdrh goto insert_cleanup; 82cce7d176Sdrh } 831ccde15dSdrh 841ccde15dSdrh /* Allocate a VDBE 851ccde15dSdrh */ 86d8bc7086Sdrh v = sqliteGetVdbe(pParse); 875974a30fSdrh if( v==0 ) goto insert_cleanup; 885e00f6c7Sdrh if( (pParse->db->flags & SQLITE_InTrans)==0 ){ 895e00f6c7Sdrh sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); 90*50e5dadfSdrh sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0, 0, 0); 915e00f6c7Sdrh } 921ccde15dSdrh 931ccde15dSdrh /* Figure out how many columns of data are supplied. If the data 941ccde15dSdrh ** is comming from a SELECT statement, then this step has to generate 951ccde15dSdrh ** all the code to implement the SELECT statement and leave the data 961ccde15dSdrh ** in a temporary table. If data is coming from an expression list, 971ccde15dSdrh ** then we just have to count the number of expressions. 981ccde15dSdrh */ 995974a30fSdrh if( pSelect ){ 1005974a30fSdrh int rc; 1015974a30fSdrh srcTab = pParse->nTab++; 102be0072d2Sdrh sqliteVdbeAddOp(v, OP_OpenTemp, srcTab, 0, 0, 0); 1035974a30fSdrh rc = sqliteSelect(pParse, pSelect, SRT_Table, srcTab); 104daffd0e5Sdrh if( rc || pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup; 1055974a30fSdrh assert( pSelect->pEList ); 106967e8b73Sdrh nColumn = pSelect->pEList->nExpr; 1075974a30fSdrh }else{ 108daffd0e5Sdrh assert( pList!=0 ); 1095974a30fSdrh srcTab = -1; 1105974a30fSdrh assert( pList ); 111967e8b73Sdrh nColumn = pList->nExpr; 1125974a30fSdrh } 1131ccde15dSdrh 1141ccde15dSdrh /* Make sure the number of columns in the source data matches the number 1151ccde15dSdrh ** of columns to be inserted into the table. 1161ccde15dSdrh */ 117967e8b73Sdrh if( pColumn==0 && nColumn!=pTab->nCol ){ 118cce7d176Sdrh char zNum1[30]; 119cce7d176Sdrh char zNum2[30]; 120967e8b73Sdrh sprintf(zNum1,"%d", nColumn); 121cce7d176Sdrh sprintf(zNum2,"%d", pTab->nCol); 122cce7d176Sdrh sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, 123cce7d176Sdrh " has ", zNum2, " columns but ", 124cce7d176Sdrh zNum1, " values were supplied", 0); 125cce7d176Sdrh pParse->nErr++; 126cce7d176Sdrh goto insert_cleanup; 127cce7d176Sdrh } 128967e8b73Sdrh if( pColumn!=0 && nColumn!=pColumn->nId ){ 129cce7d176Sdrh char zNum1[30]; 130cce7d176Sdrh char zNum2[30]; 131967e8b73Sdrh sprintf(zNum1,"%d", nColumn); 132967e8b73Sdrh sprintf(zNum2,"%d", pColumn->nId); 133cce7d176Sdrh sqliteSetString(&pParse->zErrMsg, zNum1, " values for ", 134cce7d176Sdrh zNum2, " columns", 0); 135cce7d176Sdrh pParse->nErr++; 136cce7d176Sdrh goto insert_cleanup; 137cce7d176Sdrh } 1381ccde15dSdrh 1391ccde15dSdrh /* If the INSERT statement included an IDLIST term, then make sure 1401ccde15dSdrh ** all elements of the IDLIST really are columns of the table and 1411ccde15dSdrh ** remember the column indices. 1421ccde15dSdrh */ 143967e8b73Sdrh if( pColumn ){ 144967e8b73Sdrh for(i=0; i<pColumn->nId; i++){ 145967e8b73Sdrh pColumn->a[i].idx = -1; 146cce7d176Sdrh } 147967e8b73Sdrh for(i=0; i<pColumn->nId; i++){ 148cce7d176Sdrh for(j=0; j<pTab->nCol; j++){ 149967e8b73Sdrh if( sqliteStrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){ 150967e8b73Sdrh pColumn->a[i].idx = j; 151cce7d176Sdrh break; 152cce7d176Sdrh } 153cce7d176Sdrh } 154cce7d176Sdrh if( j>=pTab->nCol ){ 155cce7d176Sdrh sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, 156967e8b73Sdrh " has no column named ", pColumn->a[i].zName, 0); 157cce7d176Sdrh pParse->nErr++; 158cce7d176Sdrh goto insert_cleanup; 159cce7d176Sdrh } 160cce7d176Sdrh } 161cce7d176Sdrh } 1621ccde15dSdrh 1631ccde15dSdrh /* Open cursors into the table that is received the new data and 1641ccde15dSdrh ** all indices of that table. 1651ccde15dSdrh */ 1665974a30fSdrh base = pParse->nTab; 167be0072d2Sdrh sqliteVdbeAddOp(v, OP_Open, base, pTab->tnum, pTab->zName, 0); 168bed8690fSdrh for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ 169be0072d2Sdrh sqliteVdbeAddOp(v, OP_Open, idx+base, pIdx->tnum, pIdx->zName, 0); 1705974a30fSdrh } 1711ccde15dSdrh 1721ccde15dSdrh /* If the data source is a SELECT statement, then we have to create 1731ccde15dSdrh ** a loop because there might be multiple rows of data. If the data 1741ccde15dSdrh ** source is an expression list, then exactly one row will be inserted 1751ccde15dSdrh ** and the loop is not used. 1761ccde15dSdrh */ 1775974a30fSdrh if( srcTab>=0 ){ 1785974a30fSdrh sqliteVdbeAddOp(v, OP_Rewind, srcTab, 0, 0, 0); 1795974a30fSdrh iBreak = sqliteVdbeMakeLabel(v); 1805974a30fSdrh iCont = sqliteVdbeAddOp(v, OP_Next, srcTab, iBreak, 0, 0); 181bed8690fSdrh } 1821ccde15dSdrh 1831ccde15dSdrh /* Create a new entry in the table and fill it with data. 1841ccde15dSdrh */ 1853fc190ccSdrh sqliteVdbeAddOp(v, OP_NewRecno, base, 0, 0, 0); 186cce7d176Sdrh if( pTab->pIndex ){ 187cce7d176Sdrh sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0); 188cce7d176Sdrh } 189cce7d176Sdrh for(i=0; i<pTab->nCol; i++){ 190967e8b73Sdrh if( pColumn==0 ){ 191cce7d176Sdrh j = i; 192cce7d176Sdrh }else{ 193967e8b73Sdrh for(j=0; j<pColumn->nId; j++){ 194967e8b73Sdrh if( pColumn->a[j].idx==i ) break; 195cce7d176Sdrh } 196cce7d176Sdrh } 197967e8b73Sdrh if( pColumn && j>=pColumn->nId ){ 1987020f651Sdrh char *zDflt = pTab->aCol[i].zDflt; 199c61053b7Sdrh if( zDflt==0 ){ 200c61053b7Sdrh sqliteVdbeAddOp(v, OP_Null, 0, 0, 0, 0); 201c61053b7Sdrh }else{ 2027020f651Sdrh sqliteVdbeAddOp(v, OP_String, 0, 0, zDflt, 0); 203c61053b7Sdrh } 2045974a30fSdrh }else if( srcTab>=0 ){ 205be0072d2Sdrh sqliteVdbeAddOp(v, OP_Column, srcTab, i, 0, 0); 206cce7d176Sdrh }else{ 207cce7d176Sdrh sqliteExprCode(pParse, pList->a[j].pExpr); 208cce7d176Sdrh } 209cce7d176Sdrh } 210cce7d176Sdrh sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0, 0, 0); 2115974a30fSdrh sqliteVdbeAddOp(v, OP_Put, base, 0, 0, 0); 2121ccde15dSdrh 2131ccde15dSdrh /* Create appropriate entries for the new data row in all indices 2141ccde15dSdrh ** of the table. 2151ccde15dSdrh */ 216bed8690fSdrh for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ 217cce7d176Sdrh if( pIdx->pNext ){ 218cce7d176Sdrh sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0); 219cce7d176Sdrh } 220967e8b73Sdrh for(i=0; i<pIdx->nColumn; i++){ 221967e8b73Sdrh int idx = pIdx->aiColumn[i]; 222967e8b73Sdrh if( pColumn==0 ){ 223cce7d176Sdrh j = idx; 224cce7d176Sdrh }else{ 225967e8b73Sdrh for(j=0; j<pColumn->nId; j++){ 226967e8b73Sdrh if( pColumn->a[j].idx==idx ) break; 227cce7d176Sdrh } 228cce7d176Sdrh } 229967e8b73Sdrh if( pColumn && j>=pColumn->nId ){ 2307020f651Sdrh char *zDflt = pTab->aCol[idx].zDflt; 231c61053b7Sdrh if( zDflt==0 ){ 232c61053b7Sdrh sqliteVdbeAddOp(v, OP_Null, 0, 0, 0, 0); 233c61053b7Sdrh }else{ 2347020f651Sdrh sqliteVdbeAddOp(v, OP_String, 0, 0, zDflt, 0); 235c61053b7Sdrh } 2365974a30fSdrh }else if( srcTab>=0 ){ 237be0072d2Sdrh sqliteVdbeAddOp(v, OP_Column, srcTab, idx, 0, 0); 238cce7d176Sdrh }else{ 239cce7d176Sdrh sqliteExprCode(pParse, pList->a[j].pExpr); 240cce7d176Sdrh } 241cce7d176Sdrh } 2425e00f6c7Sdrh sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0, 0, 0); 2435974a30fSdrh sqliteVdbeAddOp(v, OP_PutIdx, idx+base, 0, 0, 0); 244cce7d176Sdrh } 2451ccde15dSdrh 2461ccde15dSdrh /* The bottom of the loop, if the data source is a SELECT statement 2471ccde15dSdrh */ 2485974a30fSdrh if( srcTab>=0 ){ 2495974a30fSdrh sqliteVdbeAddOp(v, OP_Goto, 0, iCont, 0, 0); 2505974a30fSdrh sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, iBreak); 251cce7d176Sdrh } 2525e00f6c7Sdrh if( (pParse->db->flags & SQLITE_InTrans)==0 ){ 2535e00f6c7Sdrh sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0); 2545e00f6c7Sdrh } 2555e00f6c7Sdrh 256cce7d176Sdrh 257cce7d176Sdrh insert_cleanup: 2585974a30fSdrh if( pList ) sqliteExprListDelete(pList); 2595974a30fSdrh if( pSelect ) sqliteSelectDelete(pSelect); 260967e8b73Sdrh sqliteIdListDelete(pColumn); 261cce7d176Sdrh } 262