wasCSharpSQLite – Blame information for rev
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | using System.Diagnostics; |
2 | using System.IO; |
||
3 | using System.Text; |
||
4 | |||
5 | using FILE = System.IO.TextWriter; |
||
6 | |||
7 | using i32 = System.Int32; |
||
8 | using i64 = System.Int64; |
||
9 | using sqlite_int64 = System.Int64; |
||
10 | |||
11 | using u8 = System.Byte; |
||
12 | using u16 = System.UInt16; |
||
13 | using u32 = System.UInt32; |
||
14 | using u64 = System.UInt64; |
||
15 | |||
16 | using sqlite3_int64 = System.Int64; |
||
17 | |||
18 | using Pgno = System.UInt32; |
||
19 | /* |
||
20 | ** The yDbMask datatype for the bitmask of all attached databases. |
||
21 | */ |
||
22 | #if SQLITE_MAX_ATTACHED//>30 |
||
23 | // typedef sqlite3_uint64 yDbMask; |
||
24 | using yDbMask = System.Int64; |
||
25 | #else |
||
26 | // typedef unsigned int yDbMask; |
||
27 | using yDbMask = System.Int32; |
||
28 | #endif |
||
29 | |||
30 | namespace Community.CsharpSqlite |
||
31 | { |
||
32 | using sqlite3_value = Sqlite3.Mem; |
||
33 | using Op = Sqlite3.VdbeOp; |
||
34 | using System; |
||
35 | |||
36 | public partial class Sqlite3 |
||
37 | { |
||
38 | /* |
||
39 | ** 2001 September 15 |
||
40 | ** |
||
41 | ** The author disclaims copyright to this source code. In place of |
||
42 | ** a legal notice, here is a blessing: |
||
43 | ** |
||
44 | ** May you do good and not evil. |
||
45 | ** May you find forgiveness for yourself and forgive others. |
||
46 | ** May you share freely, never taking more than you give. |
||
47 | ** |
||
48 | ************************************************************************* |
||
49 | ** The code in this file implements execution method of the |
||
50 | ** Virtual Database Engine (VDBE). A separate file ("vdbeaux.c") |
||
51 | ** handles housekeeping details such as creating and deleting |
||
52 | ** VDBE instances. This file is solely interested in executing |
||
53 | ** the VDBE program. |
||
54 | ** |
||
55 | ** In the external interface, an "sqlite3_stmt*" is an opaque pointer |
||
56 | ** to a VDBE. |
||
57 | ** |
||
58 | ** The SQL parser generates a program which is then executed by |
||
59 | ** the VDBE to do the work of the SQL statement. VDBE programs are |
||
60 | ** similar in form to assembly language. The program consists of |
||
61 | ** a linear sequence of operations. Each operation has an opcode |
||
62 | ** and 5 operands. Operands P1, P2, and P3 are integers. Operand P4 |
||
63 | ** is a null-terminated string. Operand P5 is an unsigned character. |
||
64 | ** Few opcodes use all 5 operands. |
||
65 | ** |
||
66 | ** Computation results are stored on a set of registers numbered beginning |
||
67 | ** with 1 and going up to Vdbe.nMem. Each register can store |
||
68 | ** either an integer, a null-terminated string, a floating point |
||
69 | ** number, or the SQL "NULL" value. An implicit conversion from one |
||
70 | ** type to the other occurs as necessary. |
||
71 | ** |
||
72 | ** Most of the code in this file is taken up by the sqlite3VdbeExec() |
||
73 | ** function which does the work of interpreting a VDBE program. |
||
74 | ** But other routines are also provided to help in building up |
||
75 | ** a program instruction by instruction. |
||
76 | ** |
||
77 | ** Various scripts scan this source file in order to generate HTML |
||
78 | ** documentation, headers files, or other derived files. The formatting |
||
79 | ** of the code in this file is, therefore, important. See other comments |
||
80 | ** in this file for details. If in doubt, do not deviate from existing |
||
81 | ** commenting and indentation practices when changing or adding code. |
||
82 | ************************************************************************* |
||
83 | ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart |
||
84 | ** C#-SQLite is an independent reimplementation of the SQLite software library |
||
85 | ** |
||
86 | ** SQLITE_SOURCE_ID: 2011-06-23 19:49:22 4374b7e83ea0a3fbc3691f9c0c936272862f32f2 |
||
87 | ** |
||
88 | ************************************************************************* |
||
89 | */ |
||
90 | //#include "sqliteInt.h" |
||
91 | //#include "vdbeInt.h" |
||
92 | |||
93 | /* |
||
94 | ** Invoke this macro on memory cells just prior to changing the |
||
95 | ** value of the cell. This macro verifies that shallow copies are |
||
96 | ** not misused. |
||
97 | */ |
||
98 | #if SQLITE_DEBUG |
||
99 | //# define memAboutToChange(P,M) sqlite3VdbeMemPrepareToChange(P,M) |
||
100 | static void memAboutToChange( Vdbe P, Mem M ) |
||
101 | { |
||
102 | sqlite3VdbeMemPrepareToChange( P, M ); |
||
103 | } |
||
104 | #else |
||
105 | //# define memAboutToChange(P,M) |
||
106 | static void memAboutToChange(Vdbe P, Mem M) {} |
||
107 | #endif |
||
108 | |||
109 | /* |
||
110 | ** The following global variable is incremented every time a cursor |
||
111 | ** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes. The test |
||
112 | ** procedures use this information to make sure that indices are |
||
113 | ** working correctly. This variable has no function other than to |
||
114 | ** help verify the correct operation of the library. |
||
115 | */ |
||
116 | #if SQLITE_TEST |
||
117 | #if !TCLSH |
||
118 | static int sqlite3_search_count = 0; |
||
119 | #else |
||
120 | static tcl.lang.Var.SQLITE3_GETSET sqlite3_search_count = new tcl.lang.Var.SQLITE3_GETSET( "sqlite3_search_count" ); |
||
121 | #endif |
||
122 | #endif |
||
123 | |||
124 | /* |
||
125 | ** When this global variable is positive, it gets decremented once before |
||
126 | ** each instruction in the VDBE. When reaches zero, the u1.isInterrupted |
||
127 | ** field of the sqlite3 structure is set in order to simulate and interrupt. |
||
128 | ** |
||
129 | ** This facility is used for testing purposes only. It does not function |
||
130 | ** in an ordinary build. |
||
131 | */ |
||
132 | #if SQLITE_TEST |
||
133 | #if !TCLSH |
||
134 | static int sqlite3_interrupt_count = 0; |
||
135 | #else |
||
136 | static tcl.lang.Var.SQLITE3_GETSET sqlite3_interrupt_count = new tcl.lang.Var.SQLITE3_GETSET( "sqlite3_interrupt_count" ); |
||
137 | #endif |
||
138 | #endif |
||
139 | |||
140 | /* |
||
141 | ** The next global variable is incremented each type the OP_Sort opcode |
||
142 | ** is executed. The test procedures use this information to make sure that |
||
143 | ** sorting is occurring or not occurring at appropriate times. This variable |
||
144 | ** has no function other than to help verify the correct operation of the |
||
145 | ** library. |
||
146 | */ |
||
147 | #if SQLITE_TEST |
||
148 | #if !TCLSH |
||
149 | static int sqlite3_sort_count = 0; |
||
150 | #else |
||
151 | static tcl.lang.Var.SQLITE3_GETSET sqlite3_sort_count = new tcl.lang.Var.SQLITE3_GETSET( "sqlite3_sort_count" ); |
||
152 | #endif |
||
153 | #endif |
||
154 | |||
155 | /* |
||
156 | ** The next global variable records the size of the largest MEM_Blob |
||
157 | ** or MEM_Str that has been used by a VDBE opcode. The test procedures |
||
158 | ** use this information to make sure that the zero-blob functionality |
||
159 | ** is working correctly. This variable has no function other than to |
||
160 | ** help verify the correct operation of the library. |
||
161 | */ |
||
162 | #if SQLITE_TEST |
||
163 | #if !TCLSH |
||
164 | static int sqlite3_max_blobsize = 0; |
||
165 | #else |
||
166 | static tcl.lang.Var.SQLITE3_GETSET sqlite3_max_blobsize = new tcl.lang.Var.SQLITE3_GETSET( "sqlite3_max_blobsize" ); |
||
167 | #endif |
||
168 | |||
169 | static void updateMaxBlobsize( Mem p ) |
||
170 | { |
||
171 | #if !TCLSH |
||
172 | if ( ( p.flags & ( MEM_Str | MEM_Blob ) ) != 0 && p.n > sqlite3_max_blobsize ) |
||
173 | { |
||
174 | sqlite3_max_blobsize = p.n; |
||
175 | } |
||
176 | #else |
||
177 | if ( ( p.flags & ( MEM_Str | MEM_Blob ) ) != 0 && p.n > sqlite3_max_blobsize.iValue ) |
||
178 | { |
||
179 | sqlite3_max_blobsize.iValue = p.n; |
||
180 | } |
||
181 | #endif |
||
182 | } |
||
183 | #endif |
||
184 | |||
185 | /* |
||
186 | ** The next global variable is incremented each type the OP_Found opcode |
||
187 | ** is executed. This is used to test whether or not the foreign key |
||
188 | ** operation implemented using OP_FkIsZero is working. This variable |
||
189 | ** has no function other than to help verify the correct operation of the |
||
190 | ** library. |
||
191 | */ |
||
192 | #if SQLITE_TEST |
||
193 | #if !TCLSH |
||
194 | static int sqlite3_found_count = 0; |
||
195 | #else |
||
196 | static tcl.lang.Var.SQLITE3_GETSET sqlite3_found_count = new tcl.lang.Var.SQLITE3_GETSET( "sqlite3_found_count" ); |
||
197 | #endif |
||
198 | #endif |
||
199 | |||
200 | /* |
||
201 | /* |
||
202 | ** Test a register to see if it exceeds the current maximum blob size. |
||
203 | ** If it does, record the new maximum blob size. |
||
204 | */ |
||
205 | #if SQLITE_TEST && !SQLITE_OMIT_BUILTIN_TEST |
||
206 | static void UPDATE_MAX_BLOBSIZE( Mem P ) |
||
207 | { |
||
208 | updateMaxBlobsize( P ); |
||
209 | } |
||
210 | #else |
||
211 | //# define UPDATE_MAX_BLOBSIZE(P) |
||
212 | static void UPDATE_MAX_BLOBSIZE( Mem P ) { } |
||
213 | #endif |
||
214 | |||
215 | /* |
||
216 | ** Convert the given register into a string if it isn't one |
||
217 | ** already. Return non-zero if a malloc() fails. |
||
218 | */ |
||
219 | //#define Stringify(P, enc) \ |
||
220 | // if(((P).flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc)) \ |
||
221 | // { goto no_mem; } |
||
222 | |||
223 | /* |
||
224 | ** An ephemeral string value (signified by the MEM_Ephem flag) contains |
||
225 | ** a pointer to a dynamically allocated string where some other entity |
||
226 | ** is responsible for deallocating that string. Because the register |
||
227 | ** does not control the string, it might be deleted without the register |
||
228 | ** knowing it. |
||
229 | ** |
||
230 | ** This routine converts an ephemeral string into a dynamically allocated |
||
231 | ** string that the register itself controls. In other words, it |
||
232 | ** converts an MEM_Ephem string into an MEM_Dyn string. |
||
233 | */ |
||
234 | //#define Deephemeralize(P) \ |
||
235 | // if( ((P).flags&MEM_Ephem)!=0 \ |
||
236 | // && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;} |
||
237 | static void Deephemeralize( Mem P ) |
||
238 | { |
||
239 | } |
||
240 | |||
241 | /* |
||
242 | ** Call sqlite3VdbeMemExpandBlob() on the supplied value (type Mem) |
||
243 | ** P if required. |
||
244 | */ |
||
245 | //#define ExpandBlob(P) (((P).flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0) |
||
246 | ////static int ExpandBlob( Mem P ) |
||
247 | ////{ |
||
248 | //// return ( P.flags & MEM_Zero ) != 0 ? sqlite3VdbeMemExpandBlob( P ) : 0; |
||
249 | ////} |
||
250 | |||
251 | /* |
||
252 | ** Argument pMem points at a register that will be passed to a |
||
253 | ** user-defined function or returned to the user as the result of a query. |
||
254 | ** This routine sets the pMem.type variable used by the sqlite3_value_*() |
||
255 | ** routines. |
||
256 | */ |
||
257 | static void sqlite3VdbeMemStoreType( Mem pMem ) |
||
258 | { |
||
259 | int flags = pMem.flags; |
||
260 | if ( ( flags & MEM_Null ) != 0 ) |
||
261 | { |
||
262 | pMem.type = SQLITE_NULL; |
||
263 | pMem.z = null; |
||
264 | pMem.zBLOB = null; |
||
265 | } |
||
266 | else if ( ( flags & MEM_Int ) != 0 ) |
||
267 | { |
||
268 | pMem.type = SQLITE_INTEGER; |
||
269 | } |
||
270 | else if ( ( flags & MEM_Real ) != 0 ) |
||
271 | { |
||
272 | pMem.type = SQLITE_FLOAT; |
||
273 | } |
||
274 | else if ( ( flags & MEM_Str ) != 0 ) |
||
275 | { |
||
276 | pMem.type = SQLITE_TEXT; |
||
277 | } |
||
278 | else |
||
279 | { |
||
280 | pMem.type = SQLITE_BLOB; |
||
281 | } |
||
282 | } |
||
283 | |||
284 | /* |
||
285 | ** Allocate VdbeCursor number iCur. Return a pointer to it. Return NULL |
||
286 | ** if we run out of memory. |
||
287 | */ |
||
288 | static VdbeCursor allocateCursor( |
||
289 | Vdbe p, /* The virtual machine */ |
||
290 | int iCur, /* Index of the new VdbeCursor */ |
||
291 | int nField, /* Number of fields in the table or index */ |
||
292 | int iDb, /* When database the cursor belongs to, or -1 */ |
||
293 | int isBtreeCursor /* True for B-Tree. False for pseudo-table or vtab */ |
||
294 | ) |
||
295 | { |
||
296 | /* Find the memory cell that will be used to store the blob of memory |
||
297 | ** required for this VdbeCursor structure. It is convenient to use a |
||
298 | ** vdbe memory cell to manage the memory allocation required for a |
||
299 | ** VdbeCursor structure for the following reasons: |
||
300 | ** |
||
301 | ** * Sometimes cursor numbers are used for a couple of different |
||
302 | ** purposes in a vdbe program. The different uses might require |
||
303 | ** different sized allocations. Memory cells provide growable |
||
304 | ** allocations. |
||
305 | ** |
||
306 | ** * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can |
||
307 | ** be freed lazily via the sqlite3_release_memory() API. This |
||
308 | ** minimizes the number of malloc calls made by the system. |
||
309 | ** |
||
310 | ** Memory cells for cursors are allocated at the top of the address |
||
311 | ** space. Memory cell (p.nMem) corresponds to cursor 0. Space for |
||
312 | ** cursor 1 is managed by memory cell (p.nMem-1), etc. |
||
313 | */ |
||
314 | //Mem pMem = p.aMem[p.nMem - iCur]; |
||
315 | |||
316 | //int nByte; |
||
317 | VdbeCursor pCx = null; |
||
318 | //ROUND8(sizeof(VdbeCursor)) + |
||
319 | //( isBtreeCursor ? sqlite3BtreeCursorSize() : 0 ) + |
||
320 | //2 * nField * sizeof( u32 ); |
||
321 | |||
322 | Debug.Assert( iCur < p.nCursor ); |
||
323 | if ( p.apCsr[iCur] != null ) |
||
324 | { |
||
325 | sqlite3VdbeFreeCursor( p, p.apCsr[iCur] ); |
||
326 | p.apCsr[iCur] = null; |
||
327 | } |
||
328 | //if ( SQLITE_OK == sqlite3VdbeMemGrow( pMem, nByte, 0 ) ) |
||
329 | { |
||
330 | p.apCsr[iCur] = pCx = new VdbeCursor();// (VdbeCursor)pMem.z; |
||
331 | //memset(pCx, 0, sizeof(VdbeCursor)); |
||
332 | pCx.iDb = iDb; |
||
333 | pCx.nField = nField; |
||
334 | if ( nField != 0 ) |
||
335 | { |
||
336 | pCx.aType = new u32[nField];// (u32)&pMem.z[ROUND8(sizeof( VdbeCursor ))]; |
||
337 | } |
||
338 | if ( isBtreeCursor != 0 ) |
||
339 | { |
||
340 | pCx.pCursor = sqlite3MemMallocBtCursor( pCx.pCursor );// (BtCursor)&pMem.z[ROUND8(sizeof( VdbeCursor )) + 2 * nField * sizeof( u32 )]; |
||
341 | sqlite3BtreeCursorZero( pCx.pCursor ); |
||
342 | } |
||
343 | } |
||
344 | return pCx; |
||
345 | } |
||
346 | |||
347 | /* |
||
348 | ** Try to convert a value into a numeric representation if we can |
||
349 | ** do so without loss of information. In other words, if the string |
||
350 | ** looks like a number, convert it into a number. If it does not |
||
351 | ** look like a number, leave it alone. |
||
352 | */ |
||
353 | static void applyNumericAffinity( Mem pRec ) |
||
354 | { |
||
355 | if ( ( pRec.flags & ( MEM_Real | MEM_Int ) ) == 0 ) |
||
356 | { |
||
357 | double rValue = 0.0; |
||
358 | i64 iValue = 0; |
||
359 | u8 enc = pRec.enc; |
||
360 | if ( ( pRec.flags & MEM_Str ) == 0 ) |
||
361 | return; |
||
362 | if ( sqlite3AtoF( pRec.z, ref rValue, pRec.n, enc ) == false ) |
||
363 | return; |
||
364 | if ( 0 == sqlite3Atoi64( pRec.z, ref iValue, pRec.n, enc ) ) |
||
365 | { |
||
366 | pRec.u.i = iValue; |
||
367 | pRec.flags |= MEM_Int; |
||
368 | } |
||
369 | else |
||
370 | { |
||
371 | pRec.r = rValue; |
||
372 | pRec.flags |= MEM_Real; |
||
373 | } |
||
374 | } |
||
375 | } |
||
376 | |||
377 | /* |
||
378 | ** Processing is determine by the affinity parameter: |
||
379 | ** |
||
380 | ** SQLITE_AFF_INTEGER: |
||
381 | ** SQLITE_AFF_REAL: |
||
382 | ** SQLITE_AFF_NUMERIC: |
||
383 | ** Try to convert pRec to an integer representation or a |
||
384 | ** floating-point representation if an integer representation |
||
385 | ** is not possible. Note that the integer representation is |
||
386 | ** always preferred, even if the affinity is REAL, because |
||
387 | ** an integer representation is more space efficient on disk. |
||
388 | ** |
||
389 | ** SQLITE_AFF_TEXT: |
||
390 | ** Convert pRec to a text representation. |
||
391 | ** |
||
392 | ** SQLITE_AFF_NONE: |
||
393 | ** No-op. pRec is unchanged. |
||
394 | */ |
||
395 | static void applyAffinity( |
||
396 | Mem pRec, /* The value to apply affinity to */ |
||
397 | char affinity, /* The affinity to be applied */ |
||
398 | int enc /* Use this text encoding */ |
||
399 | ) |
||
400 | { |
||
401 | if ( affinity == SQLITE_AFF_TEXT ) |
||
402 | { |
||
403 | /* Only attempt the conversion to TEXT if there is an integer or real |
||
404 | ** representation (blob and NULL do not get converted) but no string |
||
405 | ** representation. |
||
406 | */ |
||
407 | if ( 0 == ( pRec.flags & MEM_Str ) && ( pRec.flags & ( MEM_Real | MEM_Int ) ) != 0 ) |
||
408 | { |
||
409 | sqlite3VdbeMemStringify( pRec, enc ); |
||
410 | } |
||
411 | if ( ( pRec.flags & ( MEM_Blob | MEM_Str ) ) == ( MEM_Blob | MEM_Str ) ) |
||
412 | { |
||
413 | StringBuilder sb = new StringBuilder( pRec.zBLOB.Length ); |
||
414 | for ( int i = 0; i < pRec.zBLOB.Length; i++ ) |
||
415 | sb.Append( (char)pRec.zBLOB[i] ); |
||
416 | pRec.z = sb.ToString(); |
||
417 | sqlite3_free( ref pRec.zBLOB ); |
||
418 | pRec.flags = (u16)( pRec.flags & ~MEM_Blob ); |
||
419 | } |
||
420 | pRec.flags = (u16)( pRec.flags & ~( MEM_Real | MEM_Int ) ); |
||
421 | } |
||
422 | else if ( affinity != SQLITE_AFF_NONE ) |
||
423 | { |
||
424 | Debug.Assert( affinity == SQLITE_AFF_INTEGER || affinity == SQLITE_AFF_REAL |
||
425 | || affinity == SQLITE_AFF_NUMERIC ); |
||
426 | applyNumericAffinity( pRec ); |
||
427 | if ( ( pRec.flags & MEM_Real ) != 0 ) |
||
428 | { |
||
429 | sqlite3VdbeIntegerAffinity( pRec ); |
||
430 | } |
||
431 | } |
||
432 | } |
||
433 | |||
434 | /* |
||
435 | ** Try to convert the type of a function argument or a result column |
||
436 | ** into a numeric representation. Use either INTEGER or REAL whichever |
||
437 | ** is appropriate. But only do the conversion if it is possible without |
||
438 | ** loss of information and return the revised type of the argument. |
||
439 | */ |
||
440 | static int sqlite3_value_numeric_type( sqlite3_value pVal ) |
||
441 | { |
||
442 | Mem pMem = (Mem)pVal; |
||
443 | if ( pMem.type == SQLITE_TEXT ) |
||
444 | { |
||
445 | applyNumericAffinity( pMem ); |
||
446 | sqlite3VdbeMemStoreType( pMem ); |
||
447 | } |
||
448 | return pMem.type; |
||
449 | } |
||
450 | |||
451 | /* |
||
452 | ** Exported version of applyAffinity(). This one works on sqlite3_value*, |
||
453 | ** not the internal Mem type. |
||
454 | */ |
||
455 | static void sqlite3ValueApplyAffinity( |
||
456 | sqlite3_value pVal, |
||
457 | char affinity, |
||
458 | int enc |
||
459 | ) |
||
460 | { |
||
461 | applyAffinity( (Mem)pVal, affinity, enc ); |
||
462 | } |
||
463 | |||
464 | #if SQLITE_DEBUG |
||
465 | /* |
||
466 | ** Write a nice string representation of the contents of cell pMem |
||
467 | ** into buffer zBuf, length nBuf. |
||
468 | */ |
||
469 | static StringBuilder zCsr = new StringBuilder( 100 ); |
||
470 | static void sqlite3VdbeMemPrettyPrint( Mem pMem, StringBuilder zBuf ) |
||
471 | { |
||
472 | zBuf.Length = 0; |
||
473 | zCsr.Length = 0; |
||
474 | int f = pMem.flags; |
||
475 | |||
476 | string[] encnames = new string[] { "(X)", "(8)", "(16LE)", "(16BE)" }; |
||
477 | |||
478 | if ( ( f & MEM_Blob ) != 0 ) |
||
479 | { |
||
480 | int i; |
||
481 | char c; |
||
482 | if ( ( f & MEM_Dyn ) != 0 ) |
||
483 | { |
||
484 | c = 'z'; |
||
485 | Debug.Assert( ( f & ( MEM_Static | MEM_Ephem ) ) == 0 ); |
||
486 | } |
||
487 | else if ( ( f & MEM_Static ) != 0 ) |
||
488 | { |
||
489 | c = 't'; |
||
490 | Debug.Assert( ( f & ( MEM_Dyn | MEM_Ephem ) ) == 0 ); |
||
491 | } |
||
492 | else if ( ( f & MEM_Ephem ) != 0 ) |
||
493 | { |
||
494 | c = 'e'; |
||
495 | Debug.Assert( ( f & ( MEM_Static | MEM_Dyn ) ) == 0 ); |
||
496 | } |
||
497 | else |
||
498 | { |
||
499 | c = 's'; |
||
500 | } |
||
501 | |||
502 | sqlite3_snprintf( 100, zCsr, "%c", c ); |
||
503 | zBuf.Append( zCsr );//zCsr += sqlite3Strlen30(zCsr); |
||
504 | sqlite3_snprintf( 100, zCsr, "%d[", pMem.n ); |
||
505 | zBuf.Append( zCsr );//zCsr += sqlite3Strlen30(zCsr); |
||
506 | for ( i = 0; i < 16 && i < pMem.n; i++ ) |
||
507 | { |
||
508 | sqlite3_snprintf( 100, zCsr, "%02X", ( (int)pMem.zBLOB[i] & 0xFF ) ); |
||
509 | zBuf.Append( zCsr );//zCsr += sqlite3Strlen30(zCsr); |
||
510 | } |
||
511 | for ( i = 0; i < 16 && i < pMem.n; i++ ) |
||
512 | { |
||
513 | char z = (char)pMem.zBLOB[i]; |
||
514 | if ( z < 32 || z > 126 ) |
||
515 | zBuf.Append( '.' );//*zCsr++ = '.'; |
||
516 | else |
||
517 | zBuf.Append( z );//*zCsr++ = z; |
||
518 | } |
||
519 | |||
520 | sqlite3_snprintf( 100, zCsr, "]%s", encnames[pMem.enc] ); |
||
521 | zBuf.Append( zCsr );//zCsr += sqlite3Strlen30(zCsr); |
||
522 | if ( ( f & MEM_Zero ) != 0 ) |
||
523 | { |
||
524 | sqlite3_snprintf( 100, zCsr, "+%dz", pMem.u.nZero ); |
||
525 | zBuf.Append( zCsr );//zCsr += sqlite3Strlen30(zCsr); |
||
526 | } |
||
527 | //*zCsr = '\0'; |
||
528 | } |
||
529 | else if ( ( f & MEM_Str ) != 0 ) |
||
530 | { |
||
531 | int j;//, k; |
||
532 | zBuf.Append( ' ' ); |
||
533 | if ( ( f & MEM_Dyn ) != 0 ) |
||
534 | { |
||
535 | zBuf.Append( 'z' ); |
||
536 | Debug.Assert( ( f & ( MEM_Static | MEM_Ephem ) ) == 0 ); |
||
537 | } |
||
538 | else if ( ( f & MEM_Static ) != 0 ) |
||
539 | { |
||
540 | zBuf.Append( 't' ); |
||
541 | Debug.Assert( ( f & ( MEM_Dyn | MEM_Ephem ) ) == 0 ); |
||
542 | } |
||
543 | else if ( ( f & MEM_Ephem ) != 0 ) |
||
544 | { |
||
545 | zBuf.Append( 's' ); //zBuf.Append( 'e' ); |
||
546 | Debug.Assert( ( f & ( MEM_Static | MEM_Dyn ) ) == 0 ); |
||
547 | } |
||
548 | else |
||
549 | { |
||
550 | zBuf.Append( 's' ); |
||
551 | } |
||
552 | //k = 2; |
||
553 | sqlite3_snprintf( 100, zCsr, "%d", pMem.n );//zBuf[k], "%d", pMem.n ); |
||
554 | zBuf.Append( zCsr ); |
||
555 | //k += sqlite3Strlen30( &zBuf[k] ); |
||
556 | zBuf.Append( '[' );// zBuf[k++] = '['; |
||
557 | for ( j = 0; j < 15 && j < pMem.n; j++ ) |
||
558 | { |
||
559 | u8 c = pMem.z != null ? (u8)pMem.z[j] : pMem.zBLOB[j]; |
||
560 | if ( c >= 0x20 && c < 0x7f ) |
||
561 | { |
||
562 | zBuf.Append( (char)c );//zBuf[k++] = c; |
||
563 | } |
||
564 | else |
||
565 | { |
||
566 | zBuf.Append( '.' );//zBuf[k++] = '.'; |
||
567 | } |
||
568 | } |
||
569 | zBuf.Append( ']' );//zBuf[k++] = ']'; |
||
570 | sqlite3_snprintf( 100, zCsr, encnames[pMem.enc] );//& zBuf[k], encnames[pMem.enc] ); |
||
571 | zBuf.Append( zCsr ); |
||
572 | //k += sqlite3Strlen30( &zBuf[k] ); |
||
573 | //zBuf[k++] = 0; |
||
574 | } |
||
575 | } |
||
576 | #endif |
||
577 | |||
578 | #if SQLITE_DEBUG |
||
579 | /* |
||
580 | ** Print the value of a register for tracing purposes: |
||
581 | */ |
||
582 | static void memTracePrint( FILE _out, Mem p ) |
||
583 | { |
||
584 | if ( ( p.flags & MEM_Null ) != 0 ) |
||
585 | { |
||
586 | fprintf( _out, " NULL" ); |
||
587 | } |
||
588 | else if ( ( p.flags & ( MEM_Int | MEM_Str ) ) == ( MEM_Int | MEM_Str ) ) |
||
589 | { |
||
590 | fprintf( _out, " si:%lld", p.u.i ); |
||
591 | #if !SQLITE_OMIT_FLOATING_POINT |
||
592 | } |
||
593 | else if ( ( p.flags & MEM_Int ) != 0 ) |
||
594 | { |
||
595 | fprintf( _out, " i:%lld", p.u.i ); |
||
596 | #endif |
||
597 | } |
||
598 | else if ( ( p.flags & MEM_Real ) != 0 ) |
||
599 | { |
||
600 | fprintf( _out, " r:%g", p.r ); |
||
601 | } |
||
602 | else if ( ( p.flags & MEM_RowSet ) != 0 ) |
||
603 | { |
||
604 | fprintf( _out, " (rowset)" ); |
||
605 | } |
||
606 | else |
||
607 | { |
||
608 | StringBuilder zBuf = new StringBuilder( 200 ); |
||
609 | sqlite3VdbeMemPrettyPrint( p, zBuf ); |
||
610 | fprintf( _out, " " ); |
||
611 | fprintf( _out, "%s", zBuf ); |
||
612 | } |
||
613 | } |
||
614 | static void registerTrace( FILE _out, int iReg, Mem p ) |
||
615 | { |
||
616 | fprintf( _out, "reg[%d] = ", iReg ); |
||
617 | memTracePrint( _out, p ); |
||
618 | fprintf( _out, "\n" ); |
||
619 | } |
||
620 | #endif |
||
621 | |||
622 | #if SQLITE_DEBUG |
||
623 | //# define REGISTER_TRACE(R,M) if(p.trace)registerTrace(p.trace,R,M) |
||
624 | static void REGISTER_TRACE( Vdbe p, int R, Mem M ) |
||
625 | { |
||
626 | if ( p.trace != null ) |
||
627 | registerTrace( p.trace, R, M ); |
||
628 | } |
||
629 | #else |
||
630 | //# define REGISTER_TRACE(R,M) |
||
631 | static void REGISTER_TRACE( Vdbe p, int R, Mem M ) { } |
||
632 | #endif |
||
633 | |||
634 | |||
635 | #if VDBE_PROFILE |
||
636 | |||
637 | /* |
||
638 | ** hwtime.h contains inline assembler code for implementing |
||
639 | ** high-performance timing routines. |
||
640 | */ |
||
641 | //#include "hwtime.h" |
||
642 | |||
643 | #endif |
||
644 | |||
645 | /* |
||
646 | ** The CHECK_FOR_INTERRUPT macro defined here looks to see if the |
||
647 | ** sqlite3_interrupt() routine has been called. If it has been, then |
||
648 | ** processing of the VDBE program is interrupted. |
||
649 | ** |
||
650 | ** This macro added to every instruction that does a jump in order to |
||
651 | ** implement a loop. This test used to be on every single instruction, |
||
652 | ** but that meant we more testing that we needed. By only testing the |
||
653 | ** flag on jump instructions, we get a (small) speed improvement. |
||
654 | */ |
||
655 | //#define CHECK_FOR_INTERRUPT \ |
||
656 | // if( db.u1.isInterrupted ) goto abort_due_to_interrupt; |
||
657 | |||
658 | #if !NDEBUG |
||
659 | /* |
||
660 | ** This function is only called from within an Debug.Assert() expression. It |
||
661 | ** checks that the sqlite3.nTransaction variable is correctly set to |
||
662 | ** the number of non-transaction savepoints currently in the |
||
663 | ** linked list starting at sqlite3.pSavepoint. |
||
664 | ** |
||
665 | ** Usage: |
||
666 | ** |
||
667 | ** Debug.Assert( checkSavepointCount(db) ); |
||
668 | */ |
||
669 | static int checkSavepointCount( sqlite3 db ) |
||
670 | { |
||
671 | int n = 0; |
||
672 | Savepoint p; |
||
673 | for ( p = db.pSavepoint; p != null; p = p.pNext ) |
||
674 | n++; |
||
675 | Debug.Assert( n == ( db.nSavepoint + db.isTransactionSavepoint ) ); |
||
676 | return 1; |
||
677 | } |
||
678 | #else |
||
679 | static int checkSavepointCount( sqlite3 db ) { return 1; } |
||
680 | #endif |
||
681 | |||
682 | /* |
||
683 | ** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored |
||
684 | ** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored |
||
685 | ** in memory obtained from sqlite3DbMalloc). |
||
686 | */ |
||
687 | static void importVtabErrMsg( Vdbe p, sqlite3_vtab pVtab ) |
||
688 | { |
||
689 | sqlite3 db = p.db; |
||
690 | sqlite3DbFree( db, ref p.zErrMsg ); |
||
691 | p.zErrMsg = pVtab.zErrMsg; // sqlite3DbStrDup( db, pVtab.zErrMsg ); |
||
692 | //sqlite3_free( pVtab.zErrMsg ); |
||
693 | pVtab.zErrMsg = null; |
||
694 | } |
||
695 | |||
696 | /* |
||
697 | ** Execute as much of a VDBE program as we can then return. |
||
698 | ** |
||
699 | ** sqlite3VdbeMakeReady() must be called before this routine in order to |
||
700 | ** close the program with a final OP_Halt and to set up the callbacks |
||
701 | ** and the error message pointer. |
||
702 | ** |
||
703 | ** Whenever a row or result data is available, this routine will either |
||
704 | ** invoke the result callback (if there is one) or return with |
||
705 | ** SQLITE_ROW. |
||
706 | ** |
||
707 | ** If an attempt is made to open a locked database, then this routine |
||
708 | ** will either invoke the busy callback (if there is one) or it will |
||
709 | ** return SQLITE_BUSY. |
||
710 | ** |
||
711 | ** If an error occurs, an error message is written to memory obtained |
||
712 | ** from sqlite3Malloc() and p.zErrMsg is made to point to that memory. |
||
713 | ** The error code is stored in p.rc and this routine returns SQLITE_ERROR. |
||
714 | ** |
||
715 | ** If the callback ever returns non-zero, then the program exits |
||
716 | ** immediately. There will be no error message but the p.rc field is |
||
717 | ** set to SQLITE_ABORT and this routine will return SQLITE_ERROR. |
||
718 | ** |
||
719 | ** A memory allocation error causes p.rc to be set to SQLITE_NOMEM and this |
||
720 | ** routine to return SQLITE_ERROR. |
||
721 | ** |
||
722 | ** Other fatal errors return SQLITE_ERROR. |
||
723 | ** |
||
724 | ** After this routine has finished, sqlite3VdbeFinalize() should be |
||
725 | ** used to clean up the mess that was left behind. |
||
726 | */ |
||
727 | static int sqlite3VdbeExec( |
||
728 | Vdbe p /* The VDBE */ |
||
729 | ) |
||
730 | { |
||
731 | int pc = 0; /* The program counter */ |
||
732 | Op[] aOp = p.aOp; /* Copy of p.aOp */ |
||
733 | Op pOp; /* Current operation */ |
||
734 | int rc = SQLITE_OK; /* Value to return */ |
||
735 | sqlite3 db = p.db; /* The database */ |
||
736 | u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ |
||
737 | u8 encoding = ENC( db ); /* The database encoding */ |
||
738 | #if !SQLITE_OMIT_PROGRESS_CALLBACK |
||
739 | bool checkProgress; /* True if progress callbacks are enabled */ |
||
740 | int nProgressOps = 0; /* Opcodes executed since progress callback. */ |
||
741 | #endif |
||
742 | Mem[] aMem = p.aMem; /* Copy of p.aMem */ |
||
743 | Mem pIn1 = null; /* 1st input operand */ |
||
744 | Mem pIn2 = null; /* 2nd input operand */ |
||
745 | Mem pIn3 = null; /* 3rd input operand */ |
||
746 | Mem pOut = null; /* Output operand */ |
||
747 | int iCompare = 0; /* Result of last OP_Compare operation */ |
||
748 | int[] aPermute = null; /* Permutation of columns for OP_Compare */ |
||
749 | i64 lastRowid = db.lastRowid; /* Saved value of the last insert ROWID */ |
||
750 | #if VDBE_PROFILE |
||
751 | u64 start; /* CPU clock count at start of opcode */ |
||
752 | int origPc; /* Program counter at start of opcode */ |
||
753 | #endif |
||
754 | /*** INSERT STACK UNION HERE ***/ |
||
755 | |||
756 | Debug.Assert( p.magic == VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ |
||
757 | sqlite3VdbeEnter( p ); |
||
758 | if ( p.rc == SQLITE_NOMEM ) |
||
759 | { |
||
760 | /* This happens if a malloc() inside a call to sqlite3_column_text() or |
||
761 | ** sqlite3_column_text16() failed. */ |
||
762 | goto no_mem; |
||
763 | } |
||
764 | Debug.Assert( p.rc == SQLITE_OK || p.rc == SQLITE_BUSY ); |
||
765 | p.rc = SQLITE_OK; |
||
766 | Debug.Assert( p.explain == 0 ); |
||
767 | p.pResultSet = null; |
||
768 | db.busyHandler.nBusy = 0; |
||
769 | if ( db.u1.isInterrupted ) |
||
770 | goto abort_due_to_interrupt; //CHECK_FOR_INTERRUPT; |
||
771 | #if TRACE |
||
772 | sqlite3VdbeIOTraceSql( p ); |
||
773 | #endif |
||
774 | #if !SQLITE_OMIT_PROGRESS_CALLBACK |
||
775 | checkProgress = db.xProgress != null; |
||
776 | #endif |
||
777 | #if SQLITE_DEBUG |
||
778 | sqlite3BeginBenignMalloc(); |
||
779 | if ( p.pc == 0 |
||
780 | && ( p.db.flags & SQLITE_VdbeListing ) != 0 ) |
||
781 | { |
||
782 | int i; |
||
783 | Console.Write( "VDBE Program Listing:\n" ); |
||
784 | sqlite3VdbePrintSql( p ); |
||
785 | for ( i = 0; i < p.nOp; i++ ) |
||
786 | { |
||
787 | sqlite3VdbePrintOp( Console.Out, i, aOp[i] ); |
||
788 | } |
||
789 | } |
||
790 | sqlite3EndBenignMalloc(); |
||
791 | #endif |
||
792 | for ( pc = p.pc; rc == SQLITE_OK; pc++ ) |
||
793 | { |
||
794 | Debug.Assert( pc >= 0 && pc < p.nOp ); |
||
795 | // if ( db.mallocFailed != 0 ) goto no_mem; |
||
796 | #if VDBE_PROFILE |
||
797 | origPc = pc; |
||
798 | start = sqlite3Hwtime(); |
||
799 | #endif |
||
800 | pOp = aOp[pc]; |
||
801 | |||
802 | /* Only allow tracing if SQLITE_DEBUG is defined. |
||
803 | */ |
||
804 | #if SQLITE_DEBUG |
||
805 | if ( p.trace != null ) |
||
806 | { |
||
807 | if ( pc == 0 ) |
||
808 | { |
||
809 | printf( "VDBE Execution Trace:\n" ); |
||
810 | sqlite3VdbePrintSql( p ); |
||
811 | } |
||
812 | sqlite3VdbePrintOp( p.trace, pc, pOp ); |
||
813 | } |
||
814 | #endif |
||
815 | |||
816 | |||
817 | /* Check to see if we need to simulate an interrupt. This only happens |
||
818 | ** if we have a special test build. |
||
819 | */ |
||
820 | #if SQLITE_TEST |
||
821 | #if !TCLSH |
||
822 | if ( sqlite3_interrupt_count > 0 ) |
||
823 | { |
||
824 | sqlite3_interrupt_count--; |
||
825 | if ( sqlite3_interrupt_count == 0 ) |
||
826 | #else |
||
827 | if ( sqlite3_interrupt_count.iValue > 0 ) |
||
828 | { |
||
829 | sqlite3_interrupt_count.iValue--; |
||
830 | if ( sqlite3_interrupt_count.iValue == 0 ) |
||
831 | #endif |
||
832 | { |
||
833 | sqlite3_interrupt( db ); |
||
834 | } |
||
835 | } |
||
836 | #endif |
||
837 | |||
838 | #if !SQLITE_OMIT_PROGRESS_CALLBACK |
||
839 | /* Call the progress callback if it is configured and the required number |
||
840 | ** of VDBE ops have been executed (either since this invocation of |
||
841 | ** sqlite3VdbeExec() or since last time the progress callback was called). |
||
842 | ** If the progress callback returns non-zero, exit the virtual machine with |
||
843 | ** a return code SQLITE_ABORT. |
||
844 | */ |
||
845 | if ( checkProgress ) |
||
846 | { |
||
847 | if ( db.nProgressOps == nProgressOps ) |
||
848 | { |
||
849 | int prc; |
||
850 | prc = db.xProgress( db.pProgressArg ); |
||
851 | if ( prc != 0 ) |
||
852 | { |
||
853 | rc = SQLITE_INTERRUPT; |
||
854 | goto vdbe_error_halt; |
||
855 | } |
||
856 | nProgressOps = 0; |
||
857 | } |
||
858 | nProgressOps++; |
||
859 | } |
||
860 | #endif |
||
861 | |||
862 | /* On any opcode with the "out2-prerelase" tag, free any |
||
863 | ** external allocations out of mem[p2] and set mem[p2] to be |
||
864 | ** an undefined integer. Opcodes will either fill in the integer |
||
865 | ** value or convert mem[p2] to a different type. |
||
866 | */ |
||
867 | Debug.Assert( pOp.opflags == sqlite3OpcodeProperty[pOp.opcode] ); |
||
868 | if ( ( pOp.opflags & OPFLG_OUT2_PRERELEASE ) != 0 ) |
||
869 | { |
||
870 | Debug.Assert( pOp.p2 > 0 ); |
||
871 | Debug.Assert( pOp.p2 <= p.nMem ); |
||
872 | pOut = aMem[pOp.p2]; |
||
873 | memAboutToChange( p, pOut ); |
||
874 | sqlite3VdbeMemReleaseExternal( pOut ); |
||
875 | pOut.flags = MEM_Int; |
||
876 | } |
||
877 | |||
878 | /* Sanity checking on other operands */ |
||
879 | /* Sanity checking on other operands */ |
||
880 | #if SQLITE_DEBUG |
||
881 | if ( ( pOp.opflags & OPFLG_IN1 ) != 0 ) |
||
882 | { |
||
883 | Debug.Assert( pOp.p1 > 0 ); |
||
884 | Debug.Assert( pOp.p1 <= p.nMem ); |
||
885 | Debug.Assert( memIsValid( aMem[pOp.p1] ) ); |
||
886 | REGISTER_TRACE( p, pOp.p1, aMem[pOp.p1] ); |
||
887 | } |
||
888 | if ( ( pOp.opflags & OPFLG_IN2 ) != 0 ) |
||
889 | { |
||
890 | Debug.Assert( pOp.p2 > 0 ); |
||
891 | Debug.Assert( pOp.p2 <= p.nMem ); |
||
892 | Debug.Assert( memIsValid( aMem[pOp.p2] ) ); |
||
893 | REGISTER_TRACE( p, pOp.p2, aMem[pOp.p2] ); |
||
894 | } |
||
895 | if ( ( pOp.opflags & OPFLG_IN3 ) != 0 ) |
||
896 | { |
||
897 | Debug.Assert( pOp.p3 > 0 ); |
||
898 | Debug.Assert( pOp.p3 <= p.nMem ); |
||
899 | Debug.Assert( memIsValid( aMem[pOp.p3] ) ); |
||
900 | REGISTER_TRACE( p, pOp.p3, aMem[pOp.p3] ); |
||
901 | } |
||
902 | if ( ( pOp.opflags & OPFLG_OUT2 ) != 0 ) |
||
903 | { |
||
904 | Debug.Assert( pOp.p2 > 0 ); |
||
905 | Debug.Assert( pOp.p2 <= p.nMem ); |
||
906 | memAboutToChange( p, aMem[pOp.p2] ); |
||
907 | } |
||
908 | if ( ( pOp.opflags & OPFLG_OUT3 ) != 0 ) |
||
909 | { |
||
910 | Debug.Assert( pOp.p3 > 0 ); |
||
911 | Debug.Assert( pOp.p3 <= p.nMem ); |
||
912 | memAboutToChange( p, aMem[pOp.p3] ); |
||
913 | } |
||
914 | #endif |
||
915 | |||
916 | switch ( pOp.opcode ) |
||
917 | { |
||
918 | |||
919 | /***************************************************************************** |
||
920 | ** What follows is a massive switch statement where each case implements a |
||
921 | ** separate instruction in the virtual machine. If we follow the usual |
||
922 | ** indentation conventions, each case should be indented by 6 spaces. But |
||
923 | ** that is a lot of wasted space on the left margin. So the code within |
||
924 | ** the switch statement will break with convention and be flush-left. Another |
||
925 | ** big comment (similar to this one) will mark the point in the code where |
||
926 | ** we transition back to normal indentation. |
||
927 | ** |
||
928 | ** The formatting of each case is important. The makefile for SQLite |
||
929 | ** generates two C files "opcodes.h" and "opcodes.c" by scanning this |
||
930 | ** file looking for lines that begin with "case OP_". The opcodes.h files |
||
931 | ** will be filled with #defines that give unique integer values to each |
||
932 | ** opcode and the opcodes.c file is filled with an array of strings where |
||
933 | ** each string is the symbolic name for the corresponding opcode. If the |
||
934 | ** case statement is followed by a comment of the form "/# same as ... #/" |
||
935 | ** that comment is used to determine the particular value of the opcode. |
||
936 | ** |
||
937 | ** Other keywords in the comment that follows each case are used to |
||
938 | ** construct the OPFLG_INITIALIZER value that initializes opcodeProperty[]. |
||
939 | ** Keywords include: in1, in2, in3, ref2_prerelease, ref2, ref3. See |
||
940 | ** the mkopcodeh.awk script for additional information. |
||
941 | ** |
||
942 | ** Documentation about VDBE opcodes is generated by scanning this file |
||
943 | ** for lines of that contain "Opcode:". That line and all subsequent |
||
944 | ** comment lines are used in the generation of the opcode.html documentation |
||
945 | ** file. |
||
946 | ** |
||
947 | ** SUMMARY: |
||
948 | ** |
||
949 | ** Formatting is important to scripts that scan this file. |
||
950 | ** Do not deviate from the formatting style currently in use. |
||
951 | ** |
||
952 | *****************************************************************************/ |
||
953 | |||
954 | /* Opcode: Goto * P2 * * * |
||
955 | ** |
||
956 | ** An unconditional jump to address P2. |
||
957 | ** The next instruction executed will be |
||
958 | ** the one at index P2 from the beginning of |
||
959 | ** the program. |
||
960 | */ |
||
961 | case OP_Goto: |
||
962 | { /* jump */ |
||
963 | if ( db.u1.isInterrupted ) |
||
964 | goto abort_due_to_interrupt; //CHECK_FOR_INTERRUPT; |
||
965 | pc = pOp.p2 - 1; |
||
966 | break; |
||
967 | } |
||
968 | |||
969 | /* Opcode: Gosub P1 P2 * * * |
||
970 | ** |
||
971 | ** Write the current address onto register P1 |
||
972 | ** and then jump to address P2. |
||
973 | */ |
||
974 | case OP_Gosub: |
||
975 | { /* jump, in1 */ |
||
976 | pIn1 = aMem[pOp.p1]; |
||
977 | Debug.Assert( ( pIn1.flags & MEM_Dyn ) == 0 ); |
||
978 | memAboutToChange( p, pIn1 ); |
||
979 | pIn1.flags = MEM_Int; |
||
980 | pIn1.u.i = pc; |
||
981 | REGISTER_TRACE( p, pOp.p1, pIn1 ); |
||
982 | pc = pOp.p2 - 1; |
||
983 | break; |
||
984 | } |
||
985 | |||
986 | /* Opcode: Return P1 * * * * |
||
987 | ** |
||
988 | ** Jump to the next instruction after the address in register P1. |
||
989 | */ |
||
990 | case OP_Return: |
||
991 | { /* in1 */ |
||
992 | pIn1 = aMem[pOp.p1]; |
||
993 | Debug.Assert( ( pIn1.flags & MEM_Int ) != 0 ); |
||
994 | pc = (int)pIn1.u.i; |
||
995 | break; |
||
996 | } |
||
997 | |||
998 | /* Opcode: Yield P1 * * * * |
||
999 | ** |
||
1000 | ** Swap the program counter with the value in register P1. |
||
1001 | */ |
||
1002 | case OP_Yield: |
||
1003 | { /* in1 */ |
||
1004 | int pcDest; |
||
1005 | pIn1 = aMem[pOp.p1]; |
||
1006 | Debug.Assert( ( pIn1.flags & MEM_Dyn ) == 0 ); |
||
1007 | pIn1.flags = MEM_Int; |
||
1008 | pcDest = (int)pIn1.u.i; |
||
1009 | pIn1.u.i = pc; |
||
1010 | REGISTER_TRACE( p, pOp.p1, pIn1 ); |
||
1011 | pc = pcDest; |
||
1012 | break; |
||
1013 | } |
||
1014 | |||
1015 | /* Opcode: HaltIfNull P1 P2 P3 P4 * |
||
1016 | ** |
||
1017 | ** Check the value in register P3. If it is NULL then Halt using |
||
1018 | ** parameter P1, P2, and P4 as if this were a Halt instruction. If the |
||
1019 | ** value in register P3 is not NULL, then this routine is a no-op. |
||
1020 | */ |
||
1021 | case OP_HaltIfNull: |
||
1022 | { /* in3 */ |
||
1023 | pIn3 = aMem[pOp.p3]; |
||
1024 | if ( ( pIn3.flags & MEM_Null ) == 0 ) |
||
1025 | break; |
||
1026 | /* Fall through into OP_Halt */ |
||
1027 | goto case OP_Halt; |
||
1028 | } |
||
1029 | |||
1030 | /* Opcode: Halt P1 P2 * P4 * |
||
1031 | ** |
||
1032 | ** Exit immediately. All open cursors, etc are closed |
||
1033 | ** automatically. |
||
1034 | ** |
||
1035 | ** P1 is the result code returned by sqlite3_exec(), sqlite3_reset(), |
||
1036 | ** or sqlite3_finalize(). For a normal halt, this should be SQLITE_OK (0). |
||
1037 | ** For errors, it can be some other value. If P1!=0 then P2 will determine |
||
1038 | ** whether or not to rollback the current transaction. Do not rollback |
||
1039 | ** if P2==OE_Fail. Do the rollback if P2==OE_Rollback. If P2==OE_Abort, |
||
1040 | ** then back out all changes that have occurred during this execution of the |
||
1041 | ** VDBE, but do not rollback the transaction. |
||
1042 | ** |
||
1043 | ** If P4 is not null then it is an error message string. |
||
1044 | ** |
||
1045 | ** There is an implied "Halt 0 0 0" instruction inserted at the very end of |
||
1046 | ** every program. So a jump past the last instruction of the program |
||
1047 | ** is the same as executing Halt. |
||
1048 | */ |
||
1049 | case OP_Halt: |
||
1050 | { |
||
1051 | pIn3 = aMem[pOp.p3]; |
||
1052 | if ( pOp.p1 == SQLITE_OK && p.pFrame != null ) |
||
1053 | { |
||
1054 | /* Halt the sub-program. Return control to the parent frame. */ |
||
1055 | VdbeFrame pFrame = p.pFrame; |
||
1056 | p.pFrame = pFrame.pParent; |
||
1057 | p.nFrame--; |
||
1058 | sqlite3VdbeSetChanges( db, p.nChange ); |
||
1059 | pc = sqlite3VdbeFrameRestore( pFrame ); |
||
1060 | lastRowid = db.lastRowid; |
||
1061 | if ( pOp.p2 == OE_Ignore ) |
||
1062 | { |
||
1063 | /* Instruction pc is the OP_Program that invoked the sub-program |
||
1064 | ** currently being halted. If the p2 instruction of this OP_Halt |
||
1065 | ** instruction is set to OE_Ignore, then the sub-program is throwing |
||
1066 | ** an IGNORE exception. In this case jump to the address specified |
||
1067 | ** as the p2 of the calling OP_Program. */ |
||
1068 | pc = p.aOp[pc].p2 - 1; |
||
1069 | } |
||
1070 | aOp = p.aOp; |
||
1071 | aMem = p.aMem; |
||
1072 | break; |
||
1073 | } |
||
1074 | p.rc = pOp.p1; |
||
1075 | p.errorAction = (u8)pOp.p2; |
||
1076 | p.pc = pc; |
||
1077 | if ( pOp.p4.z != null ) |
||
1078 | { |
||
1079 | Debug.Assert( p.rc != SQLITE_OK ); |
||
1080 | sqlite3SetString( ref p.zErrMsg, db, "%s", pOp.p4.z ); |
||
1081 | testcase( sqlite3GlobalConfig.xLog != null ); |
||
1082 | sqlite3_log( pOp.p1, "abort at %d in [%s]: %s", pc, p.zSql, pOp.p4.z ); |
||
1083 | } |
||
1084 | else if ( p.rc != 0 ) |
||
1085 | { |
||
1086 | testcase( sqlite3GlobalConfig.xLog != null ); |
||
1087 | sqlite3_log( pOp.p1, "constraint failed at %d in [%s]", pc, p.zSql ); |
||
1088 | } |
||
1089 | rc = sqlite3VdbeHalt( p ); |
||
1090 | Debug.Assert( rc == SQLITE_BUSY || rc == SQLITE_OK || rc == SQLITE_ERROR ); |
||
1091 | if ( rc == SQLITE_BUSY ) |
||
1092 | { |
||
1093 | p.rc = rc = SQLITE_BUSY; |
||
1094 | } |
||
1095 | else |
||
1096 | { |
||
1097 | Debug.Assert( rc == SQLITE_OK || p.rc == SQLITE_CONSTRAINT ); |
||
1098 | Debug.Assert( rc == SQLITE_OK || db.nDeferredCons > 0 ); |
||
1099 | rc = p.rc != 0 ? SQLITE_ERROR : SQLITE_DONE; |
||
1100 | } |
||
1101 | goto vdbe_return; |
||
1102 | } |
||
1103 | |||
1104 | /* Opcode: Integer P1 P2 * * * |
||
1105 | ** |
||
1106 | ** The 32-bit integer value P1 is written into register P2. |
||
1107 | */ |
||
1108 | case OP_Integer: |
||
1109 | { /* out2-prerelease */ |
||
1110 | pOut.u.i = pOp.p1; |
||
1111 | break; |
||
1112 | } |
||
1113 | |||
1114 | /* Opcode: Int64 * P2 * P4 * |
||
1115 | ** |
||
1116 | ** P4 is a pointer to a 64-bit integer value. |
||
1117 | ** Write that value into register P2. |
||
1118 | */ |
||
1119 | case OP_Int64: |
||
1120 | { /* out2-prerelease */ |
||
1121 | // Integer pointer always exists Debug.Assert( pOp.p4.pI64 != 0 ); |
||
1122 | pOut.u.i = pOp.p4.pI64; |
||
1123 | break; |
||
1124 | } |
||
1125 | |||
1126 | #if !SQLITE_OMIT_FLOATING_POINT |
||
1127 | /* Opcode: Real * P2 * P4 * |
||
1128 | ** |
||
1129 | ** P4 is a pointer to a 64-bit floating point value. |
||
1130 | ** Write that value into register P2. |
||
1131 | */ |
||
1132 | case OP_Real: |
||
1133 | { /* same as TK_FLOAT, ref2-prerelease */ |
||
1134 | pOut.flags = MEM_Real; |
||
1135 | Debug.Assert( !sqlite3IsNaN( pOp.p4.pReal ) ); |
||
1136 | pOut.r = pOp.p4.pReal; |
||
1137 | break; |
||
1138 | } |
||
1139 | #endif |
||
1140 | |||
1141 | /* Opcode: String8 * P2 * P4 * |
||
1142 | ** |
||
1143 | ** P4 points to a nul terminated UTF-8 string. This opcode is transformed |
||
1144 | ** into an OP_String before it is executed for the first time. |
||
1145 | */ |
||
1146 | case OP_String8: |
||
1147 | { /* same as TK_STRING, ref2-prerelease */ |
||
1148 | Debug.Assert( pOp.p4.z != null ); |
||
1149 | pOp.opcode = OP_String; |
||
1150 | pOp.p1 = sqlite3Strlen30( pOp.p4.z ); |
||
1151 | |||
1152 | #if !SQLITE_OMIT_UTF16 |
||
1153 | if( encoding!=SQLITE_UTF8 ){ |
||
1154 | rc = sqlite3VdbeMemSetStr(pOut, pOp.p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); |
||
1155 | if( rc==SQLITE_TOOBIG ) goto too_big; |
||
1156 | if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; |
||
1157 | Debug.Assert( pOut.zMalloc==pOut.z ); |
||
1158 | Debug.Assert( pOut.flags & MEM_Dyn ); |
||
1159 | pOut.zMalloc = 0; |
||
1160 | pOut.flags |= MEM_Static; |
||
1161 | pOut.flags &= ~MEM_Dyn; |
||
1162 | if( pOp.p4type==P4_DYNAMIC ){ |
||
1163 | sqlite3DbFree(db, ref pOp.p4.z); |
||
1164 | } |
||
1165 | pOp.p4type = P4_DYNAMIC; |
||
1166 | pOp.p4.z = pOut.z; |
||
1167 | pOp.p1 = pOut.n; |
||
1168 | } |
||
1169 | #endif |
||
1170 | if ( pOp.p1 > db.aLimit[SQLITE_LIMIT_LENGTH] ) |
||
1171 | { |
||
1172 | goto too_big; |
||
1173 | } |
||
1174 | /* Fall through to the next case, OP_String */ |
||
1175 | goto case OP_String; |
||
1176 | } |
||
1177 | |||
1178 | /* Opcode: String P1 P2 * P4 * |
||
1179 | ** |
||
1180 | ** The string value P4 of length P1 (bytes) is stored in register P2. |
||
1181 | */ |
||
1182 | case OP_String: |
||
1183 | { /* out2-prerelease */ |
||
1184 | Debug.Assert( pOp.p4.z != null ); |
||
1185 | pOut.flags = MEM_Str | MEM_Static | MEM_Term; |
||
1186 | sqlite3_free( ref pOut.zBLOB ); |
||
1187 | pOut.z = pOp.p4.z; |
||
1188 | pOut.n = pOp.p1; |
||
1189 | #if SQLITE_OMIT_UTF16 |
||
1190 | pOut.enc = SQLITE_UTF8; |
||
1191 | #else |
||
1192 | pOut.enc = encoding; |
||
1193 | #endif |
||
1194 | #if SQLITE_TEST |
||
1195 | UPDATE_MAX_BLOBSIZE( pOut ); |
||
1196 | #endif |
||
1197 | break; |
||
1198 | } |
||
1199 | |||
1200 | /* Opcode: Null * P2 * * * |
||
1201 | ** |
||
1202 | ** Write a NULL into register P2. |
||
1203 | */ |
||
1204 | case OP_Null: |
||
1205 | { /* out2-prerelease */ |
||
1206 | pOut.flags = MEM_Null; |
||
1207 | break; |
||
1208 | } |
||
1209 | |||
1210 | |||
1211 | /* Opcode: Blob P1 P2 * P4 |
||
1212 | ** |
||
1213 | ** P4 points to a blob of data P1 bytes long. Store this |
||
1214 | ** blob in register P2. |
||
1215 | */ |
||
1216 | case OP_Blob: |
||
1217 | { /* out2-prerelease */ |
||
1218 | Debug.Assert( pOp.p1 <= db.aLimit[SQLITE_LIMIT_LENGTH] ); |
||
1219 | sqlite3VdbeMemSetStr( pOut, pOp.p4.z, pOp.p1, 0, null ); |
||
1220 | pOut.enc = encoding; |
||
1221 | #if SQLITE_TEST |
||
1222 | UPDATE_MAX_BLOBSIZE( pOut ); |
||
1223 | #endif |
||
1224 | break; |
||
1225 | } |
||
1226 | |||
1227 | /* Opcode: Variable P1 P2 * P4 * |
||
1228 | ** |
||
1229 | ** Transfer the values of bound parameter P1 into register P2 |
||
1230 | ** |
||
1231 | ** If the parameter is named, then its name appears in P4 and P3==1. |
||
1232 | ** The P4 value is used by sqlite3_bind_parameter_name(). |
||
1233 | */ |
||
1234 | case OP_Variable: |
||
1235 | { /* out2-prerelease */ |
||
1236 | Mem pVar; /* Value being transferred */ |
||
1237 | |||
1238 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 <= p.nVar ); |
||
1239 | Debug.Assert( pOp.p4.z == null || pOp.p4.z == p.azVar[pOp.p1 - 1] ); |
||
1240 | pVar = p.aVar[pOp.p1 - 1]; |
||
1241 | |||
1242 | if ( sqlite3VdbeMemTooBig( pVar ) ) |
||
1243 | { |
||
1244 | goto too_big; |
||
1245 | } |
||
1246 | sqlite3VdbeMemShallowCopy( pOut, pVar, MEM_Static ); |
||
1247 | #if SQLITE_TEST |
||
1248 | UPDATE_MAX_BLOBSIZE( pOut ); |
||
1249 | #endif |
||
1250 | break; |
||
1251 | } |
||
1252 | /* Opcode: Move P1 P2 P3 * * |
||
1253 | ** |
||
1254 | ** Move the values in register P1..P1+P3-1 over into |
||
1255 | ** registers P2..P2+P3-1. Registers P1..P1+P1-1 are |
||
1256 | ** left holding a NULL. It is an error for register ranges |
||
1257 | ** P1..P1+P3-1 and P2..P2+P3-1 to overlap. |
||
1258 | */ |
||
1259 | case OP_Move: |
||
1260 | { |
||
1261 | //char* zMalloc; /* Holding variable for allocated memory */ |
||
1262 | int n; /* Number of registers left to copy */ |
||
1263 | int p1; /* Register to copy from */ |
||
1264 | int p2; /* Register to copy to */ |
||
1265 | |||
1266 | n = pOp.p3; |
||
1267 | p1 = pOp.p1; |
||
1268 | p2 = pOp.p2; |
||
1269 | Debug.Assert( n > 0 && p1 > 0 && p2 > 0 ); |
||
1270 | Debug.Assert( p1 + n <= p2 || p2 + n <= p1 ); |
||
1271 | //pIn1 = aMem[p1]; |
||
1272 | //pOut = aMem[p2]; |
||
1273 | while ( n-- != 0 ) |
||
1274 | { |
||
1275 | pIn1 = aMem[p1 + pOp.p3 - n - 1]; |
||
1276 | pOut = aMem[p2]; |
||
1277 | //Debug.Assert( pOut<=&aMem[p.nMem] ); |
||
1278 | //Debug.Assert( pIn1<=&aMem[p.nMem] ); |
||
1279 | Debug.Assert( memIsValid( pIn1 ) ); |
||
1280 | memAboutToChange( p, pOut ); |
||
1281 | //zMalloc = pOut.zMalloc; |
||
1282 | //pOut.zMalloc = null; |
||
1283 | sqlite3VdbeMemMove( pOut, pIn1 ); |
||
1284 | //pIn1.zMalloc = zMalloc; |
||
1285 | REGISTER_TRACE( p, p2++, pOut ); |
||
1286 | //pIn1++; |
||
1287 | //pOut++; |
||
1288 | } |
||
1289 | break; |
||
1290 | } |
||
1291 | |||
1292 | /* Opcode: Copy P1 P2 * * * |
||
1293 | ** |
||
1294 | ** Make a copy of register P1 into register P2. |
||
1295 | ** |
||
1296 | ** This instruction makes a deep copy of the value. A duplicate |
||
1297 | ** is made of any string or blob constant. See also OP_SCopy. |
||
1298 | */ |
||
1299 | case OP_Copy: |
||
1300 | { /* in1, ref2 */ |
||
1301 | pIn1 = aMem[pOp.p1]; |
||
1302 | pOut = aMem[pOp.p2]; |
||
1303 | |||
1304 | Debug.Assert( pOut != pIn1 ); |
||
1305 | sqlite3VdbeMemShallowCopy( pOut, pIn1, MEM_Ephem ); |
||
1306 | if ( ( pOut.flags & MEM_Ephem ) != 0 && sqlite3VdbeMemMakeWriteable( pOut ) != 0 ) |
||
1307 | { |
||
1308 | goto no_mem; |
||
1309 | }//Deephemeralize( pOut ); |
||
1310 | REGISTER_TRACE( p, pOp.p2, pOut ); |
||
1311 | break; |
||
1312 | } |
||
1313 | |||
1314 | /* Opcode: SCopy P1 P2 * * * |
||
1315 | ** |
||
1316 | ** Make a shallow copy of register P1 into register P2. |
||
1317 | ** |
||
1318 | ** This instruction makes a shallow copy of the value. If the value |
||
1319 | ** is a string or blob, then the copy is only a pointer to the |
||
1320 | ** original and hence if the original changes so will the copy. |
||
1321 | ** Worse, if the original is deallocated, the copy becomes invalid. |
||
1322 | ** Thus the program must guarantee that the original will not change |
||
1323 | ** during the lifetime of the copy. Use OP_Copy to make a complete |
||
1324 | ** copy. |
||
1325 | */ |
||
1326 | case OP_SCopy: |
||
1327 | { /* in1, ref2 */ |
||
1328 | pIn1 = aMem[pOp.p1]; |
||
1329 | pOut = aMem[pOp.p2]; |
||
1330 | Debug.Assert( pOut != pIn1 ); |
||
1331 | sqlite3VdbeMemShallowCopy( pOut, pIn1, MEM_Ephem ); |
||
1332 | #if SQLITE_DEBUG |
||
1333 | if ( pOut.pScopyFrom == null ) |
||
1334 | pOut.pScopyFrom = pIn1; |
||
1335 | #endif |
||
1336 | REGISTER_TRACE( p, pOp.p2, pOut ); |
||
1337 | break; |
||
1338 | } |
||
1339 | |||
1340 | /* Opcode: ResultRow P1 P2 * * * |
||
1341 | ** |
||
1342 | ** The registers P1 through P1+P2-1 contain a single row of |
||
1343 | ** results. This opcode causes the sqlite3_step() call to terminate |
||
1344 | ** with an SQLITE_ROW return code and it sets up the sqlite3_stmt |
||
1345 | ** structure to provide access to the top P1 values as the result |
||
1346 | ** row. |
||
1347 | */ |
||
1348 | case OP_ResultRow: |
||
1349 | { |
||
1350 | //Mem[] pMem; |
||
1351 | int i; |
||
1352 | Debug.Assert( p.nResColumn == pOp.p2 ); |
||
1353 | Debug.Assert( pOp.p1 > 0 ); |
||
1354 | Debug.Assert( pOp.p1 + pOp.p2 <= p.nMem + 1 ); |
||
1355 | |||
1356 | /* If this statement has violated immediate foreign key constraints, do |
||
1357 | ** not return the number of rows modified. And do not RELEASE the statement |
||
1358 | ** transaction. It needs to be rolled back. */ |
||
1359 | if ( SQLITE_OK != ( rc = sqlite3VdbeCheckFk( p, 0 ) ) ) |
||
1360 | { |
||
1361 | Debug.Assert( ( db.flags & SQLITE_CountRows ) != 0 ); |
||
1362 | Debug.Assert( p.usesStmtJournal ); |
||
1363 | break; |
||
1364 | } |
||
1365 | |||
1366 | /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then |
||
1367 | ** DML statements invoke this opcode to return the number of rows |
||
1368 | ** modified to the user. This is the only way that a VM that |
||
1369 | ** opens a statement transaction may invoke this opcode. |
||
1370 | ** |
||
1371 | ** In case this is such a statement, close any statement transaction |
||
1372 | ** opened by this VM before returning control to the user. This is to |
||
1373 | ** ensure that statement-transactions are always nested, not overlapping. |
||
1374 | ** If the open statement-transaction is not closed here, then the user |
||
1375 | ** may step another VM that opens its own statement transaction. This |
||
1376 | ** may lead to overlapping statement transactions. |
||
1377 | ** |
||
1378 | ** The statement transaction is never a top-level transaction. Hence |
||
1379 | ** the RELEASE call below can never fail. |
||
1380 | */ |
||
1381 | Debug.Assert( p.iStatement == 0 || ( db.flags & SQLITE_CountRows ) != 0 ); |
||
1382 | rc = sqlite3VdbeCloseStatement( p, SAVEPOINT_RELEASE ); |
||
1383 | if ( NEVER( rc != SQLITE_OK ) ) |
||
1384 | { |
||
1385 | break; |
||
1386 | } |
||
1387 | |||
1388 | /* Invalidate all ephemeral cursor row caches */ |
||
1389 | p.cacheCtr = ( p.cacheCtr + 2 ) | 1; |
||
1390 | |||
1391 | /* Make sure the results of the current row are \000 terminated |
||
1392 | ** and have an assigned type. The results are de-ephemeralized as |
||
1393 | ** as side effect. |
||
1394 | */ |
||
1395 | //pMem = p.pResultSet = aMem[pOp.p1]; |
||
1396 | p.pResultSet = new Mem[pOp.p2]; |
||
1397 | for ( i = 0; i < pOp.p2; i++ ) |
||
1398 | { |
||
1399 | p.pResultSet[i] = aMem[pOp.p1 + i]; |
||
1400 | Debug.Assert( memIsValid( p.pResultSet[i] ) ); |
||
1401 | //Deephemeralize( p.pResultSet[i] ); |
||
1402 | //Debug.Assert( ( p.pResultSet[i].flags & MEM_Ephem ) == 0 |
||
1403 | // || ( p.pResultSet[i].flags & ( MEM_Str | MEM_Blob ) ) == 0 ); |
||
1404 | sqlite3VdbeMemNulTerminate( p.pResultSet[i] ); //sqlite3VdbeMemNulTerminate(pMem[i]); |
||
1405 | sqlite3VdbeMemStoreType( p.pResultSet[i] ); |
||
1406 | REGISTER_TRACE( p, pOp.p1 + i, p.pResultSet[i] ); |
||
1407 | } |
||
1408 | // if ( db.mallocFailed != 0 ) goto no_mem; |
||
1409 | |||
1410 | /* Return SQLITE_ROW |
||
1411 | */ |
||
1412 | p.pc = pc + 1; |
||
1413 | rc = SQLITE_ROW; |
||
1414 | goto vdbe_return; |
||
1415 | } |
||
1416 | |||
1417 | /* Opcode: Concat P1 P2 P3 * * |
||
1418 | ** |
||
1419 | ** Add the text in register P1 onto the end of the text in |
||
1420 | ** register P2 and store the result in register P3. |
||
1421 | ** If either the P1 or P2 text are NULL then store NULL in P3. |
||
1422 | ** |
||
1423 | ** P3 = P2 || P1 |
||
1424 | ** |
||
1425 | ** It is illegal for P1 and P3 to be the same register. Sometimes, |
||
1426 | ** if P3 is the same register as P2, the implementation is able |
||
1427 | ** to avoid a memcpy(). |
||
1428 | */ |
||
1429 | case OP_Concat: |
||
1430 | { /* same as TK_CONCAT, in1, in2, ref3 */ |
||
1431 | i64 nByte; |
||
1432 | |||
1433 | pIn1 = aMem[pOp.p1]; |
||
1434 | pIn2 = aMem[pOp.p2]; |
||
1435 | pOut = aMem[pOp.p3]; |
||
1436 | Debug.Assert( pIn1 != pOut ); |
||
1437 | if ( ( ( pIn1.flags | pIn2.flags ) & MEM_Null ) != 0 ) |
||
1438 | { |
||
1439 | sqlite3VdbeMemSetNull( pOut ); |
||
1440 | break; |
||
1441 | } |
||
1442 | ////if ( ExpandBlob( pIn1 ) != 0 || ExpandBlob( pIn2 ) != 0 ) |
||
1443 | //// goto no_mem; |
||
1444 | if ( ( ( pIn1.flags & ( MEM_Str | MEM_Blob ) ) == 0 ) && sqlite3VdbeMemStringify( pIn1, encoding ) != 0 ) |
||
1445 | { |
||
1446 | goto no_mem; |
||
1447 | }// Stringify(pIn1, encoding); |
||
1448 | if ( ( ( pIn2.flags & ( MEM_Str | MEM_Blob ) ) == 0 ) && sqlite3VdbeMemStringify( pIn2, encoding ) != 0 ) |
||
1449 | { |
||
1450 | goto no_mem; |
||
1451 | }// Stringify(pIn2, encoding); |
||
1452 | nByte = pIn1.n + pIn2.n; |
||
1453 | if ( nByte > db.aLimit[SQLITE_LIMIT_LENGTH] ) |
||
1454 | { |
||
1455 | goto too_big; |
||
1456 | } |
||
1457 | MemSetTypeFlag( pOut, MEM_Str ); |
||
1458 | //if ( sqlite3VdbeMemGrow( pOut, (int)nByte + 2, ( pOut == pIn2 ) ? 1 : 0 ) != 0 ) |
||
1459 | //{ |
||
1460 | // goto no_mem; |
||
1461 | //} |
||
1462 | //if ( pOut != pIn2 ) |
||
1463 | //{ |
||
1464 | // memcpy( pOut.z, pIn2.z, pIn2.n ); |
||
1465 | //} |
||
1466 | //memcpy( &pOut.z[pIn2.n], pIn1.z, pIn1.n ); |
||
1467 | if ( pIn2.z != null && pIn2.z.Length >= pIn2.n ) |
||
1468 | if ( pIn1.z != null ) |
||
1469 | pOut.z = pIn2.z.Substring( 0, pIn2.n ) + ( pIn1.n < pIn1.z.Length ? pIn1.z.Substring( 0, pIn1.n ) : pIn1.z ); |
||
1470 | else |
||
1471 | { |
||
1472 | if ( ( pIn1.flags & MEM_Blob ) == 0 ) //String as Blob |
||
1473 | { |
||
1474 | StringBuilder sb = new StringBuilder( pIn1.n ); |
||
1475 | for ( int i = 0; i < pIn1.n; i++ ) |
||
1476 | sb.Append( (byte)pIn1.zBLOB[i] ); |
||
1477 | pOut.z = pIn2.z.Substring( 0, pIn2.n ) + sb.ToString(); |
||
1478 | } |
||
1479 | else // UTF-8 Blob |
||
1480 | pOut.z = pIn2.z.Substring( 0, pIn2.n ) + Encoding.UTF8.GetString( pIn1.zBLOB, 0, pIn1.zBLOB.Length ); |
||
1481 | } |
||
1482 | else |
||
1483 | { |
||
1484 | pOut.zBLOB = sqlite3Malloc( pIn1.n + pIn2.n ); |
||
1485 | Buffer.BlockCopy( pIn2.zBLOB, 0, pOut.zBLOB, 0, pIn2.n ); |
||
1486 | if ( pIn1.zBLOB != null ) |
||
1487 | Buffer.BlockCopy( pIn1.zBLOB, 0, pOut.zBLOB, pIn2.n, pIn1.n ); |
||
1488 | else |
||
1489 | for ( int i = 0; i < pIn1.n; i++ ) |
||
1490 | pOut.zBLOB[pIn2.n + i] = (byte)pIn1.z[i]; |
||
1491 | } //pOut.z[nByte] = 0; |
||
1492 | //pOut.z[nByte + 1] = 0; |
||
1493 | pOut.flags |= MEM_Term; |
||
1494 | pOut.n = (int)nByte; |
||
1495 | pOut.enc = encoding; |
||
1496 | #if SQLITE_TEST |
||
1497 | UPDATE_MAX_BLOBSIZE( pOut ); |
||
1498 | #endif |
||
1499 | break; |
||
1500 | } |
||
1501 | |||
1502 | /* Opcode: Add P1 P2 P3 * * |
||
1503 | ** |
||
1504 | ** Add the value in register P1 to the value in register P2 |
||
1505 | ** and store the result in register P3. |
||
1506 | ** If either input is NULL, the result is NULL. |
||
1507 | */ |
||
1508 | /* Opcode: Multiply P1 P2 P3 * * |
||
1509 | ** |
||
1510 | ** |
||
1511 | ** Multiply the value in register P1 by the value in register P2 |
||
1512 | ** and store the result in register P3. |
||
1513 | ** If either input is NULL, the result is NULL. |
||
1514 | */ |
||
1515 | /* Opcode: Subtract P1 P2 P3 * * |
||
1516 | ** |
||
1517 | ** Subtract the value in register P1 from the value in register P2 |
||
1518 | ** and store the result in register P3. |
||
1519 | ** If either input is NULL, the result is NULL. |
||
1520 | */ |
||
1521 | /* Opcode: Divide P1 P2 P3 * * |
||
1522 | ** |
||
1523 | ** Divide the value in register P1 by the value in register P2 |
||
1524 | ** and store the result in register P3 (P3=P2/P1). If the value in |
||
1525 | ** register P1 is zero, then the result is NULL. If either input is |
||
1526 | ** NULL, the result is NULL. |
||
1527 | */ |
||
1528 | /* Opcode: Remainder P1 P2 P3 * * |
||
1529 | ** |
||
1530 | ** Compute the remainder after integer division of the value in |
||
1531 | ** register P1 by the value in register P2 and store the result in P3. |
||
1532 | ** If the value in register P2 is zero the result is NULL. |
||
1533 | ** If either operand is NULL, the result is NULL. |
||
1534 | */ |
||
1535 | case OP_Add: /* same as TK_PLUS, in1, in2, ref3 */ |
||
1536 | case OP_Subtract: /* same as TK_MINUS, in1, in2, ref3 */ |
||
1537 | case OP_Multiply: /* same as TK_STAR, in1, in2, ref3 */ |
||
1538 | case OP_Divide: /* same as TK_SLASH, in1, in2, ref3 */ |
||
1539 | case OP_Remainder: |
||
1540 | { /* same as TK_REM, in1, in2, ref3 */ |
||
1541 | int flags; /* Combined MEM_* flags from both inputs */ |
||
1542 | i64 iA; /* Integer value of left operand */ |
||
1543 | i64 iB = 0; /* Integer value of right operand */ |
||
1544 | double rA; /* Real value of left operand */ |
||
1545 | double rB; /* Real value of right operand */ |
||
1546 | |||
1547 | pIn1 = aMem[pOp.p1]; |
||
1548 | applyNumericAffinity( pIn1 ); |
||
1549 | pIn2 = aMem[pOp.p2]; |
||
1550 | applyNumericAffinity( pIn2 ); |
||
1551 | pOut = aMem[pOp.p3]; |
||
1552 | flags = pIn1.flags | pIn2.flags; |
||
1553 | if ( ( flags & MEM_Null ) != 0 ) |
||
1554 | goto arithmetic_result_is_null; |
||
1555 | bool fp_math; |
||
1556 | if ( !( fp_math = !( ( pIn1.flags & pIn2.flags & MEM_Int ) == MEM_Int ) ) ) |
||
1557 | { |
||
1558 | iA = pIn1.u.i; |
||
1559 | iB = pIn2.u.i; |
||
1560 | switch ( pOp.opcode ) |
||
1561 | { |
||
1562 | case OP_Add: |
||
1563 | { |
||
1564 | if ( sqlite3AddInt64( ref iB, iA ) != 0 ) |
||
1565 | fp_math = true; // goto fp_math |
||
1566 | break; |
||
1567 | } |
||
1568 | case OP_Subtract: |
||
1569 | { |
||
1570 | if ( sqlite3SubInt64( ref iB, iA ) != 0 ) |
||
1571 | fp_math = true; // goto fp_math |
||
1572 | break; |
||
1573 | } |
||
1574 | case OP_Multiply: |
||
1575 | { |
||
1576 | if ( sqlite3MulInt64( ref iB, iA ) != 0 ) |
||
1577 | fp_math = true; // goto fp_math |
||
1578 | break; |
||
1579 | } |
||
1580 | case OP_Divide: |
||
1581 | { |
||
1582 | if ( iA == 0 ) |
||
1583 | goto arithmetic_result_is_null; |
||
1584 | if ( iA == -1 && iB == SMALLEST_INT64 ) |
||
1585 | { |
||
1586 | fp_math = true; // goto fp_math |
||
1587 | break; |
||
1588 | } |
||
1589 | iB /= iA; |
||
1590 | break; |
||
1591 | } |
||
1592 | default: |
||
1593 | { |
||
1594 | if ( iA == 0 ) |
||
1595 | goto arithmetic_result_is_null; |
||
1596 | if ( iA == -1 ) |
||
1597 | iA = 1; |
||
1598 | iB %= iA; |
||
1599 | break; |
||
1600 | } |
||
1601 | } |
||
1602 | } |
||
1603 | if ( !fp_math ) |
||
1604 | { |
||
1605 | pOut.u.i = iB; |
||
1606 | MemSetTypeFlag( pOut, MEM_Int ); |
||
1607 | } |
||
1608 | else |
||
1609 | { |
||
1610 | //fp_math: |
||
1611 | rA = sqlite3VdbeRealValue( pIn1 ); |
||
1612 | rB = sqlite3VdbeRealValue( pIn2 ); |
||
1613 | switch ( pOp.opcode ) |
||
1614 | { |
||
1615 | case OP_Add: |
||
1616 | rB += rA; |
||
1617 | break; |
||
1618 | case OP_Subtract: |
||
1619 | rB -= rA; |
||
1620 | break; |
||
1621 | case OP_Multiply: |
||
1622 | rB *= rA; |
||
1623 | break; |
||
1624 | case OP_Divide: |
||
1625 | { |
||
1626 | /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ |
||
1627 | if ( rA == (double)0 ) |
||
1628 | goto arithmetic_result_is_null; |
||
1629 | rB /= rA; |
||
1630 | break; |
||
1631 | } |
||
1632 | default: |
||
1633 | { |
||
1634 | iA = (i64)rA; |
||
1635 | iB = (i64)rB; |
||
1636 | if ( iA == 0 ) |
||
1637 | goto arithmetic_result_is_null; |
||
1638 | if ( iA == -1 ) |
||
1639 | iA = 1; |
||
1640 | rB = (double)( iB % iA ); |
||
1641 | break; |
||
1642 | } |
||
1643 | } |
||
1644 | #if SQLITE_OMIT_FLOATING_POINT |
||
1645 | pOut->u.i = rB; |
||
1646 | MemSetTypeFlag(pOut, MEM_Int); |
||
1647 | #else |
||
1648 | if ( sqlite3IsNaN( rB ) ) |
||
1649 | { |
||
1650 | goto arithmetic_result_is_null; |
||
1651 | } |
||
1652 | pOut.r = rB; |
||
1653 | MemSetTypeFlag( pOut, MEM_Real ); |
||
1654 | if ( ( flags & MEM_Real ) == 0 ) |
||
1655 | { |
||
1656 | sqlite3VdbeIntegerAffinity( pOut ); |
||
1657 | } |
||
1658 | #endif |
||
1659 | } |
||
1660 | break; |
||
1661 | |||
1662 | arithmetic_result_is_null: |
||
1663 | sqlite3VdbeMemSetNull( pOut ); |
||
1664 | break; |
||
1665 | } |
||
1666 | |||
1667 | /* Opcode: CollSeq * * P4 |
||
1668 | ** |
||
1669 | ** P4 is a pointer to a CollSeq struct. If the next call to a user function |
||
1670 | ** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will |
||
1671 | ** be returned. This is used by the built-in min(), max() and nullif() |
||
1672 | ** functions. |
||
1673 | ** |
||
1674 | ** The interface used by the implementation of the aforementioned functions |
||
1675 | ** to retrieve the collation sequence set by this opcode is not available |
||
1676 | ** publicly, only to user functions defined in func.c. |
||
1677 | */ |
||
1678 | case OP_CollSeq: |
||
1679 | { |
||
1680 | Debug.Assert( pOp.p4type == P4_COLLSEQ ); |
||
1681 | break; |
||
1682 | } |
||
1683 | |||
1684 | /* Opcode: Function P1 P2 P3 P4 P5 |
||
1685 | ** |
||
1686 | ** Invoke a user function (P4 is a pointer to a Function structure that |
||
1687 | ** defines the function) with P5 arguments taken from register P2 and |
||
1688 | ** successors. The result of the function is stored in register P3. |
||
1689 | ** Register P3 must not be one of the function inputs. |
||
1690 | ** |
||
1691 | ** P1 is a 32-bit bitmask indicating whether or not each argument to the |
||
1692 | ** function was determined to be constant at compile time. If the first |
||
1693 | ** argument was constant then bit 0 of P1 is set. This is used to determine |
||
1694 | ** whether meta data associated with a user function argument using the |
||
1695 | ** sqlite3_set_auxdata() API may be safely retained until the next |
||
1696 | ** invocation of this opcode. |
||
1697 | ** |
||
1698 | ** See also: AggStep and AggFinal |
||
1699 | */ |
||
1700 | case OP_Function: |
||
1701 | { |
||
1702 | int i; |
||
1703 | Mem pArg; |
||
1704 | sqlite3_context ctx = new sqlite3_context(); |
||
1705 | sqlite3_value[] apVal; |
||
1706 | int n; |
||
1707 | |||
1708 | n = pOp.p5; |
||
1709 | apVal = p.apArg; |
||
1710 | Debug.Assert( apVal != null || n == 0 ); |
||
1711 | Debug.Assert( pOp.p3 > 0 && pOp.p3 <= p.nMem ); |
||
1712 | pOut = aMem[pOp.p3]; |
||
1713 | memAboutToChange( p, pOut ); |
||
1714 | |||
1715 | Debug.Assert( n == 0 || ( pOp.p2 > 0 && pOp.p2 + n <= p.nMem + 1 ) ); |
||
1716 | Debug.Assert( pOp.p3 < pOp.p2 || pOp.p3 >= pOp.p2 + n ); |
||
1717 | //pArg = aMem[pOp.p2]; |
||
1718 | for ( i = 0; i < n; i++ )//, pArg++) |
||
1719 | { |
||
1720 | pArg = aMem[pOp.p2 + i]; |
||
1721 | Debug.Assert( memIsValid( pArg ) ); |
||
1722 | apVal[i] = pArg; |
||
1723 | Deephemeralize( pArg ); |
||
1724 | sqlite3VdbeMemStoreType( pArg ); |
||
1725 | REGISTER_TRACE( p, pOp.p2 + i, pArg ); |
||
1726 | } |
||
1727 | |||
1728 | Debug.Assert( pOp.p4type == P4_FUNCDEF || pOp.p4type == P4_VDBEFUNC ); |
||
1729 | if ( pOp.p4type == P4_FUNCDEF ) |
||
1730 | { |
||
1731 | ctx.pFunc = pOp.p4.pFunc; |
||
1732 | ctx.pVdbeFunc = null; |
||
1733 | } |
||
1734 | else |
||
1735 | { |
||
1736 | ctx.pVdbeFunc = (VdbeFunc)pOp.p4.pVdbeFunc; |
||
1737 | ctx.pFunc = ctx.pVdbeFunc.pFunc; |
||
1738 | } |
||
1739 | |||
1740 | ctx.s.flags = MEM_Null; |
||
1741 | ctx.s.db = db; |
||
1742 | ctx.s.xDel = null; |
||
1743 | //ctx.s.zMalloc = null; |
||
1744 | |||
1745 | /* The output cell may already have a buffer allocated. Move |
||
1746 | ** the pointer to ctx.s so in case the user-function can use |
||
1747 | ** the already allocated buffer instead of allocating a new one. |
||
1748 | */ |
||
1749 | sqlite3VdbeMemMove( ctx.s, pOut ); |
||
1750 | MemSetTypeFlag( ctx.s, MEM_Null ); |
||
1751 | |||
1752 | ctx.isError = 0; |
||
1753 | if ( ( ctx.pFunc.flags & SQLITE_FUNC_NEEDCOLL ) != 0 ) |
||
1754 | { |
||
1755 | Debug.Assert( pc > 1 );//Debug.Assert(pOp > aOp); |
||
1756 | Debug.Assert( p.aOp[pc - 1].p4type == P4_COLLSEQ );//Debug.Assert(pOp[-1].p4type == P4_COLLSEQ); |
||
1757 | Debug.Assert( p.aOp[pc - 1].opcode == OP_CollSeq );//Debug.Assert(pOp[-1].opcode == OP_CollSeq); |
||
1758 | ctx.pColl = p.aOp[pc - 1].p4.pColl;//ctx.pColl = pOp[-1].p4.pColl; |
||
1759 | } |
||
1760 | db.lastRowid = lastRowid; |
||
1761 | ctx.pFunc.xFunc( ctx, n, apVal );///* IMP: R-24505-23230 */ |
||
1762 | lastRowid = db.lastRowid; |
||
1763 | |||
1764 | /* If any auxillary data functions have been called by this user function, |
||
1765 | ** immediately call the destructor for any non-static values. |
||
1766 | */ |
||
1767 | if ( ctx.pVdbeFunc != null ) |
||
1768 | { |
||
1769 | sqlite3VdbeDeleteAuxData( ctx.pVdbeFunc, pOp.p1 ); |
||
1770 | pOp.p4.pVdbeFunc = ctx.pVdbeFunc; |
||
1771 | pOp.p4type = P4_VDBEFUNC; |
||
1772 | } |
||
1773 | |||
1774 | //if ( db->mallocFailed ) |
||
1775 | //{ |
||
1776 | // /* Even though a malloc() has failed, the implementation of the |
||
1777 | // ** user function may have called an sqlite3_result_XXX() function |
||
1778 | // ** to return a value. The following call releases any resources |
||
1779 | // ** associated with such a value. |
||
1780 | // */ |
||
1781 | // sqlite3VdbeMemRelease( &u.ag.ctx.s ); |
||
1782 | // goto no_mem; |
||
1783 | //} |
||
1784 | |||
1785 | /* If the function returned an error, throw an exception */ |
||
1786 | if ( ctx.isError != 0 ) |
||
1787 | { |
||
1788 | sqlite3SetString( ref p.zErrMsg, db, sqlite3_value_text( ctx.s ) ); |
||
1789 | rc = ctx.isError; |
||
1790 | } |
||
1791 | |||
1792 | /* Copy the result of the function into register P3 */ |
||
1793 | sqlite3VdbeChangeEncoding( ctx.s, encoding ); |
||
1794 | sqlite3VdbeMemMove( pOut, ctx.s ); |
||
1795 | if ( sqlite3VdbeMemTooBig( pOut ) ) |
||
1796 | { |
||
1797 | goto too_big; |
||
1798 | } |
||
1799 | #if FALSE |
||
1800 | /* The app-defined function has done something that as caused this |
||
1801 | ** statement to expire. (Perhaps the function called sqlite3_exec() |
||
1802 | ** with a CREATE TABLE statement.) |
||
1803 | */ |
||
1804 | if( p.expired ) rc = SQLITE_ABORT; |
||
1805 | #endif |
||
1806 | |||
1807 | REGISTER_TRACE( p, pOp.p3, pOut ); |
||
1808 | #if SQLITE_TEST |
||
1809 | UPDATE_MAX_BLOBSIZE( pOut ); |
||
1810 | #endif |
||
1811 | break; |
||
1812 | } |
||
1813 | |||
1814 | /* Opcode: BitAnd P1 P2 P3 * * |
||
1815 | ** |
||
1816 | ** Take the bit-wise AND of the values in register P1 and P2 and |
||
1817 | ** store the result in register P3. |
||
1818 | ** If either input is NULL, the result is NULL. |
||
1819 | */ |
||
1820 | /* Opcode: BitOr P1 P2 P3 * * |
||
1821 | ** |
||
1822 | ** Take the bit-wise OR of the values in register P1 and P2 and |
||
1823 | ** store the result in register P3. |
||
1824 | ** If either input is NULL, the result is NULL. |
||
1825 | */ |
||
1826 | /* Opcode: ShiftLeft P1 P2 P3 * * |
||
1827 | ** |
||
1828 | ** Shift the integer value in register P2 to the left by the |
||
1829 | ** number of bits specified by the integer in register P1. |
||
1830 | ** Store the result in register P3. |
||
1831 | ** If either input is NULL, the result is NULL. |
||
1832 | */ |
||
1833 | /* Opcode: ShiftRight P1 P2 P3 * * |
||
1834 | ** |
||
1835 | ** Shift the integer value in register P2 to the right by the |
||
1836 | ** number of bits specified by the integer in register P1. |
||
1837 | ** Store the result in register P3. |
||
1838 | ** If either input is NULL, the result is NULL. |
||
1839 | */ |
||
1840 | case OP_BitAnd: /* same as TK_BITAND, in1, in2, ref3 */ |
||
1841 | case OP_BitOr: /* same as TK_BITOR, in1, in2, ref3 */ |
||
1842 | case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, ref3 */ |
||
1843 | case OP_ShiftRight: |
||
1844 | { /* same as TK_RSHIFT, in1, in2, ref3 */ |
||
1845 | i64 iA; |
||
1846 | u64 uA; |
||
1847 | i64 iB; |
||
1848 | u8 op; |
||
1849 | |||
1850 | pIn1 = aMem[pOp.p1]; |
||
1851 | pIn2 = aMem[pOp.p2]; |
||
1852 | pOut = aMem[pOp.p3]; |
||
1853 | if ( ( ( pIn1.flags | pIn2.flags ) & MEM_Null ) != 0 ) |
||
1854 | { |
||
1855 | sqlite3VdbeMemSetNull( pOut ); |
||
1856 | break; |
||
1857 | } |
||
1858 | iA = sqlite3VdbeIntValue( pIn2 ); |
||
1859 | iB = sqlite3VdbeIntValue( pIn1 ); |
||
1860 | op = pOp.opcode; |
||
1861 | if ( op == OP_BitAnd ) |
||
1862 | { |
||
1863 | iA &= iB; |
||
1864 | } |
||
1865 | else if ( op == OP_BitOr ) |
||
1866 | { |
||
1867 | iA |= iB; |
||
1868 | } |
||
1869 | else if ( iB != 0 ) |
||
1870 | { |
||
1871 | Debug.Assert( op == OP_ShiftRight || op == OP_ShiftLeft ); |
||
1872 | |||
1873 | /* If shifting by a negative amount, shift in the other direction */ |
||
1874 | if ( iB < 0 ) |
||
1875 | { |
||
1876 | Debug.Assert( OP_ShiftRight == OP_ShiftLeft + 1 ); |
||
1877 | op = (u8)( 2 * OP_ShiftLeft + 1 - op ); |
||
1878 | iB = iB > ( -64 ) ? -iB : 64; |
||
1879 | } |
||
1880 | |||
1881 | if ( iB >= 64 ) |
||
1882 | { |
||
1883 | iA = ( iA >= 0 || op == OP_ShiftLeft ) ? 0 : -1; |
||
1884 | } |
||
1885 | else |
||
1886 | { |
||
1887 | //uA = (ulong)(iA << 0); // memcpy( &uA, &iA, sizeof( uA ) ); |
||
1888 | if ( op == OP_ShiftLeft ) |
||
1889 | { |
||
1890 | iA = iA << (int)iB; |
||
1891 | } |
||
1892 | else |
||
1893 | { |
||
1894 | iA = iA >> (int)iB; |
||
1895 | /* Sign-extend on a right shift of a negative number */ |
||
1896 | //if ( iA < 0 ) |
||
1897 | // uA |= ( ( (0xffffffff ) << (u8)32 ) | 0xffffffff ) << (u8)( 64 - iB ); |
||
1898 | } |
||
1899 | //iA = (long)( uA << 0 ); //memcpy( &iA, &uA, sizeof( iA ) ); |
||
1900 | } |
||
1901 | } |
||
1902 | pOut.u.i = iA; |
||
1903 | MemSetTypeFlag( pOut, MEM_Int ); |
||
1904 | break; |
||
1905 | } |
||
1906 | |||
1907 | /* Opcode: AddImm P1 P2 * * * |
||
1908 | ** |
||
1909 | ** Add the constant P2 to the value in register P1. |
||
1910 | ** The result is always an integer. |
||
1911 | ** |
||
1912 | ** To force any register to be an integer, just add 0. |
||
1913 | */ |
||
1914 | case OP_AddImm: |
||
1915 | { /* in1 */ |
||
1916 | pIn1 = aMem[pOp.p1]; |
||
1917 | memAboutToChange( p, pIn1 ); |
||
1918 | sqlite3VdbeMemIntegerify( pIn1 ); |
||
1919 | pIn1.u.i += pOp.p2; |
||
1920 | break; |
||
1921 | } |
||
1922 | |||
1923 | /* Opcode: MustBeInt P1 P2 * * * |
||
1924 | ** |
||
1925 | ** Force the value in register P1 to be an integer. If the value |
||
1926 | ** in P1 is not an integer and cannot be converted into an integer |
||
1927 | ** without data loss, then jump immediately to P2, or if P2==0 |
||
1928 | ** raise an SQLITE_MISMATCH exception. |
||
1929 | */ |
||
1930 | case OP_MustBeInt: |
||
1931 | { /* jump, in1 */ |
||
1932 | pIn1 = aMem[pOp.p1]; |
||
1933 | applyAffinity( pIn1, SQLITE_AFF_NUMERIC, encoding ); |
||
1934 | if ( ( pIn1.flags & MEM_Int ) == 0 ) |
||
1935 | { |
||
1936 | if ( pOp.p2 == 0 ) |
||
1937 | { |
||
1938 | rc = SQLITE_MISMATCH; |
||
1939 | goto abort_due_to_error; |
||
1940 | } |
||
1941 | else |
||
1942 | { |
||
1943 | pc = pOp.p2 - 1; |
||
1944 | } |
||
1945 | } |
||
1946 | else |
||
1947 | { |
||
1948 | MemSetTypeFlag( pIn1, MEM_Int ); |
||
1949 | } |
||
1950 | break; |
||
1951 | } |
||
1952 | |||
1953 | #if !SQLITE_OMIT_FLOATING_POINT |
||
1954 | /* Opcode: RealAffinity P1 * * * * |
||
1955 | ** |
||
1956 | ** If register P1 holds an integer convert it to a real value. |
||
1957 | ** |
||
1958 | ** This opcode is used when extracting information from a column that |
||
1959 | ** has REAL affinity. Such column values may still be stored as |
||
1960 | ** integers, for space efficiency, but after extraction we want them |
||
1961 | ** to have only a real value. |
||
1962 | */ |
||
1963 | case OP_RealAffinity: |
||
1964 | { /* in1 */ |
||
1965 | pIn1 = aMem[pOp.p1]; |
||
1966 | if ( ( pIn1.flags & MEM_Int ) != 0 ) |
||
1967 | { |
||
1968 | sqlite3VdbeMemRealify( pIn1 ); |
||
1969 | } |
||
1970 | break; |
||
1971 | } |
||
1972 | #endif |
||
1973 | |||
1974 | #if !SQLITE_OMIT_CAST |
||
1975 | /* Opcode: ToText P1 * * * * |
||
1976 | ** |
||
1977 | ** Force the value in register P1 to be text. |
||
1978 | ** If the value is numeric, convert it to a string using the |
||
1979 | ** equivalent of printf(). Blob values are unchanged and |
||
1980 | ** are afterwards simply interpreted as text. |
||
1981 | ** |
||
1982 | ** A NULL value is not changed by this routine. It remains NULL. |
||
1983 | */ |
||
1984 | case OP_ToText: |
||
1985 | { /* same as TK_TO_TEXT, in1 */ |
||
1986 | pIn1 = aMem[pOp.p1]; |
||
1987 | memAboutToChange( p, pIn1 ); |
||
1988 | if ( ( pIn1.flags & MEM_Null ) != 0 ) |
||
1989 | break; |
||
1990 | Debug.Assert( MEM_Str == ( MEM_Blob >> 3 ) ); |
||
1991 | pIn1.flags |= (u16)( ( pIn1.flags & MEM_Blob ) >> 3 ); |
||
1992 | applyAffinity( pIn1, SQLITE_AFF_TEXT, encoding ); |
||
1993 | rc = 0; ////ExpandBlob( pIn1 ); |
||
1994 | Debug.Assert( ( pIn1.flags & MEM_Str ) != 0 /*|| db.mallocFailed != 0 */ ); |
||
1995 | pIn1.flags = (u16)( pIn1.flags & ~( MEM_Int | MEM_Real | MEM_Blob | MEM_Zero ) ); |
||
1996 | #if SQLITE_TEST |
||
1997 | UPDATE_MAX_BLOBSIZE( pIn1 ); |
||
1998 | #endif |
||
1999 | break; |
||
2000 | } |
||
2001 | |||
2002 | /* Opcode: ToBlob P1 * * * * |
||
2003 | ** |
||
2004 | ** Force the value in register P1 to be a BLOB. |
||
2005 | ** If the value is numeric, convert it to a string first. |
||
2006 | ** Strings are simply reinterpreted as blobs with no change |
||
2007 | ** to the underlying data. |
||
2008 | ** |
||
2009 | ** A NULL value is not changed by this routine. It remains NULL. |
||
2010 | */ |
||
2011 | case OP_ToBlob: |
||
2012 | { /* same as TK_TO_BLOB, in1 */ |
||
2013 | pIn1 = aMem[pOp.p1]; |
||
2014 | if ( ( pIn1.flags & MEM_Null ) != 0 ) |
||
2015 | break; |
||
2016 | if ( ( pIn1.flags & MEM_Blob ) == 0 ) |
||
2017 | { |
||
2018 | applyAffinity( pIn1, SQLITE_AFF_TEXT, encoding ); |
||
2019 | Debug.Assert( ( pIn1.flags & MEM_Str ) != 0 /*|| db.mallocFailed != 0 */ ); |
||
2020 | MemSetTypeFlag( pIn1, MEM_Blob ); |
||
2021 | } |
||
2022 | else |
||
2023 | { |
||
2024 | pIn1.flags = (ushort)( pIn1.flags & ~( MEM_TypeMask & ~MEM_Blob ) ); |
||
2025 | } |
||
2026 | #if SQLITE_TEST |
||
2027 | UPDATE_MAX_BLOBSIZE( pIn1 ); |
||
2028 | #endif |
||
2029 | break; |
||
2030 | } |
||
2031 | |||
2032 | /* Opcode: ToNumeric P1 * * * * |
||
2033 | ** |
||
2034 | ** Force the value in register P1 to be numeric (either an |
||
2035 | ** integer or a floating-point number.) |
||
2036 | ** If the value is text or blob, try to convert it to an using the |
||
2037 | ** equivalent of atoi() or atof() and store 0 if no such conversion |
||
2038 | ** is possible. |
||
2039 | ** |
||
2040 | ** A NULL value is not changed by this routine. It remains NULL. |
||
2041 | */ |
||
2042 | case OP_ToNumeric: |
||
2043 | { /* same as TK_TO_NUMERIC, in1 */ |
||
2044 | pIn1 = aMem[pOp.p1]; |
||
2045 | sqlite3VdbeMemNumerify( pIn1 ); |
||
2046 | break; |
||
2047 | } |
||
2048 | #endif // * SQLITE_OMIT_CAST */ |
||
2049 | |||
2050 | /* Opcode: ToInt P1 * * * * |
||
2051 | ** |
||
2052 | ** Force the value in register P1 to be an integer. If |
||
2053 | ** The value is currently a real number, drop its fractional part. |
||
2054 | ** If the value is text or blob, try to convert it to an integer using the |
||
2055 | ** equivalent of atoi() and store 0 if no such conversion is possible. |
||
2056 | ** |
||
2057 | ** A NULL value is not changed by this routine. It remains NULL. |
||
2058 | */ |
||
2059 | case OP_ToInt: |
||
2060 | { /* same as TK_TO_INT, in1 */ |
||
2061 | pIn1 = aMem[pOp.p1]; |
||
2062 | if ( ( pIn1.flags & MEM_Null ) == 0 ) |
||
2063 | { |
||
2064 | sqlite3VdbeMemIntegerify( pIn1 ); |
||
2065 | } |
||
2066 | break; |
||
2067 | } |
||
2068 | |||
2069 | #if !(SQLITE_OMIT_CAST) && !(SQLITE_OMIT_FLOATING_POINT) |
||
2070 | /* Opcode: ToReal P1 * * * * |
||
2071 | ** |
||
2072 | ** Force the value in register P1 to be a floating point number. |
||
2073 | ** If The value is currently an integer, convert it. |
||
2074 | ** If the value is text or blob, try to convert it to an integer using the |
||
2075 | ** equivalent of atoi() and store 0.0 if no such conversion is possible. |
||
2076 | ** |
||
2077 | ** A NULL value is not changed by this routine. It remains NULL. |
||
2078 | */ |
||
2079 | case OP_ToReal: |
||
2080 | { /* same as TK_TO_REAL, in1 */ |
||
2081 | pIn1 = aMem[pOp.p1]; |
||
2082 | memAboutToChange( p, pIn1 ); |
||
2083 | if ( ( pIn1.flags & MEM_Null ) == 0 ) |
||
2084 | { |
||
2085 | sqlite3VdbeMemRealify( pIn1 ); |
||
2086 | } |
||
2087 | break; |
||
2088 | } |
||
2089 | #endif //* !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT) */ |
||
2090 | |||
2091 | /* Opcode: Lt P1 P2 P3 P4 P5 |
||
2092 | ** |
||
2093 | ** Compare the values in register P1 and P3. If reg(P3)<reg(P1) then |
||
2094 | ** jump to address P2. |
||
2095 | ** |
||
2096 | ** If the SQLITE_JUMPIFNULL bit of P5 is set and either reg(P1) or |
||
2097 | ** reg(P3) is NULL then take the jump. If the SQLITE_JUMPIFNULL |
||
2098 | ** bit is clear then fall through if either operand is NULL. |
||
2099 | ** |
||
2100 | ** The SQLITE_AFF_MASK portion of P5 must be an affinity character - |
||
2101 | ** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made |
||
2102 | ** to coerce both inputs according to this affinity before the |
||
2103 | ** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric |
||
2104 | ** affinity is used. Note that the affinity conversions are stored |
||
2105 | ** back into the input registers P1 and P3. So this opcode can cause |
||
2106 | ** persistent changes to registers P1 and P3. |
||
2107 | ** |
||
2108 | ** Once any conversions have taken place, and neither value is NULL, |
||
2109 | ** the values are compared. If both values are blobs then memcmp() is |
||
2110 | ** used to determine the results of the comparison. If both values |
||
2111 | ** are text, then the appropriate collating function specified in |
||
2112 | ** P4 is used to do the comparison. If P4 is not specified then |
||
2113 | ** memcmp() is used to compare text string. If both values are |
||
2114 | ** numeric, then a numeric comparison is used. If the two values |
||
2115 | ** are of different types, then numbers are considered less than |
||
2116 | ** strings and strings are considered less than blobs. |
||
2117 | ** |
||
2118 | ** If the SQLITE_STOREP2 bit of P5 is set, then do not jump. Instead, |
||
2119 | ** store a boolean result (either 0, or 1, or NULL) in register P2. |
||
2120 | */ |
||
2121 | /* Opcode: Ne P1 P2 P3 P4 P5 |
||
2122 | ** |
||
2123 | ** This works just like the Lt opcode except that the jump is taken if |
||
2124 | ** the operands in registers P1 and P3 are not equal. See the Lt opcode for |
||
2125 | ** additional information. |
||
2126 | ** |
||
2127 | ** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either |
||
2128 | ** true or false and is never NULL. If both operands are NULL then the result |
||
2129 | ** of comparison is false. If either operand is NULL then the result is true. |
||
2130 | ** If neither operand is NULL the result is the same as it would be if |
||
2131 | ** the SQLITE_NULLEQ flag were omitted from P5. |
||
2132 | */ |
||
2133 | /* Opcode: Eq P1 P2 P3 P4 P5 |
||
2134 | ** |
||
2135 | ** This works just like the Lt opcode except that the jump is taken if |
||
2136 | ** the operands in registers P1 and P3 are equal. |
||
2137 | ** See the Lt opcode for additional information. |
||
2138 | ** |
||
2139 | ** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either |
||
2140 | ** true or false and is never NULL. If both operands are NULL then the result |
||
2141 | ** of comparison is true. If either operand is NULL then the result is false. |
||
2142 | ** If neither operand is NULL the result is the same as it would be if |
||
2143 | ** the SQLITE_NULLEQ flag were omitted from P5. |
||
2144 | */ |
||
2145 | /* Opcode: Le P1 P2 P3 P4 P5 |
||
2146 | ** |
||
2147 | ** This works just like the Lt opcode except that the jump is taken if |
||
2148 | ** the content of register P3 is less than or equal to the content of |
||
2149 | ** register P1. See the Lt opcode for additional information. |
||
2150 | */ |
||
2151 | /* Opcode: Gt P1 P2 P3 P4 P5 |
||
2152 | ** |
||
2153 | ** This works just like the Lt opcode except that the jump is taken if |
||
2154 | ** the content of register P3 is greater than the content of |
||
2155 | ** register P1. See the Lt opcode for additional information. |
||
2156 | */ |
||
2157 | /* Opcode: Ge P1 P2 P3 P4 P5 |
||
2158 | ** |
||
2159 | ** This works just like the Lt opcode except that the jump is taken if |
||
2160 | ** the content of register P3 is greater than or equal to the content of |
||
2161 | ** register P1. See the Lt opcode for additional information. |
||
2162 | */ |
||
2163 | case OP_Eq: /* same as TK_EQ, jump, in1, in3 */ |
||
2164 | case OP_Ne: /* same as TK_NE, jump, in1, in3 */ |
||
2165 | case OP_Lt: /* same as TK_LT, jump, in1, in3 */ |
||
2166 | case OP_Le: /* same as TK_LE, jump, in1, in3 */ |
||
2167 | case OP_Gt: /* same as TK_GT, jump, in1, in3 */ |
||
2168 | case OP_Ge: |
||
2169 | { /* same as TK_GE, jump, in1, in3 */ |
||
2170 | int res = 0; /* Result of the comparison of pIn1 against pIn3 */ |
||
2171 | char affinity; /* Affinity to use for comparison */ |
||
2172 | u16 flags1; /* Copy of initial value of pIn1->flags */ |
||
2173 | u16 flags3; /* Copy of initial value of pIn3->flags */ |
||
2174 | pIn1 = aMem[pOp.p1]; |
||
2175 | pIn3 = aMem[pOp.p3]; |
||
2176 | flags1 = pIn1.flags; |
||
2177 | flags3 = pIn3.flags; |
||
2178 | if ( ( ( pIn1.flags | pIn3.flags ) & MEM_Null ) != 0 ) |
||
2179 | { |
||
2180 | /* One or both operands are NULL */ |
||
2181 | if ( ( pOp.p5 & SQLITE_NULLEQ ) != 0 ) |
||
2182 | { |
||
2183 | /* If SQLITE_NULLEQ is set (which will only happen if the operator is |
||
2184 | ** OP_Eq or OP_Ne) then take the jump or not depending on whether |
||
2185 | ** or not both operands are null. |
||
2186 | */ |
||
2187 | Debug.Assert( pOp.opcode == OP_Eq || pOp.opcode == OP_Ne ); |
||
2188 | res = ( pIn1.flags & pIn3.flags & MEM_Null ) == 0 ? 1 : 0; |
||
2189 | } |
||
2190 | else |
||
2191 | { |
||
2192 | /* SQLITE_NULLEQ is clear and at least one operand is NULL, |
||
2193 | ** then the result is always NULL. |
||
2194 | ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. |
||
2195 | */ |
||
2196 | if ( ( pOp.p5 & SQLITE_STOREP2 ) != 0 ) |
||
2197 | { |
||
2198 | pOut = aMem[pOp.p2]; |
||
2199 | MemSetTypeFlag( pOut, MEM_Null ); |
||
2200 | REGISTER_TRACE( p, pOp.p2, pOut ); |
||
2201 | } |
||
2202 | else if ( ( pOp.p5 & SQLITE_JUMPIFNULL ) != 0 ) |
||
2203 | { |
||
2204 | pc = pOp.p2 - 1; |
||
2205 | } |
||
2206 | break; |
||
2207 | } |
||
2208 | |||
2209 | } |
||
2210 | else |
||
2211 | { |
||
2212 | /* Neither operand is NULL. Do a comparison. */ |
||
2213 | affinity = (char)( pOp.p5 & SQLITE_AFF_MASK ); |
||
2214 | if ( affinity != '\0' ) |
||
2215 | { |
||
2216 | applyAffinity( pIn1, affinity, encoding ); |
||
2217 | applyAffinity( pIn3, affinity, encoding ); |
||
2218 | // if ( db.mallocFailed != 0 ) goto no_mem; |
||
2219 | } |
||
2220 | |||
2221 | Debug.Assert( pOp.p4type == P4_COLLSEQ || pOp.p4.pColl == null ); |
||
2222 | ////ExpandBlob( pIn1 ); |
||
2223 | ////ExpandBlob( pIn3 ); |
||
2224 | res = sqlite3MemCompare( pIn3, pIn1, pOp.p4.pColl ); |
||
2225 | } |
||
2226 | switch ( pOp.opcode ) |
||
2227 | { |
||
2228 | case OP_Eq: |
||
2229 | res = ( res == 0 ) ? 1 : 0; |
||
2230 | break; |
||
2231 | case OP_Ne: |
||
2232 | res = ( res != 0 ) ? 1 : 0; |
||
2233 | break; |
||
2234 | case OP_Lt: |
||
2235 | res = ( res < 0 ) ? 1 : 0; |
||
2236 | break; |
||
2237 | case OP_Le: |
||
2238 | res = ( res <= 0 ) ? 1 : 0; |
||
2239 | break; |
||
2240 | case OP_Gt: |
||
2241 | res = ( res > 0 ) ? 1 : 0; |
||
2242 | break; |
||
2243 | default: |
||
2244 | res = ( res >= 0 ) ? 1 : 0; |
||
2245 | break; |
||
2246 | } |
||
2247 | |||
2248 | if ( ( pOp.p5 & SQLITE_STOREP2 ) != 0 ) |
||
2249 | { |
||
2250 | pOut = aMem[pOp.p2]; |
||
2251 | memAboutToChange( p, pOut ); |
||
2252 | MemSetTypeFlag( pOut, MEM_Int ); |
||
2253 | pOut.u.i = res; |
||
2254 | REGISTER_TRACE( p, pOp.p2, pOut ); |
||
2255 | } |
||
2256 | else if ( res != 0 ) |
||
2257 | { |
||
2258 | pc = pOp.p2 - 1; |
||
2259 | } |
||
2260 | |||
2261 | /* Undo any changes made by applyAffinity() to the input registers. */ |
||
2262 | pIn1.flags = (u16)( ( pIn1.flags & ~MEM_TypeMask ) | ( flags1 & MEM_TypeMask ) ); |
||
2263 | pIn3.flags = (u16)( ( pIn3.flags & ~MEM_TypeMask ) | ( flags3 & MEM_TypeMask ) ); |
||
2264 | break; |
||
2265 | } |
||
2266 | |||
2267 | /* Opcode: Permutation * * * P4 * |
||
2268 | ** |
||
2269 | ** Set the permutation used by the OP_Compare operator to be the array |
||
2270 | ** of integers in P4. |
||
2271 | ** |
||
2272 | ** The permutation is only valid until the next OP_Permutation, OP_Compare, |
||
2273 | ** OP_Halt, or OP_ResultRow. Typically the OP_Permutation should occur |
||
2274 | ** immediately prior to the OP_Compare. |
||
2275 | */ |
||
2276 | case OP_Permutation: |
||
2277 | { |
||
2278 | Debug.Assert( pOp.p4type == P4_INTARRAY ); |
||
2279 | Debug.Assert( pOp.p4.ai != null ); |
||
2280 | aPermute = pOp.p4.ai; |
||
2281 | break; |
||
2282 | } |
||
2283 | |||
2284 | /* Opcode: Compare P1 P2 P3 P4 * |
||
2285 | ** |
||
2286 | ** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this |
||
2287 | ** vector "A") and in reg(P2)..reg(P2+P3-1) ("B"). Save the result of |
||
2288 | ** the comparison for use by the next OP_Jump instruct. |
||
2289 | ** |
||
2290 | ** P4 is a KeyInfo structure that defines collating sequences and sort |
||
2291 | ** orders for the comparison. The permutation applies to registers |
||
2292 | ** only. The KeyInfo elements are used sequentially. |
||
2293 | ** |
||
2294 | ** The comparison is a sort comparison, so NULLs compare equal, |
||
2295 | ** NULLs are less than numbers, numbers are less than strings, |
||
2296 | ** and strings are less than blobs. |
||
2297 | */ |
||
2298 | case OP_Compare: |
||
2299 | { |
||
2300 | int n; |
||
2301 | int i; |
||
2302 | int p1; |
||
2303 | int p2; |
||
2304 | KeyInfo pKeyInfo; |
||
2305 | int idx; |
||
2306 | CollSeq pColl; /* Collating sequence to use on this term */ |
||
2307 | int bRev; /* True for DESCENDING sort order */ |
||
2308 | |||
2309 | n = pOp.p3; |
||
2310 | pKeyInfo = pOp.p4.pKeyInfo; |
||
2311 | Debug.Assert( n > 0 ); |
||
2312 | Debug.Assert( pKeyInfo != null ); |
||
2313 | p1 = pOp.p1; |
||
2314 | p2 = pOp.p2; |
||
2315 | #if SQLITE_DEBUG |
||
2316 | if ( aPermute != null ) |
||
2317 | { |
||
2318 | int k, mx = 0; |
||
2319 | for ( k = 0; k < n; k++ ) |
||
2320 | if ( aPermute[k] > mx ) |
||
2321 | mx = aPermute[k]; |
||
2322 | Debug.Assert( p1 > 0 && p1 + mx <= p.nMem + 1 ); |
||
2323 | Debug.Assert( p2 > 0 && p2 + mx <= p.nMem + 1 ); |
||
2324 | } |
||
2325 | else |
||
2326 | { |
||
2327 | Debug.Assert( p1 > 0 && p1 + n <= p.nMem + 1 ); |
||
2328 | Debug.Assert( p2 > 0 && p2 + n <= p.nMem + 1 ); |
||
2329 | } |
||
2330 | #endif //* SQLITE_DEBUG */ |
||
2331 | for ( i = 0; i < n; i++ ) |
||
2332 | { |
||
2333 | idx = aPermute != null ? aPermute[i] : i; |
||
2334 | Debug.Assert( memIsValid( aMem[p1 + idx] ) ); |
||
2335 | Debug.Assert( memIsValid( aMem[p2 + idx] ) ); |
||
2336 | REGISTER_TRACE( p, p1 + idx, aMem[p1 + idx] ); |
||
2337 | REGISTER_TRACE( p, p2 + idx, aMem[p2 + idx] ); |
||
2338 | Debug.Assert( i < pKeyInfo.nField ); |
||
2339 | pColl = pKeyInfo.aColl[i]; |
||
2340 | bRev = pKeyInfo.aSortOrder[i]; |
||
2341 | iCompare = sqlite3MemCompare( aMem[p1 + idx], aMem[p2 + idx], pColl ); |
||
2342 | if ( iCompare != 0 ) |
||
2343 | { |
||
2344 | if ( bRev != 0 ) |
||
2345 | iCompare = -iCompare; |
||
2346 | break; |
||
2347 | } |
||
2348 | } |
||
2349 | aPermute = null; |
||
2350 | break; |
||
2351 | } |
||
2352 | |||
2353 | /* Opcode: Jump P1 P2 P3 * * |
||
2354 | ** |
||
2355 | ** Jump to the instruction at address P1, P2, or P3 depending on whether |
||
2356 | ** in the most recent OP_Compare instruction the P1 vector was less than |
||
2357 | ** equal to, or greater than the P2 vector, respectively. |
||
2358 | */ |
||
2359 | case OP_Jump: |
||
2360 | { /* jump */ |
||
2361 | if ( iCompare < 0 ) |
||
2362 | { |
||
2363 | pc = pOp.p1 - 1; |
||
2364 | } |
||
2365 | else if ( iCompare == 0 ) |
||
2366 | { |
||
2367 | pc = pOp.p2 - 1; |
||
2368 | } |
||
2369 | else |
||
2370 | { |
||
2371 | pc = pOp.p3 - 1; |
||
2372 | } |
||
2373 | break; |
||
2374 | } |
||
2375 | /* Opcode: And P1 P2 P3 * * |
||
2376 | ** |
||
2377 | ** Take the logical AND of the values in registers P1 and P2 and |
||
2378 | ** write the result into register P3. |
||
2379 | ** |
||
2380 | ** If either P1 or P2 is 0 (false) then the result is 0 even if |
||
2381 | ** the other input is NULL. A NULL and true or two NULLs give |
||
2382 | ** a NULL output. |
||
2383 | */ |
||
2384 | /* Opcode: Or P1 P2 P3 * * |
||
2385 | ** |
||
2386 | ** Take the logical OR of the values in register P1 and P2 and |
||
2387 | ** store the answer in register P3. |
||
2388 | ** |
||
2389 | ** If either P1 or P2 is nonzero (true) then the result is 1 (true) |
||
2390 | ** even if the other input is NULL. A NULL and false or two NULLs |
||
2391 | ** give a NULL output. |
||
2392 | */ |
||
2393 | case OP_And: /* same as TK_AND, in1, in2, ref3 */ |
||
2394 | case OP_Or: |
||
2395 | { /* same as TK_OR, in1, in2, ref3 */ |
||
2396 | int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ |
||
2397 | int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ |
||
2398 | |||
2399 | pIn1 = aMem[pOp.p1]; |
||
2400 | if ( ( pIn1.flags & MEM_Null ) != 0 ) |
||
2401 | { |
||
2402 | v1 = 2; |
||
2403 | } |
||
2404 | else |
||
2405 | { |
||
2406 | v1 = ( sqlite3VdbeIntValue( pIn1 ) != 0 ) ? 1 : 0; |
||
2407 | } |
||
2408 | pIn2 = aMem[pOp.p2]; |
||
2409 | if ( ( pIn2.flags & MEM_Null ) != 0 ) |
||
2410 | { |
||
2411 | v2 = 2; |
||
2412 | } |
||
2413 | else |
||
2414 | { |
||
2415 | v2 = ( sqlite3VdbeIntValue( pIn2 ) != 0 ) ? 1 : 0; |
||
2416 | } |
||
2417 | if ( pOp.opcode == OP_And ) |
||
2418 | { |
||
2419 | byte[] and_logic = new byte[] { 0, 0, 0, 0, 1, 2, 0, 2, 2 }; |
||
2420 | v1 = and_logic[v1 * 3 + v2]; |
||
2421 | } |
||
2422 | else |
||
2423 | { |
||
2424 | byte[] or_logic = new byte[] { 0, 1, 2, 1, 1, 1, 2, 1, 2 }; |
||
2425 | v1 = or_logic[v1 * 3 + v2]; |
||
2426 | } |
||
2427 | pOut = aMem[pOp.p3]; |
||
2428 | if ( v1 == 2 ) |
||
2429 | { |
||
2430 | MemSetTypeFlag( pOut, MEM_Null ); |
||
2431 | } |
||
2432 | else |
||
2433 | { |
||
2434 | pOut.u.i = v1; |
||
2435 | MemSetTypeFlag( pOut, MEM_Int ); |
||
2436 | } |
||
2437 | break; |
||
2438 | } |
||
2439 | |||
2440 | /* Opcode: Not P1 P2 * * * |
||
2441 | ** |
||
2442 | ** Interpret the value in register P1 as a boolean value. Store the |
||
2443 | ** boolean complement in register P2. If the value in register P1 is |
||
2444 | ** NULL, then a NULL is stored in P2. |
||
2445 | */ |
||
2446 | case OP_Not: |
||
2447 | { /* same as TK_NOT, in1 */ |
||
2448 | pIn1 = aMem[pOp.p1]; |
||
2449 | pOut = aMem[pOp.p2]; |
||
2450 | if ( ( pIn1.flags & MEM_Null ) != 0 ) |
||
2451 | { |
||
2452 | sqlite3VdbeMemSetNull( pOut ); |
||
2453 | } |
||
2454 | else |
||
2455 | { |
||
2456 | sqlite3VdbeMemSetInt64( pOut, sqlite3VdbeIntValue( pIn1 ) == 0 ? 1 : 0 ); |
||
2457 | } |
||
2458 | break; |
||
2459 | } |
||
2460 | |||
2461 | /* Opcode: BitNot P1 P2 * * * |
||
2462 | ** |
||
2463 | ** Interpret the content of register P1 as an integer. Store the |
||
2464 | ** ones-complement of the P1 value into register P2. If P1 holds |
||
2465 | ** a NULL then store a NULL in P2. |
||
2466 | */ |
||
2467 | case OP_BitNot: |
||
2468 | { /* same as TK_BITNOT, in1 */ |
||
2469 | pIn1 = aMem[pOp.p1]; |
||
2470 | pOut = aMem[pOp.p2]; |
||
2471 | if ( ( pIn1.flags & MEM_Null ) != 0 ) |
||
2472 | { |
||
2473 | sqlite3VdbeMemSetNull( pOut ); |
||
2474 | } |
||
2475 | else |
||
2476 | { |
||
2477 | sqlite3VdbeMemSetInt64( pOut, ~sqlite3VdbeIntValue( pIn1 ) ); |
||
2478 | } |
||
2479 | break; |
||
2480 | } |
||
2481 | |||
2482 | /* Opcode: If P1 P2 P3 * * |
||
2483 | ** |
||
2484 | ** Jump to P2 if the value in register P1 is true. The value |
||
2485 | ** is considered true if it is numeric and non-zero. If the value |
||
2486 | ** in P1 is NULL then take the jump if P3 is true. |
||
2487 | */ |
||
2488 | /* Opcode: IfNot P1 P2 P3 * * |
||
2489 | ** |
||
2490 | ** Jump to P2 if the value in register P1 is False. The value |
||
2491 | ** is considered true if it has a numeric value of zero. If the value |
||
2492 | ** in P1 is NULL then take the jump if P3 is true. |
||
2493 | */ |
||
2494 | case OP_If: /* jump, in1 */ |
||
2495 | case OP_IfNot: |
||
2496 | { /* jump, in1 */ |
||
2497 | int c; |
||
2498 | pIn1 = aMem[pOp.p1]; |
||
2499 | if ( ( pIn1.flags & MEM_Null ) != 0 ) |
||
2500 | { |
||
2501 | c = pOp.p3; |
||
2502 | } |
||
2503 | else |
||
2504 | { |
||
2505 | #if SQLITE_OMIT_FLOATING_POINT |
||
2506 | c = sqlite3VdbeIntValue(pIn1)!=0; |
||
2507 | #else |
||
2508 | c = ( sqlite3VdbeRealValue( pIn1 ) != 0.0 ) ? 1 : 0; |
||
2509 | #endif |
||
2510 | if ( pOp.opcode == OP_IfNot ) |
||
2511 | c = ( c == 0 ) ? 1 : 0; |
||
2512 | } |
||
2513 | if ( c != 0 ) |
||
2514 | { |
||
2515 | pc = pOp.p2 - 1; |
||
2516 | } |
||
2517 | break; |
||
2518 | } |
||
2519 | |||
2520 | /* Opcode: IsNull P1 P2 * * * |
||
2521 | ** |
||
2522 | ** Jump to P2 if the value in register P1 is NULL. |
||
2523 | */ |
||
2524 | case OP_IsNull: |
||
2525 | { /* same as TK_ISNULL, jump, in1 */ |
||
2526 | pIn1 = aMem[pOp.p1]; |
||
2527 | if ( ( pIn1.flags & MEM_Null ) != 0 ) |
||
2528 | { |
||
2529 | pc = pOp.p2 - 1; |
||
2530 | } |
||
2531 | break; |
||
2532 | } |
||
2533 | |||
2534 | /* Opcode: NotNull P1 P2 * * * |
||
2535 | ** |
||
2536 | ** Jump to P2 if the value in register P1 is not NULL. |
||
2537 | */ |
||
2538 | case OP_NotNull: |
||
2539 | { /* same as TK_NOTNULL, jump, in1 */ |
||
2540 | pIn1 = aMem[pOp.p1]; |
||
2541 | if ( ( pIn1.flags & MEM_Null ) == 0 ) |
||
2542 | { |
||
2543 | pc = pOp.p2 - 1; |
||
2544 | } |
||
2545 | break; |
||
2546 | } |
||
2547 | |||
2548 | /* Opcode: Column P1 P2 P3 P4 * |
||
2549 | ** |
||
2550 | ** Interpret the data that cursor P1 points to as a structure built using |
||
2551 | ** the MakeRecord instruction. (See the MakeRecord opcode for additional |
||
2552 | ** information about the format of the data.) Extract the P2-th column |
||
2553 | ** from this record. If there are less that (P2+1) |
||
2554 | ** values in the record, extract a NULL. |
||
2555 | ** |
||
2556 | ** The value extracted is stored in register P3. |
||
2557 | ** |
||
2558 | ** If the column contains fewer than P2 fields, then extract a NULL. Or, |
||
2559 | ** if the P4 argument is a P4_MEM use the value of the P4 argument as |
||
2560 | ** the result. |
||
2561 | ** |
||
2562 | ** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor, |
||
2563 | ** then the cache of the cursor is reset prior to extracting the column. |
||
2564 | ** The first OP_Column against a pseudo-table after the value of the content |
||
2565 | ** register has changed should have this bit set. |
||
2566 | */ |
||
2567 | case OP_Column: |
||
2568 | { |
||
2569 | u32 payloadSize; /* Number of bytes in the record */ |
||
2570 | i64 payloadSize64; /* Number of bytes in the record */ |
||
2571 | int p1; /* P1 value of the opcode */ |
||
2572 | int p2; /* column number to retrieve */ |
||
2573 | VdbeCursor pC; /* The VDBE cursor */ |
||
2574 | byte[] zRec; /* Pointer to complete record-data */ |
||
2575 | BtCursor pCrsr; /* The BTree cursor */ |
||
2576 | u32[] aType; /* aType[i] holds the numeric type of the i-th column */ |
||
2577 | u32[] aOffset; /* aOffset[i] is offset to start of data for i-th column */ |
||
2578 | int nField; /* number of fields in the record */ |
||
2579 | int len; /* The length of the serialized data for the column */ |
||
2580 | int i; /* Loop counter */ |
||
2581 | byte[] zData = null;/* Part of the record being decoded */ |
||
2582 | Mem pDest; /* Where to write the extracted value */ |
||
2583 | Mem sMem = null; /* For storing the record being decoded */ |
||
2584 | int zIdx; /* Index into header */ |
||
2585 | int zEndHdr; /* Pointer to first byte after the header */ |
||
2586 | u32 offset; /* Offset into the data */ |
||
2587 | u32 szField = 0; /* Number of bytes in the content of a field */ |
||
2588 | int szHdr; /* Size of the header size field at start of record */ |
||
2589 | int avail; /* Number of bytes of available data */ |
||
2590 | Mem pReg; /* PseudoTable input register */ |
||
2591 | |||
2592 | p1 = pOp.p1; |
||
2593 | p2 = pOp.p2; |
||
2594 | pC = null; |
||
2595 | |||
2596 | payloadSize = 0; |
||
2597 | payloadSize64 = 0; |
||
2598 | offset = 0; |
||
2599 | |||
2600 | sMem = sqlite3Malloc( sMem ); |
||
2601 | // memset(&sMem, 0, sizeof(sMem)); |
||
2602 | Debug.Assert( p1 < p.nCursor ); |
||
2603 | Debug.Assert( pOp.p3 > 0 && pOp.p3 <= p.nMem ); |
||
2604 | pDest = aMem[pOp.p3]; |
||
2605 | memAboutToChange( p, pDest ); |
||
2606 | MemSetTypeFlag( pDest, MEM_Null ); |
||
2607 | zRec = null; |
||
2608 | |||
2609 | /* This block sets the variable payloadSize to be the total number of |
||
2610 | ** bytes in the record. |
||
2611 | ** |
||
2612 | ** zRec is set to be the complete text of the record if it is available. |
||
2613 | ** The complete record text is always available for pseudo-tables |
||
2614 | ** If the record is stored in a cursor, the complete record text |
||
2615 | ** might be available in the pC.aRow cache. Or it might not be. |
||
2616 | ** If the data is unavailable, zRec is set to NULL. |
||
2617 | ** |
||
2618 | ** We also compute the number of columns in the record. For cursors, |
||
2619 | ** the number of columns is stored in the VdbeCursor.nField element. |
||
2620 | */ |
||
2621 | pC = p.apCsr[p1]; |
||
2622 | Debug.Assert( pC != null ); |
||
2623 | #if !SQLITE_OMIT_VIRTUALTABLE |
||
2624 | Debug.Assert( pC.pVtabCursor == null ); |
||
2625 | #endif |
||
2626 | pCrsr = pC.pCursor; |
||
2627 | if ( pCrsr != null ) |
||
2628 | { |
||
2629 | /* The record is stored in a B-Tree */ |
||
2630 | rc = sqlite3VdbeCursorMoveto( pC ); |
||
2631 | if ( rc != 0 ) |
||
2632 | goto abort_due_to_error; |
||
2633 | if ( pC.nullRow ) |
||
2634 | { |
||
2635 | payloadSize = 0; |
||
2636 | } |
||
2637 | else if ( ( pC.cacheStatus == p.cacheCtr ) && ( pC.aRow != -1 ) ) |
||
2638 | { |
||
2639 | payloadSize = pC.payloadSize; |
||
2640 | zRec = sqlite3Malloc( (int)payloadSize ); |
||
2641 | Buffer.BlockCopy( pCrsr.info.pCell, pC.aRow, zRec, 0, (int)payloadSize ); |
||
2642 | } |
||
2643 | else if ( pC.isIndex ) |
||
2644 | { |
||
2645 | Debug.Assert( sqlite3BtreeCursorIsValid( pCrsr ) ); |
||
2646 | rc = sqlite3BtreeKeySize( pCrsr, ref payloadSize64 ); |
||
2647 | Debug.Assert( rc == SQLITE_OK ); /* True because of CursorMoveto() call above */ |
||
2648 | /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the |
||
2649 | ** payload size, so it is impossible for payloadSize64 to be |
||
2650 | ** larger than 32 bits. */ |
||
2651 | Debug.Assert( ( (u64)payloadSize64 & SQLITE_MAX_U32 ) == (u64)payloadSize64 ); |
||
2652 | payloadSize = (u32)payloadSize64; |
||
2653 | } |
||
2654 | else |
||
2655 | { |
||
2656 | Debug.Assert( sqlite3BtreeCursorIsValid( pCrsr ) ); |
||
2657 | rc = sqlite3BtreeDataSize( pCrsr, ref payloadSize ); |
||
2658 | Debug.Assert( rc == SQLITE_OK ); /* DataSize() cannot fail */ |
||
2659 | } |
||
2660 | } |
||
2661 | else if ( pC.pseudoTableReg > 0 ) |
||
2662 | { |
||
2663 | /* The record is the sole entry of a pseudo-table */ |
||
2664 | pReg = aMem[pC.pseudoTableReg]; |
||
2665 | Debug.Assert( ( pReg.flags & MEM_Blob ) != 0 ); |
||
2666 | Debug.Assert( memIsValid( pReg ) ); |
||
2667 | payloadSize = (u32)pReg.n; |
||
2668 | zRec = pReg.zBLOB; |
||
2669 | pC.cacheStatus = ( pOp.p5 & OPFLAG_CLEARCACHE ) != 0 ? CACHE_STALE : p.cacheCtr; |
||
2670 | Debug.Assert( payloadSize == 0 || zRec != null ); |
||
2671 | } |
||
2672 | else |
||
2673 | { |
||
2674 | /* Consider the row to be NULL */ |
||
2675 | payloadSize = 0; |
||
2676 | } |
||
2677 | |||
2678 | /* If payloadSize is 0, then just store a NULL */ |
||
2679 | if ( payloadSize == 0 ) |
||
2680 | { |
||
2681 | Debug.Assert( ( pDest.flags & MEM_Null ) != 0 ); |
||
2682 | goto op_column_out; |
||
2683 | } |
||
2684 | Debug.Assert( db.aLimit[SQLITE_LIMIT_LENGTH] >= 0 ); |
||
2685 | if ( payloadSize > (u32)db.aLimit[SQLITE_LIMIT_LENGTH] ) |
||
2686 | { |
||
2687 | goto too_big; |
||
2688 | } |
||
2689 | |||
2690 | nField = pC.nField; |
||
2691 | Debug.Assert( p2 < nField ); |
||
2692 | |||
2693 | /* Read and parse the table header. Store the results of the parse |
||
2694 | ** into the record header cache fields of the cursor. |
||
2695 | */ |
||
2696 | aType = pC.aType; |
||
2697 | if ( pC.cacheStatus == p.cacheCtr ) |
||
2698 | { |
||
2699 | aOffset = pC.aOffset; |
||
2700 | } |
||
2701 | else |
||
2702 | { |
||
2703 | Debug.Assert( aType != null ); |
||
2704 | avail = 0; |
||
2705 | //pC.aOffset = aOffset = aType[nField]; |
||
2706 | aOffset = new u32[nField]; |
||
2707 | pC.aOffset = aOffset; |
||
2708 | pC.payloadSize = payloadSize; |
||
2709 | pC.cacheStatus = p.cacheCtr; |
||
2710 | |||
2711 | /* Figure out how many bytes are in the header */ |
||
2712 | if ( zRec != null ) |
||
2713 | { |
||
2714 | zData = zRec; |
||
2715 | } |
||
2716 | else |
||
2717 | { |
||
2718 | if ( pC.isIndex ) |
||
2719 | { |
||
2720 | zData = sqlite3BtreeKeyFetch( pCrsr, ref avail, ref pC.aRow ); |
||
2721 | } |
||
2722 | else |
||
2723 | { |
||
2724 | zData = sqlite3BtreeDataFetch( pCrsr, ref avail, ref pC.aRow ); |
||
2725 | } |
||
2726 | /* If KeyFetch()/DataFetch() managed to get the entire payload, |
||
2727 | ** save the payload in the pC.aRow cache. That will save us from |
||
2728 | ** having to make additional calls to fetch the content portion of |
||
2729 | ** the record. |
||
2730 | */ |
||
2731 | Debug.Assert( avail >= 0 ); |
||
2732 | if ( payloadSize <= (u32)avail ) |
||
2733 | { |
||
2734 | zRec = zData; |
||
2735 | //pC.aRow = zData; |
||
2736 | } |
||
2737 | else |
||
2738 | { |
||
2739 | pC.aRow = -1; //pC.aRow = null; |
||
2740 | } |
||
2741 | } |
||
2742 | /* The following Debug.Assert is true in all cases accept when |
||
2743 | ** the database file has been corrupted externally. |
||
2744 | ** Debug.Assert( zRec!=0 || avail>=payloadSize || avail>=9 ); */ |
||
2745 | szHdr = getVarint32( zData, out offset ); |
||
2746 | |||
2747 | /* Make sure a corrupt database has not given us an oversize header. |
||
2748 | ** Do this now to avoid an oversize memory allocation. |
||
2749 | ** |
||
2750 | ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte |
||
2751 | ** types use so much data space that there can only be 4096 and 32 of |
||
2752 | ** them, respectively. So the maximum header length results from a |
||
2753 | ** 3-byte type for each of the maximum of 32768 columns plus three |
||
2754 | ** extra bytes for the header length itself. 32768*3 + 3 = 98307. |
||
2755 | */ |
||
2756 | if ( offset > 98307 ) |
||
2757 | { |
||
2758 | rc = SQLITE_CORRUPT_BKPT(); |
||
2759 | goto op_column_out; |
||
2760 | } |
||
2761 | |||
2762 | /* Compute in len the number of bytes of data we need to read in order |
||
2763 | ** to get nField type values. offset is an upper bound on this. But |
||
2764 | ** nField might be significantly less than the true number of columns |
||
2765 | ** in the table, and in that case, 5*nField+3 might be smaller than offset. |
||
2766 | ** We want to minimize len in order to limit the size of the memory |
||
2767 | ** allocation, especially if a corrupt database file has caused offset |
||
2768 | ** to be oversized. Offset is limited to 98307 above. But 98307 might |
||
2769 | ** still exceed Robson memory allocation limits on some configurations. |
||
2770 | ** On systems that cannot tolerate large memory allocations, nField*5+3 |
||
2771 | ** will likely be much smaller since nField will likely be less than |
||
2772 | ** 20 or so. This insures that Robson memory allocation limits are |
||
2773 | ** not exceeded even for corrupt database files. |
||
2774 | */ |
||
2775 | len = nField * 5 + 3; |
||
2776 | if ( len > (int)offset ) |
||
2777 | len = (int)offset; |
||
2778 | |||
2779 | /* The KeyFetch() or DataFetch() above are fast and will get the entire |
||
2780 | ** record header in most cases. But they will fail to get the complete |
||
2781 | ** record header if the record header does not fit on a single page |
||
2782 | ** in the B-Tree. When that happens, use sqlite3VdbeMemFromBtree() to |
||
2783 | ** acquire the complete header text. |
||
2784 | */ |
||
2785 | if ( zRec == null && avail < len ) |
||
2786 | { |
||
2787 | sMem.db = null; |
||
2788 | sMem.flags = 0; |
||
2789 | rc = sqlite3VdbeMemFromBtree( pCrsr, 0, len, pC.isIndex, sMem ); |
||
2790 | if ( rc != SQLITE_OK ) |
||
2791 | { |
||
2792 | goto op_column_out; |
||
2793 | } |
||
2794 | zData = sMem.zBLOB; |
||
2795 | } |
||
2796 | zEndHdr = len;// zData[len]; |
||
2797 | zIdx = szHdr;// zData[szHdr]; |
||
2798 | |||
2799 | /* Scan the header and use it to fill in the aType[] and aOffset[] |
||
2800 | ** arrays. aType[i] will contain the type integer for the i-th |
||
2801 | ** column and aOffset[i] will contain the offset from the beginning |
||
2802 | ** of the record to the start of the data for the i-th column |
||
2803 | */ |
||
2804 | for ( i = 0; i < nField; i++ ) |
||
2805 | { |
||
2806 | if ( zIdx < zEndHdr ) |
||
2807 | { |
||
2808 | aOffset[i] = offset; |
||
2809 | zIdx += getVarint32( zData, zIdx, out aType[i] );//getVarint32(zIdx, aType[i]); |
||
2810 | szField = sqlite3VdbeSerialTypeLen( aType[i] ); |
||
2811 | offset += szField; |
||
2812 | if ( offset < szField ) |
||
2813 | { /* True if offset overflows */ |
||
2814 | zIdx = int.MaxValue; /* Forces SQLITE_CORRUPT return below */ |
||
2815 | break; |
||
2816 | } |
||
2817 | } |
||
2818 | else |
||
2819 | { |
||
2820 | /* If i is less that nField, then there are less fields in this |
||
2821 | ** record than SetNumColumns indicated there are columns in the |
||
2822 | ** table. Set the offset for any extra columns not present in |
||
2823 | ** the record to 0. This tells code below to store a NULL |
||
2824 | ** instead of deserializing a value from the record. |
||
2825 | */ |
||
2826 | aOffset[i] = 0; |
||
2827 | } |
||
2828 | } |
||
2829 | sqlite3VdbeMemRelease( sMem ); |
||
2830 | sMem.flags = MEM_Null; |
||
2831 | |||
2832 | /* If we have read more header data than was contained in the header, |
||
2833 | ** or if the end of the last field appears to be past the end of the |
||
2834 | ** record, or if the end of the last field appears to be before the end |
||
2835 | ** of the record (when all fields present), then we must be dealing |
||
2836 | ** with a corrupt database. |
||
2837 | */ |
||
2838 | if ( ( zIdx > zEndHdr ) || ( offset > payloadSize ) |
||
2839 | || ( zIdx == zEndHdr && offset != payloadSize ) ) |
||
2840 | { |
||
2841 | rc = SQLITE_CORRUPT_BKPT(); |
||
2842 | goto op_column_out; |
||
2843 | } |
||
2844 | } |
||
2845 | |||
2846 | /* Get the column information. If aOffset[p2] is non-zero, then |
||
2847 | ** deserialize the value from the record. If aOffset[p2] is zero, |
||
2848 | ** then there are not enough fields in the record to satisfy the |
||
2849 | ** request. In this case, set the value NULL or to P4 if P4 is |
||
2850 | ** a pointer to a Mem object. |
||
2851 | */ |
||
2852 | if ( aOffset[p2] != 0 ) |
||
2853 | { |
||
2854 | Debug.Assert( rc == SQLITE_OK ); |
||
2855 | if ( zRec != null ) |
||
2856 | { |
||
2857 | sqlite3VdbeMemReleaseExternal( pDest ); |
||
2858 | sqlite3VdbeSerialGet( zRec, (int)aOffset[p2], aType[p2], pDest ); |
||
2859 | } |
||
2860 | else |
||
2861 | { |
||
2862 | len = (int)sqlite3VdbeSerialTypeLen( aType[p2] ); |
||
2863 | sqlite3VdbeMemMove( sMem, pDest ); |
||
2864 | rc = sqlite3VdbeMemFromBtree( pCrsr, (int)aOffset[p2], len, pC.isIndex, sMem ); |
||
2865 | if ( rc != SQLITE_OK ) |
||
2866 | { |
||
2867 | goto op_column_out; |
||
2868 | } |
||
2869 | zData = sMem.zBLOB; |
||
2870 | sMem.zBLOB = null; |
||
2871 | sqlite3VdbeSerialGet( zData, aType[p2], pDest ); |
||
2872 | } |
||
2873 | pDest.enc = encoding; |
||
2874 | } |
||
2875 | else |
||
2876 | { |
||
2877 | if ( pOp.p4type == P4_MEM ) |
||
2878 | { |
||
2879 | sqlite3VdbeMemShallowCopy( pDest, pOp.p4.pMem, MEM_Static ); |
||
2880 | } |
||
2881 | else |
||
2882 | { |
||
2883 | Debug.Assert( ( pDest.flags & MEM_Null ) != 0 ); |
||
2884 | } |
||
2885 | } |
||
2886 | |||
2887 | /* If we dynamically allocated space to hold the data (in the |
||
2888 | ** sqlite3VdbeMemFromBtree() call above) then transfer control of that |
||
2889 | ** dynamically allocated space over to the pDest structure. |
||
2890 | ** This prevents a memory copy. |
||
2891 | */ |
||
2892 | //if ( sMem.zMalloc != null ) |
||
2893 | //{ |
||
2894 | // Debug.Assert( sMem.z == sMem.zMalloc); |
||
2895 | // Debug.Assert( sMem.xDel == null ); |
||
2896 | // Debug.Assert( ( pDest.flags & MEM_Dyn ) == 0 ); |
||
2897 | // Debug.Assert( ( pDest.flags & ( MEM_Blob | MEM_Str ) ) == 0 || pDest.z == sMem.z ); |
||
2898 | // pDest.flags &= ~( MEM_Ephem | MEM_Static ); |
||
2899 | // pDest.flags |= MEM_Term; |
||
2900 | // pDest.z = sMem.z; |
||
2901 | // pDest.zMalloc = sMem.zMalloc; |
||
2902 | //} |
||
2903 | |||
2904 | rc = sqlite3VdbeMemMakeWriteable( pDest ); |
||
2905 | |||
2906 | op_column_out: |
||
2907 | #if SQLITE_TEST |
||
2908 | UPDATE_MAX_BLOBSIZE( pDest ); |
||
2909 | #endif |
||
2910 | REGISTER_TRACE( p, pOp.p3, pDest ); |
||
2911 | if ( zData != null && zData != zRec ) |
||
2912 | sqlite3_free( ref zData ); |
||
2913 | //sqlite3_free( ref zRec ); |
||
2914 | sqlite3_free( ref sMem ); |
||
2915 | break; |
||
2916 | } |
||
2917 | |||
2918 | /* Opcode: Affinity P1 P2 * P4 * |
||
2919 | ** |
||
2920 | ** Apply affinities to a range of P2 registers starting with P1. |
||
2921 | ** |
||
2922 | ** P4 is a string that is P2 characters long. The nth character of the |
||
2923 | ** string indicates the column affinity that should be used for the nth |
||
2924 | ** memory cell in the range. |
||
2925 | */ |
||
2926 | case OP_Affinity: |
||
2927 | { |
||
2928 | string zAffinity; /* The affinity to be applied */ |
||
2929 | char cAff; /* A single character of affinity */ |
||
2930 | |||
2931 | zAffinity = pOp.p4.z; |
||
2932 | Debug.Assert( !string.IsNullOrEmpty( zAffinity ) ); |
||
2933 | Debug.Assert( zAffinity.Length <= pOp.p2 );//zAffinity[pOp.p2] == 0 |
||
2934 | //pIn1 = aMem[pOp.p1]; |
||
2935 | for ( int zI = 0; zI < zAffinity.Length; zI++ )// while( (cAff = *(zAffinity++))!=0 ){ |
||
2936 | { |
||
2937 | cAff = zAffinity[zI]; |
||
2938 | pIn1 = aMem[pOp.p1 + zI]; |
||
2939 | //Debug.Assert( pIn1 <= p->aMem[p->nMem] ); |
||
2940 | Debug.Assert( memIsValid( pIn1 ) ); |
||
2941 | ////ExpandBlob( pIn1 ); |
||
2942 | applyAffinity( pIn1, cAff, encoding ); |
||
2943 | //pIn1++; |
||
2944 | } |
||
2945 | break; |
||
2946 | } |
||
2947 | |||
2948 | /* Opcode: MakeRecord P1 P2 P3 P4 * |
||
2949 | ** |
||
2950 | ** Convert P2 registers beginning with P1 into the [record format] |
||
2951 | ** use as a data record in a database table or as a key |
||
2952 | ** in an index. The OP_Column opcode can decode the record later. |
||
2953 | ** |
||
2954 | ** P4 may be a string that is P2 characters long. The nth character of the |
||
2955 | ** string indicates the column affinity that should be used for the nth |
||
2956 | ** field of the index key. |
||
2957 | ** |
||
2958 | ** The mapping from character to affinity is given by the SQLITE_AFF_ |
||
2959 | ** macros defined in sqliteInt.h. |
||
2960 | ** |
||
2961 | ** If P4 is NULL then all index fields have the affinity NONE. |
||
2962 | */ |
||
2963 | case OP_MakeRecord: |
||
2964 | { |
||
2965 | byte[] zNewRecord; /* A buffer to hold the data for the new record */ |
||
2966 | Mem pRec; /* The new record */ |
||
2967 | u64 nData; /* Number of bytes of data space */ |
||
2968 | int nHdr; /* Number of bytes of header space */ |
||
2969 | i64 nByte; /* Data space required for this record */ |
||
2970 | int nZero; /* Number of zero bytes at the end of the record */ |
||
2971 | int nVarint; /* Number of bytes in a varint */ |
||
2972 | u32 serial_type; /* Type field */ |
||
2973 | //Mem pData0; /* First field to be combined into the record */ |
||
2974 | //Mem pLast; /* Last field of the record */ |
||
2975 | int nField; /* Number of fields in the record */ |
||
2976 | string zAffinity; /* The affinity string for the record */ |
||
2977 | int file_format; /* File format to use for encoding */ |
||
2978 | int i; /* Space used in zNewRecord[] */ |
||
2979 | int len; /* Length of a field */ |
||
2980 | /* Assuming the record contains N fields, the record format looks |
||
2981 | ** like this: |
||
2982 | ** |
||
2983 | ** ------------------------------------------------------------------------ |
||
2984 | ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | |
||
2985 | ** ------------------------------------------------------------------------ |
||
2986 | ** |
||
2987 | ** Data(0) is taken from register P1. Data(1) comes from register P1+1 |
||
2988 | ** and so froth. |
||
2989 | ** |
||
2990 | ** Each type field is a varint representing the serial type of the |
||
2991 | ** corresponding data element (see sqlite3VdbeSerialType()). The |
||
2992 | ** hdr-size field is also a varint which is the offset from the beginning |
||
2993 | ** of the record to data0. |
||
2994 | */ |
||
2995 | |||
2996 | nData = 0; /* Number of bytes of data space */ |
||
2997 | nHdr = 0; /* Number of bytes of header space */ |
||
2998 | nZero = 0; /* Number of zero bytes at the end of the record */ |
||
2999 | nField = pOp.p1; |
||
3000 | zAffinity = pOp.p4.z ?? string.Empty; |
||
3001 | Debug.Assert( nField > 0 && pOp.p2 > 0 && pOp.p2 + nField <= p.nMem + 1 ); |
||
3002 | //pData0 = aMem[nField]; |
||
3003 | nField = pOp.p2; |
||
3004 | //pLast = pData0[nField - 1]; |
||
3005 | file_format = p.minWriteFileFormat; |
||
3006 | |||
3007 | /* Identify the output register */ |
||
3008 | Debug.Assert( pOp.p3 < pOp.p1 || pOp.p3 >= pOp.p1 + pOp.p2 ); |
||
3009 | pOut = aMem[pOp.p3]; |
||
3010 | memAboutToChange( p, pOut ); |
||
3011 | |||
3012 | /* Loop through the elements that will make up the record to figure |
||
3013 | ** out how much space is required for the new record. |
||
3014 | */ |
||
3015 | //for (pRec = pData0; pRec <= pLast; pRec++) |
||
3016 | for ( int pD0 = 0; pD0 < nField; pD0++ ) |
||
3017 | { |
||
3018 | pRec = p.aMem[pOp.p1 + pD0]; |
||
3019 | Debug.Assert( memIsValid( pRec ) ); |
||
3020 | if ( pD0 < zAffinity.Length && zAffinity[pD0] != '\0' ) |
||
3021 | { |
||
3022 | applyAffinity( pRec, (char)zAffinity[pD0], encoding ); |
||
3023 | } |
||
3024 | ////if ( ( pRec.flags & MEM_Zero ) != 0 && pRec.n > 0 ) |
||
3025 | ////{ |
||
3026 | //// sqlite3VdbeMemExpandBlob( pRec ); |
||
3027 | ////} |
||
3028 | serial_type = sqlite3VdbeSerialType( pRec, file_format ); |
||
3029 | len = (int)sqlite3VdbeSerialTypeLen( serial_type ); |
||
3030 | nData += (u64)len; |
||
3031 | nHdr += sqlite3VarintLen( serial_type ); |
||
3032 | if ( ( pRec.flags & MEM_Zero ) != 0 ) |
||
3033 | { |
||
3034 | /* Only pure zero-filled BLOBs can be input to this Opcode. |
||
3035 | ** We do not allow blobs with a prefix and a zero-filled tail. */ |
||
3036 | nZero += pRec.u.nZero; |
||
3037 | } |
||
3038 | else if ( len != 0 ) |
||
3039 | { |
||
3040 | nZero = 0; |
||
3041 | } |
||
3042 | } |
||
3043 | |||
3044 | /* Add the initial header varint and total the size */ |
||
3045 | nHdr += nVarint = sqlite3VarintLen( (u64)nHdr ); |
||
3046 | if ( nVarint < sqlite3VarintLen( (u64)nHdr ) ) |
||
3047 | { |
||
3048 | nHdr++; |
||
3049 | } |
||
3050 | nByte = (i64)( (u64)nHdr + nData - (u64)nZero ); |
||
3051 | if ( nByte > db.aLimit[SQLITE_LIMIT_LENGTH] ) |
||
3052 | { |
||
3053 | goto too_big; |
||
3054 | } |
||
3055 | |||
3056 | /* Make sure the output register has a buffer large enough to store |
||
3057 | ** the new record. The output register (pOp.p3) is not allowed to |
||
3058 | ** be one of the input registers (because the following call to |
||
3059 | ** sqlite3VdbeMemGrow() could clobber the value before it is used). |
||
3060 | */ |
||
3061 | //if ( sqlite3VdbeMemGrow( pOut, (int)nByte, 0 ) != 0 ) |
||
3062 | //{ |
||
3063 | // goto no_mem; |
||
3064 | //} |
||
3065 | zNewRecord = sqlite3Malloc( (int)nByte );// (u8 )pOut.z; |
||
3066 | |||
3067 | /* Write the record */ |
||
3068 | i = putVarint32( zNewRecord, nHdr ); |
||
3069 | for ( int pD0 = 0; pD0 < nField; pD0++ )//for (pRec = pData0; pRec <= pLast; pRec++) |
||
3070 | { |
||
3071 | pRec = p.aMem[pOp.p1 + pD0]; |
||
3072 | serial_type = sqlite3VdbeSerialType( pRec, file_format ); |
||
3073 | i += putVarint32( zNewRecord, i, (int)serial_type ); /* serial type */ |
||
3074 | } |
||
3075 | for ( int pD0 = 0; pD0 < nField; pD0++ )//for (pRec = pData0; pRec <= pLast; pRec++) |
||
3076 | { /* serial data */ |
||
3077 | pRec = p.aMem[pOp.p1 + pD0]; |
||
3078 | i += (int)sqlite3VdbeSerialPut( zNewRecord, i, (int)nByte - i, pRec, file_format ); |
||
3079 | } |
||
3080 | //TODO -- Remove this for testing Debug.Assert( i == nByte ); |
||
3081 | |||
3082 | Debug.Assert( pOp.p3 > 0 && pOp.p3 <= p.nMem ); |
||
3083 | pOut.zBLOB = zNewRecord; |
||
3084 | pOut.z = null; |
||
3085 | pOut.n = (int)nByte; |
||
3086 | pOut.flags = MEM_Blob | MEM_Dyn; |
||
3087 | pOut.xDel = null; |
||
3088 | if ( nZero != 0 ) |
||
3089 | { |
||
3090 | pOut.u.nZero = nZero; |
||
3091 | pOut.flags |= MEM_Zero; |
||
3092 | } |
||
3093 | pOut.enc = SQLITE_UTF8; /* In case the blob is ever converted to text */ |
||
3094 | REGISTER_TRACE( p, pOp.p3, pOut ); |
||
3095 | #if SQLITE_TEST |
||
3096 | UPDATE_MAX_BLOBSIZE( pOut ); |
||
3097 | #endif |
||
3098 | break; |
||
3099 | } |
||
3100 | |||
3101 | /* Opcode: Count P1 P2 * * * |
||
3102 | ** |
||
3103 | ** Store the number of entries (an integer value) in the table or index |
||
3104 | ** opened by cursor P1 in register P2 |
||
3105 | */ |
||
3106 | #if !SQLITE_OMIT_BTREECOUNT |
||
3107 | case OP_Count: |
||
3108 | { /* out2-prerelease */ |
||
3109 | i64 nEntry = 0; |
||
3110 | BtCursor pCrsr; |
||
3111 | pCrsr = p.apCsr[pOp.p1].pCursor; |
||
3112 | if ( pCrsr != null ) |
||
3113 | { |
||
3114 | rc = sqlite3BtreeCount( pCrsr, ref nEntry ); |
||
3115 | } |
||
3116 | else |
||
3117 | { |
||
3118 | nEntry = 0; |
||
3119 | } |
||
3120 | pOut.u.i = nEntry; |
||
3121 | break; |
||
3122 | } |
||
3123 | #endif |
||
3124 | |||
3125 | /* Opcode: Savepoint P1 * * P4 * |
||
3126 | ** |
||
3127 | ** Open, release or rollback the savepoint named by parameter P4, depending |
||
3128 | ** on the value of P1. To open a new savepoint, P1==0. To release (commit) an |
||
3129 | ** existing savepoint, P1==1, or to rollback an existing savepoint P1==2. |
||
3130 | */ |
||
3131 | case OP_Savepoint: |
||
3132 | { |
||
3133 | int p1; /* Value of P1 operand */ |
||
3134 | string zName; /* Name of savepoint */ |
||
3135 | ////int nName; |
||
3136 | Savepoint pNew; |
||
3137 | Savepoint pSavepoint; |
||
3138 | Savepoint pTmp; |
||
3139 | int iSavepoint; |
||
3140 | int ii; |
||
3141 | |||
3142 | p1 = pOp.p1; |
||
3143 | zName = pOp.p4.z; |
||
3144 | |||
3145 | /* Assert that the p1 parameter is valid. Also that if there is no open |
||
3146 | ** transaction, then there cannot be any savepoints. |
||
3147 | */ |
||
3148 | Debug.Assert( db.pSavepoint == null || db.autoCommit == 0 ); |
||
3149 | Debug.Assert( p1 == SAVEPOINT_BEGIN || p1 == SAVEPOINT_RELEASE || p1 == SAVEPOINT_ROLLBACK ); |
||
3150 | Debug.Assert( db.pSavepoint != null || db.isTransactionSavepoint == 0 ); |
||
3151 | Debug.Assert( checkSavepointCount( db ) != 0 ); |
||
3152 | |||
3153 | if ( p1 == SAVEPOINT_BEGIN ) |
||
3154 | { |
||
3155 | if ( db.writeVdbeCnt > 0 ) |
||
3156 | { |
||
3157 | /* A new savepoint cannot be created if there are active write |
||
3158 | ** statements (i.e. open read/write incremental blob handles). |
||
3159 | */ |
||
3160 | sqlite3SetString( ref p.zErrMsg, db, "cannot open savepoint - ", |
||
3161 | "SQL statements in progress" ); |
||
3162 | rc = SQLITE_BUSY; |
||
3163 | } |
||
3164 | else |
||
3165 | { |
||
3166 | ////nName = sqlite3Strlen30( zName ); |
||
3167 | |||
3168 | #if !SQLITE_OMIT_VIRTUALTABLE |
||
3169 | /* This call is Ok even if this savepoint is actually a transaction |
||
3170 | ** savepoint (and therefore should not prompt xSavepoint()) callbacks. |
||
3171 | ** If this is a transaction savepoint being opened, it is guaranteed |
||
3172 | ** that the db->aVTrans[] array is empty. */ |
||
3173 | Debug.Assert( db.autoCommit == 0 || db.nVTrans == 0 ); |
||
3174 | rc = sqlite3VtabSavepoint( db, SAVEPOINT_BEGIN, |
||
3175 | db.nStatement + db.nSavepoint ); |
||
3176 | if ( rc != SQLITE_OK ) |
||
3177 | goto abort_due_to_error; |
||
3178 | #endif |
||
3179 | |||
3180 | /* Create a new savepoint structure. */ |
||
3181 | pNew = new Savepoint();// sqlite3DbMallocRaw( db, sizeof( Savepoint ) + nName + 1 ); |
||
3182 | if ( pNew != null ) |
||
3183 | { |
||
3184 | //pNew.zName = (char )&pNew[1]; |
||
3185 | //memcpy(pNew.zName, zName, nName+1); |
||
3186 | pNew.zName = zName; |
||
3187 | |||
3188 | /* If there is no open transaction, then mark this as a special |
||
3189 | ** "transaction savepoint". */ |
||
3190 | if ( db.autoCommit != 0 ) |
||
3191 | { |
||
3192 | db.autoCommit = 0; |
||
3193 | db.isTransactionSavepoint = 1; |
||
3194 | } |
||
3195 | else |
||
3196 | { |
||
3197 | db.nSavepoint++; |
||
3198 | } |
||
3199 | |||
3200 | /* Link the new savepoint into the database handle's list. */ |
||
3201 | pNew.pNext = db.pSavepoint; |
||
3202 | db.pSavepoint = pNew; |
||
3203 | pNew.nDeferredCons = db.nDeferredCons; |
||
3204 | } |
||
3205 | } |
||
3206 | } |
||
3207 | else |
||
3208 | { |
||
3209 | iSavepoint = 0; |
||
3210 | |||
3211 | /* Find the named savepoint. If there is no such savepoint, then an |
||
3212 | ** an error is returned to the user. */ |
||
3213 | for ( |
||
3214 | pSavepoint = db.pSavepoint; |
||
3215 | pSavepoint != null && !pSavepoint.zName.Equals( zName, StringComparison.OrdinalIgnoreCase ); |
||
3216 | pSavepoint = pSavepoint.pNext |
||
3217 | ) |
||
3218 | { |
||
3219 | iSavepoint++; |
||
3220 | } |
||
3221 | if ( null == pSavepoint ) |
||
3222 | { |
||
3223 | sqlite3SetString( ref p.zErrMsg, db, "no such savepoint: %s", zName ); |
||
3224 | rc = SQLITE_ERROR; |
||
3225 | } |
||
3226 | else if ( |
||
3227 | db.writeVdbeCnt > 0 || ( p1 == SAVEPOINT_ROLLBACK && db.activeVdbeCnt > 1 ) |
||
3228 | ) |
||
3229 | { |
||
3230 | /* It is not possible to release (commit) a savepoint if there are |
||
3231 | ** active write statements. It is not possible to rollback a savepoint |
||
3232 | ** if there are any active statements at all. |
||
3233 | */ |
||
3234 | sqlite3SetString( ref p.zErrMsg, db, |
||
3235 | "cannot %s savepoint - SQL statements in progress", |
||
3236 | ( p1 == SAVEPOINT_ROLLBACK ? "rollback" : "release" ) |
||
3237 | ); |
||
3238 | rc = SQLITE_BUSY; |
||
3239 | } |
||
3240 | else |
||
3241 | { |
||
3242 | |||
3243 | /* Determine whether or not this is a transaction savepoint. If so, |
||
3244 | ** and this is a RELEASE command, then the current transaction |
||
3245 | ** is committed. |
||
3246 | */ |
||
3247 | int isTransaction = ( pSavepoint.pNext == null && db.isTransactionSavepoint != 0 ) ? 1 : 0; |
||
3248 | if ( isTransaction != 0 && p1 == SAVEPOINT_RELEASE ) |
||
3249 | { |
||
3250 | if ( ( rc = sqlite3VdbeCheckFk( p, 1 ) ) != SQLITE_OK ) |
||
3251 | { |
||
3252 | goto vdbe_return; |
||
3253 | } |
||
3254 | db.autoCommit = 1; |
||
3255 | if ( sqlite3VdbeHalt( p ) == SQLITE_BUSY ) |
||
3256 | { |
||
3257 | p.pc = pc; |
||
3258 | db.autoCommit = 0; |
||
3259 | p.rc = rc = SQLITE_BUSY; |
||
3260 | goto vdbe_return; |
||
3261 | } |
||
3262 | db.isTransactionSavepoint = 0; |
||
3263 | rc = p.rc; |
||
3264 | } |
||
3265 | else |
||
3266 | { |
||
3267 | iSavepoint = db.nSavepoint - iSavepoint - 1; |
||
3268 | for ( ii = 0; ii < db.nDb; ii++ ) |
||
3269 | { |
||
3270 | rc = sqlite3BtreeSavepoint( db.aDb[ii].pBt, p1, iSavepoint ); |
||
3271 | if ( rc != SQLITE_OK ) |
||
3272 | { |
||
3273 | goto abort_due_to_error; |
||
3274 | } |
||
3275 | } |
||
3276 | if ( p1 == SAVEPOINT_ROLLBACK && ( db.flags & SQLITE_InternChanges ) != 0 ) |
||
3277 | { |
||
3278 | sqlite3ExpirePreparedStatements( db ); |
||
3279 | sqlite3ResetInternalSchema( db, -1 ); |
||
3280 | db.flags = ( db.flags | SQLITE_InternChanges ); |
||
3281 | } |
||
3282 | } |
||
3283 | |||
3284 | /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all |
||
3285 | ** savepoints nested inside of the savepoint being operated on. */ |
||
3286 | while ( db.pSavepoint != pSavepoint ) |
||
3287 | { |
||
3288 | pTmp = db.pSavepoint; |
||
3289 | db.pSavepoint = pTmp.pNext; |
||
3290 | sqlite3DbFree( db, ref pTmp ); |
||
3291 | db.nSavepoint--; |
||
3292 | } |
||
3293 | |||
3294 | /* If it is a RELEASE, then destroy the savepoint being operated on |
||
3295 | ** too. If it is a ROLLBACK TO, then set the number of deferred |
||
3296 | ** constraint violations present in the database to the value stored |
||
3297 | ** when the savepoint was created. */ |
||
3298 | if ( p1 == SAVEPOINT_RELEASE ) |
||
3299 | { |
||
3300 | Debug.Assert( pSavepoint == db.pSavepoint ); |
||
3301 | db.pSavepoint = pSavepoint.pNext; |
||
3302 | sqlite3DbFree( db, ref pSavepoint ); |
||
3303 | if ( 0 == isTransaction ) |
||
3304 | { |
||
3305 | db.nSavepoint--; |
||
3306 | } |
||
3307 | } |
||
3308 | else |
||
3309 | { |
||
3310 | db.nDeferredCons = pSavepoint.nDeferredCons; |
||
3311 | } |
||
3312 | |||
3313 | if ( 0 == isTransaction ) |
||
3314 | { |
||
3315 | rc = sqlite3VtabSavepoint( db, p1, iSavepoint ); |
||
3316 | if ( rc != SQLITE_OK ) |
||
3317 | goto abort_due_to_error; |
||
3318 | } |
||
3319 | |||
3320 | } |
||
3321 | } |
||
3322 | |||
3323 | break; |
||
3324 | } |
||
3325 | |||
3326 | /* Opcode: AutoCommit P1 P2 * * * |
||
3327 | ** |
||
3328 | ** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll |
||
3329 | ** back any currently active btree transactions. If there are any active |
||
3330 | ** VMs (apart from this one), then the COMMIT or ROLLBACK statement fails. |
||
3331 | ** |
||
3332 | ** This instruction causes the VM to halt. |
||
3333 | */ |
||
3334 | case OP_AutoCommit: |
||
3335 | { |
||
3336 | int desiredAutoCommit; |
||
3337 | int iRollback; |
||
3338 | int turnOnAC; |
||
3339 | |||
3340 | desiredAutoCommit = (u8)pOp.p1; |
||
3341 | iRollback = pOp.p2; |
||
3342 | turnOnAC = ( desiredAutoCommit != 0 && 0 == db.autoCommit ) ? 1 : 0; |
||
3343 | |||
3344 | Debug.Assert( desiredAutoCommit != 0 || 0 == desiredAutoCommit ); |
||
3345 | Debug.Assert( desiredAutoCommit != 0 || 0 == iRollback ); |
||
3346 | |||
3347 | Debug.Assert( db.activeVdbeCnt > 0 ); /* At least this one VM is active */ |
||
3348 | |||
3349 | if ( turnOnAC != 0 && iRollback != 0 && db.activeVdbeCnt > 1 ) |
||
3350 | { |
||
3351 | /* If this instruction implements a ROLLBACK and other VMs are |
||
3352 | ** still running, and a transaction is active, return an error indicating |
||
3353 | ** that the other VMs must complete first. |
||
3354 | */ |
||
3355 | sqlite3SetString( ref p.zErrMsg, db, "cannot rollback transaction - " + |
||
3356 | "SQL statements in progress" ); |
||
3357 | rc = SQLITE_BUSY; |
||
3358 | } |
||
3359 | else if ( turnOnAC != 0 && 0 == iRollback && db.writeVdbeCnt > 0 ) |
||
3360 | { |
||
3361 | /* If this instruction implements a COMMIT and other VMs are writing |
||
3362 | ** return an error indicating that the other VMs must complete first. |
||
3363 | */ |
||
3364 | sqlite3SetString( ref p.zErrMsg, db, "cannot commit transaction - " + |
||
3365 | "SQL statements in progress" ); |
||
3366 | rc = SQLITE_BUSY; |
||
3367 | } |
||
3368 | else if ( desiredAutoCommit != db.autoCommit ) |
||
3369 | { |
||
3370 | if ( iRollback != 0 ) |
||
3371 | { |
||
3372 | Debug.Assert( desiredAutoCommit != 0 ); |
||
3373 | sqlite3RollbackAll( db ); |
||
3374 | db.autoCommit = 1; |
||
3375 | } |
||
3376 | else if ( ( rc = sqlite3VdbeCheckFk( p, 1 ) ) != SQLITE_OK ) |
||
3377 | { |
||
3378 | goto vdbe_return; |
||
3379 | } |
||
3380 | else |
||
3381 | { |
||
3382 | db.autoCommit = (u8)desiredAutoCommit; |
||
3383 | if ( sqlite3VdbeHalt( p ) == SQLITE_BUSY ) |
||
3384 | { |
||
3385 | p.pc = pc; |
||
3386 | db.autoCommit = (u8)( desiredAutoCommit == 0 ? 1 : 0 ); |
||
3387 | p.rc = rc = SQLITE_BUSY; |
||
3388 | goto vdbe_return; |
||
3389 | } |
||
3390 | } |
||
3391 | Debug.Assert( db.nStatement == 0 ); |
||
3392 | sqlite3CloseSavepoints( db ); |
||
3393 | if ( p.rc == SQLITE_OK ) |
||
3394 | { |
||
3395 | rc = SQLITE_DONE; |
||
3396 | } |
||
3397 | else |
||
3398 | { |
||
3399 | rc = SQLITE_ERROR; |
||
3400 | } |
||
3401 | goto vdbe_return; |
||
3402 | } |
||
3403 | else |
||
3404 | { |
||
3405 | sqlite3SetString( ref p.zErrMsg, db, |
||
3406 | ( 0 == desiredAutoCommit ) ? "cannot start a transaction within a transaction" : ( |
||
3407 | ( iRollback != 0 ) ? "cannot rollback - no transaction is active" : |
||
3408 | "cannot commit - no transaction is active" ) ); |
||
3409 | rc = SQLITE_ERROR; |
||
3410 | } |
||
3411 | break; |
||
3412 | } |
||
3413 | |||
3414 | /* Opcode: Transaction P1 P2 * * * |
||
3415 | ** |
||
3416 | ** Begin a transaction. The transaction ends when a Commit or Rollback |
||
3417 | ** opcode is encountered. Depending on the ON CONFLICT setting, the |
||
3418 | ** transaction might also be rolled back if an error is encountered. |
||
3419 | ** |
||
3420 | ** P1 is the index of the database file on which the transaction is |
||
3421 | ** started. Index 0 is the main database file and index 1 is the |
||
3422 | ** file used for temporary tables. Indices of 2 or more are used for |
||
3423 | ** attached databases. |
||
3424 | ** |
||
3425 | ** If P2 is non-zero, then a write-transaction is started. A RESERVED lock is |
||
3426 | ** obtained on the database file when a write-transaction is started. No |
||
3427 | ** other process can start another write transaction while this transaction is |
||
3428 | ** underway. Starting a write transaction also creates a rollback journal. A |
||
3429 | ** write transaction must be started before any changes can be made to the |
||
3430 | ** database. If P2 is 2 or greater then an EXCLUSIVE lock is also obtained |
||
3431 | ** on the file. |
||
3432 | ** |
||
3433 | ** If a write-transaction is started and the Vdbe.usesStmtJournal flag is |
||
3434 | ** true (this flag is set if the Vdbe may modify more than one row and may |
||
3435 | ** throw an ABORT exception), a statement transaction may also be opened. |
||
3436 | ** More specifically, a statement transaction is opened iff the database |
||
3437 | ** connection is currently not in autocommit mode, or if there are other |
||
3438 | ** active statements. A statement transaction allows the affects of this |
||
3439 | ** VDBE to be rolled back after an error without having to roll back the |
||
3440 | ** entire transaction. If no error is encountered, the statement transaction |
||
3441 | ** will automatically commit when the VDBE halts. |
||
3442 | ** |
||
3443 | ** If P2 is zero, then a read-lock is obtained on the database file. |
||
3444 | */ |
||
3445 | case OP_Transaction: |
||
3446 | { |
||
3447 | Btree pBt; |
||
3448 | |||
3449 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < db.nDb ); |
||
3450 | Debug.Assert( ( p.btreeMask & ( ( (yDbMask)1 ) << pOp.p1 ) ) != 0 ); |
||
3451 | pBt = db.aDb[pOp.p1].pBt; |
||
3452 | |||
3453 | if ( pBt != null ) |
||
3454 | { |
||
3455 | rc = sqlite3BtreeBeginTrans( pBt, pOp.p2 ); |
||
3456 | if ( rc == SQLITE_BUSY ) |
||
3457 | { |
||
3458 | p.pc = pc; |
||
3459 | p.rc = rc = SQLITE_BUSY; |
||
3460 | goto vdbe_return; |
||
3461 | } |
||
3462 | if ( rc != SQLITE_OK ) |
||
3463 | { |
||
3464 | goto abort_due_to_error; |
||
3465 | } |
||
3466 | if ( pOp.p2 != 0 && p.usesStmtJournal |
||
3467 | && ( db.autoCommit == 0 || db.activeVdbeCnt > 1 ) |
||
3468 | ) |
||
3469 | { |
||
3470 | Debug.Assert( sqlite3BtreeIsInTrans( pBt ) ); |
||
3471 | if ( p.iStatement == 0 ) |
||
3472 | { |
||
3473 | Debug.Assert( db.nStatement >= 0 && db.nSavepoint >= 0 ); |
||
3474 | db.nStatement++; |
||
3475 | p.iStatement = db.nSavepoint + db.nStatement; |
||
3476 | } |
||
3477 | rc = sqlite3VtabSavepoint( db, SAVEPOINT_BEGIN, p.iStatement - 1 ); |
||
3478 | if ( rc == SQLITE_OK ) |
||
3479 | { |
||
3480 | rc = sqlite3BtreeBeginStmt( pBt, p.iStatement ); |
||
3481 | } |
||
3482 | /* Store the current value of the database handles deferred constraint |
||
3483 | ** counter. If the statement transaction needs to be rolled back, |
||
3484 | ** the value of this counter needs to be restored too. */ |
||
3485 | p.nStmtDefCons = db.nDeferredCons; |
||
3486 | } |
||
3487 | } |
||
3488 | break; |
||
3489 | } |
||
3490 | |||
3491 | /* Opcode: ReadCookie P1 P2 P3 * * |
||
3492 | ** |
||
3493 | ** Read cookie number P3 from database P1 and write it into register P2. |
||
3494 | ** P3==1 is the schema version. P3==2 is the database format. |
||
3495 | ** P3==3 is the recommended pager cache size, and so forth. P1==0 is |
||
3496 | ** the main database file and P1==1 is the database file used to store |
||
3497 | ** temporary tables. |
||
3498 | ** |
||
3499 | ** There must be a read-lock on the database (either a transaction |
||
3500 | ** must be started or there must be an open cursor) before |
||
3501 | ** executing this instruction. |
||
3502 | */ |
||
3503 | case OP_ReadCookie: |
||
3504 | { /* out2-prerelease */ |
||
3505 | u32 iMeta; |
||
3506 | int iDb; |
||
3507 | int iCookie; |
||
3508 | |||
3509 | iMeta = 0; |
||
3510 | iDb = pOp.p1; |
||
3511 | iCookie = pOp.p3; |
||
3512 | |||
3513 | Debug.Assert( pOp.p3 < SQLITE_N_BTREE_META ); |
||
3514 | Debug.Assert( iDb >= 0 && iDb < db.nDb ); |
||
3515 | Debug.Assert( db.aDb[iDb].pBt != null ); |
||
3516 | Debug.Assert( ( p.btreeMask & ( ( (yDbMask)1 ) << iDb ) ) != 0 ); |
||
3517 | sqlite3BtreeGetMeta( db.aDb[iDb].pBt, iCookie, ref iMeta ); |
||
3518 | pOut.u.i = (int)iMeta; |
||
3519 | break; |
||
3520 | } |
||
3521 | |||
3522 | /* Opcode: SetCookie P1 P2 P3 * * |
||
3523 | ** |
||
3524 | ** Write the content of register P3 (interpreted as an integer) |
||
3525 | ** into cookie number P2 of database P1. P2==1 is the schema version. |
||
3526 | ** P2==2 is the database format. P2==3 is the recommended pager cache |
||
3527 | ** size, and so forth. P1==0 is the main database file and P1==1 is the |
||
3528 | ** database file used to store temporary tables. |
||
3529 | ** |
||
3530 | ** A transaction must be started before executing this opcode. |
||
3531 | */ |
||
3532 | case OP_SetCookie: |
||
3533 | { /* in3 */ |
||
3534 | Db pDb; |
||
3535 | Debug.Assert( pOp.p2 < SQLITE_N_BTREE_META ); |
||
3536 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < db.nDb ); |
||
3537 | Debug.Assert( ( p.btreeMask & ( ( (yDbMask)1 ) << pOp.p1 ) ) != 0 ); |
||
3538 | pDb = db.aDb[pOp.p1]; |
||
3539 | Debug.Assert( pDb.pBt != null ); |
||
3540 | Debug.Assert( sqlite3SchemaMutexHeld( db, pOp.p1, null ) ); |
||
3541 | pIn3 = aMem[pOp.p3]; |
||
3542 | sqlite3VdbeMemIntegerify( pIn3 ); |
||
3543 | /* See note about index shifting on OP_ReadCookie */ |
||
3544 | rc = sqlite3BtreeUpdateMeta( pDb.pBt, pOp.p2, (u32)pIn3.u.i ); |
||
3545 | if ( pOp.p2 == BTREE_SCHEMA_VERSION ) |
||
3546 | { |
||
3547 | /* When the schema cookie changes, record the new cookie internally */ |
||
3548 | pDb.pSchema.schema_cookie = (int)pIn3.u.i; |
||
3549 | db.flags |= SQLITE_InternChanges; |
||
3550 | } |
||
3551 | else if ( pOp.p2 == BTREE_FILE_FORMAT ) |
||
3552 | { |
||
3553 | /* Record changes in the file format */ |
||
3554 | pDb.pSchema.file_format = (u8)pIn3.u.i; |
||
3555 | } |
||
3556 | if ( pOp.p1 == 1 ) |
||
3557 | { |
||
3558 | /* Invalidate all prepared statements whenever the TEMP database |
||
3559 | ** schema is changed. Ticket #1644 */ |
||
3560 | sqlite3ExpirePreparedStatements( db ); |
||
3561 | p.expired = false; |
||
3562 | } |
||
3563 | break; |
||
3564 | } |
||
3565 | |||
3566 | /* Opcode: VerifyCookie P1 P2 P3 * * |
||
3567 | ** |
||
3568 | ** Check the value of global database parameter number 0 (the |
||
3569 | ** schema version) and make sure it is equal to P2 and that the |
||
3570 | ** generation counter on the local schema parse equals P3. |
||
3571 | ** |
||
3572 | ** P1 is the database number which is 0 for the main database file |
||
3573 | ** and 1 for the file holding temporary tables and some higher number |
||
3574 | ** for auxiliary databases. |
||
3575 | ** |
||
3576 | ** The cookie changes its value whenever the database schema changes. |
||
3577 | ** This operation is used to detect when that the cookie has changed |
||
3578 | ** and that the current process needs to reread the schema. |
||
3579 | ** |
||
3580 | ** Either a transaction needs to have been started or an OP_Open needs |
||
3581 | ** to be executed (to establish a read lock) before this opcode is |
||
3582 | ** invoked. |
||
3583 | */ |
||
3584 | case OP_VerifyCookie: |
||
3585 | { |
||
3586 | u32 iMeta = 0; |
||
3587 | u32 iGen; |
||
3588 | Btree pBt; |
||
3589 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < db.nDb ); |
||
3590 | Debug.Assert( ( p.btreeMask & ( (yDbMask)1 << pOp.p1 ) ) != 0 ); |
||
3591 | Debug.Assert( sqlite3SchemaMutexHeld( db, pOp.p1, null ) ); |
||
3592 | pBt = db.aDb[pOp.p1].pBt; |
||
3593 | if ( pBt != null ) |
||
3594 | { |
||
3595 | sqlite3BtreeGetMeta( pBt, BTREE_SCHEMA_VERSION, ref iMeta ); |
||
3596 | iGen = db.aDb[pOp.p1].pSchema.iGeneration; |
||
3597 | } |
||
3598 | else |
||
3599 | { |
||
3600 | iGen = iMeta = 0; |
||
3601 | } |
||
3602 | if ( iMeta != pOp.p2 || iGen != pOp.p3 ) |
||
3603 | { |
||
3604 | sqlite3DbFree( db, ref p.zErrMsg ); |
||
3605 | p.zErrMsg = "database schema has changed";// sqlite3DbStrDup(db, "database schema has changed"); |
||
3606 | /* If the schema-cookie from the database file matches the cookie |
||
3607 | ** stored with the in-memory representation of the schema, do |
||
3608 | ** not reload the schema from the database file. |
||
3609 | ** |
||
3610 | ** If virtual-tables are in use, this is not just an optimization. |
||
3611 | ** Often, v-tables store their data in other SQLite tables, which |
||
3612 | ** are queried from within xNext() and other v-table methods using |
||
3613 | ** prepared queries. If such a query is out-of-date, we do not want to |
||
3614 | ** discard the database schema, as the user code implementing the |
||
3615 | ** v-table would have to be ready for the sqlite3_vtab structure itself |
||
3616 | ** to be invalidated whenever sqlite3_step() is called from within |
||
3617 | ** a v-table method. |
||
3618 | */ |
||
3619 | if ( db.aDb[pOp.p1].pSchema.schema_cookie != iMeta ) |
||
3620 | { |
||
3621 | sqlite3ResetInternalSchema( db, pOp.p1 ); |
||
3622 | } |
||
3623 | |||
3624 | p.expired = true; |
||
3625 | rc = SQLITE_SCHEMA; |
||
3626 | } |
||
3627 | break; |
||
3628 | } |
||
3629 | |||
3630 | /* Opcode: OpenRead P1 P2 P3 P4 P5 |
||
3631 | ** |
||
3632 | ** Open a read-only cursor for the database table whose root page is |
||
3633 | ** P2 in a database file. The database file is determined by P3. |
||
3634 | ** P3==0 means the main database, P3==1 means the database used for |
||
3635 | ** temporary tables, and P3>1 means used the corresponding attached |
||
3636 | ** database. Give the new cursor an identifier of P1. The P1 |
||
3637 | ** values need not be contiguous but all P1 values should be small integers. |
||
3638 | ** It is an error for P1 to be negative. |
||
3639 | ** |
||
3640 | ** If P5!=0 then use the content of register P2 as the root page, not |
||
3641 | ** the value of P2 itself. |
||
3642 | ** |
||
3643 | ** There will be a read lock on the database whenever there is an |
||
3644 | ** open cursor. If the database was unlocked prior to this instruction |
||
3645 | ** then a read lock is acquired as part of this instruction. A read |
||
3646 | ** lock allows other processes to read the database but prohibits |
||
3647 | ** any other process from modifying the database. The read lock is |
||
3648 | ** released when all cursors are closed. If this instruction attempts |
||
3649 | ** to get a read lock but fails, the script terminates with an |
||
3650 | ** SQLITE_BUSY error code. |
||
3651 | ** |
||
3652 | ** The P4 value may be either an integer (P4_INT32) or a pointer to |
||
3653 | ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo |
||
3654 | ** structure, then said structure defines the content and collating |
||
3655 | ** sequence of the index being opened. Otherwise, if P4 is an integer |
||
3656 | ** value, it is set to the number of columns in the table. |
||
3657 | ** |
||
3658 | ** See also OpenWrite. |
||
3659 | */ |
||
3660 | /* Opcode: OpenWrite P1 P2 P3 P4 P5 |
||
3661 | ** |
||
3662 | ** Open a read/write cursor named P1 on the table or index whose root |
||
3663 | ** page is P2. Or if P5!=0 use the content of register P2 to find the |
||
3664 | ** root page. |
||
3665 | ** |
||
3666 | ** The P4 value may be either an integer (P4_INT32) or a pointer to |
||
3667 | ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo |
||
3668 | ** structure, then said structure defines the content and collating |
||
3669 | ** sequence of the index being opened. Otherwise, if P4 is an integer |
||
3670 | ** value, it is set to the number of columns in the table, or to the |
||
3671 | ** largest index of any column of the table that is actually used. |
||
3672 | ** |
||
3673 | ** This instruction works just like OpenRead except that it opens the cursor |
||
3674 | ** in read/write mode. For a given table, there can be one or more read-only |
||
3675 | ** cursors or a single read/write cursor but not both. |
||
3676 | ** |
||
3677 | ** See also OpenRead. |
||
3678 | */ |
||
3679 | case OP_OpenRead: |
||
3680 | case OP_OpenWrite: |
||
3681 | { |
||
3682 | int nField; |
||
3683 | KeyInfo pKeyInfo; |
||
3684 | int p2; |
||
3685 | int iDb; |
||
3686 | int wrFlag; |
||
3687 | Btree pX; |
||
3688 | VdbeCursor pCur; |
||
3689 | Db pDb; |
||
3690 | |||
3691 | if ( p.expired ) |
||
3692 | { |
||
3693 | rc = SQLITE_ABORT; |
||
3694 | break; |
||
3695 | } |
||
3696 | |||
3697 | nField = 0; |
||
3698 | pKeyInfo = null; |
||
3699 | p2 = pOp.p2; |
||
3700 | iDb = pOp.p3; |
||
3701 | Debug.Assert( iDb >= 0 && iDb < db.nDb ); |
||
3702 | Debug.Assert( ( p.btreeMask & ( ( (yDbMask)1 ) << iDb ) ) != 0 ); |
||
3703 | pDb = db.aDb[iDb]; |
||
3704 | pX = pDb.pBt; |
||
3705 | Debug.Assert( pX != null ); |
||
3706 | if ( pOp.opcode == OP_OpenWrite ) |
||
3707 | { |
||
3708 | wrFlag = 1; |
||
3709 | Debug.Assert( sqlite3SchemaMutexHeld( db, iDb, null ) ); |
||
3710 | if ( pDb.pSchema.file_format < p.minWriteFileFormat ) |
||
3711 | { |
||
3712 | p.minWriteFileFormat = pDb.pSchema.file_format; |
||
3713 | } |
||
3714 | } |
||
3715 | else |
||
3716 | { |
||
3717 | wrFlag = 0; |
||
3718 | } |
||
3719 | if ( pOp.p5 != 0 ) |
||
3720 | { |
||
3721 | Debug.Assert( p2 > 0 ); |
||
3722 | Debug.Assert( p2 <= p.nMem ); |
||
3723 | pIn2 = aMem[p2]; |
||
3724 | Debug.Assert( memIsValid( pIn2 ) ); |
||
3725 | Debug.Assert( ( pIn2.flags & MEM_Int ) != 0 ); |
||
3726 | sqlite3VdbeMemIntegerify( pIn2 ); |
||
3727 | p2 = (int)pIn2.u.i; |
||
3728 | /* The p2 value always comes from a prior OP_CreateTable opcode and |
||
3729 | ** that opcode will always set the p2 value to 2 or more or else fail. |
||
3730 | ** If there were a failure, the prepared statement would have halted |
||
3731 | ** before reaching this instruction. */ |
||
3732 | if ( NEVER( p2 < 2 ) ) |
||
3733 | { |
||
3734 | rc = SQLITE_CORRUPT_BKPT(); |
||
3735 | goto abort_due_to_error; |
||
3736 | } |
||
3737 | } |
||
3738 | if ( pOp.p4type == P4_KEYINFO ) |
||
3739 | { |
||
3740 | pKeyInfo = pOp.p4.pKeyInfo; |
||
3741 | pKeyInfo.enc = ENC( p.db ); |
||
3742 | nField = pKeyInfo.nField + 1; |
||
3743 | } |
||
3744 | else if ( pOp.p4type == P4_INT32 ) |
||
3745 | { |
||
3746 | nField = pOp.p4.i; |
||
3747 | } |
||
3748 | Debug.Assert( pOp.p1 >= 0 ); |
||
3749 | pCur = allocateCursor( p, pOp.p1, nField, iDb, 1 ); |
||
3750 | if ( pCur == null ) |
||
3751 | goto no_mem; |
||
3752 | pCur.nullRow = true; |
||
3753 | pCur.isOrdered = true; |
||
3754 | rc = sqlite3BtreeCursor( pX, p2, wrFlag, pKeyInfo, pCur.pCursor ); |
||
3755 | pCur.pKeyInfo = pKeyInfo; |
||
3756 | /* Since it performs no memory allocation or IO, the only values that |
||
3757 | ** sqlite3BtreeCursor() may return are SQLITE_EMPTY and SQLITE_OK. |
||
3758 | ** SQLITE_EMPTY is only returned when attempting to open the table |
||
3759 | ** rooted at page 1 of a zero-byte database. */ |
||
3760 | Debug.Assert( rc == SQLITE_EMPTY || rc == SQLITE_OK ); |
||
3761 | if ( rc == SQLITE_EMPTY ) |
||
3762 | { |
||
3763 | sqlite3MemFreeBtCursor( ref pCur.pCursor ); |
||
3764 | rc = SQLITE_OK; |
||
3765 | } |
||
3766 | /* Set the VdbeCursor.isTable and isIndex variables. Previous versions of |
||
3767 | ** SQLite used to check if the root-page flags were sane at this point |
||
3768 | ** and report database corruption if they were not, but this check has |
||
3769 | ** since moved into the btree layer. */ |
||
3770 | pCur.isTable = pOp.p4type != P4_KEYINFO; |
||
3771 | pCur.isIndex = !pCur.isTable; |
||
3772 | break; |
||
3773 | } |
||
3774 | |||
3775 | /* Opcode: OpenEphemeral P1 P2 * P4 * |
||
3776 | ** |
||
3777 | ** Open a new cursor P1 to a transient table. |
||
3778 | ** The cursor is always opened read/write even if |
||
3779 | ** the main database is read-only. The ephemeral |
||
3780 | ** table is deleted automatically when the cursor is closed. |
||
3781 | ** |
||
3782 | ** P2 is the number of columns in the ephemeral table. |
||
3783 | ** The cursor points to a BTree table if P4==0 and to a BTree index |
||
3784 | ** if P4 is not 0. If P4 is not NULL, it points to a KeyInfo structure |
||
3785 | ** that defines the format of keys in the index. |
||
3786 | ** |
||
3787 | ** This opcode was once called OpenTemp. But that created |
||
3788 | ** confusion because the term "temp table", might refer either |
||
3789 | ** to a TEMP table at the SQL level, or to a table opened by |
||
3790 | ** this opcode. Then this opcode was call OpenVirtual. But |
||
3791 | ** that created confusion with the whole virtual-table idea. |
||
3792 | */ |
||
3793 | /* Opcode: OpenAutoindex P1 P2 * P4 * |
||
3794 | ** |
||
3795 | ** This opcode works the same as OP_OpenEphemeral. It has a |
||
3796 | ** different name to distinguish its use. Tables created using |
||
3797 | ** by this opcode will be used for automatically created transient |
||
3798 | ** indices in joins. |
||
3799 | */ |
||
3800 | case OP_OpenAutoindex: |
||
3801 | case OP_OpenEphemeral: |
||
3802 | { |
||
3803 | VdbeCursor pCx; |
||
3804 | const int vfsFlags = |
||
3805 | SQLITE_OPEN_READWRITE | |
||
3806 | SQLITE_OPEN_CREATE | |
||
3807 | SQLITE_OPEN_EXCLUSIVE | |
||
3808 | SQLITE_OPEN_DELETEONCLOSE | |
||
3809 | SQLITE_OPEN_TRANSIENT_DB; |
||
3810 | |||
3811 | Debug.Assert( pOp.p1 >= 0 ); |
||
3812 | pCx = allocateCursor( p, pOp.p1, pOp.p2, -1, 1 ); |
||
3813 | if ( pCx == null ) |
||
3814 | goto no_mem; |
||
3815 | pCx.nullRow = true; |
||
3816 | rc = sqlite3BtreeOpen( db.pVfs, null, db, ref pCx.pBt, |
||
3817 | BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp.p5, vfsFlags ); |
||
3818 | if ( rc == SQLITE_OK ) |
||
3819 | { |
||
3820 | rc = sqlite3BtreeBeginTrans( pCx.pBt, 1 ); |
||
3821 | } |
||
3822 | if ( rc == SQLITE_OK ) |
||
3823 | { |
||
3824 | /* If a transient index is required, create it by calling |
||
3825 | ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before |
||
3826 | ** opening it. If a transient table is required, just use the |
||
3827 | ** automatically created table with root-page 1 (an BLOB_INTKEY table). |
||
3828 | */ |
||
3829 | if ( pOp.p4.pKeyInfo != null ) |
||
3830 | { |
||
3831 | int pgno = 0; |
||
3832 | Debug.Assert( pOp.p4type == P4_KEYINFO ); |
||
3833 | rc = sqlite3BtreeCreateTable( pCx.pBt, ref pgno, BTREE_BLOBKEY ); |
||
3834 | if ( rc == SQLITE_OK ) |
||
3835 | { |
||
3836 | Debug.Assert( pgno == MASTER_ROOT + 1 ); |
||
3837 | rc = sqlite3BtreeCursor( pCx.pBt, pgno, 1, |
||
3838 | pOp.p4.pKeyInfo, pCx.pCursor ); |
||
3839 | pCx.pKeyInfo = pOp.p4.pKeyInfo; |
||
3840 | pCx.pKeyInfo.enc = ENC( p.db ); |
||
3841 | } |
||
3842 | pCx.isTable = false; |
||
3843 | } |
||
3844 | else |
||
3845 | { |
||
3846 | rc = sqlite3BtreeCursor( pCx.pBt, MASTER_ROOT, 1, null, pCx.pCursor ); |
||
3847 | pCx.isTable = true; |
||
3848 | } |
||
3849 | } |
||
3850 | pCx.isOrdered = ( pOp.p5 != BTREE_UNORDERED ); |
||
3851 | pCx.isIndex = !pCx.isTable; |
||
3852 | break; |
||
3853 | } |
||
3854 | |||
3855 | /* Opcode: OpenPseudo P1 P2 P3 * * |
||
3856 | ** |
||
3857 | ** Open a new cursor that points to a fake table that contains a single |
||
3858 | ** row of data. The content of that one row in the content of memory |
||
3859 | ** register P2. In other words, cursor P1 becomes an alias for the |
||
3860 | ** MEM_Blob content contained in register P2. |
||
3861 | ** |
||
3862 | ** A pseudo-table created by this opcode is used to hold a single |
||
3863 | ** row output from the sorter so that the row can be decomposed into |
||
3864 | ** individual columns using the OP_Column opcode. The OP_Column opcode |
||
3865 | ** is the only cursor opcode that works with a pseudo-table. |
||
3866 | ** |
||
3867 | ** P3 is the number of fields in the records that will be stored by |
||
3868 | ** the pseudo-table. |
||
3869 | */ |
||
3870 | case OP_OpenPseudo: |
||
3871 | { |
||
3872 | VdbeCursor pCx; |
||
3873 | Debug.Assert( pOp.p1 >= 0 ); |
||
3874 | pCx = allocateCursor( p, pOp.p1, pOp.p3, -1, 0 ); |
||
3875 | if ( pCx == null ) |
||
3876 | goto no_mem; |
||
3877 | pCx.nullRow = true; |
||
3878 | pCx.pseudoTableReg = pOp.p2; |
||
3879 | pCx.isTable = true; |
||
3880 | pCx.isIndex = false; |
||
3881 | break; |
||
3882 | } |
||
3883 | |||
3884 | /* Opcode: Close P1 * * * * |
||
3885 | ** |
||
3886 | ** Close a cursor previously opened as P1. If P1 is not |
||
3887 | ** currently open, this instruction is a no-op. |
||
3888 | */ |
||
3889 | case OP_Close: |
||
3890 | { |
||
3891 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
3892 | sqlite3VdbeFreeCursor( p, p.apCsr[pOp.p1] ); |
||
3893 | p.apCsr[pOp.p1] = null; |
||
3894 | break; |
||
3895 | } |
||
3896 | |||
3897 | /* Opcode: SeekGe P1 P2 P3 P4 * |
||
3898 | ** |
||
3899 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
||
3900 | ** use the value in register P3 as the key. If cursor P1 refers |
||
3901 | ** to an SQL index, then P3 is the first in an array of P4 registers |
||
3902 | ** that are used as an unpacked index key. |
||
3903 | ** |
||
3904 | ** Reposition cursor P1 so that it points to the smallest entry that |
||
3905 | ** is greater than or equal to the key value. If there are no records |
||
3906 | ** greater than or equal to the key and P2 is not zero, then jump to P2. |
||
3907 | ** |
||
3908 | ** See also: Found, NotFound, Distinct, SeekLt, SeekGt, SeekLe |
||
3909 | */ |
||
3910 | /* Opcode: SeekGt P1 P2 P3 P4 * |
||
3911 | ** |
||
3912 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
||
3913 | ** use the value in register P3 as a key. If cursor P1 refers |
||
3914 | ** to an SQL index, then P3 is the first in an array of P4 registers |
||
3915 | ** that are used as an unpacked index key. |
||
3916 | ** |
||
3917 | ** Reposition cursor P1 so that it points to the smallest entry that |
||
3918 | ** is greater than the key value. If there are no records greater than |
||
3919 | ** the key and P2 is not zero, then jump to P2. |
||
3920 | ** |
||
3921 | ** See also: Found, NotFound, Distinct, SeekLt, SeekGe, SeekLe |
||
3922 | */ |
||
3923 | /* Opcode: SeekLt P1 P2 P3 P4 * |
||
3924 | ** |
||
3925 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
||
3926 | ** use the value in register P3 as a key. If cursor P1 refers |
||
3927 | ** to an SQL index, then P3 is the first in an array of P4 registers |
||
3928 | ** that are used as an unpacked index key. |
||
3929 | ** |
||
3930 | ** Reposition cursor P1 so that it points to the largest entry that |
||
3931 | ** is less than the key value. If there are no records less than |
||
3932 | ** the key and P2 is not zero, then jump to P2. |
||
3933 | ** |
||
3934 | ** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLe |
||
3935 | */ |
||
3936 | /* Opcode: SeekLe P1 P2 P3 P4 * |
||
3937 | ** |
||
3938 | ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), |
||
3939 | ** use the value in register P3 as a key. If cursor P1 refers |
||
3940 | ** to an SQL index, then P3 is the first in an array of P4 registers |
||
3941 | ** that are used as an unpacked index key. |
||
3942 | ** |
||
3943 | ** Reposition cursor P1 so that it points to the largest entry that |
||
3944 | ** is less than or equal to the key value. If there are no records |
||
3945 | ** less than or equal to the key and P2 is not zero, then jump to P2. |
||
3946 | ** |
||
3947 | ** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt |
||
3948 | */ |
||
3949 | case OP_SeekLt: /* jump, in3 */ |
||
3950 | case OP_SeekLe: /* jump, in3 */ |
||
3951 | case OP_SeekGe: /* jump, in3 */ |
||
3952 | case OP_SeekGt: |
||
3953 | { /* jump, in3 */ |
||
3954 | int res; |
||
3955 | int oc; |
||
3956 | VdbeCursor pC; |
||
3957 | UnpackedRecord r; |
||
3958 | int nField; |
||
3959 | i64 iKey; /* The rowid we are to seek to */ |
||
3960 | |||
3961 | res = 0; |
||
3962 | r = new UnpackedRecord(); |
||
3963 | |||
3964 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
3965 | Debug.Assert( pOp.p2 != 0 ); |
||
3966 | pC = p.apCsr[pOp.p1]; |
||
3967 | Debug.Assert( pC != null ); |
||
3968 | Debug.Assert( pC.pseudoTableReg == 0 ); |
||
3969 | Debug.Assert( OP_SeekLe == OP_SeekLt + 1 ); |
||
3970 | Debug.Assert( OP_SeekGe == OP_SeekLt + 2 ); |
||
3971 | Debug.Assert( OP_SeekGt == OP_SeekLt + 3 ); |
||
3972 | Debug.Assert( pC.isOrdered ); |
||
3973 | if ( pC.pCursor != null ) |
||
3974 | { |
||
3975 | oc = pOp.opcode; |
||
3976 | pC.nullRow = false; |
||
3977 | if ( pC.isTable ) |
||
3978 | { |
||
3979 | /* The input value in P3 might be of any type: integer, real, string, |
||
3980 | ** blob, or NULL. But it needs to be an integer before we can do |
||
3981 | ** the seek, so convert it. */ |
||
3982 | pIn3 = aMem[pOp.p3]; |
||
3983 | applyNumericAffinity( pIn3 ); |
||
3984 | iKey = sqlite3VdbeIntValue( pIn3 ); |
||
3985 | pC.rowidIsValid = false; |
||
3986 | |||
3987 | /* If the P3 value could not be converted into an integer without |
||
3988 | ** loss of information, then special processing is required... */ |
||
3989 | if ( ( pIn3.flags & MEM_Int ) == 0 ) |
||
3990 | { |
||
3991 | if ( ( pIn3.flags & MEM_Real ) == 0 ) |
||
3992 | { |
||
3993 | /* If the P3 value cannot be converted into any kind of a number, |
||
3994 | ** then the seek is not possible, so jump to P2 */ |
||
3995 | pc = pOp.p2 - 1; |
||
3996 | break; |
||
3997 | } |
||
3998 | /* If we reach this point, then the P3 value must be a floating |
||
3999 | ** point number. */ |
||
4000 | Debug.Assert( ( pIn3.flags & MEM_Real ) != 0 ); |
||
4001 | |||
4002 | if ( iKey == SMALLEST_INT64 && ( pIn3.r < (double)iKey || pIn3.r > 0 ) ) |
||
4003 | { |
||
4004 | /* The P3 value is too large in magnitude to be expressed as an |
||
4005 | ** integer. */ |
||
4006 | res = 1; |
||
4007 | if ( pIn3.r < 0 ) |
||
4008 | { |
||
4009 | if ( oc >= OP_SeekGe ) |
||
4010 | { |
||
4011 | Debug.Assert( oc == OP_SeekGe || oc == OP_SeekGt ); |
||
4012 | rc = sqlite3BtreeFirst( pC.pCursor, ref res ); |
||
4013 | if ( rc != SQLITE_OK ) |
||
4014 | goto abort_due_to_error; |
||
4015 | } |
||
4016 | } |
||
4017 | else |
||
4018 | { |
||
4019 | if ( oc <= OP_SeekLe ) |
||
4020 | { |
||
4021 | Debug.Assert( oc == OP_SeekLt || oc == OP_SeekLe ); |
||
4022 | rc = sqlite3BtreeLast( pC.pCursor, ref res ); |
||
4023 | if ( rc != SQLITE_OK ) |
||
4024 | goto abort_due_to_error; |
||
4025 | } |
||
4026 | } |
||
4027 | if ( res != 0 ) |
||
4028 | { |
||
4029 | pc = pOp.p2 - 1; |
||
4030 | } |
||
4031 | break; |
||
4032 | } |
||
4033 | else if ( oc == OP_SeekLt || oc == OP_SeekGe ) |
||
4034 | { |
||
4035 | /* Use the ceiling() function to convert real.int */ |
||
4036 | if ( pIn3.r > (double)iKey ) |
||
4037 | iKey++; |
||
4038 | } |
||
4039 | else |
||
4040 | { |
||
4041 | /* Use the floor() function to convert real.int */ |
||
4042 | Debug.Assert( oc == OP_SeekLe || oc == OP_SeekGt ); |
||
4043 | if ( pIn3.r < (double)iKey ) |
||
4044 | iKey--; |
||
4045 | } |
||
4046 | } |
||
4047 | rc = sqlite3BtreeMovetoUnpacked( pC.pCursor, null, iKey, 0, ref res ); |
||
4048 | if ( rc != SQLITE_OK ) |
||
4049 | { |
||
4050 | goto abort_due_to_error; |
||
4051 | } |
||
4052 | if ( res == 0 ) |
||
4053 | { |
||
4054 | pC.rowidIsValid = true; |
||
4055 | pC.lastRowid = iKey; |
||
4056 | } |
||
4057 | } |
||
4058 | else |
||
4059 | { |
||
4060 | nField = pOp.p4.i; |
||
4061 | Debug.Assert( pOp.p4type == P4_INT32 ); |
||
4062 | Debug.Assert( nField > 0 ); |
||
4063 | r.pKeyInfo = pC.pKeyInfo; |
||
4064 | r.nField = (u16)nField; |
||
4065 | |||
4066 | /* The next line of code computes as follows, only faster: |
||
4067 | ** if( oc==OP_SeekGt || oc==OP_SeekLe ){ |
||
4068 | ** r.flags = UNPACKED_INCRKEY; |
||
4069 | ** }else{ |
||
4070 | ** r.flags = 0; |
||
4071 | ** } |
||
4072 | */ |
||
4073 | r.flags = (u16)( UNPACKED_INCRKEY * ( 1 & ( oc - OP_SeekLt ) ) ); |
||
4074 | Debug.Assert( oc != OP_SeekGt || r.flags == UNPACKED_INCRKEY ); |
||
4075 | Debug.Assert( oc != OP_SeekLe || r.flags == UNPACKED_INCRKEY ); |
||
4076 | Debug.Assert( oc != OP_SeekGe || r.flags == 0 ); |
||
4077 | Debug.Assert( oc != OP_SeekLt || r.flags == 0 ); |
||
4078 | |||
4079 | r.aMem = new Mem[r.nField]; |
||
4080 | for ( int rI = 0; rI < r.nField; rI++ ) |
||
4081 | r.aMem[rI] = aMem[pOp.p3 + rI];// r.aMem = aMem[pOp.p3]; |
||
4082 | #if SQLITE_DEBUG |
||
4083 | { |
||
4084 | int i; |
||
4085 | for ( i = 0; i < r.nField; i++ ) |
||
4086 | Debug.Assert( memIsValid( r.aMem[i] ) ); |
||
4087 | } |
||
4088 | #endif |
||
4089 | ////ExpandBlob( r.aMem[0] ); |
||
4090 | rc = sqlite3BtreeMovetoUnpacked( pC.pCursor, r, 0, 0, ref res ); |
||
4091 | if ( rc != SQLITE_OK ) |
||
4092 | { |
||
4093 | goto abort_due_to_error; |
||
4094 | } |
||
4095 | pC.rowidIsValid = false; |
||
4096 | } |
||
4097 | pC.deferredMoveto = false; |
||
4098 | pC.cacheStatus = CACHE_STALE; |
||
4099 | #if SQLITE_TEST |
||
4100 | #if !TCLSH |
||
4101 | sqlite3_search_count++; |
||
4102 | #else |
||
4103 | sqlite3_search_count.iValue++; |
||
4104 | #endif |
||
4105 | #endif |
||
4106 | if ( oc >= OP_SeekGe ) |
||
4107 | { |
||
4108 | Debug.Assert( oc == OP_SeekGe || oc == OP_SeekGt ); |
||
4109 | if ( res < 0 || ( res == 0 && oc == OP_SeekGt ) ) |
||
4110 | { |
||
4111 | rc = sqlite3BtreeNext( pC.pCursor, ref res ); |
||
4112 | if ( rc != SQLITE_OK ) |
||
4113 | goto abort_due_to_error; |
||
4114 | pC.rowidIsValid = false; |
||
4115 | } |
||
4116 | else |
||
4117 | { |
||
4118 | res = 0; |
||
4119 | } |
||
4120 | } |
||
4121 | else |
||
4122 | { |
||
4123 | Debug.Assert( oc == OP_SeekLt || oc == OP_SeekLe ); |
||
4124 | if ( res > 0 || ( res == 0 && oc == OP_SeekLt ) ) |
||
4125 | { |
||
4126 | rc = sqlite3BtreePrevious( pC.pCursor, ref res ); |
||
4127 | if ( rc != SQLITE_OK ) |
||
4128 | goto abort_due_to_error; |
||
4129 | pC.rowidIsValid = false; |
||
4130 | } |
||
4131 | else |
||
4132 | { |
||
4133 | /* res might be negative because the table is empty. Check to |
||
4134 | ** see if this is the case. |
||
4135 | */ |
||
4136 | res = sqlite3BtreeEof( pC.pCursor ) ? 1 : 0; |
||
4137 | } |
||
4138 | } |
||
4139 | Debug.Assert( pOp.p2 > 0 ); |
||
4140 | if ( res != 0 ) |
||
4141 | { |
||
4142 | pc = pOp.p2 - 1; |
||
4143 | } |
||
4144 | } |
||
4145 | else |
||
4146 | { |
||
4147 | /* This happens when attempting to open the sqlite3_master table |
||
4148 | ** for read access returns SQLITE_EMPTY. In this case always |
||
4149 | ** take the jump (since there are no records in the table). |
||
4150 | */ |
||
4151 | pc = pOp.p2 - 1; |
||
4152 | } |
||
4153 | break; |
||
4154 | } |
||
4155 | |||
4156 | /* Opcode: Seek P1 P2 * * * |
||
4157 | ** |
||
4158 | ** P1 is an open table cursor and P2 is a rowid integer. Arrange |
||
4159 | ** for P1 to move so that it points to the rowid given by P2. |
||
4160 | ** |
||
4161 | ** This is actually a deferred seek. Nothing actually happens until |
||
4162 | ** the cursor is used to read a record. That way, if no reads |
||
4163 | ** occur, no unnecessary I/O happens. |
||
4164 | */ |
||
4165 | case OP_Seek: |
||
4166 | { /* in2 */ |
||
4167 | VdbeCursor pC; |
||
4168 | |||
4169 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
4170 | pC = p.apCsr[pOp.p1]; |
||
4171 | Debug.Assert( ALWAYS( pC != null ) ); |
||
4172 | if ( pC.pCursor != null ) |
||
4173 | { |
||
4174 | Debug.Assert( pC.isTable ); |
||
4175 | pC.nullRow = false; |
||
4176 | pIn2 = aMem[pOp.p2]; |
||
4177 | pC.movetoTarget = sqlite3VdbeIntValue( pIn2 ); |
||
4178 | pC.rowidIsValid = false; |
||
4179 | pC.deferredMoveto = true; |
||
4180 | } |
||
4181 | break; |
||
4182 | } |
||
4183 | |||
4184 | /* Opcode: Found P1 P2 P3 P4 * |
||
4185 | ** |
||
4186 | ** If P4==0 then register P3 holds a blob constructed by MakeRecord. If |
||
4187 | ** P4>0 then register P3 is the first of P4 registers that form an unpacked |
||
4188 | ** record. |
||
4189 | ** |
||
4190 | ** Cursor P1 is on an index btree. If the record identified by P3 and P4 |
||
4191 | ** is a prefix of any entry in P1 then a jump is made to P2 and |
||
4192 | ** P1 is left pointing at the matching entry. |
||
4193 | */ |
||
4194 | /* Opcode: NotFound P1 P2 P3 P4 * |
||
4195 | ** |
||
4196 | ** If P4==0 then register P3 holds a blob constructed by MakeRecord. If |
||
4197 | ** P4>0 then register P3 is the first of P4 registers that form an unpacked |
||
4198 | ** record. |
||
4199 | ** |
||
4200 | ** Cursor P1 is on an index btree. If the record identified by P3 and P4 |
||
4201 | ** is not the prefix of any entry in P1 then a jump is made to P2. If P1 |
||
4202 | ** does contain an entry whose prefix matches the P3/P4 record then control |
||
4203 | ** falls through to the next instruction and P1 is left pointing at the |
||
4204 | ** matching entry. |
||
4205 | ** |
||
4206 | ** See also: Found, NotExists, IsUnique |
||
4207 | */ |
||
4208 | case OP_NotFound: /* jump, in3 */ |
||
4209 | case OP_Found: |
||
4210 | { /* jump, in3 */ |
||
4211 | int alreadyExists; |
||
4212 | VdbeCursor pC; |
||
4213 | int res = 0; |
||
4214 | UnpackedRecord pIdxKey; |
||
4215 | UnpackedRecord r = new UnpackedRecord(); |
||
4216 | UnpackedRecord aTempRec = new UnpackedRecord();//char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; |
||
4217 | |||
4218 | #if SQLITE_TEST |
||
4219 | #if !TCLSH |
||
4220 | sqlite3_found_count++; |
||
4221 | #else |
||
4222 | sqlite3_found_count.iValue++; |
||
4223 | #endif |
||
4224 | #endif |
||
4225 | alreadyExists = 0; |
||
4226 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
4227 | Debug.Assert( pOp.p4type == P4_INT32 ); |
||
4228 | pC = p.apCsr[pOp.p1]; |
||
4229 | Debug.Assert( pC != null ); |
||
4230 | pIn3 = aMem[pOp.p3]; |
||
4231 | if ( ALWAYS( pC.pCursor != null ) ) |
||
4232 | { |
||
4233 | |||
4234 | Debug.Assert( !pC.isTable ); |
||
4235 | if ( pOp.p4.i > 0 ) |
||
4236 | { |
||
4237 | r.pKeyInfo = pC.pKeyInfo; |
||
4238 | r.nField = (u16)pOp.p4.i; |
||
4239 | r.aMem = new Mem[r.nField]; |
||
4240 | for ( int i = 0; i < r.aMem.Length; i++ ) |
||
4241 | { |
||
4242 | r.aMem[i] = aMem[pOp.p3 + i]; |
||
4243 | #if SQLITE_DEBUG |
||
4244 | Debug.Assert( memIsValid( r.aMem[i] ) ); |
||
4245 | #endif |
||
4246 | } |
||
4247 | r.flags = UNPACKED_PREFIX_MATCH; |
||
4248 | pIdxKey = r; |
||
4249 | } |
||
4250 | else |
||
4251 | { |
||
4252 | Debug.Assert( ( pIn3.flags & MEM_Blob ) != 0 ); |
||
4253 | Debug.Assert( ( pIn3.flags & MEM_Zero ) == 0 ); /* zeroblobs already expanded */ |
||
4254 | pIdxKey = sqlite3VdbeRecordUnpack( pC.pKeyInfo, pIn3.n, pIn3.zBLOB, |
||
4255 | aTempRec, 0 );//sizeof( aTempRec ) ); |
||
4256 | if ( pIdxKey == null ) |
||
4257 | { |
||
4258 | goto no_mem; |
||
4259 | } |
||
4260 | pIdxKey.flags |= UNPACKED_PREFIX_MATCH; |
||
4261 | } |
||
4262 | rc = sqlite3BtreeMovetoUnpacked( pC.pCursor, pIdxKey, 0, 0, ref res ); |
||
4263 | if ( pOp.p4.i == 0 ) |
||
4264 | { |
||
4265 | sqlite3VdbeDeleteUnpackedRecord( pIdxKey ); |
||
4266 | } |
||
4267 | if ( rc != SQLITE_OK ) |
||
4268 | { |
||
4269 | break; |
||
4270 | } |
||
4271 | alreadyExists = ( res == 0 ) ? 1 : 0; |
||
4272 | pC.deferredMoveto = false; |
||
4273 | pC.cacheStatus = CACHE_STALE; |
||
4274 | } |
||
4275 | if ( pOp.opcode == OP_Found ) |
||
4276 | { |
||
4277 | if ( alreadyExists != 0 ) |
||
4278 | pc = pOp.p2 - 1; |
||
4279 | } |
||
4280 | else |
||
4281 | { |
||
4282 | if ( 0 == alreadyExists ) |
||
4283 | pc = pOp.p2 - 1; |
||
4284 | } |
||
4285 | break; |
||
4286 | } |
||
4287 | |||
4288 | /* Opcode: IsUnique P1 P2 P3 P4 * |
||
4289 | ** |
||
4290 | ** Cursor P1 is open on an index b-tree - that is to say, a btree which |
||
4291 | ** no data and where the key are records generated by OP_MakeRecord with |
||
4292 | ** the list field being the integer ROWID of the entry that the index |
||
4293 | ** entry refers to. |
||
4294 | ** |
||
4295 | ** The P3 register contains an integer record number. Call this record |
||
4296 | ** number R. Register P4 is the first in a set of N contiguous registers |
||
4297 | ** that make up an unpacked index key that can be used with cursor P1. |
||
4298 | ** The value of N can be inferred from the cursor. N includes the rowid |
||
4299 | ** value appended to the end of the index record. This rowid value may |
||
4300 | ** or may not be the same as R. |
||
4301 | ** |
||
4302 | ** If any of the N registers beginning with register P4 contains a NULL |
||
4303 | ** value, jump immediately to P2. |
||
4304 | ** |
||
4305 | ** Otherwise, this instruction checks if cursor P1 contains an entry |
||
4306 | ** where the first (N-1) fields match but the rowid value at the end |
||
4307 | ** of the index entry is not R. If there is no such entry, control jumps |
||
4308 | ** to instruction P2. Otherwise, the rowid of the conflicting index |
||
4309 | ** entry is copied to register P3 and control falls through to the next |
||
4310 | ** instruction. |
||
4311 | ** |
||
4312 | ** See also: NotFound, NotExists, Found |
||
4313 | */ |
||
4314 | case OP_IsUnique: |
||
4315 | { /* jump, in3 */ |
||
4316 | u16 ii; |
||
4317 | VdbeCursor pCx = new VdbeCursor(); |
||
4318 | BtCursor pCrsr; |
||
4319 | u16 nField; |
||
4320 | Mem[] aMx; |
||
4321 | UnpackedRecord r; /* B-Tree index search key */ |
||
4322 | i64 R; /* Rowid stored in register P3 */ |
||
4323 | |||
4324 | r = new UnpackedRecord(); |
||
4325 | |||
4326 | pIn3 = aMem[pOp.p3]; |
||
4327 | //aMx = aMem[pOp->p4.i]; |
||
4328 | /* Assert that the values of parameters P1 and P4 are in range. */ |
||
4329 | Debug.Assert( pOp.p4type == P4_INT32 ); |
||
4330 | Debug.Assert( pOp.p4.i > 0 && pOp.p4.i <= p.nMem ); |
||
4331 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
4332 | |||
4333 | /* Find the index cursor. */ |
||
4334 | pCx = p.apCsr[pOp.p1]; |
||
4335 | Debug.Assert( !pCx.deferredMoveto ); |
||
4336 | pCx.seekResult = 0; |
||
4337 | pCx.cacheStatus = CACHE_STALE; |
||
4338 | pCrsr = pCx.pCursor; |
||
4339 | |||
4340 | /* If any of the values are NULL, take the jump. */ |
||
4341 | nField = pCx.pKeyInfo.nField; |
||
4342 | aMx = new Mem[nField + 1]; |
||
4343 | for ( ii = 0; ii < nField; ii++ ) |
||
4344 | { |
||
4345 | aMx[ii] = aMem[pOp.p4.i + ii]; |
||
4346 | if ( ( aMx[ii].flags & MEM_Null ) != 0 ) |
||
4347 | { |
||
4348 | pc = pOp.p2 - 1; |
||
4349 | pCrsr = null; |
||
4350 | break; |
||
4351 | } |
||
4352 | } |
||
4353 | aMx[nField] = new Mem(); |
||
4354 | //Debug.Assert( ( aMx[nField].flags & MEM_Null ) == 0 ); |
||
4355 | |||
4356 | if ( pCrsr != null ) |
||
4357 | { |
||
4358 | /* Populate the index search key. */ |
||
4359 | r.pKeyInfo = pCx.pKeyInfo; |
||
4360 | r.nField = (ushort)( nField + 1 ); |
||
4361 | r.flags = UNPACKED_PREFIX_SEARCH; |
||
4362 | r.aMem = aMx; |
||
4363 | #if SQLITE_DEBUG |
||
4364 | { |
||
4365 | int i; |
||
4366 | for ( i = 0; i < r.nField; i++ ) |
||
4367 | Debug.Assert( memIsValid( r.aMem[i] ) ); |
||
4368 | } |
||
4369 | #endif |
||
4370 | |||
4371 | /* Extract the value of R from register P3. */ |
||
4372 | sqlite3VdbeMemIntegerify( pIn3 ); |
||
4373 | R = pIn3.u.i; |
||
4374 | |||
4375 | /* Search the B-Tree index. If no conflicting record is found, jump |
||
4376 | ** to P2. Otherwise, copy the rowid of the conflicting record to |
||
4377 | ** register P3 and fall through to the next instruction. */ |
||
4378 | rc = sqlite3BtreeMovetoUnpacked( pCrsr, r, 0, 0, ref pCx.seekResult ); |
||
4379 | if ( ( r.flags & UNPACKED_PREFIX_SEARCH ) != 0 || r.rowid == R ) |
||
4380 | { |
||
4381 | pc = pOp.p2 - 1; |
||
4382 | } |
||
4383 | else |
||
4384 | { |
||
4385 | pIn3.u.i = r.rowid; |
||
4386 | } |
||
4387 | } |
||
4388 | break; |
||
4389 | } |
||
4390 | |||
4391 | |||
4392 | /* Opcode: NotExists P1 P2 P3 * * |
||
4393 | ** |
||
4394 | ** Use the content of register P3 as an integer key. If a record |
||
4395 | ** with that key does not exist in table of P1, then jump to P2. |
||
4396 | ** If the record does exist, then fall through. The cursor is left |
||
4397 | ** pointing to the record if it exists. |
||
4398 | ** |
||
4399 | ** The difference between this operation and NotFound is that this |
||
4400 | ** operation assumes the key is an integer and that P1 is a table whereas |
||
4401 | ** NotFound assumes key is a blob constructed from MakeRecord and |
||
4402 | ** P1 is an index. |
||
4403 | ** |
||
4404 | ** See also: Found, NotFound, IsUnique |
||
4405 | */ |
||
4406 | case OP_NotExists: |
||
4407 | { /* jump, in3 */ |
||
4408 | VdbeCursor pC; |
||
4409 | BtCursor pCrsr; |
||
4410 | int res; |
||
4411 | i64 iKey; |
||
4412 | |||
4413 | pIn3 = aMem[pOp.p3]; |
||
4414 | Debug.Assert( ( pIn3.flags & MEM_Int ) != 0 ); |
||
4415 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
4416 | pC = p.apCsr[pOp.p1]; |
||
4417 | Debug.Assert( pC != null ); |
||
4418 | Debug.Assert( pC.isTable ); |
||
4419 | Debug.Assert( pC.pseudoTableReg == 0 ); |
||
4420 | pCrsr = pC.pCursor; |
||
4421 | if ( pCrsr != null ) |
||
4422 | { |
||
4423 | res = 0; |
||
4424 | iKey = pIn3.u.i; |
||
4425 | rc = sqlite3BtreeMovetoUnpacked( pCrsr, null, (long)iKey, 0, ref res ); |
||
4426 | pC.lastRowid = pIn3.u.i; |
||
4427 | pC.rowidIsValid = res == 0 ? true : false; |
||
4428 | pC.nullRow = false; |
||
4429 | pC.cacheStatus = CACHE_STALE; |
||
4430 | pC.deferredMoveto = false; |
||
4431 | if ( res != 0 ) |
||
4432 | { |
||
4433 | pc = pOp.p2 - 1; |
||
4434 | Debug.Assert( !pC.rowidIsValid ); |
||
4435 | } |
||
4436 | pC.seekResult = res; |
||
4437 | } |
||
4438 | else |
||
4439 | { |
||
4440 | /* This happens when an attempt to open a read cursor on the |
||
4441 | ** sqlite_master table returns SQLITE_EMPTY. |
||
4442 | */ |
||
4443 | pc = pOp.p2 - 1; |
||
4444 | Debug.Assert( !pC.rowidIsValid ); |
||
4445 | pC.seekResult = 0; |
||
4446 | } |
||
4447 | break; |
||
4448 | } |
||
4449 | |||
4450 | /* Opcode: Sequence P1 P2 * * * |
||
4451 | ** |
||
4452 | ** Find the next available sequence number for cursor P1. |
||
4453 | ** Write the sequence number into register P2. |
||
4454 | ** The sequence number on the cursor is incremented after this |
||
4455 | ** instruction. |
||
4456 | */ |
||
4457 | case OP_Sequence: |
||
4458 | { /* out2-prerelease */ |
||
4459 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
4460 | Debug.Assert( p.apCsr[pOp.p1] != null ); |
||
4461 | pOut.u.i = (long)p.apCsr[pOp.p1].seqCount++; |
||
4462 | break; |
||
4463 | } |
||
4464 | |||
4465 | |||
4466 | /* Opcode: NewRowid P1 P2 P3 * * |
||
4467 | ** |
||
4468 | ** Get a new integer record number (a.k.a "rowid") used as the key to a table. |
||
4469 | ** The record number is not previously used as a key in the database |
||
4470 | ** table that cursor P1 points to. The new record number is written |
||
4471 | ** written to register P2. |
||
4472 | ** |
||
4473 | ** If P3>0 then P3 is a register in the root frame of this VDBE that holds |
||
4474 | ** the largest previously generated record number. No new record numbers are |
||
4475 | ** allowed to be less than this value. When this value reaches its maximum, |
||
4476 | ** an SQLITE_FULL error is generated. The P3 register is updated with the ' |
||
4477 | ** generated record number. This P3 mechanism is used to help implement the |
||
4478 | ** AUTOINCREMENT feature. |
||
4479 | */ |
||
4480 | case OP_NewRowid: |
||
4481 | { /* out2-prerelease */ |
||
4482 | i64 v; /* The new rowid */ |
||
4483 | VdbeCursor pC; /* Cursor of table to get the new rowid */ |
||
4484 | int res; /* Result of an sqlite3BtreeLast() */ |
||
4485 | int cnt; /* Counter to limit the number of searches */ |
||
4486 | Mem pMem; /* Register holding largest rowid for AUTOINCREMENT */ |
||
4487 | VdbeFrame pFrame; /* Root frame of VDBE */ |
||
4488 | |||
4489 | v = 0; |
||
4490 | res = 0; |
||
4491 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
4492 | pC = p.apCsr[pOp.p1]; |
||
4493 | Debug.Assert( pC != null ); |
||
4494 | if ( NEVER( pC.pCursor == null ) ) |
||
4495 | { |
||
4496 | /* The zero initialization above is all that is needed */ |
||
4497 | } |
||
4498 | else |
||
4499 | { |
||
4500 | /* The next rowid or record number (different terms for the same |
||
4501 | ** thing) is obtained in a two-step algorithm. |
||
4502 | ** |
||
4503 | ** First we attempt to find the largest existing rowid and add one |
||
4504 | ** to that. But if the largest existing rowid is already the maximum |
||
4505 | ** positive integer, we have to fall through to the second |
||
4506 | ** probabilistic algorithm |
||
4507 | ** |
||
4508 | ** The second algorithm is to select a rowid at random and see if |
||
4509 | ** it already exists in the table. If it does not exist, we have |
||
4510 | ** succeeded. If the random rowid does exist, we select a new one |
||
4511 | ** and try again, up to 100 times. |
||
4512 | */ |
||
4513 | Debug.Assert( pC.isTable ); |
||
4514 | |||
4515 | #if SQLITE_32BIT_ROWID |
||
4516 | const int MAX_ROWID = i32.MaxValue;//# define MAX_ROWID 0x7fffffff |
||
4517 | #else |
||
4518 | /* Some compilers complain about constants of the form 0x7fffffffffffffff. |
||
4519 | ** Others complain about 0x7ffffffffffffffffLL. The following macro seems |
||
4520 | ** to provide the constant while making all compilers happy. |
||
4521 | */ |
||
4522 | const long MAX_ROWID = i64.MaxValue;// (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff ) |
||
4523 | #endif |
||
4524 | |||
4525 | if ( !pC.useRandomRowid ) |
||
4526 | { |
||
4527 | v = sqlite3BtreeGetCachedRowid( pC.pCursor ); |
||
4528 | if ( v == 0 ) |
||
4529 | { |
||
4530 | rc = sqlite3BtreeLast( pC.pCursor, ref res ); |
||
4531 | if ( rc != SQLITE_OK ) |
||
4532 | { |
||
4533 | goto abort_due_to_error; |
||
4534 | } |
||
4535 | if ( res != 0 ) |
||
4536 | { |
||
4537 | v = 1;/* IMP: R-61914-48074 */ |
||
4538 | } |
||
4539 | else |
||
4540 | { |
||
4541 | Debug.Assert( sqlite3BtreeCursorIsValid( pC.pCursor ) ); |
||
4542 | rc = sqlite3BtreeKeySize( pC.pCursor, ref v ); |
||
4543 | Debug.Assert( rc == SQLITE_OK ); /* Cannot fail following BtreeLast() */ |
||
4544 | if ( v == MAX_ROWID ) |
||
4545 | { |
||
4546 | pC.useRandomRowid = true; |
||
4547 | } |
||
4548 | else |
||
4549 | { |
||
4550 | v++; /* IMP: R-29538-34987 */ |
||
4551 | } |
||
4552 | } |
||
4553 | } |
||
4554 | |||
4555 | #if !SQLITE_OMIT_AUTOINCREMENT |
||
4556 | if ( pOp.p3 != 0 ) |
||
4557 | { |
||
4558 | /* Assert that P3 is a valid memory cell. */ |
||
4559 | Debug.Assert( pOp.p3 > 0 ); |
||
4560 | if ( p.pFrame != null ) |
||
4561 | { |
||
4562 | for ( pFrame = p.pFrame; pFrame.pParent != null; pFrame = pFrame.pParent ) |
||
4563 | ; |
||
4564 | /* Assert that P3 is a valid memory cell. */ |
||
4565 | Debug.Assert( pOp.p3 <= pFrame.nMem ); |
||
4566 | pMem = pFrame.aMem[pOp.p3]; |
||
4567 | } |
||
4568 | else |
||
4569 | { |
||
4570 | /* Assert that P3 is a valid memory cell. */ |
||
4571 | Debug.Assert( pOp.p3 <= p.nMem ); |
||
4572 | pMem = aMem[pOp.p3]; |
||
4573 | memAboutToChange( p, pMem ); |
||
4574 | } |
||
4575 | Debug.Assert( memIsValid( pMem ) ); |
||
4576 | |||
4577 | REGISTER_TRACE( p, pOp.p3, pMem ); |
||
4578 | sqlite3VdbeMemIntegerify( pMem ); |
||
4579 | Debug.Assert( ( pMem.flags & MEM_Int ) != 0 ); /* mem(P3) holds an integer */ |
||
4580 | if ( pMem.u.i == MAX_ROWID || pC.useRandomRowid ) |
||
4581 | { |
||
4582 | rc = SQLITE_FULL; /* IMP: R-12275-61338 */ |
||
4583 | goto abort_due_to_error; |
||
4584 | } |
||
4585 | if ( v < ( pMem.u.i + 1 ) ) |
||
4586 | { |
||
4587 | v = (int)( pMem.u.i + 1 ); |
||
4588 | } |
||
4589 | pMem.u.i = (long)v; |
||
4590 | } |
||
4591 | #endif |
||
4592 | |||
4593 | sqlite3BtreeSetCachedRowid( pC.pCursor, v < MAX_ROWID ? v + 1 : 0 ); |
||
4594 | } |
||
4595 | if ( pC.useRandomRowid ) |
||
4596 | { |
||
4597 | /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the |
||
4598 | ** largest possible integer (9223372036854775807) then the database |
||
4599 | ** engine starts picking positive candidate ROWIDs at random until |
||
4600 | ** it finds one that is not previously used. */ |
||
4601 | Debug.Assert( pOp.p3 == 0 ); /* We cannot be in random rowid mode if this is |
||
4602 | ** an AUTOINCREMENT table. */ |
||
4603 | /* on the first attempt, simply do one more than previous */ |
||
4604 | v = lastRowid; |
||
4605 | v &= ( MAX_ROWID >> 1 ); /* ensure doesn't go negative */ |
||
4606 | v++; /* ensure non-zero */ |
||
4607 | cnt = 0; |
||
4608 | while ( ( ( rc = sqlite3BtreeMovetoUnpacked( pC.pCursor, null, v, |
||
4609 | 0, ref res ) ) == SQLITE_OK ) |
||
4610 | && ( res == 0 ) |
||
4611 | && ( ++cnt < 100 ) ) |
||
4612 | { |
||
4613 | /* collision - try another random rowid */ |
||
4614 | sqlite3_randomness( sizeof( i64 ), ref v ); |
||
4615 | if ( cnt < 5 ) |
||
4616 | { |
||
4617 | /* try "small" random rowids for the initial attempts */ |
||
4618 | v &= 0xffffff; |
||
4619 | } |
||
4620 | else |
||
4621 | { |
||
4622 | v &= ( MAX_ROWID >> 1 ); /* ensure doesn't go negative */ |
||
4623 | } |
||
4624 | v++; /* ensure non-zero */ |
||
4625 | } |
||
4626 | if ( rc == SQLITE_OK && res == 0 ) |
||
4627 | { |
||
4628 | rc = SQLITE_FULL;/* IMP: R-38219-53002 */ |
||
4629 | goto abort_due_to_error; |
||
4630 | } |
||
4631 | Debug.Assert( v > 0 ); /* EV: R-40812-03570 */ |
||
4632 | } |
||
4633 | pC.rowidIsValid = false; |
||
4634 | pC.deferredMoveto = false; |
||
4635 | pC.cacheStatus = CACHE_STALE; |
||
4636 | } |
||
4637 | pOut.u.i = (long)v; |
||
4638 | break; |
||
4639 | } |
||
4640 | |||
4641 | /* Opcode: Insert P1 P2 P3 P4 P5 |
||
4642 | ** |
||
4643 | ** Write an entry into the table of cursor P1. A new entry is |
||
4644 | ** created if it doesn't already exist or the data for an existing |
||
4645 | ** entry is overwritten. The data is the value MEM_Blob stored in register |
||
4646 | ** number P2. The key is stored in register P3. The key must |
||
4647 | ** be a MEM_Int. |
||
4648 | ** |
||
4649 | ** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is |
||
4650 | ** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P5 is set, |
||
4651 | ** then rowid is stored for subsequent return by the |
||
4652 | ** sqlite3_last_insert_rowid() function (otherwise it is unmodified). |
||
4653 | ** |
||
4654 | ** If the OPFLAG_USESEEKRESULT flag of P5 is set and if the result of |
||
4655 | ** the last seek operation (OP_NotExists) was a success, then this |
||
4656 | ** operation will not attempt to find the appropriate row before doing |
||
4657 | ** the insert but will instead overwrite the row that the cursor is |
||
4658 | ** currently pointing to. Presumably, the prior OP_NotExists opcode |
||
4659 | ** has already positioned the cursor correctly. This is an optimization |
||
4660 | ** that boosts performance by avoiding redundant seeks. |
||
4661 | ** |
||
4662 | ** If the OPFLAG_ISUPDATE flag is set, then this opcode is part of an |
||
4663 | ** UPDATE operation. Otherwise (if the flag is clear) then this opcode |
||
4664 | ** is part of an INSERT operation. The difference is only important to |
||
4665 | ** the update hook. |
||
4666 | ** |
||
4667 | ** Parameter P4 may point to a string containing the table-name, or |
||
4668 | ** may be NULL. If it is not NULL, then the update-hook |
||
4669 | ** (sqlite3.xUpdateCallback) is invoked following a successful insert. |
||
4670 | ** |
||
4671 | ** (WARNING/TODO: If P1 is a pseudo-cursor and P2 is dynamically |
||
4672 | ** allocated, then ownership of P2 is transferred to the pseudo-cursor |
||
4673 | ** and register P2 becomes ephemeral. If the cursor is changed, the |
||
4674 | ** value of register P2 will then change. Make sure this does not |
||
4675 | ** cause any problems.) |
||
4676 | ** |
||
4677 | ** This instruction only works on tables. The equivalent instruction |
||
4678 | ** for indices is OP_IdxInsert. |
||
4679 | */ |
||
4680 | /* Opcode: InsertInt P1 P2 P3 P4 P5 |
||
4681 | ** |
||
4682 | ** This works exactly like OP_Insert except that the key is the |
||
4683 | ** integer value P3, not the value of the integer stored in register P3. |
||
4684 | */ |
||
4685 | case OP_Insert: |
||
4686 | case OP_InsertInt: |
||
4687 | { |
||
4688 | Mem pData; /* MEM cell holding data for the record to be inserted */ |
||
4689 | Mem pKey; /* MEM cell holding key for the record */ |
||
4690 | i64 iKey; /* The integer ROWID or key for the record to be inserted */ |
||
4691 | VdbeCursor pC; /* Cursor to table into which insert is written */ |
||
4692 | int nZero; /* Number of zero-bytes to append */ |
||
4693 | int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ |
||
4694 | string zDb; /* database name - used by the update hook */ |
||
4695 | string zTbl; /* Table name - used by the opdate hook */ |
||
4696 | int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ |
||
4697 | |||
4698 | pData = aMem[pOp.p2]; |
||
4699 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
4700 | Debug.Assert( memIsValid( pData ) ); |
||
4701 | pC = p.apCsr[pOp.p1]; |
||
4702 | Debug.Assert( pC != null ); |
||
4703 | Debug.Assert( pC.pCursor != null ); |
||
4704 | Debug.Assert( pC.pseudoTableReg == 0 ); |
||
4705 | Debug.Assert( pC.isTable ); |
||
4706 | REGISTER_TRACE( p, pOp.p2, pData ); |
||
4707 | |||
4708 | if ( pOp.opcode == OP_Insert ) |
||
4709 | { |
||
4710 | pKey = aMem[pOp.p3]; |
||
4711 | Debug.Assert( ( pKey.flags & MEM_Int ) != 0 ); |
||
4712 | Debug.Assert( memIsValid( pKey ) ); |
||
4713 | REGISTER_TRACE( p, pOp.p3, pKey ); |
||
4714 | iKey = pKey.u.i; |
||
4715 | } |
||
4716 | else |
||
4717 | { |
||
4718 | Debug.Assert( pOp.opcode == OP_InsertInt ); |
||
4719 | iKey = pOp.p3; |
||
4720 | } |
||
4721 | |||
4722 | if ( ( pOp.p5 & OPFLAG_NCHANGE ) != 0 ) |
||
4723 | p.nChange++; |
||
4724 | if ( ( pOp.p5 & OPFLAG_LASTROWID ) != 0 ) |
||
4725 | db.lastRowid = lastRowid = iKey; |
||
4726 | if ( ( pData.flags & MEM_Null ) != 0 ) |
||
4727 | { |
||
4728 | sqlite3_free( ref pData.zBLOB ); |
||
4729 | pData.z = null; |
||
4730 | pData.n = 0; |
||
4731 | } |
||
4732 | else |
||
4733 | { |
||
4734 | Debug.Assert( ( pData.flags & ( MEM_Blob | MEM_Str ) ) != 0 ); |
||
4735 | } |
||
4736 | seekResult = ( ( pOp.p5 & OPFLAG_USESEEKRESULT ) != 0 ? pC.seekResult : 0 ); |
||
4737 | if ( ( pData.flags & MEM_Zero ) != 0 ) |
||
4738 | { |
||
4739 | nZero = pData.u.nZero; |
||
4740 | } |
||
4741 | else |
||
4742 | { |
||
4743 | nZero = 0; |
||
4744 | } |
||
4745 | rc = sqlite3BtreeInsert( pC.pCursor, null, iKey, |
||
4746 | pData.zBLOB |
||
4747 | , pData.n, nZero, |
||
4748 | ( pOp.p5 & OPFLAG_APPEND ) != 0 ? 1 : 0, seekResult |
||
4749 | ); |
||
4750 | |||
4751 | pC.rowidIsValid = false; |
||
4752 | pC.deferredMoveto = false; |
||
4753 | pC.cacheStatus = CACHE_STALE; |
||
4754 | |||
4755 | /* Invoke the update-hook if required. */ |
||
4756 | if ( rc == SQLITE_OK && db.xUpdateCallback != null && pOp.p4.z != null ) |
||
4757 | { |
||
4758 | zDb = db.aDb[pC.iDb].zName; |
||
4759 | zTbl = pOp.p4.z; |
||
4760 | op = ( ( pOp.p5 & OPFLAG_ISUPDATE ) != 0 ? SQLITE_UPDATE : SQLITE_INSERT ); |
||
4761 | Debug.Assert( pC.isTable ); |
||
4762 | db.xUpdateCallback( db.pUpdateArg, op, zDb, zTbl, iKey ); |
||
4763 | Debug.Assert( pC.iDb >= 0 ); |
||
4764 | } |
||
4765 | break; |
||
4766 | } |
||
4767 | |||
4768 | /* Opcode: Delete P1 P2 * P4 * |
||
4769 | ** |
||
4770 | ** Delete the record at which the P1 cursor is currently pointing. |
||
4771 | ** |
||
4772 | ** The cursor will be left pointing at either the next or the previous |
||
4773 | ** record in the table. If it is left pointing at the next record, then |
||
4774 | ** the next Next instruction will be a no-op. Hence it is OK to delete |
||
4775 | ** a record from within an Next loop. |
||
4776 | ** |
||
4777 | ** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is |
||
4778 | ** incremented (otherwise not). |
||
4779 | ** |
||
4780 | ** P1 must not be pseudo-table. It has to be a real table with |
||
4781 | ** multiple rows. |
||
4782 | ** |
||
4783 | ** If P4 is not NULL, then it is the name of the table that P1 is |
||
4784 | ** pointing to. The update hook will be invoked, if it exists. |
||
4785 | ** If P4 is not NULL then the P1 cursor must have been positioned |
||
4786 | ** using OP_NotFound prior to invoking this opcode. |
||
4787 | */ |
||
4788 | case OP_Delete: |
||
4789 | { |
||
4790 | i64 iKey; |
||
4791 | VdbeCursor pC; |
||
4792 | |||
4793 | iKey = 0; |
||
4794 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
4795 | pC = p.apCsr[pOp.p1]; |
||
4796 | Debug.Assert( pC != null ); |
||
4797 | Debug.Assert( pC.pCursor != null ); /* Only valid for real tables, no pseudotables */ |
||
4798 | |||
4799 | /* If the update-hook will be invoked, set iKey to the rowid of the |
||
4800 | ** row being deleted. |
||
4801 | */ |
||
4802 | if ( db.xUpdateCallback != null && pOp.p4.z != null ) |
||
4803 | { |
||
4804 | Debug.Assert( pC.isTable ); |
||
4805 | Debug.Assert( pC.rowidIsValid ); /* lastRowid set by previous OP_NotFound */ |
||
4806 | iKey = pC.lastRowid; |
||
4807 | } |
||
4808 | |||
4809 | /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or |
||
4810 | ** OP_Column on the same table without any intervening operations that |
||
4811 | ** might move or invalidate the cursor. Hence cursor pC is always pointing |
||
4812 | ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation |
||
4813 | ** below is always a no-op and cannot fail. We will run it anyhow, though, |
||
4814 | ** to guard against future changes to the code generator. |
||
4815 | **/ |
||
4816 | Debug.Assert( pC.deferredMoveto == false ); |
||
4817 | rc = sqlite3VdbeCursorMoveto( pC ); |
||
4818 | if ( NEVER( rc != SQLITE_OK ) ) |
||
4819 | goto abort_due_to_error; |
||
4820 | sqlite3BtreeSetCachedRowid( pC.pCursor, 0 ); |
||
4821 | rc = sqlite3BtreeDelete( pC.pCursor ); |
||
4822 | pC.cacheStatus = CACHE_STALE; |
||
4823 | |||
4824 | /* Invoke the update-hook if required. */ |
||
4825 | if ( rc == SQLITE_OK && db.xUpdateCallback != null && pOp.p4.z != null ) |
||
4826 | { |
||
4827 | string zDb = db.aDb[pC.iDb].zName; |
||
4828 | string zTbl = pOp.p4.z; |
||
4829 | db.xUpdateCallback( db.pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey ); |
||
4830 | Debug.Assert( pC.iDb >= 0 ); |
||
4831 | } |
||
4832 | if ( ( pOp.p2 & OPFLAG_NCHANGE ) != 0 ) |
||
4833 | p.nChange++; |
||
4834 | break; |
||
4835 | } |
||
4836 | |||
4837 | /* Opcode: ResetCount P1 * * |
||
4838 | ** |
||
4839 | ** The value of the change counter is copied to the database handle |
||
4840 | ** change counter (returned by subsequent calls to sqlite3_changes()). |
||
4841 | ** Then the VMs internal change counter resets to 0. |
||
4842 | ** This is used by trigger programs. |
||
4843 | */ |
||
4844 | case OP_ResetCount: |
||
4845 | { |
||
4846 | sqlite3VdbeSetChanges( db, p.nChange ); |
||
4847 | p.nChange = 0; |
||
4848 | break; |
||
4849 | } |
||
4850 | |||
4851 | /* Opcode: RowData P1 P2 * * * |
||
4852 | ** |
||
4853 | ** Write into register P2 the complete row data for cursor P1. |
||
4854 | ** There is no interpretation of the data. |
||
4855 | ** It is just copied onto the P2 register exactly as |
||
4856 | ** it is found in the database file. |
||
4857 | ** |
||
4858 | ** If the P1 cursor must be pointing to a valid row (not a NULL row) |
||
4859 | ** of a real table, not a pseudo-table. |
||
4860 | */ |
||
4861 | /* Opcode: RowKey P1 P2 * * * |
||
4862 | ** |
||
4863 | ** Write into register P2 the complete row key for cursor P1. |
||
4864 | ** There is no interpretation of the data. |
||
4865 | ** The key is copied onto the P3 register exactly as |
||
4866 | ** it is found in the database file. |
||
4867 | ** |
||
4868 | ** If the P1 cursor must be pointing to a valid row (not a NULL row) |
||
4869 | ** of a real table, not a pseudo-table. |
||
4870 | */ |
||
4871 | case OP_RowKey: |
||
4872 | case OP_RowData: |
||
4873 | { |
||
4874 | VdbeCursor pC; |
||
4875 | BtCursor pCrsr; |
||
4876 | u32 n; |
||
4877 | i64 n64; |
||
4878 | |||
4879 | n = 0; |
||
4880 | n64 = 0; |
||
4881 | |||
4882 | pOut = aMem[pOp.p2]; |
||
4883 | memAboutToChange( p, pOut ); |
||
4884 | |||
4885 | /* Note that RowKey and RowData are really exactly the same instruction */ |
||
4886 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
4887 | pC = p.apCsr[pOp.p1]; |
||
4888 | Debug.Assert( pC.isTable || pOp.opcode == OP_RowKey ); |
||
4889 | Debug.Assert( pC.isIndex || pOp.opcode == OP_RowData ); |
||
4890 | Debug.Assert( pC != null ); |
||
4891 | Debug.Assert( pC.nullRow == false ); |
||
4892 | Debug.Assert( pC.pseudoTableReg == 0 ); |
||
4893 | Debug.Assert( pC.pCursor != null ); |
||
4894 | pCrsr = pC.pCursor; |
||
4895 | Debug.Assert( sqlite3BtreeCursorIsValid( pCrsr ) ); |
||
4896 | |||
4897 | /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or |
||
4898 | ** OP_Rewind/Op_Next with no intervening instructions that might invalidate |
||
4899 | ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always |
||
4900 | ** a no-op and can never fail. But we leave it in place as a safety. |
||
4901 | */ |
||
4902 | Debug.Assert( pC.deferredMoveto == false ); |
||
4903 | rc = sqlite3VdbeCursorMoveto( pC ); |
||
4904 | if ( NEVER( rc != SQLITE_OK ) ) |
||
4905 | goto abort_due_to_error; |
||
4906 | if ( pC.isIndex ) |
||
4907 | { |
||
4908 | Debug.Assert( !pC.isTable ); |
||
4909 | rc = sqlite3BtreeKeySize( pCrsr, ref n64 ); |
||
4910 | Debug.Assert( rc == SQLITE_OK ); /* True because of CursorMoveto() call above */ |
||
4911 | if ( n64 > db.aLimit[SQLITE_LIMIT_LENGTH] ) |
||
4912 | { |
||
4913 | goto too_big; |
||
4914 | } |
||
4915 | n = (u32)n64; |
||
4916 | } |
||
4917 | else |
||
4918 | { |
||
4919 | rc = sqlite3BtreeDataSize( pCrsr, ref n ); |
||
4920 | Debug.Assert( rc == SQLITE_OK ); /* DataSize() cannot fail */ |
||
4921 | if ( n > (u32)db.aLimit[SQLITE_LIMIT_LENGTH] ) |
||
4922 | { |
||
4923 | goto too_big; |
||
4924 | } |
||
4925 | if ( sqlite3VdbeMemGrow( pOut, (int)n, 0 ) != 0 ) |
||
4926 | { |
||
4927 | goto no_mem; |
||
4928 | } |
||
4929 | } |
||
4930 | pOut.n = (int)n; |
||
4931 | if ( pC.isIndex ) |
||
4932 | { |
||
4933 | pOut.zBLOB = sqlite3Malloc( (int)n ); |
||
4934 | rc = sqlite3BtreeKey( pCrsr, 0, n, pOut.zBLOB ); |
||
4935 | } |
||
4936 | else |
||
4937 | { |
||
4938 | pOut.zBLOB = sqlite3Malloc( (int)pCrsr.info.nData ); |
||
4939 | rc = sqlite3BtreeData( pCrsr, 0, (u32)n, pOut.zBLOB ); |
||
4940 | } |
||
4941 | MemSetTypeFlag( pOut, MEM_Blob ); |
||
4942 | pOut.enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ |
||
4943 | #if SQLITE_TEST |
||
4944 | UPDATE_MAX_BLOBSIZE( pOut ); |
||
4945 | #endif |
||
4946 | break; |
||
4947 | } |
||
4948 | |||
4949 | /* Opcode: Rowid P1 P2 * * * |
||
4950 | ** |
||
4951 | ** Store in register P2 an integer which is the key of the table entry that |
||
4952 | ** P1 is currently point to. |
||
4953 | ** |
||
4954 | ** P1 can be either an ordinary table or a virtual table. There used to |
||
4955 | ** be a separate OP_VRowid opcode for use with virtual tables, but this |
||
4956 | ** one opcode now works for both table types. |
||
4957 | */ |
||
4958 | case OP_Rowid: |
||
4959 | { /* out2-prerelease */ |
||
4960 | VdbeCursor pC; |
||
4961 | i64 v; |
||
4962 | sqlite3_vtab pVtab; |
||
4963 | sqlite3_module pModule; |
||
4964 | |||
4965 | v = 0; |
||
4966 | |||
4967 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
4968 | pC = p.apCsr[pOp.p1]; |
||
4969 | Debug.Assert( pC != null ); |
||
4970 | Debug.Assert( pC.pseudoTableReg == 0 ); |
||
4971 | if ( pC.nullRow ) |
||
4972 | { |
||
4973 | pOut.flags = MEM_Null; |
||
4974 | break; |
||
4975 | } |
||
4976 | else if ( pC.deferredMoveto ) |
||
4977 | { |
||
4978 | v = pC.movetoTarget; |
||
4979 | #if !SQLITE_OMIT_VIRTUALTABLE |
||
4980 | } |
||
4981 | else if ( pC.pVtabCursor!=null ) |
||
4982 | { |
||
4983 | pVtab = pC.pVtabCursor.pVtab; |
||
4984 | pModule = pVtab.pModule; |
||
4985 | Debug.Assert( pModule.xRowid != null ); |
||
4986 | rc = pModule.xRowid( pC.pVtabCursor, out v ); |
||
4987 | importVtabErrMsg( p, pVtab ); |
||
4988 | #endif //* SQLITE_OMIT_VIRTUALTABLE */ |
||
4989 | } |
||
4990 | else |
||
4991 | { |
||
4992 | Debug.Assert( pC.pCursor != null ); |
||
4993 | rc = sqlite3VdbeCursorMoveto( pC ); |
||
4994 | if ( rc != 0 ) |
||
4995 | goto abort_due_to_error; |
||
4996 | if ( pC.rowidIsValid ) |
||
4997 | { |
||
4998 | v = pC.lastRowid; |
||
4999 | } |
||
5000 | else |
||
5001 | { |
||
5002 | rc = sqlite3BtreeKeySize( pC.pCursor, ref v ); |
||
5003 | Debug.Assert( rc == SQLITE_OK ); /* Always so because of CursorMoveto() above */ |
||
5004 | } |
||
5005 | } |
||
5006 | pOut.u.i = (long)v; |
||
5007 | break; |
||
5008 | } |
||
5009 | |||
5010 | /* Opcode: NullRow P1 * * * * |
||
5011 | ** |
||
5012 | ** Move the cursor P1 to a null row. Any OP_Column operations |
||
5013 | ** that occur while the cursor is on the null row will always |
||
5014 | ** write a NULL. |
||
5015 | */ |
||
5016 | case OP_NullRow: |
||
5017 | { |
||
5018 | VdbeCursor pC; |
||
5019 | |||
5020 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
5021 | pC = p.apCsr[pOp.p1]; |
||
5022 | Debug.Assert( pC != null ); |
||
5023 | pC.nullRow = true; |
||
5024 | pC.rowidIsValid = false; |
||
5025 | if ( pC.pCursor != null ) |
||
5026 | { |
||
5027 | sqlite3BtreeClearCursor( pC.pCursor ); |
||
5028 | } |
||
5029 | break; |
||
5030 | } |
||
5031 | |||
5032 | /* Opcode: Last P1 P2 * * * |
||
5033 | ** |
||
5034 | ** The next use of the Rowid or Column or Next instruction for P1 |
||
5035 | ** will refer to the last entry in the database table or index. |
||
5036 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
||
5037 | ** If P2 is 0 or if the table or index is not empty, fall through |
||
5038 | ** to the following instruction. |
||
5039 | */ |
||
5040 | case OP_Last: |
||
5041 | { /* jump */ |
||
5042 | VdbeCursor pC; |
||
5043 | BtCursor pCrsr; |
||
5044 | int res = 0; |
||
5045 | |||
5046 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
5047 | pC = p.apCsr[pOp.p1]; |
||
5048 | Debug.Assert( pC != null ); |
||
5049 | pCrsr = pC.pCursor; |
||
5050 | if ( pCrsr == null ) |
||
5051 | { |
||
5052 | res = 1; |
||
5053 | } |
||
5054 | else |
||
5055 | { |
||
5056 | rc = sqlite3BtreeLast( pCrsr, ref res ); |
||
5057 | } |
||
5058 | pC.nullRow = res == 1 ? true : false; |
||
5059 | pC.deferredMoveto = false; |
||
5060 | pC.rowidIsValid = false; |
||
5061 | pC.cacheStatus = CACHE_STALE; |
||
5062 | if ( pOp.p2 > 0 && res != 0 ) |
||
5063 | { |
||
5064 | pc = pOp.p2 - 1; |
||
5065 | } |
||
5066 | break; |
||
5067 | } |
||
5068 | |||
5069 | |||
5070 | /* Opcode: Sort P1 P2 * * * |
||
5071 | ** |
||
5072 | ** This opcode does exactly the same thing as OP_Rewind except that |
||
5073 | ** it increments an undocumented global variable used for testing. |
||
5074 | ** |
||
5075 | ** Sorting is accomplished by writing records into a sorting index, |
||
5076 | ** then rewinding that index and playing it back from beginning to |
||
5077 | ** end. We use the OP_Sort opcode instead of OP_Rewind to do the |
||
5078 | ** rewinding so that the global variable will be incremented and |
||
5079 | ** regression tests can determine whether or not the optimizer is |
||
5080 | ** correctly optimizing out sorts. |
||
5081 | */ |
||
5082 | case OP_Sort: |
||
5083 | { /* jump */ |
||
5084 | #if SQLITE_TEST |
||
5085 | #if !TCLSH |
||
5086 | sqlite3_sort_count++; |
||
5087 | sqlite3_search_count--; |
||
5088 | #else |
||
5089 | sqlite3_sort_count.iValue++; |
||
5090 | sqlite3_search_count.iValue--; |
||
5091 | #endif |
||
5092 | #endif |
||
5093 | p.aCounter[SQLITE_STMTSTATUS_SORT - 1]++; |
||
5094 | /* Fall through into OP_Rewind */ |
||
5095 | goto case OP_Rewind; |
||
5096 | } |
||
5097 | /* Opcode: Rewind P1 P2 * * * |
||
5098 | ** |
||
5099 | ** The next use of the Rowid or Column or Next instruction for P1 |
||
5100 | ** will refer to the first entry in the database table or index. |
||
5101 | ** If the table or index is empty and P2>0, then jump immediately to P2. |
||
5102 | ** If P2 is 0 or if the table or index is not empty, fall through |
||
5103 | ** to the following instruction. |
||
5104 | */ |
||
5105 | case OP_Rewind: |
||
5106 | { /* jump */ |
||
5107 | VdbeCursor pC; |
||
5108 | BtCursor pCrsr; |
||
5109 | int res = 0; |
||
5110 | |||
5111 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
5112 | pC = p.apCsr[pOp.p1]; |
||
5113 | Debug.Assert( pC != null ); |
||
5114 | res = 1; |
||
5115 | if ( ( pCrsr = pC.pCursor ) != null ) |
||
5116 | { |
||
5117 | rc = sqlite3BtreeFirst( pCrsr, ref res ); |
||
5118 | pC.atFirst = res == 0 ? true : false; |
||
5119 | pC.deferredMoveto = false; |
||
5120 | pC.cacheStatus = CACHE_STALE; |
||
5121 | pC.rowidIsValid = false; |
||
5122 | } |
||
5123 | pC.nullRow = res == 1 ? true : false; |
||
5124 | Debug.Assert( pOp.p2 > 0 && pOp.p2 < p.nOp ); |
||
5125 | if ( res != 0 ) |
||
5126 | { |
||
5127 | pc = pOp.p2 - 1; |
||
5128 | } |
||
5129 | break; |
||
5130 | } |
||
5131 | |||
5132 | /* Opcode: Next P1 P2 * * P5 |
||
5133 | ** |
||
5134 | ** Advance cursor P1 so that it points to the next key/data pair in its |
||
5135 | ** table or index. If there are no more key/value pairs then fall through |
||
5136 | ** to the following instruction. But if the cursor advance was successful, |
||
5137 | ** jump immediately to P2. |
||
5138 | ** |
||
5139 | ** The P1 cursor must be for a real table, not a pseudo-table. |
||
5140 | ** |
||
5141 | ** See also: Prev |
||
5142 | */ |
||
5143 | /* Opcode: Prev P1 P2 * * * |
||
5144 | ** |
||
5145 | ** Back up cursor P1 so that it points to the previous key/data pair in its |
||
5146 | ** table or index. If there is no previous key/value pairs then fall through |
||
5147 | ** to the following instruction. But if the cursor backup was successful, |
||
5148 | ** jump immediately to P2. |
||
5149 | ** |
||
5150 | ** The P1 cursor must be for a real table, not a pseudo-table. |
||
5151 | ** |
||
5152 | ** If P5 is positive and the jump is taken, then event counter |
||
5153 | ** number P5-1 in the prepared statement is incremented. |
||
5154 | ** |
||
5155 | */ |
||
5156 | case OP_Prev: /* jump */ |
||
5157 | case OP_Next: |
||
5158 | { /* jump */ |
||
5159 | VdbeCursor pC; |
||
5160 | BtCursor pCrsr; |
||
5161 | int res; |
||
5162 | |||
5163 | if ( db.u1.isInterrupted ) |
||
5164 | goto abort_due_to_interrupt; //CHECK_FOR_INTERRUPT; |
||
5165 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
5166 | Debug.Assert( pOp.p5 <= ArraySize( p.aCounter ) ); |
||
5167 | pC = p.apCsr[pOp.p1]; |
||
5168 | if ( pC == null ) |
||
5169 | { |
||
5170 | break; /* See ticket #2273 */ |
||
5171 | } |
||
5172 | pCrsr = pC.pCursor; |
||
5173 | if ( pCrsr == null ) |
||
5174 | { |
||
5175 | pC.nullRow = true; |
||
5176 | break; |
||
5177 | } |
||
5178 | res = 1; |
||
5179 | Debug.Assert( !pC.deferredMoveto ); |
||
5180 | rc = pOp.opcode == OP_Next ? sqlite3BtreeNext( pCrsr, ref res ) : |
||
5181 | sqlite3BtreePrevious( pCrsr, ref res ); |
||
5182 | pC.nullRow = res == 1 ? true : false; |
||
5183 | pC.cacheStatus = CACHE_STALE; |
||
5184 | if ( res == 0 ) |
||
5185 | { |
||
5186 | pc = pOp.p2 - 1; |
||
5187 | if ( pOp.p5 != 0 ) |
||
5188 | p.aCounter[pOp.p5 - 1]++; |
||
5189 | #if SQLITE_TEST |
||
5190 | #if !TCLSH |
||
5191 | sqlite3_search_count++; |
||
5192 | #else |
||
5193 | sqlite3_search_count.iValue++; |
||
5194 | #endif |
||
5195 | #endif |
||
5196 | } |
||
5197 | pC.rowidIsValid = false; |
||
5198 | break; |
||
5199 | } |
||
5200 | |||
5201 | /* Opcode: IdxInsert P1 P2 P3 * P5 |
||
5202 | ** |
||
5203 | ** Register P2 holds an SQL index key made using the |
||
5204 | ** MakeRecord instructions. This opcode writes that key |
||
5205 | ** into the index P1. Data for the entry is nil. |
||
5206 | ** |
||
5207 | ** P3 is a flag that provides a hint to the b-tree layer that this |
||
5208 | ** insert is likely to be an append. |
||
5209 | ** |
||
5210 | ** This instruction only works for indices. The equivalent instruction |
||
5211 | ** for tables is OP_Insert. |
||
5212 | */ |
||
5213 | case OP_IdxInsert: |
||
5214 | { /* in2 */ |
||
5215 | VdbeCursor pC; |
||
5216 | BtCursor pCrsr; |
||
5217 | int nKey; |
||
5218 | byte[] zKey; |
||
5219 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
5220 | pC = p.apCsr[pOp.p1]; |
||
5221 | Debug.Assert( pC != null ); |
||
5222 | pIn2 = aMem[pOp.p2]; |
||
5223 | Debug.Assert( ( pIn2.flags & MEM_Blob ) != 0 ); |
||
5224 | pCrsr = pC.pCursor; |
||
5225 | if ( ALWAYS( pCrsr != null ) ) |
||
5226 | { |
||
5227 | Debug.Assert( !pC.isTable ); |
||
5228 | ////ExpandBlob( pIn2 ); |
||
5229 | if ( rc == SQLITE_OK ) |
||
5230 | { |
||
5231 | nKey = pIn2.n; |
||
5232 | zKey = ( pIn2.flags & MEM_Blob ) != 0 ? pIn2.zBLOB : Encoding.UTF8.GetBytes( pIn2.z ); |
||
5233 | rc = sqlite3BtreeInsert( pCrsr, zKey, nKey, null, 0, 0, ( pOp.p3 != 0 ) ? 1 : 0, |
||
5234 | ( ( pOp.p5 & OPFLAG_USESEEKRESULT ) != 0 ? pC.seekResult : 0 ) |
||
5235 | ); |
||
5236 | Debug.Assert( !pC.deferredMoveto ); |
||
5237 | pC.cacheStatus = CACHE_STALE; |
||
5238 | } |
||
5239 | } |
||
5240 | break; |
||
5241 | } |
||
5242 | |||
5243 | |||
5244 | /* Opcode: IdxDelete P1 P2 P3 * * |
||
5245 | ** |
||
5246 | ** The content of P3 registers starting at register P2 form |
||
5247 | ** an unpacked index key. This opcode removes that entry from the |
||
5248 | ** index opened by cursor P1. |
||
5249 | */ |
||
5250 | case OP_IdxDelete: |
||
5251 | { |
||
5252 | VdbeCursor pC; |
||
5253 | BtCursor pCrsr; |
||
5254 | int res; |
||
5255 | UnpackedRecord r; |
||
5256 | |||
5257 | res = 0; |
||
5258 | r = new UnpackedRecord(); |
||
5259 | |||
5260 | Debug.Assert( pOp.p3 > 0 ); |
||
5261 | Debug.Assert( pOp.p2 > 0 && pOp.p2 + pOp.p3 <= p.nMem + 1 ); |
||
5262 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
5263 | pC = p.apCsr[pOp.p1]; |
||
5264 | Debug.Assert( pC != null ); |
||
5265 | pCrsr = pC.pCursor; |
||
5266 | if ( ALWAYS( pCrsr != null ) ) |
||
5267 | { |
||
5268 | r.pKeyInfo = pC.pKeyInfo; |
||
5269 | r.nField = (u16)pOp.p3; |
||
5270 | r.flags = 0; |
||
5271 | r.aMem = new Mem[r.nField]; |
||
5272 | for ( int ra = 0; ra < r.nField; ra++ ) |
||
5273 | { |
||
5274 | r.aMem[ra] = aMem[pOp.p2 + ra]; |
||
5275 | #if SQLITE_DEBUG |
||
5276 | Debug.Assert( memIsValid( r.aMem[ra] ) ); |
||
5277 | #endif |
||
5278 | } |
||
5279 | rc = sqlite3BtreeMovetoUnpacked( pCrsr, r, 0, 0, ref res ); |
||
5280 | if ( rc == SQLITE_OK && res == 0 ) |
||
5281 | { |
||
5282 | rc = sqlite3BtreeDelete( pCrsr ); |
||
5283 | } |
||
5284 | Debug.Assert( !pC.deferredMoveto ); |
||
5285 | pC.cacheStatus = CACHE_STALE; |
||
5286 | } |
||
5287 | break; |
||
5288 | } |
||
5289 | |||
5290 | /* Opcode: IdxRowid P1 P2 * * * |
||
5291 | ** |
||
5292 | ** Write into register P2 an integer which is the last entry in the record at |
||
5293 | ** the end of the index key pointed to by cursor P1. This integer should be |
||
5294 | ** the rowid of the table entry to which this index entry points. |
||
5295 | ** |
||
5296 | ** See also: Rowid, MakeRecord. |
||
5297 | */ |
||
5298 | case OP_IdxRowid: |
||
5299 | { /* out2-prerelease */ |
||
5300 | BtCursor pCrsr; |
||
5301 | VdbeCursor pC; |
||
5302 | i64 rowid; |
||
5303 | |||
5304 | rowid = 0; |
||
5305 | |||
5306 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
5307 | pC = p.apCsr[pOp.p1]; |
||
5308 | Debug.Assert( pC != null ); |
||
5309 | pCrsr = pC.pCursor; |
||
5310 | pOut.flags = MEM_Null; |
||
5311 | if ( ALWAYS( pCrsr != null ) ) |
||
5312 | { |
||
5313 | rc = sqlite3VdbeCursorMoveto( pC ); |
||
5314 | if ( NEVER( rc != 0 ) ) |
||
5315 | goto abort_due_to_error; |
||
5316 | Debug.Assert( !pC.deferredMoveto ); |
||
5317 | Debug.Assert( !pC.isTable ); |
||
5318 | if ( !pC.nullRow ) |
||
5319 | { |
||
5320 | rc = sqlite3VdbeIdxRowid( db, pCrsr, ref rowid ); |
||
5321 | if ( rc != SQLITE_OK ) |
||
5322 | { |
||
5323 | goto abort_due_to_error; |
||
5324 | } |
||
5325 | pOut.u.i = rowid; |
||
5326 | pOut.flags = MEM_Int; |
||
5327 | } |
||
5328 | } |
||
5329 | break; |
||
5330 | } |
||
5331 | |||
5332 | /* Opcode: IdxGE P1 P2 P3 P4 P5 |
||
5333 | ** |
||
5334 | ** The P4 register values beginning with P3 form an unpacked index |
||
5335 | ** key that omits the ROWID. Compare this key value against the index |
||
5336 | ** that P1 is currently pointing to, ignoring the ROWID on the P1 index. |
||
5337 | ** |
||
5338 | ** If the P1 index entry is greater than or equal to the key value |
||
5339 | ** then jump to P2. Otherwise fall through to the next instruction. |
||
5340 | ** |
||
5341 | ** If P5 is non-zero then the key value is increased by an epsilon |
||
5342 | ** prior to the comparison. This make the opcode work like IdxGT except |
||
5343 | ** that if the key from register P3 is a prefix of the key in the cursor, |
||
5344 | ** the result is false whereas it would be true with IdxGT. |
||
5345 | */ |
||
5346 | /* Opcode: IdxLT P1 P2 P3 P4 P5 |
||
5347 | ** |
||
5348 | ** The P4 register values beginning with P3 form an unpacked index |
||
5349 | ** key that omits the ROWID. Compare this key value against the index |
||
5350 | ** that P1 is currently pointing to, ignoring the ROWID on the P1 index. |
||
5351 | ** |
||
5352 | ** If the P1 index entry is less than the key value then jump to P2. |
||
5353 | ** Otherwise fall through to the next instruction. |
||
5354 | ** |
||
5355 | ** If P5 is non-zero then the key value is increased by an epsilon prior |
||
5356 | ** to the comparison. This makes the opcode work like IdxLE. |
||
5357 | */ |
||
5358 | case OP_IdxLT: /* jump */ |
||
5359 | case OP_IdxGE: |
||
5360 | { /* jump */ |
||
5361 | VdbeCursor pC; |
||
5362 | int res; |
||
5363 | UnpackedRecord r; |
||
5364 | |||
5365 | res = 0; |
||
5366 | r = new UnpackedRecord(); |
||
5367 | |||
5368 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < p.nCursor ); |
||
5369 | pC = p.apCsr[pOp.p1]; |
||
5370 | Debug.Assert( pC != null ); |
||
5371 | Debug.Assert( pC.isOrdered ); |
||
5372 | if ( ALWAYS( pC.pCursor != null ) ) |
||
5373 | { |
||
5374 | Debug.Assert( pC.deferredMoveto == false ); |
||
5375 | Debug.Assert( pOp.p5 == 0 || pOp.p5 == 1 ); |
||
5376 | Debug.Assert( pOp.p4type == P4_INT32 ); |
||
5377 | r.pKeyInfo = pC.pKeyInfo; |
||
5378 | r.nField = (u16)pOp.p4.i; |
||
5379 | if ( pOp.p5 != 0 ) |
||
5380 | { |
||
5381 | r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; |
||
5382 | } |
||
5383 | else |
||
5384 | { |
||
5385 | r.flags = UNPACKED_IGNORE_ROWID; |
||
5386 | } |
||
5387 | r.aMem = new Mem[r.nField]; |
||
5388 | for ( int rI = 0; rI < r.nField; rI++ ) |
||
5389 | { |
||
5390 | r.aMem[rI] = aMem[pOp.p3 + rI];// r.aMem = aMem[pOp.p3]; |
||
5391 | #if SQLITE_DEBUG |
||
5392 | Debug.Assert( memIsValid( r.aMem[rI] ) ); |
||
5393 | #endif |
||
5394 | } |
||
5395 | rc = sqlite3VdbeIdxKeyCompare( pC, r, ref res ); |
||
5396 | if ( pOp.opcode == OP_IdxLT ) |
||
5397 | { |
||
5398 | res = -res; |
||
5399 | } |
||
5400 | else |
||
5401 | { |
||
5402 | Debug.Assert( pOp.opcode == OP_IdxGE ); |
||
5403 | res++; |
||
5404 | } |
||
5405 | if ( res > 0 ) |
||
5406 | { |
||
5407 | pc = pOp.p2 - 1; |
||
5408 | } |
||
5409 | } |
||
5410 | break; |
||
5411 | } |
||
5412 | |||
5413 | /* Opcode: Destroy P1 P2 P3 * * |
||
5414 | ** |
||
5415 | ** Delete an entire database table or index whose root page in the database |
||
5416 | ** file is given by P1. |
||
5417 | ** |
||
5418 | ** The table being destroyed is in the main database file if P3==0. If |
||
5419 | ** P3==1 then the table to be clear is in the auxiliary database file |
||
5420 | ** that is used to store tables create using CREATE TEMPORARY TABLE. |
||
5421 | ** |
||
5422 | ** If AUTOVACUUM is enabled then it is possible that another root page |
||
5423 | ** might be moved into the newly deleted root page in order to keep all |
||
5424 | ** root pages contiguous at the beginning of the database. The former |
||
5425 | ** value of the root page that moved - its value before the move occurred - |
||
5426 | ** is stored in register P2. If no page |
||
5427 | ** movement was required (because the table being dropped was already |
||
5428 | ** the last one in the database) then a zero is stored in register P2. |
||
5429 | ** If AUTOVACUUM is disabled then a zero is stored in register P2. |
||
5430 | ** |
||
5431 | ** See also: Clear |
||
5432 | */ |
||
5433 | case OP_Destroy: |
||
5434 | { /* out2-prerelease */ |
||
5435 | int iMoved = 0; |
||
5436 | int iCnt; |
||
5437 | Vdbe pVdbe; |
||
5438 | int iDb; |
||
5439 | |||
5440 | #if !SQLITE_OMIT_VIRTUALTABLE |
||
5441 | iCnt = 0; |
||
5442 | for ( pVdbe = db.pVdbe; pVdbe != null; pVdbe = pVdbe.pNext ) |
||
5443 | { |
||
5444 | if ( pVdbe.magic == VDBE_MAGIC_RUN && pVdbe.inVtabMethod < 2 && pVdbe.pc >= 0 ) |
||
5445 | { |
||
5446 | iCnt++; |
||
5447 | } |
||
5448 | } |
||
5449 | #else |
||
5450 | iCnt = db.activeVdbeCnt; |
||
5451 | #endif |
||
5452 | pOut.flags = MEM_Null; |
||
5453 | if ( iCnt > 1 ) |
||
5454 | { |
||
5455 | rc = SQLITE_LOCKED; |
||
5456 | p.errorAction = OE_Abort; |
||
5457 | } |
||
5458 | else |
||
5459 | { |
||
5460 | iDb = pOp.p3; |
||
5461 | Debug.Assert( iCnt == 1 ); |
||
5462 | Debug.Assert( ( p.btreeMask & ( ( (yDbMask)1 ) << iDb ) ) != 0 ); |
||
5463 | rc = sqlite3BtreeDropTable( db.aDb[iDb].pBt, pOp.p1, ref iMoved ); |
||
5464 | pOut.flags = MEM_Int; |
||
5465 | pOut.u.i = iMoved; |
||
5466 | #if !SQLITE_OMIT_AUTOVACUUM |
||
5467 | if ( rc == SQLITE_OK && iMoved != 0 ) |
||
5468 | { |
||
5469 | sqlite3RootPageMoved( db, iDb, iMoved, pOp.p1 ); |
||
5470 | /* All OP_Destroy operations occur on the same btree */ |
||
5471 | Debug.Assert( resetSchemaOnFault == 0 || resetSchemaOnFault == iDb + 1 ); |
||
5472 | resetSchemaOnFault = (u8)( iDb + 1 ); |
||
5473 | } |
||
5474 | #endif |
||
5475 | } |
||
5476 | break; |
||
5477 | } |
||
5478 | |||
5479 | /* Opcode: Clear P1 P2 P3 |
||
5480 | ** |
||
5481 | ** Delete all contents of the database table or index whose root page |
||
5482 | ** in the database file is given by P1. But, unlike Destroy, do not |
||
5483 | ** remove the table or index from the database file. |
||
5484 | ** |
||
5485 | ** The table being clear is in the main database file if P2==0. If |
||
5486 | ** P2==1 then the table to be clear is in the auxiliary database file |
||
5487 | ** that is used to store tables create using CREATE TEMPORARY TABLE. |
||
5488 | ** |
||
5489 | ** If the P3 value is non-zero, then the table referred to must be an |
||
5490 | ** intkey table (an SQL table, not an index). In this case the row change |
||
5491 | ** count is incremented by the number of rows in the table being cleared. |
||
5492 | ** If P3 is greater than zero, then the value stored in register P3 is |
||
5493 | ** also incremented by the number of rows in the table being cleared. |
||
5494 | ** |
||
5495 | ** See also: Destroy |
||
5496 | */ |
||
5497 | case OP_Clear: |
||
5498 | { |
||
5499 | int nChange; |
||
5500 | |||
5501 | nChange = 0; |
||
5502 | Debug.Assert( ( p.btreeMask & ( ( (yDbMask)1 ) << pOp.p2 ) ) != 0 ); |
||
5503 | int iDummy0 = 0; |
||
5504 | if ( pOp.p3 != 0 ) |
||
5505 | rc = sqlite3BtreeClearTable( db.aDb[pOp.p2].pBt, pOp.p1, ref nChange ); |
||
5506 | else |
||
5507 | rc = sqlite3BtreeClearTable( db.aDb[pOp.p2].pBt, pOp.p1, ref iDummy0 ); |
||
5508 | if ( pOp.p3 != 0 ) |
||
5509 | { |
||
5510 | p.nChange += nChange; |
||
5511 | if ( pOp.p3 > 0 ) |
||
5512 | { |
||
5513 | Debug.Assert( memIsValid( aMem[pOp.p3] ) ); |
||
5514 | memAboutToChange( p, aMem[pOp.p3] ); |
||
5515 | aMem[pOp.p3].u.i += nChange; |
||
5516 | } |
||
5517 | } |
||
5518 | break; |
||
5519 | } |
||
5520 | |||
5521 | /* Opcode: CreateTable P1 P2 * * * |
||
5522 | ** |
||
5523 | ** Allocate a new table in the main database file if P1==0 or in the |
||
5524 | ** auxiliary database file if P1==1 or in an attached database if |
||
5525 | ** P1>1. Write the root page number of the new table into |
||
5526 | ** register P2 |
||
5527 | ** |
||
5528 | ** The difference between a table and an index is this: A table must |
||
5529 | ** have a 4-byte integer key and can have arbitrary data. An index |
||
5530 | ** has an arbitrary key but no data. |
||
5531 | ** |
||
5532 | ** See also: CreateIndex |
||
5533 | */ |
||
5534 | /* Opcode: CreateIndex P1 P2 * * * |
||
5535 | ** |
||
5536 | ** Allocate a new index in the main database file if P1==0 or in the |
||
5537 | ** auxiliary database file if P1==1 or in an attached database if |
||
5538 | ** P1>1. Write the root page number of the new table into |
||
5539 | ** register P2. |
||
5540 | ** |
||
5541 | ** See documentation on OP_CreateTable for additional information. |
||
5542 | */ |
||
5543 | case OP_CreateIndex: /* out2-prerelease */ |
||
5544 | case OP_CreateTable: |
||
5545 | { /* out2-prerelease */ |
||
5546 | int pgno; |
||
5547 | int flags; |
||
5548 | Db pDb; |
||
5549 | |||
5550 | pgno = 0; |
||
5551 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < db.nDb ); |
||
5552 | Debug.Assert( ( p.btreeMask & ( ( (yDbMask)1 ) << pOp.p1 ) ) != 0 ); |
||
5553 | pDb = db.aDb[pOp.p1]; |
||
5554 | Debug.Assert( pDb.pBt != null ); |
||
5555 | if ( pOp.opcode == OP_CreateTable ) |
||
5556 | { |
||
5557 | /* flags = BTREE_INTKEY; */ |
||
5558 | flags = BTREE_INTKEY; |
||
5559 | } |
||
5560 | else |
||
5561 | { |
||
5562 | flags = BTREE_BLOBKEY; |
||
5563 | } |
||
5564 | rc = sqlite3BtreeCreateTable( pDb.pBt, ref pgno, flags ); |
||
5565 | pOut.u.i = pgno; |
||
5566 | break; |
||
5567 | } |
||
5568 | |||
5569 | /* Opcode: ParseSchema P1 * * P4 * |
||
5570 | ** |
||
5571 | ** Read and parse all entries from the SQLITE_MASTER table of database P1 |
||
5572 | ** that match the WHERE clause P4. |
||
5573 | ** |
||
5574 | ** This opcode invokes the parser to create a new virtual machine, |
||
5575 | ** then runs the new virtual machine. It is thus a re-entrant opcode. |
||
5576 | */ |
||
5577 | case OP_ParseSchema: |
||
5578 | { |
||
5579 | int iDb; |
||
5580 | string zMaster; |
||
5581 | string zSql; |
||
5582 | InitData initData; |
||
5583 | |||
5584 | /* Any prepared statement that invokes this opcode will hold mutexes |
||
5585 | ** on every btree. This is a prerequisite for invoking |
||
5586 | ** sqlite3InitCallback(). |
||
5587 | */ |
||
5588 | #if SQLITE_DEBUG |
||
5589 | for ( iDb = 0; iDb < db.nDb; iDb++ ) |
||
5590 | { |
||
5591 | Debug.Assert( iDb == 1 || sqlite3BtreeHoldsMutex( db.aDb[iDb].pBt ) ); |
||
5592 | } |
||
5593 | #endif |
||
5594 | |||
5595 | iDb = pOp.p1; |
||
5596 | Debug.Assert( iDb >= 0 && iDb < db.nDb ); |
||
5597 | Debug.Assert( DbHasProperty( db, iDb, DB_SchemaLoaded ) ); |
||
5598 | /* Used to be a conditional */ |
||
5599 | { |
||
5600 | zMaster = SCHEMA_TABLE( iDb ); |
||
5601 | initData = new InitData(); |
||
5602 | initData.db = db; |
||
5603 | initData.iDb = pOp.p1; |
||
5604 | initData.pzErrMsg = p.zErrMsg; |
||
5605 | zSql = sqlite3MPrintf( db, |
||
5606 | "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid", |
||
5607 | db.aDb[iDb].zName, zMaster, pOp.p4.z ); |
||
5608 | if ( string.IsNullOrEmpty( zSql ) ) |
||
5609 | { |
||
5610 | rc = SQLITE_NOMEM; |
||
5611 | } |
||
5612 | else |
||
5613 | { |
||
5614 | Debug.Assert( 0 == db.init.busy ); |
||
5615 | db.init.busy = 1; |
||
5616 | initData.rc = SQLITE_OK; |
||
5617 | //Debug.Assert( 0 == db.mallocFailed ); |
||
5618 | rc = sqlite3_exec( db, zSql, (dxCallback)sqlite3InitCallback, (object)initData, 0 ); |
||
5619 | if ( rc == SQLITE_OK ) |
||
5620 | rc = initData.rc; |
||
5621 | sqlite3DbFree( db, ref zSql ); |
||
5622 | db.init.busy = 0; |
||
5623 | } |
||
5624 | } |
||
5625 | if ( rc == SQLITE_NOMEM ) |
||
5626 | { |
||
5627 | goto no_mem; |
||
5628 | } |
||
5629 | break; |
||
5630 | } |
||
5631 | |||
5632 | #if !SQLITE_OMIT_ANALYZE |
||
5633 | /* Opcode: LoadAnalysis P1 * * * * |
||
5634 | ** |
||
5635 | ** Read the sqlite_stat1 table for database P1 and load the content |
||
5636 | ** of that table into the internal index hash table. This will cause |
||
5637 | ** the analysis to be used when preparing all subsequent queries. |
||
5638 | */ |
||
5639 | case OP_LoadAnalysis: |
||
5640 | { |
||
5641 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < db.nDb ); |
||
5642 | rc = sqlite3AnalysisLoad( db, pOp.p1 ); |
||
5643 | break; |
||
5644 | } |
||
5645 | #endif // * !SQLITE_OMIT_ANALYZE) */ |
||
5646 | |||
5647 | /* Opcode: DropTable P1 * * P4 * |
||
5648 | ** |
||
5649 | ** Remove the internal (in-memory) data structures that describe |
||
5650 | ** the table named P4 in database P1. This is called after a table |
||
5651 | ** is dropped in order to keep the internal representation of the |
||
5652 | ** schema consistent with what is on disk. |
||
5653 | */ |
||
5654 | case OP_DropTable: |
||
5655 | { |
||
5656 | sqlite3UnlinkAndDeleteTable( db, pOp.p1, pOp.p4.z ); |
||
5657 | break; |
||
5658 | } |
||
5659 | |||
5660 | /* Opcode: DropIndex P1 * * P4 * |
||
5661 | ** |
||
5662 | ** Remove the internal (in-memory) data structures that describe |
||
5663 | ** the index named P4 in database P1. This is called after an index |
||
5664 | ** is dropped in order to keep the internal representation of the |
||
5665 | ** schema consistent with what is on disk. |
||
5666 | */ |
||
5667 | case OP_DropIndex: |
||
5668 | { |
||
5669 | sqlite3UnlinkAndDeleteIndex( db, pOp.p1, pOp.p4.z ); |
||
5670 | break; |
||
5671 | } |
||
5672 | |||
5673 | /* Opcode: DropTrigger P1 * * P4 * |
||
5674 | ** |
||
5675 | ** Remove the internal (in-memory) data structures that describe |
||
5676 | ** the trigger named P4 in database P1. This is called after a trigger |
||
5677 | ** is dropped in order to keep the internal representation of the |
||
5678 | ** schema consistent with what is on disk. |
||
5679 | */ |
||
5680 | case OP_DropTrigger: |
||
5681 | { |
||
5682 | sqlite3UnlinkAndDeleteTrigger( db, pOp.p1, pOp.p4.z ); |
||
5683 | break; |
||
5684 | } |
||
5685 | |||
5686 | |||
5687 | #if !SQLITE_OMIT_INTEGRITY_CHECK |
||
5688 | /* Opcode: IntegrityCk P1 P2 P3 * P5 |
||
5689 | ** |
||
5690 | ** Do an analysis of the currently open database. Store in |
||
5691 | ** register P1 the text of an error message describing any problems. |
||
5692 | ** If no problems are found, store a NULL in register P1. |
||
5693 | ** |
||
5694 | ** The register P3 contains the maximum number of allowed errors. |
||
5695 | ** At most reg(P3) errors will be reported. |
||
5696 | ** In other words, the analysis stops as soon as reg(P1) errors are |
||
5697 | ** seen. Reg(P1) is updated with the number of errors remaining. |
||
5698 | ** |
||
5699 | ** The root page numbers of all tables in the database are integer |
||
5700 | ** stored in reg(P1), reg(P1+1), reg(P1+2), .... There are P2 tables |
||
5701 | ** total. |
||
5702 | ** |
||
5703 | ** If P5 is not zero, the check is done on the auxiliary database |
||
5704 | ** file, not the main database file. |
||
5705 | ** |
||
5706 | ** This opcode is used to implement the integrity_check pragma. |
||
5707 | */ |
||
5708 | case OP_IntegrityCk: |
||
5709 | { |
||
5710 | int nRoot; /* Number of tables to check. (Number of root pages.) */ |
||
5711 | int[] aRoot = null; /* Array of rootpage numbers for tables to be checked */ |
||
5712 | int j; /* Loop counter */ |
||
5713 | int nErr = 0; /* Number of errors reported */ |
||
5714 | string z; /* Text of the error report */ |
||
5715 | Mem pnErr; /* Register keeping track of errors remaining */ |
||
5716 | |||
5717 | nRoot = pOp.p2; |
||
5718 | Debug.Assert( nRoot > 0 ); |
||
5719 | aRoot = sqlite3Malloc( aRoot, ( nRoot + 1 ) );// sqlite3DbMallocRaw(db, sizeof(int) * (nRoot + 1)); |
||
5720 | if ( aRoot == null ) |
||
5721 | goto no_mem; |
||
5722 | Debug.Assert( pOp.p3 > 0 && pOp.p3 <= p.nMem ); |
||
5723 | pnErr = aMem[pOp.p3]; |
||
5724 | Debug.Assert( ( pnErr.flags & MEM_Int ) != 0 ); |
||
5725 | Debug.Assert( ( pnErr.flags & ( MEM_Str | MEM_Blob ) ) == 0 ); |
||
5726 | pIn1 = aMem[pOp.p1]; |
||
5727 | for ( j = 0; j < nRoot; j++ ) |
||
5728 | { |
||
5729 | aRoot[j] = (int)sqlite3VdbeIntValue( p.aMem[pOp.p1 + j] ); // pIn1[j]); |
||
5730 | } |
||
5731 | aRoot[j] = 0; |
||
5732 | Debug.Assert( pOp.p5 < db.nDb ); |
||
5733 | Debug.Assert( ( p.btreeMask & ( ( (yDbMask)1 ) << pOp.p5 ) ) != 0 ); |
||
5734 | z = sqlite3BtreeIntegrityCheck( db.aDb[pOp.p5].pBt, aRoot, nRoot, |
||
5735 | (int)pnErr.u.i, ref nErr ); |
||
5736 | sqlite3DbFree( db, ref aRoot ); |
||
5737 | pnErr.u.i -= nErr; |
||
5738 | sqlite3VdbeMemSetNull( pIn1 ); |
||
5739 | if ( nErr == 0 ) |
||
5740 | { |
||
5741 | Debug.Assert( z.Length == 0 ); |
||
5742 | } |
||
5743 | else if ( string.IsNullOrEmpty( z ) ) |
||
5744 | { |
||
5745 | goto no_mem; |
||
5746 | } |
||
5747 | else |
||
5748 | { |
||
5749 | sqlite3VdbeMemSetStr( pIn1, z, -1, SQLITE_UTF8, null ); //sqlite3_free ); |
||
5750 | } |
||
5751 | #if SQLITE_TEST |
||
5752 | UPDATE_MAX_BLOBSIZE( pIn1 ); |
||
5753 | #endif |
||
5754 | sqlite3VdbeChangeEncoding( pIn1, encoding ); |
||
5755 | break; |
||
5756 | } |
||
5757 | #endif // * SQLITE_OMIT_INTEGRITY_CHECK */ |
||
5758 | |||
5759 | /* Opcode: RowSetAdd P1 P2 * * * |
||
5760 | ** |
||
5761 | ** Insert the integer value held by register P2 into a boolean index |
||
5762 | ** held in register P1. |
||
5763 | ** |
||
5764 | ** An assertion fails if P2 is not an integer. |
||
5765 | */ |
||
5766 | case OP_RowSetAdd: |
||
5767 | { /* in1, in2 */ |
||
5768 | pIn1 = aMem[pOp.p1]; |
||
5769 | pIn2 = aMem[pOp.p2]; |
||
5770 | Debug.Assert( ( pIn2.flags & MEM_Int ) != 0 ); |
||
5771 | if ( ( pIn1.flags & MEM_RowSet ) == 0 ) |
||
5772 | { |
||
5773 | sqlite3VdbeMemSetRowSet( pIn1 ); |
||
5774 | if ( ( pIn1.flags & MEM_RowSet ) == 0 ) |
||
5775 | goto no_mem; |
||
5776 | } |
||
5777 | sqlite3RowSetInsert( pIn1.u.pRowSet, pIn2.u.i ); |
||
5778 | break; |
||
5779 | } |
||
5780 | /* Opcode: RowSetRead P1 P2 P3 * * |
||
5781 | ** |
||
5782 | ** Extract the smallest value from boolean index P1 and put that value into |
||
5783 | ** register P3. Or, if boolean index P1 is initially empty, leave P3 |
||
5784 | ** unchanged and jump to instruction P2. |
||
5785 | */ |
||
5786 | case OP_RowSetRead: |
||
5787 | { /* jump, in1, ref3 */ |
||
5788 | i64 val = 0; |
||
5789 | if ( db.u1.isInterrupted ) |
||
5790 | goto abort_due_to_interrupt; //CHECK_FOR_INTERRUPT; |
||
5791 | pIn1 = aMem[pOp.p1]; |
||
5792 | if ( ( pIn1.flags & MEM_RowSet ) == 0 |
||
5793 | || sqlite3RowSetNext( pIn1.u.pRowSet, ref val ) == 0 |
||
5794 | ) |
||
5795 | { |
||
5796 | /* The boolean index is empty */ |
||
5797 | sqlite3VdbeMemSetNull( pIn1 ); |
||
5798 | pc = pOp.p2 - 1; |
||
5799 | } |
||
5800 | else |
||
5801 | { |
||
5802 | /* A value was pulled from the index */ |
||
5803 | sqlite3VdbeMemSetInt64( aMem[pOp.p3], val ); |
||
5804 | } |
||
5805 | break; |
||
5806 | } |
||
5807 | |||
5808 | /* Opcode: RowSetTest P1 P2 P3 P4 |
||
5809 | ** |
||
5810 | ** Register P3 is assumed to hold a 64-bit integer value. If register P1 |
||
5811 | ** contains a RowSet object and that RowSet object contains |
||
5812 | ** the value held in P3, jump to register P2. Otherwise, insert the |
||
5813 | ** integer in P3 into the RowSet and continue on to the |
||
5814 | ** next opcode. |
||
5815 | ** |
||
5816 | ** The RowSet object is optimized for the case where successive sets |
||
5817 | ** of integers, where each set contains no duplicates. Each set |
||
5818 | ** of values is identified by a unique P4 value. The first set |
||
5819 | ** must have P4==0, the final set P4=-1. P4 must be either -1 or |
||
5820 | ** non-negative. For non-negative values of P4 only the lower 4 |
||
5821 | ** bits are significant. |
||
5822 | ** |
||
5823 | ** This allows optimizations: (a) when P4==0 there is no need to test |
||
5824 | ** the rowset object for P3, as it is guaranteed not to contain it, |
||
5825 | ** (b) when P4==-1 there is no need to insert the value, as it will |
||
5826 | ** never be tested for, and (c) when a value that is part of set X is |
||
5827 | ** inserted, there is no need to search to see if the same value was |
||
5828 | ** previously inserted as part of set X (only if it was previously |
||
5829 | ** inserted as part of some other set). |
||
5830 | */ |
||
5831 | case OP_RowSetTest: |
||
5832 | { /* jump, in1, in3 */ |
||
5833 | int iSet; |
||
5834 | int exists; |
||
5835 | |||
5836 | pIn1 = aMem[pOp.p1]; |
||
5837 | pIn3 = aMem[pOp.p3]; |
||
5838 | iSet = pOp.p4.i; |
||
5839 | Debug.Assert( ( pIn3.flags & MEM_Int ) != 0 ); |
||
5840 | |||
5841 | /* If there is anything other than a rowset object in memory cell P1, |
||
5842 | ** delete it now and initialize P1 with an empty rowset |
||
5843 | */ |
||
5844 | if ( ( pIn1.flags & MEM_RowSet ) == 0 ) |
||
5845 | { |
||
5846 | sqlite3VdbeMemSetRowSet( pIn1 ); |
||
5847 | if ( ( pIn1.flags & MEM_RowSet ) == 0 ) |
||
5848 | goto no_mem; |
||
5849 | } |
||
5850 | |||
5851 | Debug.Assert( pOp.p4type == P4_INT32 ); |
||
5852 | Debug.Assert( iSet == -1 || iSet >= 0 ); |
||
5853 | if ( iSet != 0 ) |
||
5854 | { |
||
5855 | exists = sqlite3RowSetTest( pIn1.u.pRowSet, |
||
5856 | (u8)( iSet >= 0 ? iSet & 0xf : 0xff ), |
||
5857 | pIn3.u.i ); |
||
5858 | if ( exists != 0 ) |
||
5859 | { |
||
5860 | pc = pOp.p2 - 1; |
||
5861 | break; |
||
5862 | } |
||
5863 | } |
||
5864 | if ( iSet >= 0 ) |
||
5865 | { |
||
5866 | sqlite3RowSetInsert( pIn1.u.pRowSet, pIn3.u.i ); |
||
5867 | } |
||
5868 | break; |
||
5869 | } |
||
5870 | |||
5871 | #if !SQLITE_OMIT_TRIGGER |
||
5872 | |||
5873 | /* Opcode: Program P1 P2 P3 P4 * |
||
5874 | ** |
||
5875 | ** Execute the trigger program passed as P4 (type P4_SUBPROGRAM). |
||
5876 | ** |
||
5877 | ** P1 contains the address of the memory cell that contains the first memory |
||
5878 | ** cell in an array of values used as arguments to the sub-program. P2 |
||
5879 | ** contains the address to jump to if the sub-program throws an IGNORE |
||
5880 | ** exception using the RAISE() function. Register P3 contains the address |
||
5881 | ** of a memory cell in this (the parent) VM that is used to allocate the |
||
5882 | ** memory required by the sub-vdbe at runtime. |
||
5883 | ** |
||
5884 | ** P4 is a pointer to the VM containing the trigger program. |
||
5885 | */ |
||
5886 | case OP_Program: |
||
5887 | { /* jump */ |
||
5888 | int nMem; /* Number of memory registers for sub-program */ |
||
5889 | int nByte; /* Bytes of runtime space required for sub-program */ |
||
5890 | Mem pRt; /* Register to allocate runtime space */ |
||
5891 | Mem pMem = null; /* Used to iterate through memory cells */ |
||
5892 | //Mem pEnd; /* Last memory cell in new array */ |
||
5893 | VdbeFrame pFrame; /* New vdbe frame to execute in */ |
||
5894 | SubProgram pProgram; /* Sub-program to execute */ |
||
5895 | int t; /* Token identifying trigger */ |
||
5896 | |||
5897 | pProgram = pOp.p4.pProgram; |
||
5898 | pRt = aMem[pOp.p3]; |
||
5899 | Debug.Assert( memIsValid( pRt ) ); |
||
5900 | Debug.Assert( pProgram.nOp > 0 ); |
||
5901 | |||
5902 | /* If the p5 flag is clear, then recursive invocation of triggers is |
||
5903 | ** disabled for backwards compatibility (p5 is set if this sub-program |
||
5904 | ** is really a trigger, not a foreign key action, and the flag set |
||
5905 | ** and cleared by the "PRAGMA recursive_triggers" command is clear). |
||
5906 | ** |
||
5907 | ** It is recursive invocation of triggers, at the SQL level, that is |
||
5908 | ** disabled. In some cases a single trigger may generate more than one |
||
5909 | ** SubProgram (if the trigger may be executed with more than one different |
||
5910 | ** ON CONFLICT algorithm). SubProgram structures associated with a |
||
5911 | ** single trigger all have the same value for the SubProgram.token |
||
5912 | ** variable. */ |
||
5913 | if ( pOp.p5 != 0 ) |
||
5914 | { |
||
5915 | t = pProgram.token; |
||
5916 | for ( pFrame = p.pFrame; pFrame != null && pFrame.token != t; pFrame = pFrame.pParent ) |
||
5917 | ; |
||
5918 | if ( pFrame != null ) |
||
5919 | break; |
||
5920 | } |
||
5921 | |||
5922 | if ( p.nFrame >= db.aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ) |
||
5923 | { |
||
5924 | rc = SQLITE_ERROR; |
||
5925 | sqlite3SetString( ref p.zErrMsg, db, "too many levels of trigger recursion" ); |
||
5926 | break; |
||
5927 | } |
||
5928 | |||
5929 | /* Register pRt is used to store the memory required to save the state |
||
5930 | ** of the current program, and the memory required at runtime to execute |
||
5931 | ** the trigger program. If this trigger has been fired before, then pRt |
||
5932 | ** is already allocated. Otherwise, it must be initialized. */ |
||
5933 | if ( ( pRt.flags & MEM_Frame ) == 0 ) |
||
5934 | { |
||
5935 | /* SubProgram.nMem is set to the number of memory cells used by the |
||
5936 | ** program stored in SubProgram.aOp. As well as these, one memory |
||
5937 | ** cell is required for each cursor used by the program. Set local |
||
5938 | ** variable nMem (and later, VdbeFrame.nChildMem) to this value. |
||
5939 | */ |
||
5940 | nMem = pProgram.nMem + pProgram.nCsr; |
||
5941 | //nByte = ROUND8( sizeof( VdbeFrame ) ) |
||
5942 | //+ nMem * sizeof( Mem ) |
||
5943 | //+ pProgram.nCsr * sizeof( VdbeCursor* ); |
||
5944 | pFrame = new VdbeFrame();// sqlite3DbMallocZero( db, nByte ); |
||
5945 | //if ( !pFrame ) |
||
5946 | //{ |
||
5947 | // goto no_mem; |
||
5948 | //} |
||
5949 | sqlite3VdbeMemRelease( pRt ); |
||
5950 | pRt.flags = MEM_Frame; |
||
5951 | pRt.u.pFrame = pFrame; |
||
5952 | |||
5953 | pFrame.v = p; |
||
5954 | pFrame.nChildMem = nMem; |
||
5955 | pFrame.nChildCsr = pProgram.nCsr; |
||
5956 | pFrame.pc = pc; |
||
5957 | pFrame.aMem = p.aMem; |
||
5958 | pFrame.nMem = p.nMem; |
||
5959 | pFrame.apCsr = p.apCsr; |
||
5960 | pFrame.nCursor = p.nCursor; |
||
5961 | pFrame.aOp = p.aOp; |
||
5962 | pFrame.nOp = p.nOp; |
||
5963 | pFrame.token = pProgram.token; |
||
5964 | |||
5965 | // &VdbeFrameMem( pFrame )[pFrame.nChildMem]; |
||
5966 | // aMem is 1 based, so allocate 1 extra cell under C# |
||
5967 | pFrame.aChildMem = new Mem[pFrame.nChildMem + 1]; |
||
5968 | for ( int i = 0; i < pFrame.aChildMem.Length; i++ )//pMem = VdbeFrameMem( pFrame ) ; pMem != pEnd ; pMem++ ) |
||
5969 | { |
||
5970 | //pFrame.aMem[i] = pFrame.aMem[pFrame.nMem+i]; |
||
5971 | pMem = sqlite3Malloc( pMem ); |
||
5972 | pMem.flags = MEM_Null; |
||
5973 | pMem.db = db; |
||
5974 | pFrame.aChildMem[i] = pMem; |
||
5975 | } |
||
5976 | pFrame.aChildCsr = new VdbeCursor[pFrame.nChildCsr]; |
||
5977 | for ( int i = 0; i < pFrame.nChildCsr; i++ ) |
||
5978 | pFrame.aChildCsr[i] = new VdbeCursor(); |
||
5979 | } |
||
5980 | else |
||
5981 | { |
||
5982 | pFrame = pRt.u.pFrame; |
||
5983 | Debug.Assert( pProgram.nMem + pProgram.nCsr == pFrame.nChildMem ); |
||
5984 | Debug.Assert( pProgram.nCsr == pFrame.nChildCsr ); |
||
5985 | Debug.Assert( pc == pFrame.pc ); |
||
5986 | } |
||
5987 | |||
5988 | p.nFrame++; |
||
5989 | pFrame.pParent = p.pFrame; |
||
5990 | pFrame.lastRowid = lastRowid; |
||
5991 | pFrame.nChange = p.nChange; |
||
5992 | p.nChange = 0; |
||
5993 | p.pFrame = pFrame; |
||
5994 | p.aMem = aMem = pFrame.aChildMem; // &VdbeFrameMem( pFrame )[-1]; |
||
5995 | p.nMem = pFrame.nChildMem; |
||
5996 | p.nCursor = (u16)pFrame.nChildCsr; |
||
5997 | p.apCsr = pFrame.aChildCsr;// (VdbeCursor *)&aMem[p->nMem+1]; |
||
5998 | p.aOp = aOp = pProgram.aOp; |
||
5999 | p.nOp = pProgram.nOp; |
||
6000 | pc = -1; |
||
6001 | |||
6002 | break; |
||
6003 | } |
||
6004 | |||
6005 | /* Opcode: Param P1 P2 * * * |
||
6006 | ** |
||
6007 | ** This opcode is only ever present in sub-programs called via the |
||
6008 | ** OP_Program instruction. Copy a value currently stored in a memory |
||
6009 | ** cell of the calling (parent) frame to cell P2 in the current frames |
||
6010 | ** address space. This is used by trigger programs to access the new.* |
||
6011 | ** and old.* values. |
||
6012 | ** |
||
6013 | ** The address of the cell in the parent frame is determined by adding |
||
6014 | ** the value of the P1 argument to the value of the P1 argument to the |
||
6015 | ** calling OP_Program instruction. |
||
6016 | */ |
||
6017 | case OP_Param: |
||
6018 | { /* out2-prerelease */ |
||
6019 | VdbeFrame pFrame; |
||
6020 | Mem pIn; |
||
6021 | pFrame = p.pFrame; |
||
6022 | pIn = pFrame.aMem[pOp.p1 + pFrame.aOp[pFrame.pc].p1]; |
||
6023 | sqlite3VdbeMemShallowCopy( pOut, pIn, MEM_Ephem ); |
||
6024 | break; |
||
6025 | } |
||
6026 | #endif // * #if !SQLITE_OMIT_TRIGGER */ |
||
6027 | |||
6028 | #if !SQLITE_OMIT_FOREIGN_KEY |
||
6029 | /* Opcode: FkCounter P1 P2 * * * |
||
6030 | ** |
||
6031 | ** Increment a "constraint counter" by P2 (P2 may be negative or positive). |
||
6032 | ** If P1 is non-zero, the database constraint counter is incremented |
||
6033 | ** (deferred foreign key constraints). Otherwise, if P1 is zero, the |
||
6034 | ** statement counter is incremented (immediate foreign key constraints). |
||
6035 | */ |
||
6036 | case OP_FkCounter: |
||
6037 | { |
||
6038 | if ( pOp.p1 != 0 ) |
||
6039 | { |
||
6040 | db.nDeferredCons += pOp.p2; |
||
6041 | } |
||
6042 | else |
||
6043 | { |
||
6044 | p.nFkConstraint += pOp.p2; |
||
6045 | } |
||
6046 | break; |
||
6047 | } |
||
6048 | |||
6049 | /* Opcode: FkIfZero P1 P2 * * * |
||
6050 | ** |
||
6051 | ** This opcode tests if a foreign key constraint-counter is currently zero. |
||
6052 | ** If so, jump to instruction P2. Otherwise, fall through to the next |
||
6053 | ** instruction. |
||
6054 | ** |
||
6055 | ** If P1 is non-zero, then the jump is taken if the database constraint-counter |
||
6056 | ** is zero (the one that counts deferred constraint violations). If P1 is |
||
6057 | ** zero, the jump is taken if the statement constraint-counter is zero |
||
6058 | ** (immediate foreign key constraint violations). |
||
6059 | */ |
||
6060 | case OP_FkIfZero: |
||
6061 | { /* jump */ |
||
6062 | if ( pOp.p1 != 0 ) |
||
6063 | { |
||
6064 | if ( db.nDeferredCons == 0 ) |
||
6065 | pc = pOp.p2 - 1; |
||
6066 | } |
||
6067 | else |
||
6068 | { |
||
6069 | if ( p.nFkConstraint == 0 ) |
||
6070 | pc = pOp.p2 - 1; |
||
6071 | } |
||
6072 | break; |
||
6073 | } |
||
6074 | #endif //* #if !SQLITE_OMIT_FOREIGN_KEY */ |
||
6075 | |||
6076 | #if !SQLITE_OMIT_AUTOINCREMENT |
||
6077 | /* Opcode: MemMax P1 P2 * * * |
||
6078 | ** |
||
6079 | ** P1 is a register in the root frame of this VM (the root frame is |
||
6080 | ** different from the current frame if this instruction is being executed |
||
6081 | ** within a sub-program). Set the value of register P1 to the maximum of |
||
6082 | ** its current value and the value in register P2. |
||
6083 | ** |
||
6084 | ** This instruction throws an error if the memory cell is not initially |
||
6085 | ** an integer. |
||
6086 | */ |
||
6087 | case OP_MemMax: |
||
6088 | { /* in2 */ |
||
6089 | Mem _pIn1; |
||
6090 | VdbeFrame pFrame; |
||
6091 | if ( p.pFrame != null ) |
||
6092 | { |
||
6093 | for ( pFrame = p.pFrame; pFrame.pParent != null; pFrame = pFrame.pParent ) |
||
6094 | ; |
||
6095 | _pIn1 = pFrame.aMem[pOp.p1]; |
||
6096 | } |
||
6097 | else |
||
6098 | { |
||
6099 | _pIn1 = aMem[pOp.p1]; |
||
6100 | } |
||
6101 | Debug.Assert( memIsValid( _pIn1 ) ); |
||
6102 | sqlite3VdbeMemIntegerify( _pIn1 ); |
||
6103 | pIn2 = aMem[pOp.p2]; |
||
6104 | sqlite3VdbeMemIntegerify( pIn2 ); |
||
6105 | if ( _pIn1.u.i < pIn2.u.i ) |
||
6106 | { |
||
6107 | _pIn1.u.i = pIn2.u.i; |
||
6108 | } |
||
6109 | break; |
||
6110 | } |
||
6111 | #endif // * SQLITE_OMIT_AUTOINCREMENT */ |
||
6112 | |||
6113 | /* Opcode: IfPos P1 P2 * * * |
||
6114 | ** |
||
6115 | ** If the value of register P1 is 1 or greater, jump to P2. |
||
6116 | ** |
||
6117 | ** It is illegal to use this instruction on a register that does |
||
6118 | ** not contain an integer. An Debug.Assertion fault will result if you try. |
||
6119 | */ |
||
6120 | case OP_IfPos: |
||
6121 | { /* jump, in1 */ |
||
6122 | pIn1 = aMem[pOp.p1]; |
||
6123 | Debug.Assert( ( pIn1.flags & MEM_Int ) != 0 ); |
||
6124 | if ( pIn1.u.i > 0 ) |
||
6125 | { |
||
6126 | pc = pOp.p2 - 1; |
||
6127 | } |
||
6128 | break; |
||
6129 | } |
||
6130 | |||
6131 | /* Opcode: IfNeg P1 P2 * * * |
||
6132 | ** |
||
6133 | ** If the value of register P1 is less than zero, jump to P2. |
||
6134 | ** |
||
6135 | ** It is illegal to use this instruction on a register that does |
||
6136 | ** not contain an integer. An Debug.Assertion fault will result if you try. |
||
6137 | */ |
||
6138 | case OP_IfNeg: |
||
6139 | { /* jump, in1 */ |
||
6140 | pIn1 = aMem[pOp.p1]; |
||
6141 | Debug.Assert( ( pIn1.flags & MEM_Int ) != 0 ); |
||
6142 | if ( pIn1.u.i < 0 ) |
||
6143 | { |
||
6144 | pc = pOp.p2 - 1; |
||
6145 | } |
||
6146 | break; |
||
6147 | } |
||
6148 | |||
6149 | /* Opcode: IfZero P1 P2 P3 * * |
||
6150 | ** |
||
6151 | ** The register P1 must contain an integer. Add literal P3 to the |
||
6152 | ** value in register P1. If the result is exactly 0, jump to P2. |
||
6153 | ** |
||
6154 | ** It is illegal to use this instruction on a register that does |
||
6155 | ** not contain an integer. An assertion fault will result if you try. |
||
6156 | */ |
||
6157 | case OP_IfZero: |
||
6158 | { /* jump, in1 */ |
||
6159 | pIn1 = aMem[pOp.p1]; |
||
6160 | Debug.Assert( ( pIn1.flags & MEM_Int ) != 0 ); |
||
6161 | pIn1.u.i += pOp.p3; |
||
6162 | if ( pIn1.u.i == 0 ) |
||
6163 | { |
||
6164 | pc = pOp.p2 - 1; |
||
6165 | } |
||
6166 | break; |
||
6167 | } |
||
6168 | |||
6169 | /* Opcode: AggStep * P2 P3 P4 P5 |
||
6170 | ** |
||
6171 | ** Execute the step function for an aggregate. The |
||
6172 | ** function has P5 arguments. P4 is a pointer to the FuncDef |
||
6173 | ** structure that specifies the function. Use register |
||
6174 | ** P3 as the accumulator. |
||
6175 | ** |
||
6176 | ** The P5 arguments are taken from register P2 and its |
||
6177 | ** successors. |
||
6178 | */ |
||
6179 | case OP_AggStep: |
||
6180 | { |
||
6181 | int n; |
||
6182 | int i; |
||
6183 | Mem pMem; |
||
6184 | Mem pRec; |
||
6185 | sqlite3_context ctx = new sqlite3_context(); |
||
6186 | sqlite3_value[] apVal; |
||
6187 | |||
6188 | n = pOp.p5; |
||
6189 | Debug.Assert( n >= 0 ); |
||
6190 | //pRec = aMem[pOp.p2]; |
||
6191 | apVal = p.apArg; |
||
6192 | Debug.Assert( apVal != null || n == 0 ); |
||
6193 | for ( i = 0; i < n; i++ )//, pRec++) |
||
6194 | { |
||
6195 | pRec = aMem[pOp.p2 + i]; |
||
6196 | Debug.Assert( memIsValid( pRec ) ); |
||
6197 | apVal[i] = pRec; |
||
6198 | memAboutToChange( p, pRec ); |
||
6199 | sqlite3VdbeMemStoreType( pRec ); |
||
6200 | } |
||
6201 | ctx.pFunc = pOp.p4.pFunc; |
||
6202 | Debug.Assert( pOp.p3 > 0 && pOp.p3 <= p.nMem ); |
||
6203 | ctx.pMem = pMem = aMem[pOp.p3]; |
||
6204 | pMem.n++; |
||
6205 | ctx.s.flags = MEM_Null; |
||
6206 | ctx.s.z = null; |
||
6207 | //ctx.s.zMalloc = null; |
||
6208 | ctx.s.xDel = null; |
||
6209 | ctx.s.db = db; |
||
6210 | ctx.isError = 0; |
||
6211 | ctx.pColl = null; |
||
6212 | if ( ( ctx.pFunc.flags & SQLITE_FUNC_NEEDCOLL ) != 0 ) |
||
6213 | { |
||
6214 | Debug.Assert( pc > 0 );//pOp > p.aOp ); |
||
6215 | Debug.Assert( p.aOp[pc - 1].p4type == P4_COLLSEQ ); //pOp[-1].p4type == P4_COLLSEQ ); |
||
6216 | Debug.Assert( p.aOp[pc - 1].opcode == OP_CollSeq ); // pOp[-1].opcode == OP_CollSeq ); |
||
6217 | ctx.pColl = p.aOp[pc - 1].p4.pColl; |
||
6218 | ;// pOp[-1].p4.pColl; |
||
6219 | } |
||
6220 | ctx.pFunc.xStep( ctx, n, apVal ); /* IMP: R-24505-23230 */ |
||
6221 | if ( ctx.isError != 0 ) |
||
6222 | { |
||
6223 | sqlite3SetString( ref p.zErrMsg, db, sqlite3_value_text( ctx.s ) ); |
||
6224 | rc = ctx.isError; |
||
6225 | } |
||
6226 | sqlite3VdbeMemRelease( ctx.s ); |
||
6227 | break; |
||
6228 | } |
||
6229 | |||
6230 | /* Opcode: AggFinal P1 P2 * P4 * |
||
6231 | ** |
||
6232 | ** Execute the finalizer function for an aggregate. P1 is |
||
6233 | ** the memory location that is the accumulator for the aggregate. |
||
6234 | ** |
||
6235 | ** P2 is the number of arguments that the step function takes and |
||
6236 | ** P4 is a pointer to the FuncDef for this function. The P2 |
||
6237 | ** argument is not used by this opcode. It is only there to disambiguate |
||
6238 | ** functions that can take varying numbers of arguments. The |
||
6239 | ** P4 argument is only needed for the degenerate case where |
||
6240 | ** the step function was not previously called. |
||
6241 | */ |
||
6242 | case OP_AggFinal: |
||
6243 | { |
||
6244 | Mem pMem; |
||
6245 | Debug.Assert( pOp.p1 > 0 && pOp.p1 <= p.nMem ); |
||
6246 | pMem = aMem[pOp.p1]; |
||
6247 | Debug.Assert( ( pMem.flags & ~( MEM_Null | MEM_Agg ) ) == 0 ); |
||
6248 | rc = sqlite3VdbeMemFinalize( pMem, pOp.p4.pFunc ); |
||
6249 | p.aMem[pOp.p1] = pMem; |
||
6250 | if ( rc != 0 ) |
||
6251 | { |
||
6252 | sqlite3SetString( ref p.zErrMsg, db, sqlite3_value_text( pMem ) ); |
||
6253 | } |
||
6254 | sqlite3VdbeChangeEncoding( pMem, encoding ); |
||
6255 | #if SQLITE_TEST |
||
6256 | UPDATE_MAX_BLOBSIZE( pMem ); |
||
6257 | #endif |
||
6258 | if ( sqlite3VdbeMemTooBig( pMem ) ) |
||
6259 | { |
||
6260 | goto too_big; |
||
6261 | } |
||
6262 | break; |
||
6263 | } |
||
6264 | |||
6265 | |||
6266 | #if !SQLITE_OMIT_WAL |
||
6267 | /* Opcode: Checkpoint P1 P2 P3 * * |
||
6268 | ** |
||
6269 | ** Checkpoint database P1. This is a no-op if P1 is not currently in |
||
6270 | ** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL |
||
6271 | ** or RESTART. Write 1 or 0 into mem[P3] if the checkpoint returns |
||
6272 | ** SQLITE_BUSY or not, respectively. Write the number of pages in the |
||
6273 | ** WAL after the checkpoint into mem[P3+1] and the number of pages |
||
6274 | ** in the WAL that have been checkpointed after the checkpoint |
||
6275 | ** completes into mem[P3+2]. However on an error, mem[P3+1] and |
||
6276 | ** mem[P3+2] are initialized to -1. |
||
6277 | */ |
||
6278 | cDebug.Ase OP_Checkpoint: { |
||
6279 | aRes[0] = 0; |
||
6280 | aRes[1] = aRes[2] = -1; |
||
6281 | Debug.Assert( pOp.p2==SQLITE_CHECKPOINT_PDebug.AsSIVE |
||
6282 | || pOp.p2==SQLITE_CHECKPOINT_FULL |
||
6283 | || pOp.p2==SQLITE_CHECKPOINT_RESTART |
||
6284 | ); |
||
6285 | rc = sqlite3Checkpoint(db, pOp.p1, pOp.p2, ref aRes[1], ref aRes[2]); |
||
6286 | if( rc==SQLITE_BUSY ){ |
||
6287 | rc = SQLITE_OK; |
||
6288 | aRes[0] = 1; |
||
6289 | } |
||
6290 | for(i=0, pMem = aMem[pOp.p3]; i<3; i++, pMem++){ |
||
6291 | sqlite3VdbeMemSetInt64(pMem, (i64)aRes[i]); |
||
6292 | } |
||
6293 | break; |
||
6294 | }; |
||
6295 | #endif |
||
6296 | |||
6297 | #if !SQLITE_OMIT_PRAGMA |
||
6298 | /* Opcode: JournalMode P1 P2 P3 * P5 |
||
6299 | ** |
||
6300 | ** Change the journal mode of database P1 to P3. P3 must be one of the |
||
6301 | ** PAGER_JOURNALMODE_XXX values. If changing between the various rollback |
||
6302 | ** modes (delete, truncate, persist, off and memory), this is a simple |
||
6303 | ** operation. No IO is required. |
||
6304 | ** |
||
6305 | ** If changing into or out of WAL mode the procedure is more complicated. |
||
6306 | ** |
||
6307 | ** Write a string containing the final journal-mode to register P2. |
||
6308 | */ |
||
6309 | case OP_JournalMode: |
||
6310 | { /* out2-prerelease */ |
||
6311 | Btree pBt; /* Btree to change journal mode of */ |
||
6312 | Pager pPager; /* Pager associated with pBt */ |
||
6313 | int eNew; /* New journal mode */ |
||
6314 | int eOld; /* The old journal mode */ |
||
6315 | string zFilename; /* Name of database file for pPager */ |
||
6316 | |||
6317 | eNew = pOp.p3; |
||
6318 | Debug.Assert( eNew == PAGER_JOURNALMODE_DELETE |
||
6319 | || eNew == PAGER_JOURNALMODE_TRUNCATE |
||
6320 | || eNew == PAGER_JOURNALMODE_PERSIST |
||
6321 | || eNew == PAGER_JOURNALMODE_OFF |
||
6322 | || eNew == PAGER_JOURNALMODE_MEMORY |
||
6323 | || eNew == PAGER_JOURNALMODE_WAL |
||
6324 | || eNew == PAGER_JOURNALMODE_QUERY |
||
6325 | ); |
||
6326 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < db.nDb ); |
||
6327 | |||
6328 | pBt = db.aDb[pOp.p1].pBt; |
||
6329 | pPager = sqlite3BtreePager( pBt ); |
||
6330 | eOld = sqlite3PagerGetJournalMode( pPager ); |
||
6331 | if ( eNew == PAGER_JOURNALMODE_QUERY ) |
||
6332 | eNew = eOld; |
||
6333 | if ( 0 == sqlite3PagerOkToChangeJournalMode( pPager ) ) |
||
6334 | eNew = eOld; |
||
6335 | |||
6336 | #if !SQLITE_OMIT_WAL |
||
6337 | zFilename = sqlite3PagerFilename(pPager); |
||
6338 | |||
6339 | /* Do not allow a transition to journal_mode=WAL for a database |
||
6340 | ** in temporary storage or if the VFS does not support shared memory |
||
6341 | */ |
||
6342 | if( eNew==PAGER_JOURNALMODE_WAL |
||
6343 | && (zFilename[0]==0 /* Temp file */ |
||
6344 | || !sqlite3PagerWalSupported(pPager)) /* No shared-memory support */ |
||
6345 | ){ |
||
6346 | eNew = eOld; |
||
6347 | } |
||
6348 | |||
6349 | if( (eNew!=eOld) |
||
6350 | && (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL) |
||
6351 | ){ |
||
6352 | if( null==db.autoCommit || db.activeVdbeCnt>1 ){ |
||
6353 | rc = SQLITE_ERROR; |
||
6354 | sqlite3SetString(&p.zErrMsg, db, |
||
6355 | "cannot change %s wal mode from within a transaction", |
||
6356 | (eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") |
||
6357 | ); |
||
6358 | break; |
||
6359 | }else{ |
||
6360 | |||
6361 | if( eOld==PAGER_JOURNALMODE_WAL ){ |
||
6362 | /* If leaving WAL mode, close the log file. If successful, the call |
||
6363 | ** to PagerCloseWal() checkpoints and deletes the write-ahead-log |
||
6364 | ** file. An EXCLUSIVE lock may still be held on the database file |
||
6365 | ** after a successful return. |
||
6366 | */ |
||
6367 | rc = sqlite3PagerCloseWal(pPager); |
||
6368 | if( rc==SQLITE_OK ){ |
||
6369 | sqlite3PagerSetJournalMode(pPager, eNew); |
||
6370 | } |
||
6371 | }else if( eOld==PAGER_JOURNALMODE_MEMORY ){ |
||
6372 | /* Cannot transition directly from MEMORY to WAL. Use mode OFF |
||
6373 | ** as an intermediate */ |
||
6374 | sqlite3PagerSetJournalMode(pPager, PAGER_JOURNALMODE_OFF); |
||
6375 | } |
||
6376 | |||
6377 | /* Open a transaction on the database file. Regardless of the journal |
||
6378 | ** mode, this transaction always uses a rollback journal. |
||
6379 | */ |
||
6380 | Debug.Assert( sqlite3BtreeIsInTrans(pBt)==0 ); |
||
6381 | if( rc==SQLITE_OK ){ |
||
6382 | rc = sqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); |
||
6383 | } |
||
6384 | } |
||
6385 | } |
||
6386 | #endif //* ifndef SQLITE_OMIT_WAL */ |
||
6387 | |||
6388 | if ( rc != 0 ) |
||
6389 | { |
||
6390 | eNew = eOld; |
||
6391 | } |
||
6392 | eNew = sqlite3PagerSetJournalMode( pPager, eNew ); |
||
6393 | |||
6394 | pOut = aMem[pOp.p2]; |
||
6395 | pOut.flags = MEM_Str | MEM_Static | MEM_Term; |
||
6396 | pOut.z = sqlite3JournalModename( eNew ); |
||
6397 | pOut.n = sqlite3Strlen30( pOut.z ); |
||
6398 | pOut.enc = SQLITE_UTF8; |
||
6399 | sqlite3VdbeChangeEncoding( pOut, encoding ); |
||
6400 | break; |
||
6401 | }; |
||
6402 | #endif //* SQLITE_OMIT_PRAGMA */ |
||
6403 | |||
6404 | #if !SQLITE_OMIT_VACUUM && !SQLITE_OMIT_ATTACH |
||
6405 | /* Opcode: Vacuum * * * * * |
||
6406 | ** |
||
6407 | ** Vacuum the entire database. This opcode will cause other virtual |
||
6408 | ** machines to be created and run. It may not be called from within |
||
6409 | ** a transaction. |
||
6410 | */ |
||
6411 | case OP_Vacuum: |
||
6412 | { |
||
6413 | rc = sqlite3RunVacuum( ref p.zErrMsg, db ); |
||
6414 | break; |
||
6415 | } |
||
6416 | #endif |
||
6417 | |||
6418 | #if !SQLITE_OMIT_AUTOVACUUM |
||
6419 | /* Opcode: IncrVacuum P1 P2 * * * |
||
6420 | ** |
||
6421 | ** Perform a single step of the incremental vacuum procedure on |
||
6422 | ** the P1 database. If the vacuum has finished, jump to instruction |
||
6423 | ** P2. Otherwise, fall through to the next instruction. |
||
6424 | */ |
||
6425 | case OP_IncrVacuum: |
||
6426 | { /* jump */ |
||
6427 | Btree pBt; |
||
6428 | |||
6429 | Debug.Assert( pOp.p1 >= 0 && pOp.p1 < db.nDb ); |
||
6430 | Debug.Assert( ( p.btreeMask & ( ( (yDbMask)1 ) << pOp.p1 ) ) != 0 ); |
||
6431 | pBt = db.aDb[pOp.p1].pBt; |
||
6432 | rc = sqlite3BtreeIncrVacuum( pBt ); |
||
6433 | if ( rc == SQLITE_DONE ) |
||
6434 | { |
||
6435 | pc = pOp.p2 - 1; |
||
6436 | rc = SQLITE_OK; |
||
6437 | } |
||
6438 | break; |
||
6439 | } |
||
6440 | #endif |
||
6441 | |||
6442 | /* Opcode: Expire P1 * * * * |
||
6443 | ** |
||
6444 | ** Cause precompiled statements to become expired. An expired statement |
||
6445 | ** fails with an error code of SQLITE_SCHEMA if it is ever executed |
||
6446 | ** (via sqlite3_step()). |
||
6447 | ** |
||
6448 | ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, |
||
6449 | ** then only the currently executing statement is affected. |
||
6450 | */ |
||
6451 | case OP_Expire: |
||
6452 | { |
||
6453 | if ( pOp.p1 == 0 ) |
||
6454 | { |
||
6455 | sqlite3ExpirePreparedStatements( db ); |
||
6456 | } |
||
6457 | else |
||
6458 | { |
||
6459 | p.expired = true; |
||
6460 | } |
||
6461 | break; |
||
6462 | } |
||
6463 | |||
6464 | #if !SQLITE_OMIT_SHARED_CACHE |
||
6465 | /* Opcode: TableLock P1 P2 P3 P4 * |
||
6466 | ** |
||
6467 | ** Obtain a lock on a particular table. This instruction is only used when |
||
6468 | ** the shared-cache feature is enabled. |
||
6469 | ** |
||
6470 | ** P1 is the index of the database in sqlite3.aDb[] of the database |
||
6471 | ** on which the lock is acquired. A readlock is obtained if P3==0 or |
||
6472 | ** a write lock if P3==1. |
||
6473 | ** |
||
6474 | ** P2 contains the root-page of the table to lock. |
||
6475 | ** |
||
6476 | ** P4 contains a pointer to the name of the table being locked. This is only |
||
6477 | ** used to generate an error message if the lock cannot be obtained. |
||
6478 | */ |
||
6479 | case OP_TableLock: |
||
6480 | { |
||
6481 | u8 isWriteLock = (u8)pOp.p3; |
||
6482 | if( isWriteLock || 0==(db.flags&SQLITE_ReadUncommitted) ){ |
||
6483 | int p1 = pOp.p1; |
||
6484 | Debug.Assert( p1 >= 0 && p1 < db.nDb ); |
||
6485 | Debug.Assert( ( p.btreeMask & ( ((yDbMask)1) << p1 ) ) != 0 ); |
||
6486 | Debug.Assert( isWriteLock == 0 || isWriteLock == 1 ); |
||
6487 | rc = sqlite3BtreeLockTable( db.aDb[p1].pBt, pOp.p2, isWriteLock ); |
||
6488 | if ( ( rc & 0xFF ) == SQLITE_LOCKED ) |
||
6489 | { |
||
6490 | string z = pOp.p4.z; |
||
6491 | sqlite3SetString( ref p.zErrMsg, db, "database table is locked: ", z ); |
||
6492 | } |
||
6493 | } |
||
6494 | break; |
||
6495 | } |
||
6496 | #endif // * SQLITE_OMIT_SHARED_CACHE */ |
||
6497 | |||
6498 | #if !SQLITE_OMIT_VIRTUALTABLE |
||
6499 | /* Opcode: VBegin * * * P4 * |
||
6500 | ** |
||
6501 | ** P4 may be a pointer to an sqlite3_vtab structure. If so, call the |
||
6502 | ** xBegin method for that table. |
||
6503 | ** |
||
6504 | ** Also, whether or not P4 is set, check that this is not being called from |
||
6505 | ** within a callback to a virtual table xSync() method. If it is, the error |
||
6506 | ** code will be set to SQLITE_LOCKED. |
||
6507 | */ |
||
6508 | case OP_VBegin: |
||
6509 | { |
||
6510 | VTable pVTab; |
||
6511 | pVTab = pOp.p4.pVtab; |
||
6512 | rc = sqlite3VtabBegin( db, pVTab ); |
||
6513 | if ( pVTab != null ) |
||
6514 | importVtabErrMsg( p, pVTab.pVtab ); |
||
6515 | break; |
||
6516 | } |
||
6517 | #endif //* SQLITE_OMIT_VIRTUALTABLE */ |
||
6518 | |||
6519 | #if !SQLITE_OMIT_VIRTUALTABLE |
||
6520 | /* Opcode: VCreate P1 * * P4 * |
||
6521 | ** |
||
6522 | ** P4 is the name of a virtual table in database P1. Call the xCreate method |
||
6523 | ** for that table. |
||
6524 | */ |
||
6525 | case OP_VCreate: |
||
6526 | { |
||
6527 | rc = sqlite3VtabCallCreate( db, pOp.p1, pOp.p4.z, ref p.zErrMsg ); |
||
6528 | break; |
||
6529 | } |
||
6530 | #endif //* SQLITE_OMIT_VIRTUALTABLE */ |
||
6531 | |||
6532 | #if !SQLITE_OMIT_VIRTUALTABLE |
||
6533 | /* Opcode: VDestroy P1 * * P4 * |
||
6534 | ** |
||
6535 | ** P4 is the name of a virtual table in database P1. Call the xDestroy method |
||
6536 | ** of that table. |
||
6537 | */ |
||
6538 | case OP_VDestroy: |
||
6539 | { |
||
6540 | p.inVtabMethod = 2; |
||
6541 | rc = sqlite3VtabCallDestroy( db, pOp.p1, pOp.p4.z ); |
||
6542 | p.inVtabMethod = 0; |
||
6543 | break; |
||
6544 | } |
||
6545 | #endif //* SQLITE_OMIT_VIRTUALTABLE */ |
||
6546 | |||
6547 | #if !SQLITE_OMIT_VIRTUALTABLE |
||
6548 | /* Opcode: VOpen P1 * * P4 * |
||
6549 | ** |
||
6550 | ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. |
||
6551 | ** P1 is a cursor number. This opcode opens a cursor to the virtual |
||
6552 | ** table and stores that cursor in P1. |
||
6553 | */ |
||
6554 | case OP_VOpen: |
||
6555 | { |
||
6556 | VdbeCursor pCur; |
||
6557 | sqlite3_vtab_cursor pVtabCursor; |
||
6558 | sqlite3_vtab pVtab; |
||
6559 | sqlite3_module pModule; |
||
6560 | |||
6561 | pCur = null; |
||
6562 | pVtab = pOp.p4.pVtab.pVtab; |
||
6563 | pModule = (sqlite3_module)pVtab.pModule; |
||
6564 | Debug.Assert( pVtab != null && pModule != null ); |
||
6565 | rc = pModule.xOpen( pVtab, out pVtabCursor ); |
||
6566 | importVtabErrMsg( p, pVtab ); |
||
6567 | if ( SQLITE_OK == rc ) |
||
6568 | { |
||
6569 | /* Initialize sqlite3_vtab_cursor base class */ |
||
6570 | pVtabCursor.pVtab = pVtab; |
||
6571 | |||
6572 | /* Initialise vdbe cursor object */ |
||
6573 | pCur = allocateCursor( p, pOp.p1, 0, -1, 0 ); |
||
6574 | if ( pCur != null ) |
||
6575 | { |
||
6576 | pCur.pVtabCursor = pVtabCursor; |
||
6577 | pCur.pModule = pVtabCursor.pVtab.pModule; |
||
6578 | } |
||
6579 | else |
||
6580 | { |
||
6581 | //db.mallocFailed = 1; |
||
6582 | pModule.xClose( ref pVtabCursor ); |
||
6583 | } |
||
6584 | } |
||
6585 | break; |
||
6586 | } |
||
6587 | #endif //* SQLITE_OMIT_VIRTUALTABLE */ |
||
6588 | |||
6589 | #if !SQLITE_OMIT_VIRTUALTABLE |
||
6590 | /* Opcode: VFilter P1 P2 P3 P4 * |
||
6591 | ** |
||
6592 | ** P1 is a cursor opened using VOpen. P2 is an address to jump to if |
||
6593 | ** the filtered result set is empty. |
||
6594 | ** |
||
6595 | ** P4 is either NULL or a string that was generated by the xBestIndex |
||
6596 | ** method of the module. The interpretation of the P4 string is left |
||
6597 | ** to the module implementation. |
||
6598 | ** |
||
6599 | ** This opcode invokes the xFilter method on the virtual table specified |
||
6600 | ** by P1. The integer query plan parameter to xFilter is stored in register |
||
6601 | ** P3. Register P3+1 stores the argc parameter to be passed to the |
||
6602 | ** xFilter method. Registers P3+2..P3+1+argc are the argc |
||
6603 | ** additional parameters which are passed to |
||
6604 | ** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter. |
||
6605 | ** |
||
6606 | ** A jump is made to P2 if the result set after filtering would be empty. |
||
6607 | */ |
||
6608 | case OP_VFilter: |
||
6609 | { /* jump */ |
||
6610 | int nArg; |
||
6611 | int iQuery; |
||
6612 | sqlite3_module pModule; |
||
6613 | Mem pQuery; |
||
6614 | Mem pArgc = null; |
||
6615 | sqlite3_vtab_cursor pVtabCursor; |
||
6616 | sqlite3_vtab pVtab; |
||
6617 | VdbeCursor pCur; |
||
6618 | int res; |
||
6619 | int i; |
||
6620 | Mem[] apArg; |
||
6621 | |||
6622 | pQuery = aMem[pOp.p3]; |
||
6623 | pArgc = aMem[pOp.p3 + 1];// pQuery[1]; |
||
6624 | pCur = p.apCsr[pOp.p1]; |
||
6625 | Debug.Assert( memIsValid( pQuery ) ); |
||
6626 | REGISTER_TRACE( p, pOp.p3, pQuery ); |
||
6627 | Debug.Assert( pCur.pVtabCursor != null ); |
||
6628 | pVtabCursor = pCur.pVtabCursor; |
||
6629 | pVtab = pVtabCursor.pVtab; |
||
6630 | pModule = pVtab.pModule; |
||
6631 | |||
6632 | /* Grab the index number and argc parameters */ |
||
6633 | Debug.Assert( ( pQuery.flags & MEM_Int ) != 0 && pArgc.flags == MEM_Int ); |
||
6634 | nArg = (int)pArgc.u.i; |
||
6635 | iQuery = (int)pQuery.u.i; |
||
6636 | |||
6637 | /* Invoke the xFilter method */ |
||
6638 | { |
||
6639 | res = 0; |
||
6640 | apArg = p.apArg; |
||
6641 | for ( i = 0; i < nArg; i++ ) |
||
6642 | { |
||
6643 | apArg[i] = aMem[(pOp.p3 + 1) + i + 1];//apArg[i] = pArgc[i + 1]; |
||
6644 | sqlite3VdbeMemStoreType( apArg[i] ); |
||
6645 | } |
||
6646 | |||
6647 | p.inVtabMethod = 1; |
||
6648 | rc = pModule.xFilter( pVtabCursor, iQuery, pOp.p4.z, nArg, apArg ); |
||
6649 | p.inVtabMethod = 0; |
||
6650 | importVtabErrMsg( p, pVtab ); |
||
6651 | if ( rc == SQLITE_OK ) |
||
6652 | { |
||
6653 | res = pModule.xEof( pVtabCursor ); |
||
6654 | } |
||
6655 | |||
6656 | if ( res != 0 ) |
||
6657 | { |
||
6658 | pc = pOp.p2 - 1; |
||
6659 | } |
||
6660 | } |
||
6661 | pCur.nullRow = false; |
||
6662 | break; |
||
6663 | } |
||
6664 | #endif //* SQLITE_OMIT_VIRTUALTABLE */ |
||
6665 | |||
6666 | #if !SQLITE_OMIT_VIRTUALTABLE |
||
6667 | /* Opcode: VColumn P1 P2 P3 * * |
||
6668 | ** |
||
6669 | ** Store the value of the P2-th column of |
||
6670 | ** the row of the virtual-table that the |
||
6671 | ** P1 cursor is pointing to into register P3. |
||
6672 | */ |
||
6673 | case OP_VColumn: |
||
6674 | { |
||
6675 | sqlite3_vtab pVtab; |
||
6676 | sqlite3_module pModule; |
||
6677 | Mem pDest; |
||
6678 | sqlite3_context sContext; |
||
6679 | |||
6680 | VdbeCursor pCur = p.apCsr[pOp.p1]; |
||
6681 | Debug.Assert( pCur.pVtabCursor != null ); |
||
6682 | Debug.Assert( pOp.p3 > 0 && pOp.p3 <= p.nMem ); |
||
6683 | pDest = aMem[pOp.p3]; |
||
6684 | memAboutToChange( p, pDest ); |
||
6685 | if ( pCur.nullRow ) |
||
6686 | { |
||
6687 | sqlite3VdbeMemSetNull( pDest ); |
||
6688 | break; |
||
6689 | } |
||
6690 | pVtab = pCur.pVtabCursor.pVtab; |
||
6691 | pModule = pVtab.pModule; |
||
6692 | Debug.Assert( pModule.xColumn != null ); |
||
6693 | sContext = new sqlite3_context();//memset( &sContext, 0, sizeof( sContext ) ); |
||
6694 | |||
6695 | /* The output cell may already have a buffer allocated. Move |
||
6696 | ** the current contents to sContext.s so in case the user-function |
||
6697 | ** can use the already allocated buffer instead of allocating a |
||
6698 | ** new one. |
||
6699 | */ |
||
6700 | sqlite3VdbeMemMove( sContext.s, pDest ); |
||
6701 | MemSetTypeFlag( sContext.s, MEM_Null ); |
||
6702 | |||
6703 | rc = pModule.xColumn( pCur.pVtabCursor, sContext, pOp.p2 ); |
||
6704 | importVtabErrMsg( p, pVtab ); |
||
6705 | |||
6706 | if ( sContext.isError != 0 ) |
||
6707 | { |
||
6708 | rc = sContext.isError; |
||
6709 | } |
||
6710 | |||
6711 | /* Copy the result of the function to the P3 register. We |
||
6712 | ** do this regardless of whether or not an error occurred to ensure any |
||
6713 | ** dynamic allocation in sContext.s (a Mem struct) is released. |
||
6714 | */ |
||
6715 | sqlite3VdbeChangeEncoding( sContext.s, encoding ); |
||
6716 | sqlite3VdbeMemMove( pDest, sContext.s ); |
||
6717 | REGISTER_TRACE( p, pOp.p3, pDest ); |
||
6718 | UPDATE_MAX_BLOBSIZE( pDest ); |
||
6719 | if ( sqlite3VdbeMemTooBig( pDest ) ) |
||
6720 | { |
||
6721 | goto too_big; |
||
6722 | } |
||
6723 | break; |
||
6724 | } |
||
6725 | #endif //* SQLITE_OMIT_VIRTUALTABLE */ |
||
6726 | |||
6727 | #if !SQLITE_OMIT_VIRTUALTABLE |
||
6728 | /* Opcode: VNext P1 P2 * * * |
||
6729 | ** |
||
6730 | ** Advance virtual table P1 to the next row in its result set and |
||
6731 | ** jump to instruction P2. Or, if the virtual table has reached |
||
6732 | ** the end of its result set, then fall through to the next instruction. |
||
6733 | */ |
||
6734 | case OP_VNext: |
||
6735 | { /* jump */ |
||
6736 | sqlite3_vtab pVtab; |
||
6737 | sqlite3_module pModule; |
||
6738 | int res; |
||
6739 | VdbeCursor pCur; |
||
6740 | |||
6741 | res = 0; |
||
6742 | pCur = p.apCsr[pOp.p1]; |
||
6743 | Debug.Assert( pCur.pVtabCursor != null ); |
||
6744 | if ( pCur.nullRow ) |
||
6745 | { |
||
6746 | break; |
||
6747 | } |
||
6748 | pVtab = pCur.pVtabCursor.pVtab; |
||
6749 | pModule = pVtab.pModule; |
||
6750 | Debug.Assert( pModule.xNext != null ); |
||
6751 | |||
6752 | /* Invoke the xNext() method of the module. There is no way for the |
||
6753 | ** underlying implementation to return an error if one occurs during |
||
6754 | ** xNext(). Instead, if an error occurs, true is returned (indicating that |
||
6755 | ** data is available) and the error code returned when xColumn or |
||
6756 | ** some other method is next invoked on the save virtual table cursor. |
||
6757 | */ |
||
6758 | p.inVtabMethod = 1; |
||
6759 | rc = pModule.xNext( pCur.pVtabCursor ); |
||
6760 | p.inVtabMethod = 0; |
||
6761 | importVtabErrMsg( p, pVtab ); |
||
6762 | if ( rc == SQLITE_OK ) |
||
6763 | { |
||
6764 | res = pModule.xEof( pCur.pVtabCursor ); |
||
6765 | } |
||
6766 | |||
6767 | if ( 0 == res ) |
||
6768 | { |
||
6769 | /* If there is data, jump to P2 */ |
||
6770 | pc = pOp.p2 - 1; |
||
6771 | } |
||
6772 | break; |
||
6773 | } |
||
6774 | #endif //* SQLITE_OMIT_VIRTUALTABLE */ |
||
6775 | |||
6776 | #if !SQLITE_OMIT_VIRTUALTABLE |
||
6777 | /* Opcode: VRename P1 * * P4 * |
||
6778 | ** |
||
6779 | ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. |
||
6780 | ** This opcode invokes the corresponding xRename method. The value |
||
6781 | ** in register P1 is passed as the zName argument to the xRename method. |
||
6782 | */ |
||
6783 | case OP_VRename: |
||
6784 | { |
||
6785 | sqlite3_vtab pVtab; |
||
6786 | Mem pName; |
||
6787 | |||
6788 | pVtab = pOp.p4.pVtab.pVtab; |
||
6789 | pName = aMem[pOp.p1]; |
||
6790 | Debug.Assert( pVtab.pModule.xRename != null ); |
||
6791 | Debug.Assert( memIsValid( pName ) ); |
||
6792 | REGISTER_TRACE( p, pOp.p1, pName ); |
||
6793 | Debug.Assert( ( pName.flags & MEM_Str ) != 0 ); |
||
6794 | rc = pVtab.pModule.xRename( pVtab, pName.z ); |
||
6795 | importVtabErrMsg( p, pVtab ); |
||
6796 | p.expired = false; |
||
6797 | break; |
||
6798 | } |
||
6799 | #endif |
||
6800 | |||
6801 | #if !SQLITE_OMIT_VIRTUALTABLE |
||
6802 | /* Opcode: VUpdate P1 P2 P3 P4 * |
||
6803 | ** |
||
6804 | ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. |
||
6805 | ** This opcode invokes the corresponding xUpdate method. P2 values |
||
6806 | ** are contiguous memory cells starting at P3 to pass to the xUpdate |
||
6807 | ** invocation. The value in register (P3+P2-1) corresponds to the |
||
6808 | ** p2th element of the argv array passed to xUpdate. |
||
6809 | ** |
||
6810 | ** The xUpdate method will do a DELETE or an INSERT or both. |
||
6811 | ** The argv[0] element (which corresponds to memory cell P3) |
||
6812 | ** is the rowid of a row to delete. If argv[0] is NULL then no |
||
6813 | ** deletion occurs. The argv[1] element is the rowid of the new |
||
6814 | ** row. This can be NULL to have the virtual table select the new |
||
6815 | ** rowid for itself. The subsequent elements in the array are |
||
6816 | ** the values of columns in the new row. |
||
6817 | ** |
||
6818 | ** If P2==1 then no insert is performed. argv[0] is the rowid of |
||
6819 | ** a row to delete. |
||
6820 | ** |
||
6821 | ** P1 is a boolean flag. If it is set to true and the xUpdate call |
||
6822 | ** is successful, then the value returned by sqlite3_last_insert_rowid() |
||
6823 | ** is set to the value of the rowid for the row just inserted. |
||
6824 | */ |
||
6825 | case OP_VUpdate: |
||
6826 | { |
||
6827 | sqlite3_vtab pVtab; |
||
6828 | sqlite3_module pModule; |
||
6829 | int nArg; |
||
6830 | int i; |
||
6831 | sqlite_int64 rowid = 0; |
||
6832 | Mem[] apArg; |
||
6833 | Mem pX; |
||
6834 | |||
6835 | Debug.Assert( pOp.p2 == 1 || pOp.p5 == OE_Fail || pOp.p5 == OE_Rollback |
||
6836 | || pOp.p5 == OE_Abort || pOp.p5 == OE_Ignore || pOp.p5 == OE_Replace |
||
6837 | ); |
||
6838 | pVtab = pOp.p4.pVtab.pVtab; |
||
6839 | pModule = (sqlite3_module)pVtab.pModule; |
||
6840 | nArg = pOp.p2; |
||
6841 | Debug.Assert( pOp.p4type == P4_VTAB ); |
||
6842 | if ( ALWAYS( pModule.xUpdate ) ) |
||
6843 | { |
||
6844 | u8 vtabOnConflict = db.vtabOnConflict; |
||
6845 | apArg = p.apArg; |
||
6846 | //pX = aMem[pOp.p3]; |
||
6847 | for ( i = 0; i < nArg; i++ ) |
||
6848 | { |
||
6849 | pX = aMem[pOp.p3 + i]; |
||
6850 | Debug.Assert( memIsValid( pX ) ); |
||
6851 | memAboutToChange( p, pX ); |
||
6852 | sqlite3VdbeMemStoreType( pX ); |
||
6853 | apArg[i] = pX; |
||
6854 | //pX++; |
||
6855 | } |
||
6856 | db.vtabOnConflict = pOp.p5; |
||
6857 | rc = pModule.xUpdate( pVtab, nArg, apArg, out rowid ); |
||
6858 | db.vtabOnConflict = vtabOnConflict; |
||
6859 | importVtabErrMsg( p, pVtab ); |
||
6860 | if ( rc == SQLITE_OK && pOp.p1 != 0 ) |
||
6861 | { |
||
6862 | Debug.Assert( nArg > 1 && apArg[0] != null && ( apArg[0].flags & MEM_Null ) != 0 ); |
||
6863 | db.lastRowid = lastRowid = rowid; |
||
6864 | } |
||
6865 | if ( rc == SQLITE_CONSTRAINT && pOp.p4.pVtab.bConstraint != 0 ) |
||
6866 | { |
||
6867 | if ( pOp.p5 == OE_Ignore ) |
||
6868 | { |
||
6869 | rc = SQLITE_OK; |
||
6870 | } |
||
6871 | else |
||
6872 | { |
||
6873 | p.errorAction = (byte)( ( pOp.p5 == OE_Replace ) ? (byte)OE_Abort : pOp.p5 ); |
||
6874 | } |
||
6875 | } |
||
6876 | else |
||
6877 | { |
||
6878 | p.nChange++; |
||
6879 | } |
||
6880 | } |
||
6881 | break; |
||
6882 | } |
||
6883 | #endif //* SQLITE_OMIT_VIRTUALTABLE */ |
||
6884 | |||
6885 | #if !SQLITE_OMIT_PAGER_PRAGMAS |
||
6886 | /* Opcode: Pagecount P1 P2 * * * |
||
6887 | ** |
||
6888 | ** Write the current number of pages in database P1 to memory cell P2. |
||
6889 | */ |
||
6890 | case OP_Pagecount: |
||
6891 | { /* out2-prerelease */ |
||
6892 | pOut.u.i = sqlite3BtreeLastPage( db.aDb[pOp.p1].pBt ); |
||
6893 | break; |
||
6894 | } |
||
6895 | #endif |
||
6896 | |||
6897 | |||
6898 | #if !SQLITE_OMIT_PAGER_PRAGMAS |
||
6899 | /* Opcode: MaxPgcnt P1 P2 P3 * * |
||
6900 | ** |
||
6901 | ** Try to set the maximum page count for database P1 to the value in P3. |
||
6902 | ** Do not let the maximum page count fall below the current page count and |
||
6903 | ** do not change the maximum page count value if P3==0. |
||
6904 | ** |
||
6905 | ** Store the maximum page count after the change in register P2. |
||
6906 | */ |
||
6907 | case OP_MaxPgcnt: |
||
6908 | { /* out2-prerelease */ |
||
6909 | i64 newMax; |
||
6910 | Btree pBt; |
||
6911 | |||
6912 | pBt = db.aDb[pOp.p1].pBt; |
||
6913 | newMax = 0; |
||
6914 | if ( pOp.p3 != 0 ) |
||
6915 | { |
||
6916 | newMax = sqlite3BtreeLastPage( pBt ); |
||
6917 | if ( newMax < pOp.p3 ) |
||
6918 | newMax = pOp.p3; |
||
6919 | } |
||
6920 | pOut.u.i = (i64)sqlite3BtreeMaxPageCount( pBt, (int)newMax ); |
||
6921 | break; |
||
6922 | } |
||
6923 | #endif |
||
6924 | |||
6925 | #if !SQLITE_OMIT_TRACE |
||
6926 | /* Opcode: Trace * * * P4 * |
||
6927 | ** |
||
6928 | ** If tracing is enabled (by the sqlite3_trace()) interface, then |
||
6929 | ** the UTF-8 string contained in P4 is emitted on the trace callback. |
||
6930 | */ |
||
6931 | case OP_Trace: |
||
6932 | { |
||
6933 | string zTrace; |
||
6934 | string z; |
||
6935 | |||
6936 | if ( db.xTrace != null && !string.IsNullOrEmpty( zTrace = ( pOp.p4.z ?? p.zSql ) ) ) |
||
6937 | { |
||
6938 | z = sqlite3VdbeExpandSql( p, zTrace ); |
||
6939 | db.xTrace( db.pTraceArg, z ); |
||
6940 | //sqlite3DbFree( db, ref z ); |
||
6941 | } |
||
6942 | #if SQLITE_DEBUG |
||
6943 | if ( ( db.flags & SQLITE_SqlTrace ) != 0 |
||
6944 | && ( zTrace = ( pOp.p4.z ?? p.zSql ) ) != string.Empty ) |
||
6945 | { |
||
6946 | sqlite3DebugPrintf( "SQL-trace: %s\n", zTrace ); |
||
6947 | } |
||
6948 | #endif // * SQLITE_DEBUG */ |
||
6949 | break; |
||
6950 | } |
||
6951 | #endif |
||
6952 | |||
6953 | |||
6954 | /* Opcode: Noop * * * * * |
||
6955 | ** |
||
6956 | ** Do nothing. This instruction is often useful as a jump |
||
6957 | ** destination. |
||
6958 | */ |
||
6959 | /* |
||
6960 | ** The magic Explain opcode are only inserted when explain==2 (which |
||
6961 | ** is to say when the EXPLAIN QUERY PLAN syntax is used.) |
||
6962 | ** This opcode records information from the optimizer. It is the |
||
6963 | ** the same as a no-op. This opcodesnever appears in a real VM program. |
||
6964 | */ |
||
6965 | default: |
||
6966 | { /* This is really OP_Noop and OP_Explain */ |
||
6967 | Debug.Assert( pOp.opcode == OP_Noop || pOp.opcode == OP_Explain ); |
||
6968 | break; |
||
6969 | } |
||
6970 | |||
6971 | /***************************************************************************** |
||
6972 | ** The cases of the switch statement above this line should all be indented |
||
6973 | ** by 6 spaces. But the left-most 6 spaces have been removed to improve the |
||
6974 | ** readability. From this point on down, the normal indentation rules are |
||
6975 | ** restored. |
||
6976 | *****************************************************************************/ |
||
6977 | } |
||
6978 | |||
6979 | #if VDBE_PROFILE |
||
6980 | { |
||
6981 | u64 elapsed = sqlite3Hwtime() - start; |
||
6982 | pOp.cycles += elapsed; |
||
6983 | pOp.cnt++; |
||
6984 | #if FALSE |
||
6985 | fprintf(stdout, "%10llu ", elapsed); |
||
6986 | sqlite3VdbePrintOp(stdout, origPc, aOp[origPc]); |
||
6987 | #endif |
||
6988 | } |
||
6989 | #endif |
||
6990 | |||
6991 | /* The following code adds nothing to the actual functionality |
||
6992 | ** of the program. It is only here for testing and debugging. |
||
6993 | ** On the other hand, it does burn CPU cycles every time through |
||
6994 | ** the evaluator loop. So we can leave it out when NDEBUG is defined. |
||
6995 | */ |
||
6996 | #if !NDEBUG |
||
6997 | Debug.Assert( pc >= -1 && pc < p.nOp ); |
||
6998 | |||
6999 | #if SQLITE_DEBUG |
||
7000 | if ( p.trace != null ) |
||
7001 | { |
||
7002 | if ( rc != 0 ) |
||
7003 | fprintf( p.trace, "rc=%d\n", rc ); |
||
7004 | if ( ( pOp.opflags & ( OPFLG_OUT2_PRERELEASE | OPFLG_OUT2 ) ) != 0 ) |
||
7005 | { |
||
7006 | registerTrace( p.trace, pOp.p2, aMem[pOp.p2] ); |
||
7007 | } |
||
7008 | if ( ( pOp.opflags & OPFLG_OUT3 ) != 0 ) |
||
7009 | { |
||
7010 | registerTrace( p.trace, pOp.p3, aMem[pOp.p3] ); |
||
7011 | } |
||
7012 | } |
||
7013 | #endif // * SQLITE_DEBUG */ |
||
7014 | #endif // * NDEBUG */ |
||
7015 | |||
7016 | } /* The end of the for(;;) loop the loops through opcodes */ |
||
7017 | |||
7018 | /* If we reach this point, it means that execution is finished with |
||
7019 | ** an error of some kind. |
||
7020 | */ |
||
7021 | vdbe_error_halt: |
||
7022 | Debug.Assert( rc != 0 ); |
||
7023 | p.rc = rc; |
||
7024 | testcase( sqlite3GlobalConfig.xLog != null ); |
||
7025 | sqlite3_log( rc, "statement aborts at %d: [%s] %s", |
||
7026 | pc, p.zSql, p.zErrMsg ); |
||
7027 | sqlite3VdbeHalt( p ); |
||
7028 | //if ( rc == SQLITE_IOERR_NOMEM ) db.mallocFailed = 1; |
||
7029 | rc = SQLITE_ERROR; |
||
7030 | if ( resetSchemaOnFault > 0 ) |
||
7031 | { |
||
7032 | sqlite3ResetInternalSchema( db, resetSchemaOnFault - 1 ); |
||
7033 | } |
||
7034 | /* This is the only way out of this procedure. We have to |
||
7035 | ** release the mutexes on btrees that were acquired at the |
||
7036 | ** top. */ |
||
7037 | vdbe_return: |
||
7038 | db.lastRowid = lastRowid; |
||
7039 | sqlite3VdbeLeave( p ); |
||
7040 | return rc; |
||
7041 | |||
7042 | /* Jump to here if a string or blob larger than db.aLimit[SQLITE_LIMIT_LENGTH] |
||
7043 | ** is encountered. |
||
7044 | */ |
||
7045 | too_big: |
||
7046 | sqlite3SetString( ref p.zErrMsg, db, "string or blob too big" ); |
||
7047 | rc = SQLITE_TOOBIG; |
||
7048 | goto vdbe_error_halt; |
||
7049 | |||
7050 | /* Jump to here if a malloc() fails. |
||
7051 | */ |
||
7052 | no_mem: |
||
7053 | //db.mallocFailed = 1; |
||
7054 | sqlite3SetString( ref p.zErrMsg, db, "out of memory" ); |
||
7055 | rc = SQLITE_NOMEM; |
||
7056 | goto vdbe_error_halt; |
||
7057 | |||
7058 | /* Jump to here for any other kind of fatal error. The "rc" variable |
||
7059 | ** should hold the error number. |
||
7060 | */ |
||
7061 | abort_due_to_error: |
||
7062 | //Debug.Assert( p.zErrMsg); /// Not needed in C# |
||
7063 | //if ( db.mallocFailed != 0 ) rc = SQLITE_NOMEM; |
||
7064 | if ( rc != SQLITE_IOERR_NOMEM ) |
||
7065 | { |
||
7066 | sqlite3SetString( ref p.zErrMsg, db, "%s", sqlite3ErrStr( rc ) ); |
||
7067 | } |
||
7068 | goto vdbe_error_halt; |
||
7069 | |||
7070 | /* Jump to here if the sqlite3_interrupt() API sets the interrupt |
||
7071 | ** flag. |
||
7072 | */ |
||
7073 | abort_due_to_interrupt: |
||
7074 | Debug.Assert( db.u1.isInterrupted ); |
||
7075 | rc = SQLITE_INTERRUPT; |
||
7076 | p.rc = rc; |
||
7077 | sqlite3SetString( ref p.zErrMsg, db, sqlite3ErrStr( rc ) ); |
||
7078 | goto vdbe_error_halt; |
||
7079 | } |
||
7080 | } |
||
7081 | } |