Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Update comments in vdbe.c. No changes to code. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
1122b410de68a3c79b4c719a3a4cc4dc |
User & Date: | drh 2014-02-07 02:29:45.685 |
Context
2014-02-07
| ||
03:28 | More comment updates. No changes to code. (check-in: be24fbc221 user: mistachkin tags: trunk) | |
02:29 | Update comments in vdbe.c. No changes to code. (check-in: 1122b410de user: drh tags: trunk) | |
2014-02-06
| ||
23:56 | Delete the OP_VerifySchema opcode. Enhance OP_Transaction to do the schema version checks that OP_VerifySchema used to do. (check-in: 2f3376ebf1 user: drh tags: trunk) | |
Changes
Changes to src/vdbe.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* | | < < < < < < < < < | < < < < < < < < < < < < < < < < | > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** The code in this file implements the function that runs the ** bytecode of a prepared statement. ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. */ #include "sqliteInt.h" #include "vdbeInt.h" /* ** Invoke this macro on memory cells just prior to changing the ** value of the cell. This macro verifies that shallow copies are ** not misused. A shallow copy of a string or blob just copies a ** pointer to the string or blob, not the content. If the original ** is changed while the copy is still in use, the string or blob might ** be changed out from under the copy. This macro verifies that nothing ** like that every happens. */ #ifdef SQLITE_DEBUG # define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M) #else # define memAboutToChange(P,M) #endif |
︙ | ︙ | |||
104 105 106 107 108 109 110 | if( (p->flags & (MEM_Str|MEM_Blob))!=0 && p->n>sqlite3_max_blobsize ){ sqlite3_max_blobsize = p->n; } } #endif /* | | | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | if( (p->flags & (MEM_Str|MEM_Blob))!=0 && p->n>sqlite3_max_blobsize ){ sqlite3_max_blobsize = p->n; } } #endif /* ** The next global variable is incremented each time the OP_Found opcode ** is executed. This is used to test whether or not the foreign key ** operation implemented using OP_FkIsZero is working. This variable ** has no function other than to help verify the correct operation of the ** library. */ #ifdef SQLITE_TEST int sqlite3_found_count = 0; |
︙ | ︙ | |||
148 149 150 151 152 153 154 | ** converts an MEM_Ephem string into an MEM_Dyn string. */ #define Deephemeralize(P) \ if( ((P)->flags&MEM_Ephem)!=0 \ && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;} /* Return true if the cursor was opened using the OP_OpenSorter opcode. */ | | | 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | ** converts an MEM_Ephem string into an MEM_Dyn string. */ #define Deephemeralize(P) \ if( ((P)->flags&MEM_Ephem)!=0 \ && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;} /* Return true if the cursor was opened using the OP_OpenSorter opcode. */ #define isSorter(x) ((x)->pSorter!=0) /* ** Argument pMem points at a register that will be passed to a ** user-defined function or returned to the user as the result of a query. ** This routine sets the pMem->type variable used by the sqlite3_value_*() ** routines. */ |
︙ | ︙ | |||
453 454 455 456 457 458 459 | /* ** hwtime.h contains inline assembler code for implementing ** high-performance timing routines. */ #include "hwtime.h" #endif | < < < < < < < < < < < < < < | 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | /* ** hwtime.h contains inline assembler code for implementing ** high-performance timing routines. */ #include "hwtime.h" #endif #ifndef NDEBUG /* ** This function is only called from within an assert() expression. It ** checks that the sqlite3.nTransaction variable is correctly set to ** the number of non-transaction savepoints currently in the ** linked list starting at sqlite3.pSavepoint. |
︙ | ︙ | |||
490 491 492 493 494 495 496 | assert( n==(db->nSavepoint + db->isTransactionSavepoint) ); return 1; } #endif /* | | < < < < < < < < < < < < < < | < < < < < < < < < < < < < | 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 | assert( n==(db->nSavepoint + db->isTransactionSavepoint) ); return 1; } #endif /* ** Execute as much of a VDBE program as we can. ** This is the core of sqlite3_step(). */ int sqlite3VdbeExec( Vdbe *p /* The VDBE */ ){ int pc=0; /* The program counter */ Op *aOp = p->aOp; /* Copy of p->aOp */ Op *pOp; /* Current operation */ |
︙ | ︙ | |||
562 563 564 565 566 567 568 | assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY ); assert( p->bIsReader || p->readOnly!=0 ); p->rc = SQLITE_OK; p->iCurrentTime = 0; assert( p->explain==0 ); p->pResultSet = 0; db->busyHandler.nBusy = 0; | | | 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 | assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY ); assert( p->bIsReader || p->readOnly!=0 ); p->rc = SQLITE_OK; p->iCurrentTime = 0; assert( p->explain==0 ); p->pResultSet = 0; db->busyHandler.nBusy = 0; if( db->u1.isInterrupted ) goto abort_due_to_interrupt; sqlite3VdbeIOTraceSql(p); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( db->xProgress ){ assert( 0 < db->nProgressOps ); nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP]; if( nProgressLimit==0 ){ nProgressLimit = db->nProgressOps; |
︙ | ︙ | |||
738 739 740 741 742 743 744 | ** ** This code uses unstructured "goto" statements and does not look clean. ** But that is not due to sloppy coding habits. The code is written this ** way for performance, to avoid having to run the interrupt and progress ** checks on every opcode. This helps sqlite3_step() to run about 1.5% ** faster according to "valgrind --tool=cachegrind" */ check_for_interrupt: | | | 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 | ** ** This code uses unstructured "goto" statements and does not look clean. ** But that is not due to sloppy coding habits. The code is written this ** way for performance, to avoid having to run the interrupt and progress ** checks on every opcode. This helps sqlite3_step() to run about 1.5% ** faster according to "valgrind --tool=cachegrind" */ check_for_interrupt: if( db->u1.isInterrupted ) goto abort_due_to_interrupt; #ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* Call the progress callback if it is configured and the required number ** of VDBE ops have been executed (either since this invocation of ** sqlite3VdbeExec() or since last time the progress callback was called). ** If the progress callback returns non-zero, exit the virtual machine with ** a return code SQLITE_ABORT. */ |
︙ | ︙ | |||
760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 | } #endif break; } /* Opcode: Gosub P1 P2 * * * ** ** Write the current address onto register P1 ** and then jump to address P2. */ case OP_Gosub: { /* jump */ assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); pIn1 = &aMem[pOp->p1]; assert( (pIn1->flags & MEM_Dyn)==0 ); memAboutToChange(p, pIn1); pIn1->flags = MEM_Int; pIn1->u.i = pc; REGISTER_TRACE(pOp->p1, pIn1); pc = pOp->p2 - 1; break; } /* Opcode: Return P1 * * * * ** ** Jump to the next instruction after the address in register P1. */ case OP_Return: { /* in1 */ pIn1 = &aMem[pOp->p1]; assert( pIn1->flags & MEM_Int ); pc = (int)pIn1->u.i; break; } /* Opcode: Yield P1 * * * * ** ** Swap the program counter with the value in register P1. */ case OP_Yield: { /* in1 */ int pcDest; pIn1 = &aMem[pOp->p1]; assert( (pIn1->flags & MEM_Dyn)==0 ); pIn1->flags = MEM_Int; pcDest = (int)pIn1->u.i; pIn1->u.i = pc; REGISTER_TRACE(pOp->p1, pIn1); pc = pcDest; break; } /* Opcode: HaltIfNull P1 P2 P3 P4 P5 | > > > | | 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 | } #endif break; } /* Opcode: Gosub P1 P2 * * * ** Synopsis: r[P1]=pc; pc=P2 ** ** Write the current address onto register P1 ** and then jump to address P2. */ case OP_Gosub: { /* jump */ assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); pIn1 = &aMem[pOp->p1]; assert( (pIn1->flags & MEM_Dyn)==0 ); memAboutToChange(p, pIn1); pIn1->flags = MEM_Int; pIn1->u.i = pc; REGISTER_TRACE(pOp->p1, pIn1); pc = pOp->p2 - 1; break; } /* Opcode: Return P1 * * * * ** Synopsis: pc=r[P1]+1 ** ** Jump to the next instruction after the address in register P1. */ case OP_Return: { /* in1 */ pIn1 = &aMem[pOp->p1]; assert( pIn1->flags & MEM_Int ); pc = (int)pIn1->u.i; break; } /* Opcode: Yield P1 * * * * ** Synopsis: swap(pc,r[P1]) ** ** Swap the program counter with the value in register P1. */ case OP_Yield: { /* in1 */ int pcDest; pIn1 = &aMem[pOp->p1]; assert( (pIn1->flags & MEM_Dyn)==0 ); pIn1->flags = MEM_Int; pcDest = (int)pIn1->u.i; pIn1->u.i = pc; REGISTER_TRACE(pOp->p1, pIn1); pc = pcDest; break; } /* Opcode: HaltIfNull P1 P2 P3 P4 P5 ** Synopsis: if r[P3]=null halt ** ** Check the value in register P3. If it is NULL then Halt using ** parameter P1, P2, and P4 as if this were a Halt instruction. If the ** value in register P3 is not NULL, then this routine is a no-op. ** The P5 parameter should be 1. */ case OP_HaltIfNull: { /* in3 */ |
︙ | ︙ | |||
952 953 954 955 956 957 958 | } #endif /* Opcode: String8 * P2 * P4 * ** Synopsis: r[P2]='P4' ** ** P4 points to a nul terminated UTF-8 string. This opcode is transformed | | > > | 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 | } #endif /* Opcode: String8 * P2 * P4 * ** Synopsis: r[P2]='P4' ** ** P4 points to a nul terminated UTF-8 string. This opcode is transformed ** into an OP_String before it is executed for the first time. During ** this transformation, the length of string P4 is computed and stored ** as the P1 parameter. */ case OP_String8: { /* same as TK_STRING, out2-prerelease */ assert( pOp->p4.z!=0 ); pOp->opcode = OP_String; pOp->p1 = sqlite3Strlen30(pOp->p4.z); #ifndef SQLITE_OMIT_UTF16 |
︙ | ︙ | |||
1046 1047 1048 1049 1050 1051 1052 | } /* Opcode: Variable P1 P2 * P4 * ** Synopsis: r[P2]=parameter(P1,P4) ** ** Transfer the values of bound parameter P1 into register P2 ** | | | 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 | } /* Opcode: Variable P1 P2 * P4 * ** Synopsis: r[P2]=parameter(P1,P4) ** ** Transfer the values of bound parameter P1 into register P2 ** ** If the parameter is named, then its name appears in P4. ** The P4 value is used by sqlite3_bind_parameter_name(). */ case OP_Variable: { /* out2-prerelease */ Mem *pVar; /* Value being transferred */ assert( pOp->p1>0 && pOp->p1<=p->nVar ); assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] ); |
︙ | ︙ | |||
1165 1166 1167 1168 1169 1170 1171 | /* Opcode: ResultRow P1 P2 * * * ** Synopsis: output=r[P1@P2] ** ** The registers P1 through P1+P2-1 contain a single row of ** results. This opcode causes the sqlite3_step() call to terminate ** with an SQLITE_ROW return code and it sets up the sqlite3_stmt | | | | 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 | /* Opcode: ResultRow P1 P2 * * * ** Synopsis: output=r[P1@P2] ** ** The registers P1 through P1+P2-1 contain a single row of ** results. This opcode causes the sqlite3_step() call to terminate ** with an SQLITE_ROW return code and it sets up the sqlite3_stmt ** structure to provide access to the r[P1]..r[P1+P2-1] values as ** the result row. */ case OP_ResultRow: { Mem *pMem; int i; assert( p->nResColumn==pOp->p2 ); assert( pOp->p1>0 ); assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 ); |
︙ | ︙ | |||
1694 1695 1696 1697 1698 1699 1700 | #endif #ifndef SQLITE_OMIT_CAST /* Opcode: ToText P1 * * * * ** ** Force the value in register P1 to be text. ** If the value is numeric, convert it to a string using the | | | 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 | #endif #ifndef SQLITE_OMIT_CAST /* Opcode: ToText P1 * * * * ** ** Force the value in register P1 to be text. ** If the value is numeric, convert it to a string using the ** equivalent of sprintf(). Blob values are unchanged and ** are afterwards simply interpreted as text. ** ** A NULL value is not changed by this routine. It remains NULL. */ case OP_ToText: { /* same as TK_TO_TEXT, in1 */ pIn1 = &aMem[pOp->p1]; memAboutToChange(p, pIn1); |
︙ | ︙ | |||
2149 2150 2151 2152 2153 2154 2155 | } break; } /* Opcode: Once P1 P2 * * * ** ** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise, | | > > | 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 | } break; } /* Opcode: Once P1 P2 * * * ** ** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise, ** set the flag and fall through to the next instruction. In other words, ** this opcode causes all following up codes up through P2 (but not including ** P2) to run just once and skipped on subsequent times through the loop. */ case OP_Once: { /* jump */ assert( pOp->p1<p->nOnceFlag ); if( p->aOnceFlag[pOp->p1] ){ pc = pOp->p2-1; }else{ p->aOnceFlag[pOp->p1] = 1; |
︙ | ︙ | |||
3342 3343 3344 3345 3346 3347 3348 | pCx->isTable = 1; } } pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); break; } | | | 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 | pCx->isTable = 1; } } pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); break; } /* Opcode: SorterOpen P1 P2 * P4 * ** ** This opcode works like OP_OpenEphemeral except that it opens ** a transient index that is specifically designed to sort large ** tables using an external merge-sort algorithm. */ case OP_SorterOpen: { VdbeCursor *pCx; |
︙ | ︙ | |||
4209 4210 4211 4212 4213 4214 4215 | ** of a real table, not a pseudo-table. */ /* Opcode: RowKey P1 P2 * * * ** Synopsis: r[P2]=key ** ** Write into register P2 the complete row key for cursor P1. ** There is no interpretation of the data. | | | 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 | ** of a real table, not a pseudo-table. */ /* Opcode: RowKey P1 P2 * * * ** Synopsis: r[P2]=key ** ** Write into register P2 the complete row key for cursor P1. ** There is no interpretation of the data. ** The key is copied onto the P2 register exactly as ** it is found in the database file. ** ** If the P1 cursor must be pointing to a valid row (not a NULL row) ** of a real table, not a pseudo-table. */ case OP_RowKey: case OP_RowData: { |
︙ | ︙ | |||
4435 4436 4437 4438 4439 4440 4441 | assert( pOp->p2>0 && pOp->p2<p->nOp ); if( res ){ pc = pOp->p2 - 1; } break; } | | | 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 | assert( pOp->p2>0 && pOp->p2<p->nOp ); if( res ){ pc = pOp->p2 - 1; } break; } /* Opcode: Next P1 P2 P3 P4 P5 ** ** Advance cursor P1 so that it points to the next key/data pair in its ** table or index. If there are no more key/value pairs then fall through ** to the following instruction. But if the cursor advance was successful, ** jump immediately to P2. ** ** The P1 cursor must be for a real table, not a pseudo-table. P1 must have |
︙ | ︙ | |||
4458 4459 4460 4461 4462 4463 4464 | ** sqlite3BtreeNext(). ** ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. ** ** See also: Prev, NextIfOpen */ | | | | | 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 | ** sqlite3BtreeNext(). ** ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. ** ** See also: Prev, NextIfOpen */ /* Opcode: NextIfOpen P1 P2 P3 P4 P5 ** ** This opcode works just like OP_Next except that if cursor P1 is not ** open it behaves a no-op. */ /* Opcode: Prev P1 P2 P3 P4 P5 ** ** Back up cursor P1 so that it points to the previous key/data pair in its ** table or index. If there is no previous key/value pairs then fall through ** to the following instruction. But if the cursor backup was successful, ** jump immediately to P2. ** ** The P1 cursor must be for a real table, not a pseudo-table. If P1 is ** not open then the behavior is undefined. ** ** The P3 value is a hint to the btree implementation. If P3==1, that ** means P1 is an SQL index and that this instruction could have been ** omitted if that index had been unique. P3 is usually 0. P3 is ** always either 0 or 1. ** ** P4 is always of type P4_ADVANCE. The function pointer points to ** sqlite3BtreePrevious(). ** ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. */ /* Opcode: PrevIfOpen P1 P2 P3 P4 P5 ** ** This opcode works just like OP_Prev except that if cursor P1 is not ** open it behaves a no-op. */ case OP_SorterNext: { /* jump */ VdbeCursor *pC; int res; |
︙ | ︙ | |||
4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 | ** ** Register P2 holds an SQL index key made using the ** MakeRecord instructions. This opcode writes that key ** into the index P1. Data for the entry is nil. ** ** P3 is a flag that provides a hint to the b-tree layer that this ** insert is likely to be an append. ** ** This instruction only works for indices. The equivalent instruction ** for tables is OP_Insert. */ case OP_SorterInsert: /* in2 */ case OP_IdxInsert: { /* in2 */ VdbeCursor *pC; | > > > > > > > > | 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 | ** ** Register P2 holds an SQL index key made using the ** MakeRecord instructions. This opcode writes that key ** into the index P1. Data for the entry is nil. ** ** P3 is a flag that provides a hint to the b-tree layer that this ** insert is likely to be an append. ** ** If P5 contains bet OPFLAG_NCHANGE, then the change counter is ** incremented by this instruction. If OPFLAG_NCHANGE is clear, then ** the change counter is unchanged. ** ** If P5 contains OPFLAG_USESEEKRESULT then the cursor must have just ** done a seek to the spot where the new entry is to be inserted. This ** flag avoids doing an extra seek. ** ** This instruction only works for indices. The equivalent instruction ** for tables is OP_Insert. */ case OP_SorterInsert: /* in2 */ case OP_IdxInsert: { /* in2 */ VdbeCursor *pC; |
︙ | ︙ | |||
5143 5144 5145 5146 5147 5148 5149 | } break; } #ifndef SQLITE_OMIT_TRIGGER | | > > | 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 | } break; } #ifndef SQLITE_OMIT_TRIGGER /* Opcode: Program P1 P2 P3 P4 P5 ** ** Execute the trigger program passed as P4 (type P4_SUBPROGRAM). ** ** P1 contains the address of the memory cell that contains the first memory ** cell in an array of values used as arguments to the sub-program. P2 ** contains the address to jump to if the sub-program throws an IGNORE ** exception using the RAISE() function. Register P3 contains the address ** of a memory cell in this (the parent) VM that is used to allocate the ** memory required by the sub-vdbe at runtime. ** ** P4 is a pointer to the VM containing the trigger program. ** ** If P5 is non-zero, then recursive program invocation is enabled. */ case OP_Program: { /* jump */ int nMem; /* Number of memory registers for sub-program */ int nByte; /* Bytes of runtime space required for sub-program */ Mem *pRt; /* Register to allocate runtime space */ Mem *pMem; /* Used to iterate through memory cells */ Mem *pEnd; /* Last memory cell in new array */ |
︙ | ︙ | |||
5542 5543 5544 5545 5546 5547 5548 | sqlite3VdbeMemSetInt64(pMem, (i64)aRes[i]); } break; }; #endif #ifndef SQLITE_OMIT_PRAGMA | | | 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 | sqlite3VdbeMemSetInt64(pMem, (i64)aRes[i]); } break; }; #endif #ifndef SQLITE_OMIT_PRAGMA /* Opcode: JournalMode P1 P2 P3 * * ** ** Change the journal mode of database P1 to P3. P3 must be one of the ** PAGER_JOURNALMODE_XXX values. If changing between the various rollback ** modes (delete, truncate, persist, off and memory), this is a simple ** operation. No IO is required. ** ** If changing into or out of WAL mode the procedure is more complicated. |
︙ | ︙ | |||
6028 6029 6030 6031 6032 6033 6034 | p->expired = 0; } break; } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE | | | 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 | p->expired = 0; } break; } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VUpdate P1 P2 P3 P4 P5 ** Synopsis: data=r[P3@P2] ** ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. ** This opcode invokes the corresponding xUpdate method. P2 values ** are contiguous memory cells starting at P3 to pass to the xUpdate ** invocation. The value in register (P3+P2-1) corresponds to the ** p2th element of the argv array passed to xUpdate. |
︙ | ︙ | |||
6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 | ** ** If P2==1 then no insert is performed. argv[0] is the rowid of ** a row to delete. ** ** P1 is a boolean flag. If it is set to true and the xUpdate call ** is successful, then the value returned by sqlite3_last_insert_rowid() ** is set to the value of the rowid for the row just inserted. */ case OP_VUpdate: { sqlite3_vtab *pVtab; sqlite3_module *pModule; int nArg; int i; sqlite_int64 rowid; | > > > | 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 | ** ** If P2==1 then no insert is performed. argv[0] is the rowid of ** a row to delete. ** ** P1 is a boolean flag. If it is set to true and the xUpdate call ** is successful, then the value returned by sqlite3_last_insert_rowid() ** is set to the value of the rowid for the row just inserted. ** ** P5 is the error actions (OE_Replace, OE_Fail, OE_Ignore, etc) to ** apply in the case of a constraint failure on an insert or update. */ case OP_VUpdate: { sqlite3_vtab *pVtab; sqlite3_module *pModule; int nArg; int i; sqlite_int64 rowid; |
︙ | ︙ |