Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Begin adding the failsafe() macro. (CVS 5383) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
8aae4fe7e702b7636fba1fd609a0ca22 |
User & Date: | drh 2008-07-09 13:28:54.000 |
Context
2008-07-09
| ||
14:47 | Add a test case to join.test. No code changes, no bugs found. (CVS 5384) (check-in: 417aa1580a user: danielk1977 tags: trunk) | |
13:28 | Begin adding the failsafe() macro. (CVS 5383) (check-in: 8aae4fe7e7 user: drh tags: trunk) | |
11:49 | Coverage testing for balance_quick() and balance_deeper(). (CVS 5382) (check-in: 491f8f9613 user: danielk1977 tags: trunk) | |
Changes
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.473 2008/07/09 13:28:54 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #ifdef SQLITE_ENABLE_FTS3 # include "fts3.h" #endif |
︙ | ︙ | |||
575 576 577 578 579 580 581 | ** ** This routine is called when an operation failed with a lock. ** If this routine returns non-zero, the lock is retried. If it ** returns 0, the operation aborts with an SQLITE_BUSY error. */ int sqlite3InvokeBusyHandler(BusyHandler *p){ int rc; | > | | 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 | ** ** This routine is called when an operation failed with a lock. ** If this routine returns non-zero, the lock is retried. If it ** returns 0, the operation aborts with an SQLITE_BUSY error. */ int sqlite3InvokeBusyHandler(BusyHandler *p){ int rc; failsafe( p==0, 0x912aaf8d, {return 0;}) if( p->xFunc==0 || p->nBusy<0 ) return 0; rc = p->xFunc(p->pArg, p->nBusy); if( rc==0 ){ p->nBusy = -1; }else{ p->nBusy++; } return rc; |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
26 27 28 29 30 31 32 | ** on how SQLite interfaces are suppose to operate. ** ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | ** on how SQLite interfaces are suppose to operate. ** ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** ** @(#) $Id: sqlite.h.in,v 1.365 2008/07/09 13:28:54 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++. |
︙ | ︙ | |||
6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 | */ #define SQLITE_STATUS_MEMORY_USED 0 #define SQLITE_STATUS_PAGECACHE_USED 1 #define SQLITE_STATUS_PAGECACHE_OVERFLOW 2 #define SQLITE_STATUS_SCRATCH_USED 3 #define SQLITE_STATUS_SCRATCH_OVERFLOW 4 #define SQLITE_STATUS_MALLOC_SIZE 5 /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT | > | 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 | */ #define SQLITE_STATUS_MEMORY_USED 0 #define SQLITE_STATUS_PAGECACHE_USED 1 #define SQLITE_STATUS_PAGECACHE_OVERFLOW 2 #define SQLITE_STATUS_SCRATCH_USED 3 #define SQLITE_STATUS_SCRATCH_OVERFLOW 4 #define SQLITE_STATUS_MALLOC_SIZE 5 #define SQLITE_STATUS_FAILSAFE 6 /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT |
︙ | ︙ |
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.739 2008/07/09 13:28:54 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Include the configuration header output by 'configure' if we're using the ** autoconf-based build |
︙ | ︙ | |||
58 59 60 61 62 63 64 65 66 67 68 69 70 71 | #ifdef SQLITE_COVERAGE_TEST void sqlite3Coverage(int); # define testcase(X) if( X ){ sqlite3Coverage(__LINE__); } #else # define testcase(X) #endif /* ** The macro unlikely() is a hint that surrounds a boolean ** expression that is usually false. Macro likely() surrounds ** a boolean expression that is usually true. GCC is able to ** use these hints to generate better code, sometimes. */ | > > > > > > > > > > > > > > > > > > > > | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | #ifdef SQLITE_COVERAGE_TEST void sqlite3Coverage(int); # define testcase(X) if( X ){ sqlite3Coverage(__LINE__); } #else # define testcase(X) #endif /* ** The failsafe() macro is used to test for error conditions that ** should never occur. This is similar to assert() except that with ** failsafe() the application attempts to recover gracefully rather ** than abort. If a error condition is detected, a global flag is ** set to the "Id" prior to recovery in order to alert the application ** to the error condition. ** ** The Id should be a random integer. The idea behind the Id is that ** failsafe() faults in the field can be mapped back to specific failsafe() ** macros, even if line numbers and filenames have changed. ** ** The test condition is argument Cond. The recovery action is ** argument Action. */ #ifdef SQLITE_COVERAGE_TEST # define failsafe(Cond,Id,Action) #else # define failsafe(Cond,Id,Action) if( Cond ){ sqlite3Failsafe(Id); Action; } #endif /* ** The macro unlikely() is a hint that surrounds a boolean ** expression that is usually false. Macro likely() surrounds ** a boolean expression that is usually true. GCC is able to ** use these hints to generate better code, sometimes. */ |
︙ | ︙ | |||
1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 | ** This structure also contains some state information. */ struct Sqlite3Config { int bMemstat; /* True to enable memory status */ int bCoreMutex; /* True to enable core mutexing */ int bFullMutex; /* True to enable full mutexing */ int mxStrlen; /* Maximum string length */ sqlite3_mem_methods m; /* Low-level memory allocation interface */ sqlite3_mutex_methods mutex; /* Low-level mutex interface */ void *pHeap; /* Heap storage space */ int nHeap; /* Size of pHeap[] */ int mnReq, mxReq; /* Min and max heap requests sizes */ void *pScratch; /* Scratch memory */ int szScratch; /* Size of each scratch buffer */ | > | 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 | ** This structure also contains some state information. */ struct Sqlite3Config { int bMemstat; /* True to enable memory status */ int bCoreMutex; /* True to enable core mutexing */ int bFullMutex; /* True to enable full mutexing */ int mxStrlen; /* Maximum string length */ int iFailsafe; /* Id of failed failsafe() */ sqlite3_mem_methods m; /* Low-level memory allocation interface */ sqlite3_mutex_methods mutex; /* Low-level mutex interface */ void *pHeap; /* Heap storage space */ int nHeap; /* Size of pHeap[] */ int mnReq, mxReq; /* Min and max heap requests sizes */ void *pScratch; /* Scratch memory */ int szScratch; /* Size of each scratch buffer */ |
︙ | ︙ | |||
1787 1788 1789 1790 1791 1792 1793 | ** builds) or a function call (for debugging). If it is a function call, ** it allows the operator to set a breakpoint at the spot where database ** corruption is first detected. */ #ifdef SQLITE_DEBUG int sqlite3Corrupt(void); # define SQLITE_CORRUPT_BKPT sqlite3Corrupt() | < < | 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 | ** builds) or a function call (for debugging). If it is a function call, ** it allows the operator to set a breakpoint at the spot where database ** corruption is first detected. */ #ifdef SQLITE_DEBUG int sqlite3Corrupt(void); # define SQLITE_CORRUPT_BKPT sqlite3Corrupt() #else # define SQLITE_CORRUPT_BKPT SQLITE_CORRUPT #endif /* ** Internal function prototypes */ int sqlite3StrICmp(const char *, const char *); int sqlite3StrNICmp(const char *, const char *, int); |
︙ | ︙ | |||
1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 | int sqlite3SafetyOff(sqlite3*); #else # define sqlite3SafetyOn(A) 0 # define sqlite3SafetyOff(A) 0 #endif int sqlite3SafetyCheckOk(sqlite3*); int sqlite3SafetyCheckSickOrOk(sqlite3*); void sqlite3ChangeCookie(Parse*, int); void sqlite3MaterializeView(Parse*, Select*, Expr*, int); #ifndef SQLITE_OMIT_TRIGGER void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, Expr*,int, int); void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*); | > | 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 | int sqlite3SafetyOff(sqlite3*); #else # define sqlite3SafetyOn(A) 0 # define sqlite3SafetyOff(A) 0 #endif int sqlite3SafetyCheckOk(sqlite3*); int sqlite3SafetyCheckSickOrOk(sqlite3*); void sqlite3Failsafe(int); void sqlite3ChangeCookie(Parse*, int); void sqlite3MaterializeView(Parse*, Select*, Expr*, int); #ifndef SQLITE_OMIT_TRIGGER void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, Expr*,int, int); void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*); |
︙ | ︙ |
Changes to src/status.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This module implements the sqlite3_status() interface and related ** functionality. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This module implements the sqlite3_status() interface and related ** functionality. ** ** $Id: status.c,v 1.2 2008/07/09 13:28:54 drh Exp $ */ #include "sqliteInt.h" /* ** Variables in which to record status information. */ static struct { |
︙ | ︙ | |||
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | ** Query status information. ** ** This implementation assumes that reading or writing an aligned ** 32-bit integer is an atomic operation. If that assumption is not true, ** then this routine is not threadsafe. */ int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){ if( op<0 || op>=ArraySize(sqlite3Stat.nowValue) ){ return SQLITE_MISUSE; } *pCurrent = sqlite3Stat.nowValue[op]; *pHighwater = sqlite3Stat.mxValue[op]; if( resetFlag ){ sqlite3Stat.mxValue[op] = sqlite3Stat.nowValue[op]; } return SQLITE_OK; } | > > > > > | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | ** Query status information. ** ** This implementation assumes that reading or writing an aligned ** 32-bit integer is an atomic operation. If that assumption is not true, ** then this routine is not threadsafe. */ int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){ if( op==SQLITE_STATUS_FAILSAFE ){ *pCurrent = *pHighwater = sqlite3Config.iFailsafe; if( resetFlag ) sqlite3Config.iFailsafe = 0; return SQLITE_OK; } if( op<0 || op>=ArraySize(sqlite3Stat.nowValue) ){ return SQLITE_MISUSE; } *pCurrent = sqlite3Stat.nowValue[op]; *pHighwater = sqlite3Stat.mxValue[op]; if( resetFlag ){ sqlite3Stat.mxValue[op] = sqlite3Stat.nowValue[op]; } return SQLITE_OK; } |
Changes to src/test_malloc.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code used to implement test interfaces to the ** memory allocation subsystem. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code used to implement test interfaces to the ** memory allocation subsystem. ** ** $Id: test_malloc.c,v 1.34 2008/07/09 13:28:54 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> #include <assert.h> |
︙ | ︙ | |||
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 | } aOp[] = { { "SQLITE_STATUS_MEMORY_USED", SQLITE_STATUS_MEMORY_USED }, { "SQLITE_STATUS_PAGECACHE_USED", SQLITE_STATUS_PAGECACHE_USED }, { "SQLITE_STATUS_PAGECACHE_OVERFLOW", SQLITE_STATUS_PAGECACHE_OVERFLOW }, { "SQLITE_STATUS_SCRATCH_USED", SQLITE_STATUS_SCRATCH_USED }, { "SQLITE_STATUS_SCRATCH_OVERFLOW", SQLITE_STATUS_SCRATCH_OVERFLOW }, { "SQLITE_STATUS_MALLOC_SIZE", SQLITE_STATUS_MALLOC_SIZE }, }; Tcl_Obj *pResult; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "PARAMETER RESETFLAG"); return TCL_ERROR; } zOpName = Tcl_GetString(objv[1]); | > | 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 | } aOp[] = { { "SQLITE_STATUS_MEMORY_USED", SQLITE_STATUS_MEMORY_USED }, { "SQLITE_STATUS_PAGECACHE_USED", SQLITE_STATUS_PAGECACHE_USED }, { "SQLITE_STATUS_PAGECACHE_OVERFLOW", SQLITE_STATUS_PAGECACHE_OVERFLOW }, { "SQLITE_STATUS_SCRATCH_USED", SQLITE_STATUS_SCRATCH_USED }, { "SQLITE_STATUS_SCRATCH_OVERFLOW", SQLITE_STATUS_SCRATCH_OVERFLOW }, { "SQLITE_STATUS_MALLOC_SIZE", SQLITE_STATUS_MALLOC_SIZE }, { "SQLITE_STATUS_FAILSAFE", SQLITE_STATUS_FAILSAFE }, }; Tcl_Obj *pResult; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "PARAMETER RESETFLAG"); return TCL_ERROR; } zOpName = Tcl_GetString(objv[1]); |
︙ | ︙ |
Changes to src/util.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** ** $Id: util.c,v 1.235 2008/07/09 13:28:54 drh Exp $ */ #include "sqliteInt.h" #include <stdarg.h> #include <ctype.h> /* |
︙ | ︙ | |||
932 933 934 935 936 937 938 | if( db==0 ) return 0; magic = db->magic; if( magic!=SQLITE_MAGIC_SICK && magic!=SQLITE_MAGIC_OPEN && magic!=SQLITE_MAGIC_BUSY ) return 0; return 1; } | > > > > > > > > > > > > > > | 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 | if( db==0 ) return 0; magic = db->magic; if( magic!=SQLITE_MAGIC_SICK && magic!=SQLITE_MAGIC_OPEN && magic!=SQLITE_MAGIC_BUSY ) return 0; return 1; } /* ** Report a failsafe() macro failure */ void sqlite3Failsafe(int iCode){ sqlite3Config.iFailsafe = iCode; /* The following assert is always false. When assert() is enabled, ** the following causes a failsafe() failure to work like an assert() ** failure. Normal operating mode for SQLite is for assert() to be ** disabled, however, so the following is normally a no-op. */ assert( iCode==0 ); /* Always fails if assert() is enabled */ } |
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 responsible 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 responsible 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.315 2008/07/09 13:28:54 drh Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) |
︙ | ︙ | |||
446 447 448 449 450 451 452 453 454 455 456 457 458 | int iColumn, /* Column number of LHS */ Bitmask notReady, /* RHS must not overlap with this mask */ u16 op, /* Mask of WO_xx values describing operator */ Index *pIdx /* Must be compatible with this index, if not NULL */ ){ WhereTerm *pTerm; int k; for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){ if( pTerm->leftCursor==iCur && (pTerm->prereqRight & notReady)==0 && pTerm->leftColumn==iColumn && (pTerm->eOperator & op)!=0 ){ | > | | | > | 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 | int iColumn, /* Column number of LHS */ Bitmask notReady, /* RHS must not overlap with this mask */ u16 op, /* Mask of WO_xx values describing operator */ Index *pIdx /* Must be compatible with this index, if not NULL */ ){ WhereTerm *pTerm; int k; assert( iCur>=0 ); for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){ if( pTerm->leftCursor==iCur && (pTerm->prereqRight & notReady)==0 && pTerm->leftColumn==iColumn && (pTerm->eOperator & op)!=0 ){ if( pIdx && pTerm->eOperator!=WO_ISNULL ){ Expr *pX = pTerm->pExpr; CollSeq *pColl; char idxaff; int j; Parse *pParse = pWC->pParse; idxaff = pIdx->pTable->aCol[iColumn].affinity; if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue; /* Figure out the collation sequence required from an index for ** it to be useful for optimising expression pX. Store this ** value in variable pColl. */ assert(pX->pLeft); pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); if( !pColl ){ pColl = pParse->db->pDfltColl; } for(j=0; pIdx->aiColumn[j]!=iColumn; j++){ failsafe( j>=pIdx->nColumn, 0x0128fc98, {return 0;}); } if( sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue; } return pTerm; } } return 0; } |
︙ | ︙ | |||
862 863 864 865 866 867 868 | } } }while( !ok && (sOr.a[j++].flags & TERM_COPIED)!=0 && j<2 ); if( ok ){ ExprList *pList = 0; Expr *pNew, *pDup; Expr *pLeft = 0; | | | 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 | } } }while( !ok && (sOr.a[j++].flags & TERM_COPIED)!=0 && j<2 ); if( ok ){ ExprList *pList = 0; Expr *pNew, *pDup; Expr *pLeft = 0; for(i=sOr.nTerm-1, pOrTerm=sOr.a; i>=0; i--, pOrTerm++){ if( (pOrTerm->flags & TERM_OR_OK)==0 ) continue; pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight); pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup, 0); pLeft = pOrTerm->pExpr->pLeft; } assert( pLeft!=0 ); pDup = sqlite3ExprDup(db, pLeft); |
︙ | ︙ | |||
1602 1603 1604 1605 1606 1607 1608 | if( pTerm==0 ) break; flags |= WHERE_COLUMN_EQ; if( pTerm->eOperator & WO_IN ){ Expr *pExpr = pTerm->pExpr; flags |= WHERE_COLUMN_IN; if( pExpr->pSelect!=0 ){ inMultiplier *= 25; | > | | 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 | if( pTerm==0 ) break; flags |= WHERE_COLUMN_EQ; if( pTerm->eOperator & WO_IN ){ Expr *pExpr = pTerm->pExpr; flags |= WHERE_COLUMN_IN; if( pExpr->pSelect!=0 ){ inMultiplier *= 25; }else{ failsafe( pExpr->pList==0, 0x16b91d0f, continue); inMultiplier *= pExpr->pList->nExpr + 1; } } } cost = pProbe->aiRowEst[i] * inMultiplier * estLog(inMultiplier); nEq = i; if( pProbe->onError!=OE_None && (flags & WHERE_COLUMN_IN)==0 |
︙ | ︙ | |||
1718 1719 1720 1721 1722 1723 1724 | ** loop. We would get the correct results if nothing were ever disabled, ** but joins might run a little slower. The trick is to disable as much ** as we can without disabling too much. If we disabled in (1), we'd get ** the wrong answer. See ticket #813. */ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ if( pTerm | < > | 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 | ** loop. We would get the correct results if nothing were ever disabled, ** but joins might run a little slower. The trick is to disable as much ** as we can without disabling too much. If we disabled in (1), we'd get ** the wrong answer. See ticket #813. */ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ if( pTerm && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin)) ){ failsafe( (pTerm->flags & TERM_CODED)!=0, 0x641154a4, /* no-op */ ); pTerm->flags |= TERM_CODED; if( pTerm->iParent>=0 ){ WhereTerm *pOther = &pTerm->pWC->a[pTerm->iParent]; if( (--pOther->nChild)==0 ){ disableTerm(pLevel, pOther); } } |
︙ | ︙ | |||
1866 1867 1868 1869 1870 1871 1872 | /* Evaluate the equality constraints */ assert( pIdx->nColumn>=nEq ); for(j=0; j<nEq; j++){ int r1; int k = pIdx->aiColumn[j]; pTerm = findTerm(pWC, iCur, k, notReady, pLevel->flags, pIdx); | | | 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 | /* Evaluate the equality constraints */ assert( pIdx->nColumn>=nEq ); for(j=0; j<nEq; j++){ int r1; int k = pIdx->aiColumn[j]; pTerm = findTerm(pWC, iCur, k, notReady, pLevel->flags, pIdx); failsafe( pTerm==0, 0x7592494c, break ); assert( (pTerm->flags & TERM_CODED)==0 ); r1 = codeEqualityTerm(pParse, pTerm, pLevel, regBase+j); if( r1!=regBase+j ){ sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j); } testcase( pTerm->eOperator & WO_ISNULL ); testcase( pTerm->eOperator & WO_IN ); |
︙ | ︙ |