SQLite

Changes On Branch not-working
Login

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

Changes In Branch not-working Excluding Merge-Ins

This is equivalent to a diff from a8da85c5 to ad32da80

2022-04-30
18:40
Simplified fix to the problem with subroutine reuse in the RIGHT JOIN no-match logic for a subquery on the right-hand side of an IN operator. The code still needs simplification. (check-in: a1937497 user: drh tags: trunk)
17:22
Fix another problem with subroutine reuse in the RIGHT JOIN no-match code for the subquery on the right-hand side of an IN operator. The current code works for all known cases, but seems unnecessarily complex and in need of simplification. Later: The fuzzer finds memory leaks with this version. (Closed-Leaf check-in: ad32da80 user: drh tags: not-working)
12:55
Preserve the COLLATE operator on an index on an expression when resolving the use of that expression into a reference to the index. See forum thread 7efabf4b03328e57 for details. (check-in: ef72f9e2 user: drh tags: branch-3.38)
12:35
Preserve the COLLATE operator on an index on an expression when resolving the use of that expression into a reference to the index. See forum thread 7efabf4b03328e57 for details. (check-in: a8da85c5 user: drh tags: trunk)
00:06
Further improvements to codeEqualityTerm() for cases when an IN operator with a right-hand side subquery is used as a constraint that needs to be processed by the RIGHT JOIN non-matched logic. (check-in: bb2798be user: drh tags: trunk)

Changes to src/vdbe.h.

228
229
230
231
232
233
234

235
236
237
238
239
240
241
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3);
void sqlite3VdbeChangeP5(Vdbe*, u16 P5);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeJumpHereOrPopInst(Vdbe*, int addr);
int sqlite3VdbeChangeToNoop(Vdbe*, int addr);
int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);

#ifdef SQLITE_DEBUG
  void sqlite3VdbeReleaseRegisters(Parse*,int addr, int n, u32 mask, int);
#else
# define sqlite3VdbeReleaseRegisters(P,A,N,M,F)
#endif
void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type);







>







228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3);
void sqlite3VdbeChangeP5(Vdbe*, u16 P5);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeJumpHereOrPopInst(Vdbe*, int addr);
int sqlite3VdbeChangeToNoop(Vdbe*, int addr);
int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);
void sqlite3VdbeUndoBackTo(Vdbe*, int addr);
#ifdef SQLITE_DEBUG
  void sqlite3VdbeReleaseRegisters(Parse*,int addr, int n, u32 mask, int);
#else
# define sqlite3VdbeReleaseRegisters(P,A,N,M,F)
#endif
void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type);

Changes to src/vdbeaux.c.

1298
1299
1300
1301
1302
1303
1304
















1305
1306
1307
1308
1309
1310
1311
int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
  if( p->nOp>0 && p->aOp[p->nOp-1].opcode==op ){
    return sqlite3VdbeChangeToNoop(p, p->nOp-1);
  }else{
    return 0;
  }
}

















#ifdef SQLITE_DEBUG
/*
** Generate an OP_ReleaseReg opcode to indicate that a range of
** registers, except any identified by mask, are no longer in use.
*/
void sqlite3VdbeReleaseRegisters(







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
  if( p->nOp>0 && p->aOp[p->nOp-1].opcode==op ){
    return sqlite3VdbeChangeToNoop(p, p->nOp-1);
  }else{
    return 0;
  }
}

/*
** Undo all opcode inserts so that addr is the last opcode.
*/
void sqlite3VdbeUndoBackTo(Vdbe *p, int addr){
  while( p->nOp>addr ){
#ifdef SQLITE_DEBUG
    if( p->db->flags & SQLITE_VdbeAddopTrace ){
      printf("UNDO: ");
      sqlite3VdbePrintOp(0, p->nOp-1, &p->aOp[p->nOp-1]);
    }
#endif
    sqlite3VdbeChangeToNoop(p, p->nOp-1);
    p->nOp--;
  }
}

#ifdef SQLITE_DEBUG
/*
** Generate an OP_ReleaseReg opcode to indicate that a range of
** registers, except any identified by mask, are no longer in use.
*/
void sqlite3VdbeReleaseRegisters(

Changes to src/wherecode.c.

615
616
617
618
619
620
621
622
623
624
625

626
627


628
629

630
631
632
633
634
635
636
      if(  pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){
        sqlite3 *db = pParse->db;
        pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);
        if( !db->mallocFailed ){
          aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
          eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab);
          pExpr->iTable = iTab;
          pExpr->op2 = eType;
        }
        sqlite3ExprDelete(db, pX);
      }else{

        sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
                          pExpr->y.sub.iAddr);


        iTab = pExpr->iTable;
        eType = pExpr->op2;

      }
      pX = pExpr;
    }

    if( eType==IN_INDEX_INDEX_DESC ){
      testcase( bRev );
      bRev = !bRev;







<



>
|
|
>
>

<
>







615
616
617
618
619
620
621

622
623
624
625
626
627
628
629
630

631
632
633
634
635
636
637
638
      if(  pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){
        sqlite3 *db = pParse->db;
        pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);
        if( !db->mallocFailed ){
          aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
          eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab);
          pExpr->iTable = iTab;

        }
        sqlite3ExprDelete(db, pX);
      }else{
        int j1;
        j1 = sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
                               pExpr->y.sub.iAddr);
        aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
        eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab);
        iTab = pExpr->iTable;

        sqlite3VdbeUndoBackTo(v, j1+1);
      }
      pX = pExpr;
    }

    if( eType==IN_INDEX_INDEX_DESC ){
      testcase( bRev );
      bRev = !bRev;

Changes to test/join8.test.

168
169
170
171
172
173
174







175
176
do_execsql_test join8-6010 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a INT PRIMARY KEY, b TEXT, c TEXT, d INT) WITHOUT ROWID;
  INSERT INTO t1 VALUES(15,'xray','baker',42);
  SELECT value, t1.* FROM json_each('7') NATURAL RIGHT JOIN t1
   WHERE (a,b) IN (SELECT a, b FROM t1);
} {7 15 xray baker 42}








finish_test







>
>
>
>
>
>
>


168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
do_execsql_test join8-6010 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a INT PRIMARY KEY, b TEXT, c TEXT, d INT) WITHOUT ROWID;
  INSERT INTO t1 VALUES(15,'xray','baker',42);
  SELECT value, t1.* FROM json_each('7') NATURAL RIGHT JOIN t1
   WHERE (a,b) IN (SELECT a, b FROM t1);
} {7 15 xray baker 42}
do_execsql_test join8-6020 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a INTEGER PRIMARY KEY,b);
  INSERT INTO t1 VALUES(0,NULL),(1,2);
  SELECT value, t1.* FROM json_each('17') NATURAL RIGHT JOIN t1
   WHERE (a,b) IN (SELECT rowid, b FROM t1);
} {17 1 2}

finish_test