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

Overview
Comment:Combine the OP_MakeIdxKey and OP_MakeKey opcodes into a single OP_MakeKey that does the work of both. Standardize the parameter meanings on OP_MakeRecord and OP_MakeKey. Remove the unused OP_Seek opcode. Other related code simplifications and cleanup.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ed5d6992cd896855ecaae58fa9bda6257f59abb2
User & Date: drh 2013-07-30 20:27:26.605
Context
2013-07-31
08:37
Fix up test/speed1.test so that it runs. check-in: 8f00d13162 user: drh tags: trunk
2013-07-30
20:27
Combine the OP_MakeIdxKey and OP_MakeKey opcodes into a single OP_MakeKey that does the work of both. Standardize the parameter meanings on OP_MakeRecord and OP_MakeKey. Remove the unused OP_Seek opcode. Other related code simplifications and cleanup. check-in: ed5d6992cd user: drh tags: trunk
20:22
Combine the OP_MakeIdxKey and OP_MakeKey opcodes into a single OP_MakeKey that does the work of both. Standardize the parameter meanings on OP_MakeRecord and OP_MakeKey. Remove the unused OP_Seek opcode. Other related code simplifications and cleanup. Closed-Leaf check-in: 1122ff55e5 user: drh tags: refactor-MakeRecord
20:01
Add experimental sqlite_kvstore table. Currently read-only. check-in: c13692183a user: dan tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/analyze.c.
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
      sqlite4VdbeAddOp3(v, OP_Divide, aregCard+i, regTemp, regTemp);
      sqlite4VdbeAddOp1(v, OP_ToInt, regTemp);
      sqlite4VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
    }
    sqlite4VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
    sqlite4VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
    sqlite4VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
    sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
  }

  sqlite4VdbeJumpHere(v, jZeroRows);
  jZeroRows = sqlite4VdbeAddOp0(v, OP_Goto);
  sqlite4VdbeAddOp2(v, OP_Null, 0, regIdxname);
  sqlite4VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
  sqlite4VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
  sqlite4VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
  sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
  if( pParse->nMem<regRec ) pParse->nMem = regRec;
  sqlite4VdbeJumpHere(v, jZeroRows);
}

/*
** Generate code that will cause the most recent index analysis to
** be loaded into internal hash tables where is can be used.







<








<







652
653
654
655
656
657
658

659
660
661
662
663
664
665
666

667
668
669
670
671
672
673
      sqlite4VdbeAddOp3(v, OP_Divide, aregCard+i, regTemp, regTemp);
      sqlite4VdbeAddOp1(v, OP_ToInt, regTemp);
      sqlite4VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
    }
    sqlite4VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
    sqlite4VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
    sqlite4VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);

  }

  sqlite4VdbeJumpHere(v, jZeroRows);
  jZeroRows = sqlite4VdbeAddOp0(v, OP_Goto);
  sqlite4VdbeAddOp2(v, OP_Null, 0, regIdxname);
  sqlite4VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
  sqlite4VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
  sqlite4VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);

  if( pParse->nMem<regRec ) pParse->nMem = regRec;
  sqlite4VdbeJumpHere(v, jZeroRows);
}

/*
** Generate code that will cause the most recent index analysis to
** be loaded into internal hash tables where is can be used.
Changes to src/build.c.
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
      int tnum = firstAvailableTableNumber(db, iDb);
      sqlite4VdbeAddOp2(v, OP_Integer, tnum, reg2);
    }
#endif
    sqlite4OpenMasterTable(pParse, iDb);
    sqlite4VdbeAddOp2(v, OP_NewRowid, 0, reg1);
    sqlite4VdbeAddOp3(v, OP_Insert, 0, 0, reg1);
    sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
    sqlite4VdbeAddOp0(v, OP_Close);
  }

  /* Normal (non-error) return. */
  return;

  /* If an error occurs, we jump here */







<







820
821
822
823
824
825
826

827
828
829
830
831
832
833
      int tnum = firstAvailableTableNumber(db, iDb);
      sqlite4VdbeAddOp2(v, OP_Integer, tnum, reg2);
    }
#endif
    sqlite4OpenMasterTable(pParse, iDb);
    sqlite4VdbeAddOp2(v, OP_NewRowid, 0, reg1);
    sqlite4VdbeAddOp3(v, OP_Insert, 0, 0, reg1);

    sqlite4VdbeAddOp0(v, OP_Close);
  }

  /* Normal (non-error) return. */
  return;

  /* If an error occurs, we jump here */
Changes to src/delete.c.
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
    }else{
      sqlite4VdbeAddOp3(v, OP_Column, iPkCsr, pPk->aiColumn[i], regVal);
    }
  }

  /* Build the index key. If bAddSeq is true, append a sequence number to 
  ** the end of the key to ensure it is unique.  */
  sqlite4VdbeAddOp3(v, OP_MakeIdxKey, iIdxCsr, regTmp, regOut);
  if( bAddSeq ) sqlite4VdbeChangeP5(v, OPFLAG_SEQCOUNT);

  /* Release temp registers */
  sqlite4ReleaseTempRange(pParse, regTmp, nTmpReg);
}

/*







|







551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
    }else{
      sqlite4VdbeAddOp3(v, OP_Column, iPkCsr, pPk->aiColumn[i], regVal);
    }
  }

  /* Build the index key. If bAddSeq is true, append a sequence number to 
  ** the end of the key to ensure it is unique.  */
  sqlite4VdbeAddOp4Int(v, OP_MakeKey, regTmp, nTmpReg, regOut, iIdxCsr);
  if( bAddSeq ) sqlite4VdbeChangeP5(v, OPFLAG_SEQCOUNT);

  /* Release temp registers */
  sqlite4ReleaseTempRange(pParse, regTmp, nTmpReg);
}

/*
Changes to src/expr.c.
1767
1768
1769
1770
1771
1772
1773
1774

1775
1776
1777
1778
1779
1780
1781
1782
            sqlite4VdbeChangeToNoop(v, testAddr);
            testAddr = -1;
          }

          /* Evaluate the expression and insert it into the temp table */
          r3 = sqlite4ExprCodeTarget(pParse, pE2, r1);
          r4 = sqlite4GetTempReg(pParse);
          sqlite4VdbeAddOp2(v, OP_MakeKey, pExpr->iTable, r4);

          sqlite4VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
          sqlite4ExprCacheAffinityChange(pParse, r3, 1);
          sqlite4VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r4);
          sqlite4ReleaseTempReg(pParse, r4);
        }
        sqlite4ReleaseTempReg(pParse, r1);
        sqlite4ReleaseTempReg(pParse, r2);
      }







|
>
|







1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
            sqlite4VdbeChangeToNoop(v, testAddr);
            testAddr = -1;
          }

          /* Evaluate the expression and insert it into the temp table */
          r3 = sqlite4ExprCodeTarget(pParse, pE2, r1);
          r4 = sqlite4GetTempReg(pParse);
          sqlite4VdbeAddOp4(v, OP_Affinity, r3, 1, 0, &affinity, 1);
          sqlite4VdbeAddOp4Int(v, OP_MakeKey, r3, 1, r4, pExpr->iTable);
          sqlite4VdbeAddOp3(v, OP_MakeRecord, r3, 1, r2);
          sqlite4ExprCacheAffinityChange(pParse, r3, 1);
          sqlite4VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r4);
          sqlite4ReleaseTempReg(pParse, r4);
        }
        sqlite4ReleaseTempReg(pParse, r1);
        sqlite4ReleaseTempReg(pParse, r2);
      }
Changes to src/fkey.c.
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
        sqlite4VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent);
        sqlite4VdbeChangeP5(v, SQLITE4_JUMPIFNULL);
        assert( iChild<=pParse->nMem && iParent<=pParse->nMem );
      }
      sqlite4VdbeAddOp2(v, OP_Goto, 0, iOk);
    }

    sqlite4VdbeAddOp4Int(v, OP_MakeIdxKey, iCur, regTemp, regRec, nCol);
    sqlite4VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0);

#if 0
    sqlite4VdbeAddOp3(v, OP_MakeRecord, regTemp, nCol, regRec);
    sqlite4VdbeChangeP4(v, -1, sqlite4IndexAffinityStr(v,pIdx), P4_TRANSIENT);
    sqlite4VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0);
#endif

    sqlite4ReleaseTempReg(pParse, regRec);
    sqlite4ReleaseTempRange(pParse, regTemp, nCol);
  }

  if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
    /* Special case: If this is an INSERT statement that will insert exactly







|

<
<
<
<
<
<







361
362
363
364
365
366
367
368
369






370
371
372
373
374
375
376
        sqlite4VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent);
        sqlite4VdbeChangeP5(v, SQLITE4_JUMPIFNULL);
        assert( iChild<=pParse->nMem && iParent<=pParse->nMem );
      }
      sqlite4VdbeAddOp2(v, OP_Goto, 0, iOk);
    }

    sqlite4VdbeAddOp4Int(v, OP_MakeKey, regTemp, nCol, regRec, iCur);
    sqlite4VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0);







    sqlite4ReleaseTempReg(pParse, regRec);
    sqlite4ReleaseTempRange(pParse, regTemp, nCol);
  }

  if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
    /* Special case: If this is an INSERT statement that will insert exactly
Changes to src/insert.c.
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
    j5 = sqlite4VdbeAddOp0(v, OP_Goto);
    sqlite4VdbeJumpHere(v, j4);
    sqlite4VdbeAddOp2(v, OP_Rowid, 0, memId+1);
    sqlite4VdbeJumpHere(v, j1);
    sqlite4VdbeJumpHere(v, j5);
    sqlite4VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec);
    sqlite4VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1);
    sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
    sqlite4VdbeAddOp0(v, OP_Close);
    sqlite4ReleaseTempReg(pParse, iRec);
  }
}
#else
/*
** If SQLITE4_OMIT_AUTOINCREMENT is defined, then the three routines







<







360
361
362
363
364
365
366

367
368
369
370
371
372
373
    j5 = sqlite4VdbeAddOp0(v, OP_Goto);
    sqlite4VdbeJumpHere(v, j4);
    sqlite4VdbeAddOp2(v, OP_Rowid, 0, memId+1);
    sqlite4VdbeJumpHere(v, j1);
    sqlite4VdbeJumpHere(v, j5);
    sqlite4VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec);
    sqlite4VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1);

    sqlite4VdbeAddOp0(v, OP_Close);
    sqlite4ReleaseTempReg(pParse, iRec);
  }
}
#else
/*
** If SQLITE4_OMIT_AUTOINCREMENT is defined, then the three routines
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
    }
    if( pIdx!=pPk ){
      for(i=0; i<pPk->nColumn; i++){
        int idx = pPk->aiColumn[i];
        sqlite4VdbeAddOp2(v, OP_SCopy, regContent+idx, regTmp+i+pIdx->nColumn);
      }
    }
    sqlite4VdbeAddOp3(v, OP_MakeIdxKey, iIdx, regTmp, regKey);
    VdbeComment((v, "key for %s", pIdx->zName));

    /* If Index.onError==OE_None, then pIdx is not a UNIQUE or PRIMARY KEY 
    ** index. In this case there is no need to test the index for uniqueness
    ** - all that is required is to populate the regKey register. Jump 
    ** to the next iteration of the loop if this is the case.  */
    onError = pIdx->onError;







|







1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
    }
    if( pIdx!=pPk ){
      for(i=0; i<pPk->nColumn; i++){
        int idx = pPk->aiColumn[i];
        sqlite4VdbeAddOp2(v, OP_SCopy, regContent+idx, regTmp+i+pIdx->nColumn);
      }
    }
    sqlite4VdbeAddOp4Int(v, OP_MakeKey, regTmp, nTmpReg-1, regKey, iIdx);
    VdbeComment((v, "key for %s", pIdx->zName));

    /* If Index.onError==OE_None, then pIdx is not a UNIQUE or PRIMARY KEY 
    ** index. In this case there is no need to test the index for uniqueness
    ** - all that is required is to populate the regKey register. Jump 
    ** to the next iteration of the loop if this is the case.  */
    onError = pIdx->onError;
Changes to src/pragma.c.
757
758
759
760
761
762
763
764

765
766
767
768
769
770
771
              }
            }

            if( (pPk->nColumn+pIdx->nColumn)>nMaxArray ){
              nMaxArray = pPk->nColumn + pIdx->nColumn;
            }

            sqlite4VdbeAddOp3(v, OP_MakeIdxKey, iCsr, regArray, regKey);

            jmp = sqlite4VdbeAddOp4(v, OP_Found, iCsr, 0, regKey, 0, P4_INT32);
            sqlite4VdbeAddOp2(v, OP_AddImm, regErrcnt, 1);
            zErr = sqlite4MPrintf(
                db, "entry missing from index %s: ", pIdx->zName
            );
            sqlite4VdbeAddOp4(v, OP_String8, 0, regTmp, 0, zErr, 0);
            sqlite4VdbeAddOp3(v, OP_Concat, regTmp, regErrstr, regErrstr);







|
>







757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
              }
            }

            if( (pPk->nColumn+pIdx->nColumn)>nMaxArray ){
              nMaxArray = pPk->nColumn + pIdx->nColumn;
            }

            sqlite4VdbeAddOp4Int(v, OP_MakeKey, regArray,
                                 pIdx->nColumn+pPk->nColumn, regKey, iCsr);
            jmp = sqlite4VdbeAddOp4(v, OP_Found, iCsr, 0, regKey, 0, P4_INT32);
            sqlite4VdbeAddOp2(v, OP_AddImm, regErrcnt, 1);
            zErr = sqlite4MPrintf(
                db, "entry missing from index %s: ", pIdx->zName
            );
            sqlite4VdbeAddOp4(v, OP_String8, 0, regTmp, 0, zErr, 0);
            sqlite4VdbeAddOp3(v, OP_Concat, regTmp, regErrstr, regErrstr);
Changes to src/select.c.
431
432
433
434
435
436
437

438
439
440
441
442
443
444
445
446
447
448
  ** number. The sequence number allows more than one row with the same
  ** sort-key.  */
  sqlite4ExprCacheClear(pParse);
  sqlite4ExprCodeExprList(pParse, pOrderBy, regBase, 0);
  sqlite4VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr);

  /* Encode the sort-key. */

  sqlite4VdbeAddOp3(v, OP_MakeIdxKey, pOrderBy->iECursor, regBase, regKey);

  /* Insert an entry into the sorter. The key inserted is the encoded key
  ** created by the OP_MakeIdxKey coded above. The value is the record
  ** currently stored in register regData.  */
  sqlite4VdbeAddOp3(v, OP_Insert, pOrderBy->iECursor, regData, regKey);

  /* Release the temporary registers */
  sqlite4ReleaseTempReg(pParse, regKey);
  sqlite4ReleaseTempRange(pParse, regBase, nExpr+1);








>
|


|







431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
  ** number. The sequence number allows more than one row with the same
  ** sort-key.  */
  sqlite4ExprCacheClear(pParse);
  sqlite4ExprCodeExprList(pParse, pOrderBy, regBase, 0);
  sqlite4VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr);

  /* Encode the sort-key. */
  sqlite4VdbeAddOp4Int(v, OP_MakeKey, regBase, nExpr+1, regKey,
                       pOrderBy->iECursor);

  /* Insert an entry into the sorter. The key inserted is the encoded key
  ** created by the OP_MakeKey coded above. The value is the record
  ** currently stored in register regData.  */
  sqlite4VdbeAddOp3(v, OP_Insert, pOrderBy->iECursor, regData, regKey);

  /* Release the temporary registers */
  sqlite4ReleaseTempReg(pParse, regKey);
  sqlite4ReleaseTempRange(pParse, regBase, nExpr+1);

501
502
503
504
505
506
507
508
509

510
511
512
513
514
515
516
  Vdbe *v;
  int r1, r2;

  v = pParse->pVdbe;
  r1 = sqlite4GetTempReg(pParse);
  r2 = sqlite4GetTempReg(pParse);
  sqlite4VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N);
  sqlite4VdbeAddOp2(v, OP_MakeKey, iTab, r2);
  sqlite4VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1);

  sqlite4VdbeAddOp3(v, OP_Insert, iTab, r1, r2);
  sqlite4ReleaseTempReg(pParse, r1);
  sqlite4ReleaseTempReg(pParse, r2);
}

#ifndef SQLITE4_OMIT_SUBQUERY
/*







|

>







502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
  Vdbe *v;
  int r1, r2;

  v = pParse->pVdbe;
  r1 = sqlite4GetTempReg(pParse);
  r2 = sqlite4GetTempReg(pParse);
  sqlite4VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N);
  sqlite4VdbeAddOp4Int(v, OP_MakeKey, iMem, N, r2, iTab);
  sqlite4VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1);
  sqlite4VdbeChangeP5(v, OPFLAG_USEKEY);
  sqlite4VdbeAddOp3(v, OP_Insert, iTab, r1, r2);
  sqlite4ReleaseTempReg(pParse, r1);
  sqlite4ReleaseTempReg(pParse, r2);
}

#ifndef SQLITE4_OMIT_SUBQUERY
/*
619
620
621
622
623
624
625
626
627

628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
    ** table iParm.
    */
#ifndef SQLITE4_OMIT_COMPOUND_SELECT
    case SRT_Union: {
      int r1, r2;
      r1 = sqlite4GetTempReg(pParse);
      r2 = sqlite4GetTempReg(pParse);
      sqlite4VdbeAddOp2(v, OP_MakeKey, iParm, r2);
      sqlite4VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);

      sqlite4VdbeAddOp3(v, OP_Insert, iParm, r1, r2);
      sqlite4ReleaseTempReg(pParse, r1);
      sqlite4ReleaseTempReg(pParse, r2);
      break;
    }

    /* This is used for processing queries of the form:
    **
    **     <select-1> EXCEPT <select-2>
    **
    ** Temporary index iParm contains the results of <select-1>. This
    ** code is processing the results of <select-2>. For each row of
    ** <select-2>, remove any identical row from iParm.  */
    case SRT_Except: {
      int regKey = sqlite4GetTempReg(pParse);
      sqlite4VdbeAddOp4Int(v, OP_MakeIdxKey, iParm, regResult, regKey, 0);
      sqlite4VdbeAddOp3(v, OP_IdxDelete, iParm, 0, regKey);
      sqlite4ReleaseTempReg(pParse, regKey);
      break;
    }
#endif

    /* Store the result as data using a unique key.
    */
    case SRT_Table:
    case SRT_EphemTab: {
      int r1 = sqlite4GetTempReg(pParse);
      testcase( eDest==SRT_Table );
      testcase( eDest==SRT_EphemTab );
      sqlite4VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
      if( pOrderBy ){
        pushOntoSorter(pParse, pOrderBy, p, r1);
      }else{
        int r2 = sqlite4GetTempReg(pParse);
        sqlite4VdbeAddOp2(v, OP_NewRowid, iParm, r2);
        sqlite4VdbeAddOp3(v, OP_Insert, iParm, r1, r2);
        sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
        sqlite4ReleaseTempReg(pParse, r2);
      }
      sqlite4ReleaseTempReg(pParse, r1);
      break;
    }

#ifndef SQLITE4_OMIT_SUBQUERY







|

>















|




















<







621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666

667
668
669
670
671
672
673
    ** table iParm.
    */
#ifndef SQLITE4_OMIT_COMPOUND_SELECT
    case SRT_Union: {
      int r1, r2;
      r1 = sqlite4GetTempReg(pParse);
      r2 = sqlite4GetTempReg(pParse);
      sqlite4VdbeAddOp4Int(v, OP_MakeKey, regResult, nColumn, r2, iParm);
      sqlite4VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
      sqlite4VdbeChangeP5(v, OPFLAG_USEKEY);
      sqlite4VdbeAddOp3(v, OP_Insert, iParm, r1, r2);
      sqlite4ReleaseTempReg(pParse, r1);
      sqlite4ReleaseTempReg(pParse, r2);
      break;
    }

    /* This is used for processing queries of the form:
    **
    **     <select-1> EXCEPT <select-2>
    **
    ** Temporary index iParm contains the results of <select-1>. This
    ** code is processing the results of <select-2>. For each row of
    ** <select-2>, remove any identical row from iParm.  */
    case SRT_Except: {
      int regKey = sqlite4GetTempReg(pParse);
      sqlite4VdbeAddOp4Int(v, OP_MakeKey, regResult, nColumn, regKey, iParm);
      sqlite4VdbeAddOp3(v, OP_IdxDelete, iParm, 0, regKey);
      sqlite4ReleaseTempReg(pParse, regKey);
      break;
    }
#endif

    /* Store the result as data using a unique key.
    */
    case SRT_Table:
    case SRT_EphemTab: {
      int r1 = sqlite4GetTempReg(pParse);
      testcase( eDest==SRT_Table );
      testcase( eDest==SRT_EphemTab );
      sqlite4VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
      if( pOrderBy ){
        pushOntoSorter(pParse, pOrderBy, p, r1);
      }else{
        int r2 = sqlite4GetTempReg(pParse);
        sqlite4VdbeAddOp2(v, OP_NewRowid, iParm, r2);
        sqlite4VdbeAddOp3(v, OP_Insert, iParm, r1, r2);

        sqlite4ReleaseTempReg(pParse, r2);
      }
      sqlite4ReleaseTempReg(pParse, r1);
      break;
    }

#ifndef SQLITE4_OMIT_SUBQUERY
682
683
684
685
686
687
688
689
690
691


692
693
694
695
696
697
698
        ** ORDER BY in this case since the order of entries in the set
        ** does not matter.  But there might be a LIMIT clause, in which
        ** case the order does matter */
        sqlite4VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1);
        pushOntoSorter(pParse, pOrderBy, p, r1);
      }else{
        int r2 = sqlite4GetTempReg(pParse);
        sqlite4VdbeAddOp2(v, OP_MakeKey, iParm, r2);
        sqlite4VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1);
        sqlite4ExprCacheAffinityChange(pParse, regResult, 1);


        sqlite4VdbeAddOp3(v, OP_Insert, iParm, r1, r2);
        sqlite4ReleaseTempReg(pParse, r2);
      }
      sqlite4ReleaseTempReg(pParse, r1);
      break;
    }








|
|

>
>







684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
        ** ORDER BY in this case since the order of entries in the set
        ** does not matter.  But there might be a LIMIT clause, in which
        ** case the order does matter */
        sqlite4VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1);
        pushOntoSorter(pParse, pOrderBy, p, r1);
      }else{
        int r2 = sqlite4GetTempReg(pParse);
        sqlite4VdbeAddOp4(v, OP_Affinity, regResult, 1, 0, &p->affinity, 1);
        sqlite4VdbeAddOp4Int(v, OP_MakeKey, regResult, 1, r2, iParm);
        sqlite4ExprCacheAffinityChange(pParse, regResult, 1);
        sqlite4VdbeAddOp3(v, OP_MakeRecord, regResult, 1, r1);
        sqlite4VdbeChangeP5(v, OPFLAG_USEKEY);
        sqlite4VdbeAddOp3(v, OP_Insert, iParm, r1, r2);
        sqlite4ReleaseTempReg(pParse, r2);
      }
      sqlite4ReleaseTempReg(pParse, r1);
      break;
    }

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
      int regRowid = sqlite4GetTempReg(pParse);
      int regRow = sqlite4GetTempReg(pParse);
      testcase( eDest==SRT_Table );
      testcase( eDest==SRT_EphemTab );
      sqlite4VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
      sqlite4VdbeAddOp2(v, OP_RowData, iTab, regRow);
      sqlite4VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
      sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
      sqlite4ReleaseTempReg(pParse, regRow);
      sqlite4ReleaseTempReg(pParse, regRowid);
      break;
    }
#ifndef SQLITE4_OMIT_SUBQUERY
    case SRT_Set: {
      int regRes = sqlite4GetTempReg(pParse);
      int regKey = sqlite4GetTempReg(pParse);
      int regValue = sqlite4GetTempReg(pParse);
      assert( nColumn==1 );
      sqlite4VdbeAddOp3(v, OP_Column, iTab, 0, regRes);
      sqlite4VdbeAddOp2(v, OP_MakeKey, iParm, regKey);


      sqlite4VdbeAddOp4(v, OP_MakeRecord, regRes, 1, regValue, &p->affinity, 1);

      sqlite4VdbeAddOp3(v, OP_Insert, iParm, regValue, regKey);
      sqlite4ReleaseTempReg(pParse, regKey);
      sqlite4ReleaseTempReg(pParse, regRes);
      sqlite4ReleaseTempReg(pParse, regValue);
      break;
    }
    case SRT_Mem: {







<











|
>
>
|
>







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
      int regRowid = sqlite4GetTempReg(pParse);
      int regRow = sqlite4GetTempReg(pParse);
      testcase( eDest==SRT_Table );
      testcase( eDest==SRT_EphemTab );
      sqlite4VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
      sqlite4VdbeAddOp2(v, OP_RowData, iTab, regRow);
      sqlite4VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);

      sqlite4ReleaseTempReg(pParse, regRow);
      sqlite4ReleaseTempReg(pParse, regRowid);
      break;
    }
#ifndef SQLITE4_OMIT_SUBQUERY
    case SRT_Set: {
      int regRes = sqlite4GetTempReg(pParse);
      int regKey = sqlite4GetTempReg(pParse);
      int regValue = sqlite4GetTempReg(pParse);
      assert( nColumn==1 );
      sqlite4VdbeAddOp3(v, OP_Column, iTab, 0, regRes);
      sqlite4VdbeAddOp4(v, OP_Affinity, regRes, 1, 0, &p->affinity, 1);
      sqlite4VdbeAddOp4Int(v, OP_MakeKey, regRes, 1, regKey, iParm);
      sqlite4ExprCacheAffinityChange(pParse, regRes, 1);
      sqlite4VdbeAddOp3(v, OP_MakeRecord, regRes, 1, regValue);
      sqlite4VdbeChangeP5(v, OPFLAG_USEKEY);
      sqlite4VdbeAddOp3(v, OP_Insert, iParm, regValue, regKey);
      sqlite4ReleaseTempReg(pParse, regKey);
      sqlite4ReleaseTempReg(pParse, regRes);
      sqlite4ReleaseTempReg(pParse, regValue);
      break;
    }
    case SRT_Mem: {
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995



1996
1997
1998
1999
2000
2001
2002
      int r1 = sqlite4GetTempReg(pParse);
      int r2 = sqlite4GetTempReg(pParse);
      testcase( pDest->eDest==SRT_Table );
      testcase( pDest->eDest==SRT_EphemTab );
      sqlite4VdbeAddOp3(v, OP_MakeRecord, pIn->iMem, pIn->nMem, r1);
      sqlite4VdbeAddOp2(v, OP_NewRowid, pDest->iParm, r2);
      sqlite4VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2);
      sqlite4VdbeChangeP5(v, OPFLAG_APPEND);
      sqlite4ReleaseTempReg(pParse, r2);
      sqlite4ReleaseTempReg(pParse, r1);
      break;
    }

#ifndef SQLITE4_OMIT_SUBQUERY
    /* If we are creating a set for an "expr IN (SELECT ...)" construct,
    ** then there should be a single item on the stack.  Write this
    ** item into the set table with bogus data.
    */
    case SRT_Set: {
      int r1, r2;
      assert( pIn->nMem==1 );
      p->affinity = 
         sqlite4CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity);
      r1 = sqlite4GetTempReg(pParse);
      r2 = sqlite4GetTempReg(pParse);
      sqlite4VdbeAddOp2(v, OP_MakeKey, pDest->iParm, r2);
      sqlite4VdbeAddOp4(v, OP_MakeRecord, pIn->iMem, 1, r1, &p->affinity, 1);
      sqlite4ExprCacheAffinityChange(pParse, pIn->iMem, 1);



      sqlite4VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2);
      sqlite4ReleaseTempReg(pParse, r1);
      sqlite4ReleaseTempReg(pParse, r2);
      break;
    }

#if 0  /* Never occurs on an ORDER BY query */







<

















<
|

>
>
>







1974
1975
1976
1977
1978
1979
1980

1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997

1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
      int r1 = sqlite4GetTempReg(pParse);
      int r2 = sqlite4GetTempReg(pParse);
      testcase( pDest->eDest==SRT_Table );
      testcase( pDest->eDest==SRT_EphemTab );
      sqlite4VdbeAddOp3(v, OP_MakeRecord, pIn->iMem, pIn->nMem, r1);
      sqlite4VdbeAddOp2(v, OP_NewRowid, pDest->iParm, r2);
      sqlite4VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2);

      sqlite4ReleaseTempReg(pParse, r2);
      sqlite4ReleaseTempReg(pParse, r1);
      break;
    }

#ifndef SQLITE4_OMIT_SUBQUERY
    /* If we are creating a set for an "expr IN (SELECT ...)" construct,
    ** then there should be a single item on the stack.  Write this
    ** item into the set table with bogus data.
    */
    case SRT_Set: {
      int r1, r2;
      assert( pIn->nMem==1 );
      p->affinity = 
         sqlite4CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity);
      r1 = sqlite4GetTempReg(pParse);
      r2 = sqlite4GetTempReg(pParse);

      sqlite4VdbeAddOp4(v, OP_Affinity, pIn->iMem, 1, 0, &p->affinity, 1);
      sqlite4ExprCacheAffinityChange(pParse, pIn->iMem, 1);
      sqlite4VdbeAddOp4Int(v, OP_MakeKey, pIn->iMem, 1, r2, pDest->iParm);
      sqlite4VdbeAddOp3(v, OP_MakeRecord, pIn->iMem, 1, r1);
      sqlite4VdbeChangeP5(v, OPFLAG_USEKEY);
      sqlite4VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2);
      sqlite4ReleaseTempReg(pParse, r1);
      sqlite4ReleaseTempReg(pParse, r2);
      break;
    }

#if 0  /* Never occurs on an ORDER BY query */
4151
4152
4153
4154
4155
4156
4157

4158
4159
4160
4161
4162
4163
4164
4165
        /* Encode the key for the sorting index. The key consists of each
        ** of the expressions in the GROUP BY list followed by a sequence
        ** number (to ensure each key is unique - the point of this is just
        ** to sort the rows, not to eliminate duplicates).  */
        sqlite4ExprCacheClear(pParse);
        regBase = sqlite4GetTempRange(pParse, nGroup);
        sqlite4ExprCodeExprList(pParse, pGroupBy, regBase, 0);

        sqlite4VdbeAddOp3(v, OP_MakeIdxKey, sAggInfo.sortingIdx,regBase,regKey);
        sqlite4VdbeChangeP5(v, OPFLAG_SEQCOUNT);
        sqlite4ReleaseTempRange(pParse, regBase, nGroup);

        /* Encode the record for the sorting index. The record contains all
        ** required column values from the elements of the FROM clause.  
        ** If no column values are required, insert a NULL into the sorting
        ** index instead of a record. No column values are required for 







>
|







4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
        /* Encode the key for the sorting index. The key consists of each
        ** of the expressions in the GROUP BY list followed by a sequence
        ** number (to ensure each key is unique - the point of this is just
        ** to sort the rows, not to eliminate duplicates).  */
        sqlite4ExprCacheClear(pParse);
        regBase = sqlite4GetTempRange(pParse, nGroup);
        sqlite4ExprCodeExprList(pParse, pGroupBy, regBase, 0);
        sqlite4VdbeAddOp4Int(v, OP_MakeKey, regBase, nGroup, regKey, 
                                sAggInfo.sortingIdx);
        sqlite4VdbeChangeP5(v, OPFLAG_SEQCOUNT);
        sqlite4ReleaseTempRange(pParse, regBase, nGroup);

        /* Encode the record for the sorting index. The record contains all
        ** required column values from the elements of the FROM clause.  
        ** If no column values are required, insert a NULL into the sorting
        ** index instead of a record. No column values are required for 
Changes to src/sqliteInt.h.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
** The KeyInfo for addrOpenTran[0] and [1] contains collating sequences
** for the result set.  The KeyInfo for addrOpenTran[2] contains collating
** sequences for the ORDER BY clause.
*/
struct Select {
  ExprList *pEList;      /* The fields of the result */
  u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
  char affinity;         /* MakeRecord with this affinity for SRT_Set */
  u16 selFlags;          /* Various SF_* values */
  SrcList *pSrc;         /* The FROM clause */
  Expr *pWhere;          /* The WHERE clause */
  ExprList *pGroupBy;    /* The GROUP BY clause */
  Expr *pHaving;         /* The HAVING clause */
  ExprList *pOrderBy;    /* The ORDER BY clause */
  Select *pPrior;        /* Prior select in a compound select statement */







|







2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
** The KeyInfo for addrOpenTran[0] and [1] contains collating sequences
** for the result set.  The KeyInfo for addrOpenTran[2] contains collating
** sequences for the ORDER BY clause.
*/
struct Select {
  ExprList *pEList;      /* The fields of the result */
  u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
  char affinity;         /* EncodeData with this affinity for SRT_Set */
  u16 selFlags;          /* Various SF_* values */
  SrcList *pSrc;         /* The FROM clause */
  Expr *pWhere;          /* The WHERE clause */
  ExprList *pGroupBy;    /* The GROUP BY clause */
  Expr *pHaving;         /* The HAVING clause */
  ExprList *pOrderBy;    /* The ORDER BY clause */
  Select *pPrior;        /* Prior select in a compound select statement */
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
  Parse *pParse;              /* The Parse structure */
};

/*
** Bitfield flags for P5 value in OP_Insert and OP_Delete
*/
#define OPFLAG_NCHANGE       0x01    /* Set to update db->nChange */
#define OPFLAG_PARTIALKEY    0x02    /* Not all values given to OP_MakeIdxKey */
#define OPFLAG_ISUPDATE      0x04    /* This OP_Insert is an sql UPDATE */
#define OPFLAG_APPEND        0x08    /* This is likely to be an append */
#define OPFLAG_SEQCOUNT      0x10    /* Append sequence number to key */
#define OPFLAG_CLEARCACHE    0x20    /* Clear pseudo-table cache in OP_Column */
#define OPFLAG_APPENDBIAS    0x40    /* Bias inserts for appending */

/*
 * Each trigger present in the database schema is stored as an instance of
 * struct Trigger. 
 *
 * Pointers to instances of struct Trigger are stored in two ways.
 * 1. In the "trigHash" hash table (part of the sqlite4* that represents the 







<
|
|
|
|
<







2247
2248
2249
2250
2251
2252
2253

2254
2255
2256
2257

2258
2259
2260
2261
2262
2263
2264
  Parse *pParse;              /* The Parse structure */
};

/*
** Bitfield flags for P5 value in OP_Insert and OP_Delete
*/
#define OPFLAG_NCHANGE       0x01    /* Set to update db->nChange */

#define OPFLAG_ISUPDATE      0x02    /* This OP_Insert is an sql UPDATE */
#define OPFLAG_USEKEY        0x04    /* Optimize OP_EncodeData using key content */
#define OPFLAG_SEQCOUNT      0x08    /* Append sequence number to key */
#define OPFLAG_CLEARCACHE    0x10    /* Clear pseudo-table cache in OP_Column */


/*
 * Each trigger present in the database schema is stored as an instance of
 * struct Trigger. 
 *
 * Pointers to instances of struct Trigger are stored in two ways.
 * 1. In the "trigHash" hash table (part of the sqlite4* that represents the 
Changes to src/vdbe.c.
2130
2131
2132
2133
2134
2135
2136













































































































2137
2138
2139
2140
2141
2142
2143
  }else{
    sqlite4VdbeMemSetNull(pDest);
  }
  UPDATE_MAX_BLOBSIZE(pDest);
  REGISTER_TRACE(pOp->p3, pDest);
  break;
}














































































































/* Opcode: Affinity P1 P2 * P4 *
**
** Apply affinities to a range of P2 registers starting with P1.
**
** P4 is a string that is P2 characters long. The nth character of the
** string indicates the column affinity that should be used for the nth







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







2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
  }else{
    sqlite4VdbeMemSetNull(pDest);
  }
  UPDATE_MAX_BLOBSIZE(pDest);
  REGISTER_TRACE(pOp->p3, pDest);
  break;
}

/* Opcode:  MakeKey  P1 P2 P3 P4 P5
**
** Encode the values in registers P1..P1+P2-1 using the key encoding
** and write the result into register P3.  The cursor used for the encoding
** is given by the P4 value which must be an integer (P4_INT32).
**
** If the OPFLAG_SEQCOUNT bit of P5 is set, then a sequence number 
** (unique within the cursor) is appended to the record. The sole purpose
** of this is to ensure that the key blob is unique within the cursor table.
*/
/* Opcode:  MakeRecord  P1 P2 P3 P4 P5
**
** Encode the values in registers P1..P1+P2-1 using the data encoding
** and write the result into register P3.  Apply affinities in P4 prior
** to performing the encoding.
**
** If the OPFLAG_USEKEY bit of P5 is set and this opcode immediately follows
** an MakeKey opcode, then the data encoding generated may try to refer
** to content in the previously generated key in order to make the encoding
** smaller.
*/
case OP_MakeKey:
case OP_MakeRecord: {
  VdbeCursor *pC;        /* The cursor for OP_MakeKey */
  Mem *pData0;           /* First field to be combined into the record */
  Mem *pLast;            /* Last field of the record */
  Mem *pMem;             /* For looping over inputs */
  Mem *pOut;             /* Where to store results */
  int nIn;               /* Number of input values to be encoded */
  char *zAffinity;       /* The affinity string */
  u8 *aRec;              /* The constructed key or value */
  int nRec;              /* Size of aRec[] in bytes */
  int bRepeat;           /* True to loop to the next opcode */
  u8 aSeq[10];           /* Encoded sequence number */
  int nSeq;              /* Size of sequence number in bytes */
  u64 iSeq;              /* Sequence number, if any */

  do{
    bRepeat = 0;
    zAffinity = pOp->p4type==P4_INT32 ? 0 : pOp->p4.z;
    assert( pOp->p1>0 && pOp->p2>0 && pOp->p2+pOp->p1<=p->nMem+1 );
    pData0 = &aMem[pOp->p1];
    nIn = pOp->p2;
    pLast = &pData0[nIn-1];
    assert( pOp->p3>0 && pOp->p3<=p->nMem );
    pOut = &aMem[pOp->p3];
    memAboutToChange(p, pOut);
    aRec = 0;
    nSeq = 0;

    /* Apply affinities */
    if( zAffinity ){
      for(pMem=pData0; pMem<=pLast; pMem++){
        assert( memIsValid(pMem) );
        applyAffinity(pMem, *(zAffinity++), encoding);
      }
    }

    if( pOp->opcode==OP_MakeKey ){
      assert( pOp->p4type==P4_INT32 );
      assert( pOp->p4.i>=0 && pOp->p4.i<p->nCursor );
      pC = p->apCsr[pOp->p4.i];

      /* If P4 contains OPFLAG_SEQCOUNT, encode the sequence number blob to be
      ** appended to the end of the key.  Variable nSeq is set to the number
      ** of bytes in the encoded key.  A non-standard encoding is used (not
      ** the usual varint encoding) so that the OP_GrpCompare opcode can easily
      ** back up over the sequence count to find the true end of the key.
      */
      if( pOp->p5 & OPFLAG_SEQCOUNT ){
        iSeq = pC->seqCount++;
        do {
          nSeq++;
          aSeq[sizeof(aSeq)-nSeq] = (u8)(iSeq & 0x007F);
          iSeq = iSeq >> 7;
        }while( iSeq );
        aSeq[sizeof(aSeq)-nSeq] |= 0x80;
      }

      /* Generate the key encoding */
      rc = sqlite4VdbeEncodeKey(
        db, pData0, nIn, pC->iRoot, pC->pKeyInfo, &aRec, &nRec, nSeq
      );
      
      if( pOp[1].opcode==OP_MakeRecord ){
        pc++;
        pOp++;
        bRepeat = 1;
      }
    }else{
      assert( pOp->opcode==OP_MakeRecord );
      rc = sqlite4VdbeEncodeData(db, pData0, aPermute, nIn, &aRec, &nRec);
      aPermute = 0;
    } 

    /* Store the result */
    if( rc!=SQLITE4_OK ){
      sqlite4DbFree(db, aRec);
    }else{
      if( nSeq ) memcpy(&aRec[nRec], &aSeq[sizeof(aSeq)-nSeq], nSeq);
      rc = sqlite4VdbeMemSetStr(pOut, (char *)aRec, nRec+nSeq, 0,
                                SQLITE4_DYNAMIC, 0);
      REGISTER_TRACE(pOp->p3, pOut);
      UPDATE_MAX_BLOBSIZE(pOut);
    }
  }while( rc==SQLITE4_OK && bRepeat );
  break;
}

/* Opcode: Affinity P1 P2 * P4 *
**
** Apply affinities to a range of P2 registers starting with P1.
**
** P4 is a string that is P2 characters long. The nth character of the
** string indicates the column affinity that should be used for the nth
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
    applyAffinity(pIn1, *(zAffinity++), encoding);
    REGISTER_TRACE(pIn1-aMem, pIn1);
  }

  break;
}

/* Opcode: MakeIdxKey P1 P2 P3 P4 P5
**
** P1 is an open cursor. P2 is the first register in a contiguous array
** of N registers containing values to encode into a database key. Normally,
** N is taken from the KeyInfo object of P1.  However, of P4 is a positive
** integer, P4 is used for N instead.
**
** This instruction encodes the N values into a database key and writes
** the result to register P3. No affinity transformations are applied to 
** the input values before they are encoded. 
**
** If the OPFLAG_SEQCOUNT bit of P5 is set, then a sequence number 
** (unique within the cursor) is appended to the record. The sole purpose
** of this is to ensure that the key blob is unique within the cursor table.
**
** If the OPFLAG_PARTIALKEY bit of P5 is set, that means the value supplied
** for N is not the true number of values in the key, only the number that
** need to be encoded for this operation.  This effects the encoding of
** final BLOBs.
*/
case OP_MakeIdxKey: {
  VdbeCursor *pC;
  KeyInfo *pKeyInfo;
  Mem *pData0;                    /* First in array of input registers */
  u8 *aRec;                       /* The constructed database key */
  int nRec;                       /* Size of aRec[] in bytes */
  int nField;                     /* Number of fields in encoded record */
  u8 aSeq[10];                    /* Encoded sequence number */
  int nSeq;                       /* Size of sequence number in bytes */
  u64 iSeq;                       /* Sequence number, if any */
  
  pC = p->apCsr[pOp->p1];
  pKeyInfo = pC->pKeyInfo;
  pData0 = &aMem[pOp->p2];
  pOut = &aMem[pOp->p3];
  aRec = 0;

  /* If P4 contains OPFLAG_SEQCOUNT, encode the sequence number blob to be
  ** appended to the end of the key.  Variable nSeq is set to the number
  ** of bytes in the encoded key.  A non-standard encoding is used (not
  ** the usual varint encoding) so that the OP_GrpCompare opcode can easily
  ** back up over the sequence count to find the true end of the key.
  */
  nSeq = 0;
  if( pOp->p5 & OPFLAG_SEQCOUNT ){
    iSeq = pC->seqCount++;
    do {
      nSeq++;
      aSeq[sizeof(aSeq)-nSeq] = (u8)(iSeq & 0x007F);
      iSeq = iSeq >> 7;
    }while( iSeq );
    aSeq[sizeof(aSeq)-nSeq] |= 0x80;
  }

  memAboutToChange(p, pOut);

  if( pOp->p4type==P4_INT32 && pOp->p4.i>0 ){
    nField = pOp->p4.i;
    assert( nField<=pKeyInfo->nField );
  }else{
    nField = pKeyInfo->nField;
  }
  rc = sqlite4VdbeEncodeKey(
    db, pData0, nField, pKeyInfo->nField,
    pC->iRoot, pKeyInfo, &aRec, &nRec, nSeq
  );

  if( rc ){
    sqlite4DbFree(db, aRec);
  }else{
    if( nSeq ){
      memcpy(&aRec[nRec], &aSeq[sizeof(aSeq)-nSeq], nSeq);
    }
    rc = sqlite4VdbeMemSetStr(pOut, (char *)aRec, nRec+nSeq, 0,
                              SQLITE4_DYNAMIC, 0);
    REGISTER_TRACE(pOp->p3, pOut);
    UPDATE_MAX_BLOBSIZE(pOut);
  }

  break;
}

/* Opcode: MakeKey P1 P2 * * *
**
** This must be followed immediately by a MakeRecord opcode.  This
** opcode performs the subsequent MakeRecord and also generates
** a key for the cursor P1 and stores that key in register P2.
*/
/* Opcode: MakeRecord P1 P2 P3 P4 *
**
** This opcode uses the array of P2 registers starting at P1 as inputs.
**
** P4 may be a string that is P2 characters long, or it may be NULL. The nth 
** character of the string indicates the column affinity that should be used
** for the nth field of the index key. The mapping from character to affinity
** is given by the SQLITE4_AFF_ macros defined in sqliteInt.h. If P4 is NULL
** then all index fields have the affinity NONE.
**
** If this instruction is immediately preceded by OP_Permutation, then the
** specified permutation is used to determine the order that registers are
** used to build the record.  The i-th column of the record is taken from
** register P1+aPermute[i].  If OP_Permutation has not been run, then the i-th
** column comes from register P1+i.
**
** This opcode applies the affinities that it specifies to the input
** array elements. Then, if P3 is not 0, it encodes the input array
** into a data record and stores the result in register P3. The OP_Column 
** opcode can be used to decode the record.
**
** Specifying P3==0 is only useful if the previous opcode is an OP_MakeKey.
*/
case OP_MakeKey:
case OP_MakeRecord: {
  Mem *pData0;           /* First field to be combined into the record */
  Mem *pLast;            /* Last field of the record */
  Mem *pMem;             /* For looping over inputs */
  int nField;            /* Number of fields in the record */
  char *zAffinity;       /* The affinity string for the record */
  VdbeCursor *pC;        /* Cursor to generate key for */
  Mem *pKeyOut;          /* Where to store the generated key */
  int keyReg;            /* Register into which to write the key */
  u8 *aRec;              /* The constructed key or value */
  int nRec;              /* Size of aRec[] in bytes */

  assert( aPermute==0 || pOp->opcode!=OP_MakeKey );
  assert( aPermute==0 || pOp->p4type==P4_NOTUSED );
  assert( aPermute==0 || pOp->p3 );

  if( pOp->opcode==OP_MakeKey ){
    pC = p->apCsr[pOp->p1];
    keyReg = pOp->p2;
    pKeyOut = &aMem[keyReg];
    memAboutToChange(p, pKeyOut);
    assert( pC!=0 );
    assert( pC->pKeyInfo!=0 );
    pc++;
    pOp++;
    assert( pOp->opcode==OP_MakeRecord );
#ifdef SQLITE4_DEBUG
    if( p->trace ) sqlite4VdbePrintOp(p->trace, pc, pOp);
#endif
  }else{
    pC = 0;
  }
  zAffinity = pOp->p4.z;
  assert( pOp->p1>0 && pOp->p2>0 && pOp->p2+pOp->p1<=p->nMem+1 );
  pData0 = &aMem[pOp->p1];
  nField = pOp->p2;
  pLast = &pData0[nField-1];

  /* Loop through the input elements.  Apply affinity to each one and
  ** expand all zero-blobs.
  */
  for(pMem=pData0; pMem<=pLast; pMem++){
    assert( memIsValid(pMem) );
    if( zAffinity ){
      applyAffinity(pMem, *(zAffinity++), encoding);
    }
  }

  /* Compute the key (if this is a MakeKey opcode) */
  if( pC ){
    aRec = 0;
    rc = sqlite4VdbeEncodeKey(db, 
        pData0, pC->pKeyInfo->nField, pC->pKeyInfo->nField,
        pC->iRoot, pC->pKeyInfo, &aRec, &nRec, 0
    );
    if( rc ){
      sqlite4DbFree(db, aRec);
    }else{
      rc = sqlite4VdbeMemSetStr(pKeyOut, (char *)aRec, nRec, 0,
                                SQLITE4_DYNAMIC, 0);
      REGISTER_TRACE(keyReg, pKeyOut);
      UPDATE_MAX_BLOBSIZE(pKeyOut);
    }
  }

  /* If P3 is not 0, compute the data record */
  if( rc==SQLITE4_OK && pOp->p3 ){
    assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
    pOut = &aMem[pOp->p3];
    memAboutToChange(p, pOut);
    aRec = 0;
    rc = sqlite4VdbeEncodeData(db, pData0, aPermute, nField, &aRec, &nRec);
    if( rc ){
      sqlite4DbFree(db, aRec);
    }else{
      rc = sqlite4VdbeMemSetStr(pOut, (char *)aRec, nRec, 0, SQLITE4_DYNAMIC,0);
      REGISTER_TRACE(pOp->p3, pOut);
      UPDATE_MAX_BLOBSIZE(pOut);
    }
  }
  aPermute = 0;
  break;
}

/* Opcode: Count P1 P2 * * *
**
** Store the number of entries (an integer value) in the table or index 
** opened by cursor P1 in register P2
*/
case OP_Count: {         /* out2-prerelease */
  i64 nEntry;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2267
2268
2269
2270
2271
2272
2273




































































































































































































2274
2275
2276
2277
2278
2279
2280
    applyAffinity(pIn1, *(zAffinity++), encoding);
    REGISTER_TRACE(pIn1-aMem, pIn1);
  }

  break;
}





































































































































































































/* Opcode: Count P1 P2 * * *
**
** Store the number of entries (an integer value) in the table or index 
** opened by cursor P1 in register P2
*/
case OP_Count: {         /* out2-prerelease */
  i64 nEntry;
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
  /* Encode a database key consisting of the contents of the P4 registers
  ** starting at register P3. Have the vdbecodec module allocate an extra
  ** free byte at the end of the database key (see below).  */
  nField = pOp->p4.i;
  pIn3 = &aMem[pOp->p3];
  if( pC->iRoot!=KVSTORE_ROOT ){
    rc = sqlite4VdbeEncodeKey(
        db, pIn3, nField, nField+(pOp->p5 & OPFLAG_PARTIALKEY),
        pC->iRoot, pC->pKeyInfo, &aProbe, &nProbe, 1
    );

    /*   Opcode    search-dir    increment-key
    **  --------------------------------------
    **   SeekLt    -1            no
    **   SeekLe    -1            yes
    **   SeekGe    +1            no







<
|







2871
2872
2873
2874
2875
2876
2877

2878
2879
2880
2881
2882
2883
2884
2885
  /* Encode a database key consisting of the contents of the P4 registers
  ** starting at register P3. Have the vdbecodec module allocate an extra
  ** free byte at the end of the database key (see below).  */
  nField = pOp->p4.i;
  pIn3 = &aMem[pOp->p3];
  if( pC->iRoot!=KVSTORE_ROOT ){
    rc = sqlite4VdbeEncodeKey(

        db, pIn3, nField, pC->iRoot, pC->pKeyInfo, &aProbe, &nProbe, 1
    );

    /*   Opcode    search-dir    increment-key
    **  --------------------------------------
    **   SeekLt    -1            no
    **   SeekLe    -1            yes
    **   SeekGe    +1            no
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052

  if( rc==SQLITE4_NOTFOUND ){
    rc = SQLITE4_OK;
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: Seek P1 P2 * * *
**
** P1 is an open table cursor and P2 is a rowid integer.  Arrange
** for P1 to move so that it points to the rowid given by P2.
*/
case OP_Seek: {    /* in2 */
  VdbeCursor *pC;
  KVCursor *pKVCur;
  KVByteArray *aKey;
  KVSize nKey;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  pC->rowChnged = 1;
  assert( pC!=0 );
  pKVCur = pC->pKVCur;
  rc = sqlite4VdbeEncodeKey(db, aMem+pOp->p2, 1, 1, pC->iRoot, 0,
                            &aKey, &nKey, 0);
  if( rc==SQLITE4_OK ){
    rc = sqlite4KVCursorSeek(pKVCur, aKey, nKey, 0);
    if( rc==SQLITE4_NOTFOUND ) rc = SQLITE4_CORRUPT_BKPT;
  }
  sqlite4DbFree(db, aKey);
  break;
}
  

/* Opcode: Found P1 P2 P3 P4 *
**
** If P4==0 then register P3 holds a blob constructed by MakeKey.  If
** P4>0 then register P3 is the first of P4 registers that should be
** combined to generate a key.
**







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2924
2925
2926
2927
2928
2929
2930
2931


























2932
2933
2934
2935
2936
2937
2938

  if( rc==SQLITE4_NOTFOUND ){
    rc = SQLITE4_OK;
    pc = pOp->p2 - 1;
  }
  break;
}
 



























/* Opcode: Found P1 P2 P3 P4 *
**
** If P4==0 then register P3 holds a blob constructed by MakeKey.  If
** P4>0 then register P3 is the first of P4 registers that should be
** combined to generate a key.
**
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
** Use the content of register P3 as an integer key.  If a record 
** with that key does not exist in table of P1, then jump to P2. 
** If the record does exist, then fall through.  The cursor is left 
** pointing to the record if it exists.
**
** The difference between this operation and NotFound is that this
** operation assumes the key is an integer and that P1 is a table whereas
** NotFound assumes key is a blob constructed from MakeRecord and
** P1 is an index.
**
** See also: Found, NotFound, IsUnique
*/
case OP_NotExists: {    /* jump, in3 */
  pOp->p4.i = 1;
  pOp->p4type = P4_INT32;







|







2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
** Use the content of register P3 as an integer key.  If a record 
** with that key does not exist in table of P1, then jump to P2. 
** If the record does exist, then fall through.  The cursor is left 
** pointing to the record if it exists.
**
** The difference between this operation and NotFound is that this
** operation assumes the key is an integer and that P1 is a table whereas
** NotFound assumes key is a blob constructed from MakeKey and
** P1 is an index.
**
** See also: Found, NotFound, IsUnique
*/
case OP_NotExists: {    /* jump, in3 */
  pOp->p4.i = 1;
  pOp->p4type = P4_INT32;
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
  pC->sSeekKey.n = 0;
  pC->rowChnged = 1;
  assert( pC!=0 );
  pIn3 = &aMem[pOp->p3];
  assert( pC->pKVCur!=0 );
  if( pOp->p4.i>0 ){
    rc = sqlite4VdbeEncodeKey(
        db, pIn3, pOp->p4.i, pOp->p4.i + (pOp->p5 & OPFLAG_PARTIALKEY),
        pC->iRoot, pC->pKeyInfo, &pProbe, &nProbe, 0
    );
    pFree = pProbe;
  }else{
    pProbe = (KVByteArray*)pIn3->z;
    nProbe = pIn3->n;
    pFree = 0;
  }







<
|







2994
2995
2996
2997
2998
2999
3000

3001
3002
3003
3004
3005
3006
3007
3008
  pC->sSeekKey.n = 0;
  pC->rowChnged = 1;
  assert( pC!=0 );
  pIn3 = &aMem[pOp->p3];
  assert( pC->pKVCur!=0 );
  if( pOp->p4.i>0 ){
    rc = sqlite4VdbeEncodeKey(

        db, pIn3, pOp->p4.i, pC->iRoot, pC->pKeyInfo, &pProbe, &nProbe, 0
    );
    pFree = pProbe;
  }else{
    pProbe = (KVByteArray*)pIn3->z;
    nProbe = pIn3->n;
    pFree = 0;
  }
Changes to src/vdbe.h.
216
217
218
219
220
221
222










223
224
225
226
227
228
229
#endif
sqlite4_value *sqlite4ColumnValue(sqlite4_stmt *pStmt, int iCol);

#ifndef SQLITE4_OMIT_TRIGGER
void sqlite4VdbeLinkSubProgram(Vdbe *, SubProgram *);
#endif












#ifndef NDEBUG
  void sqlite4VdbeComment(Vdbe*, const char*, ...);
# define VdbeComment(X)  sqlite4VdbeComment X
  void sqlite4VdbeNoopComment(Vdbe*, const char*, ...);
# define VdbeNoopComment(X)  sqlite4VdbeNoopComment X
#else







>
>
>
>
>
>
>
>
>
>







216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#endif
sqlite4_value *sqlite4ColumnValue(sqlite4_stmt *pStmt, int iCol);

#ifndef SQLITE4_OMIT_TRIGGER
void sqlite4VdbeLinkSubProgram(Vdbe *, SubProgram *);
#endif

int sqlite4VdbeEncodeKey(
  sqlite4 *db,                 /* The database connection */
  Mem *aIn,                    /* Values to be encoded */
  int nIn,                     /* Number of entries in aIn[] */
  int iTabno,                  /* The table this key applies to */
  KeyInfo *pKeyInfo,           /* Collating sequence information */
  u8 **pzOut,                  /* Write the resulting key here */
  int *pnOut,                  /* Number of bytes in the key */
  int nExtra                   /* Append extra bytes on end of key */
);

#ifndef NDEBUG
  void sqlite4VdbeComment(Vdbe*, const char*, ...);
# define VdbeComment(X)  sqlite4VdbeComment X
  void sqlite4VdbeNoopComment(Vdbe*, const char*, ...);
# define VdbeNoopComment(X)  sqlite4VdbeNoopComment X
#else
Changes to src/vdbeInt.h.
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
  sqlite4 *db,                /* The database connection */
  Mem *aIn,                   /* Array of values to encode */
  int *aPermute,              /* Permutation (or NULL) */
  int nIn,                    /* Number of entries in aIn[] */
  u8 **pzOut,                 /* The output data record */
  int *pnOut                  /* Bytes of content in pzOut */
);
int sqlite4VdbeEncodeKey(
  sqlite4 *db,                 /* The database connection */
  Mem *aIn,                    /* Values to be encoded */
  int nIn,                     /* Number of entries in aIn[] */
  int nInTotal,                /* Number of values in complete key */
  int iTabno,                  /* The table this key applies to */
  KeyInfo *pKeyInfo,           /* Collating sequence information */
  u8 **pzOut,                  /* Write the resulting key here */
  int *pnOut,                  /* Number of bytes in the key */
  int nExtra                   /* Append extra bytes on end of key */
);
int sqlite4VdbeEncodeIntKey(u8 *aBuf,sqlite4_int64 v);
int sqlite4VdbeDecodeNumericKey(const KVByteArray*, KVSize, sqlite4_num*);
int sqlite4VdbeShortKey(const u8 *, int, int, int *);
int sqlite4MemCompare(Mem*, Mem*, const CollSeq*,int*);
int sqlite4VdbeExec(Vdbe*);
int sqlite4VdbeList(Vdbe*);
int sqlite4VdbeHalt(Vdbe*);







<
<
<
<
<
<
<
<
<
<
<







363
364
365
366
367
368
369











370
371
372
373
374
375
376
  sqlite4 *db,                /* The database connection */
  Mem *aIn,                   /* Array of values to encode */
  int *aPermute,              /* Permutation (or NULL) */
  int nIn,                    /* Number of entries in aIn[] */
  u8 **pzOut,                 /* The output data record */
  int *pnOut                  /* Bytes of content in pzOut */
);











int sqlite4VdbeEncodeIntKey(u8 *aBuf,sqlite4_int64 v);
int sqlite4VdbeDecodeNumericKey(const KVByteArray*, KVSize, sqlite4_num*);
int sqlite4VdbeShortKey(const u8 *, int, int, int *);
int sqlite4MemCompare(Mem*, Mem*, const CollSeq*,int*);
int sqlite4VdbeExec(Vdbe*);
int sqlite4VdbeList(Vdbe*);
int sqlite4VdbeHalt(Vdbe*);
Changes to src/vdbecodec.c.
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
vdbeEncodeData_error:
  sqlite4StackFree(db, aAux);
  sqlite4DbFree(db, aOut);
  return rc;
}

/*
** An output buffer for EncodeKey
*/
typedef struct KeyEncoder KeyEncoder;
struct KeyEncoder {
  sqlite4 *db;   /* Database connection */
  u8 *aOut;      /* Output buffer */
  int nOut;      /* Slots of aOut[] used */
  int nAlloc;    /* Slots of aOut[] allocated */







|







673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
vdbeEncodeData_error:
  sqlite4StackFree(db, aAux);
  sqlite4DbFree(db, aOut);
  return rc;
}

/*
** An output buffer for sqlite4VdbeEncodeKey
*/
typedef struct KeyEncoder KeyEncoder;
struct KeyEncoder {
  sqlite4 *db;   /* Database connection */
  u8 *aOut;      /* Output buffer */
  int nOut;      /* Slots of aOut[] used */
  int nAlloc;    /* Slots of aOut[] allocated */
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
** Space to hold the key is obtained from sqlite4DbMalloc() and should
** be freed by the caller using sqlite4DbFree() to avoid a memory leak.
*/
int sqlite4VdbeEncodeKey(
  sqlite4 *db,                 /* The database connection */
  Mem *aIn,                    /* Values to be encoded */
  int nIn,                     /* Number of entries in aIn[] */
  int nInTotal,                /* Number of values in a complete key */
  int iTabno,                  /* The table this key applies to, or negative */
  KeyInfo *pKeyInfo,           /* Collating sequence and sort-order info */
  u8 **paOut,                  /* Write the resulting key here */
  int *pnOut,                  /* Number of bytes in the key */
  int nExtra                   /* extra bytes of space appended to the key */
){
  int i;







<







1006
1007
1008
1009
1010
1011
1012

1013
1014
1015
1016
1017
1018
1019
** Space to hold the key is obtained from sqlite4DbMalloc() and should
** be freed by the caller using sqlite4DbFree() to avoid a memory leak.
*/
int sqlite4VdbeEncodeKey(
  sqlite4 *db,                 /* The database connection */
  Mem *aIn,                    /* Values to be encoded */
  int nIn,                     /* Number of entries in aIn[] */

  int iTabno,                  /* The table this key applies to, or negative */
  KeyInfo *pKeyInfo,           /* Collating sequence and sort-order info */
  u8 **paOut,                  /* Write the resulting key here */
  int *pnOut,                  /* Number of bytes in the key */
  int nExtra                   /* extra bytes of space appended to the key */
){
  int i;
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
  if( iTabno>=0 ){
    x.nOut = sqlite4PutVarint64(x.aOut, iTabno);
  }
  aColl = pKeyInfo->aColl;
  so = pKeyInfo->aSortOrder;
  for(i=0; i<nIn && rc==SQLITE4_OK; i++){
    rc = encodeOneKeyValue(&x, aIn+i, so ? so[i] : SQLITE4_SO_ASC,
                           i==nInTotal-1, aColl[i]);
  }

  if( rc==SQLITE4_OK && nExtra ){ rc = enlargeEncoderAllocation(&x, nExtra); }
  if( rc ){
    sqlite4DbFree(db, x.aOut);
  }else{
    *paOut = x.aOut;
    *pnOut = x.nOut;
  }
  return rc;
}







|











1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
  if( iTabno>=0 ){
    x.nOut = sqlite4PutVarint64(x.aOut, iTabno);
  }
  aColl = pKeyInfo->aColl;
  so = pKeyInfo->aSortOrder;
  for(i=0; i<nIn && rc==SQLITE4_OK; i++){
    rc = encodeOneKeyValue(&x, aIn+i, so ? so[i] : SQLITE4_SO_ASC,
                           i==pKeyInfo->nField-1, aColl[i]);
  }

  if( rc==SQLITE4_OK && nExtra ){ rc = enlargeEncoderAllocation(&x, nExtra); }
  if( rc ){
    sqlite4DbFree(db, x.aOut);
  }else{
    *paOut = x.aOut;
    *pnOut = x.nOut;
  }
  return rc;
}
Changes to src/where.c.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
** 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".
*/
#include "sqliteInt.h"

/* For VdbeCodecEncodeKey() - revisit this */
#include "vdbeInt.h"

/*
** Trace output macros
*/
#if defined(SQLITE4_TEST) || defined(SQLITE4_DEBUG)
/***/ int sqlite4WhereTrace = 0;
#endif
#if defined(SQLITE4_DEBUG) \







<
<
<







14
15
16
17
18
19
20



21
22
23
24
25
26
27
** 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".
*/
#include "sqliteInt.h"




/*
** Trace output macros
*/
#if defined(SQLITE4_TEST) || defined(SQLITE4_DEBUG)
/***/ int sqlite4WhereTrace = 0;
#endif
#if defined(SQLITE4_DEBUG) \
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
  }else{
    rc = sqlite4ValueFromExpr(db, pExpr, SQLITE4_UTF8, aff, &pVal);
  }

  if( pVal && rc==SQLITE4_OK ){
    u8 *aOut;
    int nOut;
    rc = sqlite4VdbeEncodeKey(db, pVal, 1, 2, -1, pKeyinfo, &aOut, &nOut, 0);
    if( rc==SQLITE4_OK ){
      rc = sqlite4_buffer_set(pBuf, aOut, nOut);
    }
    sqlite4DbFree(db, aOut);
  }

  sqlite4ValueFree(pVal);







|







2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
  }else{
    rc = sqlite4ValueFromExpr(db, pExpr, SQLITE4_UTF8, aff, &pVal);
  }

  if( pVal && rc==SQLITE4_OK ){
    u8 *aOut;
    int nOut;
    rc = sqlite4VdbeEncodeKey(db, pVal, 1, -1, pKeyinfo, &aOut, &nOut, 0);
    if( rc==SQLITE4_OK ){
      rc = sqlite4_buffer_set(pBuf, aOut, nOut);
    }
    sqlite4DbFree(db, aOut);
  }

  sqlite4ValueFree(pVal);
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
    testcase( op==OP_Rewind );
    testcase( op==OP_Last );
    testcase( op==OP_SeekGt );
    testcase( op==OP_SeekGe );
    testcase( op==OP_SeekLe );
    testcase( op==OP_SeekLt );
    sqlite4VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
    if( nEq<idxColumnCount(pIdx, pPk) ){
      sqlite4VdbeChangeP5(v, OPFLAG_PARTIALKEY);
    }

    /* Set variable op to the instruction required to determine if the
    ** cursor is passed the end of the range. If the range is unbounded,
    ** then set op to OP_Noop. Nothing to do in this case.  */
    assert( (endEq==0 || endEq==1) );
    op = aEndOp[(pRangeEnd || nEq) * (1 + (endEq+endEq) + bRev)];
    testcase( op==OP_Noop );







<
<
<







3620
3621
3622
3623
3624
3625
3626



3627
3628
3629
3630
3631
3632
3633
    testcase( op==OP_Rewind );
    testcase( op==OP_Last );
    testcase( op==OP_SeekGt );
    testcase( op==OP_SeekGe );
    testcase( op==OP_SeekLe );
    testcase( op==OP_SeekLt );
    sqlite4VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);




    /* Set variable op to the instruction required to determine if the
    ** cursor is passed the end of the range. If the range is unbounded,
    ** then set op to OP_Noop. Nothing to do in this case.  */
    assert( (endEq==0 || endEq==1) );
    op = aEndOp[(pRangeEnd || nEq) * (1 + (endEq+endEq) + bRev)];
    testcase( op==OP_Noop );
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
          }
        }  
        codeApplyAffinity(pParse, regBase, nEq+1, zEndAff);
        nConstraint++;
        testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
      }

      /* Now compute an end-key using OP_MakeIdxKey */
      regEndKey = ++pParse->nMem;
      if( pIdx->tnum==KVSTORE_ROOT ){
        sqlite4VdbeAddOp2(v, OP_Copy, regBase, regEndKey);
        sqlite4VdbeAddOp1(v, OP_ToBlob, regEndKey);
      }else{
        sqlite4VdbeAddOp4Int(
            v, OP_MakeIdxKey, iIdxCur, regBase, regEndKey, nConstraint
        );
      }

    }

    sqlite4DbFree(pParse->db, zStartAff);
    sqlite4DbFree(pParse->db, zEndAff);

    /* Top of the loop body */
    pLevel->p2 = sqlite4VdbeCurrentAddr(v);







|





|
<
|

<







3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673

3674
3675

3676
3677
3678
3679
3680
3681
3682
          }
        }  
        codeApplyAffinity(pParse, regBase, nEq+1, zEndAff);
        nConstraint++;
        testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
      }

      /* Now compute an end-key using OP_MakeKey */
      regEndKey = ++pParse->nMem;
      if( pIdx->tnum==KVSTORE_ROOT ){
        sqlite4VdbeAddOp2(v, OP_Copy, regBase, regEndKey);
        sqlite4VdbeAddOp1(v, OP_ToBlob, regEndKey);
      }else{
        sqlite4VdbeAddOp4Int(v, OP_MakeKey, regBase, nConstraint, regEndKey,

                                iIdxCur);
      }

    }

    sqlite4DbFree(pParse->db, zStartAff);
    sqlite4DbFree(pParse->db, zEndAff);

    /* Top of the loop body */
    pLevel->p2 = sqlite4VdbeCurrentAddr(v);