|
dvander@1203
|
1 |
/* |
|
dvander@1203
|
2 |
** 2001 September 15 |
|
dvander@1203
|
3 |
** |
|
dvander@1203
|
4 |
** The author disclaims copyright to this source code. In place of |
|
dvander@1203
|
5 |
** a legal notice, here is a blessing: |
|
dvander@1203
|
6 |
** |
|
dvander@1203
|
7 |
** May you do good and not evil. |
|
dvander@1203
|
8 |
** May you find forgiveness for yourself and forgive others. |
|
dvander@1203
|
9 |
** May you share freely, never taking more than you give. |
|
dvander@1203
|
10 |
** |
|
dvander@1203
|
11 |
************************************************************************* |
|
dvander@1203
|
12 |
** This file contains C code routines that are called by the parser |
|
dvander@1203
|
13 |
** to handle INSERT statements in SQLite. |
|
dvander@1203
|
14 |
** |
|
dvander@1203
|
15 |
** $Id$ |
|
dvander@1203
|
16 |
*/ |
|
dvander@1203
|
17 |
#include "sqliteInt.h" |
|
dvander@1203
|
18 |
|
|
dvander@1203
|
19 |
/* |
|
dvander@1203
|
20 |
** Set P3 of the most recently inserted opcode to a column affinity |
|
dvander@1203
|
21 |
** string for index pIdx. A column affinity string has one character |
|
dvander@1203
|
22 |
** for each column in the table, according to the affinity of the column: |
|
dvander@1203
|
23 |
** |
|
dvander@1203
|
24 |
** Character Column affinity |
|
dvander@1203
|
25 |
** ------------------------------ |
|
dvander@1203
|
26 |
** 'a' TEXT |
|
dvander@1203
|
27 |
** 'b' NONE |
|
dvander@1203
|
28 |
** 'c' NUMERIC |
|
dvander@1203
|
29 |
** 'd' INTEGER |
|
dvander@1203
|
30 |
** 'e' REAL |
|
dvander@1203
|
31 |
*/ |
|
dvander@1203
|
32 |
void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ |
|
dvander@1203
|
33 |
if( !pIdx->zColAff ){ |
|
dvander@1203
|
34 |
/* The first time a column affinity string for a particular index is |
|
dvander@1203
|
35 |
** required, it is allocated and populated here. It is then stored as |
|
dvander@1203
|
36 |
** a member of the Index structure for subsequent use. |
|
dvander@1203
|
37 |
** |
|
dvander@1203
|
38 |
** The column affinity string will eventually be deleted by |
|
dvander@1203
|
39 |
** sqliteDeleteIndex() when the Index structure itself is cleaned |
|
dvander@1203
|
40 |
** up. |
|
dvander@1203
|
41 |
*/ |
|
dvander@1203
|
42 |
int n; |
|
dvander@1203
|
43 |
Table *pTab = pIdx->pTable; |
|
dvander@1203
|
44 |
pIdx->zColAff = (char *)sqliteMalloc(pIdx->nColumn+1); |
|
dvander@1203
|
45 |
if( !pIdx->zColAff ){ |
|
dvander@1203
|
46 |
return; |
|
dvander@1203
|
47 |
} |
|
dvander@1203
|
48 |
for(n=0; n<pIdx->nColumn; n++){ |
|
dvander@1203
|
49 |
pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity; |
|
dvander@1203
|
50 |
} |
|
dvander@1203
|
51 |
pIdx->zColAff[pIdx->nColumn] = '\0'; |
|
dvander@1203
|
52 |
} |
|
dvander@1203
|
53 |
|
|
dvander@1203
|
54 |
sqlite3VdbeChangeP3(v, -1, pIdx->zColAff, 0); |
|
dvander@1203
|
55 |
} |
|
dvander@1203
|
56 |
|
|
dvander@1203
|
57 |
/* |
|
dvander@1203
|
58 |
** Set P3 of the most recently inserted opcode to a column affinity |
|
dvander@1203
|
59 |
** string for table pTab. A column affinity string has one character |
|
dvander@1203
|
60 |
** for each column indexed by the index, according to the affinity of the |
|
dvander@1203
|
61 |
** column: |
|
dvander@1203
|
62 |
** |
|
dvander@1203
|
63 |
** Character Column affinity |
|
dvander@1203
|
64 |
** ------------------------------ |
|
dvander@1203
|
65 |
** 'a' TEXT |
|
dvander@1203
|
66 |
** 'b' NONE |
|
dvander@1203
|
67 |
** 'c' NUMERIC |
|
dvander@1203
|
68 |
** 'd' INTEGER |
|
dvander@1203
|
69 |
** 'e' REAL |
|
dvander@1203
|
70 |
*/ |
|
dvander@1203
|
71 |
void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){ |
|
dvander@1203
|
72 |
/* The first time a column affinity string for a particular table |
|
dvander@1203
|
73 |
** is required, it is allocated and populated here. It is then |
|
dvander@1203
|
74 |
** stored as a member of the Table structure for subsequent use. |
|
dvander@1203
|
75 |
** |
|
dvander@1203
|
76 |
** The column affinity string will eventually be deleted by |
|
dvander@1203
|
77 |
** sqlite3DeleteTable() when the Table structure itself is cleaned up. |
|
dvander@1203
|
78 |
*/ |
|
dvander@1203
|
79 |
if( !pTab->zColAff ){ |
|
dvander@1203
|
80 |
char *zColAff; |
|
dvander@1203
|
81 |
int i; |
|
dvander@1203
|
82 |
|
|
dvander@1203
|
83 |
zColAff = (char *)sqliteMalloc(pTab->nCol+1); |
|
dvander@1203
|
84 |
if( !zColAff ){ |
|
dvander@1203
|
85 |
return; |
|
dvander@1203
|
86 |
} |
|
dvander@1203
|
87 |
|
|
dvander@1203
|
88 |
for(i=0; i<pTab->nCol; i++){ |
|
dvander@1203
|
89 |
zColAff[i] = pTab->aCol[i].affinity; |
|
dvander@1203
|
90 |
} |
|
dvander@1203
|
91 |
zColAff[pTab->nCol] = '\0'; |
|
dvander@1203
|
92 |
|
|
dvander@1203
|
93 |
pTab->zColAff = zColAff; |
|
dvander@1203
|
94 |
} |
|
dvander@1203
|
95 |
|
|
dvander@1203
|
96 |
sqlite3VdbeChangeP3(v, -1, pTab->zColAff, 0); |
|
dvander@1203
|
97 |
} |
|
dvander@1203
|
98 |
|
|
dvander@1203
|
99 |
/* |
|
dvander@1203
|
100 |
** Return non-zero if SELECT statement p opens the table with rootpage |
|
dvander@1203
|
101 |
** iTab in database iDb. This is used to see if a statement of the form |
|
dvander@1203
|
102 |
** "INSERT INTO <iDb, iTab> SELECT ..." can run without using temporary |
|
dvander@1203
|
103 |
** table for the results of the SELECT. |
|
dvander@1203
|
104 |
** |
|
dvander@1203
|
105 |
** No checking is done for sub-selects that are part of expressions. |
|
dvander@1203
|
106 |
*/ |
|
dvander@1203
|
107 |
static int selectReadsTable(Select *p, Schema *pSchema, int iTab){ |
|
dvander@1203
|
108 |
int i; |
|
dvander@1203
|
109 |
struct SrcList_item *pItem; |
|
dvander@1203
|
110 |
if( p->pSrc==0 ) return 0; |
|
dvander@1203
|
111 |
for(i=0, pItem=p->pSrc->a; i<p->pSrc->nSrc; i++, pItem++){ |
|
dvander@1203
|
112 |
if( pItem->pSelect ){ |
|
dvander@1203
|
113 |
if( selectReadsTable(pItem->pSelect, pSchema, iTab) ) return 1; |
|
dvander@1203
|
114 |
}else{ |
|
dvander@1203
|
115 |
if( pItem->pTab->pSchema==pSchema && pItem->pTab->tnum==iTab ) return 1; |
|
dvander@1203
|
116 |
} |
|
dvander@1203
|
117 |
} |
|
dvander@1203
|
118 |
return 0; |
|
dvander@1203
|
119 |
} |
|
dvander@1203
|
120 |
|
|
dvander@1203
|
121 |
#ifndef SQLITE_OMIT_AUTOINCREMENT |
|
dvander@1203
|
122 |
/* |
|
dvander@1203
|
123 |
** Write out code to initialize the autoincrement logic. This code |
|
dvander@1203
|
124 |
** looks up the current autoincrement value in the sqlite_sequence |
|
dvander@1203
|
125 |
** table and stores that value in a memory cell. Code generated by |
|
dvander@1203
|
126 |
** autoIncStep() will keep that memory cell holding the largest |
|
dvander@1203
|
127 |
** rowid value. Code generated by autoIncEnd() will write the new |
|
dvander@1203
|
128 |
** largest value of the counter back into the sqlite_sequence table. |
|
dvander@1203
|
129 |
** |
|
dvander@1203
|
130 |
** This routine returns the index of the mem[] cell that contains |
|
dvander@1203
|
131 |
** the maximum rowid counter. |
|
dvander@1203
|
132 |
** |
|
dvander@1203
|
133 |
** Two memory cells are allocated. The next memory cell after the |
|
dvander@1203
|
134 |
** one returned holds the rowid in sqlite_sequence where we will |
|
dvander@1203
|
135 |
** write back the revised maximum rowid. |
|
dvander@1203
|
136 |
*/ |
|
dvander@1203
|
137 |
static int autoIncBegin( |
|
dvander@1203
|
138 |
Parse *pParse, /* Parsing context */ |
|
dvander@1203
|
139 |
int iDb, /* Index of the database holding pTab */ |
|
dvander@1203
|
140 |
Table *pTab /* The table we are writing to */ |
|
dvander@1203
|
141 |
){ |
|
dvander@1203
|
142 |
int memId = 0; |
|
dvander@1203
|
143 |
if( pTab->autoInc ){ |
|
dvander@1203
|
144 |
Vdbe *v = pParse->pVdbe; |
|
dvander@1203
|
145 |
Db *pDb = &pParse->db->aDb[iDb]; |
|
dvander@1203
|
146 |
int iCur = pParse->nTab; |
|
dvander@1203
|
147 |
int addr; |
|
dvander@1203
|
148 |
assert( v ); |
|
dvander@1203
|
149 |
addr = sqlite3VdbeCurrentAddr(v); |
|
dvander@1203
|
150 |
memId = pParse->nMem+1; |
|
dvander@1203
|
151 |
pParse->nMem += 2; |
|
dvander@1203
|
152 |
sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenRead); |
|
dvander@1203
|
153 |
sqlite3VdbeAddOp(v, OP_Rewind, iCur, addr+13); |
|
dvander@1203
|
154 |
sqlite3VdbeAddOp(v, OP_Column, iCur, 0); |
|
dvander@1203
|
155 |
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); |
|
dvander@1203
|
156 |
sqlite3VdbeAddOp(v, OP_Ne, 0x100, addr+12); |
|
dvander@1203
|
157 |
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0); |
|
dvander@1203
|
158 |
sqlite3VdbeAddOp(v, OP_MemStore, memId-1, 1); |
|
dvander@1203
|
159 |
sqlite3VdbeAddOp(v, OP_Column, iCur, 1); |
|
dvander@1203
|
160 |
sqlite3VdbeAddOp(v, OP_MemStore, memId, 1); |
|
dvander@1203
|
161 |
sqlite3VdbeAddOp(v, OP_Goto, 0, addr+13); |
|
dvander@1203
|
162 |
sqlite3VdbeAddOp(v, OP_Next, iCur, addr+4); |
|
dvander@1203
|
163 |
sqlite3VdbeAddOp(v, OP_Close, iCur, 0); |
|
dvander@1203
|
164 |
} |
|
dvander@1203
|
165 |
return memId; |
|
dvander@1203
|
166 |
} |
|
dvander@1203
|
167 |
|
|
dvander@1203
|
168 |
/* |
|
dvander@1203
|
169 |
** Update the maximum rowid for an autoincrement calculation. |
|
dvander@1203
|
170 |
** |
|
dvander@1203
|
171 |
** This routine should be called when the top of the stack holds a |
|
dvander@1203
|
172 |
** new rowid that is about to be inserted. If that new rowid is |
|
dvander@1203
|
173 |
** larger than the maximum rowid in the memId memory cell, then the |
|
dvander@1203
|
174 |
** memory cell is updated. The stack is unchanged. |
|
dvander@1203
|
175 |
*/ |
|
dvander@1203
|
176 |
static void autoIncStep(Parse *pParse, int memId){ |
|
dvander@1203
|
177 |
if( memId>0 ){ |
|
dvander@1203
|
178 |
sqlite3VdbeAddOp(pParse->pVdbe, OP_MemMax, memId, 0); |
|
dvander@1203
|
179 |
} |
|
dvander@1203
|
180 |
} |
|
dvander@1203
|
181 |
|
|
dvander@1203
|
182 |
/* |
|
dvander@1203
|
183 |
** After doing one or more inserts, the maximum rowid is stored |
|
dvander@1203
|
184 |
** in mem[memId]. Generate code to write this value back into the |
|
dvander@1203
|
185 |
** the sqlite_sequence table. |
|
dvander@1203
|
186 |
*/ |
|
dvander@1203
|
187 |
static void autoIncEnd( |
|
dvander@1203
|
188 |
Parse *pParse, /* The parsing context */ |
|
dvander@1203
|
189 |
int iDb, /* Index of the database holding pTab */ |
|
dvander@1203
|
190 |
Table *pTab, /* Table we are inserting into */ |
|
dvander@1203
|
191 |
int memId /* Memory cell holding the maximum rowid */ |
|
dvander@1203
|
192 |
){ |
|
dvander@1203
|
193 |
if( pTab->autoInc ){ |
|
dvander@1203
|
194 |
int iCur = pParse->nTab; |
|
dvander@1203
|
195 |
Vdbe *v = pParse->pVdbe; |
|
dvander@1203
|
196 |
Db *pDb = &pParse->db->aDb[iDb]; |
|
dvander@1203
|
197 |
int addr; |
|
dvander@1203
|
198 |
assert( v ); |
|
dvander@1203
|
199 |
addr = sqlite3VdbeCurrentAddr(v); |
|
dvander@1203
|
200 |
sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); |
|
dvander@1203
|
201 |
sqlite3VdbeAddOp(v, OP_MemLoad, memId-1, 0); |
|
dvander@1203
|
202 |
sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+7); |
|
dvander@1203
|
203 |
sqlite3VdbeAddOp(v, OP_Pop, 1, 0); |
|
dvander@1203
|
204 |
sqlite3VdbeAddOp(v, OP_NewRowid, iCur, 0); |
|
dvander@1203
|
205 |
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); |
|
dvander@1203
|
206 |
sqlite3VdbeAddOp(v, OP_MemLoad, memId, 0); |
|
dvander@1203
|
207 |
sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0); |
|
dvander@1203
|
208 |
sqlite3VdbeAddOp(v, OP_Insert, iCur, OPFLAG_APPEND); |
|
dvander@1203
|
209 |
sqlite3VdbeAddOp(v, OP_Close, iCur, 0); |
|
dvander@1203
|
210 |
} |
|
dvander@1203
|
211 |
} |
|
dvander@1203
|
212 |
#else |
|
dvander@1203
|
213 |
/* |
|
dvander@1203
|
214 |
** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines |
|
dvander@1203
|
215 |
** above are all no-ops |
|
dvander@1203
|
216 |
*/ |
|
dvander@1203
|
217 |
# define autoIncBegin(A,B,C) (0) |
|
dvander@1203
|
218 |
# define autoIncStep(A,B) |
|
dvander@1203
|
219 |
# define autoIncEnd(A,B,C,D) |
|
dvander@1203
|
220 |
#endif /* SQLITE_OMIT_AUTOINCREMENT */ |
|
dvander@1203
|
221 |
|
|
dvander@1203
|
222 |
|
|
dvander@1203
|
223 |
/* Forward declaration */ |
|
dvander@1203
|
224 |
static int xferOptimization( |
|
dvander@1203
|
225 |
Parse *pParse, /* Parser context */ |
|
dvander@1203
|
226 |
Table *pDest, /* The table we are inserting into */ |
|
dvander@1203
|
227 |
Select *pSelect, /* A SELECT statement to use as the data source */ |
|
dvander@1203
|
228 |
int onError, /* How to handle constraint errors */ |
|
dvander@1203
|
229 |
int iDbDest /* The database of pDest */ |
|
dvander@1203
|
230 |
); |
|
dvander@1203
|
231 |
|
|
dvander@1203
|
232 |
/* |
|
dvander@1203
|
233 |
** This routine is call to handle SQL of the following forms: |
|
dvander@1203
|
234 |
** |
|
dvander@1203
|
235 |
** insert into TABLE (IDLIST) values(EXPRLIST) |
|
dvander@1203
|
236 |
** insert into TABLE (IDLIST) select |
|
dvander@1203
|
237 |
** |
|
dvander@1203
|
238 |
** The IDLIST following the table name is always optional. If omitted, |
|
dvander@1203
|
239 |
** then a list of all columns for the table is substituted. The IDLIST |
|
dvander@1203
|
240 |
** appears in the pColumn parameter. pColumn is NULL if IDLIST is omitted. |
|
dvander@1203
|
241 |
** |
|
dvander@1203
|
242 |
** The pList parameter holds EXPRLIST in the first form of the INSERT |
|
dvander@1203
|
243 |
** statement above, and pSelect is NULL. For the second form, pList is |
|
dvander@1203
|
244 |
** NULL and pSelect is a pointer to the select statement used to generate |
|
dvander@1203
|
245 |
** data for the insert. |
|
dvander@1203
|
246 |
** |
|
dvander@1203
|
247 |
** The code generated follows one of four templates. For a simple |
|
dvander@1203
|
248 |
** select with data coming from a VALUES clause, the code executes |
|
dvander@1203
|
249 |
** once straight down through. The template looks like this: |
|
dvander@1203
|
250 |
** |
|
dvander@1203
|
251 |
** open write cursor to <table> and its indices |
|
dvander@1203
|
252 |
** puts VALUES clause expressions onto the stack |
|
dvander@1203
|
253 |
** write the resulting record into <table> |
|
dvander@1203
|
254 |
** cleanup |
|
dvander@1203
|
255 |
** |
|
dvander@1203
|
256 |
** The three remaining templates assume the statement is of the form |
|
dvander@1203
|
257 |
** |
|
dvander@1203
|
258 |
** INSERT INTO <table> SELECT ... |
|
dvander@1203
|
259 |
** |
|
dvander@1203
|
260 |
** If the SELECT clause is of the restricted form "SELECT * FROM <table2>" - |
|
dvander@1203
|
261 |
** in other words if the SELECT pulls all columns from a single table |
|
dvander@1203
|
262 |
** and there is no WHERE or LIMIT or GROUP BY or ORDER BY clauses, and |
|
dvander@1203
|
263 |
** if <table2> and <table1> are distinct tables but have identical |
|
dvander@1203
|
264 |
** schemas, including all the same indices, then a special optimization |
|
dvander@1203
|
265 |
** is invoked that copies raw records from <table2> over to <table1>. |
|
dvander@1203
|
266 |
** See the xferOptimization() function for the implementation of this |
|
dvander@1203
|
267 |
** template. This is the second template. |
|
dvander@1203
|
268 |
** |
|
dvander@1203
|
269 |
** open a write cursor to <table> |
|
dvander@1203
|
270 |
** open read cursor on <table2> |
|
dvander@1203
|
271 |
** transfer all records in <table2> over to <table> |
|
dvander@1203
|
272 |
** close cursors |
|
dvander@1203
|
273 |
** foreach index on <table> |
|
dvander@1203
|
274 |
** open a write cursor on the <table> index |
|
dvander@1203
|
275 |
** open a read cursor on the corresponding <table2> index |
|
dvander@1203
|
276 |
** transfer all records from the read to the write cursors |
|
dvander@1203
|
277 |
** close cursors |
|
dvander@1203
|
278 |
** end foreach |
|
dvander@1203
|
279 |
** |
|
dvander@1203
|
280 |
** The third template is for when the second template does not apply |
|
dvander@1203
|
281 |
** and the SELECT clause does not read from <table> at any time. |
|
dvander@1203
|
282 |
** The generated code follows this template: |
|
dvander@1203
|
283 |
** |
|
dvander@1203
|
284 |
** goto B |
|
dvander@1203
|
285 |
** A: setup for the SELECT |
|
dvander@1203
|
286 |
** loop over the rows in the SELECT |
|
dvander@1203
|
287 |
** gosub C |
|
dvander@1203
|
288 |
** end loop |
|
dvander@1203
|
289 |
** cleanup after the SELECT |
|
dvander@1203
|
290 |
** goto D |
|
dvander@1203
|
291 |
** B: open write cursor to <table> and its indices |
|
dvander@1203
|
292 |
** goto A |
|
dvander@1203
|
293 |
** C: insert the select result into <table> |
|
dvander@1203
|
294 |
** return |
|
dvander@1203
|
295 |
** D: cleanup |
|
dvander@1203
|
296 |
** |
|
dvander@1203
|
297 |
** The fourth template is used if the insert statement takes its |
|
dvander@1203
|
298 |
** values from a SELECT but the data is being inserted into a table |
|
dvander@1203
|
299 |
** that is also read as part of the SELECT. In the third form, |
|
dvander@1203
|
300 |
** we have to use a intermediate table to store the results of |
|
dvander@1203
|
301 |
** the select. The template is like this: |
|
dvander@1203
|
302 |
** |
|
dvander@1203
|
303 |
** goto B |
|
dvander@1203
|
304 |
** A: setup for the SELECT |
|
dvander@1203
|
305 |
** loop over the tables in the SELECT |
|
dvander@1203
|
306 |
** gosub C |
|
dvander@1203
|
307 |
** end loop |
|
dvander@1203
|
308 |
** cleanup after the SELECT |
|
dvander@1203
|
309 |
** goto D |
|
dvander@1203
|
310 |
** C: insert the select result into the intermediate table |
|
dvander@1203
|
311 |
** return |
|
dvander@1203
|
312 |
** B: open a cursor to an intermediate table |
|
dvander@1203
|
313 |
** goto A |
|
dvander@1203
|
314 |
** D: open write cursor to <table> and its indices |
|
dvander@1203
|
315 |
** loop over the intermediate table |
|
dvander@1203
|
316 |
** transfer values form intermediate table into <table> |
|
dvander@1203
|
317 |
** end the loop |
|
dvander@1203
|
318 |
** cleanup |
|
dvander@1203
|
319 |
*/ |
|
dvander@1203
|
320 |
void sqlite3Insert( |
|
dvander@1203
|
321 |
Parse *pParse, /* Parser context */ |
|
dvander@1203
|
322 |
SrcList *pTabList, /* Name of table into which we are inserting */ |
|
dvander@1203
|
323 |
ExprList *pList, /* List of values to be inserted */ |
|
dvander@1203
|
324 |
Select *pSelect, /* A SELECT statement to use as the data source */ |
|
dvander@1203
|
325 |
IdList *pColumn, /* Column names corresponding to IDLIST. */ |
|
dvander@1203
|
326 |
int onError /* How to handle constraint errors */ |
|
dvander@1203
|
327 |
){ |
|
dvander@1203
|
328 |
Table *pTab; /* The table to insert into */ |
|
dvander@1203
|
329 |
char *zTab; /* Name of the table into which we are inserting */ |
|
dvander@1203
|
330 |
const char *zDb; /* Name of the database holding this table */ |
|
dvander@1203
|
331 |
int i, j, idx; /* Loop counters */ |
|
dvander@1203
|
332 |
Vdbe *v; /* Generate code into this virtual machine */ |
|
dvander@1203
|
333 |
Index *pIdx; /* For looping over indices of the table */ |
|
dvander@1203
|
334 |
int nColumn; /* Number of columns in the data */ |
|
dvander@1203
|
335 |
int base = 0; /* VDBE Cursor number for pTab */ |
|
dvander@1203
|
336 |
int iCont=0,iBreak=0; /* Beginning and end of the loop over srcTab */ |
|
dvander@1203
|
337 |
sqlite3 *db; /* The main database structure */ |
|
dvander@1203
|
338 |
int keyColumn = -1; /* Column that is the INTEGER PRIMARY KEY */ |
|
dvander@1203
|
339 |
int endOfLoop; /* Label for the end of the insertion loop */ |
|
dvander@1203
|
340 |
int useTempTable = 0; /* Store SELECT results in intermediate table */ |
|
dvander@1203
|
341 |
int srcTab = 0; /* Data comes from this temporary cursor if >=0 */ |
|
dvander@1203
|
342 |
int iSelectLoop = 0; /* Address of code that implements the SELECT */ |
|
dvander@1203
|
343 |
int iCleanup = 0; /* Address of the cleanup code */ |
|
dvander@1203
|
344 |
int iInsertBlock = 0; /* Address of the subroutine used to insert data */ |
|
dvander@1203
|
345 |
int iCntMem = 0; /* Memory cell used for the row counter */ |
|
dvander@1203
|
346 |
int newIdx = -1; /* Cursor for the NEW table */ |
|
dvander@1203
|
347 |
Db *pDb; /* The database containing table being inserted into */ |
|
dvander@1203
|
348 |
int counterMem = 0; /* Memory cell holding AUTOINCREMENT counter */ |
|
dvander@1203
|
349 |
int appendFlag = 0; /* True if the insert is likely to be an append */ |
|
dvander@1203
|
350 |
int iDb; |
|
dvander@1203
|
351 |
|
|
dvander@1203
|
352 |
int nHidden = 0; |
|
dvander@1203
|
353 |
|
|
dvander@1203
|
354 |
#ifndef SQLITE_OMIT_TRIGGER |
|
dvander@1203
|
355 |
int isView; /* True if attempting to insert into a view */ |
|
dvander@1203
|
356 |
int triggers_exist = 0; /* True if there are FOR EACH ROW triggers */ |
|
dvander@1203
|
357 |
#endif |
|
dvander@1203
|
358 |
|
|
dvander@1203
|
359 |
if( pParse->nErr || sqlite3MallocFailed() ){ |
|
dvander@1203
|
360 |
goto insert_cleanup; |
|
dvander@1203
|
361 |
} |
|
dvander@1203
|
362 |
db = pParse->db; |
|
dvander@1203
|
363 |
|
|
dvander@1203
|
364 |
/* Locate the table into which we will be inserting new information. |
|
dvander@1203
|
365 |
*/ |
|
dvander@1203
|
366 |
assert( pTabList->nSrc==1 ); |
|
dvander@1203
|
367 |
zTab = pTabList->a[0].zName; |
|
dvander@1203
|
368 |
if( zTab==0 ) goto insert_cleanup; |
|
dvander@1203
|
369 |
pTab = sqlite3SrcListLookup(pParse, pTabList); |
|
dvander@1203
|
370 |
if( pTab==0 ){ |
|
dvander@1203
|
371 |
goto insert_cleanup; |
|
dvander@1203
|
372 |
} |
|
dvander@1203
|
373 |
iDb = sqlite3SchemaToIndex(db, pTab->pSchema); |
|
dvander@1203
|
374 |
assert( iDb<db->nDb ); |
|
dvander@1203
|
375 |
pDb = &db->aDb[iDb]; |
|
dvander@1203
|
376 |
zDb = pDb->zName; |
|
dvander@1203
|
377 |
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){ |
|
dvander@1203
|
378 |
goto insert_cleanup; |
|
dvander@1203
|
379 |
} |
|
dvander@1203
|
380 |
|
|
dvander@1203
|
381 |
/* Figure out if we have any triggers and if the table being |
|
dvander@1203
|
382 |
** inserted into is a view |
|
dvander@1203
|
383 |
*/ |
|
dvander@1203
|
384 |
#ifndef SQLITE_OMIT_TRIGGER |
|
dvander@1203
|
385 |
triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0); |
|
dvander@1203
|
386 |
isView = pTab->pSelect!=0; |
|
dvander@1203
|
387 |
#else |
|
dvander@1203
|
388 |
# define triggers_exist 0 |
|
dvander@1203
|
389 |
# define isView 0 |
|
dvander@1203
|
390 |
#endif |
|
dvander@1203
|
391 |
#ifdef SQLITE_OMIT_VIEW |
|
dvander@1203
|
392 |
# undef isView |
|
dvander@1203
|
393 |
# define isView 0 |
|
dvander@1203
|
394 |
#endif |
|
dvander@1203
|
395 |
|
|
dvander@1203
|
396 |
/* Ensure that: |
|
dvander@1203
|
397 |
* (a) the table is not read-only, |
|
dvander@1203
|
398 |
* (b) that if it is a view then ON INSERT triggers exist |
|
dvander@1203
|
399 |
*/ |
|
dvander@1203
|
400 |
if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){ |
|
dvander@1203
|
401 |
goto insert_cleanup; |
|
dvander@1203
|
402 |
} |
|
dvander@1203
|
403 |
assert( pTab!=0 ); |
|
dvander@1203
|
404 |
|
|
dvander@1203
|
405 |
/* If pTab is really a view, make sure it has been initialized. |
|
dvander@1203
|
406 |
** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual |
|
dvander@1203
|
407 |
** module table). |
|
dvander@1203
|
408 |
*/ |
|
dvander@1203
|
409 |
if( sqlite3ViewGetColumnNames(pParse, pTab) ){ |
|
dvander@1203
|
410 |
goto insert_cleanup; |
|
dvander@1203
|
411 |
} |
|
dvander@1203
|
412 |
|
|
dvander@1203
|
413 |
/* Allocate a VDBE |
|
dvander@1203
|
414 |
*/ |
|
dvander@1203
|
415 |
v = sqlite3GetVdbe(pParse); |
|
dvander@1203
|
416 |
if( v==0 ) goto insert_cleanup; |
|
dvander@1203
|
417 |
if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); |
|
dvander@1203
|
418 |
sqlite3BeginWriteOperation(pParse, pSelect || triggers_exist, iDb); |
|
dvander@1203
|
419 |
|
|
dvander@1203
|
420 |
/* if there are row triggers, allocate a temp table for new.* references. */ |
|
dvander@1203
|
421 |
if( triggers_exist ){ |
|
dvander@1203
|
422 |
newIdx = pParse->nTab++; |
|
dvander@1203
|
423 |
} |
|
dvander@1203
|
424 |
|
|
dvander@1203
|
425 |
#ifndef SQLITE_OMIT_XFER_OPT |
|
dvander@1203
|
426 |
/* If the statement is of the form |
|
dvander@1203
|
427 |
** |
|
dvander@1203
|
428 |
** INSERT INTO <table1> SELECT * FROM <table2>; |
|
dvander@1203
|
429 |
** |
|
dvander@1203
|
430 |
** Then special optimizations can be applied that make the transfer |
|
dvander@1203
|
431 |
** very fast and which reduce fragmentation of indices. |
|
dvander@1203
|
432 |
*/ |
|
dvander@1203
|
433 |
if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){ |
|
dvander@1203
|
434 |
assert( !triggers_exist ); |
|
dvander@1203
|
435 |
assert( pList==0 ); |
|
dvander@1203
|
436 |
goto insert_cleanup; |
|
dvander@1203
|
437 |
} |
|
dvander@1203
|
438 |
#endif /* SQLITE_OMIT_XFER_OPT */ |
|
dvander@1203
|
439 |
|
|
dvander@1203
|
440 |
/* If this is an AUTOINCREMENT table, look up the sequence number in the |
|
dvander@1203
|
441 |
** sqlite_sequence table and store it in memory cell counterMem. Also |
|
dvander@1203
|
442 |
** remember the rowid of the sqlite_sequence table entry in memory cell |
|
dvander@1203
|
443 |
** counterRowid. |
|
dvander@1203
|
444 |
*/ |
|
dvander@1203
|
445 |
counterMem = autoIncBegin(pParse, iDb, pTab); |
|
dvander@1203
|
446 |
|
|
dvander@1203
|
447 |
/* Figure out how many columns of data are supplied. If the data |
|
dvander@1203
|
448 |
** is coming from a SELECT statement, then this step also generates |
|
dvander@1203
|
449 |
** all the code to implement the SELECT statement and invoke a subroutine |
|
dvander@1203
|
450 |
** to process each row of the result. (Template 2.) If the SELECT |
|
dvander@1203
|
451 |
** statement uses the the table that is being inserted into, then the |
|
dvander@1203
|
452 |
** subroutine is also coded here. That subroutine stores the SELECT |
|
dvander@1203
|
453 |
** results in a temporary table. (Template 3.) |
|
dvander@1203
|
454 |
*/ |
|
dvander@1203
|
455 |
if( pSelect ){ |
|
dvander@1203
|
456 |
/* Data is coming from a SELECT. Generate code to implement that SELECT |
|
dvander@1203
|
457 |
*/ |
|
dvander@1203
|
458 |
int rc, iInitCode; |
|
dvander@1203
|
459 |
iInitCode = sqlite3VdbeAddOp(v, OP_Goto, 0, 0); |
|
dvander@1203
|
460 |
iSelectLoop = sqlite3VdbeCurrentAddr(v); |
|
dvander@1203
|
461 |
iInsertBlock = sqlite3VdbeMakeLabel(v); |
|
dvander@1203
|
462 |
|
|
dvander@1203
|
463 |
/* Resolve the expressions in the SELECT statement and execute it. */ |
|
dvander@1203
|
464 |
rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock,0,0,0,0); |
|
dvander@1203
|
465 |
if( rc || pParse->nErr || sqlite3MallocFailed() ){ |
|
dvander@1203
|
466 |
goto insert_cleanup; |
|
dvander@1203
|
467 |
} |
|
dvander@1203
|
468 |
|
|
dvander@1203
|
469 |
iCleanup = sqlite3VdbeMakeLabel(v); |
|
dvander@1203
|
470 |
sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup); |
|
dvander@1203
|
471 |
assert( pSelect->pEList ); |
|
dvander@1203
|
472 |
nColumn = pSelect->pEList->nExpr; |
|
dvander@1203
|
473 |
|
|
dvander@1203
|
474 |
/* Set useTempTable to TRUE if the result of the SELECT statement |
|
dvander@1203
|
475 |
** should be written into a temporary table. Set to FALSE if each |
|
dvander@1203
|
476 |
** row of the SELECT can be written directly into the result table. |
|
dvander@1203
|
477 |
** |
|
dvander@1203
|
478 |
** A temp table must be used if the table being updated is also one |
|
dvander@1203
|
479 |
** of the tables being read by the SELECT statement. Also use a |
|
dvander@1203
|
480 |
** temp table in the case of row triggers. |
|
dvander@1203
|
481 |
*/ |
|
dvander@1203
|
482 |
if( triggers_exist || selectReadsTable(pSelect,pTab->pSchema,pTab->tnum) ){ |
|
dvander@1203
|
483 |
useTempTable = 1; |
|
dvander@1203
|
484 |
} |
|
dvander@1203
|
485 |
|
|
dvander@1203
|
486 |
if( useTempTable ){ |
|
dvander@1203
|
487 |
/* Generate the subroutine that SELECT calls to process each row of |
|
dvander@1203
|
488 |
** the result. Store the result in a temporary table |
|
dvander@1203
|
489 |
*/ |
|
dvander@1203
|
490 |
srcTab = pParse->nTab++; |
|
dvander@1203
|
491 |
sqlite3VdbeResolveLabel(v, iInsertBlock); |
|
dvander@1203
|
492 |
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0); |
|
dvander@1203
|
493 |
sqlite3VdbeAddOp(v, OP_NewRowid, srcTab, 0); |
|
dvander@1203
|
494 |
sqlite3VdbeAddOp(v, OP_Pull, 1, 0); |
|
dvander@1203
|
495 |
sqlite3VdbeAddOp(v, OP_Insert, srcTab, OPFLAG_APPEND); |
|
dvander@1203
|
496 |
sqlite3VdbeAddOp(v, OP_Return, 0, 0); |
|
dvander@1203
|
497 |
|
|
dvander@1203
|
498 |
/* The following code runs first because the GOTO at the very top |
|
dvander@1203
|
499 |
** of the program jumps to it. Create the temporary table, then jump |
|
dvander@1203
|
500 |
** back up and execute the SELECT code above. |
|
dvander@1203
|
501 |
*/ |
|
dvander@1203
|
502 |
sqlite3VdbeJumpHere(v, iInitCode); |
|
dvander@1203
|
503 |
sqlite3VdbeAddOp(v, OP_OpenEphemeral, srcTab, 0); |
|
dvander@1203
|
504 |
sqlite3VdbeAddOp(v, OP_SetNumColumns, srcTab, nColumn); |
|
dvander@1203
|
505 |
sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop); |
|
dvander@1203
|
506 |
sqlite3VdbeResolveLabel(v, iCleanup); |
|
dvander@1203
|
507 |
}else{ |
|
dvander@1203
|
508 |
sqlite3VdbeJumpHere(v, iInitCode); |
|
dvander@1203
|
509 |
} |
|
dvander@1203
|
510 |
}else{ |
|
dvander@1203
|
511 |
/* This is the case if the data for the INSERT is coming from a VALUES |
|
dvander@1203
|
512 |
** clause |
|
dvander@1203
|
513 |
*/ |
|
dvander@1203
|
514 |
NameContext sNC; |
|
dvander@1203
|
515 |
memset(&sNC, 0, sizeof(sNC)); |
|
dvander@1203
|
516 |
sNC.pParse = pParse; |
|
dvander@1203
|
517 |
srcTab = -1; |
|
dvander@1203
|
518 |
useTempTable = 0; |
|
dvander@1203
|
519 |
nColumn = pList ? pList->nExpr : 0; |
|
dvander@1203
|
520 |
for(i=0; i<nColumn; i++){ |
|
dvander@1203
|
521 |
if( sqlite3ExprResolveNames(&sNC, pList->a[i].pExpr) ){ |
|
dvander@1203
|
522 |
goto insert_cleanup; |
|
dvander@1203
|
523 |
} |
|
dvander@1203
|
524 |
} |
|
dvander@1203
|
525 |
} |
|
dvander@1203
|
526 |
|
|
dvander@1203
|
527 |
/* Make sure the number of columns in the source data matches the number |
|
dvander@1203
|
528 |
** of columns to be inserted into the table. |
|
dvander@1203
|
529 |
*/ |
|
dvander@1203
|
530 |
if( IsVirtual(pTab) ){ |
|
dvander@1203
|
531 |
for(i=0; i<pTab->nCol; i++){ |
|
dvander@1203
|
532 |
nHidden += (IsHiddenColumn(&pTab->aCol[i]) ? 1 : 0); |
|
dvander@1203
|
533 |
} |
|
dvander@1203
|
534 |
} |
|
dvander@1203
|
535 |
if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){ |
|
dvander@1203
|
536 |
sqlite3ErrorMsg(pParse, |
|
dvander@1203
|
537 |
"table %S has %d columns but %d values were supplied", |
|
dvander@1203
|
538 |
pTabList, 0, pTab->nCol, nColumn); |
|
dvander@1203
|
539 |
goto insert_cleanup; |
|
dvander@1203
|
540 |
} |
|
dvander@1203
|
541 |
if( pColumn!=0 && nColumn!=pColumn->nId ){ |
|
dvander@1203
|
542 |
sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId); |
|
dvander@1203
|
543 |
goto insert_cleanup; |
|
dvander@1203
|
544 |
} |
|
dvander@1203
|
545 |
|
|
dvander@1203
|
546 |
/* If the INSERT statement included an IDLIST term, then make sure |
|
dvander@1203
|
547 |
** all elements of the IDLIST really are columns of the table and |
|
dvander@1203
|
548 |
** remember the column indices. |
|
dvander@1203
|
549 |
** |
|
dvander@1203
|
550 |
** If the table has an INTEGER PRIMARY KEY column and that column |
|
dvander@1203
|
551 |
** is named in the IDLIST, then record in the keyColumn variable |
|
dvander@1203
|
552 |
** the index into IDLIST of the primary key column. keyColumn is |
|
dvander@1203
|
553 |
** the index of the primary key as it appears in IDLIST, not as |
|
dvander@1203
|
554 |
** is appears in the original table. (The index of the primary |
|
dvander@1203
|
555 |
** key in the original table is pTab->iPKey.) |
|
dvander@1203
|
556 |
*/ |
|
dvander@1203
|
557 |
if( pColumn ){ |
|
dvander@1203
|
558 |
for(i=0; i<pColumn->nId; i++){ |
|
dvander@1203
|
559 |
pColumn->a[i].idx = -1; |
|
dvander@1203
|
560 |
} |
|
dvander@1203
|
561 |
for(i=0; i<pColumn->nId; i++){ |
|
dvander@1203
|
562 |
for(j=0; j<pTab->nCol; j++){ |
|
dvander@1203
|
563 |
if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){ |
|
dvander@1203
|
564 |
pColumn->a[i].idx = j; |
|
dvander@1203
|
565 |
if( j==pTab->iPKey ){ |
|
dvander@1203
|
566 |
keyColumn = i; |
|
dvander@1203
|
567 |
} |
|
dvander@1203
|
568 |
break; |
|
dvander@1203
|
569 |
} |
|
dvander@1203
|
570 |
} |
|
dvander@1203
|
571 |
if( j>=pTab->nCol ){ |
|
dvander@1203
|
572 |
if( sqlite3IsRowid(pColumn->a[i].zName) ){ |
|
dvander@1203
|
573 |
keyColumn = i; |
|
dvander@1203
|
574 |
}else{ |
|
dvander@1203
|
575 |
sqlite3ErrorMsg(pParse, "table %S has no column named %s", |
|
dvander@1203
|
576 |
pTabList, 0, pColumn->a[i].zName); |
|
dvander@1203
|
577 |
pParse->nErr++; |
|
dvander@1203
|
578 |
goto insert_cleanup; |
|
dvander@1203
|
579 |
} |
|
dvander@1203
|
580 |
} |
|
dvander@1203
|
581 |
} |
|
dvander@1203
|
582 |
} |
|
dvander@1203
|
583 |
|
|
dvander@1203
|
584 |
/* If there is no IDLIST term but the table has an integer primary |
|
dvander@1203
|
585 |
** key, the set the keyColumn variable to the primary key column index |
|
dvander@1203
|
586 |
** in the original table definition. |
|
dvander@1203
|
587 |
*/ |
|
dvander@1203
|
588 |
if( pColumn==0 && nColumn>0 ){ |
|
dvander@1203
|
589 |
keyColumn = pTab->iPKey; |
|
dvander@1203
|
590 |
} |
|
dvander@1203
|
591 |
|
|
dvander@1203
|
592 |
/* Open the temp table for FOR EACH ROW triggers |
|
dvander@1203
|
593 |
*/ |
|
dvander@1203
|
594 |
if( triggers_exist ){ |
|
dvander@1203
|
595 |
sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0); |
|
dvander@1203
|
596 |
sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol); |
|
dvander@1203
|
597 |
} |
|
dvander@1203
|
598 |
|
|
dvander@1203
|
599 |
/* Initialize the count of rows to be inserted |
|
dvander@1203
|
600 |
*/ |
|
dvander@1203
|
601 |
if( db->flags & SQLITE_CountRows ){ |
|
dvander@1203
|
602 |
iCntMem = pParse->nMem++; |
|
dvander@1203
|
603 |
sqlite3VdbeAddOp(v, OP_MemInt, 0, iCntMem); |
|
dvander@1203
|
604 |
} |
|
dvander@1203
|
605 |
|
|
dvander@1203
|
606 |
/* Open tables and indices if there are no row triggers */ |
|
dvander@1203
|
607 |
if( !triggers_exist ){ |
|
dvander@1203
|
608 |
base = pParse->nTab; |
|
dvander@1203
|
609 |
sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite); |
|
dvander@1203
|
610 |
} |
|
dvander@1203
|
611 |
|
|
dvander@1203
|
612 |
/* If the data source is a temporary table, then we have to create |
|
dvander@1203
|
613 |
** a loop because there might be multiple rows of data. If the data |
|
dvander@1203
|
614 |
** source is a subroutine call from the SELECT statement, then we need |
|
dvander@1203
|
615 |
** to launch the SELECT statement processing. |
|
dvander@1203
|
616 |
*/ |
|
dvander@1203
|
617 |
if( useTempTable ){ |
|
dvander@1203
|
618 |
iBreak = sqlite3VdbeMakeLabel(v); |
|
dvander@1203
|
619 |
sqlite3VdbeAddOp(v, OP_Rewind, srcTab, iBreak); |
|
dvander@1203
|
620 |
iCont = sqlite3VdbeCurrentAddr(v); |
|
dvander@1203
|
621 |
}else if( pSelect ){ |
|
dvander@1203
|
622 |
sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop); |
|
dvander@1203
|
623 |
sqlite3VdbeResolveLabel(v, iInsertBlock); |
|
dvander@1203
|
624 |
} |
|
dvander@1203
|
625 |
|
|
dvander@1203
|
626 |
/* Run the BEFORE and INSTEAD OF triggers, if there are any |
|
dvander@1203
|
627 |
*/ |
|
dvander@1203
|
628 |
endOfLoop = sqlite3VdbeMakeLabel(v); |
|
dvander@1203
|
629 |
if( triggers_exist & TRIGGER_BEFORE ){ |
|
dvander@1203
|
630 |
|
|
dvander@1203
|
631 |
/* build the NEW.* reference row. Note that if there is an INTEGER |
|
dvander@1203
|
632 |
** PRIMARY KEY into which a NULL is being inserted, that NULL will be |
|
dvander@1203
|
633 |
** translated into a unique ID for the row. But on a BEFORE trigger, |
|
dvander@1203
|
634 |
** we do not know what the unique ID will be (because the insert has |
|
dvander@1203
|
635 |
** not happened yet) so we substitute a rowid of -1 |
|
dvander@1203
|
636 |
*/ |
|
dvander@1203
|
637 |
if( keyColumn<0 ){ |
|
dvander@1203
|
638 |
sqlite3VdbeAddOp(v, OP_Integer, -1, 0); |
|
dvander@1203
|
639 |
}else if( useTempTable ){ |
|
dvander@1203
|
640 |
sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn); |
|
dvander@1203
|
641 |
}else{ |
|
dvander@1203
|
642 |
assert( pSelect==0 ); /* Otherwise useTempTable is true */ |
|
dvander@1203
|
643 |
sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr); |
|
dvander@1203
|
644 |
sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); |
|
dvander@1203
|
645 |
sqlite3VdbeAddOp(v, OP_Pop, 1, 0); |
|
dvander@1203
|
646 |
sqlite3VdbeAddOp(v, OP_Integer, -1, 0); |
|
dvander@1203
|
647 |
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); |
|
dvander@1203
|
648 |
} |
|
dvander@1203
|
649 |
|
|
dvander@1203
|
650 |
/* Cannot have triggers on a virtual table. If it were possible, |
|
dvander@1203
|
651 |
** this block would have to account for hidden column. |
|
dvander@1203
|
652 |
*/ |
|
dvander@1203
|
653 |
assert(!IsVirtual(pTab)); |
|
dvander@1203
|
654 |
|
|
dvander@1203
|
655 |
/* Create the new column data |
|
dvander@1203
|
656 |
*/ |
|
dvander@1203
|
657 |
for(i=0; i<pTab->nCol; i++){ |
|
dvander@1203
|
658 |
if( pColumn==0 ){ |
|
dvander@1203
|
659 |
j = i; |
|
dvander@1203
|
660 |
}else{ |
|
dvander@1203
|
661 |
for(j=0; j<pColumn->nId; j++){ |
|
dvander@1203
|
662 |
if( pColumn->a[j].idx==i ) break; |
|
dvander@1203
|
663 |
} |
|
dvander@1203
|
664 |
} |
|
dvander@1203
|
665 |
if( pColumn && j>=pColumn->nId ){ |
|
dvander@1203
|
666 |
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); |
|
dvander@1203
|
667 |
}else if( useTempTable ){ |
|
dvander@1203
|
668 |
sqlite3VdbeAddOp(v, OP_Column, srcTab, j); |
|
dvander@1203
|
669 |
}else{ |
|
dvander@1203
|
670 |
assert( pSelect==0 ); /* Otherwise useTempTable is true */ |
|
dvander@1203
|
671 |
sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr); |
|
dvander@1203
|
672 |
} |
|
dvander@1203
|
673 |
} |
|
dvander@1203
|
674 |
sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0); |
|
dvander@1203
|
675 |
|
|
dvander@1203
|
676 |
/* If this is an INSERT on a view with an INSTEAD OF INSERT trigger, |
|
dvander@1203
|
677 |
** do not attempt any conversions before assembling the record. |
|
dvander@1203
|
678 |
** If this is a real table, attempt conversions as required by the |
|
dvander@1203
|
679 |
** table column affinities. |
|
dvander@1203
|
680 |
*/ |
|
dvander@1203
|
681 |
if( !isView ){ |
|
dvander@1203
|
682 |
sqlite3TableAffinityStr(v, pTab); |
|
dvander@1203
|
683 |
} |
|
dvander@1203
|
684 |
sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0); |
|
dvander@1203
|
685 |
|
|
dvander@1203
|
686 |
/* Fire BEFORE or INSTEAD OF triggers */ |
|
dvander@1203
|
687 |
if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab, |
|
dvander@1203
|
688 |
newIdx, -1, onError, endOfLoop) ){ |
|
dvander@1203
|
689 |
goto insert_cleanup; |
|
dvander@1203
|
690 |
} |
|
dvander@1203
|
691 |
} |
|
dvander@1203
|
692 |
|
|
dvander@1203
|
693 |
/* If any triggers exists, the opening of tables and indices is deferred |
|
dvander@1203
|
694 |
** until now. |
|
dvander@1203
|
695 |
*/ |
|
dvander@1203
|
696 |
if( triggers_exist && !isView ){ |
|
dvander@1203
|
697 |
base = pParse->nTab; |
|
dvander@1203
|
698 |
sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite); |
|
dvander@1203
|
699 |
} |
|
dvander@1203
|
700 |
|
|
dvander@1203
|
701 |
/* Push the record number for the new entry onto the stack. The |
|
dvander@1203
|
702 |
** record number is a randomly generate integer created by NewRowid |
|
dvander@1203
|
703 |
** except when the table has an INTEGER PRIMARY KEY column, in which |
|
dvander@1203
|
704 |
** case the record number is the same as that column. |
|
dvander@1203
|
705 |
*/ |
|
dvander@1203
|
706 |
if( !isView ){ |
|
dvander@1203
|
707 |
if( IsVirtual(pTab) ){ |
|
dvander@1203
|
708 |
/* The row that the VUpdate opcode will delete: none */ |
|
dvander@1203
|
709 |
sqlite3VdbeAddOp(v, OP_Null, 0, 0); |
|
dvander@1203
|
710 |
} |
|
dvander@1203
|
711 |
if( keyColumn>=0 ){ |
|
dvander@1203
|
712 |
if( useTempTable ){ |
|
dvander@1203
|
713 |
sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn); |
|
dvander@1203
|
714 |
}else if( pSelect ){ |
|
dvander@1203
|
715 |
sqlite3VdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1); |
|
dvander@1203
|
716 |
}else{ |
|
dvander@1203
|
717 |
VdbeOp *pOp; |
|
dvander@1203
|
718 |
sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr); |
|
dvander@1203
|
719 |
pOp = sqlite3VdbeGetOp(v, sqlite3VdbeCurrentAddr(v) - 1); |
|
dvander@1203
|
720 |
if( pOp && pOp->opcode==OP_Null ){ |
|
dvander@1203
|
721 |
appendFlag = 1; |
|
dvander@1203
|
722 |
pOp->opcode = OP_NewRowid; |
|
dvander@1203
|
723 |
pOp->p1 = base; |
|
dvander@1203
|
724 |
pOp->p2 = counterMem; |
|
dvander@1203
|
725 |
} |
|
dvander@1203
|
726 |
} |
|
dvander@1203
|
727 |
/* If the PRIMARY KEY expression is NULL, then use OP_NewRowid |
|
dvander@1203
|
728 |
** to generate a unique primary key value. |
|
dvander@1203
|
729 |
*/ |
|
dvander@1203
|
730 |
if( !appendFlag ){ |
|
dvander@1203
|
731 |
sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); |
|
dvander@1203
|
732 |
sqlite3VdbeAddOp(v, OP_Pop, 1, 0); |
|
dvander@1203
|
733 |
sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem); |
|
dvander@1203
|
734 |
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); |
|
dvander@1203
|
735 |
} |
|
dvander@1203
|
736 |
}else if( IsVirtual(pTab) ){ |
|
dvander@1203
|
737 |
sqlite3VdbeAddOp(v, OP_Null, 0, 0); |
|
dvander@1203
|
738 |
}else{ |
|
dvander@1203
|
739 |
sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem); |
|
dvander@1203
|
740 |
appendFlag = 1; |
|
dvander@1203
|
741 |
} |
|
dvander@1203
|
742 |
autoIncStep(pParse, counterMem); |
|
dvander@1203
|
743 |
|
|
dvander@1203
|
744 |
/* Push onto the stack, data for all columns of the new entry, beginning |
|
dvander@1203
|
745 |
** with the first column. |
|
dvander@1203
|
746 |
*/ |
|
dvander@1203
|
747 |
nHidden = 0; |
|
dvander@1203
|
748 |
for(i=0; i<pTab->nCol; i++){ |
|
dvander@1203
|
749 |
if( i==pTab->iPKey ){ |
|
dvander@1203
|
750 |
/* The value of the INTEGER PRIMARY KEY column is always a NULL. |
|
dvander@1203
|
751 |
** Whenever this column is read, the record number will be substituted |
|
dvander@1203
|
752 |
** in its place. So will fill this column with a NULL to avoid |
|
dvander@1203
|
753 |
** taking up data space with information that will never be used. */ |
|
dvander@1203
|
754 |
sqlite3VdbeAddOp(v, OP_Null, 0, 0); |
|
dvander@1203
|
755 |
continue; |
|
dvander@1203
|
756 |
} |
|
dvander@1203
|
757 |
if( pColumn==0 ){ |
|
dvander@1203
|
758 |
if( IsHiddenColumn(&pTab->aCol[i]) ){ |
|
dvander@1203
|
759 |
assert( IsVirtual(pTab) ); |
|
dvander@1203
|
760 |
j = -1; |
|
dvander@1203
|
761 |
nHidden++; |
|
dvander@1203
|
762 |
}else{ |
|
dvander@1203
|
763 |
j = i - nHidden; |
|
dvander@1203
|
764 |
} |
|
dvander@1203
|
765 |
}else{ |
|
dvander@1203
|
766 |
for(j=0; j<pColumn->nId; j++){ |
|
dvander@1203
|
767 |
if( pColumn->a[j].idx==i ) break; |
|
dvander@1203
|
768 |
} |
|
dvander@1203
|
769 |
} |
|
dvander@1203
|
770 |
if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){ |
|
dvander@1203
|
771 |
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); |
|
dvander@1203
|
772 |
}else if( useTempTable ){ |
|
dvander@1203
|
773 |
sqlite3VdbeAddOp(v, OP_Column, srcTab, j); |
|
dvander@1203
|
774 |
}else if( pSelect ){ |
|
dvander@1203
|
775 |
sqlite3VdbeAddOp(v, OP_Dup, i+nColumn-j+IsVirtual(pTab), 1); |
|
dvander@1203
|
776 |
}else{ |
|
dvander@1203
|
777 |
sqlite3ExprCode(pParse, pList->a[j].pExpr); |
|
dvander@1203
|
778 |
} |
|
dvander@1203
|
779 |
} |
|
dvander@1203
|
780 |
|
|
dvander@1203
|
781 |
/* Generate code to check constraints and generate index keys and |
|
dvander@1203
|
782 |
** do the insertion. |
|
dvander@1203
|
783 |
*/ |
|
dvander@1203
|
784 |
#ifndef SQLITE_OMIT_VIRTUALTABLE |
|
dvander@1203
|
785 |
if( IsVirtual(pTab) ){ |
|
dvander@1203
|
786 |
pParse->pVirtualLock = pTab; |
|
dvander@1203
|
787 |
sqlite3VdbeOp3(v, OP_VUpdate, 1, pTab->nCol+2, |
|
dvander@1203
|
788 |
(const char*)pTab->pVtab, P3_VTAB); |
|
dvander@1203
|
789 |
}else |
|
dvander@1203
|
790 |
#endif |
|
dvander@1203
|
791 |
{ |
|
dvander@1203
|
792 |
sqlite3GenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0, |
|
dvander@1203
|
793 |
0, onError, endOfLoop); |
|
dvander@1203
|
794 |
sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0, |
|
dvander@1203
|
795 |
(triggers_exist & TRIGGER_AFTER)!=0 ? newIdx : -1, |
|
dvander@1203
|
796 |
appendFlag); |
|
dvander@1203
|
797 |
} |
|
dvander@1203
|
798 |
} |
|
dvander@1203
|
799 |
|
|
dvander@1203
|
800 |
/* Update the count of rows that are inserted |
|
dvander@1203
|
801 |
*/ |
|
dvander@1203
|
802 |
if( (db->flags & SQLITE_CountRows)!=0 ){ |
|
dvander@1203
|
803 |
sqlite3VdbeAddOp(v, OP_MemIncr, 1, iCntMem); |
|
dvander@1203
|
804 |
} |
|
dvander@1203
|
805 |
|
|
dvander@1203
|
806 |
if( triggers_exist ){ |
|
dvander@1203
|
807 |
/* Close all tables opened */ |
|
dvander@1203
|
808 |
if( !isView ){ |
|
dvander@1203
|
809 |
sqlite3VdbeAddOp(v, OP_Close, base, 0); |
|
dvander@1203
|
810 |
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ |
|
dvander@1203
|
811 |
sqlite3VdbeAddOp(v, OP_Close, idx+base, 0); |
|
dvander@1203
|
812 |
} |
|
dvander@1203
|
813 |
} |
|
dvander@1203
|
814 |
|
|
dvander@1203
|
815 |
/* Code AFTER triggers */ |
|
dvander@1203
|
816 |
if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_AFTER, pTab, |
|
dvander@1203
|
817 |
newIdx, -1, onError, endOfLoop) ){ |
|
dvander@1203
|
818 |
goto insert_cleanup; |
|
dvander@1203
|
819 |
} |
|
dvander@1203
|
820 |
} |
|
dvander@1203
|
821 |
|
|
dvander@1203
|
822 |
/* The bottom of the loop, if the data source is a SELECT statement |
|
dvander@1203
|
823 |
*/ |
|
dvander@1203
|
824 |
sqlite3VdbeResolveLabel(v, endOfLoop); |
|
dvander@1203
|
825 |
if( useTempTable ){ |
|
dvander@1203
|
826 |
sqlite3VdbeAddOp(v, OP_Next, srcTab, iCont); |
|
dvander@1203
|
827 |
sqlite3VdbeResolveLabel(v, iBreak); |
|
dvander@1203
|
828 |
sqlite3VdbeAddOp(v, OP_Close, srcTab, 0); |
|
dvander@1203
|
829 |
}else if( pSelect ){ |
|
dvander@1203
|
830 |
sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0); |
|
dvander@1203
|
831 |
sqlite3VdbeAddOp(v, OP_Return, 0, 0); |
|
dvander@1203
|
832 |
sqlite3VdbeResolveLabel(v, iCleanup); |
|
dvander@1203
|
833 |
} |
|
dvander@1203
|
834 |
|
|
dvander@1203
|
835 |
if( !triggers_exist && !IsVirtual(pTab) ){ |
|
dvander@1203
|
836 |
/* Close all tables opened */ |
|
dvander@1203
|
837 |
sqlite3VdbeAddOp(v, OP_Close, base, 0); |
|
dvander@1203
|
838 |
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ |
|
dvander@1203
|
839 |
sqlite3VdbeAddOp(v, OP_Close, idx+base, 0); |
|
dvander@1203
|
840 |
} |
|
dvander@1203
|
841 |
} |
|
dvander@1203
|
842 |
|
|
dvander@1203
|
843 |
/* Update the sqlite_sequence table by storing the content of the |
|
dvander@1203
|
844 |
** counter value in memory counterMem back into the sqlite_sequence |
|
dvander@1203
|
845 |
** table. |
|
dvander@1203
|
846 |
*/ |
|
dvander@1203
|
847 |
autoIncEnd(pParse, iDb, pTab, counterMem); |
|
dvander@1203
|
848 |
|
|
dvander@1203
|
849 |
/* |
|
dvander@1203
|
850 |
** Return the number of rows inserted. If this routine is |
|
dvander@1203
|
851 |
** generating code because of a call to sqlite3NestedParse(), do not |
|
dvander@1203
|
852 |
** invoke the callback function. |
|
dvander@1203
|
853 |
*/ |
|
dvander@1203
|
854 |
if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){ |
|
dvander@1203
|
855 |
sqlite3VdbeAddOp(v, OP_MemLoad, iCntMem, 0); |
|
dvander@1203
|
856 |
sqlite3VdbeAddOp(v, OP_Callback, 1, 0); |
|
dvander@1203
|
857 |
sqlite3VdbeSetNumCols(v, 1); |
|
dvander@1203
|
858 |
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", P3_STATIC); |
|
dvander@1203
|
859 |
} |
|
dvander@1203
|
860 |
|
|
dvander@1203
|
861 |
insert_cleanup: |
|
dvander@1203
|
862 |
sqlite3SrcListDelete(pTabList); |
|
dvander@1203
|
863 |
sqlite3ExprListDelete(pList); |
|
dvander@1203
|
864 |
sqlite3SelectDelete(pSelect); |
|
dvander@1203
|
865 |
sqlite3IdListDelete(pColumn); |
|
dvander@1203
|
866 |
} |
|
dvander@1203
|
867 |
|
|
dvander@1203
|
868 |
/* |
|
dvander@1203
|
869 |
** Generate code to do a constraint check prior to an INSERT or an UPDATE. |
|
dvander@1203
|
870 |
** |
|
dvander@1203
|
871 |
** When this routine is called, the stack contains (from bottom to top) |
|
dvander@1203
|
872 |
** the following values: |
|
dvander@1203
|
873 |
** |
|
dvander@1203
|
874 |
** 1. The rowid of the row to be updated before the update. This |
|
dvander@1203
|
875 |
** value is omitted unless we are doing an UPDATE that involves a |
|
dvander@1203
|
876 |
** change to the record number. |
|
dvander@1203
|
877 |
** |
|
dvander@1203
|
878 |
** 2. The rowid of the row after the update. |
|
dvander@1203
|
879 |
** |
|
dvander@1203
|
880 |
** 3. The data in the first column of the entry after the update. |
|
dvander@1203
|
881 |
** |
|
dvander@1203
|
882 |
** i. Data from middle columns... |
|
dvander@1203
|
883 |
** |
|
dvander@1203
|
884 |
** N. The data in the last column of the entry after the update. |
|
dvander@1203
|
885 |
** |
|
dvander@1203
|
886 |
** The old rowid shown as entry (1) above is omitted unless both isUpdate |
|
dvander@1203
|
887 |
** and rowidChng are 1. isUpdate is true for UPDATEs and false for |
|
dvander@1203
|
888 |
** INSERTs and rowidChng is true if the record number is being changed. |
|
dvander@1203
|
889 |
** |
|
dvander@1203
|
890 |
** The code generated by this routine pushes additional entries onto |
|
dvander@1203
|
891 |
** the stack which are the keys for new index entries for the new record. |
|
dvander@1203
|
892 |
** The order of index keys is the same as the order of the indices on |
|
dvander@1203
|
893 |
** the pTable->pIndex list. A key is only created for index i if |
|
dvander@1203
|
894 |
** aIdxUsed!=0 and aIdxUsed[i]!=0. |
|
dvander@1203
|
895 |
** |
|
dvander@1203
|
896 |
** This routine also generates code to check constraints. NOT NULL, |
|
dvander@1203
|
897 |
** CHECK, and UNIQUE constraints are all checked. If a constraint fails, |
|
dvander@1203
|
898 |
** then the appropriate action is performed. There are five possible |
|
dvander@1203
|
899 |
** actions: ROLLBACK, ABORT, FAIL, REPLACE, and IGNORE. |
|
dvander@1203
|
900 |
** |
|
dvander@1203
|
901 |
** Constraint type Action What Happens |
|
dvander@1203
|
902 |
** --------------- ---------- ---------------------------------------- |
|
dvander@1203
|
903 |
** any ROLLBACK The current transaction is rolled back and |
|
dvander@1203
|
904 |
** sqlite3_exec() returns immediately with a |
|
dvander@1203
|
905 |
** return code of SQLITE_CONSTRAINT. |
|
dvander@1203
|
906 |
** |
|
dvander@1203
|
907 |
** any ABORT Back out changes from the current command |
|
dvander@1203
|
908 |
** only (do not do a complete rollback) then |
|
dvander@1203
|
909 |
** cause sqlite3_exec() to return immediately |
|
dvander@1203
|
910 |
** with SQLITE_CONSTRAINT. |
|
dvander@1203
|
911 |
** |
|
dvander@1203
|
912 |
** any FAIL Sqlite_exec() returns immediately with a |
|
dvander@1203
|
913 |
** return code of SQLITE_CONSTRAINT. The |
|
dvander@1203
|
914 |
** transaction is not rolled back and any |
|
dvander@1203
|
915 |
** prior changes are retained. |
|
dvander@1203
|
916 |
** |
|
dvander@1203
|
917 |
** any IGNORE The record number and data is popped from |
|
dvander@1203
|
918 |
** the stack and there is an immediate jump |
|
dvander@1203
|
919 |
** to label ignoreDest. |
|
dvander@1203
|
920 |
** |
|
dvander@1203
|
921 |
** NOT NULL REPLACE The NULL value is replace by the default |
|
dvander@1203
|
922 |
** value for that column. If the default value |
|
dvander@1203
|
923 |
** is NULL, the action is the same as ABORT. |
|
dvander@1203
|
924 |
** |
|
dvander@1203
|
925 |
** UNIQUE REPLACE The other row that conflicts with the row |
|
dvander@1203
|
926 |
** being inserted is removed. |
|
dvander@1203
|
927 |
** |
|
dvander@1203
|
928 |
** CHECK REPLACE Illegal. The results in an exception. |
|
dvander@1203
|
929 |
** |
|
dvander@1203
|
930 |
** Which action to take is determined by the overrideError parameter. |
|
dvander@1203
|
931 |
** Or if overrideError==OE_Default, then the pParse->onError parameter |
|
dvander@1203
|
932 |
** is used. Or if pParse->onError==OE_Default then the onError value |
|
dvander@1203
|
933 |
** for the constraint is used. |
|
dvander@1203
|
934 |
** |
|
dvander@1203
|
935 |
** The calling routine must open a read/write cursor for pTab with |
|
dvander@1203
|
936 |
** cursor number "base". All indices of pTab must also have open |
|
dvander@1203
|
937 |
** read/write cursors with cursor number base+i for the i-th cursor. |
|
dvander@1203
|
938 |
** Except, if there is no possibility of a REPLACE action then |
|
dvander@1203
|
939 |
** cursors do not need to be open for indices where aIdxUsed[i]==0. |
|
dvander@1203
|
940 |
** |
|
dvander@1203
|
941 |
** If the isUpdate flag is true, it means that the "base" cursor is |
|
dvander@1203
|
942 |
** initially pointing to an entry that is being updated. The isUpdate |
|
dvander@1203
|
943 |
** flag causes extra code to be generated so that the "base" cursor |
|
dvander@1203
|
944 |
** is still pointing at the same entry after the routine returns. |
|
dvander@1203
|
945 |
** Without the isUpdate flag, the "base" cursor might be moved. |
|
dvander@1203
|
946 |
*/ |
|
dvander@1203
|
947 |
void sqlite3GenerateConstraintChecks( |
|
dvander@1203
|
948 |
Parse *pParse, /* The parser context */ |
|
dvander@1203
|
949 |
Table *pTab, /* the table into which we are inserting */ |
|
dvander@1203
|
950 |
int base, /* Index of a read/write cursor pointing at pTab */ |
|
dvander@1203
|
951 |
char *aIdxUsed, /* Which indices are used. NULL means all are used */ |
|
dvander@1203
|
952 |
int rowidChng, /* True if the record number will change */ |
|
dvander@1203
|
953 |
int isUpdate, /* True for UPDATE, False for INSERT */ |
|
dvander@1203
|
954 |
int overrideError, /* Override onError to this if not OE_Default */ |
|
dvander@1203
|
955 |
int ignoreDest /* Jump to this label on an OE_Ignore resolution */ |
|
dvander@1203
|
956 |
){ |
|
dvander@1203
|
957 |
int i; |
|
dvander@1203
|
958 |
Vdbe *v; |
|
dvander@1203
|
959 |
int nCol; |
|
dvander@1203
|
960 |
int onError; |
|
dvander@1203
|
961 |
int addr; |
|
dvander@1203
|
962 |
int extra; |
|
dvander@1203
|
963 |
int iCur; |
|
dvander@1203
|
964 |
Index *pIdx; |
|
dvander@1203
|
965 |
int seenReplace = 0; |
|
dvander@1203
|
966 |
int jumpInst1=0, jumpInst2; |
|
dvander@1203
|
967 |
int hasTwoRowids = (isUpdate && rowidChng); |
|
dvander@1203
|
968 |
|
|
dvander@1203
|
969 |
v = sqlite3GetVdbe(pParse); |
|
dvander@1203
|
970 |
assert( v!=0 ); |
|
dvander@1203
|
971 |
assert( pTab->pSelect==0 ); /* This table is not a VIEW */ |
|
dvander@1203
|
972 |
nCol = pTab->nCol; |
|
dvander@1203
|
973 |
|
|
dvander@1203
|
974 |
/* Test all NOT NULL constraints. |
|
dvander@1203
|
975 |
*/ |
|
dvander@1203
|
976 |
for(i=0; i<nCol; i++){ |
|
dvander@1203
|
977 |
if( i==pTab->iPKey ){ |
|
dvander@1203
|
978 |
continue; |
|
dvander@1203
|
979 |
} |
|
dvander@1203
|
980 |
onError = pTab->aCol[i].notNull; |
|
dvander@1203
|
981 |
if( onError==OE_None ) continue; |
|
dvander@1203
|
982 |
if( overrideError!=OE_Default ){ |
|
dvander@1203
|
983 |
onError = overrideError; |
|
dvander@1203
|
984 |
}else if( onError==OE_Default ){ |
|
dvander@1203
|
985 |
onError = OE_Abort; |
|
dvander@1203
|
986 |
} |
|
dvander@1203
|
987 |
if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){ |
|
dvander@1203
|
988 |
onError = OE_Abort; |
|
dvander@1203
|
989 |
} |
|
dvander@1203
|
990 |
sqlite3VdbeAddOp(v, OP_Dup, nCol-1-i, 1); |
|
dvander@1203
|
991 |
addr = sqlite3VdbeAddOp(v, OP_NotNull, 1, 0); |
|
dvander@1203
|
992 |
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail |
|
dvander@1203
|
993 |
|| onError==OE_Ignore || onError==OE_Replace ); |
|
dvander@1203
|
994 |
switch( onError ){ |
|
dvander@1203
|
995 |
case OE_Rollback: |
|
dvander@1203
|
996 |
case OE_Abort: |
|
dvander@1203
|
997 |
case OE_Fail: { |
|
dvander@1203
|
998 |
char *zMsg = 0; |
|
dvander@1203
|
999 |
sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError); |
|
dvander@1203
|
1000 |
sqlite3SetString(&zMsg, pTab->zName, ".", pTab->aCol[i].zName, |
|
dvander@1203
|
1001 |
" may not be NULL", (char*)0); |
|
dvander@1203
|
1002 |
sqlite3VdbeChangeP3(v, -1, zMsg, P3_DYNAMIC); |
|
dvander@1203
|
1003 |
break; |
|
dvander@1203
|
1004 |
} |
|
dvander@1203
|
1005 |
case OE_Ignore: { |
|
dvander@1203
|
1006 |
sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0); |
|
dvander@1203
|
1007 |
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest); |
|
dvander@1203
|
1008 |
break; |
|
dvander@1203
|
1009 |
} |
|
dvander@1203
|
1010 |
case OE_Replace: { |
|
dvander@1203
|
1011 |
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); |
|
dvander@1203
|
1012 |
sqlite3VdbeAddOp(v, OP_Push, nCol-i, 0); |
|
dvander@1203
|
1013 |
break; |
|
dvander@1203
|
1014 |
} |
|
dvander@1203
|
1015 |
} |
|
dvander@1203
|
1016 |
sqlite3VdbeJumpHere(v, addr); |
|
dvander@1203
|
1017 |
} |
|
dvander@1203
|
1018 |
|
|
dvander@1203
|
1019 |
/* Test all CHECK constraints |
|
dvander@1203
|
1020 |
*/ |
|
dvander@1203
|
1021 |
#ifndef SQLITE_OMIT_CHECK |
|
dvander@1203
|
1022 |
if( pTab->pCheck && (pParse->db->flags & SQLITE_IgnoreChecks)==0 ){ |
|
dvander@1203
|
1023 |
int allOk = sqlite3VdbeMakeLabel(v); |
|
dvander@1203
|
1024 |
assert( pParse->ckOffset==0 ); |
|
dvander@1203
|
1025 |
pParse->ckOffset = nCol; |
|
dvander@1203
|
1026 |
sqlite3ExprIfTrue(pParse, pTab->pCheck, allOk, 1); |
|
dvander@1203
|
1027 |
assert( pParse->ckOffset==nCol ); |
|
dvander@1203
|
1028 |
pParse->ckOffset = 0; |
|
dvander@1203
|
1029 |
onError = overrideError!=OE_Default ? overrideError : OE_Abort; |
|
dvander@1203
|
1030 |
if( onError==OE_Ignore || onError==OE_Replace ){ |
|
dvander@1203
|
1031 |
sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0); |
|
dvander@1203
|
1032 |
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest); |
|
dvander@1203
|
1033 |
}else{ |
|
dvander@1203
|
1034 |
sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError); |
|
dvander@1203
|
1035 |
} |
|
dvander@1203
|
1036 |
sqlite3VdbeResolveLabel(v, allOk); |
|
dvander@1203
|
1037 |
} |
|
dvander@1203
|
1038 |
#endif /* !defined(SQLITE_OMIT_CHECK) */ |
|
dvander@1203
|
1039 |
|
|
dvander@1203
|
1040 |
/* If we have an INTEGER PRIMARY KEY, make sure the primary key |
|
dvander@1203
|
1041 |
** of the new record does not previously exist. Except, if this |
|
dvander@1203
|
1042 |
** is an UPDATE and the primary key is not changing, that is OK. |
|
dvander@1203
|
1043 |
*/ |
|
dvander@1203
|
1044 |
if( rowidChng ){ |
|
dvander@1203
|
1045 |
onError = pTab->keyConf; |
|
dvander@1203
|
1046 |
if( overrideError!=OE_Default ){ |
|
dvander@1203
|
1047 |
onError = overrideError; |
|
dvander@1203
|
1048 |
}else if( onError==OE_Default ){ |
|
dvander@1203
|
1049 |
onError = OE_Abort; |
|
dvander@1203
|
1050 |
} |
|
dvander@1203
|
1051 |
|
|
dvander@1203
|
1052 |
if( isUpdate ){ |
|
dvander@1203
|
1053 |
sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1); |
|
dvander@1203
|
1054 |
sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1); |
|
dvander@1203
|
1055 |
jumpInst1 = sqlite3VdbeAddOp(v, OP_Eq, 0, 0); |
|
dvander@1203
|
1056 |
} |
|
dvander@1203
|
1057 |
sqlite3VdbeAddOp(v, OP_Dup, nCol, 1); |
|
dvander@1203
|
1058 |
jumpInst2 = sqlite3VdbeAddOp(v, OP_NotExists, base, 0); |
|
dvander@1203
|
1059 |
switch( onError ){ |
|
dvander@1203
|
1060 |
default: { |
|
dvander@1203
|
1061 |
onError = OE_Abort; |
|
dvander@1203
|
1062 |
/* Fall thru into the next case */ |
|
dvander@1203
|
1063 |
} |
|
dvander@1203
|
1064 |
case OE_Rollback: |
|
dvander@1203
|
1065 |
case OE_Abort: |
|
dvander@1203
|
1066 |
case OE_Fail: { |
|
dvander@1203
|
1067 |
sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, |
|
dvander@1203
|
1068 |
"PRIMARY KEY must be unique", P3_STATIC); |
|
dvander@1203
|
1069 |
break; |
|
dvander@1203
|
1070 |
} |
|
dvander@1203
|
1071 |
case OE_Replace: { |
|
dvander@1203
|
1072 |
sqlite3GenerateRowIndexDelete(v, pTab, base, 0); |
|
dvander@1203
|
1073 |
if( isUpdate ){ |
|
dvander@1203
|
1074 |
sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRowids, 1); |
|
dvander@1203
|
1075 |
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); |
|
dvander@1203
|
1076 |
} |
|
dvander@1203
|
1077 |
seenReplace = 1; |
|
dvander@1203
|
1078 |
break; |
|
dvander@1203
|
1079 |
} |
|
dvander@1203
|
1080 |
case OE_Ignore: { |
|
dvander@1203
|
1081 |
assert( seenReplace==0 ); |
|
dvander@1203
|
1082 |
sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0); |
|
dvander@1203
|
1083 |
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest); |
|
dvander@1203
|
1084 |
break; |
|
dvander@1203
|
1085 |
} |
|
dvander@1203
|
1086 |
} |
|
dvander@1203
|
1087 |
sqlite3VdbeJumpHere(v, jumpInst2); |
|
dvander@1203
|
1088 |
if( isUpdate ){ |
|
dvander@1203
|
1089 |
sqlite3VdbeJumpHere(v, jumpInst1); |
|
dvander@1203
|
1090 |
sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1); |
|
dvander@1203
|
1091 |
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); |
|
dvander@1203
|
1092 |
} |
|
dvander@1203
|
1093 |
} |
|
dvander@1203
|
1094 |
|
|
dvander@1203
|
1095 |
/* Test all UNIQUE constraints by creating entries for each UNIQUE |
|
dvander@1203
|
1096 |
** index and making sure that duplicate entries do not already exist. |
|
dvander@1203
|
1097 |
** Add the new records to the indices as we go. |
|
dvander@1203
|
1098 |
*/ |
|
dvander@1203
|
1099 |
extra = -1; |
|
dvander@1203
|
1100 |
for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){ |
|
dvander@1203
|
1101 |
if( aIdxUsed && aIdxUsed[iCur]==0 ) continue; /* Skip unused indices */ |
|
dvander@1203
|
1102 |
extra++; |
|
dvander@1203
|
1103 |
|
|
dvander@1203
|
1104 |
/* Create a key for accessing the index entry */ |
|
dvander@1203
|
1105 |
sqlite3VdbeAddOp(v, OP_Dup, nCol+extra, 1); |
|
dvander@1203
|
1106 |
for(i=0; i<pIdx->nColumn; i++){ |
|
dvander@1203
|
1107 |
int idx = pIdx->aiColumn[i]; |
|
dvander@1203
|
1108 |
if( idx==pTab->iPKey ){ |
|
dvander@1203
|
1109 |
sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol+1, 1); |
|
dvander@1203
|
1110 |
}else{ |
|
dvander@1203
|
1111 |
sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol-idx, 1); |
|
dvander@1203
|
1112 |
} |
|
dvander@1203
|
1113 |
} |
|
dvander@1203
|
1114 |
jumpInst1 = sqlite3VdbeAddOp(v, OP_MakeIdxRec, pIdx->nColumn, 0); |
|
dvander@1203
|
1115 |
sqlite3IndexAffinityStr(v, pIdx); |
|
dvander@1203
|
1116 |
|
|
dvander@1203
|
1117 |
/* Find out what action to take in case there is an indexing conflict */ |
|
dvander@1203
|
1118 |
onError = pIdx->onError; |
|
dvander@1203
|
1119 |
if( onError==OE_None ) continue; /* pIdx is not a UNIQUE index */ |
|
dvander@1203
|
1120 |
if( overrideError!=OE_Default ){ |
|
dvander@1203
|
1121 |
onError = overrideError; |
|
dvander@1203
|
1122 |
}else if( onError==OE_Default ){ |
|
dvander@1203
|
1123 |
onError = OE_Abort; |
|
dvander@1203
|
1124 |
} |
|
dvander@1203
|
1125 |
if( seenReplace ){ |
|
dvander@1203
|
1126 |
if( onError==OE_Ignore ) onError = OE_Replace; |
|
dvander@1203
|
1127 |
else if( onError==OE_Fail ) onError = OE_Abort; |
|
dvander@1203
|
1128 |
} |
|
dvander@1203
|
1129 |
|
|
dvander@1203
|
1130 |
|
|
dvander@1203
|
1131 |
/* Check to see if the new index entry will be unique */ |
|
dvander@1203
|
1132 |
sqlite3VdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRowids, 1); |
|
dvander@1203
|
1133 |
jumpInst2 = sqlite3VdbeAddOp(v, OP_IsUnique, base+iCur+1, 0); |
|
dvander@1203
|
1134 |
|
|
dvander@1203
|
1135 |
/* Generate code that executes if the new index entry is not unique */ |
|
dvander@1203
|
1136 |
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail |
|
dvander@1203
|
1137 |
|| onError==OE_Ignore || onError==OE_Replace ); |
|
dvander@1203
|
1138 |
switch( onError ){ |
|
dvander@1203
|
1139 |
case OE_Rollback: |
|
dvander@1203
|
1140 |
case OE_Abort: |
|
dvander@1203
|
1141 |
case OE_Fail: { |
|
dvander@1203
|
1142 |
int j, n1, n2; |
|
dvander@1203
|
1143 |
char zErrMsg[200]; |
|
dvander@1203
|
1144 |
sqlite3_snprintf(sizeof(zErrMsg), zErrMsg, |
|
dvander@1203
|
1145 |
pIdx->nColumn>1 ? "columns " : "column "); |
|
dvander@1203
|
1146 |
n1 = strlen(zErrMsg); |
|
dvander@1203
|
1147 |
for(j=0; j<pIdx->nColumn && n1<sizeof(zErrMsg)-30; j++){ |
|
dvander@1203
|
1148 |
char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName; |
|
dvander@1203
|
1149 |
n2 = strlen(zCol); |
|
dvander@1203
|
1150 |
if( j>0 ){ |
|
dvander@1203
|
1151 |
sqlite3_snprintf(sizeof(zErrMsg)-n1, &zErrMsg[n1], ", "); |
|
dvander@1203
|
1152 |
n1 += 2; |
|
dvander@1203
|
1153 |
} |
|
dvander@1203
|
1154 |
if( n1+n2>sizeof(zErrMsg)-30 ){ |
|
dvander@1203
|
1155 |
sqlite3_snprintf(sizeof(zErrMsg)-n1, &zErrMsg[n1], "..."); |
|
dvander@1203
|
1156 |
n1 += 3; |
|
dvander@1203
|
1157 |
break; |
|
dvander@1203
|
1158 |
}else{ |
|
dvander@1203
|
1159 |
sqlite3_snprintf(sizeof(zErrMsg)-n1, &zErrMsg[n1], "%s", zCol); |
|
dvander@1203
|
1160 |
n1 += n2; |
|
dvander@1203
|
1161 |
} |
|
dvander@1203
|
1162 |
} |
|
dvander@1203
|
1163 |
sqlite3_snprintf(sizeof(zErrMsg)-n1, &zErrMsg[n1], |
|
dvander@1203
|
1164 |
pIdx->nColumn>1 ? " are not unique" : " is not unique"); |
|
dvander@1203
|
1165 |
sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, zErrMsg, 0); |
|
dvander@1203
|
1166 |
break; |
|
dvander@1203
|
1167 |
} |
|
dvander@1203
|
1168 |
case OE_Ignore: { |
|
dvander@1203
|
1169 |
assert( seenReplace==0 ); |
|
dvander@1203
|
1170 |
sqlite3VdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRowids, 0); |
|
dvander@1203
|
1171 |
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest); |
|
dvander@1203
|
1172 |
break; |
|
dvander@1203
|
1173 |
} |
|
dvander@1203
|
1174 |
case OE_Replace: { |
|
dvander@1203
|
1175 |
sqlite3GenerateRowDelete(pParse->db, v, pTab, base, 0); |
|
dvander@1203
|
1176 |
if( isUpdate ){ |
|
dvander@1203
|
1177 |
sqlite3VdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRowids, 1); |
|
dvander@1203
|
1178 |
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); |
|
dvander@1203
|
1179 |
} |
|
dvander@1203
|
1180 |
seenReplace = 1; |
|
dvander@1203
|
1181 |
break; |
|
dvander@1203
|
1182 |
} |
|
dvander@1203
|
1183 |
} |
|
dvander@1203
|
1184 |
#if NULL_DISTINCT_FOR_UNIQUE |
|
dvander@1203
|
1185 |
sqlite3VdbeJumpHere(v, jumpInst1); |
|
dvander@1203
|
1186 |
#endif |
|
dvander@1203
|
1187 |
sqlite3VdbeJumpHere(v, jumpInst2); |
|
dvander@1203
|
1188 |
} |
|
dvander@1203
|
1189 |
} |
|
dvander@1203
|
1190 |
|
|
dvander@1203
|
1191 |
/* |
|
dvander@1203
|
1192 |
** This routine generates code to finish the INSERT or UPDATE operation |
|
dvander@1203
|
1193 |
** that was started by a prior call to sqlite3GenerateConstraintChecks. |
|
dvander@1203
|
1194 |
** The stack must contain keys for all active indices followed by data |
|
dvander@1203
|
1195 |
** and the rowid for the new entry. This routine creates the new |
|
dvander@1203
|
1196 |
** entries in all indices and in the main table. |
|
dvander@1203
|
1197 |
** |
|
dvander@1203
|
1198 |
** The arguments to this routine should be the same as the first six |
|
dvander@1203
|
1199 |
** arguments to sqlite3GenerateConstraintChecks. |
|
dvander@1203
|
1200 |
*/ |
|
dvander@1203
|
1201 |
void sqlite3CompleteInsertion( |
|
dvander@1203
|
1202 |
Parse *pParse, /* The parser context */ |
|
dvander@1203
|
1203 |
Table *pTab, /* the table into which we are inserting */ |
|
dvander@1203
|
1204 |
int base, /* Index of a read/write cursor pointing at pTab */ |
|
dvander@1203
|
1205 |
char *aIdxUsed, /* Which indices are used. NULL means all are used */ |
|
dvander@1203
|
1206 |
int rowidChng, /* True if the record number will change */ |
|
dvander@1203
|
1207 |
int isUpdate, /* True for UPDATE, False for INSERT */ |
|
dvander@1203
|
1208 |
int newIdx, /* Index of NEW table for triggers. -1 if none */ |
|
dvander@1203
|
1209 |
int appendBias /* True if this is likely to be an append */ |
|
dvander@1203
|
1210 |
){ |
|
dvander@1203
|
1211 |
int i; |
|
dvander@1203
|
1212 |
Vdbe *v; |
|
dvander@1203
|
1213 |
int nIdx; |
|
dvander@1203
|
1214 |
Index *pIdx; |
|
dvander@1203
|
1215 |
int pik_flags; |
|
dvander@1203
|
1216 |
|
|
dvander@1203
|
1217 |
v = sqlite3GetVdbe(pParse); |
|
dvander@1203
|
1218 |
assert( v!=0 ); |
|
dvander@1203
|
1219 |
assert( pTab->pSelect==0 ); /* This table is not a VIEW */ |
|
dvander@1203
|
1220 |
for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){} |
|
dvander@1203
|
1221 |
for(i=nIdx-1; i>=0; i--){ |
|
dvander@1203
|
1222 |
if( aIdxUsed && aIdxUsed[i]==0 ) continue; |
|
dvander@1203
|
1223 |
sqlite3VdbeAddOp(v, OP_IdxInsert, base+i+1, 0); |
|
dvander@1203
|
1224 |
} |
|
dvander@1203
|
1225 |
sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0); |
|
dvander@1203
|
1226 |
sqlite3TableAffinityStr(v, pTab); |
|
dvander@1203
|
1227 |
#ifndef SQLITE_OMIT_TRIGGER |
|
dvander@1203
|
1228 |
if( newIdx>=0 ){ |
|
dvander@1203
|
1229 |
sqlite3VdbeAddOp(v, OP_Dup, 1, 0); |
|
dvander@1203
|
1230 |
sqlite3VdbeAddOp(v, OP_Dup, 1, 0); |
|
dvander@1203
|
1231 |
sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0); |
|
dvander@1203
|
1232 |
} |
|
dvander@1203
|
1233 |
#endif |
|
dvander@1203
|
1234 |
if( pParse->nested ){ |
|
dvander@1203
|
1235 |
pik_flags = 0; |
|
dvander@1203
|
1236 |
}else{ |
|
dvander@1203
|
1237 |
pik_flags = OPFLAG_NCHANGE; |
|
dvander@1203
|
1238 |
pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID); |
|
dvander@1203
|
1239 |
} |
|
dvander@1203
|
1240 |
if( appendBias ){ |
|
dvander@1203
|
1241 |
pik_flags |= OPFLAG_APPEND; |
|
dvander@1203
|
1242 |
} |
|
dvander@1203
|
1243 |
sqlite3VdbeAddOp(v, OP_Insert, base, pik_flags); |
|
dvander@1203
|
1244 |
if( !pParse->nested ){ |
|
dvander@1203
|
1245 |
sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC); |
|
dvander@1203
|
1246 |
} |
|
dvander@1203
|
1247 |
|
|
dvander@1203
|
1248 |
if( isUpdate && rowidChng ){ |
|
dvander@1203
|
1249 |
sqlite3VdbeAddOp(v, OP_Pop, 1, 0); |
|
dvander@1203
|
1250 |
} |
|
dvander@1203
|
1251 |
} |
|
dvander@1203
|
1252 |
|
|
dvander@1203
|
1253 |
/* |
|
dvander@1203
|
1254 |
** Generate code that will open cursors for a table and for all |
|
dvander@1203
|
1255 |
** indices of that table. The "base" parameter is the cursor number used |
|
dvander@1203
|
1256 |
** for the table. Indices are opened on subsequent cursors. |
|
dvander@1203
|
1257 |
*/ |
|
dvander@1203
|
1258 |
void sqlite3OpenTableAndIndices( |
|
dvander@1203
|
1259 |
Parse *pParse, /* Parsing context */ |
|
dvander@1203
|
1260 |
Table *pTab, /* Table to be opened */ |
|
dvander@1203
|
1261 |
int base, /* Cursor number assigned to the table */ |
|
dvander@1203
|
1262 |
int op /* OP_OpenRead or OP_OpenWrite */ |
|
dvander@1203
|
1263 |
){ |
|
dvander@1203
|
1264 |
int i; |
|
dvander@1203
|
1265 |
int iDb; |
|
dvander@1203
|
1266 |
Index *pIdx; |
|
dvander@1203
|
1267 |
Vdbe *v; |
|
dvander@1203
|
1268 |
|
|
dvander@1203
|
1269 |
if( IsVirtual(pTab) ) return; |
|
dvander@1203
|
1270 |
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); |
|
dvander@1203
|
1271 |
v = sqlite3GetVdbe(pParse); |
|
dvander@1203
|
1272 |
assert( v!=0 ); |
|
dvander@1203
|
1273 |
sqlite3OpenTable(pParse, base, iDb, pTab, op); |
|
dvander@1203
|
1274 |
for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ |
|
dvander@1203
|
1275 |
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); |
|
dvander@1203
|
1276 |
assert( pIdx->pSchema==pTab->pSchema ); |
|
dvander@1203
|
1277 |
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); |
|
dvander@1203
|
1278 |
VdbeComment((v, "# %s", pIdx->zName)); |
|
dvander@1203
|
1279 |
sqlite3VdbeOp3(v, op, i+base, pIdx->tnum, (char*)pKey, P3_KEYINFO_HANDOFF); |
|
dvander@1203
|
1280 |
} |
|
dvander@1203
|
1281 |
if( pParse->nTab<=base+i ){ |
|
dvander@1203
|
1282 |
pParse->nTab = base+i; |
|
dvander@1203
|
1283 |
} |
|
dvander@1203
|
1284 |
} |
|
dvander@1203
|
1285 |
|
|
dvander@1203
|
1286 |
|
|
dvander@1203
|
1287 |
#ifdef SQLITE_TEST |
|
dvander@1203
|
1288 |
/* |
|
dvander@1203
|
1289 |
** The following global variable is incremented whenever the |
|
dvander@1203
|
1290 |
** transfer optimization is used. This is used for testing |
|
dvander@1203
|
1291 |
** purposes only - to make sure the transfer optimization really |
|
dvander@1203
|
1292 |
** is happening when it is suppose to. |
|
dvander@1203
|
1293 |
*/ |
|
dvander@1203
|
1294 |
int sqlite3_xferopt_count; |
|
dvander@1203
|
1295 |
#endif /* SQLITE_TEST */ |
|
dvander@1203
|
1296 |
|
|
dvander@1203
|
1297 |
|
|
dvander@1203
|
1298 |
#ifndef SQLITE_OMIT_XFER_OPT |
|
dvander@1203
|
1299 |
/* |
|
dvander@1203
|
1300 |
** Check to collation names to see if they are compatible. |
|
dvander@1203
|
1301 |
*/ |
|
dvander@1203
|
1302 |
static int xferCompatibleCollation(const char *z1, const char *z2){ |
|
dvander@1203
|
1303 |
if( z1==0 ){ |
|
dvander@1203
|
1304 |
return z2==0; |
|
dvander@1203
|
1305 |
} |
|
dvander@1203
|
1306 |
if( z2==0 ){ |
|
dvander@1203
|
1307 |
return 0; |
|
dvander@1203
|
1308 |
} |
|
dvander@1203
|
1309 |
return sqlite3StrICmp(z1, z2)==0; |
|
dvander@1203
|
1310 |
} |
|
dvander@1203
|
1311 |
|
|
dvander@1203
|
1312 |
|
|
dvander@1203
|
1313 |
/* |
|
dvander@1203
|
1314 |
** Check to see if index pSrc is compatible as a source of data |
|
dvander@1203
|
1315 |
** for index pDest in an insert transfer optimization. The rules |
|
dvander@1203
|
1316 |
** for a compatible index: |
|
dvander@1203
|
1317 |
** |
|
dvander@1203
|
1318 |
** * The index is over the same set of columns |
|
dvander@1203
|
1319 |
** * The same DESC and ASC markings occurs on all columns |
|
dvander@1203
|
1320 |
** * The same onError processing (OE_Abort, OE_Ignore, etc) |
|
dvander@1203
|
1321 |
** * The same collating sequence on each column |
|
dvander@1203
|
1322 |
*/ |
|
dvander@1203
|
1323 |
static int xferCompatibleIndex(Index *pDest, Index *pSrc){ |
|
dvander@1203
|
1324 |
int i; |
|
dvander@1203
|
1325 |
assert( pDest && pSrc ); |
|
dvander@1203
|
1326 |
assert( pDest->pTable!=pSrc->pTable ); |
|
dvander@1203
|
1327 |
if( pDest->nColumn!=pSrc->nColumn ){ |
|
dvander@1203
|
1328 |
return 0; /* Different number of columns */ |
|
dvander@1203
|
1329 |
} |
|
dvander@1203
|
1330 |
if( pDest->onError!=pSrc->onError ){ |
|
dvander@1203
|
1331 |
return 0; /* Different conflict resolution strategies */ |
|
dvander@1203
|
1332 |
} |
|
dvander@1203
|
1333 |
for(i=0; i<pSrc->nColumn; i++){ |
|
dvander@1203
|
1334 |
if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){ |
|
dvander@1203
|
1335 |
return 0; /* Different columns indexed */ |
|
dvander@1203
|
1336 |
} |
|
dvander@1203
|
1337 |
if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){ |
|
dvander@1203
|
1338 |
return 0; /* Different sort orders */ |
|
dvander@1203
|
1339 |
} |
|
dvander@1203
|
1340 |
if( pSrc->azColl[i]!=pDest->azColl[i] ){ |
|
dvander@1203
|
1341 |
return 0; /* Different sort orders */ |
|
dvander@1203
|
1342 |
} |
|
dvander@1203
|
1343 |
} |
|
dvander@1203
|
1344 |
|
|
dvander@1203
|
1345 |
/* If no test above fails then the indices must be compatible */ |
|
dvander@1203
|
1346 |
return 1; |
|
dvander@1203
|
1347 |
} |
|
dvander@1203
|
1348 |
|
|
dvander@1203
|
1349 |
/* |
|
dvander@1203
|
1350 |
** Attempt the transfer optimization on INSERTs of the form |
|
dvander@1203
|
1351 |
** |
|
dvander@1203
|
1352 |
** INSERT INTO tab1 SELECT * FROM tab2; |
|
dvander@1203
|
1353 |
** |
|
dvander@1203
|
1354 |
** This optimization is only attempted if |
|
dvander@1203
|
1355 |
** |
|
dvander@1203
|
1356 |
** (1) tab1 and tab2 have identical schemas including all the |
|
dvander@1203
|
1357 |
** same indices and constraints |
|
dvander@1203
|
1358 |
** |
|
dvander@1203
|
1359 |
** (2) tab1 and tab2 are different tables |
|
dvander@1203
|
1360 |
** |
|
dvander@1203
|
1361 |
** (3) There must be no triggers on tab1 |
|
dvander@1203
|
1362 |
** |
|
dvander@1203
|
1363 |
** (4) The result set of the SELECT statement is "*" |
|
dvander@1203
|
1364 |
** |
|
dvander@1203
|
1365 |
** (5) The SELECT statement has no WHERE, HAVING, ORDER BY, GROUP BY, |
|
dvander@1203
|
1366 |
** or LIMIT clause. |
|
dvander@1203
|
1367 |
** |
|
dvander@1203
|
1368 |
** (6) The SELECT statement is a simple (not a compound) select that |
|
dvander@1203
|
1369 |
** contains only tab2 in its FROM clause |
|
dvander@1203
|
1370 |
** |
|
dvander@1203
|
1371 |
** This method for implementing the INSERT transfers raw records from |
|
dvander@1203
|
1372 |
** tab2 over to tab1. The columns are not decoded. Raw records from |
|
dvander@1203
|
1373 |
** the indices of tab2 are transfered to tab1 as well. In so doing, |
|
dvander@1203
|
1374 |
** the resulting tab1 has much less fragmentation. |
|
dvander@1203
|
1375 |
** |
|
dvander@1203
|
1376 |
** This routine returns TRUE if the optimization is attempted. If any |
|
dvander@1203
|
1377 |
** of the conditions above fail so that the optimization should not |
|
dvander@1203
|
1378 |
** be attempted, then this routine returns FALSE. |
|
dvander@1203
|
1379 |
*/ |
|
dvander@1203
|
1380 |
static int xferOptimization( |
|
dvander@1203
|
1381 |
Parse *pParse, /* Parser context */ |
|
dvander@1203
|
1382 |
Table *pDest, /* The table we are inserting into */ |
|
dvander@1203
|
1383 |
Select *pSelect, /* A SELECT statement to use as the data source */ |
|
dvander@1203
|
1384 |
int onError, /* How to handle constraint errors */ |
|
dvander@1203
|
1385 |
int iDbDest /* The database of pDest */ |
|
dvander@1203
|
1386 |
){ |
|
dvander@1203
|
1387 |
ExprList *pEList; /* The result set of the SELECT */ |
|
dvander@1203
|
1388 |
Table *pSrc; /* The table in the FROM clause of SELECT */ |
|
dvander@1203
|
1389 |
Index *pSrcIdx, *pDestIdx; /* Source and destination indices */ |
|
dvander@1203
|
1390 |
struct SrcList_item *pItem; /* An element of pSelect->pSrc */ |
|
dvander@1203
|
1391 |
int i; /* Loop counter */ |
|
dvander@1203
|
1392 |
int iDbSrc; /* The database of pSrc */ |
|
dvander@1203
|
1393 |
int iSrc, iDest; /* Cursors from source and destination */ |
|
dvander@1203
|
1394 |
int addr1, addr2; /* Loop addresses */ |
|
dvander@1203
|
1395 |
int emptyDestTest; /* Address of test for empty pDest */ |
|
dvander@1203
|
1396 |
int emptySrcTest; /* Address of test for empty pSrc */ |
|
dvander@1203
|
1397 |
Vdbe *v; /* The VDBE we are building */ |
|
dvander@1203
|
1398 |
KeyInfo *pKey; /* Key information for an index */ |
|
dvander@1203
|
1399 |
int counterMem; /* Memory register used by AUTOINC */ |
|
dvander@1203
|
1400 |
int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */ |
|
dvander@1203
|
1401 |
|
|
dvander@1203
|
1402 |
if( pSelect==0 ){ |
|
dvander@1203
|
1403 |
return 0; /* Must be of the form INSERT INTO ... SELECT ... */ |
|
dvander@1203
|
1404 |
} |
|
dvander@1203
|
1405 |
if( pDest->pTrigger ){ |
|
dvander@1203
|
1406 |
return 0; /* tab1 must not have triggers */ |
|
dvander@1203
|
1407 |
} |
|
dvander@1203
|
1408 |
#ifndef SQLITE_OMIT_VIRTUALTABLE |
|
dvander@1203
|
1409 |
if( pDest->isVirtual ){ |
|
dvander@1203
|
1410 |
return 0; /* tab1 must not be a virtual table */ |
|
dvander@1203
|
1411 |
} |
|
dvander@1203
|
1412 |
#endif |
|
dvander@1203
|
1413 |
if( onError==OE_Default ){ |
|
dvander@1203
|
1414 |
onError = OE_Abort; |
|
dvander@1203
|
1415 |
} |
|
dvander@1203
|
1416 |
if( onError!=OE_Abort && onError!=OE_Rollback ){ |
|
dvander@1203
|
1417 |
return 0; /* Cannot do OR REPLACE or OR IGNORE or OR FAIL */ |
|
dvander@1203
|
1418 |
} |
|
dvander@1203
|
1419 |
if( pSelect->pSrc==0 ){ |
|
dvander@1203
|
1420 |
return 0; /* SELECT must have a FROM clause */ |
|
dvander@1203
|
1421 |
} |
|
dvander@1203
|
1422 |
if( pSelect->pSrc->nSrc!=1 ){ |
|
dvander@1203
|
1423 |
return 0; /* FROM clause must have exactly one term */ |
|
dvander@1203
|
1424 |
} |
|
dvander@1203
|
1425 |
if( pSelect->pSrc->a[0].pSelect ){ |
|
dvander@1203
|
1426 |
return 0; /* FROM clause cannot contain a subquery */ |
|
dvander@1203
|
1427 |
} |
|
dvander@1203
|
1428 |
if( pSelect->pWhere ){ |
|
dvander@1203
|
1429 |
return 0; /* SELECT may not have a WHERE clause */ |
|
dvander@1203
|
1430 |
} |
|
dvander@1203
|
1431 |
if( pSelect->pOrderBy ){ |
|
dvander@1203
|
1432 |
return 0; /* SELECT may not have an ORDER BY clause */ |
|
dvander@1203
|
1433 |
} |
|
dvander@1203
|
1434 |
/* Do not need to test for a HAVING clause. If HAVING is present but |
|
dvander@1203
|
1435 |
** there is no ORDER BY, we will get an error. */ |
|
dvander@1203
|
1436 |
if( pSelect->pGroupBy ){ |
|
dvander@1203
|
1437 |
return 0; /* SELECT may not have a GROUP BY clause */ |
|
dvander@1203
|
1438 |
} |
|
dvander@1203
|
1439 |
if( pSelect->pLimit ){ |
|
dvander@1203
|
1440 |
return 0; /* SELECT may not have a LIMIT clause */ |
|
dvander@1203
|
1441 |
} |
|
dvander@1203
|
1442 |
assert( pSelect->pOffset==0 ); /* Must be so if pLimit==0 */ |
|
dvander@1203
|
1443 |
if( pSelect->pPrior ){ |
|
dvander@1203
|
1444 |
return 0; /* SELECT may not be a compound query */ |
|
dvander@1203
|
1445 |
} |
|
dvander@1203
|
1446 |
if( pSelect->isDistinct ){ |
|
dvander@1203
|
1447 |
return 0; /* SELECT may not be DISTINCT */ |
|
dvander@1203
|
1448 |
} |
|
dvander@1203
|
1449 |
pEList = pSelect->pEList; |
|
dvander@1203
|
1450 |
assert( pEList!=0 ); |
|
dvander@1203
|
1451 |
if( pEList->nExpr!=1 ){ |
|
dvander@1203
|
1452 |
return 0; /* The result set must have exactly one column */ |
|
dvander@1203
|
1453 |
} |
|
dvander@1203
|
1454 |
assert( pEList->a[0].pExpr ); |
|
dvander@1203
|
1455 |
if( pEList->a[0].pExpr->op!=TK_ALL ){ |
|
dvander@1203
|
1456 |
return 0; /* The result set must be the special operator "*" */ |
|
dvander@1203
|
1457 |
} |
|
dvander@1203
|
1458 |
|
|
dvander@1203
|
1459 |
/* At this point we have established that the statement is of the |
|
dvander@1203
|
1460 |
** correct syntactic form to participate in this optimization. Now |
|
dvander@1203
|
1461 |
** we have to check the semantics. |
|
dvander@1203
|
1462 |
*/ |
|
dvander@1203
|
1463 |
pItem = pSelect->pSrc->a; |
|
dvander@1203
|
1464 |
pSrc = sqlite3LocateTable(pParse, pItem->zName, pItem->zDatabase); |
|
dvander@1203
|
1465 |
if( pSrc==0 ){ |
|
dvander@1203
|
1466 |
return 0; /* FROM clause does not contain a real table */ |
|
dvander@1203
|
1467 |
} |
|
dvander@1203
|
1468 |
if( pSrc==pDest ){ |
|
dvander@1203
|
1469 |
return 0; /* tab1 and tab2 may not be the same table */ |
|
dvander@1203
|
1470 |
} |
|
dvander@1203
|
1471 |
#ifndef SQLITE_OMIT_VIRTUALTABLE |
|
dvander@1203
|
1472 |
if( pSrc->isVirtual ){ |
|
dvander@1203
|
1473 |
return 0; /* tab2 must not be a virtual table */ |
|
dvander@1203
|
1474 |
} |
|
dvander@1203
|
1475 |
#endif |
|
dvander@1203
|
1476 |
if( pSrc->pSelect ){ |
|
dvander@1203
|
1477 |
return 0; /* tab2 may not be a view */ |
|
dvander@1203
|
1478 |
} |
|
dvander@1203
|
1479 |
if( pDest->nCol!=pSrc->nCol ){ |
|
dvander@1203
|
1480 |
return 0; /* Number of columns must be the same in tab1 and tab2 */ |
|
dvander@1203
|
1481 |
} |
|
dvander@1203
|
1482 |
if( pDest->iPKey!=pSrc->iPKey ){ |
|
dvander@1203
|
1483 |
return 0; /* Both tables must have the same INTEGER PRIMARY KEY */ |
|
dvander@1203
|
1484 |
} |
|
dvander@1203
|
1485 |
for(i=0; i<pDest->nCol; i++){ |
|
dvander@1203
|
1486 |
if( pDest->aCol[i].affinity!=pSrc->aCol[i].affinity ){ |
|
dvander@1203
|
1487 |
return 0; /* Affinity must be the same on all columns */ |
|
dvander@1203
|
1488 |
} |
|
dvander@1203
|
1489 |
if( !xferCompatibleCollation(pDest->aCol[i].zColl, pSrc->aCol[i].zColl) ){ |
|
dvander@1203
|
1490 |
return 0; /* Collating sequence must be the same on all columns */ |
|
dvander@1203
|
1491 |
} |
|
dvander@1203
|
1492 |
if( pDest->aCol[i].notNull && !pSrc->aCol[i].notNull ){ |
|
dvander@1203
|
1493 |
return 0; /* tab2 must be NOT NULL if tab1 is */ |
|
dvander@1203
|
1494 |
} |
|
dvander@1203
|
1495 |
} |
|
dvander@1203
|
1496 |
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ |
|
dvander@1203
|
1497 |
if( pDestIdx->onError!=OE_None ){ |
|
dvander@1203
|
1498 |
destHasUniqueIdx = 1; |
|
dvander@1203
|
1499 |
} |
|
dvander@1203
|
1500 |
for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){ |
|
dvander@1203
|
1501 |
if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; |
|
dvander@1203
|
1502 |
} |
|
dvander@1203
|
1503 |
if( pSrcIdx==0 ){ |
|
dvander@1203
|
1504 |
return 0; /* pDestIdx has no corresponding index in pSrc */ |
|
dvander@1203
|
1505 |
} |
|
dvander@1203
|
1506 |
} |
|
dvander@1203
|
1507 |
#ifndef SQLITE_OMIT_CHECK |
|
dvander@1203
|
1508 |
if( pDest->pCheck && !sqlite3ExprCompare(pSrc->pCheck, pDest->pCheck) ){ |
|
dvander@1203
|
1509 |
return 0; /* Tables have different CHECK constraints. Ticket #2252 */ |
|
dvander@1203
|
1510 |
} |
|
dvander@1203
|
1511 |
#endif |
|
dvander@1203
|
1512 |
|
|
dvander@1203
|
1513 |
/* If we get this far, it means either: |
|
dvander@1203
|
1514 |
** |
|
dvander@1203
|
1515 |
** * We can always do the transfer if the table contains an |
|
dvander@1203
|
1516 |
** an integer primary key |
|
dvander@1203
|
1517 |
** |
|
dvander@1203
|
1518 |
** * We can conditionally do the transfer if the destination |
|
dvander@1203
|
1519 |
** table is empty. |
|
dvander@1203
|
1520 |
*/ |
|
dvander@1203
|
1521 |
#ifdef SQLITE_TEST |
|
dvander@1203
|
1522 |
sqlite3_xferopt_count++; |
|
dvander@1203
|
1523 |
#endif |
|
dvander@1203
|
1524 |
iDbSrc = sqlite3SchemaToIndex(pParse->db, pSrc->pSchema); |
|
dvander@1203
|
1525 |
v = sqlite3GetVdbe(pParse); |
|
dvander@1203
|
1526 |
iSrc = pParse->nTab++; |
|
dvander@1203
|
1527 |
iDest = pParse->nTab++; |
|
dvander@1203
|
1528 |
counterMem = autoIncBegin(pParse, iDbDest, pDest); |
|
dvander@1203
|
1529 |
sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); |
|
dvander@1203
|
1530 |
if( (pDest->iPKey<0 && pDest->pIndex!=0) || destHasUniqueIdx ){ |
|
dvander@1203
|
1531 |
/* If tables do not have an INTEGER PRIMARY KEY and there |
|
dvander@1203
|
1532 |
** are indices to be copied and the destination is not empty, |
|
dvander@1203
|
1533 |
** we have to disallow the transfer optimization because the |
|
dvander@1203
|
1534 |
** the rowids might change which will mess up indexing. |
|
dvander@1203
|
1535 |
** |
|
dvander@1203
|
1536 |
** Or if the destination has a UNIQUE index and is not empty, |
|
dvander@1203
|
1537 |
** we also disallow the transfer optimization because we cannot |
|
dvander@1203
|
1538 |
** insure that all entries in the union of DEST and SRC will be |
|
dvander@1203
|
1539 |
** unique. |
|
dvander@1203
|
1540 |
*/ |
|
dvander@1203
|
1541 |
addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iDest, 0); |
|
dvander@1203
|
1542 |
emptyDestTest = sqlite3VdbeAddOp(v, OP_Goto, 0, 0); |
|
dvander@1203
|
1543 |
sqlite3VdbeJumpHere(v, addr1); |
|
dvander@1203
|
1544 |
}else{ |
|
dvander@1203
|
1545 |
emptyDestTest = 0; |
|
dvander@1203
|
1546 |
} |
|
dvander@1203
|
1547 |
sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead); |
|
dvander@1203
|
1548 |
emptySrcTest = sqlite3VdbeAddOp(v, OP_Rewind, iSrc, 0); |
|
dvander@1203
|
1549 |
if( pDest->iPKey>=0 ){ |
|
dvander@1203
|
1550 |
addr1 = sqlite3VdbeAddOp(v, OP_Rowid, iSrc, 0); |
|
dvander@1203
|
1551 |
sqlite3VdbeAddOp(v, OP_Dup, 0, 0); |
|
dvander@1203
|
1552 |
addr2 = sqlite3VdbeAddOp(v, OP_NotExists, iDest, 0); |
|
dvander@1203
|
1553 |
sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, |
|
dvander@1203
|
1554 |
"PRIMARY KEY must be unique", P3_STATIC); |
|
dvander@1203
|
1555 |
sqlite3VdbeJumpHere(v, addr2); |
|
dvander@1203
|
1556 |
autoIncStep(pParse, counterMem); |
|
dvander@1203
|
1557 |
}else if( pDest->pIndex==0 ){ |
|
dvander@1203
|
1558 |
addr1 = sqlite3VdbeAddOp(v, OP_NewRowid, iDest, 0); |
|
dvander@1203
|
1559 |
}else{ |
|
dvander@1203
|
1560 |
addr1 = sqlite3VdbeAddOp(v, OP_Rowid, iSrc, 0); |
|
dvander@1203
|
1561 |
assert( pDest->autoInc==0 ); |
|
dvander@1203
|
1562 |
} |
|
dvander@1203
|
1563 |
sqlite3VdbeAddOp(v, OP_RowData, iSrc, 0); |
|
dvander@1203
|
1564 |
sqlite3VdbeOp3(v, OP_Insert, iDest, |
|
dvander@1203
|
1565 |
OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND, |
|
dvander@1203
|
1566 |
pDest->zName, 0); |
|
dvander@1203
|
1567 |
sqlite3VdbeAddOp(v, OP_Next, iSrc, addr1); |
|
dvander@1203
|
1568 |
autoIncEnd(pParse, iDbDest, pDest, counterMem); |
|
dvander@1203
|
1569 |
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ |
|
dvander@1203
|
1570 |
for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){ |
|
dvander@1203
|
1571 |
if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; |
|
dvander@1203
|
1572 |
} |
|
dvander@1203
|
1573 |
assert( pSrcIdx ); |
|
dvander@1203
|
1574 |
sqlite3VdbeAddOp(v, OP_Close, iSrc, 0); |
|
dvander@1203
|
1575 |
sqlite3VdbeAddOp(v, OP_Close, iDest, 0); |
|
dvander@1203
|
1576 |
sqlite3VdbeAddOp(v, OP_Integer, iDbSrc, 0); |
|
dvander@1203
|
1577 |
pKey = sqlite3IndexKeyinfo(pParse, pSrcIdx); |
|
dvander@1203
|
1578 |
VdbeComment((v, "# %s", pSrcIdx->zName)); |
|
dvander@1203
|
1579 |
sqlite3VdbeOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, |
|
dvander@1203
|
1580 |
(char*)pKey, P3_KEYINFO_HANDOFF); |
|
dvander@1203
|
1581 |
sqlite3VdbeAddOp(v, OP_Integer, iDbDest, 0); |
|
dvander@1203
|
1582 |
pKey = sqlite3IndexKeyinfo(pParse, pDestIdx); |
|
dvander@1203
|
1583 |
VdbeComment((v, "# %s", pDestIdx->zName)); |
|
dvander@1203
|
1584 |
sqlite3VdbeOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, |
|
dvander@1203
|
1585 |
(char*)pKey, P3_KEYINFO_HANDOFF); |
|
dvander@1203
|
1586 |
addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iSrc, 0); |
|
dvander@1203
|
1587 |
sqlite3VdbeAddOp(v, OP_RowKey, iSrc, 0); |
|
dvander@1203
|
1588 |
sqlite3VdbeAddOp(v, OP_IdxInsert, iDest, 1); |
|
dvander@1203
|
1589 |
sqlite3VdbeAddOp(v, OP_Next, iSrc, addr1+1); |
|
dvander@1203
|
1590 |
sqlite3VdbeJumpHere(v, addr1); |
|
dvander@1203
|
1591 |
} |
|
dvander@1203
|
1592 |
sqlite3VdbeJumpHere(v, emptySrcTest); |
|
dvander@1203
|
1593 |
sqlite3VdbeAddOp(v, OP_Close, iSrc, 0); |
|
dvander@1203
|
1594 |
sqlite3VdbeAddOp(v, OP_Close, iDest, 0); |
|
dvander@1203
|
1595 |
if( emptyDestTest ){ |
|
dvander@1203
|
1596 |
sqlite3VdbeAddOp(v, OP_Halt, SQLITE_OK, 0); |
|
dvander@1203
|
1597 |
sqlite3VdbeJumpHere(v, emptyDestTest); |
|
dvander@1203
|
1598 |
sqlite3VdbeAddOp(v, OP_Close, iDest, 0); |
|
dvander@1203
|
1599 |
return 0; |
|
dvander@1203
|
1600 |
}else{ |
|
dvander@1203
|
1601 |
return 1; |
|
dvander@1203
|
1602 |
} |
|
dvander@1203
|
1603 |
} |
|
dvander@1203
|
1604 |
#endif /* SQLITE_OMIT_XFER_OPT */ |