/ Check-in [82ca2131]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Simplified error detection in the xBestIndex processing.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 82ca2131b670505578628687746135ac413d156b
User & Date: drh 2016-03-08 02:59:33
Context
2016-03-08
13:56
Fix comments on pager flag settings to include synchronous=EXTRA. check-in: 3a65a1fc user: drh tags: trunk
02:59
Simplified error detection in the xBestIndex processing. check-in: 82ca2131 user: drh tags: trunk
01:32
Add the ALLBITS macro as a shorthand for "(Bitmask)(-1)". check-in: 91bd619d user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/where.c.

   930    930   **
   931    931   ** Whether or not an error is returned, it is the responsibility of the
   932    932   ** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates
   933    933   ** that this is required.
   934    934   */
   935    935   static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
   936    936     sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab;
   937         -  int i;
   938    937     int rc;
   939    938   
   940    939     TRACE_IDX_INPUTS(p);
   941    940     rc = pVtab->pModule->xBestIndex(pVtab, p);
   942    941     TRACE_IDX_OUTPUTS(p);
   943    942   
   944    943     if( rc!=SQLITE_OK ){
................................................................................
   949    948       }else{
   950    949         sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg);
   951    950       }
   952    951     }
   953    952     sqlite3_free(pVtab->zErrMsg);
   954    953     pVtab->zErrMsg = 0;
   955    954   
          955  +#if 0
          956  +  /* This error is now caught by the caller.
          957  +  ** Search for "xBestIndex malfunction" below */
   956    958     for(i=0; i<p->nConstraint; i++){
   957    959       if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){
   958    960         sqlite3ErrorMsg(pParse, 
   959    961             "table %s: xBestIndex returned an invalid plan", pTab->zName);
   960    962       }
   961    963     }
          964  +#endif
   962    965   
   963    966     return pParse->nErr;
   964    967   }
   965    968   #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
   966    969   
   967    970   #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
   968    971   /*
................................................................................
  2831   2834       if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
  2832   2835         WhereTerm *pTerm;
  2833   2836         int j = pIdxCons->iTermOffset;
  2834   2837         if( iTerm>=nConstraint
  2835   2838          || j<0
  2836   2839          || j>=pWC->nTerm
  2837   2840          || pNew->aLTerm[iTerm]!=0
         2841  +       || pIdxCons->usable==0
  2838   2842         ){
  2839   2843           rc = SQLITE_ERROR;
  2840         -        sqlite3ErrorMsg(pParse,"%s.xBestIndex() malfunction",pSrc->pTab->zName);
         2844  +        sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName);
  2841   2845           return rc;
  2842   2846         }
  2843   2847         testcase( iTerm==nConstraint-1 );
  2844   2848         testcase( j==0 );
  2845   2849         testcase( j==pWC->nTerm-1 );
  2846   2850         pTerm = &pWC->a[j];
  2847   2851         pNew->prereq |= pTerm->prereqRight;
................................................................................
  2855   2859           /* A virtual table that is constrained by an IN clause may not
  2856   2860           ** consume the ORDER BY clause because (1) the order of IN terms
  2857   2861           ** is not necessarily related to the order of output terms and
  2858   2862           ** (2) Multiple outputs from a single IN value will not merge
  2859   2863           ** together.  */
  2860   2864           pIdxInfo->orderByConsumed = 0;
  2861   2865           pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
  2862         -        *pbIn = 1;
         2866  +        *pbIn = 1; assert( (mExclude & WO_IN)==0 );
  2863   2867         }
  2864   2868       }
  2865   2869     }
  2866   2870   
  2867   2871     pNew->nLTerm = mxTerm+1;
  2868   2872     assert( pNew->nLTerm<=pNew->nLSlot );
  2869   2873     pNew->u.vtab.idxNum = pIdxInfo->idxNum;
................................................................................
  2968   2972       Bitmask mPrev = 0;
  2969   2973       Bitmask mBestNoIn = 0;
  2970   2974   
  2971   2975       /* If the plan produced by the earlier call uses an IN(...) term, call
  2972   2976       ** xBestIndex again, this time with IN(...) terms disabled. */
  2973   2977       if( rc==SQLITE_OK && bIn ){
  2974   2978         rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, WO_IN, p, &bIn);
         2979  +      assert( bIn==0 );
  2975   2980         mBestNoIn = pNew->prereq & ~mPrereq;
  2976   2981         if( mBestNoIn==0 ){
  2977   2982           seenZero = 1;
  2978         -        if( bIn==0 ) seenZeroNoIN = 1;
         2983  +        seenZeroNoIN = 1;
  2979   2984         }
  2980   2985       }
  2981   2986   
  2982   2987       /* Call xBestIndex once for each distinct value of (prereqRight & ~mPrereq) 
  2983   2988       ** in the set of terms that apply to the current virtual table.  */
  2984   2989       while( rc==SQLITE_OK ){
  2985   2990         int i;

Changes to test/vtab6.test.

   562    562   set ::echo_module_ignore_usable 1
   563    563   db cache flush
   564    564   
   565    565   do_test vtab6-11.4.1 {
   566    566     catchsql {
   567    567       SELECT a, b, c FROM ab NATURAL JOIN bc;
   568    568     }
   569         -} {1 {table ab: xBestIndex returned an invalid plan}}
          569  +} {1 {ab.xBestIndex malfunction}}
   570    570   do_test vtab6-11.4.2 {
   571    571     catchsql {
   572    572       SELECT a, b, c FROM bc NATURAL JOIN ab;
   573    573     }
   574         -} {1 {table bc: xBestIndex returned an invalid plan}}
          574  +} {1 {bc.xBestIndex malfunction}}
   575    575   
   576    576   unset ::echo_module_ignore_usable
   577    577   
   578    578   finish_test