Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Tables and indices use the same record format. (CVS 1481) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
ebd564d10b0ecd7ff15cbd6cd2b979c9 |
User & Date: | drh 2004-05-28 08:21:02.000 |
Context
2004-05-28
| ||
08:21 | Tables and indices use the same record format. (CVS 1482) (check-in: 1b15b32bdb user: drh tags: trunk) | |
08:21 | Tables and indices use the same record format. (CVS 1481) (check-in: ebd564d10b user: drh tags: trunk) | |
01:39 | Remove the encoding argument from sqlite3VdbeSerialGet. Use the 32-bit version of sqlite3GetVarint for schema-level parameters. (CVS 1480) (check-in: 321f8c4635 user: drh tags: trunk) | |
Changes
Changes to VERSION.
|
| | | 1 | 3.0.0alpha |
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.131 2004/05/28 08:21:06 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> char const *sqlite3AffinityString(char affinity){ switch( affinity ){ case SQLITE_AFF_INTEGER: return "i"; |
︙ | ︙ | |||
820 821 822 823 824 825 826 827 828 829 830 831 832 833 | */ pExpr->iTable = pParse->nTab++; memset(&keyInfo, 0, sizeof(keyInfo)); keyInfo.nField = 1; keyInfo.aColl[0] = pParse->db->pDfltColl; sqlite3VdbeOp3(v, OP_OpenTemp, pExpr->iTable, 0, \ (char*)&keyInfo, P3_KEYINFO); if( pExpr->pSelect ){ /* Case 1: expr IN (SELECT ...) ** ** Generate code to write the results of the select into the temporary ** table allocated and opened above. */ | > | 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 | */ pExpr->iTable = pParse->nTab++; memset(&keyInfo, 0, sizeof(keyInfo)); keyInfo.nField = 1; keyInfo.aColl[0] = pParse->db->pDfltColl; sqlite3VdbeOp3(v, OP_OpenTemp, pExpr->iTable, 0, \ (char*)&keyInfo, P3_KEYINFO); sqlite3VdbeAddOp(v, OP_SetNumColumns, pExpr->iTable, 1); if( pExpr->pSelect ){ /* Case 1: expr IN (SELECT ...) ** ** Generate code to write the results of the select into the temporary ** table allocated and opened above. */ |
︙ | ︙ |
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.343 2004/05/28 08:21:09 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
400 401 402 403 404 405 406 | /* Temporary - this is useful in conjunction with prettyPrintMem whilst ** debugging. */ char zGdbBuf[100]; #endif | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 400 401 402 403 404 405 406 407 408 409 410 411 412 413 | /* Temporary - this is useful in conjunction with prettyPrintMem whilst ** debugging. */ char zGdbBuf[100]; #endif #ifdef VDBE_PROFILE /* ** The following routine only works on pentium-class processors. ** It uses the RDTSC opcode to read cycle count value out of the ** processor and returns that value. This can be used for high-res ** profiling. |
︙ | ︙ | |||
1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 | */ case OP_SetNumColumns: { assert( (pOp->p1)<p->nCursor ); p->apCsr[pOp->p1]->nField = pOp->p2; break; } /* Opcode: Column P1 P2 * ** ** Interpret the data that cursor P1 points to as a structure built using ** the MakeRecord instruction. (See the MakeRecord opcode for additional ** information about the format of the data.) Push onto the stack the value ** of the P2-th column contained in the data. ** ** If the KeyAsData opcode has previously executed on this cursor, then the ** field might be extracted from the key rather than the data. ** ** If P1 is negative, then the record is stored on the stack rather than in ** a table. For P1==-1, the top of the stack is used. For P1==-2, the ** next on the stack is used. And so forth. The value pushed is always ** just a pointer into the record which is stored further down on the ** stack. The column value is not copied. The number of columns in the ** record is stored on the stack just above the record itself. */ case OP_Column: { int payloadSize; /* Number of bytes in the record */ int p1 = pOp->p1; /* P1 value of the opcode */ int p2 = pOp->p2; /* column number to retrieve */ Cursor *pC = 0; /* The VDBE cursor */ char *zRec; /* Pointer to record-data from stack or pseudo-table. */ BtCursor *pCrsr; /* The BTree cursor */ | > > > > > > | 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 | */ case OP_SetNumColumns: { assert( (pOp->p1)<p->nCursor ); p->apCsr[pOp->p1]->nField = pOp->p2; break; } /* Opcode: IdxColumn P1 * * ** ** P1 is a cursor opened on an index. Push the first field from the ** current index key onto the stack. */ /* Opcode: Column P1 P2 * ** ** Interpret the data that cursor P1 points to as a structure built using ** the MakeRecord instruction. (See the MakeRecord opcode for additional ** information about the format of the data.) Push onto the stack the value ** of the P2-th column contained in the data. ** ** If the KeyAsData opcode has previously executed on this cursor, then the ** field might be extracted from the key rather than the data. ** ** If P1 is negative, then the record is stored on the stack rather than in ** a table. For P1==-1, the top of the stack is used. For P1==-2, the ** next on the stack is used. And so forth. The value pushed is always ** just a pointer into the record which is stored further down on the ** stack. The column value is not copied. The number of columns in the ** record is stored on the stack just above the record itself. */ case OP_IdxColumn: case OP_Column: { int payloadSize; /* Number of bytes in the record */ int p1 = pOp->p1; /* P1 value of the opcode */ int p2 = pOp->p2; /* column number to retrieve */ Cursor *pC = 0; /* The VDBE cursor */ char *zRec; /* Pointer to record-data from stack or pseudo-table. */ BtCursor *pCrsr; /* The BTree cursor */ |
︙ | ︙ | |||
1917 1918 1919 1920 1921 1922 1923 | zData = (char*)sqlite3BtreeDataFetch(pCrsr, sz); } } idx = sqlite3GetVarint32(zData, &szHdr); /* Get the complete header text */ if( !zRec ){ | | | 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 | zData = (char*)sqlite3BtreeDataFetch(pCrsr, sz); } } idx = sqlite3GetVarint32(zData, &szHdr); /* Get the complete header text */ if( !zRec ){ rc = sqlite3VdbeMemFromBtree(pCrsr, 0, szHdr, pC->keyAsData, &sMem); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } zData = sMem.z; } /* Scan the header and use it to fill in the aType[] and aOffset[] |
︙ | ︙ | |||
1967 1968 1969 1970 1971 1972 1973 | /* Get the column information. */ if( zRec ){ zData = &zRec[aOffset[p2]]; }else{ len = sqlite3VdbeSerialTypeLen(aType[p2]); | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 | /* Get the column information. */ if( zRec ){ zData = &zRec[aOffset[p2]]; }else{ len = sqlite3VdbeSerialTypeLen(aType[p2]); sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->keyAsData, &sMem); zData = sMem.z; } sqlite3VdbeSerialGet(zData, aType[p2], pTos); pTos->enc = db->enc; if( rc!=SQLITE_OK ){ goto abort_due_to_error; } Release(&sMem); /* Release the aType[] memory if we are not dealing with cursor */ if( !pC ){ sqliteFree(aType); } break; } /* Opcode: MakeKey P1 P2 P3 ** ** Convert the top P1 entries of the stack into a single entry suitable ** for use as the key in an index. If P2 is zero, then the original |
︙ | ︙ | |||
2131 2132 2133 2134 2135 2136 2137 2138 | ** 'n' NUMERIC ** 'i' INTEGER ** 't' TEXT ** 'o' NONE ** ** If P3 is NULL then datatype coercion occurs. */ case OP_MakeKey: | > > > > > > > > > > > > > > > > > > > > > > | | < < < < < | < < < | < < > > | < > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | < < < < | < < < < < < < | > | | | | > | < | > > > > | | | | | > > | > > > | > > | < | | > > > > > > > | | > | | | | | 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 | ** 'n' NUMERIC ** 'i' INTEGER ** 't' TEXT ** 'o' NONE ** ** If P3 is NULL then datatype coercion occurs. */ /* Opcode MakeRecord P1 * P3 ** ** Convert the top P1 entries of the stack into a single entry ** suitable for use as a data record in a database table. The ** details of the format are irrelavant as long as the OP_Column ** opcode can decode the record later. Refer to source code ** comments for the details of the record format. ** ** P3 may be a string that is P1 characters long. The nth character of the ** string indicates the column affinity that should be used for the nth ** field of the index key (i.e. the first character of P3 corresponds to the ** lowest element on the stack). ** ** Character Column affinity ** ------------------------------ ** 'n' NUMERIC ** 'i' INTEGER ** 't' TEXT ** 'o' NONE ** ** If P3 is NULL then all index fields have the affinity NONE. */ case OP_MakeKey: case OP_MakeIdxKey: case OP_MakeRecord: { /* Assuming the record contains N fields, the record format looks ** like this: ** ** -------------------------------------------------------------------------- ** | header-siz | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | ** -------------------------------------------------------------------------- ** ** Data(0) is taken from the lowest element of the stack and data(N-1) is ** the top of the stack. ** ** Each type field is a varint representing the serial type of the ** corresponding data element (see sqlite3VdbeSerialType()). The ** num-fields field is also a varint storing N. ** ** TODO: Even when the record is short enough for Mem::zShort, this opcode ** allocates it dynamically. */ int nField = pOp->p1; unsigned char *zNewRecord; unsigned char *zCsr; char *zAffinity; Mem *pRec; Mem *pRowid; int nData = 0; /* Number of bytes of data space */ int nHdr = 0; /* Number of bytes of header space */ int nByte = 0; /* Space required for this record */ int addRowid; /* True to append a rowid column at the end */ u32 serial_type; /* Type field */ int containsNull; /* True if any of the data fields are NULL */ Mem *pData0 = &pTos[1-nField]; assert( pData0>=p->aStack ); zAffinity = pOp->p3; addRowid = pOp->opcode==OP_MakeIdxKey; containsNull = 0; /* Loop through the elements that will make up the record to figure ** out how much space is required for the new record. */ for(pRec=pData0; pRec<=pTos; pRec++){ if( zAffinity ){ applyAffinity(pRec, zAffinity[pRec-pData0], db->enc); } if( pRec->flags&MEM_Null ){ containsNull = 1; } serial_type = sqlite3VdbeSerialType(pRec); nData += sqlite3VdbeSerialTypeLen(serial_type); nHdr += sqlite3VarintLen(serial_type); } /* If we have to append a varint rowid to this record, set 'rowid' ** to the value of the rowid and increase nByte by the amount of space ** required to store it and the 0x00 seperator byte. */ if( addRowid ){ pRowid = &pTos[0-nField]; assert( pRowid>=p->aStack ); Integerify(pRowid, db->enc); serial_type = sqlite3VdbeSerialType(pRowid); nData += sqlite3VdbeSerialTypeLen(serial_type); nHdr += sqlite3VarintLen(serial_type); } /* Add the initial header varint and total the size */ nHdr += sqlite3VarintLen(nHdr); nByte = nHdr+nData; if( nByte>MAX_BYTES_PER_ROW ){ rc = SQLITE_TOOBIG; goto abort_due_to_error; } /* Allocate space for the new record. */ zNewRecord = sqliteMallocRaw(nByte); if( !zNewRecord ){ goto no_mem; } /* Write the record */ zCsr = zNewRecord; zCsr += sqlite3PutVarint(zCsr, nHdr); for(pRec=pData0; pRec<=pTos; pRec++){ serial_type = sqlite3VdbeSerialType(pRec); zCsr += sqlite3PutVarint(zCsr, serial_type); /* serial type */ } if( addRowid ){ zCsr += sqlite3PutVarint(zCsr, sqlite3VdbeSerialType(pRowid)); } for(pRec=pData0; pRec<=pTos; pRec++){ zCsr += sqlite3VdbeSerialPut(zCsr, pRec); /* serial data */ } if( addRowid ){ zCsr += sqlite3VdbeSerialPut(zCsr, pRowid); } /* If zCsr has not been advanced exactly nByte bytes, then one ** of the sqlite3PutVarint() or sqlite3VdbeSerialPut() calls above ** failed. This indicates a corrupted memory cell or code bug. */ if( zCsr!=(zNewRecord+nByte) ){ rc = SQLITE_INTERNAL; goto abort_due_to_error; } /* Pop nField entries from the stack and push the new entry on */ if( addRowid || pOp->p2==0 ){ popStack(&pTos, nField+addRowid); } pTos++; pTos->n = nByte; pTos->z = zNewRecord; pTos->flags = MEM_Blob | MEM_Dyn; /* If P2 is non-zero, and if the key contains a NULL value, and if this ** was an OP_MakeIdxKey instruction, not OP_MakeKey, jump to P2. */ if( pOp->p2 && containsNull && addRowid ){ pc = pOp->p2 - 1; } |
︙ | ︙ | |||
2838 2839 2840 2841 2842 2843 2844 | ** The top of the stack is an integer record number. Call this ** record number R. The next on the stack is an index key created ** using MakeIdxKey. Call it K. This instruction pops R from the ** stack but it leaves K unchanged. ** ** P1 is an index. So it has no data and its key consists of a ** record generated by OP_MakeIdxKey. This key contains one or more | | | | 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 | ** The top of the stack is an integer record number. Call this ** record number R. The next on the stack is an index key created ** using MakeIdxKey. Call it K. This instruction pops R from the ** stack but it leaves K unchanged. ** ** P1 is an index. So it has no data and its key consists of a ** record generated by OP_MakeIdxKey. This key contains one or more ** fields followed by a ROWID field. ** ** This instruction asks if there is an entry in P1 where the ** fields matches K but the rowid is different from R. ** If there is no such entry, then there is an immediate ** 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. |
︙ | ︙ | |||
2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 | pCrsr = pCx->pCursor; if( pCrsr!=0 ){ int res, rc; i64 v; /* The record number on the P1 entry that matches K */ char *zKey; /* The value of K */ int nKey; /* Number of bytes in K */ int len; /* Number of bytes in K without the rowid at the end */ /* Make sure K is a string and make zKey point to K */ Stringify(pNos, db->enc); zKey = pNos->z; nKey = pNos->n; | > | | < | 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 | pCrsr = pCx->pCursor; if( pCrsr!=0 ){ int res, rc; i64 v; /* The record number on the P1 entry that matches K */ char *zKey; /* The value of K */ int nKey; /* Number of bytes in K */ int len; /* Number of bytes in K without the rowid at the end */ int szRowid; /* Size of the rowid column at the end of zKey */ /* Make sure K is a string and make zKey point to K */ Stringify(pNos, db->enc); zKey = pNos->z; nKey = pNos->n; szRowid = sqlite3VdbeIdxRowidLen(nKey, zKey); len = nKey-szRowid; /* Search for an entry in P1 where all but the last four bytes match K. ** If there is no such entry, jump immediately to P2. */ assert( pCx->deferredMoveto==0 ); pCx->cacheValid = 0; rc = sqlite3BtreeMoveto(pCrsr, zKey, len, &res); |
︙ | ︙ | |||
2905 2906 2907 2908 2909 2910 2911 | if( rc!=SQLITE_OK ) goto abort_due_to_error; if( res>0 ){ pc = pOp->p2 - 1; break; } /* At this point, pCrsr is pointing to an entry in P1 where all but | | | | 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 | if( rc!=SQLITE_OK ) goto abort_due_to_error; if( res>0 ){ pc = pOp->p2 - 1; break; } /* At this point, pCrsr is pointing to an entry in P1 where all but ** the final entry (the rowid) matches K. Check to see if the ** final rowid column is different from R. If it equals R then jump ** immediately to P2. */ rc = sqlite3VdbeIdxRowid(pCrsr, &v); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } if( v==R ){ |
︙ | ︙ | |||
3343 3344 3345 3346 3347 3348 3349 | v = keyToInt(v); } pTos->i = v; pTos->flags = MEM_Int; break; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 | v = keyToInt(v); } pTos->i = v; pTos->flags = MEM_Int; break; } /* Opcode: FullKey P1 * * ** ** Extract the complete key from the record that cursor P1 is currently ** pointing to and push the key onto the stack as a string. ** ** Compare this opcode to Recno. The Recno opcode extracts the first ** 4 bytes of the key and pushes those bytes onto the stack as an |
︙ | ︙ | |||
3588 3589 3590 3591 3592 3593 3594 | assert( pTos->flags & MEM_Blob ); if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ int nKey = pTos->n; const char *zKey = pTos->z; if( pOp->p2 ){ int res; int len; | < | < | < < | < < | 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 | assert( pTos->flags & MEM_Blob ); if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ int nKey = pTos->n; const char *zKey = pTos->z; if( pOp->p2 ){ int res; int len; /* 'len' is the length of the key minus the rowid at the end */ len = nKey - sqlite3VdbeIdxRowidLen(nKey, zKey); rc = sqlite3BtreeMoveto(pCrsr, zKey, len, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; while( res!=0 && !sqlite3BtreeEof(pCrsr) ){ int c; if( sqlite3VdbeIdxKeyCompare(pC, len, zKey, &c)==SQLITE_OK && c==0 ){ rc = SQLITE_CONSTRAINT; if( pOp->p3 && pOp->p3[0] ){ sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0); } goto abort_due_to_error; } if( res<0 ){ |
︙ | ︙ | |||
3719 3720 3721 3722 3723 3724 3725 | pTos->flags = MEM_Null; } break; } /* Opcode: IdxGT P1 P2 * ** | | | > > > > | | | | > | | | > > | > | 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 | pTos->flags = MEM_Null; } break; } /* Opcode: IdxGT P1 P2 * ** ** The top of the stack is an index entry that omits the ROWID. Compare ** the top of stack against the index that P1 is currently pointing to. ** Ignore the ROWID on the P1 index. ** ** The top of the stack might have fewer columns that P1. ** ** If the P1 index entry is greater than the top of the stack ** then jump to P2. Otherwise fall through to the next instruction. ** In either case, the stack is popped once. */ /* Opcode: IdxGE P1 P2 P3 ** ** The top of the stack is an index entry that omits the ROWID. Compare ** the top of stack against the index that P1 is currently pointing to. ** Ignore the ROWID on the P1 index. ** ** If the P1 index entry is greater than or equal to the top of the stack ** then jump to P2. Otherwise fall through to the next instruction. ** 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 make the opcode work ** like IdxGT except that if the key from the stack is a prefix of ** the key in the cursor, the result is false whereas it would be ** true with IdxGT. */ /* Opcode: IdxLT P1 P2 P3 ** ** The top of the stack is an index entry that omits the ROWID. Compare ** the top of stack against the index that P1 is currently pointing to. ** Ignore the ROWID on the P1 index. ** ** If the P1 index entry is less than the top of the stack ** then jump to P2. Otherwise fall through to the next instruction. ** 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: case OP_IdxGT: case OP_IdxGE: { int i= pOp->p1; BtCursor *pCrsr; Cursor *pC; assert( i>=0 && i<p->nCursor ); assert( pTos>=p->aStack ); if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ int res, rc; assert( pTos->flags & MEM_Blob ); /* Created using OP_Make*Key */ Stringify(pTos, db->enc); assert( pC->deferredMoveto==0 ); *pC->pIncrKey = pOp->p3!=0; assert( pOp->p3==0 || pOp->opcode!=OP_IdxGT ); rc = sqlite3VdbeIdxKeyCompare(pC, pTos->n, pTos->z, &res); *pC->pIncrKey = 0; if( rc!=SQLITE_OK ){ |
︙ | ︙ | |||
3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 | ** ** The index entry is always popped from the stack. */ case OP_IdxIsNull: { int i = pOp->p1; int k, n; const char *z; assert( pTos>=p->aStack ); assert( pTos->flags & MEM_Blob ); z = pTos->z; n = pTos->n; | > > | < < | 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 | ** ** The index entry is always popped from the stack. */ case OP_IdxIsNull: { int i = pOp->p1; int k, n; const char *z; u32 serial_type; assert( pTos>=p->aStack ); assert( pTos->flags & MEM_Blob ); z = pTos->z; n = pTos->n; k = sqlite3GetVarint32(z, &serial_type); for(; k<n && i>0; i--){ k += sqlite3GetVarint32(&z[k], &serial_type); if( serial_type==6 ){ /* Serial type 6 is a NULL */ pc = pOp->p2-1; break; } } Release(pTos); pTos--; break; } /* Opcode: Destroy P1 P2 * |
︙ | ︙ |