Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Work toward combining the OP_MakeKey, OP_MakeIdxKey, and OP_MakeRecord opcodes into one. The work is incomplete. (CVS 1524) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
165d69a04cca719dec2b042117f848f1 |
User & Date: | drh 2004-06-02 01:22:02.000 |
Context
2004-06-02
| ||
06:30 | Fix a segfault in sqlite3OsLock() (CVS 1525) (check-in: 51348b82c4 user: danielk1977 tags: trunk) | |
01:22 | Work toward combining the OP_MakeKey, OP_MakeIdxKey, and OP_MakeRecord opcodes into one. The work is incomplete. (CVS 1524) (check-in: 165d69a04c user: drh tags: trunk) | |
00:41 | Remove the sqlite3_libencoding() api and the ISO8859 encoding option. (CVS 1523) (check-in: b53640ed22 user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** 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 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* ** $Id: btree.c,v 1.155 2004/06/02 01:22:02 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: ** "Sorting And Searching", pages 473-480. Addison-Wesley ** Publishing Company, Reading, Massachusetts. |
︙ | ︙ | |||
1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 | releasePage(pCur->pPage); sqliteFree(pCur); } unlockBtreeIfUnused(pBt); return rc; } /* ** Change the value of the comparison function used by a cursor. */ void sqlite3BtreeSetCompare( BtCursor *pCur, /* The cursor to whose comparison function is changed */ int(*xCmp)(void*,int,const void*,int,const void*), /* New comparison func */ void *pArg /* First argument to xCmp() */ ){ pCur->xCompare = xCmp ? xCmp : dfltCompare; pCur->pArg = pArg; } /* ** Close a cursor. The read lock on the database file is released ** when the last cursor is closed. */ int sqlite3BtreeCloseCursor(BtCursor *pCur){ Btree *pBt = pCur->pBt; | > > | 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 | releasePage(pCur->pPage); sqliteFree(pCur); } unlockBtreeIfUnused(pBt); return rc; } #if 0 /* Not Used */ /* ** Change the value of the comparison function used by a cursor. */ void sqlite3BtreeSetCompare( BtCursor *pCur, /* The cursor to whose comparison function is changed */ int(*xCmp)(void*,int,const void*,int,const void*), /* New comparison func */ void *pArg /* First argument to xCmp() */ ){ pCur->xCompare = xCmp ? xCmp : dfltCompare; pCur->pArg = pArg; } #endif /* ** Close a cursor. The read lock on the database file is released ** when the last cursor is closed. */ int sqlite3BtreeCloseCursor(BtCursor *pCur){ Btree *pBt = pCur->pBt; |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
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 header file defines the interface that the SQLite library ** presents to client programs. ** | | | 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 header file defines the interface that the SQLite library ** presents to client programs. ** ** @(#) $Id: sqlite.h.in,v 1.91 2004/06/02 01:22:02 drh Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
33 34 35 36 37 38 39 | /* ** The version string is also compiled into the library so that a program ** can check to make sure that the lib*.a file and the *.h file are from ** the same version. */ extern const char sqlite3_version[]; | < < < < < < < < < < < < < < < | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | /* ** The version string is also compiled into the library so that a program ** can check to make sure that the lib*.a file and the *.h file are from ** the same version. */ extern const char sqlite3_version[]; /* ** Each open sqlite database is represented by an instance of the ** following opaque structure. */ typedef struct sqlite sqlite; typedef struct sqlite sqlite3; |
︙ | ︙ |
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.355 2004/06/02 01:22:02 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
218 219 220 221 222 223 224 | */ static Sorter *Merge(Sorter *pLeft, Sorter *pRight, KeyInfo *pKeyInfo){ Sorter sHead; Sorter *pTail; pTail = &sHead; pTail->pNext = 0; while( pLeft && pRight ){ | | | < | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | */ static Sorter *Merge(Sorter *pLeft, Sorter *pRight, KeyInfo *pKeyInfo){ Sorter sHead; Sorter *pTail; pTail = &sHead; pTail->pNext = 0; while( pLeft && pRight ){ int c = sqlite3VdbeRecordCompare(pKeyInfo, pLeft->nKey, pLeft->zKey, pRight->nKey, pRight->zKey); if( c<=0 ){ pTail->pNext = pLeft; pLeft = pLeft->pNext; }else{ pTail->pNext = pRight; pRight = pRight->pNext; } |
︙ | ︙ | |||
2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 | ** '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: ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | < | < | 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 | ** 'n' NUMERIC ** 'i' INTEGER ** 't' TEXT ** 'o' NONE ** ** If P3 is NULL then all index fields have the affinity NONE. */ /* Opcode MakeRecord P1 P2 P3 ** ** Convert the top abs(P1) entries of the stack into a single entry ** suitable for use as a data record in a database table or as a key ** in an index. The details of the format are irrelavant as long as ** the OP_Column opcode can decode the record later and as long as the ** sqlite3VdbeRecordCompare function will correctly compare two encoded ** records. Refer to source code comments for the details of the record ** format. ** ** The original stack entries are popped from the stack if P1>0 but ** remain on the stack if P1<0. ** ** If P2 is not zero and one or more of the entries are NULL, then jump ** to P2. This feature can be used to skip a uniqueness test on indices. ** ** 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: ** ** ------------------------------------------------------------------------ ** | hdr-size | 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 ** hdr-size field is also a varint which is the offset from the beginning ** of the record to data0. */ int nField = pOp->p1; unsigned char *zNewRecord; unsigned char *zCsr; char *zAffinity; Mem *pRec; Mem *pRowid; |
︙ | ︙ | |||
2447 2448 2449 2450 2451 2452 2453 | assert( i>=0 ); if( expandCursorArraySize(p, i) ) goto no_mem; pCur = p->apCsr[i]; sqlite3VdbeCleanupCursor(pCur); pCur->nullRow = 1; if( pX==0 ) break; do{ | | | < < | | 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 | assert( i>=0 ); if( expandCursorArraySize(p, i) ) goto no_mem; pCur = p->apCsr[i]; sqlite3VdbeCleanupCursor(pCur); pCur->nullRow = 1; if( pX==0 ) break; do{ /* We always provide a key comparison function. If the table being ** opened is of type INTKEY, the comparision function will be ignored. */ rc = sqlite3BtreeCursor(pX, p2, wrFlag, sqlite3VdbeRecordCompare, pOp->p3, &pCur->pCursor); pCur->pKeyInfo = (KeyInfo*)pOp->p3; if( pCur->pKeyInfo ){ pCur->pIncrKey = &pCur->pKeyInfo->incrKey; pCur->pKeyInfo->enc = p->db->enc; }else{ pCur->pIncrKey = &pCur->bogusIncrKey; |
︙ | ︙ | |||
2538 2539 2540 2541 2542 2543 2544 | */ if( pOp->p3 ){ int pgno; assert( pOp->p3type==P3_KEYINFO ); rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA); if( rc==SQLITE_OK ){ assert( pgno==MASTER_ROOT+1 ); | | | 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 | */ if( pOp->p3 ){ int pgno; assert( pOp->p3type==P3_KEYINFO ); rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA); if( rc==SQLITE_OK ){ assert( pgno==MASTER_ROOT+1 ); rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, sqlite3VdbeRecordCompare, pOp->p3, &pCx->pCursor); pCx->pKeyInfo = (KeyInfo*)pOp->p3; pCx->pKeyInfo->enc = p->db->enc; pCx->pIncrKey = &pCx->pKeyInfo->incrKey; } }else{ rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, 0, &pCx->pCursor); |
︙ | ︙ | |||
3158 3159 3160 3161 3162 3163 3164 | /* 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. | < < < < < | 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 | /* 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: { int i = pOp->p1; Cursor *pC; assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; pC->keyAsData = pOp->p2; break; } /* Opcode: RowData P1 * * ** ** Push onto the stack the complete row data for cursor P1. ** There is no interpretation of the data. It is just copied |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
343 344 345 346 347 348 349 | int sqlite3VdbeSerialPut(unsigned char*, Mem*); int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); int sqlite3VdbeIdxKeyCompare(Cursor*, int , const unsigned char*, int*); int sqlite3VdbeIdxRowid(BtCursor *, i64 *); int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); | | < | 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 | int sqlite3VdbeSerialPut(unsigned char*, Mem*); int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); int sqlite3VdbeIdxKeyCompare(Cursor*, int , const unsigned char*, int*); int sqlite3VdbeIdxRowid(BtCursor *, i64 *); int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); int sqlite3VdbeRecordCompare(void*,int,const void*,int, const void*); int sqlite3VdbeIdxRowidLen(int,const u8*); int sqlite3VdbeExec(Vdbe*); int sqlite3VdbeList(Vdbe*); int sqlite3VdbeChangeEncoding(Mem *, int); int sqlite3VdbeMemCopy(Mem*, const Mem*); int sqlite3VdbeMemNulTerminate(Mem*); int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, int); |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
1319 1320 1321 1322 1323 1324 1325 | pMem->flags = MEM_Blob | MEM_Ephem; } } return len; } /* | < < < < < < < < < < < < < < < < < < < < < < | | < < < | | | 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 | pMem->flags = MEM_Blob | MEM_Ephem; } } return len; } /* ** This function compares the two table rows or index records specified by ** {nKey1, pKey1} and {nKey2, pKey2}, returning a negative, zero ** or positive integer if {nKey1, pKey1} is less than, equal to or ** greater than {nKey2, pKey2}. Both Key1 and Key2 must be byte strings ** composed by the OP_MakeRecord opcode of the VDBE. */ int sqlite3VdbeRecordCompare( void *userData, int nKey1, const void *pKey1, int nKey2, const void *pKey2 ){ KeyInfo *pKeyInfo = (KeyInfo*)userData; u32 d1, d2; /* Offset into aKey[] of next data element */ u32 idx1, idx2; /* Offset into aKey[] of next header element */ |
︙ | ︙ | |||
1425 1426 1427 1428 1429 1430 1431 | rc = -rc; } return rc; } /* | | > > | | | | | 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 | rc = -rc; } return rc; } /* ** The argument is an index entry composed using the OP_MakeRecord opcode. ** The last entry in this record should be an integer (specifically ** an integer rowid). This routine returns the number of bytes in ** that integer. */ int sqlite3VdbeIdxRowidLen(int nKey, const u8 *aKey){ u32 szHdr; /* Size of the header */ u32 typeRowid; /* Serial type of the rowid */ sqlite3GetVarint32(aKey, &szHdr); sqlite3GetVarint32(&aKey[szHdr-1], &typeRowid); return sqlite3VdbeSerialTypeLen(typeRowid); } /* ** pCur points at an index entry created using the OP_MakeRecord opcode. ** Read the rowid (the last field in the record) and store it in *rowid. ** Return SQLITE_OK if everything works, or an error code otherwise. */ int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){ u64 nCellKey; int rc; u32 szHdr; /* Size of the header */ u32 typeRowid; /* Serial type of the rowid */ u32 lenRowid; /* Size of the rowid */ |
︙ | ︙ | |||
1501 1502 1503 1504 1505 1506 1507 | return SQLITE_OK; } rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m); if( rc ){ return rc; } lenRowid = sqlite3VdbeIdxRowidLen(m.n, m.z); | | | 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 | return SQLITE_OK; } rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m); if( rc ){ return rc; } lenRowid = sqlite3VdbeIdxRowidLen(m.n, m.z); *res = sqlite3VdbeRecordCompare(pC->pKeyInfo, m.n-lenRowid, m.z, nKey, pKey); if( m.flags & MEM_Dyn ){ sqliteFree(m.z); } return SQLITE_OK; } |