aboutsummaryrefslogtreecommitdiff
path: root/src/insert.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2014-01-24 14:05:18 +0000
committerdrh <drh@noemail.net>2014-01-24 14:05:18 +0000
commitc1876986148b24227fc9ec7cb017bcac2a6c4402 (patch)
treee0da8e6005c85815241cdb71e9ab20126974e2a6 /src/insert.c
parentd9e3c267b469a4cefa99fc2ec2273eed9810c86e (diff)
parentb090352b5a46884806d1c1d99dbcd336b103fe67 (diff)
downloadsqlite-c1876986148b24227fc9ec7cb017bcac2a6c4402.tar.gz
sqlite-c1876986148b24227fc9ec7cb017bcac2a6c4402.zip
Bring in all the latest trunk changes, including the Common Table
Expressions implementation. FossilOrigin-Name: 9b43e559195680e558264c4c00d34dc9cf9d9146
Diffstat (limited to 'src/insert.c')
-rw-r--r--src/insert.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/src/insert.c b/src/insert.c
index c23d1b09f..ef7921bdd 100644
--- a/src/insert.c
+++ b/src/insert.c
@@ -540,7 +540,6 @@ static int xferOptimization(
void sqlite3Insert(
Parse *pParse, /* Parser context */
SrcList *pTabList, /* Name of table into which we are inserting */
- ExprList *pList, /* List of values to be inserted */
Select *pSelect, /* A SELECT statement to use as the data source */
IdList *pColumn, /* Column names corresponding to IDLIST. */
int onError /* How to handle constraint errors */
@@ -568,6 +567,7 @@ void sqlite3Insert(
Db *pDb; /* The database containing table being inserted into */
int appendFlag = 0; /* True if the insert is likely to be an append */
int withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */
+ ExprList *pList = 0; /* List of VALUES() to be inserted */
/* Register allocations */
int regFromSelect = 0;/* Base register for data coming from SELECT */
@@ -591,6 +591,17 @@ void sqlite3Insert(
goto insert_cleanup;
}
+ /* If the Select object is really just a simple VALUES() list with a
+ ** single row values (the common case) then keep that one row of values
+ ** and go ahead and discard the Select object
+ */
+ if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){
+ pList = pSelect->pEList;
+ pSelect->pEList = 0;
+ sqlite3SelectDelete(db, pSelect);
+ pSelect = 0;
+ }
+
/* Locate the table into which we will be inserting new information.
*/
assert( pTabList->nSrc==1 );
@@ -1233,6 +1244,7 @@ void sqlite3GenerateConstraintChecks(
int ipkTop = 0; /* Top of the rowid change constraint check */
int ipkBottom = 0; /* Bottom of the rowid change constraint check */
u8 isUpdate; /* True if this is an UPDATE operation */
+ int regRowid = -1; /* Register holding ROWID value */
isUpdate = regOldData!=0;
db = pParse->db;
@@ -1475,7 +1487,9 @@ void sqlite3GenerateConstraintChecks(
int iField = pIdx->aiColumn[i];
int x;
if( iField<0 || iField==pTab->iPKey ){
+ if( regRowid==regIdx+i ) continue; /* ROWID already in regIdx+i */
x = regNewData;
+ regRowid = pIdx->pPartIdxWhere ? -1 : regIdx+i;
}else{
x = iField + regNewData + 1;
}
@@ -1856,6 +1870,12 @@ static int xferOptimization(
if( pSelect==0 ){
return 0; /* Must be of the form INSERT INTO ... SELECT ... */
}
+ if( pParse->pWith || pSelect->pWith ){
+ /* Do not attempt to process this query if there are an WITH clauses
+ ** attached to it. Proceeding may generate a false "no such table: xxx"
+ ** error if pSelect reads from a CTE named "xxx". */
+ return 0;
+ }
if( sqlite3TriggerList(pParse, pDest) ){
return 0; /* tab1 must not have triggers */
}