Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Added code to iterate through virtual tables. All regression tests pass but the new code is completely untested. (CVS 3219) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
010965433140fbe508a907d861dbad79 |
User & Date: | drh 2006-06-12 21:59:14.000 |
Context
2006-06-13
| ||
01:04 | Progress toward getting the virtual-table code generator to work. (CVS 3220) (check-in: 3532f1340f user: drh tags: trunk) | |
2006-06-12
| ||
21:59 | Added code to iterate through virtual tables. All regression tests pass but the new code is completely untested. (CVS 3219) (check-in: 0109654331 user: drh tags: trunk) | |
16:01 | Add code to invoke the xDestroy method of a virtual table when it is dropped. (CVS 3218) (check-in: f0c7c8d12c user: danielk1977 tags: trunk) | |
Changes
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.170 2006/06/12 21:59:14 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 | const char *zFile, /* Name of the shared library containing extension */ const char *zProc, /* Entry point. Derived from zFile if 0 */ char **pzErrMsg /* Put error message here if not 0 */ ); /* ****** EXPERIMENTAL - subject to change without notice ************** */ typedef struct sqlite3_vtab sqlite3_vtab; typedef struct sqlite3_index_info sqlite3_index_info; typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; typedef struct sqlite3_module sqlite3_module; struct sqlite3_module { int iVersion; const char *zName; void *pAux; int (*xCreate)(sqlite3*, const sqlite3_module *pModule, int argc, char **argv, sqlite3_vtab **ppVTab); | > > > > > > > > > > > > > > > > > | 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 | const char *zFile, /* Name of the shared library containing extension */ const char *zProc, /* Entry point. Derived from zFile if 0 */ char **pzErrMsg /* Put error message here if not 0 */ ); /* ****** EXPERIMENTAL - subject to change without notice ************** ** ** The interface to the virtual-table mechanism is currently considered ** to be experimental. The interface might change in incompatible ways. ** If this is a problem for you, do not use the interface at this time. ** ** When the virtual-table mechanism stablizes, we will declare the ** interface fixed, support it indefinitely, and remove this comment. */ /* ** Structures used by the virtual table interface */ typedef struct sqlite3_vtab sqlite3_vtab; typedef struct sqlite3_index_info sqlite3_index_info; typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; typedef struct sqlite3_module sqlite3_module; /* ** A module is a class of virtual tables. Each module is defined ** by an instance of the following structure. This structure consists ** mostly of methods for the module. */ struct sqlite3_module { int iVersion; const char *zName; void *pAux; int (*xCreate)(sqlite3*, const sqlite3_module *pModule, int argc, char **argv, sqlite3_vtab **ppVTab); |
︙ | ︙ | |||
1539 1540 1541 1542 1543 1544 1545 1546 1547 | int (*xDelete)(sqlite3_vtab *pVTab, sqlite_int64 rowid); int (*xBegin)(sqlite3_vtab *pVTab); int (*xSync)(sqlite3_vtab *pVTab); int (*xCommit)(sqlite3_vtab *pVTab); int (*xRollback)(sqlite3_vtab *pVTab); int (*xIsInTrans)(sqlite3_vtab *pVTab); }; struct sqlite3_index_info { /* Inputs */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | > | | | | | | > > > > | < < | > | | | | | | > > > > > > > | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 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 1619 1620 1621 1622 1623 1624 1625 1626 1627 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 1665 1666 1667 1668 1669 1670 1671 1672 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 | int (*xDelete)(sqlite3_vtab *pVTab, sqlite_int64 rowid); int (*xBegin)(sqlite3_vtab *pVTab); int (*xSync)(sqlite3_vtab *pVTab); int (*xCommit)(sqlite3_vtab *pVTab); int (*xRollback)(sqlite3_vtab *pVTab); int (*xIsInTrans)(sqlite3_vtab *pVTab); }; /* ** The sqlite3_index_info structure and its substructures is used to ** pass information into and receive the reply from the xBestIndex ** method of an sqlite3_module. The fields under **Inputs** are the ** inputs to xBestIndex and are read-only. xBestIndex inserts its ** results into the **Outputs** fields. ** ** The aConstraint[] array records WHERE clause constraints of the ** form: ** ** column OP expr ** ** Where OP is =, <, <=, >, or >=. The particular operator is stored ** in aConstraint[].op. The index of the column is stored in ** aConstraint[].iColumn. aConstraint[].usable is TRUE if the ** expr on the right-hand side can be evaluated (and thus the constraint ** is usable) and false if it cannot. ** ** The optimizer automatically inverts terms of the form "expr OP column" ** and makes other simplificatinos to the WHERE clause in an attempt to ** get as many WHERE clause terms into the form shown above as possible. ** The aConstraint[] array only reports WHERE clause terms in the correct ** form that refer to the particular virtual table being queried. ** ** Information about the ORDER BY clause is stored in aOrderBy[]. ** Each term of aOrderBy records a column of the ORDER BY clause. ** ** The xBestIndex method must fill aConstraintUsage[] with information ** about what parameters to pass to xBestIndex. If argvIndex>0 then ** the right-hand side of the corresponding aConstraint[] is evaluated ** and becomes the argvIndex-th entry in argv. If aConstraintUsage[].omit ** is true, then the constraint is assumed to be fully handled by the ** virtual table and is not checked again by SQLite. ** ** The idxNum value is recorded and passed into xFilter. ** ** The orderByConsumed means that output from xFilter will occur in ** the correct order to satisfy the ORDER BY clause so that no separate ** sorting step is required. ** ** The estimatedCost value is an estimate of the cost of doing the ** particular lookup. A full scan of a table with N entries should have ** a cost of N. A binary search of a table of N entries should have a ** cost of approximately log(N). */ struct sqlite3_index_info { /* Inputs */ const int nConstraint; /* Number of entries in aConstraint */ const struct sqlite3_index_constraint { int iColumn; /* Column on left-hand side of constraint */ unsigned char op; /* Constraint operator */ unsigned char usable; /* True if this constraint is usable */ int iTermOffset; /* Used internally - xBestIndex should ignore */ } *const aConstraint; /* Table of WHERE clause constraints */ const int nOrderBy; /* Number of terms in the ORDER BY clause */ const struct sqlite3_index_orderby { int iColumn; /* Column number */ unsigned char desc; /* True for DESC. False for ASC. */ } *const aOrderBy; /* The ORDER BY clause */ /* Outputs */ struct sqlite3_index_constraint_usage { int argvIndex; /* if >0, constraint is part of argv to xFilter */ unsigned char omit; /* Do not code a test for this constraint */ } *const aConstraintUsage; int idxNum; /* Index number passed to xFilter */ int orderByConsumed; /* True if output is already ordered */ double estimatedCost; /* Estimated cost of using this index */ }; #define SQLITE_INDEX_CONSTRAINT_EQ 2 #define SQLITE_INDEX_CONSTRAINT_GT 4 #define SQLITE_INDEX_CONSTRAINT_LE 8 #define SQLITE_INDEX_CONSTRAINT_LT 16 #define SQLITE_INDEX_CONSTRAINT_GE 32 #define SQLITE_INDEX_CONSTRAINT_MATCH 64 /* ** This routine is used to register a new module name with an SQLite ** connection. Module names must be registered before creating new ** virtual tables on the module, or before using preexisting virtual ** tables of the module. */ int sqlite3_create_module( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ const sqlite3_module * /* Methods for the module */ ); /* ** Every module implementation uses a subclass of the following structure ** to describe a particular instance of the module. Each subclass will ** be taylored to the specific needs of the module implementation. The ** purpose of this superclass is to define certain fields that are common ** to all module implementations. */ struct sqlite3_vtab { sqlite3_module *pModule; /* The module for this virtual table */ /* Virtual table implementations will typically add additional fields */ }; /* Every module implementation uses a subclass of the following structure ** to describe cursors that point into the virtual table and are used ** to loop through the virtual table. Cursors are created using the ** xOpen method of the module. Each module implementation will define ** the content of a cursor structure to suit its own needs. ** ** This superclass exists in order to define fields of the cursor that ** are common to all implementations. */ struct sqlite3_vtab_cursor { sqlite3_vtab *pVtab; /* Virtual table of this cursor */ /* Virtual table implementations will typically add additional fields */ }; /* ** The xCreate and xConnect methods of a module use the following API ** to declare the format (the names and datatypes of the columns) of ** the virtual tables they implement. */ int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable); /* ** The interface to the virtual-table mechanism defined above (back up ** to a comment remarkably similar to this one) is currently considered ** to be experimental. The interface might change in incompatible ways. ** If this is a problem for you, do not use the interface at this time. ** ** When the virtual-table mechanism stablizes, we will declare the ** interface fixed, support it indefinitely, and remove this comment. ** ****** EXPERIMENTAL - subject to change without notice ************** */ /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT # undef double #endif #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif #endif |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.502 2006/06/12 21:59:14 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Extra interface definitions for those who need them */ |
︙ | ︙ | |||
1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 | int brk; /* Jump here to break out of the loop */ int cont; /* Jump here to continue with the next loop cycle */ int top; /* First instruction of interior of the loop */ int op, p1, p2; /* Opcode used to terminate the loop */ int nEq; /* Number of == or IN constraints on this loop */ int nIn; /* Number of IN operators constraining this loop */ int *aInLoop; /* Loop terminators for IN operators */ }; /* ** The WHERE clause processing routine has two halves. The ** first part does the start of the WHERE loop and the second ** half does the tail of the WHERE loop. An instance of ** this structure is returned by the first half and passed | > | 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 | int brk; /* Jump here to break out of the loop */ int cont; /* Jump here to continue with the next loop cycle */ int top; /* First instruction of interior of the loop */ int op, p1, p2; /* Opcode used to terminate the loop */ int nEq; /* Number of == or IN constraints on this loop */ int nIn; /* Number of IN operators constraining this loop */ int *aInLoop; /* Loop terminators for IN operators */ sqlite3_index_info *pIdxInfo; /* Index information for virtual tables */ }; /* ** The WHERE clause processing routine has two halves. The ** first part does the start of the WHERE loop and the second ** half does the tail of the WHERE loop. An instance of ** this structure is returned by the first half and passed |
︙ | ︙ |
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.554 2006/06/12 21:59:14 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 | ** ** P3 is the name of a virtual table in database P1. Call the xDestroy method ** of that table. */ case OP_VDestroy: { rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p3); break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ /* An other opcode is illegal... */ default: { assert( 0 ); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 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 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 | ** ** P3 is the name of a virtual table in database P1. Call the xDestroy method ** of that table. */ case OP_VDestroy: { rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p3); break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VOpen P1 * P3 ** ** P3 is a pointer to a virtual table object, an sqlite3_vtab structure. ** P1 is a cursor number. This opcode opens a cursor to the virtual ** table and stores that cursor in P1. */ case OP_VOpen: { break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VFilter P1 P2 * ** ** P1 is a cursor opened using VOpen. P2 is an address to jump to if ** the filtered result set is empty. ** ** This opcode invokes the xFilter method on the virtual table specified ** by P1. The index number parameter to xFilter is the top of the stack. ** Next down on the stack is the argc parameter. Beneath the ** next of stack are argc additional parameters which are passed to ** xFilter as argv. The index number, argc, and all argv stack values ** are popped from the stack before this instruction completes. ** ** A jump is made to P2 if the result set after filtering would be ** empty. */ case OP_VFilter: { break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VRowid P1 * * ** ** Push an integer onto the stack which is the rowid of ** the virtual-table that the P1 cursor is pointing to. */ case OP_VRowid: { break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VColumn P1 P2 * ** ** Push onto the stack the value of the P2-th column of ** the row of the virtual-table that the P1 cursor is pointing to. */ case OP_VColumn: { break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VNext P1 P2 * ** ** Advance virtual table P1 to the next row in its result set and ** jump to instruction P2. Or, if the virtual table has reached ** the end of its result set, then fall through to the next instruction. */ case OP_VNext: { break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ /* An other opcode is illegal... */ default: { assert( 0 ); |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
79 80 81 82 83 84 85 86 87 88 89 90 91 92 | int nData; /* Number of bytes in pData */ char *pData; /* Data for a NEW or OLD pseudo-table */ i64 iKey; /* Key for the NEW or OLD pseudo-table row */ u8 *pIncrKey; /* Pointer to pKeyInfo->incrKey */ KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ int nField; /* Number of fields in the header */ i64 seqCount; /* Sequence counter */ /* Cached information about the header for the data record that the ** cursor is currently pointing to. Only valid if cacheValid is true. ** aRow might point to (ephemeral) data for the current row, or it might ** be NULL. */ int cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ | > > > | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | int nData; /* Number of bytes in pData */ char *pData; /* Data for a NEW or OLD pseudo-table */ i64 iKey; /* Key for the NEW or OLD pseudo-table row */ u8 *pIncrKey; /* Pointer to pKeyInfo->incrKey */ KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ int nField; /* Number of fields in the header */ i64 seqCount; /* Sequence counter */ #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ #endif /* Cached information about the header for the data record that the ** cursor is currently pointing to. Only valid if cacheValid is true. ** aRow might point to (ephemeral) data for the current row, or it might ** be NULL. */ int cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
828 829 830 831 832 833 834 835 836 837 838 839 840 841 | } if( pCx->pCursor ){ sqlite3BtreeCloseCursor(pCx->pCursor); } if( pCx->pBt ){ sqlite3BtreeClose(pCx->pBt); } sqliteFree(pCx->pData); sqliteFree(pCx->aType); sqliteFree(pCx); } /* ** Close all cursors | > > > > > > > > | 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 | } if( pCx->pCursor ){ sqlite3BtreeCloseCursor(pCx->pCursor); } if( pCx->pBt ){ sqlite3BtreeClose(pCx->pBt); } #ifndef SQLITE_OMIT_VIRTUALTABLE if( pCx->pVtabCursor ){ sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor; sqlite3_vtab *pVtab = pVtabCursor->pVtab; sqlite3_module *pModule = pVtab->pModule; pModule->xClose(pVtabCursor); } #endif sqliteFree(pCx->pData); sqliteFree(pCx->aType); sqliteFree(pCx); } /* ** Close all cursors |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** ** $Id: where.c,v 1.211 2006/06/12 21:59:14 drh Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) |
︙ | ︙ | |||
167 168 169 170 171 172 173 174 175 176 177 178 179 180 | #define WHERE_COLUMN_IN 0x0040 /* x IN (...) */ #define WHERE_TOP_LIMIT 0x0100 /* x<EXPR or x<=EXPR constraint */ #define WHERE_BTM_LIMIT 0x0200 /* x>EXPR or x>=EXPR constraint */ #define WHERE_IDX_ONLY 0x0800 /* Use index only - omit table */ #define WHERE_ORDERBY 0x1000 /* Output will appear in correct order */ #define WHERE_REVERSE 0x2000 /* Scan in reverse order */ #define WHERE_UNIQUE 0x4000 /* Selects no more than one row */ /* ** Initialize a preallocated WhereClause structure. */ static void whereClauseInit(WhereClause *pWC, Parse *pParse){ pWC->pParse = pParse; pWC->nTerm = 0; | > | 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | #define WHERE_COLUMN_IN 0x0040 /* x IN (...) */ #define WHERE_TOP_LIMIT 0x0100 /* x<EXPR or x<=EXPR constraint */ #define WHERE_BTM_LIMIT 0x0200 /* x>EXPR or x>=EXPR constraint */ #define WHERE_IDX_ONLY 0x0800 /* Use index only - omit table */ #define WHERE_ORDERBY 0x1000 /* Output will appear in correct order */ #define WHERE_REVERSE 0x2000 /* Scan in reverse order */ #define WHERE_UNIQUE 0x4000 /* Selects no more than one row */ #define WHERE_VIRTUALTABLE 0x8000 /* Use virtual-table processing */ /* ** Initialize a preallocated WhereClause structure. */ static void whereClauseInit(WhereClause *pWC, Parse *pParse){ pWC->pParse = pParse; pWC->nTerm = 0; |
︙ | ︙ | |||
880 881 882 883 884 885 886 887 888 889 890 891 892 893 | while( N>x ){ logN += 1; x *= 10; } return logN; } /* ** Find the best index for accessing a particular table. Return a pointer ** to the index, flags that describe how the index should be used, the ** number of equality constraints, and the "cost" for this index. ** ** The lowest cost index wins. The cost is an estimate of the amount of ** CPU and disk I/O need to process the request using the selected index. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 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 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 | while( N>x ){ logN += 1; x *= 10; } return logN; } #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Compute the best index for a virtual table */ static double bestVirtualIndex( Parse *pParse, /* The parsing context */ WhereClause *pWC, /* The WHERE clause */ struct SrcList_item *pSrc, /* The FROM clause term to search */ Bitmask notReady, /* Mask of cursors that are not available */ ExprList *pOrderBy, /* The order by clause */ int orderByUsable, /* True if we can potential sort */ sqlite3_index_info **ppIdxInfo /* Index information passed to xBestIndex */ ){ Table *pTab = pSrc->pTab; sqlite3_index_info *pIdxInfo; struct sqlite3_index_constraint *pIdxCons; struct sqlite3_index_orderby *pIdxOrderBy; struct sqlite3_index_constraint_usage *pUsage; WhereTerm *pTerm; int i, j; int nOrderBy; /* If the sqlite3_index_info structure has not been previously ** allocated and initialized for this virtual table, then allocate ** and initialize it now */ pIdxInfo = *ppIdxInfo; if( pIdxInfo==0 ){ WhereTerm *pTerm; int nTerm; /* Count the number of possible WHERE clause constraints referring ** to this virtual table */ for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ if( pTerm->leftCursor != pSrc->iCursor ) continue; if( pTerm->eOperator==WO_IN ) continue; nTerm++; } /* If the ORDER BY clause contains only columns in the current ** virtual table then allocate space for the aOrderBy part of ** the sqlite3_index_info structure. */ nOrderBy = 0; if( pOrderBy ){ for(i=0; i<pOrderBy->nExpr; i++){ Expr *pExpr = pOrderBy->a[i].pExpr; if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break; } if( i==pOrderBy->nExpr ){ nOrderBy = pOrderBy->nExpr; } } /* Allocate the sqlite3_index_info structure */ pIdxInfo = sqliteMalloc( sizeof(*pIdxInfo) + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm + sizeof(*pIdxOrderBy)*nOrderBy ); if( pIdxInfo==0 ){ sqlite3ErrorMsg(pParse, "out of memory"); return 0.0; } *ppIdxInfo = pIdxInfo; /* Initialize the structure. The sqlite3_index_info structure contains ** many fields that are declared "const" to prevent xBestIndex from ** changing them. We have to do some funky casting in order to ** initialize those fields. */ pIdxCons = (struct sqlite3_index_constraint*)&pIdxInfo[1]; pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm]; pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy]; *(int*)&pIdxInfo->nConstraint = nTerm; *(int*)&pIdxInfo->nOrderBy = nOrderBy; *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint = pIdxCons; *(struct sqlite3_index_orderby**)&pIdxInfo->aOrderBy = pIdxOrderBy; *(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage = pUsage; for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ if( pTerm->leftCursor != pSrc->iCursor ) continue; if( pTerm->eOperator==WO_IN ) continue; pIdxCons[j].iColumn = pTerm->leftColumn; pIdxCons[j].iTermOffset = i; pIdxCons[j].op = pTerm->eOperator; assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ ); assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT ); assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE ); assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT ); assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE ); assert( pTerm->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE) ); j++; } for(i=0; i<nOrderBy; i++){ Expr *pExpr = pOrderBy->a[i].pExpr; pIdxOrderBy[i].iColumn = pExpr->iColumn; pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder; } } /* The module name must be defined */ assert( pTab->azModuleArg && pTab->azModuleArg[0] ); if( pTab->pVtab==0 ){ sqlite3ErrorMsg(pParse, "undefined module %s for table %s", pTab->azModuleArg[0], pTab->zName); return 0.0; } /* Set the aConstraint[].usable fields and initialize all ** output variables */ pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; pUsage = pIdxInfo->aConstraintUsage; for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){ j = pIdxCons->iTermOffset; pTerm = &pWC->a[j]; pIdxCons->usable = (pTerm->prereqRight & notReady)==0; } memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint); pIdxInfo->idxNum = 0; pIdxInfo->orderByConsumed = 0; pIdxInfo->estimatedCost = SQLITE_BIG_DBL; nOrderBy = pIdxInfo->nOrderBy; if( pIdxInfo->nOrderBy && !orderByUsable ){ *(int*)pIdxInfo->nOrderBy = 0; } pTab->pVtab->pModule->xBestIndex(pTab->pVtab, pIdxInfo); *(int*)pIdxInfo->nOrderBy = nOrderBy; return pIdxInfo->estimatedCost; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ /* ** Find the best index for accessing a particular table. Return a pointer ** to the index, flags that describe how the index should be used, the ** number of equality constraints, and the "cost" for this index. ** ** The lowest cost index wins. The cost is an estimate of the amount of ** CPU and disk I/O need to process the request using the selected index. |
︙ | ︙ | |||
1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 | */ char sqlite3_query_plan[BMS*2*40]; /* Text of the join */ static int nQPlan = 0; /* Next free slow in _query_plan[] */ #endif /* SQLITE_TEST */ /* ** Generate the beginning of the loop used for WHERE clause processing. ** The return value is a pointer to an opaque structure that contains ** information needed to terminate the loop. Later, the calling routine ** should invoke sqlite3WhereEnd() with the return value of this function ** in order to complete the WHERE clause processing. | > > > > > > > > > > > > > | 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 | */ char sqlite3_query_plan[BMS*2*40]; /* Text of the join */ static int nQPlan = 0; /* Next free slow in _query_plan[] */ #endif /* SQLITE_TEST */ /* ** Free a WhereInfo structure */ static void whereInfoFree(WhereInfo *pWInfo){ if( pWInfo ){ int i; for(i=0; i<pWInfo->nLevel; i++){ sqliteFree(pWInfo->a[i].pIdxInfo); } sqliteFree(pWInfo); } } /* ** Generate the beginning of the loop used for WHERE clause processing. ** The return value is a pointer to an opaque structure that contains ** information needed to terminate the loop. Later, the calling routine ** should invoke sqlite3WhereEnd() with the return value of this function ** in order to complete the WHERE clause processing. |
︙ | ︙ | |||
1523 1524 1525 1526 1527 1528 1529 | || (j>0 && (pTabItem[-1].jointype & (JT_LEFT|JT_CROSS))!=0); if( once && doNotReorder ) break; m = getMask(&maskSet, pTabItem->iCursor); if( (m & notReady)==0 ){ if( j==iFrom ) iFrom++; continue; } | > > > > > > > > > > > > | | | > | 1670 1671 1672 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 | || (j>0 && (pTabItem[-1].jointype & (JT_LEFT|JT_CROSS))!=0); if( once && doNotReorder ) break; m = getMask(&maskSet, pTabItem->iCursor); if( (m & notReady)==0 ){ if( j==iFrom ) iFrom++; continue; } assert( pTabItem->pTab ); #ifndef SQLITE_OMIT_VIRTUALTABLE if( pTabItem->pTab->isVirtual ){ cost = bestVirtualIndex(pParse, &wc, pTabItem, notReady, ppOrderBy ? *ppOrderBy : 0, i==0, &pLevel->pIdxInfo); flags = WHERE_VIRTUALTABLE; pIdx = 0; nEq = 0; }else #endif { cost = bestIndex(pParse, &wc, pTabItem, notReady, (i==0 && ppOrderBy) ? *ppOrderBy : 0, &pIdx, &flags, &nEq); } if( cost<lowestCost ){ once = 1; lowestCost = cost; pBest = pIdx; bestFlags = flags; bestNEq = nEq; bestJ = j; |
︙ | ︙ | |||
1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 | zMsg = sqlite3MPrintf("%z AS %s", zMsg, pItem->zAlias); } if( (pIx = pLevel->pIdx)!=0 ){ zMsg = sqlite3MPrintf("%z WITH INDEX %s", zMsg, pIx->zName); }else if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){ zMsg = sqlite3MPrintf("%z USING PRIMARY KEY", zMsg); } if( pLevel->flags & WHERE_ORDERBY ){ zMsg = sqlite3MPrintf("%z ORDER BY", zMsg); } sqlite3VdbeOp3(v, OP_Explain, i, pLevel->iFrom, zMsg, P3_DYNAMIC); } #endif /* SQLITE_OMIT_EXPLAIN */ pTabItem = &pTabList->a[pLevel->iFrom]; pTab = pTabItem->pTab; iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); if( pTab->isEphem || pTab->pSelect ) continue; if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){ sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, OP_OpenRead); if( pTab->nCol<(sizeof(Bitmask)*8) ){ Bitmask b = pTabItem->colUsed; int n = 0; for(; b; b=b>>1, n++){} sqlite3VdbeChangeP2(v, sqlite3VdbeCurrentAddr(v)-1, n); | > > > > > > > > > > > | 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 1774 1775 1776 1777 1778 1779 1780 1781 1782 | zMsg = sqlite3MPrintf("%z AS %s", zMsg, pItem->zAlias); } if( (pIx = pLevel->pIdx)!=0 ){ zMsg = sqlite3MPrintf("%z WITH INDEX %s", zMsg, pIx->zName); }else if( pLevel->flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){ zMsg = sqlite3MPrintf("%z USING PRIMARY KEY", zMsg); } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( pLevel->pIdxInfo ){ zMsg = sqlite3MPrintf("%z VIRTUAL TABLE INDEX %d", pLevel->pIdxInfo->idxNum); } #endif if( pLevel->flags & WHERE_ORDERBY ){ zMsg = sqlite3MPrintf("%z ORDER BY", zMsg); } sqlite3VdbeOp3(v, OP_Explain, i, pLevel->iFrom, zMsg, P3_DYNAMIC); } #endif /* SQLITE_OMIT_EXPLAIN */ pTabItem = &pTabList->a[pLevel->iFrom]; pTab = pTabItem->pTab; iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); if( pTab->isEphem || pTab->pSelect ) continue; #ifndef SQLITE_OMIT_VIRTUALTABLE if( pLevel->pIdxInfo ){ sqlite3VdbeAddOp(v, OP_VOpen, 0, 0); /***** Fix Me *****/ }else #endif if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){ sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, OP_OpenRead); if( pTab->nCol<(sizeof(Bitmask)*8) ){ Bitmask b = pTabItem->colUsed; int n = 0; for(; b; b=b>>1, n++){} sqlite3VdbeChangeP2(v, sqlite3VdbeCurrentAddr(v)-1, n); |
︙ | ︙ | |||
1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 | if( pLevel->iFrom>0 && (pTabItem[-1].jointype & JT_LEFT)!=0 ){ if( !pParse->nMem ) pParse->nMem++; pLevel->iLeftJoin = pParse->nMem++; sqlite3VdbeAddOp(v, OP_MemInt, 0, pLevel->iLeftJoin); VdbeComment((v, "# init LEFT JOIN no-match flag")); } if( pLevel->flags & WHERE_ROWID_EQ ){ /* Case 1: We can directly reference a single row using an ** equality comparison against the ROWID field. Or ** we reference multiple rows using a "rowid IN (...)" ** construct. */ pTerm = findTerm(&wc, iCur, -1, notReady, WO_EQ|WO_IN, 0); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 | if( pLevel->iFrom>0 && (pTabItem[-1].jointype & JT_LEFT)!=0 ){ if( !pParse->nMem ) pParse->nMem++; pLevel->iLeftJoin = pParse->nMem++; sqlite3VdbeAddOp(v, OP_MemInt, 0, pLevel->iLeftJoin); VdbeComment((v, "# init LEFT JOIN no-match flag")); } #ifndef SQLITE_OMIT_VIRTUALTABLE if( pLevel->pIdxInfo ){ /* Case 0: That table is a virtual-table. Use the VFilter and VNext. */ sqlite3_index_info *pIdxInfo = pLevel->pIdxInfo; for(i=1; i<=pIdxInfo->nConstraint; i++){ int j; for(j=0; j<pIdxInfo->nConstraint; j++){ if( pIdxInfo->aConstraintUsage[j].argvIndex==i ){ sqlite3ExprCode(pParse, wc.a[j].pExpr->pRight); break; } } if( j==pIdxInfo->nConstraint ) break; } sqlite3VdbeAddOp(v, OP_VFilter, iCur, pIdxInfo->idxNum); if( i>1 ){ sqlite3VdbeAddOp(v, OP_Pop, i-1, 0); } for(i=0; i<pIdxInfo->nConstraint; i++){ if( pIdxInfo->aConstraintUsage[i].omit ){ disableTerm(pLevel, &wc.a[i]); } } pLevel->op = OP_VNext; }else #endif /* SQLITE_OMIT_VIRTUALTABLE */ if( pLevel->flags & WHERE_ROWID_EQ ){ /* Case 1: We can directly reference a single row using an ** equality comparison against the ROWID field. Or ** we reference multiple rows using a "rowid IN (...)" ** construct. */ pTerm = findTerm(&wc, iCur, -1, notReady, WO_EQ|WO_IN, 0); |
︙ | ︙ | |||
2028 2029 2030 2031 2032 2033 2034 | pWInfo->iContinue = cont; whereClauseClear(&wc); return pWInfo; /* Jump here if malloc fails */ whereBeginNoMem: whereClauseClear(&wc); | | | 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 | pWInfo->iContinue = cont; whereClauseClear(&wc); return pWInfo; /* Jump here if malloc fails */ whereBeginNoMem: whereClauseClear(&wc); whereInfoFree(pWInfo); return 0; } /* ** Generate the end of the WHERE loop. See comments on ** sqlite3WhereBegin() for additional information. */ |
︙ | ︙ | |||
2130 2131 2132 2133 2134 2135 2136 | } } } } /* Final cleanup */ | | | 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 | } } } } /* Final cleanup */ whereInfoFree(pWInfo); return; } |