/ Check-in [8d663bfa]
Login

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

Overview
Comment:Disable the use of coroutines for subqueries within a query that is the RHS of an IN operator, as the IN operator might be evaluated more than once. Possible fix for [787fa716be3a7f65], unless we can come up with something better. Later: Counter-example found.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | tkt787fa716-deadend
Files: files | file ages | folders
SHA3-256:8d663bfaaa4656c4f4ff115017404aa88da4931a6aacc8069060f121e43d0240
User & Date: drh 2018-11-09 00:02:02
Original Comment: Disable the use of coroutines for subqueries within a query that is the RHS of an IN operator, as the IN operator might be evaluated more than once. Possible fix for [787fa716be3a7f65], unless we can come up with something better.
References
2018-11-09
13:39 Ticket [787fa716] Assertion fault when multi-use subquery implemented by co-routine status still Open with 4 other changes artifact: 23c14e4a user: drh
Context
2018-11-09
00:02
Disable the use of coroutines for subqueries within a query that is the RHS of an IN operator, as the IN operator might be evaluated more than once. Possible fix for [787fa716be3a7f65], unless we can come up with something better. Later: Counter-example found. Closed-Leaf check-in: 8d663bfa user: drh tags: tkt787fa716-deadend
2018-11-08
22:53
In the treeview.c module, break out the display of SrcList into a separate subroutine, so that it can be invoked while debugging. check-in: 8c74065f user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

2512
2513
2514
2515
2516
2517
2518



2519
2520
2521
2522
2523
2524
2525
    if( inFlags & IN_INDEX_LOOP ){
      pParse->nQueryLoop = 0;
      if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){
        eType = IN_INDEX_ROWID;
      }
    }else if( prRhsHasNull ){
      *prRhsHasNull = rMayHaveNull = ++pParse->nMem;



    }
    sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
    pParse->nQueryLoop = savedNQueryLoop;
  }else{
    pX->iTable = iTab;
  }








>
>
>







2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
    if( inFlags & IN_INDEX_LOOP ){
      pParse->nQueryLoop = 0;
      if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){
        eType = IN_INDEX_ROWID;
      }
    }else if( prRhsHasNull ){
      *prRhsHasNull = rMayHaveNull = ++pParse->nMem;
    }
    if( ExprHasProperty(pX, EP_xIsSelect) ){
      pX->x.pSelect->selFlags |= SF_RhsOfIN;
    }
    sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
    pParse->nQueryLoop = savedNQueryLoop;
  }else{
    pX->iTable = iTab;
  }

Changes to src/select.c.

5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889

5890
5891
5892
5893
5894
5895
5896
    zSavedAuthContext = pParse->zAuthContext;
    pParse->zAuthContext = pItem->zName;

    /* Generate code to implement the subquery
    **
    ** The subquery is implemented as a co-routine if the subquery is
    ** guaranteed to be the outer loop (so that it does not need to be
    ** computed more than once)
    **
    ** TODO: Are there other reasons beside (1) to use a co-routine
    ** implementation?
    */
    if( i==0
     && (pTabList->nSrc==1
            || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0)  /* (1) */

    ){
      /* Implement a co-routine that will return a single row of the result
      ** set on each invocation.
      */
      int addrTop = sqlite3VdbeCurrentAddr(v)+1;
     
      pItem->regReturn = ++pParse->nMem;







|

|
|




>







5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
    zSavedAuthContext = pParse->zAuthContext;
    pParse->zAuthContext = pItem->zName;

    /* Generate code to implement the subquery
    **
    ** The subquery is implemented as a co-routine if the subquery is
    ** guaranteed to be the outer loop (so that it does not need to be
    ** computed more than once). (1)
    **
    ** Avoid using a co-routines to compute any SELECT that occurs in
    ** the RHS of an IN operator, as they can be used multiple times. (2)
    */
    if( i==0
     && (pTabList->nSrc==1
            || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0)  /* (1) */
     && (p->selFlags & SF_RhsOfIN)==0                               /* (2) */
    ){
      /* Implement a co-routine that will return a single row of the result
      ** set on each invocation.
      */
      int addrTop = sqlite3VdbeCurrentAddr(v)+1;
     
      pItem->regReturn = ++pParse->nMem;

Changes to src/sqliteInt.h.

2860
2861
2862
2863
2864
2865
2866

2867
2868
2869
2870
2871
2872
2873
#define SF_MinMaxAgg      0x01000  /* Aggregate containing min() or max() */
#define SF_Recursive      0x02000  /* The recursive part of a recursive CTE */
#define SF_FixedLimit     0x04000  /* nSelectRow set by a constant LIMIT */
#define SF_MaybeConvert   0x08000  /* Need convertCompoundSelectToSubquery() */
#define SF_Converted      0x10000  /* By convertCompoundSelectToSubquery() */
#define SF_IncludeHidden  0x20000  /* Include hidden columns in output */
#define SF_ComplexResult  0x40000  /* Result contains subquery or function */


/*
** The results of a SELECT can be distributed in several ways, as defined
** by one of the following macros.  The "SRT" prefix means "SELECT Result
** Type".
**
**     SRT_Union       Store results as a key in a temporary index







>







2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
#define SF_MinMaxAgg      0x01000  /* Aggregate containing min() or max() */
#define SF_Recursive      0x02000  /* The recursive part of a recursive CTE */
#define SF_FixedLimit     0x04000  /* nSelectRow set by a constant LIMIT */
#define SF_MaybeConvert   0x08000  /* Need convertCompoundSelectToSubquery() */
#define SF_Converted      0x10000  /* By convertCompoundSelectToSubquery() */
#define SF_IncludeHidden  0x20000  /* Include hidden columns in output */
#define SF_ComplexResult  0x40000  /* Result contains subquery or function */
#define SF_RhsOfIN        0x80000  /* Result uses as the RHS of IN operator */

/*
** The results of a SELECT can be distributed in several ways, as defined
** by one of the following macros.  The "SRT" prefix means "SELECT Result
** Type".
**
**     SRT_Union       Store results as a key in a temporary index