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*daffd0e5Sdrh ** $Id: insert.c,v 1.13 2001/04/11 14:28:42 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 63*daffd0e5Sdrh if( pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup; 64*daffd0e5Sdrh 651ccde15dSdrh /* Locate the table into which we will be inserting new information. 661ccde15dSdrh */ 67cce7d176Sdrh zTab = sqliteTableNameFromToken(pTableName); 68*daffd0e5Sdrh 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; 881ccde15dSdrh 891ccde15dSdrh /* Figure out how many columns of data are supplied. If the data 901ccde15dSdrh ** is comming from a SELECT statement, then this step has to generate 911ccde15dSdrh ** all the code to implement the SELECT statement and leave the data 921ccde15dSdrh ** in a temporary table. If data is coming from an expression list, 931ccde15dSdrh ** then we just have to count the number of expressions. 941ccde15dSdrh */ 955974a30fSdrh if( pSelect ){ 965974a30fSdrh int rc; 975974a30fSdrh srcTab = pParse->nTab++; 98345fda3eSdrh sqliteVdbeAddOp(v, OP_OpenTbl, srcTab, 1, 0, 0); 995974a30fSdrh rc = sqliteSelect(pParse, pSelect, SRT_Table, srcTab); 100*daffd0e5Sdrh if( rc || pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup; 1015974a30fSdrh assert( pSelect->pEList ); 102967e8b73Sdrh nColumn = pSelect->pEList->nExpr; 1035974a30fSdrh }else{ 104*daffd0e5Sdrh assert( pList!=0 ); 1055974a30fSdrh srcTab = -1; 1065974a30fSdrh assert( pList ); 107967e8b73Sdrh nColumn = pList->nExpr; 1085974a30fSdrh } 1091ccde15dSdrh 1101ccde15dSdrh /* Make sure the number of columns in the source data matches the number 1111ccde15dSdrh ** of columns to be inserted into the table. 1121ccde15dSdrh */ 113967e8b73Sdrh if( pColumn==0 && nColumn!=pTab->nCol ){ 114cce7d176Sdrh char zNum1[30]; 115cce7d176Sdrh char zNum2[30]; 116967e8b73Sdrh sprintf(zNum1,"%d", nColumn); 117cce7d176Sdrh sprintf(zNum2,"%d", pTab->nCol); 118cce7d176Sdrh sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, 119cce7d176Sdrh " has ", zNum2, " columns but ", 120cce7d176Sdrh zNum1, " values were supplied", 0); 121cce7d176Sdrh pParse->nErr++; 122cce7d176Sdrh goto insert_cleanup; 123cce7d176Sdrh } 124967e8b73Sdrh if( pColumn!=0 && nColumn!=pColumn->nId ){ 125cce7d176Sdrh char zNum1[30]; 126cce7d176Sdrh char zNum2[30]; 127967e8b73Sdrh sprintf(zNum1,"%d", nColumn); 128967e8b73Sdrh sprintf(zNum2,"%d", pColumn->nId); 129cce7d176Sdrh sqliteSetString(&pParse->zErrMsg, zNum1, " values for ", 130cce7d176Sdrh zNum2, " columns", 0); 131cce7d176Sdrh pParse->nErr++; 132cce7d176Sdrh goto insert_cleanup; 133cce7d176Sdrh } 1341ccde15dSdrh 1351ccde15dSdrh /* If the INSERT statement included an IDLIST term, then make sure 1361ccde15dSdrh ** all elements of the IDLIST really are columns of the table and 1371ccde15dSdrh ** remember the column indices. 1381ccde15dSdrh */ 139967e8b73Sdrh if( pColumn ){ 140967e8b73Sdrh for(i=0; i<pColumn->nId; i++){ 141967e8b73Sdrh pColumn->a[i].idx = -1; 142cce7d176Sdrh } 143967e8b73Sdrh for(i=0; i<pColumn->nId; i++){ 144cce7d176Sdrh for(j=0; j<pTab->nCol; j++){ 145967e8b73Sdrh if( sqliteStrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){ 146967e8b73Sdrh pColumn->a[i].idx = j; 147cce7d176Sdrh break; 148cce7d176Sdrh } 149cce7d176Sdrh } 150cce7d176Sdrh if( j>=pTab->nCol ){ 151cce7d176Sdrh sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, 152967e8b73Sdrh " has no column named ", pColumn->a[i].zName, 0); 153cce7d176Sdrh pParse->nErr++; 154cce7d176Sdrh goto insert_cleanup; 155cce7d176Sdrh } 156cce7d176Sdrh } 157cce7d176Sdrh } 1581ccde15dSdrh 1591ccde15dSdrh /* Open cursors into the table that is received the new data and 1601ccde15dSdrh ** all indices of that table. 1611ccde15dSdrh */ 1625974a30fSdrh base = pParse->nTab; 163345fda3eSdrh sqliteVdbeAddOp(v, OP_OpenTbl, base, 1, pTab->zName, 0); 164bed8690fSdrh for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ 165345fda3eSdrh sqliteVdbeAddOp(v, OP_OpenIdx, idx+base, 1, pIdx->zName, 0); 1665974a30fSdrh } 1671ccde15dSdrh 1681ccde15dSdrh /* If the data source is a SELECT statement, then we have to create 1691ccde15dSdrh ** a loop because there might be multiple rows of data. If the data 1701ccde15dSdrh ** source is an expression list, then exactly one row will be inserted 1711ccde15dSdrh ** and the loop is not used. 1721ccde15dSdrh */ 1735974a30fSdrh if( srcTab>=0 ){ 1745974a30fSdrh sqliteVdbeAddOp(v, OP_Rewind, srcTab, 0, 0, 0); 1755974a30fSdrh iBreak = sqliteVdbeMakeLabel(v); 1765974a30fSdrh iCont = sqliteVdbeAddOp(v, OP_Next, srcTab, iBreak, 0, 0); 177bed8690fSdrh } 1781ccde15dSdrh 1791ccde15dSdrh /* Create a new entry in the table and fill it with data. 1801ccde15dSdrh */ 181cce7d176Sdrh sqliteVdbeAddOp(v, OP_New, 0, 0, 0, 0); 182cce7d176Sdrh if( pTab->pIndex ){ 183cce7d176Sdrh sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0); 184cce7d176Sdrh } 185cce7d176Sdrh for(i=0; i<pTab->nCol; i++){ 186967e8b73Sdrh if( pColumn==0 ){ 187cce7d176Sdrh j = i; 188cce7d176Sdrh }else{ 189967e8b73Sdrh for(j=0; j<pColumn->nId; j++){ 190967e8b73Sdrh if( pColumn->a[j].idx==i ) break; 191cce7d176Sdrh } 192cce7d176Sdrh } 193967e8b73Sdrh if( pColumn && j>=pColumn->nId ){ 1947020f651Sdrh char *zDflt = pTab->aCol[i].zDflt; 195c61053b7Sdrh if( zDflt==0 ){ 196c61053b7Sdrh sqliteVdbeAddOp(v, OP_Null, 0, 0, 0, 0); 197c61053b7Sdrh }else{ 1987020f651Sdrh sqliteVdbeAddOp(v, OP_String, 0, 0, zDflt, 0); 199c61053b7Sdrh } 2005974a30fSdrh }else if( srcTab>=0 ){ 2015974a30fSdrh sqliteVdbeAddOp(v, OP_Field, srcTab, i, 0, 0); 202cce7d176Sdrh }else{ 203cce7d176Sdrh sqliteExprCode(pParse, pList->a[j].pExpr); 204cce7d176Sdrh } 205cce7d176Sdrh } 206cce7d176Sdrh sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0, 0, 0); 2075974a30fSdrh sqliteVdbeAddOp(v, OP_Put, base, 0, 0, 0); 2081ccde15dSdrh 2091ccde15dSdrh /* Create appropriate entries for the new data row in all indices 2101ccde15dSdrh ** of the table. 2111ccde15dSdrh */ 212bed8690fSdrh for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ 213cce7d176Sdrh if( pIdx->pNext ){ 214cce7d176Sdrh sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0); 215cce7d176Sdrh } 216967e8b73Sdrh for(i=0; i<pIdx->nColumn; i++){ 217967e8b73Sdrh int idx = pIdx->aiColumn[i]; 218967e8b73Sdrh if( pColumn==0 ){ 219cce7d176Sdrh j = idx; 220cce7d176Sdrh }else{ 221967e8b73Sdrh for(j=0; j<pColumn->nId; j++){ 222967e8b73Sdrh if( pColumn->a[j].idx==idx ) break; 223cce7d176Sdrh } 224cce7d176Sdrh } 225967e8b73Sdrh if( pColumn && j>=pColumn->nId ){ 2267020f651Sdrh char *zDflt = pTab->aCol[idx].zDflt; 227c61053b7Sdrh if( zDflt==0 ){ 228c61053b7Sdrh sqliteVdbeAddOp(v, OP_Null, 0, 0, 0, 0); 229c61053b7Sdrh }else{ 2307020f651Sdrh sqliteVdbeAddOp(v, OP_String, 0, 0, zDflt, 0); 231c61053b7Sdrh } 2325974a30fSdrh }else if( srcTab>=0 ){ 233cc85b411Sdrh sqliteVdbeAddOp(v, OP_Field, srcTab, idx, 0, 0); 234cce7d176Sdrh }else{ 235cce7d176Sdrh sqliteExprCode(pParse, pList->a[j].pExpr); 236cce7d176Sdrh } 237cce7d176Sdrh } 238967e8b73Sdrh sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nColumn, 0, 0, 0); 2395974a30fSdrh sqliteVdbeAddOp(v, OP_PutIdx, idx+base, 0, 0, 0); 240cce7d176Sdrh } 2411ccde15dSdrh 2421ccde15dSdrh /* The bottom of the loop, if the data source is a SELECT statement 2431ccde15dSdrh */ 2445974a30fSdrh if( srcTab>=0 ){ 2455974a30fSdrh sqliteVdbeAddOp(v, OP_Goto, 0, iCont, 0, 0); 2465974a30fSdrh sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, iBreak); 247cce7d176Sdrh } 248cce7d176Sdrh 249cce7d176Sdrh insert_cleanup: 2505974a30fSdrh if( pList ) sqliteExprListDelete(pList); 2515974a30fSdrh if( pSelect ) sqliteSelectDelete(pSelect); 252967e8b73Sdrh sqliteIdListDelete(pColumn); 253cce7d176Sdrh } 254