Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Change 'stack' to the more descriptive 'no-push' in vdbe.c. (CVS 2429) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
7e54d3c7289c091d449844d21b923e55 |
User & Date: | danielk1977 2005-03-29 13:07:00.000 |
Context
2005-03-29
| ||
13:17 | Fix a C++-ism in the code. (CVS 2430) (check-in: 312587acf9 user: drh tags: trunk) | |
13:07 | Change 'stack' to the more descriptive 'no-push' in vdbe.c. (CVS 2429) (check-in: 7e54d3c728 user: danielk1977 tags: trunk) | |
08:26 | Reduce the space allocated for the runtime virtual machine stack. (CVS 2428) (check-in: 7d6818da33 user: danielk1977 tags: trunk) | |
Changes
Changes to mkopcodeh.awk.
︙ | ︙ | |||
40 41 42 43 44 45 46 | if($i=="same" && $(i+1)=="as"){ sym = $(i+2) sub(/,/,"",sym) op[name] = tk[sym] used[op[name]] = 1 sameas[op[name]] = sym } | | | | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | if($i=="same" && $(i+1)=="as"){ sym = $(i+2) sub(/,/,"",sym) op[name] = tk[sym] used[op[name]] = 1 sameas[op[name]] = sym } if($i=="no-push"){ nopush[name] = 1 } } } # Assign numbers to all opcodes and output the result. END { cnt = 0 |
︙ | ︙ | |||
81 82 83 84 85 86 87 | printf "#define %-25s %15d\n", sprintf( "OP_NotUsed_%-3d", i ), i } } # Generate the 10 16-bit bitmasks used by function opcodeUsesStack() # in vdbeaux.c. See comments in that function for details. # | | | | | | | | | | | | | | | < | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | printf "#define %-25s %15d\n", sprintf( "OP_NotUsed_%-3d", i ), i } } # Generate the 10 16-bit bitmasks used by function opcodeUsesStack() # in vdbeaux.c. See comments in that function for details. # nopush[0] = 0 # 0..15 nopush[1] = 0 # 16..31 nopush[2] = 0 # 32..47 nopush[3] = 0 # 48..63 nopush[4] = 0 # 64..79 nopush[5] = 0 # 80..95 nopush[6] = 0 # 96..111 nopush[7] = 0 # 112..127 nopush[8] = 0 # 128..143 nopush[9] = 0 # 144..159 for(name in op){ if( nopush[name] ){ n = op[name] j = n%16 i = ((n - j)/16) nopush[i] = nopush[i] + (2^j) } } printf "\n" for(i=0; i<10; i++){ printf "#define NOPUSH_MASK_%d %d\n", i, nopush[i] } } |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** 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. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** 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. ** ** $Id: vdbe.c,v 1.463 2005/03/29 13:07:00 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
534 535 536 537 538 539 540 | } nProgressOps++; } #endif #ifndef NDEBUG /* This is to check that the return value of static function | | | | | 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 | } nProgressOps++; } #endif #ifndef NDEBUG /* This is to check that the return value of static function ** opcodeNoPush() (see vdbeaux.c) returns values that match the ** implementation of the virtual machine in this file. If ** opcodeNoPush() returns non-zero, then the stack is guarenteed ** not to grow when the opcode is executed. If it returns zero, then ** the stack may grow by at most 1. ** ** The global wrapper function sqlite3VdbeOpcodeUsesStack() is not ** available if NDEBUG is defined at build time. */ pStackLimit = pTos; if( !sqlite3VdbeOpcodeNoPush(pOp->opcode) ){ pStackLimit++; } #endif switch( pOp->opcode ){ /***************************************************************************** |
︙ | ︙ | |||
570 571 572 573 574 575 576 | ** will be filled with #defines that give unique integer values to each ** opcode and the opcodes.c file is filled with an array of strings where ** each string is the symbolic name for the corresponding opcode. If the ** case statement is followed by a comment of the form "/# same as ... #/" ** that comment is used to determine the particular value of the opcode. ** ** If a comment on the same line as the "case OP_" construction contains | | | | 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 | ** will be filled with #defines that give unique integer values to each ** opcode and the opcodes.c file is filled with an array of strings where ** each string is the symbolic name for the corresponding opcode. If the ** case statement is followed by a comment of the form "/# same as ... #/" ** that comment is used to determine the particular value of the opcode. ** ** If a comment on the same line as the "case OP_" construction contains ** the word "no-push", then the opcode is guarenteed not to grow the ** vdbe stack when it is executed. See function opcode() in ** vdbeaux.c for details. ** ** Documentation about VDBE opcodes is generated by scanning this file ** for lines of that contain "Opcode:". That line and all subsequent ** comment lines are used in the generation of the opcode.html documentation ** file. ** |
︙ | ︙ | |||
593 594 595 596 597 598 599 | /* Opcode: Goto * P2 * ** ** An unconditional jump to address P2. ** The next instruction executed will be ** the one at index P2 from the beginning of ** the program. */ | | | | | 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 | /* Opcode: Goto * P2 * ** ** An unconditional jump to address P2. ** The next instruction executed will be ** the one at index P2 from the beginning of ** the program. */ case OP_Goto: { /* no-push */ CHECK_FOR_INTERRUPT; pc = pOp->p2 - 1; break; } /* Opcode: Gosub * P2 * ** ** Push the current address plus 1 onto the return address stack ** and then jump to address P2. ** ** The return address stack is of limited depth. If too many ** OP_Gosub operations occur without intervening OP_Returns, then ** the return address stack will fill up and processing will abort ** with a fatal error. */ case OP_Gosub: { /* no-push */ assert( p->returnDepth<sizeof(p->returnStack)/sizeof(p->returnStack[0]) ); p->returnStack[p->returnDepth++] = pc+1; pc = pOp->p2 - 1; break; } /* Opcode: Return * * * ** ** Jump immediately to the next instruction after the last unreturned ** OP_Gosub. If an OP_Return has occurred for all OP_Gosubs, then ** processing aborts with a fatal error. */ case OP_Return: { /* no-push */ assert( p->returnDepth>0 ); p->returnDepth--; pc = p->returnStack[p->returnDepth] - 1; break; } /* Opcode: Halt P1 P2 * |
︙ | ︙ | |||
646 647 648 649 650 651 652 | ** then back out all changes that have occurred during this execution of the ** VDBE, but do not rollback the transaction. ** ** There is an implied "Halt 0 0 0" instruction inserted at the very end of ** every program. So a jump past the last instruction of the program ** is the same as executing Halt. */ | | | 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 | ** then back out all changes that have occurred during this execution of the ** VDBE, but do not rollback the transaction. ** ** There is an implied "Halt 0 0 0" instruction inserted at the very end of ** every program. So a jump past the last instruction of the program ** is the same as executing Halt. */ case OP_Halt: { /* no-push */ p->pTos = pTos; p->rc = pOp->p1; p->pc = pc; p->errorAction = pOp->p2; if( pOp->p3 ){ sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0); } |
︙ | ︙ | |||
828 829 830 831 832 833 834 | break; } /* Opcode: Pop P1 * * ** ** P1 elements are popped off of the top of stack and discarded. */ | | | 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 | break; } /* Opcode: Pop P1 * * ** ** P1 elements are popped off of the top of stack and discarded. */ case OP_Pop: { /* no-push */ assert( pOp->p1>=0 ); popStack(&pTos, pOp->p1); assert( pTos>=&p->aStack[-1] ); break; } /* Opcode: Dup P1 P2 * |
︙ | ︙ | |||
871 872 873 874 875 876 877 | ** the stack and pushed back on top of the stack. The ** top of the stack is element 0, so "Pull 0 0 0" is ** a no-op. "Pull 1 0 0" swaps the top two elements of ** the stack. ** ** See also the Dup instruction. */ | | | 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 | ** the stack and pushed back on top of the stack. The ** top of the stack is element 0, so "Pull 0 0 0" is ** a no-op. "Pull 1 0 0" swaps the top two elements of ** the stack. ** ** See also the Dup instruction. */ case OP_Pull: { /* no-push */ Mem *pFrom = &pTos[-pOp->p1]; int i; Mem ts; ts = *pFrom; Deephemeralize(pTos); for(i=0; i<pOp->p1; i++, pFrom++){ |
︙ | ︙ | |||
903 904 905 906 907 908 909 | /* Opcode: Push P1 * * ** ** Overwrite the value of the P1-th element down on the ** stack (P1==0 is the top of the stack) with the value ** of the top of the stack. Then pop the top of the stack. */ | | | | 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 | /* Opcode: Push P1 * * ** ** Overwrite the value of the P1-th element down on the ** stack (P1==0 is the top of the stack) with the value ** of the top of the stack. Then pop the top of the stack. */ case OP_Push: { /* no-push */ Mem *pTo = &pTos[-pOp->p1]; assert( pTo>=p->aStack ); sqlite3VdbeMemMove(pTo, pTos); pTos--; break; } /* Opcode: Callback P1 * * ** ** Pop P1 values off the stack and form them into an array. Then ** invoke the callback function using the newly formed array as the ** 3rd parameter. */ case OP_Callback: { /* no-push */ int i; assert( p->nResColumn==pOp->p1 ); for(i=0; i<pOp->p1; i++){ Mem *pVal = &pTos[0-i]; sqlite3VdbeMemNulTerminate(pVal); storeTypeInfo(pVal, db->enc); |
︙ | ︙ | |||
1054 1055 1056 1057 1058 1059 1060 | ** first (what was on top of the stack) from the second (the ** next on stack) ** and push the remainder after division onto the stack. If either element ** is a string then it is converted to a double using the atof() ** function before the division. Division by zero returns NULL. ** If either operand is NULL, the result is NULL. */ | | | | | | | 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 | ** first (what was on top of the stack) from the second (the ** next on stack) ** and push the remainder after division onto the stack. If either element ** is a string then it is converted to a double using the atof() ** function before the division. Division by zero returns NULL. ** If either operand is NULL, the result is NULL. */ case OP_Add: /* same as TK_PLUS, no-push */ case OP_Subtract: /* same as TK_MINUS, no-push */ case OP_Multiply: /* same as TK_STAR, no-push */ case OP_Divide: /* same as TK_SLASH, no-push */ case OP_Remainder: { /* same as TK_REM, no-push */ Mem *pNos = &pTos[-1]; assert( pNos>=p->aStack ); if( ((pTos->flags | pNos->flags) & MEM_Null)!=0 ){ Release(pTos); pTos--; Release(pTos); pTos->flags = MEM_Null; |
︙ | ︙ | |||
1138 1139 1140 1141 1142 1143 1144 | ** be returned. This is used by the built-in min(), max() and nullif() ** functions. ** ** The interface used by the implementation of the aforementioned functions ** to retrieve the collation sequence set by this opcode is not available ** publicly, only to user functions defined in func.c. */ | | | 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 | ** be returned. This is used by the built-in min(), max() and nullif() ** functions. ** ** The interface used by the implementation of the aforementioned functions ** to retrieve the collation sequence set by this opcode is not available ** publicly, only to user functions defined in func.c. */ case OP_CollSeq: { /* no-push */ assert( pOp->p3type==P3_COLLSEQ ); break; } /* Opcode: Function P1 P2 P3 ** ** Invoke a user function (P3 is a pointer to a Function structure that |
︙ | ︙ | |||
1256 1257 1258 1259 1260 1261 1262 | /* Opcode: ShiftRight * * * ** ** Pop the top two elements from the stack. Convert both elements ** to integers. Push back onto the stack the second element shifted ** right by N bits where N is the top element on the stack. ** If either operand is NULL, the result is NULL. */ | | | | | | 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 | /* Opcode: ShiftRight * * * ** ** Pop the top two elements from the stack. Convert both elements ** to integers. Push back onto the stack the second element shifted ** right by N bits where N is the top element on the stack. ** If either operand is NULL, the result is NULL. */ case OP_BitAnd: /* same as TK_BITAND, no-push */ case OP_BitOr: /* same as TK_BITOR, no-push */ case OP_ShiftLeft: /* same as TK_LSHIFT, no-push */ case OP_ShiftRight: { /* same as TK_RSHIFT, no-push */ Mem *pNos = &pTos[-1]; int a, b; assert( pNos>=p->aStack ); if( (pTos->flags | pNos->flags) & MEM_Null ){ popStack(&pTos, 2); pTos++; |
︙ | ︙ | |||
1294 1295 1296 1297 1298 1299 1300 | /* Opcode: AddImm P1 * * ** ** Add the value P1 to whatever is on top of the stack. The result ** is always an integer. ** ** To force the top of the stack to be an integer, just add 0. */ | | | | 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 | /* Opcode: AddImm P1 * * ** ** Add the value P1 to whatever is on top of the stack. The result ** is always an integer. ** ** To force the top of the stack to be an integer, just add 0. */ case OP_AddImm: { /* no-push */ assert( pTos>=p->aStack ); Integerify(pTos); pTos->i += pOp->p1; break; } /* Opcode: ForceInt P1 P2 * ** ** Convert the top of the stack into an integer. If the current top of ** the stack is not numeric (meaning that is is a NULL or a string that ** does not look like an integer or floating point number) then pop the ** stack and jump to P2. If the top of the stack is numeric then ** convert it into the least integer that is greater than or equal to its ** current value if P1==0, or to the least integer that is strictly ** greater than its current value if P1==1. */ case OP_ForceInt: { /* no-push */ int v; assert( pTos>=p->aStack ); applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc); if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){ Release(pTos); pTos--; pc = pOp->p2 - 1; |
︙ | ︙ | |||
1346 1347 1348 1349 1350 1351 1352 | ** with out data loss, then jump immediately to P2, or if P2==0 ** raise an SQLITE_MISMATCH exception. ** ** If the top of the stack is not an integer and P2 is not zero and ** P1 is 1, then the stack is popped. In all other cases, the depth ** of the stack is unchanged. */ | | | 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 | ** with out data loss, then jump immediately to P2, or if P2==0 ** raise an SQLITE_MISMATCH exception. ** ** If the top of the stack is not an integer and P2 is not zero and ** P1 is 1, then the stack is popped. In all other cases, the depth ** of the stack is unchanged. */ case OP_MustBeInt: { /* no-push */ assert( pTos>=p->aStack ); applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc); if( (pTos->flags & MEM_Int)==0 ){ if( pOp->p2==0 ){ rc = SQLITE_MISMATCH; goto abort_due_to_error; }else{ |
︙ | ︙ | |||
1421 1422 1423 1424 1425 1426 1427 | */ /* Opcode: Ge P1 P2 P3 ** ** This works just like the Eq opcode except that the jump is taken if ** the 2nd element down on the stack is greater than or equal to the ** top of the stack. See the Eq opcode for additional information. */ | | | | | | | | 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 | */ /* Opcode: Ge P1 P2 P3 ** ** This works just like the Eq opcode except that the jump is taken if ** the 2nd element down on the stack is greater than or equal to the ** top of the stack. See the Eq opcode for additional information. */ case OP_Eq: /* same as TK_EQ, no-push */ case OP_Ne: /* same as TK_NE, no-push */ case OP_Lt: /* same as TK_LT, no-push */ case OP_Le: /* same as TK_LE, no-push */ case OP_Gt: /* same as TK_GT, no-push */ case OP_Ge: { /* same as TK_GE, no-push */ Mem *pNos; int flags; int res; char affinity; pNos = &pTos[-1]; flags = pTos->flags|pNos->flags; |
︙ | ︙ | |||
1492 1493 1494 1495 1496 1497 1498 | */ /* Opcode: Or * * * ** ** Pop two values off the stack. Take the logical OR of the ** two values and push the resulting boolean value back onto the ** stack. */ | | | | 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 | */ /* Opcode: Or * * * ** ** Pop two values off the stack. Take the logical OR of the ** two values and push the resulting boolean value back onto the ** stack. */ case OP_And: /* same as TK_AND, no-push */ case OP_Or: { /* same as TK_OR, no-push */ Mem *pNos = &pTos[-1]; int v1, v2; /* 0==TRUE, 1==FALSE, 2==UNKNOWN or NULL */ assert( pNos>=p->aStack ); if( pTos->flags & MEM_Null ){ v1 = 2; }else{ |
︙ | ︙ | |||
1540 1541 1542 1543 1544 1545 1546 | */ /* Opcode: AbsValue * * * ** ** Treat the top of the stack as a numeric quantity. Replace it ** with its absolute value. If the top of the stack is NULL ** its value is unchanged. */ | | | 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 | */ /* Opcode: AbsValue * * * ** ** Treat the top of the stack as a numeric quantity. Replace it ** with its absolute value. If the top of the stack is NULL ** its value is unchanged. */ case OP_Negative: /* same as TK_UMINUS, no-push */ case OP_AbsValue: { assert( pTos>=p->aStack ); if( pTos->flags & MEM_Real ){ Release(pTos); if( pOp->opcode==OP_Negative || pTos->r<0.0 ){ pTos->r = -pTos->r; } |
︙ | ︙ | |||
1573 1574 1575 1576 1577 1578 1579 | /* Opcode: Not * * * ** ** Interpret the top of the stack as a boolean value. Replace it ** with its complement. If the top of the stack is NULL its value ** is unchanged. */ | | | | | 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 | /* Opcode: Not * * * ** ** Interpret the top of the stack as a boolean value. Replace it ** with its complement. If the top of the stack is NULL its value ** is unchanged. */ case OP_Not: { /* same as TK_NOT, no-push */ assert( pTos>=p->aStack ); if( pTos->flags & MEM_Null ) break; /* Do nothing to NULLs */ Integerify(pTos); assert( (pTos->flags & MEM_Dyn)==0 ); pTos->i = !pTos->i; pTos->flags = MEM_Int; break; } /* Opcode: BitNot * * * ** ** Interpret the top of the stack as an value. Replace it ** with its ones-complement. If the top of the stack is NULL its ** value is unchanged. */ case OP_BitNot: { /* same as TK_BITNOT, no-push */ assert( pTos>=p->aStack ); if( pTos->flags & MEM_Null ) break; /* Do nothing to NULLs */ Integerify(pTos); assert( (pTos->flags & MEM_Dyn)==0 ); pTos->i = ~pTos->i; pTos->flags = MEM_Int; break; } /* Opcode: Noop * * * ** ** Do nothing. This instruction is often useful as a jump ** destination. */ case OP_Noop: { /* no-push */ break; } /* Opcode: If P1 P2 * ** ** Pop a single boolean from the stack. If the boolean popped is ** true, then jump to p2. Otherwise continue to the next instruction. |
︙ | ︙ | |||
1628 1629 1630 1631 1632 1633 1634 | ** false, then jump to p2. Otherwise continue to the next instruction. ** An integer is false if zero and true otherwise. A string is ** false if it has zero length and true otherwise. ** ** If the value popped of the stack is NULL, then take the jump if P1 ** is true and fall through if P1 is false. */ | | | | | 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 | ** false, then jump to p2. Otherwise continue to the next instruction. ** An integer is false if zero and true otherwise. A string is ** false if it has zero length and true otherwise. ** ** If the value popped of the stack is NULL, then take the jump if P1 ** is true and fall through if P1 is false. */ case OP_If: /* no-push */ case OP_IfNot: { /* no-push */ int c; assert( pTos>=p->aStack ); if( pTos->flags & MEM_Null ){ c = pOp->p1; }else{ c = sqlite3VdbeIntValue(pTos); if( pOp->opcode==OP_IfNot ) c = !c; } Release(pTos); pTos--; if( c ) pc = pOp->p2-1; break; } /* Opcode: IsNull P1 P2 * ** ** If any of the top abs(P1) values on the stack are NULL, then jump ** to P2. Pop the stack P1 times if P1>0. If P1<0 leave the stack ** unchanged. */ case OP_IsNull: { /* same as TK_ISNULL, no-push */ int i, cnt; Mem *pTerm; cnt = pOp->p1; if( cnt<0 ) cnt = -cnt; pTerm = &pTos[1-cnt]; assert( pTerm>=p->aStack ); for(i=0; i<cnt; i++, pTerm++){ |
︙ | ︙ | |||
1673 1674 1675 1676 1677 1678 1679 | /* Opcode: NotNull P1 P2 * ** ** Jump to P2 if the top P1 values on the stack are all not NULL. Pop the ** stack if P1 times if P1 is greater than zero. If P1 is less than ** zero then leave the stack unchanged. */ | | | | 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 | /* Opcode: NotNull P1 P2 * ** ** Jump to P2 if the top P1 values on the stack are all not NULL. Pop the ** stack if P1 times if P1 is greater than zero. If P1 is less than ** zero then leave the stack unchanged. */ case OP_NotNull: { /* same as TK_NOTNULL, no-push */ int i, cnt; cnt = pOp->p1; if( cnt<0 ) cnt = -cnt; assert( &pTos[1-cnt] >= p->aStack ); for(i=0; i<cnt && (pTos[1+i-cnt].flags & MEM_Null)==0; i++){} if( i>=cnt ) pc = pOp->p2-1; if( pOp->p1>0 ) popStack(&pTos, cnt); break; } /* Opcode: SetNumColumns P1 P2 * ** ** Before the OP_Column opcode can be executed on a cursor, this ** opcode must be called to set the number of fields in the table. ** ** This opcode sets the number of columns for cursor P1 to P2. ** ** If OP_KeyAsData is to be applied to cursor P1, it must be executed ** before this op-code. */ case OP_SetNumColumns: { /* no-push */ Cursor *pC; assert( (pOp->p1)<p->nCursor ); assert( p->apCsr[pOp->p1]!=0 ); pC = p->apCsr[pOp->p1]; pC->nField = pOp->p2; if( (!pC->keyAsData && pC->zeroData) || (pC->keyAsData && pC->intKey) ){ rc = SQLITE_CORRUPT; |
︙ | ︙ | |||
2152 2153 2154 2155 2156 2157 2158 | ** entire transaction. The statement transaction will automatically ** commit when the VDBE halts. ** ** The statement is begun on the database file with index P1. The main ** database file has an index of 0 and the file used for temporary tables ** has an index of 1. */ | | | | 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 | ** entire transaction. The statement transaction will automatically ** commit when the VDBE halts. ** ** The statement is begun on the database file with index P1. The main ** database file has an index of 0 and the file used for temporary tables ** has an index of 1. */ case OP_Statement: { /* no-push */ int i = pOp->p1; Btree *pBt; if( i>=0 && i<db->nDb && (pBt = db->aDb[i].pBt) && !(db->autoCommit) ){ assert( sqlite3BtreeIsInTrans(pBt) ); if( !sqlite3BtreeIsInStmt(pBt) ){ rc = sqlite3BtreeBeginStmt(pBt); } } break; } /* Opcode: AutoCommit P1 P2 * ** ** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll ** back any currently active btree transactions. If there are any active ** VMs (apart from this one), then the COMMIT or ROLLBACK statement fails. ** ** This instruction causes the VM to halt. */ case OP_AutoCommit: { /* no-push */ u8 i = pOp->p1; u8 rollback = pOp->p2; assert( i==1 || i==0 ); assert( i==1 || rollback==0 ); assert( db->activeVdbeCnt>0 ); /* At least this one VM is active */ |
︙ | ︙ | |||
2233 2234 2235 2236 2237 2238 2239 | ** underway. Starting a write transaction also creates a rollback journal. A ** write transaction must be started before any changes can be made to the ** database. If P2 is 2 or greater then an EXCLUSIVE lock is also obtained ** on the file. ** ** If P2 is zero, then a read-lock is obtained on the database file. */ | | | 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 | ** underway. Starting a write transaction also creates a rollback journal. A ** write transaction must be started before any changes can be made to the ** database. If P2 is 2 or greater then an EXCLUSIVE lock is also obtained ** on the file. ** ** If P2 is zero, then a read-lock is obtained on the database file. */ case OP_Transaction: { /* no-push */ int i = pOp->p1; Btree *pBt; assert( i>=0 && i<db->nDb ); pBt = db->aDb[i].pBt; if( pBt ){ |
︙ | ︙ | |||
2296 2297 2298 2299 2300 2301 2302 | ** P2==0 is the schema version. P2==1 is the database format. ** P2==2 is the recommended pager cache size, and so forth. P1==0 is ** the main database file and P1==1 is the database file used to store ** temporary tables. ** ** A transaction must be started before executing this opcode. */ | | | 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 | ** P2==0 is the schema version. P2==1 is the database format. ** P2==2 is the recommended pager cache size, and so forth. P1==0 is ** the main database file and P1==1 is the database file used to store ** temporary tables. ** ** A transaction must be started before executing this opcode. */ case OP_SetCookie: { /* no-push */ Db *pDb; assert( pOp->p2<SQLITE_N_BTREE_META ); assert( pOp->p1>=0 && pOp->p1<db->nDb ); pDb = &db->aDb[pOp->p1]; assert( pDb->pBt!=0 ); assert( pTos>=p->aStack ); Integerify(pTos); |
︙ | ︙ | |||
2332 2333 2334 2335 2336 2337 2338 | ** This operation is used to detect when that the cookie has changed ** and that the current process needs to reread the schema. ** ** Either a transaction needs to have been started or an OP_Open needs ** to be executed (to establish a read lock) before this opcode is ** invoked. */ | | | 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 | ** This operation is used to detect when that the cookie has changed ** and that the current process needs to reread the schema. ** ** Either a transaction needs to have been started or an OP_Open needs ** to be executed (to establish a read lock) before this opcode is ** invoked. */ case OP_VerifyCookie: { /* no-push */ int iMeta; Btree *pBt; assert( pOp->p1>=0 && pOp->p1<db->nDb ); pBt = db->aDb[pOp->p1].pBt; if( pBt ){ rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&iMeta); }else{ |
︙ | ︙ | |||
2392 2393 2394 2395 2396 2397 2398 | ** ** This instruction works just like OpenRead except that it opens the cursor ** in read/write mode. For a given table, there can be one or more read-only ** cursors or a single read/write cursor but not both. ** ** See also OpenRead. */ | | | | 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 | ** ** This instruction works just like OpenRead except that it opens the cursor ** in read/write mode. For a given table, there can be one or more read-only ** cursors or a single read/write cursor but not both. ** ** See also OpenRead. */ case OP_OpenRead: /* no-push */ case OP_OpenWrite: { /* no-push */ int i = pOp->p1; int p2 = pOp->p2; int wrFlag; Btree *pX; int iDb; Cursor *pCur; |
︙ | ︙ | |||
2481 2482 2483 2484 2485 2486 2487 | ** This opcode is used for tables that exist for the duration of a single ** SQL statement only. Tables created using CREATE TEMPORARY TABLE ** are opened using OP_OpenRead or OP_OpenWrite. "Temporary" in the ** context of this opcode means for the duration of a single SQL statement ** whereas "Temporary" in the context of CREATE TABLE means for the duration ** of the connection to the database. Same word; different meanings. */ | | | 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 | ** This opcode is used for tables that exist for the duration of a single ** SQL statement only. Tables created using CREATE TEMPORARY TABLE ** are opened using OP_OpenRead or OP_OpenWrite. "Temporary" in the ** context of this opcode means for the duration of a single SQL statement ** whereas "Temporary" in the context of CREATE TABLE means for the duration ** of the connection to the database. Same word; different meanings. */ case OP_OpenTemp: { /* no-push */ int i = pOp->p1; Cursor *pCx; assert( i>=0 ); pCx = allocateCursor(p, i); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; rc = sqlite3BtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt); |
︙ | ︙ | |||
2530 2531 2532 2533 2534 2535 2536 | ** row of data. Any attempt to write a second row of data causes the ** first row to be deleted. All data is deleted when the cursor is ** closed. ** ** A pseudo-table created by this opcode is useful for holding the ** NEW or OLD tables in a trigger. */ | | | | 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 | ** row of data. Any attempt to write a second row of data causes the ** first row to be deleted. All data is deleted when the cursor is ** closed. ** ** A pseudo-table created by this opcode is useful for holding the ** NEW or OLD tables in a trigger. */ case OP_OpenPseudo: { /* no-push */ int i = pOp->p1; Cursor *pCx; assert( i>=0 ); pCx = allocateCursor(p, i); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; pCx->pseudoTable = 1; pCx->pIncrKey = &pCx->bogusIncrKey; break; } #endif /* Opcode: Close P1 * * ** ** Close a cursor previously opened as P1. If P1 is not ** currently open, this instruction is a no-op. */ case OP_Close: { /* no-push */ int i = pOp->p1; if( i>=0 && i<p->nCursor ){ sqlite3VdbeFreeCursor(p->apCsr[i]); p->apCsr[i] = 0; } break; } |
︙ | ︙ | |||
2597 2598 2599 2600 2601 2602 2603 | ** cursor P1 so that it points to the largest entry that is less than ** or equal to the key that was popped from the stack. ** If there are no records less than or eqal to the key and P2 is not zero, ** then jump to P2. ** ** See also: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLt */ | | | | | | 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 | ** cursor P1 so that it points to the largest entry that is less than ** or equal to the key that was popped from the stack. ** If there are no records less than or eqal to the key and P2 is not zero, ** then jump to P2. ** ** See also: Found, NotFound, Distinct, MoveGt, MoveGe, MoveLt */ case OP_MoveLt: /* no-push */ case OP_MoveLe: /* no-push */ case OP_MoveGe: /* no-push */ case OP_MoveGt: { /* no-push */ int i = pOp->p1; Cursor *pC; assert( pTos>=p->aStack ); assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; assert( pC!=0 ); |
︙ | ︙ | |||
2709 2710 2711 2712 2713 2714 2715 | ** record if it exists. The key is popped from the stack. ** ** The difference between this operation and Distinct is that ** Distinct does not pop the key from the stack. ** ** See also: Distinct, Found, MoveTo, NotExists, IsUnique */ | | | | | 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 | ** record if it exists. The key is popped from the stack. ** ** The difference between this operation and Distinct is that ** Distinct does not pop the key from the stack. ** ** See also: Distinct, Found, MoveTo, NotExists, IsUnique */ case OP_Distinct: /* no-push */ case OP_NotFound: /* no-push */ case OP_Found: { /* no-push */ int i = pOp->p1; int alreadyExists = 0; Cursor *pC; assert( pTos>=p->aStack ); assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); if( (pC = p->apCsr[i])->pCursor!=0 ){ |
︙ | ︙ | |||
2760 2761 2762 2763 2764 2765 2766 | ** jump to P2. If any entry does exist where the index string ** matches K but the record number is not R, then the record ** number for that entry is pushed onto the stack and control ** falls through to the next instruction. ** ** See also: Distinct, NotFound, NotExists, Found */ | | | 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 | ** jump to P2. If any entry does exist where the index string ** matches K but the record number is not R, then the record ** number for that entry is pushed onto the stack and control ** falls through to the next instruction. ** ** See also: Distinct, NotFound, NotExists, Found */ case OP_IsUnique: { /* no-push */ int i = pOp->p1; Mem *pNos = &pTos[-1]; Cursor *pCx; BtCursor *pCrsr; i64 R; /* Pop the value R off the top of the stack |
︙ | ︙ | |||
2854 2855 2856 2857 2858 2859 2860 | ** ** The difference between this operation and NotFound is that this ** operation assumes the key is an integer and NotFound assumes it ** is a string. ** ** See also: Distinct, Found, MoveTo, NotFound, IsUnique */ | | | 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 | ** ** The difference between this operation and NotFound is that this ** operation assumes the key is an integer and NotFound assumes it ** is a string. ** ** See also: Distinct, Found, MoveTo, NotFound, IsUnique */ case OP_NotExists: { /* no-push */ int i = pOp->p1; Cursor *pC; BtCursor *pCrsr; assert( pTos>=p->aStack ); assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ |
︙ | ︙ | |||
3057 3058 3059 3060 3061 3062 3063 | ** created if it doesn't already exist or the data for an existing ** entry is overwritten. The data is the value on the top of the ** stack. The key is the next value down on the stack. The key must ** be a string. The stack is popped twice by this instruction. ** ** P1 may not be a pseudo-table opened using the OpenPseudo opcode. */ | | | | 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 | ** created if it doesn't already exist or the data for an existing ** entry is overwritten. The data is the value on the top of the ** stack. The key is the next value down on the stack. The key must ** be a string. The stack is popped twice by this instruction. ** ** P1 may not be a pseudo-table opened using the OpenPseudo opcode. */ case OP_PutIntKey: /* no-push */ case OP_PutStrKey: { /* no-push */ Mem *pNos = &pTos[-1]; int i = pOp->p1; Cursor *pC; assert( pNos>=p->aStack ); assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){ |
︙ | ︙ | |||
3152 3153 3154 3155 3156 3157 3158 | ** a record from within an Next loop. ** ** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is ** incremented (otherwise not). ** ** If P1 is a pseudo-table, then this instruction is a no-op. */ | | | 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 | ** a record from within an Next loop. ** ** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is ** incremented (otherwise not). ** ** If P1 is a pseudo-table, then this instruction is a no-op. */ case OP_Delete: { /* no-push */ int i = pOp->p1; Cursor *pC; assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; assert( pC!=0 ); if( pC->pCursor!=0 ){ rc = sqlite3VdbeCursorMoveto(pC); |
︙ | ︙ | |||
3176 3177 3178 3179 3180 3181 3182 | /* Opcode: ResetCount P1 * * ** ** This opcode resets the VMs internal change counter to 0. If P1 is true, ** then the value of the change counter is copied to the database handle ** change counter (returned by subsequent calls to sqlite3_changes()) ** before it is reset. This is used by trigger programs. */ | | | | 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 | /* Opcode: ResetCount P1 * * ** ** This opcode resets the VMs internal change counter to 0. If P1 is true, ** then the value of the change counter is copied to the database handle ** change counter (returned by subsequent calls to sqlite3_changes()) ** before it is reset. This is used by trigger programs. */ case OP_ResetCount: { /* no-push */ if( pOp->p1 ){ sqlite3VdbeSetChanges(db, p->nChange); } p->nChange = 0; break; } /* Opcode: KeyAsData P1 P2 * ** ** Turn the key-as-data mode for cursor P1 either on (if P2==1) or ** off (if P2==0). In key-as-data mode, the OP_Column opcode pulls ** data off of the key rather than the data. This is used for ** processing compound selects. */ case OP_KeyAsData: { /* no-push */ int i = pOp->p1; Cursor *pC; assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; assert( pC!=0 ); pC->keyAsData = pOp->p2; break; |
︙ | ︙ | |||
3367 3368 3369 3370 3371 3372 3373 | /* Opcode: NullRow P1 * * ** ** Move the cursor P1 to a null row. Any OP_Column operations ** that occur while the cursor is on the null row will always push ** a NULL onto the stack. */ | | | | 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 | /* Opcode: NullRow P1 * * ** ** Move the cursor P1 to a null row. Any OP_Column operations ** that occur while the cursor is on the null row will always push ** a NULL onto the stack. */ case OP_NullRow: { /* no-push */ int i = pOp->p1; Cursor *pC; assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; assert( pC!=0 ); pC->nullRow = 1; pC->recnoIsValid = 0; break; } /* Opcode: Last P1 P2 * ** ** The next use of the Recno or Column or Next instruction for P1 ** will refer to the last entry in the database table or index. ** If the table or index is empty and P2>0, then jump immediately to P2. ** If P2 is 0 or if the table or index is not empty, fall through ** to the following instruction. */ case OP_Last: { /* no-push */ int i = pOp->p1; Cursor *pC; BtCursor *pCrsr; assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; assert( pC!=0 ); |
︙ | ︙ | |||
3418 3419 3420 3421 3422 3423 3424 | ** ** The next use of the Recno or Column or Next instruction for P1 ** will refer to the first entry in the database table or index. ** If the table or index is empty and P2>0, then jump immediately to P2. ** If P2 is 0 or if the table or index is not empty, fall through ** to the following instruction. */ | | | 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 | ** ** The next use of the Recno or Column or Next instruction for P1 ** will refer to the first entry in the database table or index. ** If the table or index is empty and P2>0, then jump immediately to P2. ** If P2 is 0 or if the table or index is not empty, fall through ** to the following instruction. */ case OP_Rewind: { /* no-push */ int i = pOp->p1; Cursor *pC; BtCursor *pCrsr; int res; assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; |
︙ | ︙ | |||
3458 3459 3460 3461 3462 3463 3464 | /* Opcode: Prev P1 P2 * ** ** 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. */ | | | | 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 | /* Opcode: Prev P1 P2 * ** ** 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. */ case OP_Prev: /* no-push */ case OP_Next: { /* no-push */ Cursor *pC; BtCursor *pCrsr; CHECK_FOR_INTERRUPT; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); |
︙ | ︙ | |||
3500 3501 3502 3503 3504 3505 3506 | ** index P1. Data for the entry is nil. ** ** If P2==1, then the key must be unique. If the key is not unique, ** the program aborts with a SQLITE_CONSTRAINT error and the database ** is rolled back. If P3 is not null, then it becomes part of the ** error message returned with the SQLITE_CONSTRAINT. */ | | | 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 | ** index P1. Data for the entry is nil. ** ** If P2==1, then the key must be unique. If the key is not unique, ** the program aborts with a SQLITE_CONSTRAINT error and the database ** is rolled back. If P3 is not null, then it becomes part of the ** error message returned with the SQLITE_CONSTRAINT. */ case OP_IdxPut: { /* no-push */ int i = pOp->p1; Cursor *pC; BtCursor *pCrsr; assert( pTos>=p->aStack ); assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); assert( pTos->flags & MEM_Blob ); |
︙ | ︙ | |||
3552 3553 3554 3555 3556 3557 3558 | } /* Opcode: IdxDelete P1 * * ** ** The top of the stack is an index key built using the MakeIdxKey opcode. ** This opcode removes that entry from the index. */ | | | 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 | } /* Opcode: IdxDelete P1 * * ** ** The top of the stack is an index key built using the MakeIdxKey opcode. ** This opcode removes that entry from the index. */ case OP_IdxDelete: { /* no-push */ int i = pOp->p1; Cursor *pC; BtCursor *pCrsr; assert( pTos>=p->aStack ); assert( pTos->flags & MEM_Blob ); assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); |
︙ | ︙ | |||
3654 3655 3656 3657 3658 3659 3660 | ** In either case, the stack is popped once. ** ** If P3 is the "+" string (or any other non-NULL string) then the ** index taken from the top of the stack is temporarily increased by ** an epsilon prior to the comparison. This makes the opcode work ** like IdxLE. */ | | | | | 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 | ** In either case, the stack is popped once. ** ** If P3 is the "+" string (or any other non-NULL string) then the ** index taken from the top of the stack is temporarily increased by ** an epsilon prior to the comparison. This makes the opcode work ** like IdxLE. */ case OP_IdxLT: /* no-push */ case OP_IdxGT: /* no-push */ case OP_IdxGE: { /* no-push */ int i= pOp->p1; BtCursor *pCrsr; Cursor *pC; assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); assert( pTos>=p->aStack ); |
︙ | ︙ | |||
3700 3701 3702 3703 3704 3705 3706 | ** The top of the stack contains an index entry such as might be generated ** by the MakeIdxKey opcode. This routine looks at the first P1 fields of ** that key. If any of the first P1 fields are NULL, then a jump is made ** to address P2. Otherwise we fall straight through. ** ** The index entry is always popped from the stack. */ | | | 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 | ** The top of the stack contains an index entry such as might be generated ** by the MakeIdxKey opcode. This routine looks at the first P1 fields of ** that key. If any of the first P1 fields are NULL, then a jump is made ** to address P2. Otherwise we fall straight through. ** ** The index entry is always popped from the stack. */ case OP_IdxIsNull: { /* no-push */ int i = pOp->p1; int k, n; const char *z; u32 serial_type; assert( pTos>=p->aStack ); assert( pTos->flags & MEM_Blob ); |
︙ | ︙ | |||
3774 3775 3776 3777 3778 3779 3780 | ** ** The table being clear is in the main database file if P2==0. If ** P2==1 then the table to be clear is in the auxiliary database file ** that is used to store tables create using CREATE TEMPORARY TABLE. ** ** See also: Destroy */ | | | 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 | ** ** The table being clear is in the main database file if P2==0. If ** P2==1 then the table to be clear is in the auxiliary database file ** that is used to store tables create using CREATE TEMPORARY TABLE. ** ** See also: Destroy */ case OP_Clear: { /* no-push */ rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1); break; } /* Opcode: CreateTable P1 * * ** ** Allocate a new table in the main database file if P2==0 or in the |
︙ | ︙ | |||
3832 3833 3834 3835 3836 3837 3838 | ** ** Read and parse all entries from the SQLITE_MASTER table of database P1 ** that match the WHERE clause P3. ** ** This opcode invokes the parser to create a new virtual machine, ** then runs the new virtual machine. It is thus a reentrant opcode. */ | | | 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 | ** ** Read and parse all entries from the SQLITE_MASTER table of database P1 ** that match the WHERE clause P3. ** ** This opcode invokes the parser to create a new virtual machine, ** then runs the new virtual machine. It is thus a reentrant opcode. */ case OP_ParseSchema: { /* no-push */ char *zSql; int iDb = pOp->p1; const char *zMaster; InitData initData; assert( iDb>=0 && iDb<db->nDb ); if( !DbHasProperty(db, iDb, DB_SchemaLoaded) ) break; |
︙ | ︙ | |||
3864 3865 3866 3867 3868 3869 3870 | /* Opcode: DropTable P1 * P3 ** ** Remove the internal (in-memory) data structures that describe ** the table named P3 in database P1. This is called after a table ** is dropped in order to keep the internal representation of the ** schema consistent with what is on disk. */ | | | | | 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 | /* Opcode: DropTable P1 * P3 ** ** Remove the internal (in-memory) data structures that describe ** the table named P3 in database P1. This is called after a table ** is dropped in order to keep the internal representation of the ** schema consistent with what is on disk. */ case OP_DropTable: { /* no-push */ sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p3); break; } /* Opcode: DropIndex P1 * P3 ** ** Remove the internal (in-memory) data structures that describe ** the index named P3 in database P1. This is called after an index ** is dropped in order to keep the internal representation of the ** schema consistent with what is on disk. */ case OP_DropIndex: { /* no-push */ sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p3); break; } /* Opcode: DropTrigger P1 * P3 ** ** Remove the internal (in-memory) data structures that describe ** the trigger named P3 in database P1. This is called after a trigger ** is dropped in order to keep the internal representation of the ** schema consistent with what is on disk. */ case OP_DropTrigger: { /* no-push */ sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p3); break; } #ifndef SQLITE_OMIT_INTEGRITY_CHECK /* Opcode: IntegrityCk * P2 * |
︙ | ︙ | |||
3953 3954 3955 3956 3957 3958 3959 | #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* Opcode: ListWrite * * * ** ** Write the integer on the top of the stack ** into the temporary storage list. */ | | | 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 | #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* Opcode: ListWrite * * * ** ** Write the integer on the top of the stack ** into the temporary storage list. */ case OP_ListWrite: { /* no-push */ Keylist *pKeylist; assert( pTos>=p->aStack ); pKeylist = p->pList; if( pKeylist==0 || pKeylist->nUsed>=pKeylist->nKey ){ pKeylist = sqliteMallocRaw( sizeof(Keylist)+999*sizeof(pKeylist->aKey[0]) ); if( pKeylist==0 ) goto no_mem; pKeylist->nKey = 1000; |
︙ | ︙ | |||
3977 3978 3979 3980 3981 3982 3983 | break; } /* Opcode: ListRewind * * * ** ** Rewind the temporary buffer back to the beginning. */ | | | 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 | break; } /* Opcode: ListRewind * * * ** ** Rewind the temporary buffer back to the beginning. */ case OP_ListRewind: { /* no-push */ /* What this opcode codes, really, is reverse the order of the ** linked list of Keylist structures so that they are read out ** in the same order that they were read in. */ Keylist *pRev, *pTop; pRev = 0; while( p->pList ){ pTop = p->pList; |
︙ | ︙ | |||
4024 4025 4026 4027 4028 4029 4030 | break; } /* Opcode: ListReset * * * ** ** Reset the temporary storage buffer so that it holds nothing. */ | | | | | | 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 | break; } /* Opcode: ListReset * * * ** ** Reset the temporary storage buffer so that it holds nothing. */ case OP_ListReset: { /* no-push */ if( p->pList ){ sqlite3VdbeKeylistFree(p->pList); p->pList = 0; } break; } #ifndef SQLITE_OMIT_SUBQUERY /* Opcode: AggContextPush * * * ** ** Save the state of the current aggregator. It is restored an ** AggContextPop opcode. ** */ case OP_AggContextPush: { /* no-push */ p->pAgg++; assert( p->pAgg<&p->apAgg[p->nAgg] ); break; } /* Opcode: AggContextPop * * * ** ** Restore the aggregator to the state it was in when AggContextPush ** was last called. Any data in the current aggregator is deleted. */ case OP_AggContextPop: { /* no-push */ p->pAgg--; assert( p->pAgg>=p->apAgg ); break; } #endif #ifndef SQLITE_OMIT_TRIGGER /* Opcode: ContextPush * * * ** ** Save the current Vdbe context such that it can be restored by a ContextPop ** opcode. The context stores the last insert row id, the last statement change ** count, and the current statement change count. */ case OP_ContextPush: { /* no-push */ int i = p->contextStackTop++; Context *pContext; assert( i>=0 ); /* FIX ME: This should be allocated as part of the vdbe at compile-time */ if( i>=p->contextStackDepth ){ p->contextStackDepth = i+1; |
︙ | ︙ | |||
4089 4090 4091 4092 4093 4094 4095 | /* Opcode: ContextPop * * * ** ** Restore the Vdbe context to the state it was in when contextPush was last ** executed. The context stores the last insert row id, the last statement ** change count, and the current statement change count. */ | | | | 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 | /* Opcode: ContextPop * * * ** ** Restore the Vdbe context to the state it was in when contextPush was last ** executed. The context stores the last insert row id, the last statement ** change count, and the current statement change count. */ case OP_ContextPop: { /* no-push */ Context *pContext = &p->contextStack[--p->contextStackTop]; assert( p->contextStackTop>=0 ); db->lastRowid = pContext->lastRowid; p->nChange = pContext->nChange; sqlite3VdbeKeylistFree(p->pList); p->pList = pContext->pList; break; } #endif /* #ifndef SQLITE_OMIT_TRIGGER */ /* Opcode: SortPut * * * ** ** The TOS is the key and the NOS is the data. Pop both from the stack ** and put them on the sorter. The key and data should have been ** made using the MakeRecord opcode. */ case OP_SortPut: { /* no-push */ Mem *pNos = &pTos[-1]; Sorter *pSorter; assert( pNos>=p->aStack ); if( Dynamicify(pTos, db->enc) ) goto no_mem; pSorter = sqliteMallocRaw( sizeof(Sorter) ); if( pSorter==0 ) goto no_mem; pSorter->pNext = p->pSort; |
︙ | ︙ | |||
4130 4131 4132 4133 4134 4135 4136 | /* Opcode: Sort * * P3 ** ** Sort all elements on the sorter. The algorithm is a ** mergesort. The P3 argument is a pointer to a KeyInfo structure ** that describes the keys to be sorted. */ | | | 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 | /* Opcode: Sort * * P3 ** ** Sort all elements on the sorter. The algorithm is a ** mergesort. The P3 argument is a pointer to a KeyInfo structure ** that describes the keys to be sorted. */ case OP_Sort: { /* no-push */ int i; KeyInfo *pKeyInfo = (KeyInfo*)pOp->p3; Sorter *pElem; Sorter *apSorter[NSORT]; sqlite3_sort_count++; pKeyInfo->enc = p->db->enc; for(i=0; i<NSORT; i++){ |
︙ | ︙ | |||
4192 4193 4194 4195 4196 4197 4198 | break; } /* Opcode: SortReset * * * ** ** Remove any elements that remain on the sorter. */ | | | | 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 | break; } /* Opcode: SortReset * * * ** ** Remove any elements that remain on the sorter. */ case OP_SortReset: { /* no-push */ sqlite3VdbeSorterReset(p); break; } /* Opcode: MemStore P1 P2 * ** ** Write the top of the stack into memory location P1. ** P1 should be a small integer since space is allocated ** for all memory locations between 0 and P1 inclusive. ** ** After the data is stored in the memory location, the ** stack is popped once if P2 is 1. If P2 is zero, then ** the original data remains on the stack. */ case OP_MemStore: { /* no-push */ assert( pTos>=p->aStack ); assert( pOp->p1>=0 && pOp->p1<p->nMem ); rc = sqlite3VdbeMemMove(&p->aMem[pOp->p1], pTos); pTos--; /* If P2 is 0 then fall thru to the next opcode, OP_MemLoad, that will ** restore the top of the stack to its original value. |
︙ | ︙ | |||
4246 4247 4248 4249 4250 4251 4252 | ** ** Set the value of memory cell P1 to the maximum of its current value ** and the value on the top of the stack. The stack is unchanged. ** ** This instruction throws an error if the memory cell is not initially ** an integer. */ | | | 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 | ** ** Set the value of memory cell P1 to the maximum of its current value ** and the value on the top of the stack. The stack is unchanged. ** ** This instruction throws an error if the memory cell is not initially ** an integer. */ case OP_MemMax: { /* no-push */ int i = pOp->p1; Mem *pMem; assert( pTos>=p->aStack ); assert( i>=0 && i<p->nMem ); pMem = &p->aMem[i]; Integerify(pMem); Integerify(pTos); |
︙ | ︙ | |||
4270 4271 4272 4273 4274 4275 4276 | ** Increment the integer valued memory cell P1 by 1. If P2 is not zero ** and the result after the increment is exactly 1, then jump ** to P2. ** ** This instruction throws an error if the memory cell is not initially ** an integer. */ | | | | 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 | ** Increment the integer valued memory cell P1 by 1. If P2 is not zero ** and the result after the increment is exactly 1, then jump ** to P2. ** ** This instruction throws an error if the memory cell is not initially ** an integer. */ case OP_MemIncr: { /* no-push */ int i = pOp->p1; Mem *pMem; assert( i>=0 && i<p->nMem ); pMem = &p->aMem[i]; assert( pMem->flags==MEM_Int ); pMem->i++; if( pOp->p2>0 && pMem->i==1 ){ pc = pOp->p2 - 1; } break; } /* Opcode: IfMemPos P1 P2 * ** ** If the value of memory cell P1 is 1 or greater, jump to P2. This ** opcode assumes that memory cell P1 holds an integer value. */ case OP_IfMemPos: { /* no-push */ int i = pOp->p1; Mem *pMem; assert( i>=0 && i<p->nMem ); pMem = &p->aMem[i]; assert( pMem->flags==MEM_Int ); if( pMem->i>0 ){ pc = pOp->p2 - 1; |
︙ | ︙ | |||
4310 4311 4312 4313 4314 4315 4316 | ** data. Future aggregator elements will contain P2 values each and be sorted ** using the KeyInfo structure pointed to by P3. ** ** If P1 is non-zero, then only a single aggregator row is available (i.e. ** there is no GROUP BY expression). In this case it is illegal to invoke ** OP_AggFocus. */ | | | 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 | ** data. Future aggregator elements will contain P2 values each and be sorted ** using the KeyInfo structure pointed to by P3. ** ** If P1 is non-zero, then only a single aggregator row is available (i.e. ** there is no GROUP BY expression). In this case it is illegal to invoke ** OP_AggFocus. */ case OP_AggReset: { /* no-push */ assert( !pOp->p3 || pOp->p3type==P3_KEYINFO ); if( pOp->p1 ){ rc = sqlite3VdbeAggReset(0, p->pAgg, (KeyInfo *)pOp->p3); p->pAgg->nMem = pOp->p2; /* Agg.nMem is used by AggInsert() */ rc = AggInsert(p->pAgg, 0, 0); }else{ rc = sqlite3VdbeAggReset(db, p->pAgg, (KeyInfo *)pOp->p3); |
︙ | ︙ | |||
4334 4335 4336 4337 4338 4339 4340 | /* Opcode: AggInit * P2 P3 ** ** Initialize the function parameters for an aggregate function. ** The aggregate will operate out of aggregate column P2. ** P3 is a pointer to the FuncDef structure for the function. */ | | | | 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 | /* Opcode: AggInit * P2 P3 ** ** Initialize the function parameters for an aggregate function. ** The aggregate will operate out of aggregate column P2. ** P3 is a pointer to the FuncDef structure for the function. */ case OP_AggInit: { /* no-push */ int i = pOp->p2; assert( i>=0 && i<p->pAgg->nMem ); p->pAgg->apFunc[i] = (FuncDef*)pOp->p3; break; } /* Opcode: AggFunc * P2 P3 ** ** Execute the step function for an aggregate. The ** function has P2 arguments. P3 is a pointer to the FuncDef ** structure that specifies the function. ** ** The top of the stack must be an integer which is the index of ** the aggregate column that corresponds to this aggregate function. ** Ideally, this index would be another parameter, but there are ** no free parameters left. The integer is popped from the stack. */ case OP_AggFunc: { /* no-push */ int n = pOp->p2; int i; Mem *pMem, *pRec; sqlite3_context ctx; sqlite3_value **apVal; assert( n>=0 ); |
︙ | ︙ | |||
4410 4411 4412 4413 4414 4415 4416 | ** ** The order of aggregator opcodes is important. The order is: ** AggReset AggFocus AggNext. In other words, you must execute ** AggReset first, then zero or more AggFocus operations, then ** zero or more AggNext operations. You must not execute an AggFocus ** in between an AggNext and an AggReset. */ | | | 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 | ** ** The order of aggregator opcodes is important. The order is: ** AggReset AggFocus AggNext. In other words, you must execute ** AggReset first, then zero or more AggFocus operations, then ** zero or more AggNext operations. You must not execute an AggFocus ** in between an AggNext and an AggReset. */ case OP_AggFocus: { /* no-push */ char *zKey; int nKey; int res; assert( pTos>=p->aStack ); Stringify(pTos, db->enc); zKey = pTos->z; nKey = pTos->n; |
︙ | ︙ | |||
4444 4445 4446 4447 4448 4449 4450 | } /* Opcode: AggSet * P2 * ** ** Move the top of the stack into the P2-th field of the current ** aggregate. String values are duplicated into new memory. */ | | | 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 | } /* Opcode: AggSet * P2 * ** ** Move the top of the stack into the P2-th field of the current ** aggregate. String values are duplicated into new memory. */ case OP_AggSet: { /* no-push */ AggElem *pFocus; int i = pOp->p2; pFocus = p->pAgg->pCurrent; assert( pTos>=p->aStack ); if( pFocus==0 ) goto no_mem; assert( i>=0 && i<p->pAgg->nMem ); rc = sqlite3VdbeMemMove(&pFocus->aMem[i], pTos); |
︙ | ︙ | |||
4509 4510 4511 4512 4513 4514 4515 | ** ** The order of aggregator opcodes is important. The order is: ** AggReset AggFocus AggNext. In other words, you must execute ** AggReset first, then zero or more AggFocus operations, then ** zero or more AggNext operations. You must not execute an AggFocus ** in between an AggNext and an AggReset. */ | | | 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 | ** ** The order of aggregator opcodes is important. The order is: ** AggReset AggFocus AggNext. In other words, you must execute ** AggReset first, then zero or more AggFocus operations, then ** zero or more AggNext operations. You must not execute an AggFocus ** in between an AggNext and an AggReset. */ case OP_AggNext: { /* no-push */ int res; assert( rc==SQLITE_OK ); CHECK_FOR_INTERRUPT; if( p->pAgg->searching==0 ){ p->pAgg->searching = 1; if( p->pAgg->pCsr ){ rc = sqlite3BtreeFirst(p->pAgg->pCsr, &res); |
︙ | ︙ | |||
4570 4571 4572 4573 4574 4575 4576 | /* Opcode: Vacuum * * * ** ** Vacuum the entire database. This opcode will cause other virtual ** machines to be created and run. It may not be called from within ** a transaction. */ | | | | 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 | /* Opcode: Vacuum * * * ** ** Vacuum the entire database. This opcode will cause other virtual ** machines to be created and run. It may not be called from within ** a transaction. */ case OP_Vacuum: { /* no-push */ if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; rc = sqlite3RunVacuum(&p->zErrMsg, db); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; break; } /* Opcode: Expire P1 * * ** ** Cause precompiled statements to become expired. An expired statement ** fails with an error code of SQLITE_SCHEMA if it is ever executed ** (via sqlite3_step()). ** ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, ** then only the currently executing statement is affected. */ case OP_Expire: { /* no-push */ if( !pOp->p1 ){ sqlite3ExpirePreparedStatements(db); }else{ p->expired = 1; } break; } |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
402 403 404 405 406 407 408 | int sqlite3VdbeMemIntegerify(Mem*); double sqlite3VdbeRealValue(Mem*); int sqlite3VdbeMemRealify(Mem*); int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*); void sqlite3VdbeMemRelease(Mem *p); #ifndef NDEBUG void sqlite3VdbeMemSanity(Mem*, u8); | | | 402 403 404 405 406 407 408 409 410 411 412 413 | int sqlite3VdbeMemIntegerify(Mem*); double sqlite3VdbeRealValue(Mem*); int sqlite3VdbeMemRealify(Mem*); int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*); void sqlite3VdbeMemRelease(Mem *p); #ifndef NDEBUG void sqlite3VdbeMemSanity(Mem*, u8); int sqlite3VdbeOpcodeNoPush(u8); #endif int sqlite3VdbeMemTranslate(Mem*, u8); void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf, int nBuf); int sqlite3VdbeMemHandleBom(Mem *pMem); |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
166 167 168 169 170 171 172 | } } /* ** Return non-zero if opcode 'op' is guarenteed not to push more values ** onto the VDBE stack than it pops off. */ | | | | | | | | | | | | | 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | } } /* ** Return non-zero if opcode 'op' is guarenteed not to push more values ** onto the VDBE stack than it pops off. */ static int opcodeNoPush(u8 op){ /* The 10 NOPUSH_MASK_n constants are defined in the automatically ** generated header file opcodes.h. Each is a 16-bit bitmask, one ** bit corresponding to each opcode implemented by the virtual ** machine in vdbe.c. The bit is true if the word "no-push" appears ** in a comment on the same line as the "case OP_XXX:" in ** sqlite3VdbeExec() in vdbe.c. ** ** If the bit is true, then the corresponding opcode is guarenteed not ** to grow the stack when it is executed. Otherwise, it may grow the ** stack by at most one entry. ** ** NOPUSH_MASK_0 corresponds to opcodes 0 to 15. NOPUSH_MASK_1 contains ** one bit for opcodes 16 to 31, and so on. ** ** 16-bit bitmasks (rather than 32-bit) are specified in opcodes.h ** because the file is generated by an awk program. Awk manipulates ** all numbers as floating-point and we don't want to risk a rounding ** error if someone builds with an awk that uses (for example) 32-bit ** IEEE floats. */ static u32 masks[5] = { NOPUSH_MASK_0 + (NOPUSH_MASK_1<<16), NOPUSH_MASK_2 + (NOPUSH_MASK_3<<16), NOPUSH_MASK_4 + (NOPUSH_MASK_5<<16), NOPUSH_MASK_6 + (NOPUSH_MASK_7<<16), NOPUSH_MASK_8 + (NOPUSH_MASK_9<<16) }; return (masks[op>>5] & (1<<(op&0x1F))); } #ifndef NDEBUG int sqlite3VdbeOpcodeNoPush(u8 op){ return opcodeNoPush(op); } #endif /* ** Loop through the program looking for P2 values that are negative. ** Each such value is a label. Resolve the label by setting the P2 ** value to its correct non-zero value. |
︙ | ︙ | |||
235 236 237 238 239 240 241 | */ if( opcode==OP_Function ){ if( pOp->p1>nMaxArgs ) nMaxArgs = pOp->p1; }else if( opcode==OP_AggFunc ){ if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; } | | | 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | */ if( opcode==OP_Function ){ if( pOp->p1>nMaxArgs ) nMaxArgs = pOp->p1; }else if( opcode==OP_AggFunc ){ if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; } if( opcodeNoPush(opcode) ){ nMaxStack--; } if( pOp->p2>=0 ) continue; assert( -1-pOp->p2<p->nLabel ); pOp->p2 = aLabel[-1-pOp->p2]; } |
︙ | ︙ |