System.Data.SQLite

Login
This project makes use of Eagle, provided by Mistachkin Systems.
Eagle: Secure Software Automation

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

Changes In Branch threadAbortProtect Excluding Merge-Ins

This is equivalent to a diff from c826898164 to 8c37793c05

2012-10-13
06:25
Merge thread abort protection and several other changes to trunk. check-in: 722904a344 user: mistachkin tags: trunk
06:24
Update version history docs. Closed-Leaf check-in: 8c37793c05 user: mistachkin tags: threadAbortProtect
06:14
Update SQLite core library to latest trunk code. Centralize sqlite3_shutdown handling in the test suite infrastructure. check-in: 986baaa70f user: mistachkin tags: threadAbortProtect
2012-10-12
04:23
Add experimental protection against leaking native resources when the Thread.Abort method is used. These changes may not be included in any official release. check-in: e553cea4a0 user: mistachkin tags: threadAbortProtect
2012-10-11
06:58
Add sqlite3_backup_finish_interop function with optional diagnostics. Improvements to sqlite3_finalize_interop diagnostics. Make interop function names consistent. check-in: c826898164 user: mistachkin tags: trunk
2012-10-10
13:56
Re-order the #if statements used for native library/assembly selection to reflect the necessity of using the custom interop assembly when compiled for the .NET Compact Framework. check-in: affb80d75d user: mistachkin tags: trunk

Changes to Doc/Extra/version.html.

47
48
49
50
51
52
53
54


55
56
57
58
59
60
61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77







-
+
+














+







    <ul>
      <li>Updated to <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.7.15</a>.</li>
      <li>Add Visual Studio 2012 support to all the applicable solution/project files, their associated supporting files, and the test suite.</li>
      <li>Add Visual Studio 2012 support to the redesigned designer support installer.</li>
      <li>Allow opened connections to skip adding the extension functions included in the interop assembly via the new NoExtensionFunctions connection flag.</li>
      <li>Support loading of SQLite extensions via the new EnableExtensions and LoadExtension methods of the SQLiteConnection class. Pursuant to <a href="http://system.data.sqlite.org/index.html/info/17045010df">[17045010df]</a>.</li>
      <li>Add notifications before and after any connection is opened and closed, as well as other related notifications, via the new static Changed event.</li>
      <li>Add an overload of the SQLiteLog.LogMessage method that takes a single string argument.</li>
      <li>Add an overload of the SQLiteLog.LogMessage method that takes a single string parameter.</li>
      <li>Add an overload of the SQLiteConnection.LogMessage method that takes a SQLiteErrorCode parameter.</li>
      <li>All applicable calls into the SQLite core library now return a SQLiteErrorCode instead of an integer error code.</li>
      <li>Make sure the error code of the SQLiteException class gets serialized.</li>
      <li>Make the test project for the .NET Compact Framework more flexible.</li>
      <li>When available, the new sqlite3_errstr function from the core library is used to get the error message for a specific return code.</li>
      <li>The SetMemoryStatus, Shutdown, ResultCode, ExtendedResultCode, and SetAvRetry methods of the SQLiteConnection class now return a SQLiteErrorCode instead of an integer error code.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>The public constructor for the SQLiteException now takes a SQLiteErrorCode instead of an integer error code.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>The ErrorCode property of the SQLiteException is now an Int32, to allow the property inherited from the base class to be properly overridden.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>The ErrorCode field of the LogEventArgs is now an object instead of an integer.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>The names and messages associated with the SQLiteErrorCode enumeration values have been normalized to match those in the SQLite core library.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>Implement more robust locking semantics for the CriticalHandle derived classes when compiled for the .NET Compact Framework.</li>
      <li>Cache column indexes are they are looked up when using the SQLiteDataReader to improve performance.</li>
      <li>Prevent the SQLiteConnection.Close method from throwing non-fatal exceptions during its disposal.</li>
      <li>Rename the interop assembly functions sqlite3_cursor_rowid, sqlite3_context_collcompare, sqlite3_context_collseq, sqlite3_cursor_rowid, and sqlite3_table_cursor to include an &quot;_interop&quot; suffix.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>Prevent the LastInsertRowId, MemoryUsed, and MemoryHighwater connection properties from throwing NotSupportedException when running on the .NET Compact Framework. Fix for <a href="http://system.data.sqlite.org/index.html/info/dd45aba387">[dd45aba387]</a>.</li>
      <li>Add protection against ThreadAbortException asynchronously interrupting native resource initialization and finalization.</li>
      <li>Add test automation for the Windows CE binaries.</li>
    </ul>
    <p><b>1.0.82.0 - September 3, 2012</b></p>
    <ul>
      <li>Updated to <a href="http://www.sqlite.org/releaselog/3_7_14.html">SQLite 3.7.14</a>.</li>
      <li>Properly handle quoted data source values in the connection string. Fix for <a href="http://system.data.sqlite.org/index.html/info/8c3bee31c8">[8c3bee31c8]</a>.</li>
      <li>The <a href="http://nuget.org/packages/System.Data.SQLite">primary NuGet package</a> now supports x86 / x64 and the .NET Framework 2.0 / 4.0 (i.e. in a single package).</li>

Changes to SQLite.Interop/props/sqlite3.props.

12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
12
13
14
15
16
17
18

19
20
21
22
23
24
25
26







-
+







    <SQLITE_MANIFEST_VERSION>3.7.15</SQLITE_MANIFEST_VERSION>
    <SQLITE_RC_VERSION>3,7,15</SQLITE_RC_VERSION>
    <SQLITE_COMMON_DEFINES>_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;SQLITE_THREADSAFE=1;SQLITE_USE_URI=1;SQLITE_ENABLE_COLUMN_METADATA=1;SQLITE_ENABLE_STAT3=1;SQLITE_ENABLE_FTS3=1;SQLITE_ENABLE_LOAD_EXTENSION=1;SQLITE_ENABLE_RTREE=1;SQLITE_SOUNDEX=1</SQLITE_COMMON_DEFINES>
    <SQLITE_EXTRA_DEFINES>SQLITE_HAS_CODEC=1</SQLITE_EXTRA_DEFINES>
    <SQLITE_WINCE_DEFINES>SQLITE_OMIT_WAL=1</SQLITE_WINCE_DEFINES>
    <SQLITE_DEBUG_DEFINES>SQLITE_DEBUG=1;SQLITE_MEMDEBUG=1</SQLITE_DEBUG_DEFINES>
    <SQLITE_RELEASE_DEFINES>SQLITE_WIN32_MALLOC=1</SQLITE_RELEASE_DEFINES>
    <SQLITE_DISABLE_WARNINGS>4100;4127;4146;4210;4232;4244;4245;4267;4306;4389;4701;4703;4706</SQLITE_DISABLE_WARNINGS>
    <SQLITE_DISABLE_WARNINGS>4055;4100;4127;4146;4210;4232;4244;4245;4267;4306;4389;4701;4703;4706</SQLITE_DISABLE_WARNINGS>
    <SQLITE_DISABLE_X64_WARNINGS></SQLITE_DISABLE_X64_WARNINGS>
  </PropertyGroup>
  <ItemGroup>
    <BuildMacro Include="SQLITE_MANIFEST_VERSION">
      <Value>$(SQLITE_MANIFEST_VERSION)</Value>
      <EnvironmentVariable>true</EnvironmentVariable>
    </BuildMacro>

Changes to SQLite.Interop/props/sqlite3.vsprops.

45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59







-
+







	<UserMacro
		Name="SQLITE_RELEASE_DEFINES"
		Value="SQLITE_WIN32_MALLOC=1"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="SQLITE_DISABLE_WARNINGS"
		Value="4100;4127;4146;4210;4232;4244;4245;4267;4306;4389;4701;4703;4706"
		Value="4055;4100;4127;4146;4210;4232;4244;4245;4267;4306;4389;4701;4703;4706"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="SQLITE_DISABLE_X64_WARNINGS"
		Value=""
		PerformEnvironmentSet="true"
	/>

Changes to SQLite.Interop/src/core/sqlite3.c.

671
672
673
674
675
676
677
678

679
680
681
682
683
684
685
671
672
673
674
675
676
677

678
679
680
681
682
683
684
685







-
+







**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.7.15"
#define SQLITE_VERSION_NUMBER 3007015
#define SQLITE_SOURCE_ID      "2012-09-19 21:15:46 94b48064db3cbb43e911fdf7183218b08146ec10"
#define SQLITE_SOURCE_ID      "2012-10-12 18:06:07 de784399ed1f0e27fc875e32719643d19819c8fb"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
1419
1420
1421
1422
1423
1424
1425











1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440

1441
1442
1443
1444
1445
1446
1447
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459







+
+
+
+
+
+
+
+
+
+
+















+







** prepared statement.  ^If the [SQLITE_FCNTL_PRAGMA] file control returns
** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means
** that the VFS encountered an error while handling the [PRAGMA] and the
** compilation of the PRAGMA fails with an error.  ^The [SQLITE_FCNTL_PRAGMA]
** file control occurs at the beginning of pragma statement analysis and so
** it is able to override built-in [PRAGMA] statements.
** </ul>
**
** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
** ^This file-control may be invoked by SQLite on the database file handle
** shortly after it is opened in order to provide a custom VFS with access
** to the connections busy-handler callback. The argument is of type (void **)
** - an array of two (void *) values. The first (void *) actually points
** to a function of type (int (*)(void *)). In order to invoke the connections
** busy-handler, this function should be invoked with the second (void *) in
** the array as the only argument. If it returns non-zero, then the operation
** should be retried. If it returns zero, the custom VFS should abandon the
** current operation.
*/
#define SQLITE_FCNTL_LOCKSTATE               1
#define SQLITE_GET_LOCKPROXYFILE             2
#define SQLITE_SET_LOCKPROXYFILE             3
#define SQLITE_LAST_ERRNO                    4
#define SQLITE_FCNTL_SIZE_HINT               5
#define SQLITE_FCNTL_CHUNK_SIZE              6
#define SQLITE_FCNTL_FILE_POINTER            7
#define SQLITE_FCNTL_SYNC_OMITTED            8
#define SQLITE_FCNTL_WIN32_AV_RETRY          9
#define SQLITE_FCNTL_PERSIST_WAL            10
#define SQLITE_FCNTL_OVERWRITE              11
#define SQLITE_FCNTL_VFSNAME                12
#define SQLITE_FCNTL_POWERSAFE_OVERWRITE    13
#define SQLITE_FCNTL_PRAGMA                 14
#define SQLITE_FCNTL_BUSYHANDLER            15

/*
** CAPI3REF: Mutex Handle
**
** The mutex module within SQLite defines [sqlite3_mutex] to be an
** abstract type for a mutex object.  The SQLite core never looks
** at the internal representation of an [sqlite3_mutex].  It only
5313
5314
5315
5316
5317
5318
5319



5320
5321
5322
5323
5324
5325
5326
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341







+
+
+







**
** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled
** successfully.  An [error code] is returned otherwise.)^
**
** ^Shared cache is disabled by default. But this might change in
** future releases of SQLite.  Applications that care about shared
** cache setting should set it explicitly.
**
** This interface is threadsafe on processors where writing a
** 32-bit integer is atomic.
**
** See Also:  [SQLite Shared-Cache Mode]
*/
SQLITE_API int sqlite3_enable_shared_cache(int);

/*
** CAPI3REF: Attempt To Free Heap Memory
8279
8280
8281
8282
8283
8284
8285

8286
8287
8288
8289
8290
8291
8292
8294
8295
8296
8297
8298
8299
8300
8301
8302
8303
8304
8305
8306
8307
8308







+







typedef struct LookasideSlot LookasideSlot;
typedef struct Module Module;
typedef struct NameContext NameContext;
typedef struct Parse Parse;
typedef struct RowSet RowSet;
typedef struct Savepoint Savepoint;
typedef struct Select Select;
typedef struct SelectDest SelectDest;
typedef struct SrcList SrcList;
typedef struct StrAccum StrAccum;
typedef struct Table Table;
typedef struct TableLock TableLock;
typedef struct Token Token;
typedef struct Trigger Trigger;
typedef struct TriggerPrg TriggerPrg;
8375
8376
8377
8378
8379
8380
8381



8382
8383
8384
8385
8386
8387
8388
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407







+
+
+







SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*);
SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*);
SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int);
SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree*);
SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree*);
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p);
#endif
SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int);
SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *);
SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int);
SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*);
SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*,int);
8885
8886
8887
8888
8889
8890
8891
8892

8893
8894
8895
8896
8897
8898
8899
8904
8905
8906
8907
8908
8909
8910

8911
8912
8913
8914
8915
8916
8917
8918







-
+







#define OPFLG_IN1             0x0004  /* in1:   P1 is an input */
#define OPFLG_IN2             0x0008  /* in2:   P2 is an input */
#define OPFLG_IN3             0x0010  /* in3:   P3 is an input */
#define OPFLG_OUT2            0x0020  /* out2:  P2 is an output */
#define OPFLG_OUT3            0x0040  /* out3:  P3 is an output */
#define OPFLG_INITIALIZER {\
/*   0 */ 0x00, 0x01, 0x01, 0x04, 0x04, 0x10, 0x00, 0x02,\
/*   8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x24, 0x24,\
/*   8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x24,\
/*  16 */ 0x00, 0x00, 0x00, 0x24, 0x04, 0x05, 0x04, 0x00,\
/*  24 */ 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00, 0x00,\
/*  32 */ 0x02, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,\
/*  40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\
/*  48 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x02,\
/*  56 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
/*  64 */ 0x00, 0x02, 0x00, 0x01, 0x4c, 0x4c, 0x01, 0x01,\
9122
9123
9124
9125
9126
9127
9128

9129
9130
9131
9132
9133







9134
9135
9136
9137
9138
9139
9140
9141
9142
9143
9144
9145
9146
9147
9148
9149
9150

9151
9152
9153
9154
9155
9156
9157
9141
9142
9143
9144
9145
9146
9147
9148





9149
9150
9151
9152
9153
9154
9155
9156
9157
9158
9159
9160
9161
9162
9163
9164
9165
9166
9167
9168
9169
9170
9171
9172
9173
9174
9175
9176
9177
9178
9179
9180







+
-
-
-
-
-
+
+
+
+
+
+
+

















+







SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager);
SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*);
SQLITE_PRIVATE int sqlite3PagerRollback(Pager*);
SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager);

#ifndef SQLITE_OMIT_WAL
SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*);
SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager);
SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager);
SQLITE_PRIVATE   int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*);
SQLITE_PRIVATE   int sqlite3PagerWalSupported(Pager *pPager);
SQLITE_PRIVATE   int sqlite3PagerWalCallback(Pager *pPager);
SQLITE_PRIVATE   int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
SQLITE_PRIVATE   int sqlite3PagerCloseWal(Pager *pPager);
#endif

#ifdef SQLITE_ENABLE_ZIPVFS
SQLITE_PRIVATE   int sqlite3PagerWalFramesize(Pager *pPager);
#endif

/* Functions used to query pager state and configuration. */
SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*);
SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*);
SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*);
SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*, int);
SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*);
SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*);
SQLITE_PRIVATE int sqlite3PagerNosync(Pager*);
SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *);
SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);

/* Functions used to truncate the database file. */
SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);

#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
SQLITE_PRIVATE void *sqlite3PagerCodec(DbPage *);
#endif
9841
9842
9843
9844
9845
9846
9847

9848
9849
9850
9851
9852
9853
9854
9864
9865
9866
9867
9868
9869
9870
9871
9872
9873
9874
9875
9876
9877
9878







+







  Db *aDb;                      /* All backends */
  int nDb;                      /* Number of backends currently in use */
  int flags;                    /* Miscellaneous flags. See below */
  i64 lastRowid;                /* ROWID of most recent insert (see above) */
  unsigned int openFlags;       /* Flags passed to sqlite3_vfs.xOpen() */
  int errCode;                  /* Most recent error code (SQLITE_*) */
  int errMask;                  /* & result codes with this before returning */
  u8 dbOptFlags;                /* Flags to enable/disable optimizations */
  u8 autoCommit;                /* The auto-commit flag. */
  u8 temp_store;                /* 1: file 2: memory 0: default */
  u8 mallocFailed;              /* True if we have seen a malloc failure */
  u8 dfltLockMode;              /* Default locking-mode for attached dbs */
  signed char nextAutovac;      /* Autovac setting after VACUUM if >=0 */
  u8 suppressErr;               /* Do not issue error messages if true */
  u8 vtabOnConflict;            /* Value to return for s3_vtab_on_conflict() */
9945
9946
9947
9948
9949
9950
9951
9952
9953
9954
9955
9956





9957
9958
9959

9960
9961
9962
9963
9964
9965
9966
9967
9968
9969
9970
9971
9972
9973
9974
9975
9976
9977

















9978
9979
9980
9981
9982



9983
9984
9985
9986
9987
9988
9989
9990
9991




















9992
9993
9994
9995
9996
9997
9998
9969
9970
9971
9972
9973
9974
9975





9976
9977
9978
9979
9980
9981
9982

9983
9984

















9985
9986
9987
9988
9989
9990
9991
9992
9993
9994
9995
9996
9997
9998
9999
10000
10001
10002
10003



10004
10005
10006
10007








10008
10009
10010
10011
10012
10013
10014
10015
10016
10017
10018
10019
10020
10021
10022
10023
10024
10025
10026
10027
10028
10029
10030
10031
10032
10033
10034







-
-
-
-
-
+
+
+
+
+


-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
-
+
+
+

-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







** A macro to discover the encoding of a database.
*/
#define ENC(db) ((db)->aDb[0].pSchema->enc)

/*
** Possible values for the sqlite3.flags.
*/
#define SQLITE_VdbeTrace      0x00000100  /* True to trace VDBE execution */
#define SQLITE_InternChanges  0x00000200  /* Uncommitted Hash table changes */
#define SQLITE_FullColNames   0x00000400  /* Show full column names on SELECT */
#define SQLITE_ShortColNames  0x00000800  /* Show short columns names */
#define SQLITE_CountRows      0x00001000  /* Count rows changed by INSERT, */
#define SQLITE_VdbeTrace      0x00000001  /* True to trace VDBE execution */
#define SQLITE_InternChanges  0x00000002  /* Uncommitted Hash table changes */
#define SQLITE_FullColNames   0x00000004  /* Show full column names on SELECT */
#define SQLITE_ShortColNames  0x00000008  /* Show short columns names */
#define SQLITE_CountRows      0x00000010  /* Count rows changed by INSERT, */
                                          /*   DELETE, or UPDATE and return */
                                          /*   the count using a callback. */
#define SQLITE_NullCallback   0x00002000  /* Invoke the callback once if the */
#define SQLITE_NullCallback   0x00000020  /* Invoke the callback once if the */
                                          /*   result set is empty */
#define SQLITE_SqlTrace       0x00004000  /* Debug print SQL as it executes */
#define SQLITE_VdbeListing    0x00008000  /* Debug listings of VDBE programs */
#define SQLITE_WriteSchema    0x00010000  /* OK to update SQLITE_MASTER */
                         /*   0x00020000  Unused */
#define SQLITE_IgnoreChecks   0x00040000  /* Do not enforce check constraints */
#define SQLITE_ReadUncommitted 0x0080000  /* For shared-cache mode */
#define SQLITE_LegacyFileFmt  0x00100000  /* Create new databases in format 1 */
#define SQLITE_FullFSync      0x00200000  /* Use full fsync on the backend */
#define SQLITE_CkptFullFSync  0x00400000  /* Use full fsync for checkpoint */
#define SQLITE_RecoveryMode   0x00800000  /* Ignore schema errors */
#define SQLITE_ReverseOrder   0x01000000  /* Reverse unordered SELECTs */
#define SQLITE_RecTriggers    0x02000000  /* Enable recursive triggers */
#define SQLITE_ForeignKeys    0x04000000  /* Enforce foreign key constraints  */
#define SQLITE_AutoIndex      0x08000000  /* Enable automatic indexes */
#define SQLITE_PreferBuiltin  0x10000000  /* Preference to built-in funcs */
#define SQLITE_LoadExtension  0x20000000  /* Enable load_extension */
#define SQLITE_EnableTrigger  0x40000000  /* True to enable triggers */
#define SQLITE_SqlTrace       0x00000040  /* Debug print SQL as it executes */
#define SQLITE_VdbeListing    0x00000080  /* Debug listings of VDBE programs */
#define SQLITE_WriteSchema    0x00000100  /* OK to update SQLITE_MASTER */
                         /*   0x00000200  Unused */
#define SQLITE_IgnoreChecks   0x00000400  /* Do not enforce check constraints */
#define SQLITE_ReadUncommitted 0x0000800  /* For shared-cache mode */
#define SQLITE_LegacyFileFmt  0x00001000  /* Create new databases in format 1 */
#define SQLITE_FullFSync      0x00002000  /* Use full fsync on the backend */
#define SQLITE_CkptFullFSync  0x00004000  /* Use full fsync for checkpoint */
#define SQLITE_RecoveryMode   0x00008000  /* Ignore schema errors */
#define SQLITE_ReverseOrder   0x00010000  /* Reverse unordered SELECTs */
#define SQLITE_RecTriggers    0x00020000  /* Enable recursive triggers */
#define SQLITE_ForeignKeys    0x00040000  /* Enforce foreign key constraints  */
#define SQLITE_AutoIndex      0x00080000  /* Enable automatic indexes */
#define SQLITE_PreferBuiltin  0x00100000  /* Preference to built-in funcs */
#define SQLITE_LoadExtension  0x00200000  /* Enable load_extension */
#define SQLITE_EnableTrigger  0x00400000  /* True to enable triggers */

/*
** Bits of the sqlite3.flags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface.
** These must be the low-order bits of the flags field.
** Bits of the sqlite3.dbOptFlags field that are used by the
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
** selectively disable various optimizations.
*/
#define SQLITE_QueryFlattener 0x01   /* Disable query flattening */
#define SQLITE_ColumnCache    0x02   /* Disable the column cache */
#define SQLITE_GroupByOrder   0x04   /* Disable GROUPBY cover of ORDERBY */
#define SQLITE_FactorOutConst 0x08   /* Disable factoring out constants */
#define SQLITE_IdxRealAsInt   0x10   /* Store REAL as INT in indices */
#define SQLITE_DistinctOpt    0x20   /* DISTINCT using indexes */
#define SQLITE_CoverIdxScan   0x40   /* Disable covering index scans */
#define SQLITE_OptMask        0xff   /* Mask of all disablable opts */
#define SQLITE_QueryFlattener 0x0001   /* Query flattening */
#define SQLITE_ColumnCache    0x0002   /* Column cache */
#define SQLITE_GroupByOrder   0x0004   /* GROUPBY cover of ORDERBY */
#define SQLITE_FactorOutConst 0x0008   /* Constant factoring */
#define SQLITE_IdxRealAsInt   0x0010   /* Store REAL as INT in indices */
#define SQLITE_DistinctOpt    0x0020   /* DISTINCT using indexes */
#define SQLITE_CoverIdxScan   0x0040   /* Covering index scans */
#define SQLITE_OrderByIdxJoin 0x0080   /* ORDER BY of joins via index */
#define SQLITE_AllOpts        0x00ff   /* All optimizations */

/*
** Macros for testing whether or not optimizations are enabled or disabled.
*/
#ifndef SQLITE_OMIT_BUILTIN_TEST
#define OptimizationDisabled(db, mask)  (((db)->dbOptFlags&(mask))!=0)
#define OptimizationEnabled(db, mask)   (((db)->dbOptFlags&(mask))==0)
#else
#define OptimizationDisabled(db, mask)  0
#define OptimizationEnabled(db, mask)   1
#endif

/*
** Possible values for the sqlite.magic field.
** The numbers are obtained at random and have no special meaning, other
** than being distinct from one another.
*/
#define SQLITE_MAGIC_OPEN     0xa029a697  /* Database is open */
10870
10871
10872
10873
10874
10875
10876

10877
10878
10879
10880
10881
10882
10883
10906
10907
10908
10909
10910
10911
10912
10913
10914
10915
10916
10917
10918
10919
10920







+







** In the colUsed field, the high-order bit (bit 63) is set if the table
** contains more than 63 columns and the 64-th or later column is used.
*/
struct SrcList {
  i16 nSrc;        /* Number of tables or subqueries in the FROM clause */
  i16 nAlloc;      /* Number of entries allocated in a[] below */
  struct SrcList_item {
    Schema *pSchema;  /* Schema to which this item is fixed */
    char *zDatabase;  /* Name of database holding this table */
    char *zName;      /* Name of the table */
    char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
    Table *pTab;      /* An SQL table corresponding to zName */
    Select *pSelect;  /* A SELECT statement used in place of a table name */
    int addrFillSub;  /* Address of subroutine to manifest a subquery */
    int regReturn;    /* Register holding return address of addrFillSub */
10920
10921
10922
10923
10924
10925
10926
10927


10928
10929
10930
10931
10932
10933
10934
10957
10958
10959
10960
10961
10962
10963

10964
10965
10966
10967
10968
10969
10970
10971
10972







-
+
+







** Within the union, pIdx is only used when wsFlags&WHERE_INDEXED is true.
** pTerm is only used when wsFlags&WHERE_MULTI_OR is true.  And pVtabIdx
** is only used when wsFlags&WHERE_VIRTUALTABLE is true.  It is never the
** case that more than one of these conditions is true.
*/
struct WherePlan {
  u32 wsFlags;                   /* WHERE_* flags that describe the strategy */
  u32 nEq;                       /* Number of == constraints */
  u16 nEq;                       /* Number of == constraints */
  u16 nOBSat;                    /* Number of ORDER BY terms satisfied */
  double nRow;                   /* Estimated number of rows (for EQP) */
  union {
    Index *pIdx;                   /* Index when WHERE_INDEXED is true */
    struct WhereTerm *pTerm;       /* WHERE clause term for OR-search */
    sqlite3_index_info *pVtabIdx;  /* Virtual table index to use */
  } u;
};
10996
10997
10998
10999
11000
11001
11002
11003
11004
11005
11006
11007







11008
11009
11010
11011
11012
11013
11014
11015
11016








11017
11018
11019
11020
11021
11022





11023
11024
11025
11026
11027
11028
11029
11034
11035
11036
11037
11038
11039
11040





11041
11042
11043
11044
11045
11046
11047









11048
11049
11050
11051
11052
11053
11054
11055
11056
11057




11058
11059
11060
11061
11062
11063
11064
11065
11066
11067
11068
11069







-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+


-
-
-
-
+
+
+
+
+







** The WHERE clause processing routine has two halves.  The
** first part does the start of the WHERE loop and the second
** half does the tail of the WHERE loop.  An instance of
** this structure is returned by the first half and passed
** into the second half to give some continuity.
*/
struct WhereInfo {
  Parse *pParse;       /* Parsing and code generating context */
  u16 wctrlFlags;      /* Flags originally passed to sqlite3WhereBegin() */
  u8 okOnePass;        /* Ok to use one-pass algorithm for UPDATE or DELETE */
  u8 untestedTerms;    /* Not all WHERE terms resolved by outer loop */
  u8 eDistinct;                  /* One of the WHERE_DISTINCT_* values below */
  Parse *pParse;            /* Parsing and code generating context */
  SrcList *pTabList;        /* List of tables in the join */
  u16 nOBSat;               /* Number of ORDER BY terms satisfied by indices */
  u16 wctrlFlags;           /* Flags originally passed to sqlite3WhereBegin() */
  u8 okOnePass;             /* Ok to use one-pass algorithm for UPDATE/DELETE */
  u8 untestedTerms;         /* Not all WHERE terms resolved by outer loop */
  u8 eDistinct;             /* One of the WHERE_DISTINCT_* values below */
  SrcList *pTabList;             /* List of tables in the join */
  int iTop;                      /* The very beginning of the WHERE loop */
  int iContinue;                 /* Jump here to continue with next record */
  int iBreak;                    /* Jump here to break out of the loop */
  int nLevel;                    /* Number of nested loop */
  struct WhereClause *pWC;       /* Decomposition of the WHERE clause */
  double savedNQueryLoop;        /* pParse->nQueryLoop outside the WHERE loop */
  double nRowOut;                /* Estimated number of output rows */
  WhereLevel a[1];               /* Information about each nest loop in WHERE */
  int iTop;                 /* The very beginning of the WHERE loop */
  int iContinue;            /* Jump here to continue with next record */
  int iBreak;               /* Jump here to break out of the loop */
  int nLevel;               /* Number of nested loop */
  struct WhereClause *pWC;  /* Decomposition of the WHERE clause */
  double savedNQueryLoop;   /* pParse->nQueryLoop outside the WHERE loop */
  double nRowOut;           /* Estimated number of output rows */
  WhereLevel a[1];          /* Information about each nest loop in WHERE */
};

/* Allowed values for WhereInfo.eDistinct */
#define WHERE_DISTINCT_NOT     0  /* May contain non-adjacent duplicates */
#define WHERE_DISTINCT_UNIQUE  1  /* No duplicates */
#define WHERE_DISTINCT_ORDERED 2  /* All duplicates are adjacent */
/* Allowed values for WhereInfo.eDistinct and DistinctCtx.eTnctType */
#define WHERE_DISTINCT_NOOP      0  /* DISTINCT keyword not used */
#define WHERE_DISTINCT_UNIQUE    1  /* No duplicates */
#define WHERE_DISTINCT_ORDERED   2  /* All duplicates are adjacent */
#define WHERE_DISTINCT_UNORDERED 3  /* Duplicates are scattered */

/*
** A NameContext defines a context in which to resolve table and column
** names.  The context consists of a list of tables (the pSrcList) field and
** a list of named expression (pEList).  The named expression list may
** be NULL.  The pSrc corresponds to the FROM clause of a SELECT or
** to the table being operated on by INSERT, UPDATE, or DELETE.  The
11074
11075
11076
11077
11078
11079
11080
11081

11082
11083
11084
11085
11086
11087
11088
11089
11090
11091
11092
11093
11094
11114
11115
11116
11117
11118
11119
11120

11121
11122
11123
11124
11125
11126

11127
11128
11129
11130
11131
11132
11133







-
+





-







** addrOpenEphm[] entries contain the address of OP_OpenEphemeral opcodes.
** These addresses must be stored so that we can go back and fill in
** the P4_KEYINFO and P2 parameters later.  Neither the KeyInfo nor
** the number of columns in P2 can be computed at the same time
** as the OP_OpenEphm instruction is coded because not
** enough information about the compound query is known at that point.
** The KeyInfo for addrOpenTran[0] and [1] contains collating sequences
** for the result set.  The KeyInfo for addrOpenTran[2] contains collating
** for the result set.  The KeyInfo for addrOpenEphm[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 */
  int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
  int addrOpenEphm[3];   /* OP_OpenEphem opcodes related to this select */
  double nSelectRow;     /* Estimated number of result rows */
  SrcList *pSrc;         /* The FROM clause */
  Expr *pWhere;          /* The WHERE clause */
  ExprList *pGroupBy;    /* The GROUP BY clause */
11131
11132
11133
11134
11135
11136
11137
11138
11139


11140
11141
11142
11143
11144


11145
11146
11147
11148
11149
11150
11151
11170
11171
11172
11173
11174
11175
11176


11177
11178
11179

11180


11181
11182
11183
11184
11185
11186
11187
11188
11189







-
-
+
+

-

-
-
+
+







#define SRT_Mem          6  /* Store result in a memory cell */
#define SRT_Set          7  /* Store results as keys in an index */
#define SRT_Table        8  /* Store result as data with an automatic rowid */
#define SRT_EphemTab     9  /* Create transient tab and store like SRT_Table */
#define SRT_Coroutine   10  /* Generate a single row of result */

/*
** A structure used to customize the behavior of sqlite3Select(). See
** comments above sqlite3Select() for details.
** An instance of this object describes where to put of the results of
** a SELECT statement.
*/
typedef struct SelectDest SelectDest;
struct SelectDest {
  u8 eDest;         /* How to dispose of the results */
  u8 affSdst;       /* Affinity used when eDest==SRT_Set */
  u8 eDest;         /* How to dispose of the results.  On of SRT_* above. */
  char affSdst;     /* Affinity used when eDest==SRT_Set */
  int iSDParm;      /* A parameter used by the eDest disposal method */
  int iSdst;        /* Base register where results are written */
  int nSdst;        /* Number of registers allocated */
};

/*
** During code generation of statements that do inserts into AUTOINCREMENT 
11437
11438
11439
11440
11441
11442
11443

11444
11445
11446
11447
11448
11449
11450
11475
11476
11477
11478
11479
11480
11481
11482
11483
11484
11485
11486
11487
11488
11489







+







** The following structure contains information used by the sqliteFix...
** routines as they walk the parse tree to make database references
** explicit.  
*/
typedef struct DbFixer DbFixer;
struct DbFixer {
  Parse *pParse;      /* The parsing context.  Error messages written here */
  Schema *pSchema;    /* Fix items to this schema */
  const char *zDb;    /* Make sure all objects are contained in this database */
  const char *zType;  /* Type of the container - used for error messages */
  const Token *pName; /* Name of the container - used for error messages */
};

/*
** An objected used to accumulate the text of a string where we
11826
11827
11828
11829
11830
11831
11832
11833

11834
11835
11836
11837
11838
11839
11840
11841
11842
11843
11844
11845
11846
11847
11848
11849
11850
11851
11852
11853
11854
11855

11856
11857
11858
11859
11860
11861
11862
11865
11866
11867
11868
11869
11870
11871

11872

11873
11874
11875
11876

11877
11878
11879
11880
11881
11882
11883
11884
11885
11886
11887
11888
11889
11890
11891
11892
11893
11894
11895
11896
11897
11898
11899
11900







-
+
-




-
















+







SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse *, SrcList *, Expr *, ExprList *, Expr *, Expr *, char *);
#endif
SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
    Parse*,SrcList*,Expr*,ExprList**,ExprList*,u16,int);
SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*);
SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*, int);
SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int);
SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*);
SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int);
SQLITE_PRIVATE int sqlite3ExprCode(Parse*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse*, Expr*, int);
SQLITE_PRIVATE void sqlite3ExprCodeConstants(Parse*, Expr*);
SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int);
SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*);
SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,int isView,const char*, const char*);
SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *);
SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
SQLITE_PRIVATE void sqlite3Vacuum(Parse*);
SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*);
SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*);
12079
12080
12081
12082
12083
12084
12085
12086

12087
12088
12089
12090
12091
12092
12093
12117
12118
12119
12120
12121
12122
12123

12124
12125
12126
12127
12128
12129
12130
12131







-
+







SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(sqlite3*, u8, CollSeq *, const char*);
SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
SQLITE_PRIVATE char sqlite3AffinityType(const char*);
SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *);
SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB);
SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3*,Index*);
12183
12184
12185
12186
12187
12188
12189

12190
12191



12192
12193
12194
12195
12196
12197
12198
12221
12222
12223
12224
12225
12226
12227
12228


12229
12230
12231
12232
12233
12234
12235
12236
12237
12238







+
-
-
+
+
+







SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*);
SQLITE_PRIVATE const char *sqlite3JournalModename(int);
#ifndef SQLITE_OMIT_WAL
SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
SQLITE_PRIVATE   int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
SQLITE_PRIVATE   int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
#endif

/* Declarations for functions in fkey.c. All of these are replaced by
** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
** key functionality is available. If OMIT_TRIGGER is defined but
** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In
** this case foreign keys are parsed, but no other functionality is 
** provided (enforcement of FK constraints requires the triggers sub-system).
24883
24884
24885
24886
24887
24888
24889
24890

24891
24892
24893
24894
24895
24896


24897
24898
24899
24900
24901
24902
24903
24923
24924
24925
24926
24927
24928
24929

24930
24931
24932
24933
24934


24935
24936
24937
24938
24939
24940
24941
24942
24943







-
+




-
-
+
+







  return SQLITE_OK;
}

/*
** Close a file.  Make sure the lock has been released before closing.
*/
static int dotlockClose(sqlite3_file *id) {
  int rc;
  int rc = SQLITE_OK;
  if( id ){
    unixFile *pFile = (unixFile*)id;
    dotlockUnlock(id, NO_LOCK);
    sqlite3_free(pFile->lockingContext);
  }
  rc = closeUnixFile(id);
    rc = closeUnixFile(id);
  }
  return rc;
}
/****************** End of the dot-file lock implementation *******************
******************************************************************************/

/******************************************************************************
************************** Begin flock Locking ********************************
25093
25094
25095
25096
25097
25098
25099

25100
25101

25102
25103

25104
25105
25106
25107
25108
25109
25110
25133
25134
25135
25136
25137
25138
25139
25140
25141
25142
25143
25144

25145
25146
25147
25148
25149
25150
25151
25152







+


+

-
+







  }
}

/*
** Close a file.
*/
static int flockClose(sqlite3_file *id) {
  int rc = SQLITE_OK;
  if( id ){
    flockUnlock(id, NO_LOCK);
    rc = closeUnixFile(id);
  }
  return closeUnixFile(id);
  return rc;
}

#endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */

/******************* End of the flock lock implementation *********************
******************************************************************************/

25807
25808
25809
25810
25811
25812
25813


25814
25815
25816
25817
25818
25819
25820
25849
25850
25851
25852
25853
25854
25855
25856
25857
25858
25859
25860
25861
25862
25863
25864







+
+







static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
  int got;
  int prior = 0;
#if (!defined(USE_PREAD) && !defined(USE_PREAD64))
  i64 newOffset;
#endif
  TIMER_START;
  assert( cnt==(cnt&0x1ffff) );
  cnt &= 0x1ffff;
  do{
#if defined(USE_PREAD)
    got = osPread(id->h, pBuf, cnt, offset);
    SimulateIOError( got = -1 );
#elif defined(USE_PREAD64)
    got = osPread64(id->h, pBuf, cnt, offset);
    SimulateIOError( got = -1 );
25896
25897
25898
25899
25900
25901
25902


25903
25904
25905
25906
25907
25908
25909
25940
25941
25942
25943
25944
25945
25946
25947
25948
25949
25950
25951
25952
25953
25954
25955







+
+







** is set before returning.
*/
static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
  int got;
#if (!defined(USE_PREAD) && !defined(USE_PREAD64))
  i64 newOffset;
#endif
  assert( cnt==(cnt&0x1ffff) );
  cnt &= 0x1ffff;
  TIMER_START;
#if defined(USE_PREAD)
  do{ got = osPwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR );
#elif defined(USE_PREAD64)
  do{ got = osPwrite64(id->h, pBuf, cnt, offset);}while( got<0 && errno==EINTR);
#else
  do{
26891
26892
26893
26894
26895
26896
26897
26898

26899
26900
26901
26902
26903
26904
26905
26937
26938
26939
26940
26941
26942
26943

26944
26945
26946
26947
26948
26949
26950
26951







-
+







    }
    pShmNode->apRegion = apNew;
    while(pShmNode->nRegion<=iRegion){
      void *pMem;
      if( pShmNode->h>=0 ){
        pMem = mmap(0, szRegion,
            pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, 
            MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion
            MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
        );
        if( pMem==MAP_FAILED ){
          rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
          goto shmpage_out;
        }
      }else{
        pMem = sqlite3_malloc(szRegion);
29930
29931
29932
29933
29934
29935
29936



















































29937
29938
29939
29940
29941
29942
29943
29976
29977
29978
29979
29980
29981
29982
29983
29984
29985
29986
29987
29988
29989
29990
29991
29992
29993
29994
29995
29996
29997
29998
29999
30000
30001
30002
30003
30004
30005
30006
30007
30008
30009
30010
30011
30012
30013
30014
30015
30016
30017
30018
30019
30020
30021
30022
30023
30024
30025
30026
30027
30028
30029
30030
30031
30032
30033
30034
30035
30036
30037
30038
30039
30040







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







** available in Windows platforms based on the NT kernel.
*/
#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL)
# error "WAL mode requires support from the Windows NT kernel, compile\
 with SQLITE_OMIT_WAL."
#endif

/*
** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
** based on the sub-platform)?
*/
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
#  define SQLITE_WIN32_HAS_ANSI
#endif

/*
** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions
** based on the sub-platform)?
*/
#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT
#  define SQLITE_WIN32_HAS_WIDE
#endif

/*
** Do we need to manually define the Win32 file mapping APIs for use with WAL
** mode (e.g. these APIs are available in the Windows CE SDK; however, they
** are not present in the header file)?
*/
#if SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL)
/*
** Two of the file mapping APIs are different under WinRT.  Figure out which
** set we need.
*/
#if SQLITE_OS_WINRT
WINBASEAPI HANDLE WINAPI CreateFileMappingFromApp(HANDLE, \
        LPSECURITY_ATTRIBUTES, ULONG, ULONG64, LPCWSTR);

WINBASEAPI LPVOID WINAPI MapViewOfFileFromApp(HANDLE, ULONG, ULONG64, SIZE_T);
#else
#if defined(SQLITE_WIN32_HAS_ANSI)
WINBASEAPI HANDLE WINAPI CreateFileMappingA(HANDLE, LPSECURITY_ATTRIBUTES, \
        DWORD, DWORD, DWORD, LPCSTR);
#endif /* defined(SQLITE_WIN32_HAS_ANSI) */

#if defined(SQLITE_WIN32_HAS_WIDE)
WINBASEAPI HANDLE WINAPI CreateFileMappingW(HANDLE, LPSECURITY_ATTRIBUTES, \
        DWORD, DWORD, DWORD, LPCWSTR);
#endif /* defined(SQLITE_WIN32_HAS_WIDE) */

WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#endif /* SQLITE_OS_WINRT */

/*
** This file mapping API is common to both Win32 and WinRT.
*/
WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
#endif /* SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) */

/*
** Macro to find the minimum of two numeric values.
*/
#ifndef MIN
# define MIN(x,y) ((x)<(y)?(x):(y))
#endif

30135
30136
30137
30138
30139
30140
30141
30142
30143
30144
30145
30146
30147
30148
30149
30150
30151
30152
30153
30154
30155
30156
30232
30233
30234
30235
30236
30237
30238








30239
30240
30241
30242
30243
30244
30245







-
-
-
-
-
-
-
-







*/
#ifdef SQLITE_TEST
SQLITE_API int sqlite3_os_type = 0;
#else
static int sqlite3_os_type = 0;
#endif

#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
#  define SQLITE_WIN32_HAS_ANSI
#endif

#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT
#  define SQLITE_WIN32_HAS_WIDE
#endif

#ifndef SYSCALL
#  define SYSCALL sqlite3_syscall_ptr
#endif

/*
** This function is not available on Windows CE or WinRT.
 */
30299
30300
30301
30302
30303
30304
30305

30306



30307
30308
30309
30310
30311
30312
30313
30388
30389
30390
30391
30392
30393
30394
30395
30396
30397
30398
30399
30400
30401
30402
30403
30404
30405
30406







+

+
+
+







#else
  { "FormatMessageW",          (SYSCALL)0,                       0 },
#endif

#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \
        DWORD,va_list*))aSyscall[15].pCurrent)

#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
  { "FreeLibrary",             (SYSCALL)FreeLibrary,             0 },
#else
  { "FreeLibrary",             (SYSCALL)0,                       0 },
#endif

#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent)

  { "GetCurrentProcessId",     (SYSCALL)GetCurrentProcessId,     0 },

#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent)

30380
30381
30382
30383
30384
30385
30386

30387
30388
30389
30390
30391
30392
30393
30394



30395
30396
30397
30398
30399
30400
30401
30473
30474
30475
30476
30477
30478
30479
30480
30481
30482
30483
30484
30485
30486
30487
30488
30489
30490
30491
30492
30493
30494
30495
30496
30497
30498







+








+
+
+







#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \
        LPWSTR*))aSyscall[25].pCurrent)

  { "GetLastError",            (SYSCALL)GetLastError,            0 },

#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent)

#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
#if SQLITE_OS_WINCE
  /* The GetProcAddressA() routine is only available on Windows CE. */
  { "GetProcAddressA",         (SYSCALL)GetProcAddressA,         0 },
#else
  /* All other Windows platforms expect GetProcAddress() to take
  ** an ANSI string regardless of the _UNICODE setting */
  { "GetProcAddressA",         (SYSCALL)GetProcAddress,          0 },
#endif
#else
  { "GetProcAddressA",         (SYSCALL)0,                       0 },
#endif

#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \
        LPCSTR))aSyscall[27].pCurrent)

#if !SQLITE_OS_WINRT
  { "GetSystemInfo",           (SYSCALL)GetSystemInfo,           0 },
#else
30491
30492
30493
30494
30495
30496
30497
30498

30499
30500
30501
30502
30503
30504
30505
30506


30507
30508
30509
30510
30511
30512
30513
30588
30589
30590
30591
30592
30593
30594

30595
30596
30597
30598
30599
30600
30601
30602

30603
30604
30605
30606
30607
30608
30609
30610
30611







-
+







-
+
+







#else
  { "HeapValidate",            (SYSCALL)0,                       0 },
#endif

#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
        LPCVOID))aSyscall[41].pCurrent)

#if defined(SQLITE_WIN32_HAS_ANSI)
#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
  { "LoadLibraryA",            (SYSCALL)LoadLibraryA,            0 },
#else
  { "LoadLibraryA",            (SYSCALL)0,                       0 },
#endif

#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent)

#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
        !defined(SQLITE_OMIT_LOAD_EXTENSION)
  { "LoadLibraryW",            (SYSCALL)LoadLibraryW,            0 },
#else
  { "LoadLibraryW",            (SYSCALL)0,                       0 },
#endif

#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent)

30688
30689
30690
30691
30692
30693
30694
30695

30696
30697
30698
30699
30700
30701
30702
30786
30787
30788
30789
30790
30791
30792

30793
30794
30795
30796
30797
30798
30799
30800







-
+







#else
  { "CreateFile2",             (SYSCALL)0,                       0 },
#endif

#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
        LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[66].pCurrent)

#if SQLITE_OS_WINRT
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
  { "LoadPackagedLibrary",     (SYSCALL)LoadPackagedLibrary,     0 },
#else
  { "LoadPackagedLibrary",     (SYSCALL)0,                       0 },
#endif

#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
        DWORD))aSyscall[67].pCurrent)
39540
39541
39542
39543
39544
39545
39546















39547
39548
39549
39550
39551
39552
39553
39638
39639
39640
39641
39642
39643
39644
39645
39646
39647
39648
39649
39650
39651
39652
39653
39654
39655
39656
39657
39658
39659
39660
39661
39662
39663
39664
39665
39666







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







      if( rc==SQLITE_OK ){
        pPager->dbFileSize = nPage;
      }
    }
  }
  return rc;
}

/*
** Return a sanitized version of the sector-size of OS file pFile. The
** return value is guaranteed to lie between 32 and MAX_SECTOR_SIZE.
*/
SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *pFile){
  int iRet = sqlite3OsSectorSize(pFile);
  if( iRet<32 ){
    iRet = 512;
  }else if( iRet>MAX_SECTOR_SIZE ){
    assert( MAX_SECTOR_SIZE>=512 );
    iRet = MAX_SECTOR_SIZE;
  }
  return iRet;
}

/*
** Set the value of the Pager.sectorSize variable for the given
** pager based on the value returned by the xSectorSize method
** of the open database file. The sector size will be used used 
** to determine the size and alignment of journal header and 
** master journal pointers within created journal files.
39576
39577
39578
39579
39580
39581
39582
39583
39584
39585

39586
39587
39588
39589
39590
39591
39592
39593
39594
39595
39596
39597
39689
39690
39691
39692
39693
39694
39695



39696





39697
39698
39699
39700
39701
39702
39703







-
-
-
+
-
-
-
-
-







              SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0
  ){
    /* Sector size doesn't matter for temporary files. Also, the file
    ** may not have been opened yet, in which case the OsSectorSize()
    ** call will segfault. */
    pPager->sectorSize = 512;
  }else{
    pPager->sectorSize = sqlite3OsSectorSize(pPager->fd);
    if( pPager->sectorSize<32 ){
      pPager->sectorSize = 512;
    pPager->sectorSize = sqlite3SectorSize(pPager->fd);
    }
    if( pPager->sectorSize>MAX_SECTOR_SIZE ){
      assert( MAX_SECTOR_SIZE>=512 );
      pPager->sectorSize = MAX_SECTOR_SIZE;
    }
  }
}

/*
** Playback the journal and thus restore the database file to
** the state it was in before we started making changes.  
**
40500
40501
40502
40503
40504
40505
40506
40507

40508
40509







40510
40511
40512
40513
40514
40515
40516
40606
40607
40608
40609
40610
40611
40612

40613
40614
40615
40616
40617
40618
40619
40620
40621
40622
40623
40624
40625
40626
40627
40628
40629







-
+


+
+
+
+
+
+
+







** retried. If it returns zero, then the SQLITE_BUSY error is
** returned to the caller of the pager API function.
*/
SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(
  Pager *pPager,                       /* Pager object */
  int (*xBusyHandler)(void *),         /* Pointer to busy-handler function */
  void *pBusyHandlerArg                /* Argument to pass to xBusyHandler */
){  
){
  pPager->xBusyHandler = xBusyHandler;
  pPager->pBusyHandlerArg = pBusyHandlerArg;

  if( isOpen(pPager->fd) ){
    void **ap = (void **)&pPager->xBusyHandler;
    assert( ((int(*)(void *))(ap[0]))==xBusyHandler );
    assert( ap[1]==pBusyHandlerArg );
    sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
  }
}

/*
** Change the page size used by the Pager object. The new page size 
** is passed in *pPageSize.
**
** If the pager is in the error state when this function is called, it
43933
43934
43935
43936
43937
43938
43939


43940
43941
43942
43943
43944
43945
43946
44046
44047
44048
44049
44050
44051
44052
44053
44054
44055
44056
44057
44058
44059
44060
44061







+
+







                           pPager->pageSize, (u8*)pPager->pTmpSpace);
      pPager->pWal = 0;
    }
  }
  return rc;
}

#endif /* !SQLITE_OMIT_WAL */

#ifdef SQLITE_ENABLE_ZIPVFS
/*
** A read-lock must be held on the pager when this function is called. If
** the pager is in WAL mode and the WAL file currently contains one or more
** frames, return the size in bytes of the page images stored within the
** WAL frames. Otherwise, if this is not a WAL database or the WAL file
** is empty, return 0.
43962
43963
43964
43965
43966
43967
43968
43969
43970
43971
43972
43973
43974
43975
43976
43977
44077
44078
44079
44080
44081
44082
44083


44084
44085
44086
44087
44088
44089
44090







-
-







SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
  void *aData = 0;
  CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData);
  return aData;
}
#endif /* SQLITE_HAS_CODEC */

#endif /* !SQLITE_OMIT_WAL */

#endif /* SQLITE_OMIT_DISKIO */

/************** End of pager.c ***********************************************/
/************** Begin file wal.c *********************************************/
/*
** 2010 February 1
**
46797
46798
46799
46800
46801
46802
46803
46804

46805
46806
46807
46808
46809
46810
46811
46910
46911
46912
46913
46914
46915
46916

46917
46918
46919
46920
46921
46922
46923
46924







-
+







  ** final frame is repeated (with its commit mark) until the next sector
  ** boundary is crossed.  Only the part of the WAL prior to the last
  ** sector boundary is synced; the part of the last frame that extends
  ** past the sector boundary is written after the sync.
  */
  if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
    if( pWal->padToSectorBoundary ){
      int sectorSize = sqlite3OsSectorSize(pWal->pWalFd);
      int sectorSize = sqlite3SectorSize(pWal->pWalFd);
      w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize;
      while( iOffset<w.iSyncPoint ){
        rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset);
        if( rc ) return rc;
        iOffset += szFrame;
        nExtra++;
      }
50209
50210
50211
50212
50213
50214
50215


















50216
50217
50218
50219
50220
50221
50222
50322
50323
50324
50325
50326
50327
50328
50329
50330
50331
50332
50333
50334
50335
50336
50337
50338
50339
50340
50341
50342
50343
50344
50345
50346
50347
50348
50349
50350
50351
50352
50353







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








/*
** Return the currently defined page size
*/
SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){
  return p->pBt->pageSize;
}

#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
/*
** This function is similar to sqlite3BtreeGetReserve(), except that it
** may only be called if it is guaranteed that the b-tree mutex is already
** held.
**
** This is useful in one special case in the backup API code where it is
** known that the shared b-tree mutex is held, but the mutex on the 
** database handle that owns *p is not. In this case if sqlite3BtreeEnter()
** were to be called, it might collide with some other operation on the
** database handle that owns *p, causing undefined behaviour.
*/
SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p){
  assert( sqlite3_mutex_held(p->pBt->mutex) );
  return p->pBt->pageSize - p->pBt->usableSize;
}
#endif /* SQLITE_HAS_CODEC || SQLITE_DEBUG */

#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
/*
** Return the number of bytes of space at the end of every page that
** are intentually left unused.  This is the "reserved" space that is
** sometimes used by extensions.
*/
53266
53267
53268
53269
53270
53271
53272
53273

53274
53275
53276
53277
53278
53279
53280
53397
53398
53399
53400
53401
53402
53403

53404
53405
53406
53407
53408
53409
53410
53411







-
+








  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  btreeParseCellPtr(pPage, pCell, &info);
  if( info.iOverflow==0 ){
    return SQLITE_OK;  /* No overflow pages. Return without doing anything */
  }
  if( pCell+info.iOverflow+3 > pPage->aData+pPage->maskPage ){
    return SQLITE_CORRUPT;  /* Cell extends past end of page */
    return SQLITE_CORRUPT_BKPT;  /* Cell extends past end of page */
  }
  ovflPgno = get4byte(&pCell[info.iOverflow]);
  assert( pBt->usableSize > 4 );
  ovflPageSize = pBt->usableSize - 4;
  nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
  assert( ovflPgno==0 || nOvfl>0 );
  while( nOvfl-- ){
53932
53933
53934
53935
53936
53937
53938



53939
53940
53941
53942
53943
53944
53945
54063
54064
54065
54066
54067
54068
54069
54070
54071
54072
54073
54074
54075
54076
54077
54078
54079







+
+
+







** size of a cell stored within an internal node is always less than 1/4
** of the page-size, the aOvflSpace[] buffer is guaranteed to be large
** enough for all overflow cells.
**
** If aOvflSpace is set to a null pointer, this function returns 
** SQLITE_NOMEM.
*/
#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
#pragma optimize("", off)
#endif
static int balance_nonroot(
  MemPage *pParent,               /* Parent page of siblings being balanced */
  int iParentIdx,                 /* Index of "the page" in pParent */
  u8 *aOvflSpace,                 /* page-size bytes of space for parent ovfl */
  int isRoot,                     /* True if pParent is a root-page */
  int bBulk                       /* True if this call is part of a bulk load */
){
54562
54563
54564
54565
54566
54567
54568



54569
54570
54571
54572
54573
54574
54575
54696
54697
54698
54699
54700
54701
54702
54703
54704
54705
54706
54707
54708
54709
54710
54711
54712







+
+
+







  }
  for(i=0; i<nNew; i++){
    releasePage(apNew[i]);
  }

  return rc;
}
#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
#pragma optimize("", on)
#endif


/*
** This function is called when the root page of a b-tree structure is
** overfull (has one or more overflow pages).
**
** A new child page is allocated and the contents of the current root
56540
56541
56542
56543
56544
56545
56546



56547

56548
56549
56550
56551
56552
56553

56554
56555
56556
56557
56558
56559
56560
56677
56678
56679
56680
56681
56682
56683
56684
56685
56686

56687
56688
56689

56690
56691
56692
56693
56694
56695
56696
56697
56698
56699
56700







+
+
+
-
+


-



+







static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){
  Pager * const pDestPager = sqlite3BtreePager(p->pDest);
  const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
  int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
  const int nCopy = MIN(nSrcPgsz, nDestPgsz);
  const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
#ifdef SQLITE_HAS_CODEC
  /* Use BtreeGetReserveNoMutex() for the source b-tree, as although it is
  ** guaranteed that the shared-mutex is held by this thread, handle
  ** p->pSrc may not actually be the owner.  */
  int nSrcReserve = sqlite3BtreeGetReserve(p->pSrc);
  int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc);
  int nDestReserve = sqlite3BtreeGetReserve(p->pDest);
#endif

  int rc = SQLITE_OK;
  i64 iOff;

  assert( sqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 );
  assert( p->bDestLocked );
  assert( !isFatalError(p->rc) );
  assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );
  assert( zSrcData );

  /* Catch the case where the destination is an in-memory database and the
  ** page sizes of the source and destination differ. 
59970
59971
59972
59973
59974
59975
59976

59977

59978
59979
59980
59981
59982
59983
59984
60110
60111
60112
60113
60114
60115
60116
60117
60118
60119
60120
60121
60122
60123
60124
60125
60126







+

+







  ** file is required for an atomic commit.
  */ 
  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ 
    Btree *pBt = db->aDb[i].pBt;
    if( sqlite3BtreeIsInTrans(pBt) ){
      needXcommit = 1;
      if( i!=1 ) nTrans++;
      sqlite3BtreeEnter(pBt);
      rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt));
      sqlite3BtreeLeave(pBt);
    }
  }
  if( rc!=SQLITE_OK ){
    return rc;
  }

  /* If there are any write-transactions at all, invoke the commit hook */
63706
63707
63708
63709
63710
63711
63712



63713
63714
63715
63716

63717
63718
63719

63720
63721
63722
63723
63724
63725
63726

63727
63728
63729
63730
63731
63732
63733

63734
63735
63736
63737
63738
63739

63740
63741
63742
63743
63744
63745

63746
63747
63748
63749
63750
63751
63752
63753
63754
63755

63756
63757
63758
63759

63760
63761
63762

63763
63764
63765
63766
63767
63768
63769
63848
63849
63850
63851
63852
63853
63854
63855
63856
63857
63858
63859
63860

63861
63862
63863

63864
63865
63866
63867
63868
63869
63870

63871
63872
63873
63874
63875
63876
63877

63878
63879
63880
63881
63882
63883

63884
63885
63886
63887
63888
63889

63890
63891
63892
63893
63894
63895
63896
63897
63898
63899

63900
63901
63902
63903

63904
63905
63906

63907
63908
63909
63910
63911
63912
63913
63914







+
+
+



-
+


-
+






-
+






-
+





-
+





-
+









-
+



-
+


-
+







    } ac;
    struct OP_Move_stack_vars {
      char *zMalloc;   /* Holding variable for allocated memory */
      int n;           /* Number of registers left to copy */
      int p1;          /* Register to copy from */
      int p2;          /* Register to copy to */
    } ad;
    struct OP_Copy_stack_vars {
      int n;
    } ae;
    struct OP_ResultRow_stack_vars {
      Mem *pMem;
      int i;
    } ae;
    } af;
    struct OP_Concat_stack_vars {
      i64 nByte;
    } af;
    } ag;
    struct OP_Remainder_stack_vars {
      int flags;      /* Combined MEM_* flags from both inputs */
      i64 iA;         /* Integer value of left operand */
      i64 iB;         /* Integer value of right operand */
      double rA;      /* Real value of left operand */
      double rB;      /* Real value of right operand */
    } ag;
    } ah;
    struct OP_Function_stack_vars {
      int i;
      Mem *pArg;
      sqlite3_context ctx;
      sqlite3_value **apVal;
      int n;
    } ah;
    } ai;
    struct OP_ShiftRight_stack_vars {
      i64 iA;
      u64 uA;
      i64 iB;
      u8 op;
    } ai;
    } aj;
    struct OP_Ge_stack_vars {
      int res;            /* Result of the comparison of pIn1 against pIn3 */
      char affinity;      /* Affinity to use for comparison */
      u16 flags1;         /* Copy of initial value of pIn1->flags */
      u16 flags3;         /* Copy of initial value of pIn3->flags */
    } aj;
    } ak;
    struct OP_Compare_stack_vars {
      int n;
      int i;
      int p1;
      int p2;
      const KeyInfo *pKeyInfo;
      int idx;
      CollSeq *pColl;    /* Collating sequence to use on this term */
      int bRev;          /* True for DESCENDING sort order */
    } ak;
    } al;
    struct OP_Or_stack_vars {
      int v1;    /* Left operand:  0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
      int v2;    /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
    } al;
    } am;
    struct OP_IfNot_stack_vars {
      int c;
    } am;
    } an;
    struct OP_Column_stack_vars {
      u32 payloadSize;   /* Number of bytes in the record */
      i64 payloadSize64; /* Number of bytes in the record */
      int p1;            /* P1 value of the opcode */
      int p2;            /* column number to retrieve */
      VdbeCursor *pC;    /* The VDBE cursor */
      char *zRec;        /* Pointer to complete record-data */
63780
63781
63782
63783
63784
63785
63786
63787

63788
63789
63790
63791

63792
63793
63794
63795
63796
63797
63798
63799
63800
63801
63802
63803
63804
63805
63806
63807
63808

63809
63810
63811
63812

63813
63814
63815
63816
63817
63818
63819
63820
63821
63822

63823
63824
63825
63826
63827

63828
63829
63830

63831
63832
63833
63834
63835

63836
63837
63838

63839
63840
63841
63842
63843

63844
63845
63846
63847
63848
63849
63850
63851
63852
63853

63854
63855
63856

63857
63858
63859

63860
63861
63862

63863
63864
63865
63866
63867
63868
63869
63870

63871
63872
63873

63874
63875
63876
63877
63878
63879
63880
63881
63882

63883
63884
63885
63886
63887
63888
63889
63890
63891

63892
63893
63894
63895
63896
63897

63898
63899
63900
63901
63902
63903
63904
63905

63906
63907
63908
63909
63910
63911
63912
63913
63914
63915
63916

63917
63918
63919
63920

63921
63922
63923
63924

63925
63926
63927

63928
63929
63930
63931
63932
63933

63934
63935
63936
63937
63938
63939

63940
63941
63942

63943
63944
63945
63946
63947

63948
63949
63950
63951
63952

63953
63954
63955
63956

63957
63958
63959
63960
63961
63962

63963
63964
63965
63966
63967
63968

63969
63970
63971
63972
63973

63974
63975
63976
63977
63978

63979
63980
63981
63982
63983
63984

63985
63986
63987

63988
63989
63990
63991
63992

63993
63994
63995
63996
63997
63998

63999
64000
64001
64002
64003
64004
64005
64006

64007
64008
64009

64010
64011
64012
64013

64014
64015
64016
64017
64018
64019
64020
64021
64022
64023

64024
64025
64026
64027

64028
64029
64030
64031

64032
64033
64034
64035
64036
64037
64038
64039

64040
64041
64042

64043
64044
64045
64046
64047

64048
64049
64050
64051
64052
64053
64054
64055
64056

64057
64058
64059

64060
64061
64062

64063
64064
64065
64066
64067
64068

64069
64070
64071
64072
64073
64074
64075
64076
64077
64078
64079
64080
64081

64082
64083
64084
64085
64086
64087

64088
64089
64090
64091
64092
64093

64094
64095
64096
64097

64098
64099
64100
64101
64102
64103
64104
64105
64106

64107
64108
64109
64110

64111
64112
64113
64114
64115
64116
64117
63925
63926
63927
63928
63929
63930
63931

63932
63933
63934
63935

63936
63937
63938
63939
63940
63941
63942
63943
63944
63945
63946
63947
63948
63949
63950
63951
63952

63953
63954
63955
63956

63957
63958
63959
63960
63961
63962
63963
63964
63965
63966

63967
63968
63969
63970
63971

63972
63973
63974

63975
63976
63977
63978
63979

63980
63981
63982

63983
63984
63985
63986
63987

63988
63989
63990
63991
63992
63993
63994
63995
63996
63997

63998
63999
64000

64001
64002
64003

64004
64005
64006

64007
64008
64009
64010
64011
64012
64013
64014

64015
64016
64017

64018
64019
64020
64021
64022
64023
64024
64025
64026

64027
64028
64029
64030
64031
64032
64033
64034
64035

64036
64037
64038
64039
64040
64041

64042
64043
64044
64045
64046
64047
64048
64049

64050
64051
64052
64053
64054
64055
64056
64057
64058
64059
64060

64061
64062
64063
64064

64065
64066
64067
64068

64069
64070
64071

64072
64073
64074
64075
64076
64077

64078
64079
64080
64081
64082
64083

64084
64085
64086

64087
64088
64089
64090
64091

64092
64093
64094
64095
64096

64097
64098
64099
64100

64101
64102
64103
64104
64105
64106

64107
64108
64109
64110
64111
64112

64113
64114
64115
64116
64117

64118
64119
64120
64121
64122

64123
64124
64125
64126
64127
64128

64129
64130
64131

64132
64133
64134
64135
64136

64137
64138
64139
64140
64141
64142

64143
64144
64145
64146
64147
64148
64149
64150

64151
64152
64153

64154
64155
64156
64157

64158
64159
64160
64161
64162
64163
64164
64165
64166
64167

64168
64169
64170
64171

64172
64173
64174
64175

64176
64177
64178
64179
64180
64181
64182
64183

64184
64185
64186

64187
64188
64189
64190
64191

64192
64193
64194
64195
64196
64197
64198
64199
64200

64201
64202
64203

64204
64205
64206

64207
64208
64209
64210
64211
64212

64213
64214
64215
64216
64217
64218
64219
64220
64221
64222
64223
64224
64225

64226
64227
64228
64229
64230
64231

64232
64233
64234
64235
64236
64237

64238
64239
64240
64241

64242
64243
64244
64245
64246
64247
64248
64249
64250

64251
64252
64253
64254

64255
64256
64257
64258
64259
64260
64261
64262







-
+



-
+
















-
+



-
+









-
+




-
+


-
+




-
+


-
+




-
+









-
+


-
+


-
+


-
+







-
+


-
+








-
+








-
+





-
+







-
+










-
+



-
+



-
+


-
+





-
+





-
+


-
+




-
+




-
+



-
+





-
+





-
+




-
+




-
+





-
+


-
+




-
+





-
+







-
+


-
+



-
+









-
+



-
+



-
+







-
+


-
+




-
+








-
+


-
+


-
+





-
+












-
+





-
+





-
+



-
+








-
+



-
+







      u8 *zEndHdr;       /* Pointer to first byte after the header */
      u32 offset;        /* Offset into the data */
      u32 szField;       /* Number of bytes in the content of a field */
      int szHdr;         /* Size of the header size field at start of record */
      int avail;         /* Number of bytes of available data */
      u32 t;             /* A type code from the record header */
      Mem *pReg;         /* PseudoTable input register */
    } an;
    } ao;
    struct OP_Affinity_stack_vars {
      const char *zAffinity;   /* The affinity to be applied */
      char cAff;               /* A single character of affinity */
    } ao;
    } ap;
    struct OP_MakeRecord_stack_vars {
      u8 *zNewRecord;        /* A buffer to hold the data for the new record */
      Mem *pRec;             /* The new record */
      u64 nData;             /* Number of bytes of data space */
      int nHdr;              /* Number of bytes of header space */
      i64 nByte;             /* Data space required for this record */
      int nZero;             /* Number of zero bytes at the end of the record */
      int nVarint;           /* Number of bytes in a varint */
      u32 serial_type;       /* Type field */
      Mem *pData0;           /* First field to be combined into the record */
      Mem *pLast;            /* Last field of the record */
      int nField;            /* Number of fields in the record */
      char *zAffinity;       /* The affinity string for the record */
      int file_format;       /* File format to use for encoding */
      int i;                 /* Space used in zNewRecord[] */
      int len;               /* Length of a field */
    } ap;
    } aq;
    struct OP_Count_stack_vars {
      i64 nEntry;
      BtCursor *pCrsr;
    } aq;
    } ar;
    struct OP_Savepoint_stack_vars {
      int p1;                         /* Value of P1 operand */
      char *zName;                    /* Name of savepoint */
      int nName;
      Savepoint *pNew;
      Savepoint *pSavepoint;
      Savepoint *pTmp;
      int iSavepoint;
      int ii;
    } ar;
    } as;
    struct OP_AutoCommit_stack_vars {
      int desiredAutoCommit;
      int iRollback;
      int turnOnAC;
    } as;
    } at;
    struct OP_Transaction_stack_vars {
      Btree *pBt;
    } at;
    } au;
    struct OP_ReadCookie_stack_vars {
      int iMeta;
      int iDb;
      int iCookie;
    } au;
    } av;
    struct OP_SetCookie_stack_vars {
      Db *pDb;
    } av;
    } aw;
    struct OP_VerifyCookie_stack_vars {
      int iMeta;
      int iGen;
      Btree *pBt;
    } aw;
    } ax;
    struct OP_OpenWrite_stack_vars {
      int nField;
      KeyInfo *pKeyInfo;
      int p2;
      int iDb;
      int wrFlag;
      Btree *pX;
      VdbeCursor *pCur;
      Db *pDb;
    } ax;
    } ay;
    struct OP_OpenEphemeral_stack_vars {
      VdbeCursor *pCx;
    } ay;
    } az;
    struct OP_SorterOpen_stack_vars {
      VdbeCursor *pCx;
    } az;
    } ba;
    struct OP_OpenPseudo_stack_vars {
      VdbeCursor *pCx;
    } ba;
    } bb;
    struct OP_SeekGt_stack_vars {
      int res;
      int oc;
      VdbeCursor *pC;
      UnpackedRecord r;
      int nField;
      i64 iKey;      /* The rowid we are to seek to */
    } bb;
    } bc;
    struct OP_Seek_stack_vars {
      VdbeCursor *pC;
    } bc;
    } bd;
    struct OP_Found_stack_vars {
      int alreadyExists;
      VdbeCursor *pC;
      int res;
      char *pFree;
      UnpackedRecord *pIdxKey;
      UnpackedRecord r;
      char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
    } bd;
    } be;
    struct OP_IsUnique_stack_vars {
      u16 ii;
      VdbeCursor *pCx;
      BtCursor *pCrsr;
      u16 nField;
      Mem *aMx;
      UnpackedRecord r;                  /* B-Tree index search key */
      i64 R;                             /* Rowid stored in register P3 */
    } be;
    } bf;
    struct OP_NotExists_stack_vars {
      VdbeCursor *pC;
      BtCursor *pCrsr;
      int res;
      u64 iKey;
    } bf;
    } bg;
    struct OP_NewRowid_stack_vars {
      i64 v;                 /* The new rowid */
      VdbeCursor *pC;        /* Cursor of table to get the new rowid */
      int res;               /* Result of an sqlite3BtreeLast() */
      int cnt;               /* Counter to limit the number of searches */
      Mem *pMem;             /* Register holding largest rowid for AUTOINCREMENT */
      VdbeFrame *pFrame;     /* Root frame of VDBE */
    } bg;
    } bh;
    struct OP_InsertInt_stack_vars {
      Mem *pData;       /* MEM cell holding data for the record to be inserted */
      Mem *pKey;        /* MEM cell holding key  for the record */
      i64 iKey;         /* The integer ROWID or key for the record to be inserted */
      VdbeCursor *pC;   /* Cursor to table into which insert is written */
      int nZero;        /* Number of zero-bytes to append */
      int seekResult;   /* Result of prior seek or 0 if no USESEEKRESULT flag */
      const char *zDb;  /* database name - used by the update hook */
      const char *zTbl; /* Table name - used by the opdate hook */
      int op;           /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
    } bh;
    } bi;
    struct OP_Delete_stack_vars {
      i64 iKey;
      VdbeCursor *pC;
    } bi;
    } bj;
    struct OP_SorterCompare_stack_vars {
      VdbeCursor *pC;
      int res;
    } bj;
    } bk;
    struct OP_SorterData_stack_vars {
      VdbeCursor *pC;
    } bk;
    } bl;
    struct OP_RowData_stack_vars {
      VdbeCursor *pC;
      BtCursor *pCrsr;
      u32 n;
      i64 n64;
    } bl;
    } bm;
    struct OP_Rowid_stack_vars {
      VdbeCursor *pC;
      i64 v;
      sqlite3_vtab *pVtab;
      const sqlite3_module *pModule;
    } bm;
    } bn;
    struct OP_NullRow_stack_vars {
      VdbeCursor *pC;
    } bn;
    } bo;
    struct OP_Last_stack_vars {
      VdbeCursor *pC;
      BtCursor *pCrsr;
      int res;
    } bo;
    } bp;
    struct OP_Rewind_stack_vars {
      VdbeCursor *pC;
      BtCursor *pCrsr;
      int res;
    } bp;
    } bq;
    struct OP_Next_stack_vars {
      VdbeCursor *pC;
      int res;
    } bq;
    } br;
    struct OP_IdxInsert_stack_vars {
      VdbeCursor *pC;
      BtCursor *pCrsr;
      int nKey;
      const char *zKey;
    } br;
    } bs;
    struct OP_IdxDelete_stack_vars {
      VdbeCursor *pC;
      BtCursor *pCrsr;
      int res;
      UnpackedRecord r;
    } bs;
    } bt;
    struct OP_IdxRowid_stack_vars {
      BtCursor *pCrsr;
      VdbeCursor *pC;
      i64 rowid;
    } bt;
    } bu;
    struct OP_IdxGE_stack_vars {
      VdbeCursor *pC;
      int res;
      UnpackedRecord r;
    } bu;
    } bv;
    struct OP_Destroy_stack_vars {
      int iMoved;
      int iCnt;
      Vdbe *pVdbe;
      int iDb;
    } bv;
    } bw;
    struct OP_Clear_stack_vars {
      int nChange;
    } bw;
    } bx;
    struct OP_CreateTable_stack_vars {
      int pgno;
      int flags;
      Db *pDb;
    } bx;
    } by;
    struct OP_ParseSchema_stack_vars {
      int iDb;
      const char *zMaster;
      char *zSql;
      InitData initData;
    } by;
    } bz;
    struct OP_IntegrityCk_stack_vars {
      int nRoot;      /* Number of tables to check.  (Number of root pages.) */
      int *aRoot;     /* Array of rootpage numbers for tables to be checked */
      int j;          /* Loop counter */
      int nErr;       /* Number of errors reported */
      char *z;        /* Text of the error report */
      Mem *pnErr;     /* Register keeping track of errors remaining */
    } bz;
    } ca;
    struct OP_RowSetRead_stack_vars {
      i64 val;
    } ca;
    } cb;
    struct OP_RowSetTest_stack_vars {
      int iSet;
      int exists;
    } cb;
    } cc;
    struct OP_Program_stack_vars {
      int nMem;               /* Number of memory registers for sub-program */
      int nByte;              /* Bytes of runtime space required for sub-program */
      Mem *pRt;               /* Register to allocate runtime space */
      Mem *pMem;              /* Used to iterate through memory cells */
      Mem *pEnd;              /* Last memory cell in new array */
      VdbeFrame *pFrame;      /* New vdbe frame to execute in */
      SubProgram *pProgram;   /* Sub-program to execute */
      void *t;                /* Token identifying trigger */
    } cc;
    } cd;
    struct OP_Param_stack_vars {
      VdbeFrame *pFrame;
      Mem *pIn;
    } cd;
    } ce;
    struct OP_MemMax_stack_vars {
      Mem *pIn1;
      VdbeFrame *pFrame;
    } ce;
    } cf;
    struct OP_AggStep_stack_vars {
      int n;
      int i;
      Mem *pMem;
      Mem *pRec;
      sqlite3_context ctx;
      sqlite3_value **apVal;
    } cf;
    } cg;
    struct OP_AggFinal_stack_vars {
      Mem *pMem;
    } cg;
    } ch;
    struct OP_Checkpoint_stack_vars {
      int i;                          /* Loop counter */
      int aRes[3];                    /* Results */
      Mem *pMem;                      /* Write results here */
    } ch;
    } ci;
    struct OP_JournalMode_stack_vars {
      Btree *pBt;                     /* Btree to change journal mode of */
      Pager *pPager;                  /* Pager associated with pBt */
      int eNew;                       /* New journal mode */
      int eOld;                       /* The old journal mode */
#ifndef SQLITE_OMIT_WAL
      const char *zFilename;          /* Name of database file for pPager */
#endif
    } ci;
    } cj;
    struct OP_IncrVacuum_stack_vars {
      Btree *pBt;
    } cj;
    } ck;
    struct OP_VBegin_stack_vars {
      VTable *pVTab;
    } ck;
    } cl;
    struct OP_VOpen_stack_vars {
      VdbeCursor *pCur;
      sqlite3_vtab_cursor *pVtabCursor;
      sqlite3_vtab *pVtab;
      sqlite3_module *pModule;
    } cl;
    } cm;
    struct OP_VFilter_stack_vars {
      int nArg;
      int iQuery;
      const sqlite3_module *pModule;
      Mem *pQuery;
      Mem *pArgc;
      sqlite3_vtab_cursor *pVtabCursor;
      sqlite3_vtab *pVtab;
      VdbeCursor *pCur;
      int res;
      int i;
      Mem **apArg;
    } cm;
    } cn;
    struct OP_VColumn_stack_vars {
      sqlite3_vtab *pVtab;
      const sqlite3_module *pModule;
      Mem *pDest;
      sqlite3_context sContext;
    } cn;
    } co;
    struct OP_VNext_stack_vars {
      sqlite3_vtab *pVtab;
      const sqlite3_module *pModule;
      int res;
      VdbeCursor *pCur;
    } co;
    } cp;
    struct OP_VRename_stack_vars {
      sqlite3_vtab *pVtab;
      Mem *pName;
    } cp;
    } cq;
    struct OP_VUpdate_stack_vars {
      sqlite3_vtab *pVtab;
      sqlite3_module *pModule;
      int nArg;
      int i;
      sqlite_int64 rowid;
      Mem **apArg;
      Mem *pX;
    } cq;
    } cr;
    struct OP_Trace_stack_vars {
      char *zTrace;
      char *z;
    } cr;
    } cs;
  } u;
  /* End automatically generated code
  ********************************************************************/

  assert( p->magic==VDBE_MAGIC_RUN );  /* sqlite3_step() verifies this */
  sqlite3VdbeEnter(p);
  if( p->rc==SQLITE_NOMEM ){
64562
64563
64564
64565
64566
64567
64568
64569
64570


64571
64572

64573
64574
64575
64576
64577
64578
64579
64580
64581
64582

64583
64584
64585
64586
64587
64588
64589
64707
64708
64709
64710
64711
64712
64713


64714
64715
64716

64717
64718
64719
64720
64721
64722
64723
64724
64725
64726

64727
64728
64729
64730
64731
64732
64733
64734







-
-
+
+

-
+









-
+







  sqlite3VdbeMemShallowCopy(pOut, u.ac.pVar, MEM_Static);
  UPDATE_MAX_BLOBSIZE(pOut);
  break;
}

/* Opcode: Move P1 P2 P3 * *
**
** Move the values in register P1..P1+P3-1 over into
** registers P2..P2+P3-1.  Registers P1..P1+P1-1 are
** Move the values in register P1..P1+P3 over into
** registers P2..P2+P3.  Registers P1..P1+P3 are
** left holding a NULL.  It is an error for register ranges
** P1..P1+P3-1 and P2..P2+P3-1 to overlap.
** P1..P1+P3 and P2..P2+P3 to overlap.
*/
case OP_Move: {
#if 0  /* local variables moved into u.ad */
  char *zMalloc;   /* Holding variable for allocated memory */
  int n;           /* Number of registers left to copy */
  int p1;          /* Register to copy from */
  int p2;          /* Register to copy to */
#endif /* local variables moved into u.ad */

  u.ad.n = pOp->p3;
  u.ad.n = pOp->p3 + 1;
  u.ad.p1 = pOp->p1;
  u.ad.p2 = pOp->p2;
  assert( u.ad.n>0 && u.ad.p1>0 && u.ad.p2>0 );
  assert( u.ad.p1+u.ad.n<=u.ad.p2 || u.ad.p2+u.ad.n<=u.ad.p1 );

  pIn1 = &aMem[u.ad.p1];
  pOut = &aMem[u.ad.p2];
64604
64605
64606
64607
64608
64609
64610
64611

64612
64613

64614
64615
64616
64617
64618






64619
64620
64621

64622
64623
64624







64625
64626
64627
64628
64629
64630
64631
64749
64750
64751
64752
64753
64754
64755

64756
64757

64758
64759
64760
64761
64762

64763
64764
64765
64766
64767
64768
64769
64770
64771
64772



64773
64774
64775
64776
64777
64778
64779
64780
64781
64782
64783
64784
64785
64786







-
+

-
+




-
+
+
+
+
+
+



+
-
-
-
+
+
+
+
+
+
+







    REGISTER_TRACE(u.ad.p2++, pOut);
    pIn1++;
    pOut++;
  }
  break;
}

/* Opcode: Copy P1 P2 * * *
/* Opcode: Copy P1 P2 P3 * *
**
** Make a copy of register P1 into register P2.
** Make a copy of registers P1..P1+P3 into registers P2..P2+P3.
**
** This instruction makes a deep copy of the value.  A duplicate
** is made of any string or blob constant.  See also OP_SCopy.
*/
case OP_Copy: {             /* in1, out2 */
case OP_Copy: {
#if 0  /* local variables moved into u.ae */
  int n;
#endif /* local variables moved into u.ae */

  u.ae.n = pOp->p3;
  pIn1 = &aMem[pOp->p1];
  pOut = &aMem[pOp->p2];
  assert( pOut!=pIn1 );
  while( 1 ){
  sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
  Deephemeralize(pOut);
  REGISTER_TRACE(pOp->p2, pOut);
    sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
    Deephemeralize(pOut);
    REGISTER_TRACE(pOp->p2+pOp->p3-u.ae.n, pOut);
    if( (u.ae.n--)==0 ) break;
    pOut++;
    pIn1++;
  }
  break;
}

/* Opcode: SCopy P1 P2 * * *
**
** Make a shallow copy of register P1 into register P2.
**
64654
64655
64656
64657
64658
64659
64660
64661

64662
64663
64664

64665
64666
64667
64668
64669
64670
64671
64809
64810
64811
64812
64813
64814
64815

64816
64817
64818

64819
64820
64821
64822
64823
64824
64825
64826







-
+


-
+







** The registers P1 through P1+P2-1 contain a single row of
** results. This opcode causes the sqlite3_step() call to terminate
** with an SQLITE_ROW return code and it sets up the sqlite3_stmt
** structure to provide access to the top P1 values as the result
** row.
*/
case OP_ResultRow: {
#if 0  /* local variables moved into u.ae */
#if 0  /* local variables moved into u.af */
  Mem *pMem;
  int i;
#endif /* local variables moved into u.ae */
#endif /* local variables moved into u.af */
  assert( p->nResColumn==pOp->p2 );
  assert( pOp->p1>0 );
  assert( pOp->p1+pOp->p2<=p->nMem+1 );

  /* If this statement has violated immediate foreign key constraints, do
  ** not return the number of rows modified. And do not RELEASE the statement
  ** transaction. It needs to be rolled back.  */
64699
64700
64701
64702
64703
64704
64705
64706
64707
64708
64709
64710
64711
64712
64713
64714









64715
64716
64717
64718
64719
64720
64721
64854
64855
64856
64857
64858
64859
64860









64861
64862
64863
64864
64865
64866
64867
64868
64869
64870
64871
64872
64873
64874
64875
64876







-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+







  /* Invalidate all ephemeral cursor row caches */
  p->cacheCtr = (p->cacheCtr + 2)|1;

  /* Make sure the results of the current row are \000 terminated
  ** and have an assigned type.  The results are de-ephemeralized as
  ** a side effect.
  */
  u.ae.pMem = p->pResultSet = &aMem[pOp->p1];
  for(u.ae.i=0; u.ae.i<pOp->p2; u.ae.i++){
    assert( memIsValid(&u.ae.pMem[u.ae.i]) );
    Deephemeralize(&u.ae.pMem[u.ae.i]);
    assert( (u.ae.pMem[u.ae.i].flags & MEM_Ephem)==0
            || (u.ae.pMem[u.ae.i].flags & (MEM_Str|MEM_Blob))==0 );
    sqlite3VdbeMemNulTerminate(&u.ae.pMem[u.ae.i]);
    sqlite3VdbeMemStoreType(&u.ae.pMem[u.ae.i]);
    REGISTER_TRACE(pOp->p1+u.ae.i, &u.ae.pMem[u.ae.i]);
  u.af.pMem = p->pResultSet = &aMem[pOp->p1];
  for(u.af.i=0; u.af.i<pOp->p2; u.af.i++){
    assert( memIsValid(&u.af.pMem[u.af.i]) );
    Deephemeralize(&u.af.pMem[u.af.i]);
    assert( (u.af.pMem[u.af.i].flags & MEM_Ephem)==0
            || (u.af.pMem[u.af.i].flags & (MEM_Str|MEM_Blob))==0 );
    sqlite3VdbeMemNulTerminate(&u.af.pMem[u.af.i]);
    sqlite3VdbeMemStoreType(&u.af.pMem[u.af.i]);
    REGISTER_TRACE(pOp->p1+u.af.i, &u.af.pMem[u.af.i]);
  }
  if( db->mallocFailed ) goto no_mem;

  /* Return SQLITE_ROW
  */
  p->pc = pc + 1;
  rc = SQLITE_ROW;
64731
64732
64733
64734
64735
64736
64737
64738

64739
64740

64741
64742
64743
64744
64745
64746
64747
64748
64749
64750
64751
64752
64753
64754


64755
64756
64757
64758

64759
64760
64761
64762
64763
64764
64765
64766


64767
64768

64769
64770
64771
64772
64773
64774
64775
64886
64887
64888
64889
64890
64891
64892

64893
64894

64895
64896
64897
64898
64899
64900
64901
64902
64903
64904
64905
64906
64907


64908
64909
64910
64911
64912

64913
64914
64915
64916
64917
64918
64919


64920
64921
64922

64923
64924
64925
64926
64927
64928
64929
64930







-
+

-
+












-
-
+
+



-
+






-
-
+
+

-
+







**   P3 = P2 || P1
**
** It is illegal for P1 and P3 to be the same register. Sometimes,
** if P3 is the same register as P2, the implementation is able
** to avoid a memcpy().
*/
case OP_Concat: {           /* same as TK_CONCAT, in1, in2, out3 */
#if 0  /* local variables moved into u.af */
#if 0  /* local variables moved into u.ag */
  i64 nByte;
#endif /* local variables moved into u.af */
#endif /* local variables moved into u.ag */

  pIn1 = &aMem[pOp->p1];
  pIn2 = &aMem[pOp->p2];
  pOut = &aMem[pOp->p3];
  assert( pIn1!=pOut );
  if( (pIn1->flags | pIn2->flags) & MEM_Null ){
    sqlite3VdbeMemSetNull(pOut);
    break;
  }
  if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
  Stringify(pIn1, encoding);
  Stringify(pIn2, encoding);
  u.af.nByte = pIn1->n + pIn2->n;
  if( u.af.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
  u.ag.nByte = pIn1->n + pIn2->n;
  if( u.ag.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
    goto too_big;
  }
  MemSetTypeFlag(pOut, MEM_Str);
  if( sqlite3VdbeMemGrow(pOut, (int)u.af.nByte+2, pOut==pIn2) ){
  if( sqlite3VdbeMemGrow(pOut, (int)u.ag.nByte+2, pOut==pIn2) ){
    goto no_mem;
  }
  if( pOut!=pIn2 ){
    memcpy(pOut->z, pIn2->z, pIn2->n);
  }
  memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
  pOut->z[u.af.nByte] = 0;
  pOut->z[u.af.nByte+1] = 0;
  pOut->z[u.ag.nByte] = 0;
  pOut->z[u.ag.nByte+1] = 0;
  pOut->flags |= MEM_Term;
  pOut->n = (int)u.af.nByte;
  pOut->n = (int)u.ag.nByte;
  pOut->enc = encoding;
  UPDATE_MAX_BLOBSIZE(pOut);
  break;
}

/* Opcode: Add P1 P2 P3 * *
**
64805
64806
64807
64808
64809
64810
64811
64812

64813
64814
64815
64816
64817
64818

64819
64820
64821
64822
64823
64824
64825
64826


64827
64828
64829


64830
64831
64832
64833



64834
64835
64836
64837



64838
64839
64840
64841
64842
64843



64844
64845
64846
64847

64848
64849
64850
64851
64852


64853
64854
64855
64856



64857
64858
64859
64860


64861
64862
64863
64864
64865
64866
64867
64868





64869
64870
64871
64872
64873

64874
64875
64876

64877
64878
64879

64880
64881

64882
64883
64884
64885
64886
64887
64888
64960
64961
64962
64963
64964
64965
64966

64967
64968
64969
64970
64971
64972

64973
64974
64975
64976
64977
64978
64979


64980
64981
64982


64983
64984
64985



64986
64987
64988
64989



64990
64991
64992
64993
64994
64995



64996
64997
64998
64999
65000
65001

65002
65003
65004
65005


65006
65007
65008



65009
65010
65011
65012
65013


65014
65015
65016
65017
65018





65019
65020
65021
65022
65023
65024
65025
65026
65027

65028
65029
65030

65031
65032
65033

65034
65035

65036
65037
65038
65039
65040
65041
65042
65043







-
+





-
+






-
-
+
+

-
-
+
+

-
-
-
+
+
+

-
-
-
+
+
+



-
-
-
+
+
+



-
+



-
-
+
+

-
-
-
+
+
+


-
-
+
+



-
-
-
-
-
+
+
+
+
+




-
+


-
+


-
+

-
+







** If either operand is NULL, the result is NULL.
*/
case OP_Add:                   /* same as TK_PLUS, in1, in2, out3 */
case OP_Subtract:              /* same as TK_MINUS, in1, in2, out3 */
case OP_Multiply:              /* same as TK_STAR, in1, in2, out3 */
case OP_Divide:                /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
#if 0  /* local variables moved into u.ag */
#if 0  /* local variables moved into u.ah */
  int flags;      /* Combined MEM_* flags from both inputs */
  i64 iA;         /* Integer value of left operand */
  i64 iB;         /* Integer value of right operand */
  double rA;      /* Real value of left operand */
  double rB;      /* Real value of right operand */
#endif /* local variables moved into u.ag */
#endif /* local variables moved into u.ah */

  pIn1 = &aMem[pOp->p1];
  applyNumericAffinity(pIn1);
  pIn2 = &aMem[pOp->p2];
  applyNumericAffinity(pIn2);
  pOut = &aMem[pOp->p3];
  u.ag.flags = pIn1->flags | pIn2->flags;
  if( (u.ag.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
  u.ah.flags = pIn1->flags | pIn2->flags;
  if( (u.ah.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
  if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
    u.ag.iA = pIn1->u.i;
    u.ag.iB = pIn2->u.i;
    u.ah.iA = pIn1->u.i;
    u.ah.iB = pIn2->u.i;
    switch( pOp->opcode ){
      case OP_Add:       if( sqlite3AddInt64(&u.ag.iB,u.ag.iA) ) goto fp_math;  break;
      case OP_Subtract:  if( sqlite3SubInt64(&u.ag.iB,u.ag.iA) ) goto fp_math;  break;
      case OP_Multiply:  if( sqlite3MulInt64(&u.ag.iB,u.ag.iA) ) goto fp_math;  break;
      case OP_Add:       if( sqlite3AddInt64(&u.ah.iB,u.ah.iA) ) goto fp_math;  break;
      case OP_Subtract:  if( sqlite3SubInt64(&u.ah.iB,u.ah.iA) ) goto fp_math;  break;
      case OP_Multiply:  if( sqlite3MulInt64(&u.ah.iB,u.ah.iA) ) goto fp_math;  break;
      case OP_Divide: {
        if( u.ag.iA==0 ) goto arithmetic_result_is_null;
        if( u.ag.iA==-1 && u.ag.iB==SMALLEST_INT64 ) goto fp_math;
        u.ag.iB /= u.ag.iA;
        if( u.ah.iA==0 ) goto arithmetic_result_is_null;
        if( u.ah.iA==-1 && u.ah.iB==SMALLEST_INT64 ) goto fp_math;
        u.ah.iB /= u.ah.iA;
        break;
      }
      default: {
        if( u.ag.iA==0 ) goto arithmetic_result_is_null;
        if( u.ag.iA==-1 ) u.ag.iA = 1;
        u.ag.iB %= u.ag.iA;
        if( u.ah.iA==0 ) goto arithmetic_result_is_null;
        if( u.ah.iA==-1 ) u.ah.iA = 1;
        u.ah.iB %= u.ah.iA;
        break;
      }
    }
    pOut->u.i = u.ag.iB;
    pOut->u.i = u.ah.iB;
    MemSetTypeFlag(pOut, MEM_Int);
  }else{
fp_math:
    u.ag.rA = sqlite3VdbeRealValue(pIn1);
    u.ag.rB = sqlite3VdbeRealValue(pIn2);
    u.ah.rA = sqlite3VdbeRealValue(pIn1);
    u.ah.rB = sqlite3VdbeRealValue(pIn2);
    switch( pOp->opcode ){
      case OP_Add:         u.ag.rB += u.ag.rA;       break;
      case OP_Subtract:    u.ag.rB -= u.ag.rA;       break;
      case OP_Multiply:    u.ag.rB *= u.ag.rA;       break;
      case OP_Add:         u.ah.rB += u.ah.rA;       break;
      case OP_Subtract:    u.ah.rB -= u.ah.rA;       break;
      case OP_Multiply:    u.ah.rB *= u.ah.rA;       break;
      case OP_Divide: {
        /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
        if( u.ag.rA==(double)0 ) goto arithmetic_result_is_null;
        u.ag.rB /= u.ag.rA;
        if( u.ah.rA==(double)0 ) goto arithmetic_result_is_null;
        u.ah.rB /= u.ah.rA;
        break;
      }
      default: {
        u.ag.iA = (i64)u.ag.rA;
        u.ag.iB = (i64)u.ag.rB;
        if( u.ag.iA==0 ) goto arithmetic_result_is_null;
        if( u.ag.iA==-1 ) u.ag.iA = 1;
        u.ag.rB = (double)(u.ag.iB % u.ag.iA);
        u.ah.iA = (i64)u.ah.rA;
        u.ah.iB = (i64)u.ah.rB;
        if( u.ah.iA==0 ) goto arithmetic_result_is_null;
        if( u.ah.iA==-1 ) u.ah.iA = 1;
        u.ah.rB = (double)(u.ah.iB % u.ah.iA);
        break;
      }
    }
#ifdef SQLITE_OMIT_FLOATING_POINT
    pOut->u.i = u.ag.rB;
    pOut->u.i = u.ah.rB;
    MemSetTypeFlag(pOut, MEM_Int);
#else
    if( sqlite3IsNaN(u.ag.rB) ){
    if( sqlite3IsNaN(u.ah.rB) ){
      goto arithmetic_result_is_null;
    }
    pOut->r = u.ag.rB;
    pOut->r = u.ah.rB;
    MemSetTypeFlag(pOut, MEM_Real);
    if( (u.ag.flags & MEM_Real)==0 ){
    if( (u.ah.flags & MEM_Real)==0 ){
      sqlite3VdbeIntegerAffinity(pOut);
    }
#endif
  }
  break;

arithmetic_result_is_null:
64926
64927
64928
64929
64930
64931
64932
64933

64934
64935
64936
64937
64938
64939

64940
64941
64942
64943



64944
64945
64946
64947
64948
64949
64950
64951
64952
64953
64954
64955
64956









64957
64958
64959
64960
64961
64962


64963
64964
64965


64966
64967
64968
64969
64970
64971




64972
64973
64974

64975
64976
64977
64978


64979
64980
64981


64982
64983
64984
64985

64986
64987
64988

64989
64990
64991
64992
64993
64994
64995
64996



64997
64998
64999
65000
65001
65002
65003
65004
65005
65006

65007
65008
65009
65010
65011
65012
65013



65014
65015
65016
65017
65018


65019
65020
65021
65022
65023
65024
65025
65081
65082
65083
65084
65085
65086
65087

65088
65089
65090
65091
65092
65093

65094
65095



65096
65097
65098
65099
65100
65101
65102









65103
65104
65105
65106
65107
65108
65109
65110
65111
65112
65113
65114
65115


65116
65117
65118


65119
65120
65121
65122




65123
65124
65125
65126
65127
65128

65129
65130
65131


65132
65133
65134


65135
65136
65137
65138
65139

65140
65141
65142

65143
65144
65145
65146
65147
65148



65149
65150
65151
65152
65153
65154
65155
65156
65157
65158
65159
65160

65161
65162
65163
65164
65165



65166
65167
65168
65169
65170
65171


65172
65173
65174
65175
65176
65177
65178
65179
65180







-
+





-
+

-
-
-
+
+
+




-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+




-
-
+
+

-
-
+
+


-
-
-
-
+
+
+
+


-
+


-
-
+
+

-
-
+
+



-
+


-
+





-
-
-
+
+
+









-
+




-
-
-
+
+
+



-
-
+
+







** whether meta data associated with a user function argument using the
** sqlite3_set_auxdata() API may be safely retained until the next
** invocation of this opcode.
**
** See also: AggStep and AggFinal
*/
case OP_Function: {
#if 0  /* local variables moved into u.ah */
#if 0  /* local variables moved into u.ai */
  int i;
  Mem *pArg;
  sqlite3_context ctx;
  sqlite3_value **apVal;
  int n;
#endif /* local variables moved into u.ah */
#endif /* local variables moved into u.ai */

  u.ah.n = pOp->p5;
  u.ah.apVal = p->apArg;
  assert( u.ah.apVal || u.ah.n==0 );
  u.ai.n = pOp->p5;
  u.ai.apVal = p->apArg;
  assert( u.ai.apVal || u.ai.n==0 );
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  pOut = &aMem[pOp->p3];
  memAboutToChange(p, pOut);

  assert( u.ah.n==0 || (pOp->p2>0 && pOp->p2+u.ah.n<=p->nMem+1) );
  assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ah.n );
  u.ah.pArg = &aMem[pOp->p2];
  for(u.ah.i=0; u.ah.i<u.ah.n; u.ah.i++, u.ah.pArg++){
    assert( memIsValid(u.ah.pArg) );
    u.ah.apVal[u.ah.i] = u.ah.pArg;
    Deephemeralize(u.ah.pArg);
    sqlite3VdbeMemStoreType(u.ah.pArg);
    REGISTER_TRACE(pOp->p2+u.ah.i, u.ah.pArg);
  assert( u.ai.n==0 || (pOp->p2>0 && pOp->p2+u.ai.n<=p->nMem+1) );
  assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ai.n );
  u.ai.pArg = &aMem[pOp->p2];
  for(u.ai.i=0; u.ai.i<u.ai.n; u.ai.i++, u.ai.pArg++){
    assert( memIsValid(u.ai.pArg) );
    u.ai.apVal[u.ai.i] = u.ai.pArg;
    Deephemeralize(u.ai.pArg);
    sqlite3VdbeMemStoreType(u.ai.pArg);
    REGISTER_TRACE(pOp->p2+u.ai.i, u.ai.pArg);
  }

  assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC );
  if( pOp->p4type==P4_FUNCDEF ){
    u.ah.ctx.pFunc = pOp->p4.pFunc;
    u.ah.ctx.pVdbeFunc = 0;
    u.ai.ctx.pFunc = pOp->p4.pFunc;
    u.ai.ctx.pVdbeFunc = 0;
  }else{
    u.ah.ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
    u.ah.ctx.pFunc = u.ah.ctx.pVdbeFunc->pFunc;
    u.ai.ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
    u.ai.ctx.pFunc = u.ai.ctx.pVdbeFunc->pFunc;
  }

  u.ah.ctx.s.flags = MEM_Null;
  u.ah.ctx.s.db = db;
  u.ah.ctx.s.xDel = 0;
  u.ah.ctx.s.zMalloc = 0;
  u.ai.ctx.s.flags = MEM_Null;
  u.ai.ctx.s.db = db;
  u.ai.ctx.s.xDel = 0;
  u.ai.ctx.s.zMalloc = 0;

  /* The output cell may already have a buffer allocated. Move
  ** the pointer to u.ah.ctx.s so in case the user-function can use
  ** the pointer to u.ai.ctx.s so in case the user-function can use
  ** the already allocated buffer instead of allocating a new one.
  */
  sqlite3VdbeMemMove(&u.ah.ctx.s, pOut);
  MemSetTypeFlag(&u.ah.ctx.s, MEM_Null);
  sqlite3VdbeMemMove(&u.ai.ctx.s, pOut);
  MemSetTypeFlag(&u.ai.ctx.s, MEM_Null);

  u.ah.ctx.isError = 0;
  if( u.ah.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
  u.ai.ctx.isError = 0;
  if( u.ai.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
    assert( pOp>aOp );
    assert( pOp[-1].p4type==P4_COLLSEQ );
    assert( pOp[-1].opcode==OP_CollSeq );
    u.ah.ctx.pColl = pOp[-1].p4.pColl;
    u.ai.ctx.pColl = pOp[-1].p4.pColl;
  }
  db->lastRowid = lastRowid;
  (*u.ah.ctx.pFunc->xFunc)(&u.ah.ctx, u.ah.n, u.ah.apVal); /* IMP: R-24505-23230 */
  (*u.ai.ctx.pFunc->xFunc)(&u.ai.ctx, u.ai.n, u.ai.apVal); /* IMP: R-24505-23230 */
  lastRowid = db->lastRowid;

  /* If any auxiliary data functions have been called by this user function,
  ** immediately call the destructor for any non-static values.
  */
  if( u.ah.ctx.pVdbeFunc ){
    sqlite3VdbeDeleteAuxData(u.ah.ctx.pVdbeFunc, pOp->p1);
    pOp->p4.pVdbeFunc = u.ah.ctx.pVdbeFunc;
  if( u.ai.ctx.pVdbeFunc ){
    sqlite3VdbeDeleteAuxData(u.ai.ctx.pVdbeFunc, pOp->p1);
    pOp->p4.pVdbeFunc = u.ai.ctx.pVdbeFunc;
    pOp->p4type = P4_VDBEFUNC;
  }

  if( db->mallocFailed ){
    /* Even though a malloc() has failed, the implementation of the
    ** user function may have called an sqlite3_result_XXX() function
    ** to return a value. The following call releases any resources
    ** associated with such a value.
    */
    sqlite3VdbeMemRelease(&u.ah.ctx.s);
    sqlite3VdbeMemRelease(&u.ai.ctx.s);
    goto no_mem;
  }

  /* If the function returned an error, throw an exception */
  if( u.ah.ctx.isError ){
    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ah.ctx.s));
    rc = u.ah.ctx.isError;
  if( u.ai.ctx.isError ){
    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ai.ctx.s));
    rc = u.ai.ctx.isError;
  }

  /* Copy the result of the function into register P3 */
  sqlite3VdbeChangeEncoding(&u.ah.ctx.s, encoding);
  sqlite3VdbeMemMove(pOut, &u.ah.ctx.s);
  sqlite3VdbeChangeEncoding(&u.ai.ctx.s, encoding);
  sqlite3VdbeMemMove(pOut, &u.ai.ctx.s);
  if( sqlite3VdbeMemTooBig(pOut) ){
    goto too_big;
  }

#if 0
  /* The app-defined function has done something that as caused this
  ** statement to expire.  (Perhaps the function called sqlite3_exec()
65059
65060
65061
65062
65063
65064
65065
65066

65067
65068
65069
65070
65071

65072
65073
65074
65075
65076
65077
65078
65079
65080
65081
65082
65083
65084
65085
65086
65087
65088









65089
65090
65091

65092
65093
65094


65095
65096
65097
65098


65099
65100
65101
65102



65103
65104

65105
65106

65107
65108

65109
65110
65111

65112
65113
65114
65115
65116
65117
65118
65214
65215
65216
65217
65218
65219
65220

65221
65222
65223
65224
65225

65226
65227
65228
65229
65230
65231
65232
65233
65234









65235
65236
65237
65238
65239
65240
65241
65242
65243
65244
65245

65246
65247


65248
65249
65250
65251


65252
65253
65254



65255
65256
65257
65258

65259
65260

65261
65262

65263
65264
65265

65266
65267
65268
65269
65270
65271
65272
65273







-
+




-
+








-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+


-
+

-
-
+
+


-
-
+
+

-
-
-
+
+
+

-
+

-
+

-
+


-
+







** Store the result in register P3.
** If either input is NULL, the result is NULL.
*/
case OP_BitAnd:                 /* same as TK_BITAND, in1, in2, out3 */
case OP_BitOr:                  /* same as TK_BITOR, in1, in2, out3 */
case OP_ShiftLeft:              /* same as TK_LSHIFT, in1, in2, out3 */
case OP_ShiftRight: {           /* same as TK_RSHIFT, in1, in2, out3 */
#if 0  /* local variables moved into u.ai */
#if 0  /* local variables moved into u.aj */
  i64 iA;
  u64 uA;
  i64 iB;
  u8 op;
#endif /* local variables moved into u.ai */
#endif /* local variables moved into u.aj */

  pIn1 = &aMem[pOp->p1];
  pIn2 = &aMem[pOp->p2];
  pOut = &aMem[pOp->p3];
  if( (pIn1->flags | pIn2->flags) & MEM_Null ){
    sqlite3VdbeMemSetNull(pOut);
    break;
  }
  u.ai.iA = sqlite3VdbeIntValue(pIn2);
  u.ai.iB = sqlite3VdbeIntValue(pIn1);
  u.ai.op = pOp->opcode;
  if( u.ai.op==OP_BitAnd ){
    u.ai.iA &= u.ai.iB;
  }else if( u.ai.op==OP_BitOr ){
    u.ai.iA |= u.ai.iB;
  }else if( u.ai.iB!=0 ){
    assert( u.ai.op==OP_ShiftRight || u.ai.op==OP_ShiftLeft );
  u.aj.iA = sqlite3VdbeIntValue(pIn2);
  u.aj.iB = sqlite3VdbeIntValue(pIn1);
  u.aj.op = pOp->opcode;
  if( u.aj.op==OP_BitAnd ){
    u.aj.iA &= u.aj.iB;
  }else if( u.aj.op==OP_BitOr ){
    u.aj.iA |= u.aj.iB;
  }else if( u.aj.iB!=0 ){
    assert( u.aj.op==OP_ShiftRight || u.aj.op==OP_ShiftLeft );

    /* If shifting by a negative amount, shift in the other direction */
    if( u.ai.iB<0 ){
    if( u.aj.iB<0 ){
      assert( OP_ShiftRight==OP_ShiftLeft+1 );
      u.ai.op = 2*OP_ShiftLeft + 1 - u.ai.op;
      u.ai.iB = u.ai.iB>(-64) ? -u.ai.iB : 64;
      u.aj.op = 2*OP_ShiftLeft + 1 - u.aj.op;
      u.aj.iB = u.aj.iB>(-64) ? -u.aj.iB : 64;
    }

    if( u.ai.iB>=64 ){
      u.ai.iA = (u.ai.iA>=0 || u.ai.op==OP_ShiftLeft) ? 0 : -1;
    if( u.aj.iB>=64 ){
      u.aj.iA = (u.aj.iA>=0 || u.aj.op==OP_ShiftLeft) ? 0 : -1;
    }else{
      memcpy(&u.ai.uA, &u.ai.iA, sizeof(u.ai.uA));
      if( u.ai.op==OP_ShiftLeft ){
        u.ai.uA <<= u.ai.iB;
      memcpy(&u.aj.uA, &u.aj.iA, sizeof(u.aj.uA));
      if( u.aj.op==OP_ShiftLeft ){
        u.aj.uA <<= u.aj.iB;
      }else{
        u.ai.uA >>= u.ai.iB;
        u.aj.uA >>= u.aj.iB;
        /* Sign-extend on a right shift of a negative number */
        if( u.ai.iA<0 ) u.ai.uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-u.ai.iB);
        if( u.aj.iA<0 ) u.aj.uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-u.aj.iB);
      }
      memcpy(&u.ai.iA, &u.ai.uA, sizeof(u.ai.iA));
      memcpy(&u.aj.iA, &u.aj.uA, sizeof(u.aj.iA));
    }
  }
  pOut->u.i = u.ai.iA;
  pOut->u.i = u.aj.iA;
  MemSetTypeFlag(pOut, MEM_Int);
  break;
}

/* Opcode: AddImm  P1 P2 * * *
** 
** Add the constant P2 to the value in register P1.
65349
65350
65351
65352
65353
65354
65355
65356

65357
65358
65359
65360
65361

65362
65363
65364
65365
65366
65367



65368
65369
65370
65371
65372
65373
65374
65375
65376
65377
65378




65379
65380

65381
65382

65383
65384
65385
65386
65387
65388
65389
65390
65391
65392
65393
65394
65395
65396
65397
65398
65399
65400
65401
65402
65403




65404
65405
65406
65407
65408
65409
65410

65411
65412
65413
65414
65415
65416
65417
65418






65419
65420
65421
65422
65423
65424
65425

65426
65427

65428
65429
65430
65431
65432
65433


65434
65435
65436
65437
65438
65439
65440
65504
65505
65506
65507
65508
65509
65510

65511
65512
65513
65514
65515

65516
65517
65518
65519



65520
65521
65522
65523
65524
65525
65526
65527
65528
65529




65530
65531
65532
65533
65534

65535
65536

65537
65538
65539
65540
65541
65542
65543
65544
65545
65546
65547
65548
65549
65550
65551
65552
65553
65554




65555
65556
65557
65558
65559
65560
65561
65562
65563
65564

65565
65566
65567






65568
65569
65570
65571
65572
65573
65574
65575
65576
65577
65578
65579

65580
65581

65582
65583
65584
65585
65586


65587
65588
65589
65590
65591
65592
65593
65594
65595







-
+




-
+



-
-
-
+
+
+







-
-
-
-
+
+
+
+

-
+

-
+

















-
-
-
-
+
+
+
+






-
+


-
-
-
-
-
-
+
+
+
+
+
+






-
+

-
+




-
-
+
+







*/
case OP_Eq:               /* same as TK_EQ, jump, in1, in3 */
case OP_Ne:               /* same as TK_NE, jump, in1, in3 */
case OP_Lt:               /* same as TK_LT, jump, in1, in3 */
case OP_Le:               /* same as TK_LE, jump, in1, in3 */
case OP_Gt:               /* same as TK_GT, jump, in1, in3 */
case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
#if 0  /* local variables moved into u.aj */
#if 0  /* local variables moved into u.ak */
  int res;            /* Result of the comparison of pIn1 against pIn3 */
  char affinity;      /* Affinity to use for comparison */
  u16 flags1;         /* Copy of initial value of pIn1->flags */
  u16 flags3;         /* Copy of initial value of pIn3->flags */
#endif /* local variables moved into u.aj */
#endif /* local variables moved into u.ak */

  pIn1 = &aMem[pOp->p1];
  pIn3 = &aMem[pOp->p3];
  u.aj.flags1 = pIn1->flags;
  u.aj.flags3 = pIn3->flags;
  if( (u.aj.flags1 | u.aj.flags3)&MEM_Null ){
  u.ak.flags1 = pIn1->flags;
  u.ak.flags3 = pIn3->flags;
  if( (u.ak.flags1 | u.ak.flags3)&MEM_Null ){
    /* One or both operands are NULL */
    if( pOp->p5 & SQLITE_NULLEQ ){
      /* If SQLITE_NULLEQ is set (which will only happen if the operator is
      ** OP_Eq or OP_Ne) then take the jump or not depending on whether
      ** or not both operands are null.
      */
      assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
      assert( (u.aj.flags1 & MEM_Cleared)==0 );
      if( (u.aj.flags1&MEM_Null)!=0
       && (u.aj.flags3&MEM_Null)!=0
       && (u.aj.flags3&MEM_Cleared)==0
      assert( (u.ak.flags1 & MEM_Cleared)==0 );
      if( (u.ak.flags1&MEM_Null)!=0
       && (u.ak.flags3&MEM_Null)!=0
       && (u.ak.flags3&MEM_Cleared)==0
      ){
        u.aj.res = 0;  /* Results are equal */
        u.ak.res = 0;  /* Results are equal */
      }else{
        u.aj.res = 1;  /* Results are not equal */
        u.ak.res = 1;  /* Results are not equal */
      }
    }else{
      /* SQLITE_NULLEQ is clear and at least one operand is NULL,
      ** then the result is always NULL.
      ** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
      */
      if( pOp->p5 & SQLITE_STOREP2 ){
        pOut = &aMem[pOp->p2];
        MemSetTypeFlag(pOut, MEM_Null);
        REGISTER_TRACE(pOp->p2, pOut);
      }else if( pOp->p5 & SQLITE_JUMPIFNULL ){
        pc = pOp->p2-1;
      }
      break;
    }
  }else{
    /* Neither operand is NULL.  Do a comparison. */
    u.aj.affinity = pOp->p5 & SQLITE_AFF_MASK;
    if( u.aj.affinity ){
      applyAffinity(pIn1, u.aj.affinity, encoding);
      applyAffinity(pIn3, u.aj.affinity, encoding);
    u.ak.affinity = pOp->p5 & SQLITE_AFF_MASK;
    if( u.ak.affinity ){
      applyAffinity(pIn1, u.ak.affinity, encoding);
      applyAffinity(pIn3, u.ak.affinity, encoding);
      if( db->mallocFailed ) goto no_mem;
    }

    assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
    ExpandBlob(pIn1);
    ExpandBlob(pIn3);
    u.aj.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
    u.ak.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
  }
  switch( pOp->opcode ){
    case OP_Eq:    u.aj.res = u.aj.res==0;     break;
    case OP_Ne:    u.aj.res = u.aj.res!=0;     break;
    case OP_Lt:    u.aj.res = u.aj.res<0;      break;
    case OP_Le:    u.aj.res = u.aj.res<=0;     break;
    case OP_Gt:    u.aj.res = u.aj.res>0;      break;
    default:       u.aj.res = u.aj.res>=0;     break;
    case OP_Eq:    u.ak.res = u.ak.res==0;     break;
    case OP_Ne:    u.ak.res = u.ak.res!=0;     break;
    case OP_Lt:    u.ak.res = u.ak.res<0;      break;
    case OP_Le:    u.ak.res = u.ak.res<=0;     break;
    case OP_Gt:    u.ak.res = u.ak.res>0;      break;
    default:       u.ak.res = u.ak.res>=0;     break;
  }

  if( pOp->p5 & SQLITE_STOREP2 ){
    pOut = &aMem[pOp->p2];
    memAboutToChange(p, pOut);
    MemSetTypeFlag(pOut, MEM_Int);
    pOut->u.i = u.aj.res;
    pOut->u.i = u.ak.res;
    REGISTER_TRACE(pOp->p2, pOut);
  }else if( u.aj.res ){
  }else if( u.ak.res ){
    pc = pOp->p2-1;
  }

  /* Undo any changes made by applyAffinity() to the input registers. */
  pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (u.aj.flags1&MEM_TypeMask);
  pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (u.aj.flags3&MEM_TypeMask);
  pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (u.ak.flags1&MEM_TypeMask);
  pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (u.ak.flags3&MEM_TypeMask);
  break;
}

/* Opcode: Permutation * * * P4 *
**
** Set the permutation used by the OP_Compare operator to be the array
** of integers in P4.
65461
65462
65463
65464
65465
65466
65467
65468

65469
65470
65471
65472
65473
65474
65475
65476
65477

65478
65479
65480
65481
65482
65483
65484






65485
65486
65487
65488
65489
65490



65491
65492
65493


65494
65495
65496
65497
65498
65499
65500
65501
65502
65503
65504
65505










65506
65507

65508
65509
65510
65511
65512
65513
65514
65616
65617
65618
65619
65620
65621
65622

65623
65624
65625
65626
65627
65628
65629
65630
65631

65632
65633






65634
65635
65636
65637
65638
65639
65640
65641
65642



65643
65644
65645
65646


65647
65648
65649
65650










65651
65652
65653
65654
65655
65656
65657
65658
65659
65660
65661

65662
65663
65664
65665
65666
65667
65668
65669







-
+








-
+

-
-
-
-
-
-
+
+
+
+
+
+



-
-
-
+
+
+

-
-
+
+


-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+

-
+







** only.  The KeyInfo elements are used sequentially.
**
** The comparison is a sort comparison, so NULLs compare equal,
** NULLs are less than numbers, numbers are less than strings,
** and strings are less than blobs.
*/
case OP_Compare: {
#if 0  /* local variables moved into u.ak */
#if 0  /* local variables moved into u.al */
  int n;
  int i;
  int p1;
  int p2;
  const KeyInfo *pKeyInfo;
  int idx;
  CollSeq *pColl;    /* Collating sequence to use on this term */
  int bRev;          /* True for DESCENDING sort order */
#endif /* local variables moved into u.ak */
#endif /* local variables moved into u.al */

  u.ak.n = pOp->p3;
  u.ak.pKeyInfo = pOp->p4.pKeyInfo;
  assert( u.ak.n>0 );
  assert( u.ak.pKeyInfo!=0 );
  u.ak.p1 = pOp->p1;
  u.ak.p2 = pOp->p2;
  u.al.n = pOp->p3;
  u.al.pKeyInfo = pOp->p4.pKeyInfo;
  assert( u.al.n>0 );
  assert( u.al.pKeyInfo!=0 );
  u.al.p1 = pOp->p1;
  u.al.p2 = pOp->p2;
#if SQLITE_DEBUG
  if( aPermute ){
    int k, mx = 0;
    for(k=0; k<u.ak.n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
    assert( u.ak.p1>0 && u.ak.p1+mx<=p->nMem+1 );
    assert( u.ak.p2>0 && u.ak.p2+mx<=p->nMem+1 );
    for(k=0; k<u.al.n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
    assert( u.al.p1>0 && u.al.p1+mx<=p->nMem+1 );
    assert( u.al.p2>0 && u.al.p2+mx<=p->nMem+1 );
  }else{
    assert( u.ak.p1>0 && u.ak.p1+u.ak.n<=p->nMem+1 );
    assert( u.ak.p2>0 && u.ak.p2+u.ak.n<=p->nMem+1 );
    assert( u.al.p1>0 && u.al.p1+u.al.n<=p->nMem+1 );
    assert( u.al.p2>0 && u.al.p2+u.al.n<=p->nMem+1 );
  }
#endif /* SQLITE_DEBUG */
  for(u.ak.i=0; u.ak.i<u.ak.n; u.ak.i++){
    u.ak.idx = aPermute ? aPermute[u.ak.i] : u.ak.i;
    assert( memIsValid(&aMem[u.ak.p1+u.ak.idx]) );
    assert( memIsValid(&aMem[u.ak.p2+u.ak.idx]) );
    REGISTER_TRACE(u.ak.p1+u.ak.idx, &aMem[u.ak.p1+u.ak.idx]);
    REGISTER_TRACE(u.ak.p2+u.ak.idx, &aMem[u.ak.p2+u.ak.idx]);
    assert( u.ak.i<u.ak.pKeyInfo->nField );
    u.ak.pColl = u.ak.pKeyInfo->aColl[u.ak.i];
    u.ak.bRev = u.ak.pKeyInfo->aSortOrder[u.ak.i];
    iCompare = sqlite3MemCompare(&aMem[u.ak.p1+u.ak.idx], &aMem[u.ak.p2+u.ak.idx], u.ak.pColl);
  for(u.al.i=0; u.al.i<u.al.n; u.al.i++){
    u.al.idx = aPermute ? aPermute[u.al.i] : u.al.i;
    assert( memIsValid(&aMem[u.al.p1+u.al.idx]) );
    assert( memIsValid(&aMem[u.al.p2+u.al.idx]) );
    REGISTER_TRACE(u.al.p1+u.al.idx, &aMem[u.al.p1+u.al.idx]);
    REGISTER_TRACE(u.al.p2+u.al.idx, &aMem[u.al.p2+u.al.idx]);
    assert( u.al.i<u.al.pKeyInfo->nField );
    u.al.pColl = u.al.pKeyInfo->aColl[u.al.i];
    u.al.bRev = u.al.pKeyInfo->aSortOrder[u.al.i];
    iCompare = sqlite3MemCompare(&aMem[u.al.p1+u.al.idx], &aMem[u.al.p2+u.al.idx], u.al.pColl);
    if( iCompare ){
      if( u.ak.bRev ) iCompare = -iCompare;
      if( u.al.bRev ) iCompare = -iCompare;
      break;
    }
  }
  aPermute = 0;
  break;
}

65545
65546
65547
65548
65549
65550
65551
65552

65553
65554
65555

65556
65557
65558
65559

65560
65561

65562
65563
65564
65565

65566
65567

65568
65569
65570
65571

65572
65573
65574

65575
65576
65577

65578
65579
65580

65581
65582
65583
65584
65585
65586
65587
65700
65701
65702
65703
65704
65705
65706

65707
65708
65709

65710
65711
65712
65713

65714
65715

65716
65717
65718
65719

65720
65721

65722
65723
65724
65725

65726
65727
65728

65729
65730
65731

65732
65733
65734

65735
65736
65737
65738
65739
65740
65741
65742







-
+


-
+



-
+

-
+



-
+

-
+



-
+


-
+


-
+


-
+







**
** If either P1 or P2 is nonzero (true) then the result is 1 (true)
** even if the other input is NULL.  A NULL and false or two NULLs
** give a NULL output.
*/
case OP_And:              /* same as TK_AND, in1, in2, out3 */
case OP_Or: {             /* same as TK_OR, in1, in2, out3 */
#if 0  /* local variables moved into u.al */
#if 0  /* local variables moved into u.am */
  int v1;    /* Left operand:  0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
  int v2;    /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
#endif /* local variables moved into u.al */
#endif /* local variables moved into u.am */

  pIn1 = &aMem[pOp->p1];
  if( pIn1->flags & MEM_Null ){
    u.al.v1 = 2;
    u.am.v1 = 2;
  }else{
    u.al.v1 = sqlite3VdbeIntValue(pIn1)!=0;
    u.am.v1 = sqlite3VdbeIntValue(pIn1)!=0;
  }
  pIn2 = &aMem[pOp->p2];
  if( pIn2->flags & MEM_Null ){
    u.al.v2 = 2;
    u.am.v2 = 2;
  }else{
    u.al.v2 = sqlite3VdbeIntValue(pIn2)!=0;
    u.am.v2 = sqlite3VdbeIntValue(pIn2)!=0;
  }
  if( pOp->opcode==OP_And ){
    static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
    u.al.v1 = and_logic[u.al.v1*3+u.al.v2];
    u.am.v1 = and_logic[u.am.v1*3+u.am.v2];
  }else{
    static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
    u.al.v1 = or_logic[u.al.v1*3+u.al.v2];
    u.am.v1 = or_logic[u.am.v1*3+u.am.v2];
  }
  pOut = &aMem[pOp->p3];
  if( u.al.v1==2 ){
  if( u.am.v1==2 ){
    MemSetTypeFlag(pOut, MEM_Null);
  }else{
    pOut->u.i = u.al.v1;
    pOut->u.i = u.am.v1;
    MemSetTypeFlag(pOut, MEM_Int);
  }
  break;
}

/* Opcode: Not P1 P2 * * *
**
65644
65645
65646
65647
65648
65649
65650
65651

65652
65653

65654
65655
65656

65657
65658
65659

65660
65661

65662
65663

65664
65665

65666
65667
65668
65669
65670
65671
65672
65799
65800
65801
65802
65803
65804
65805

65806
65807

65808
65809
65810

65811
65812
65813

65814
65815

65816
65817

65818
65819

65820
65821
65822
65823
65824
65825
65826
65827







-
+

-
+


-
+


-
+

-
+

-
+

-
+







**
** Jump to P2 if the value in register P1 is False.  The value
** is considered false if it has a numeric value of zero.  If the value
** in P1 is NULL then take the jump if P3 is zero.
*/
case OP_If:                 /* jump, in1 */
case OP_IfNot: {            /* jump, in1 */
#if 0  /* local variables moved into u.am */
#if 0  /* local variables moved into u.an */
  int c;
#endif /* local variables moved into u.am */
#endif /* local variables moved into u.an */
  pIn1 = &aMem[pOp->p1];
  if( pIn1->flags & MEM_Null ){
    u.am.c = pOp->p3;
    u.an.c = pOp->p3;
  }else{
#ifdef SQLITE_OMIT_FLOATING_POINT
    u.am.c = sqlite3VdbeIntValue(pIn1)!=0;
    u.an.c = sqlite3VdbeIntValue(pIn1)!=0;
#else
    u.am.c = sqlite3VdbeRealValue(pIn1)!=0.0;
    u.an.c = sqlite3VdbeRealValue(pIn1)!=0.0;
#endif
    if( pOp->opcode==OP_IfNot ) u.am.c = !u.am.c;
    if( pOp->opcode==OP_IfNot ) u.an.c = !u.an.c;
  }
  if( u.am.c ){
  if( u.an.c ){
    pc = pOp->p2-1;
  }
  break;
}

/* Opcode: IsNull P1 P2 * * *
**
65713
65714
65715
65716
65717
65718
65719
65720

65721
65722
65723
65724
65725
65726
65727
65868
65869
65870
65871
65872
65873
65874

65875
65876
65877
65878
65879
65880
65881
65882







-
+







**
** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 when
** the result is guaranteed to only be used as the argument of a length()
** or typeof() function, respectively.  The loading of large blobs can be
** skipped for length() and all content loading can be skipped for typeof().
*/
case OP_Column: {
#if 0  /* local variables moved into u.an */
#if 0  /* local variables moved into u.ao */
  u32 payloadSize;   /* Number of bytes in the record */
  i64 payloadSize64; /* Number of bytes in the record */
  int p1;            /* P1 value of the opcode */
  int p2;            /* column number to retrieve */
  VdbeCursor *pC;    /* The VDBE cursor */
  char *zRec;        /* Pointer to complete record-data */
  BtCursor *pCrsr;   /* The BTree cursor */
65737
65738
65739
65740
65741
65742
65743
65744

65745
65746
65747
65748
65749
65750
65751





65752
65753
65754
65755



65756
65757

65758
65759
65760

65761
65762
65763
65764


65765
65766
65767
65768
65769
65770


65771
65772

65773
65774
65775


65776
65777

65778
65779
65780
65781
65782
65783
65784
65785
65786








65787
65788
65789

65790
65791
65792


65793
65794
65795


65796
65797
65798
65799
65800
65801
65802
65803
65804
65805








65806
65807
65808

65809
65810
65811

65812
65813
65814


65815
65816
65817
65818

65819
65820
65821
65822
65823


65824
65825
65826
65827
65828
65829
65830



65831
65832
65833
65834
65835
65836





65837
65838
65839
65840


65841
65842
65843


65844
65845

65846
65847
65848

65849
65850
65851
65852
65853
65854
65855




65856
65857

65858
65859
65860
65861
65862
65863


65864
65865
65866
65867
65868
65869
65870
65871
65872
65873
65874

65875
65876
65877
65878
65879
65880
65881
65882
65883
65884






65885
65886
65887
65888


65889
65890
65891
65892
65893


65894
65895
65896
65897
65898
65899
65900
65901
65902
65903
65904




65905
65906
65907
65908

65909
65910
65911


65912
65913
65914
65915
65916




65917
65918
65919
65920
65921
65922
65923






65924
65925

65926
65927
65928
65929
65930
65931





65932
65933
65934
65935

65936
65937

65938
65939
65940
65941

65942
65943
65944
65945


65946
65947
65948
65949
65950
65951
65952
65953
65954


65955
65956
65957
65958
65959
65960
65961


65962
65963
65964
65965
65966

65967
65968

65969
65970
65971


65972
65973
65974

65975
65976

65977
65978
65979
65980
65981

65982
65983

65984
65985
65986
65987
65988




65989
65990
65991
65992

65993
65994

65995
65996

65997
65998
65999

66000
66001

66002
66003
66004
66005
66006
66007

66008
66009
66010
66011
66012
66013
66014
66015
66016
66017








66018
66019
66020

66021
66022
66023
66024


66025
66026
66027
66028
66029
66030
66031
66032
66033
66034
66035
66036
66037

66038
66039
66040

66041
66042
66043
66044



66045
66046

66047
66048
66049
66050

66051
66052
66053
66054
66055
66056
66057
65892
65893
65894
65895
65896
65897
65898

65899
65900
65901





65902
65903
65904
65905
65906
65907



65908
65909
65910
65911

65912
65913
65914

65915
65916
65917


65918
65919
65920
65921
65922
65923


65924
65925
65926

65927
65928


65929
65930
65931

65932
65933








65934
65935
65936
65937
65938
65939
65940
65941
65942
65943

65944
65945


65946
65947
65948


65949
65950
65951
65952








65953
65954
65955
65956
65957
65958
65959
65960
65961
65962

65963
65964
65965

65966
65967


65968
65969
65970
65971
65972

65973
65974
65975
65976


65977
65978
65979
65980
65981
65982



65983
65984
65985
65986





65987
65988
65989
65990
65991
65992
65993


65994
65995
65996


65997
65998
65999

66000
66001
66002

66003
66004
66005
66006




66007
66008
66009
66010
66011

66012
66013
66014
66015
66016


66017
66018
66019
66020
66021
66022
66023
66024
66025
66026
66027
66028

66029
66030
66031
66032
66033






66034
66035
66036
66037
66038
66039
66040
66041


66042
66043
66044
66045
66046


66047
66048
66049
66050
66051
66052
66053
66054
66055




66056
66057
66058
66059
66060
66061
66062

66063
66064


66065
66066
66067




66068
66069
66070
66071
66072






66073
66074
66075
66076
66077
66078
66079

66080
66081





66082
66083
66084
66085
66086
66087
66088
66089

66090
66091

66092
66093
66094
66095

66096
66097
66098


66099
66100
66101
66102
66103
66104
66105
66106
66107


66108
66109
66110
66111
66112
66113
66114


66115
66116
66117
66118
66119
66120

66121
66122

66123
66124


66125
66126
66127
66128

66129
66130

66131
66132
66133
66134
66135

66136
66137

66138
66139




66140
66141
66142
66143
66144
66145
66146

66147
66148

66149
66150

66151
66152
66153

66154
66155

66156
66157
66158
66159
66160
66161

66162
66163
66164








66165
66166
66167
66168
66169
66170
66171
66172
66173
66174

66175
66176
66177


66178
66179
66180
66181
66182
66183
66184
66185
66186
66187
66188
66189
66190
66191

66192
66193
66194

66195
66196



66197
66198
66199
66200

66201
66202
66203
66204

66205
66206
66207
66208
66209
66210
66211
66212







-
+


-
-
-
-
-
+
+
+
+
+

-
-
-
+
+
+

-
+


-
+


-
-
+
+




-
-
+
+

-
+

-
-
+
+

-
+

-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+


-
+

-
-
+
+

-
-
+
+


-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+


-
+


-
+

-
-
+
+



-
+



-
-
+
+




-
-
-
+
+
+

-
-
-
-
-
+
+
+
+
+


-
-
+
+

-
-
+
+

-
+


-
+



-
-
-
-
+
+
+
+

-
+




-
-
+
+










-
+




-
-
-
-
-
-
+
+
+
+
+
+


-
-
+
+



-
-
+
+







-
-
-
-
+
+
+
+



-
+

-
-
+
+

-
-
-
-
+
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+

-
+

-
-
-
-
-
+
+
+
+
+



-
+

-
+



-
+


-
-
+
+







-
-
+
+





-
-
+
+




-
+

-
+

-
-
+
+


-
+

-
+




-
+

-
+

-
-
-
-
+
+
+
+



-
+

-
+

-
+


-
+

-
+





-
+


-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+


-
+


-
-
+
+












-
+


-
+

-
-
-
+
+
+

-
+



-
+







  u8 *zEndHdr;       /* Pointer to first byte after the header */
  u32 offset;        /* Offset into the data */
  u32 szField;       /* Number of bytes in the content of a field */
  int szHdr;         /* Size of the header size field at start of record */
  int avail;         /* Number of bytes of available data */
  u32 t;             /* A type code from the record header */
  Mem *pReg;         /* PseudoTable input register */
#endif /* local variables moved into u.an */
#endif /* local variables moved into u.ao */


  u.an.p1 = pOp->p1;
  u.an.p2 = pOp->p2;
  u.an.pC = 0;
  memset(&u.an.sMem, 0, sizeof(u.an.sMem));
  assert( u.an.p1<p->nCursor );
  u.ao.p1 = pOp->p1;
  u.ao.p2 = pOp->p2;
  u.ao.pC = 0;
  memset(&u.ao.sMem, 0, sizeof(u.ao.sMem));
  assert( u.ao.p1<p->nCursor );
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  u.an.pDest = &aMem[pOp->p3];
  memAboutToChange(p, u.an.pDest);
  u.an.zRec = 0;
  u.ao.pDest = &aMem[pOp->p3];
  memAboutToChange(p, u.ao.pDest);
  u.ao.zRec = 0;

  /* This block sets the variable u.an.payloadSize to be the total number of
  /* This block sets the variable u.ao.payloadSize to be the total number of
  ** bytes in the record.
  **
  ** u.an.zRec is set to be the complete text of the record if it is available.
  ** u.ao.zRec is set to be the complete text of the record if it is available.
  ** The complete record text is always available for pseudo-tables
  ** If the record is stored in a cursor, the complete record text
  ** might be available in the  u.an.pC->aRow cache.  Or it might not be.
  ** If the data is unavailable,  u.an.zRec is set to NULL.
  ** might be available in the  u.ao.pC->aRow cache.  Or it might not be.
  ** If the data is unavailable,  u.ao.zRec is set to NULL.
  **
  ** We also compute the number of columns in the record.  For cursors,
  ** the number of columns is stored in the VdbeCursor.nField element.
  */
  u.an.pC = p->apCsr[u.an.p1];
  assert( u.an.pC!=0 );
  u.ao.pC = p->apCsr[u.ao.p1];
  assert( u.ao.pC!=0 );
#ifndef SQLITE_OMIT_VIRTUALTABLE
  assert( u.an.pC->pVtabCursor==0 );
  assert( u.ao.pC->pVtabCursor==0 );
#endif
  u.an.pCrsr = u.an.pC->pCursor;
  if( u.an.pCrsr!=0 ){
  u.ao.pCrsr = u.ao.pC->pCursor;
  if( u.ao.pCrsr!=0 ){
    /* The record is stored in a B-Tree */
    rc = sqlite3VdbeCursorMoveto(u.an.pC);
    rc = sqlite3VdbeCursorMoveto(u.ao.pC);
    if( rc ) goto abort_due_to_error;
    if( u.an.pC->nullRow ){
      u.an.payloadSize = 0;
    }else if( u.an.pC->cacheStatus==p->cacheCtr ){
      u.an.payloadSize = u.an.pC->payloadSize;
      u.an.zRec = (char*)u.an.pC->aRow;
    }else if( u.an.pC->isIndex ){
      assert( sqlite3BtreeCursorIsValid(u.an.pCrsr) );
      VVA_ONLY(rc =) sqlite3BtreeKeySize(u.an.pCrsr, &u.an.payloadSize64);
    if( u.ao.pC->nullRow ){
      u.ao.payloadSize = 0;
    }else if( u.ao.pC->cacheStatus==p->cacheCtr ){
      u.ao.payloadSize = u.ao.pC->payloadSize;
      u.ao.zRec = (char*)u.ao.pC->aRow;
    }else if( u.ao.pC->isIndex ){
      assert( sqlite3BtreeCursorIsValid(u.ao.pCrsr) );
      VVA_ONLY(rc =) sqlite3BtreeKeySize(u.ao.pCrsr, &u.ao.payloadSize64);
      assert( rc==SQLITE_OK );   /* True because of CursorMoveto() call above */
      /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
      ** payload size, so it is impossible for u.an.payloadSize64 to be
      ** payload size, so it is impossible for u.ao.payloadSize64 to be
      ** larger than 32 bits. */
      assert( (u.an.payloadSize64 & SQLITE_MAX_U32)==(u64)u.an.payloadSize64 );
      u.an.payloadSize = (u32)u.an.payloadSize64;
      assert( (u.ao.payloadSize64 & SQLITE_MAX_U32)==(u64)u.ao.payloadSize64 );
      u.ao.payloadSize = (u32)u.ao.payloadSize64;
    }else{
      assert( sqlite3BtreeCursorIsValid(u.an.pCrsr) );
      VVA_ONLY(rc =) sqlite3BtreeDataSize(u.an.pCrsr, &u.an.payloadSize);
      assert( sqlite3BtreeCursorIsValid(u.ao.pCrsr) );
      VVA_ONLY(rc =) sqlite3BtreeDataSize(u.ao.pCrsr, &u.ao.payloadSize);
      assert( rc==SQLITE_OK );   /* DataSize() cannot fail */
    }
  }else if( ALWAYS(u.an.pC->pseudoTableReg>0) ){
    u.an.pReg = &aMem[u.an.pC->pseudoTableReg];
    assert( u.an.pReg->flags & MEM_Blob );
    assert( memIsValid(u.an.pReg) );
    u.an.payloadSize = u.an.pReg->n;
    u.an.zRec = u.an.pReg->z;
    u.an.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr;
    assert( u.an.payloadSize==0 || u.an.zRec!=0 );
  }else if( ALWAYS(u.ao.pC->pseudoTableReg>0) ){
    u.ao.pReg = &aMem[u.ao.pC->pseudoTableReg];
    assert( u.ao.pReg->flags & MEM_Blob );
    assert( memIsValid(u.ao.pReg) );
    u.ao.payloadSize = u.ao.pReg->n;
    u.ao.zRec = u.ao.pReg->z;
    u.ao.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr;
    assert( u.ao.payloadSize==0 || u.ao.zRec!=0 );
  }else{
    /* Consider the row to be NULL */
    u.an.payloadSize = 0;
    u.ao.payloadSize = 0;
  }

  /* If u.an.payloadSize is 0, then just store a NULL.  This can happen because of
  /* If u.ao.payloadSize is 0, then just store a NULL.  This can happen because of
  ** nullRow or because of a corrupt database. */
  if( u.an.payloadSize==0 ){
    MemSetTypeFlag(u.an.pDest, MEM_Null);
  if( u.ao.payloadSize==0 ){
    MemSetTypeFlag(u.ao.pDest, MEM_Null);
    goto op_column_out;
  }
  assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 );
  if( u.an.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
  if( u.ao.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
    goto too_big;
  }

  u.an.nField = u.an.pC->nField;
  assert( u.an.p2<u.an.nField );
  u.ao.nField = u.ao.pC->nField;
  assert( u.ao.p2<u.ao.nField );

  /* Read and parse the table header.  Store the results of the parse
  ** into the record header cache fields of the cursor.
  */
  u.an.aType = u.an.pC->aType;
  if( u.an.pC->cacheStatus==p->cacheCtr ){
    u.an.aOffset = u.an.pC->aOffset;
  u.ao.aType = u.ao.pC->aType;
  if( u.ao.pC->cacheStatus==p->cacheCtr ){
    u.ao.aOffset = u.ao.pC->aOffset;
  }else{
    assert(u.an.aType);
    u.an.avail = 0;
    u.an.pC->aOffset = u.an.aOffset = &u.an.aType[u.an.nField];
    u.an.pC->payloadSize = u.an.payloadSize;
    u.an.pC->cacheStatus = p->cacheCtr;
    assert(u.ao.aType);
    u.ao.avail = 0;
    u.ao.pC->aOffset = u.ao.aOffset = &u.ao.aType[u.ao.nField];
    u.ao.pC->payloadSize = u.ao.payloadSize;
    u.ao.pC->cacheStatus = p->cacheCtr;

    /* Figure out how many bytes are in the header */
    if( u.an.zRec ){
      u.an.zData = u.an.zRec;
    if( u.ao.zRec ){
      u.ao.zData = u.ao.zRec;
    }else{
      if( u.an.pC->isIndex ){
        u.an.zData = (char*)sqlite3BtreeKeyFetch(u.an.pCrsr, &u.an.avail);
      if( u.ao.pC->isIndex ){
        u.ao.zData = (char*)sqlite3BtreeKeyFetch(u.ao.pCrsr, &u.ao.avail);
      }else{
        u.an.zData = (char*)sqlite3BtreeDataFetch(u.an.pCrsr, &u.an.avail);
        u.ao.zData = (char*)sqlite3BtreeDataFetch(u.ao.pCrsr, &u.ao.avail);
      }
      /* If KeyFetch()/DataFetch() managed to get the entire payload,
      ** save the payload in the u.an.pC->aRow cache.  That will save us from
      ** save the payload in the u.ao.pC->aRow cache.  That will save us from
      ** having to make additional calls to fetch the content portion of
      ** the record.
      */
      assert( u.an.avail>=0 );
      if( u.an.payloadSize <= (u32)u.an.avail ){
        u.an.zRec = u.an.zData;
        u.an.pC->aRow = (u8*)u.an.zData;
      assert( u.ao.avail>=0 );
      if( u.ao.payloadSize <= (u32)u.ao.avail ){
        u.ao.zRec = u.ao.zData;
        u.ao.pC->aRow = (u8*)u.ao.zData;
      }else{
        u.an.pC->aRow = 0;
        u.ao.pC->aRow = 0;
      }
    }
    /* The following assert is true in all cases except when
    ** the database file has been corrupted externally.
    **    assert( u.an.zRec!=0 || u.an.avail>=u.an.payloadSize || u.an.avail>=9 ); */
    u.an.szHdr = getVarint32((u8*)u.an.zData, u.an.offset);
    **    assert( u.ao.zRec!=0 || u.ao.avail>=u.ao.payloadSize || u.ao.avail>=9 ); */
    u.ao.szHdr = getVarint32((u8*)u.ao.zData, u.ao.offset);

    /* Make sure a corrupt database has not given us an oversize header.
    ** Do this now to avoid an oversize memory allocation.
    **
    ** Type entries can be between 1 and 5 bytes each.  But 4 and 5 byte
    ** types use so much data space that there can only be 4096 and 32 of
    ** them, respectively.  So the maximum header length results from a
    ** 3-byte type for each of the maximum of 32768 columns plus three
    ** extra bytes for the header length itself.  32768*3 + 3 = 98307.
    */
    if( u.an.offset > 98307 ){
    if( u.ao.offset > 98307 ){
      rc = SQLITE_CORRUPT_BKPT;
      goto op_column_out;
    }

    /* Compute in u.an.len the number of bytes of data we need to read in order
    ** to get u.an.nField type values.  u.an.offset is an upper bound on this.  But
    ** u.an.nField might be significantly less than the true number of columns
    ** in the table, and in that case, 5*u.an.nField+3 might be smaller than u.an.offset.
    ** We want to minimize u.an.len in order to limit the size of the memory
    ** allocation, especially if a corrupt database file has caused u.an.offset
    /* Compute in u.ao.len the number of bytes of data we need to read in order
    ** to get u.ao.nField type values.  u.ao.offset is an upper bound on this.  But
    ** u.ao.nField might be significantly less than the true number of columns
    ** in the table, and in that case, 5*u.ao.nField+3 might be smaller than u.ao.offset.
    ** We want to minimize u.ao.len in order to limit the size of the memory
    ** allocation, especially if a corrupt database file has caused u.ao.offset
    ** to be oversized. Offset is limited to 98307 above.  But 98307 might
    ** still exceed Robson memory allocation limits on some configurations.
    ** On systems that cannot tolerate large memory allocations, u.an.nField*5+3
    ** will likely be much smaller since u.an.nField will likely be less than
    ** On systems that cannot tolerate large memory allocations, u.ao.nField*5+3
    ** will likely be much smaller since u.ao.nField will likely be less than
    ** 20 or so.  This insures that Robson memory allocation limits are
    ** not exceeded even for corrupt database files.
    */
    u.an.len = u.an.nField*5 + 3;
    if( u.an.len > (int)u.an.offset ) u.an.len = (int)u.an.offset;
    u.ao.len = u.ao.nField*5 + 3;
    if( u.ao.len > (int)u.ao.offset ) u.ao.len = (int)u.ao.offset;

    /* The KeyFetch() or DataFetch() above are fast and will get the entire
    ** record header in most cases.  But they will fail to get the complete
    ** record header if the record header does not fit on a single page
    ** in the B-Tree.  When that happens, use sqlite3VdbeMemFromBtree() to
    ** acquire the complete header text.
    */
    if( !u.an.zRec && u.an.avail<u.an.len ){
      u.an.sMem.flags = 0;
      u.an.sMem.db = 0;
      rc = sqlite3VdbeMemFromBtree(u.an.pCrsr, 0, u.an.len, u.an.pC->isIndex, &u.an.sMem);
    if( !u.ao.zRec && u.ao.avail<u.ao.len ){
      u.ao.sMem.flags = 0;
      u.ao.sMem.db = 0;
      rc = sqlite3VdbeMemFromBtree(u.ao.pCrsr, 0, u.ao.len, u.ao.pC->isIndex, &u.ao.sMem);
      if( rc!=SQLITE_OK ){
        goto op_column_out;
      }
      u.an.zData = u.an.sMem.z;
      u.ao.zData = u.ao.sMem.z;
    }
    u.an.zEndHdr = (u8 *)&u.an.zData[u.an.len];
    u.an.zIdx = (u8 *)&u.an.zData[u.an.szHdr];
    u.ao.zEndHdr = (u8 *)&u.ao.zData[u.ao.len];
    u.ao.zIdx = (u8 *)&u.ao.zData[u.ao.szHdr];

    /* Scan the header and use it to fill in the u.an.aType[] and u.an.aOffset[]
    ** arrays.  u.an.aType[u.an.i] will contain the type integer for the u.an.i-th
    ** column and u.an.aOffset[u.an.i] will contain the u.an.offset from the beginning
    ** of the record to the start of the data for the u.an.i-th column
    /* Scan the header and use it to fill in the u.ao.aType[] and u.ao.aOffset[]
    ** arrays.  u.ao.aType[u.ao.i] will contain the type integer for the u.ao.i-th
    ** column and u.ao.aOffset[u.ao.i] will contain the u.ao.offset from the beginning
    ** of the record to the start of the data for the u.ao.i-th column
    */
    for(u.an.i=0; u.an.i<u.an.nField; u.an.i++){
      if( u.an.zIdx<u.an.zEndHdr ){
        u.an.aOffset[u.an.i] = u.an.offset;
        if( u.an.zIdx[0]<0x80 ){
          u.an.t = u.an.zIdx[0];
          u.an.zIdx++;
    for(u.ao.i=0; u.ao.i<u.ao.nField; u.ao.i++){
      if( u.ao.zIdx<u.ao.zEndHdr ){
        u.ao.aOffset[u.ao.i] = u.ao.offset;
        if( u.ao.zIdx[0]<0x80 ){
          u.ao.t = u.ao.zIdx[0];
          u.ao.zIdx++;
        }else{
          u.an.zIdx += sqlite3GetVarint32(u.an.zIdx, &u.an.t);
          u.ao.zIdx += sqlite3GetVarint32(u.ao.zIdx, &u.ao.t);
        }
        u.an.aType[u.an.i] = u.an.t;
        u.an.szField = sqlite3VdbeSerialTypeLen(u.an.t);
        u.an.offset += u.an.szField;
        if( u.an.offset<u.an.szField ){  /* True if u.an.offset overflows */
          u.an.zIdx = &u.an.zEndHdr[1];  /* Forces SQLITE_CORRUPT return below */
        u.ao.aType[u.ao.i] = u.ao.t;
        u.ao.szField = sqlite3VdbeSerialTypeLen(u.ao.t);
        u.ao.offset += u.ao.szField;
        if( u.ao.offset<u.ao.szField ){  /* True if u.ao.offset overflows */
          u.ao.zIdx = &u.ao.zEndHdr[1];  /* Forces SQLITE_CORRUPT return below */
          break;
        }
      }else{
        /* If u.an.i is less that u.an.nField, then there are fewer fields in this
        /* If u.ao.i is less that u.ao.nField, then there are fewer fields in this
        ** record than SetNumColumns indicated there are columns in the
        ** table. Set the u.an.offset for any extra columns not present in
        ** table. Set the u.ao.offset for any extra columns not present in
        ** the record to 0. This tells code below to store the default value
        ** for the column instead of deserializing a value from the record.
        */
        u.an.aOffset[u.an.i] = 0;
        u.ao.aOffset[u.ao.i] = 0;
      }
    }
    sqlite3VdbeMemRelease(&u.an.sMem);
    u.an.sMem.flags = MEM_Null;
    sqlite3VdbeMemRelease(&u.ao.sMem);
    u.ao.sMem.flags = MEM_Null;

    /* If we have read more header data than was contained in the header,
    ** or if the end of the last field appears to be past the end of the
    ** record, or if the end of the last field appears to be before the end
    ** of the record (when all fields present), then we must be dealing
    ** with a corrupt database.
    */
    if( (u.an.zIdx > u.an.zEndHdr) || (u.an.offset > u.an.payloadSize)
         || (u.an.zIdx==u.an.zEndHdr && u.an.offset!=u.an.payloadSize) ){
    if( (u.ao.zIdx > u.ao.zEndHdr) || (u.ao.offset > u.ao.payloadSize)
         || (u.ao.zIdx==u.ao.zEndHdr && u.ao.offset!=u.ao.payloadSize) ){
      rc = SQLITE_CORRUPT_BKPT;
      goto op_column_out;
    }
  }

  /* Get the column information. If u.an.aOffset[u.an.p2] is non-zero, then
  ** deserialize the value from the record. If u.an.aOffset[u.an.p2] is zero,
  /* Get the column information. If u.ao.aOffset[u.ao.p2] is non-zero, then
  ** deserialize the value from the record. If u.ao.aOffset[u.ao.p2] is zero,
  ** then there are not enough fields in the record to satisfy the
  ** request.  In this case, set the value NULL or to P4 if P4 is
  ** a pointer to a Mem object.
  */
  if( u.an.aOffset[u.an.p2] ){
  if( u.ao.aOffset[u.ao.p2] ){
    assert( rc==SQLITE_OK );
    if( u.an.zRec ){
    if( u.ao.zRec ){
      /* This is the common case where the whole row fits on a single page */
      VdbeMemRelease(u.an.pDest);
      sqlite3VdbeSerialGet((u8 *)&u.an.zRec[u.an.aOffset[u.an.p2]], u.an.aType[u.an.p2], u.an.pDest);
      VdbeMemRelease(u.ao.pDest);
      sqlite3VdbeSerialGet((u8 *)&u.ao.zRec[u.ao.aOffset[u.ao.p2]], u.ao.aType[u.ao.p2], u.ao.pDest);
    }else{
      /* This branch happens only when the row overflows onto multiple pages */
      u.an.t = u.an.aType[u.an.p2];
      u.ao.t = u.ao.aType[u.ao.p2];
      if( (pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
       && ((u.an.t>=12 && (u.an.t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)
       && ((u.ao.t>=12 && (u.ao.t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)
      ){
        /* Content is irrelevant for the typeof() function and for
        ** the length(X) function if X is a blob.  So we might as well use
        ** bogus content rather than reading content from disk.  NULL works
        ** for text and blob and whatever is in the u.an.payloadSize64 variable
        ** for text and blob and whatever is in the u.ao.payloadSize64 variable
        ** will work for everything else. */
        u.an.zData = u.an.t<12 ? (char*)&u.an.payloadSize64 : 0;
        u.ao.zData = u.ao.t<12 ? (char*)&u.ao.payloadSize64 : 0;
      }else{
        u.an.len = sqlite3VdbeSerialTypeLen(u.an.t);
        sqlite3VdbeMemMove(&u.an.sMem, u.an.pDest);
        rc = sqlite3VdbeMemFromBtree(u.an.pCrsr, u.an.aOffset[u.an.p2], u.an.len,  u.an.pC->isIndex,
                                     &u.an.sMem);
        u.ao.len = sqlite3VdbeSerialTypeLen(u.ao.t);
        sqlite3VdbeMemMove(&u.ao.sMem, u.ao.pDest);
        rc = sqlite3VdbeMemFromBtree(u.ao.pCrsr, u.ao.aOffset[u.ao.p2], u.ao.len,  u.ao.pC->isIndex,
                                     &u.ao.sMem);
        if( rc!=SQLITE_OK ){
          goto op_column_out;
        }
        u.an.zData = u.an.sMem.z;
        u.ao.zData = u.ao.sMem.z;
      }
      sqlite3VdbeSerialGet((u8*)u.an.zData, u.an.t, u.an.pDest);
      sqlite3VdbeSerialGet((u8*)u.ao.zData, u.ao.t, u.ao.pDest);
    }
    u.an.pDest->enc = encoding;
    u.ao.pDest->enc = encoding;
  }else{
    if( pOp->p4type==P4_MEM ){
      sqlite3VdbeMemShallowCopy(u.an.pDest, pOp->p4.pMem, MEM_Static);
      sqlite3VdbeMemShallowCopy(u.ao.pDest, pOp->p4.pMem, MEM_Static);
    }else{
      MemSetTypeFlag(u.an.pDest, MEM_Null);
      MemSetTypeFlag(u.ao.pDest, MEM_Null);
    }
  }

  /* If we dynamically allocated space to hold the data (in the
  ** sqlite3VdbeMemFromBtree() call above) then transfer control of that
  ** dynamically allocated space over to the u.an.pDest structure.
  ** dynamically allocated space over to the u.ao.pDest structure.
  ** This prevents a memory copy.
  */
  if( u.an.sMem.zMalloc ){
    assert( u.an.sMem.z==u.an.sMem.zMalloc );
    assert( !(u.an.pDest->flags & MEM_Dyn) );
    assert( !(u.an.pDest->flags & (MEM_Blob|MEM_Str)) || u.an.pDest->z==u.an.sMem.z );
    u.an.pDest->flags &= ~(MEM_Ephem|MEM_Static);
    u.an.pDest->flags |= MEM_Term;
    u.an.pDest->z = u.an.sMem.z;
    u.an.pDest->zMalloc = u.an.sMem.zMalloc;
  if( u.ao.sMem.zMalloc ){
    assert( u.ao.sMem.z==u.ao.sMem.zMalloc );
    assert( !(u.ao.pDest->flags & MEM_Dyn) );
    assert( !(u.ao.pDest->flags & (MEM_Blob|MEM_Str)) || u.ao.pDest->z==u.ao.sMem.z );
    u.ao.pDest->flags &= ~(MEM_Ephem|MEM_Static);
    u.ao.pDest->flags |= MEM_Term;
    u.ao.pDest->z = u.ao.sMem.z;
    u.ao.pDest->zMalloc = u.ao.sMem.zMalloc;
  }

  rc = sqlite3VdbeMemMakeWriteable(u.an.pDest);
  rc = sqlite3VdbeMemMakeWriteable(u.ao.pDest);

op_column_out:
  UPDATE_MAX_BLOBSIZE(u.an.pDest);
  REGISTER_TRACE(pOp->p3, u.an.pDest);
  UPDATE_MAX_BLOBSIZE(u.ao.pDest);
  REGISTER_TRACE(pOp->p3, u.ao.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
** memory cell in the range.
*/
case OP_Affinity: {
#if 0  /* local variables moved into u.ao */
#if 0  /* local variables moved into u.ap */
  const char *zAffinity;   /* The affinity to be applied */
  char cAff;               /* A single character of affinity */
#endif /* local variables moved into u.ao */
#endif /* local variables moved into u.ap */

  u.ao.zAffinity = pOp->p4.z;
  assert( u.ao.zAffinity!=0 );
  assert( u.ao.zAffinity[pOp->p2]==0 );
  u.ap.zAffinity = pOp->p4.z;
  assert( u.ap.zAffinity!=0 );
  assert( u.ap.zAffinity[pOp->p2]==0 );
  pIn1 = &aMem[pOp->p1];
  while( (u.ao.cAff = *(u.ao.zAffinity++))!=0 ){
  while( (u.ap.cAff = *(u.ap.zAffinity++))!=0 ){
    assert( pIn1 <= &p->aMem[p->nMem] );
    assert( memIsValid(pIn1) );
    ExpandBlob(pIn1);
    applyAffinity(pIn1, u.ao.cAff, encoding);
    applyAffinity(pIn1, u.ap.cAff, encoding);
    pIn1++;
  }
  break;
}

/* Opcode: MakeRecord P1 P2 P3 P4 *
**
66065
66066
66067
66068
66069
66070
66071
66072

66073
66074
66075
66076
66077
66078
66079
66080
66081
66082
66083
66084
66085
66086
66087
66088

66089
66090
66091
66092
66093
66094
66095
66096
66097
66098
66099
66100
66101
66102
66103
66104
66105
66106
66107
66108
66109
66110
66111
66112
66113
66114










66115
66116
66117
66118
66119
66120
66121
66122
66123
66124
66125
66126
66127




66128
66129
66130


66131
66132
66133
66134
66135
66136





66137
66138
66139
66140
66141



66142
66143
66144
66145
66146
66147
66148



66149
66150
66151


66152
66153
66154
66155
66156
66157
66158
66159
66160

66161
66162
66163

66164
66165
66166
66167
66168
66169




66170
66171
66172


66173
66174

66175
66176
66177

66178
66179
66180
66181


66182
66183
66184
66185
66186
66187
66188
66189
66190
66191
66192
66193
66194
66195
66196
66197

66198
66199
66200

66201
66202
66203
66204



66205
66206

66207
66208

66209
66210
66211
66212
66213
66214
66215
66216
66217
66218
66219
66220

66221
66222
66223
66224
66225
66226
66227
66228
66229

66230
66231
66232


66233
66234

66235
66236
66237
66238

66239
66240
66241
66242

66243
66244
66245
66246
66247
66248
66249
66250
66251

66252
66253
66254
66255
66256
66257
66258
66259
66260
66261
66262
66263
66264
66265
66266
66267
66268




66269
66270
66271
66272
66273
66274
66275
66276
66277
66278
66279
66280
66281
66282



66283
66284
66285
66286

66287
66288
66289
66290
66291
66292
66293



66294
66295

66296
66297
66298


66299
66300

66301
66302
66303
66304
66305
66306
66307
66308
66309
66310
66311
66312
66313
66314
66315


66316
66317
66318
66319
66320
66321
66322
66323
66324
66325
66326
66327
66328
66329
66330
66331
66332




66333
66334
66335
66336


66337
66338
66339
66340
66341

66342
66343
66344
66345
66346
66347
66348
66349
66350
66351
66352
66353




66354
66355
66356
66357
66358
66359
66360
66361
66362
66363
66364




66365
66366
66367
66368
66369

66370
66371
66372
66373

66374
66375
66376
66377
66378
66379
66380
66381
66382
66383
66384
66385
66386
66387
66388
66389
66390
66391
66392

66393
66394
66395
66396

66397
66398
66399
66400
66401
66402





66403
66404
66405
66406

66407
66408
66409
66410
66411
66412
66413
66414
66415
66416

66417
66418
66419
66420
66421
66422
66423
66424
66425



66426
66427
66428
66429
66430
66431

66432
66433
66434

66435
66436
66437
66438
66439
66440
66441
66442
66443
66444
66445
66446
66447
66448
66449
66450


66451
66452
66453
66454
66455
66456
66457
66220
66221
66222
66223
66224
66225
66226

66227
66228
66229
66230
66231
66232
66233
66234
66235
66236
66237
66238
66239
66240
66241
66242

66243
66244
66245
66246
66247
66248
66249
66250
66251
66252
66253
66254
66255
66256
66257
66258
66259










66260
66261
66262
66263
66264
66265
66266
66267
66268
66269
66270
66271
66272
66273
66274
66275
66276
66277
66278




66279
66280
66281
66282
66283


66284
66285
66286





66287
66288
66289
66290
66291
66292
66293



66294
66295
66296
66297
66298
66299
66300



66301
66302
66303
66304


66305
66306
66307
66308
66309
66310
66311
66312
66313
66314

66315
66316
66317

66318
66319
66320




66321
66322
66323
66324
66325


66326
66327
66328

66329
66330
66331

66332
66333
66334


66335
66336
66337
66338
66339
66340
66341
66342
66343
66344
66345
66346
66347
66348
66349
66350
66351

66352
66353
66354

66355
66356



66357
66358
66359
66360

66361
66362

66363
66364
66365
66366
66367
66368
66369
66370
66371
66372
66373
66374

66375
66376
66377
66378
66379
66380
66381
66382
66383

66384
66385


66386
66387
66388

66389
66390
66391
66392

66393
66394
66395
66396

66397
66398
66399
66400
66401
66402
66403
66404
66405

66406
66407
66408
66409
66410
66411
66412
66413
66414
66415
66416
66417
66418
66419




66420
66421
66422
66423
66424
66425
66426
66427
66428
66429
66430
66431
66432
66433
66434



66435
66436
66437
66438
66439
66440

66441
66442
66443
66444
66445



66446
66447
66448
66449

66450
66451


66452
66453
66454

66455
66456
66457
66458
66459
66460
66461
66462
66463
66464
66465
66466
66467
66468


66469
66470
66471
66472
66473
66474
66475
66476
66477
66478
66479
66480
66481
66482
66483




66484
66485
66486
66487
66488
66489


66490
66491
66492
66493
66494
66495

66496
66497
66498
66499
66500
66501
66502
66503
66504




66505
66506
66507
66508
66509
66510
66511
66512
66513
66514
66515




66516
66517
66518
66519
66520
66521
66522
66523

66524
66525
66526
66527

66528
66529
66530
66531
66532
66533
66534
66535
66536
66537
66538
66539
66540
66541
66542
66543
66544
66545
66546

66547
66548
66549
66550

66551
66552





66553
66554
66555
66556
66557
66558
66559
66560

66561
66562
66563
66564
66565
66566
66567
66568
66569
66570

66571
66572
66573
66574
66575
66576
66577



66578
66579
66580
66581
66582
66583
66584
66585

66586
66587
66588

66589
66590
66591
66592
66593
66594
66595
66596
66597
66598
66599
66600
66601
66602
66603


66604
66605
66606
66607
66608
66609
66610
66611
66612







-
+















-
+
















-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+









-
-
-
-
+
+
+
+

-
-
+
+

-
-
-
-
-
+
+
+
+
+


-
-
-
+
+
+




-
-
-
+
+
+

-
-
+
+








-
+


-
+


-
-
-
-
+
+
+
+

-
-
+
+

-
+


-
+


-
-
+
+















-
+


-
+

-
-
-
+
+
+

-
+

-
+











-
+








-
+

-
-
+
+

-
+



-
+



-
+








-
+













-
-
-
-
+
+
+
+











-
-
-
+
+
+



-
+




-
-
-
+
+
+

-
+

-
-
+
+

-
+













-
-
+
+













-
-
-
-
+
+
+
+


-
-
+
+




-
+








-
-
-
-
+
+
+
+







-
-
-
-
+
+
+
+




-
+



-
+


















-
+



-
+

-
-
-
-
-
+
+
+
+
+



-
+









-
+






-
-
-
+
+
+





-
+


-
+














-
-
+
+







**
** The mapping from character to affinity is given by the SQLITE_AFF_
** macros defined in sqliteInt.h.
**
** If P4 is NULL then all index fields have the affinity NONE.
*/
case OP_MakeRecord: {
#if 0  /* local variables moved into u.ap */
#if 0  /* local variables moved into u.aq */
  u8 *zNewRecord;        /* A buffer to hold the data for the new record */
  Mem *pRec;             /* The new record */
  u64 nData;             /* Number of bytes of data space */
  int nHdr;              /* Number of bytes of header space */
  i64 nByte;             /* Data space required for this record */
  int nZero;             /* Number of zero bytes at the end of the record */
  int nVarint;           /* Number of bytes in a varint */
  u32 serial_type;       /* Type field */
  Mem *pData0;           /* First field to be combined into the record */
  Mem *pLast;            /* Last field of the record */
  int nField;            /* Number of fields in the record */
  char *zAffinity;       /* The affinity string for the record */
  int file_format;       /* File format to use for encoding */
  int i;                 /* Space used in zNewRecord[] */
  int len;               /* Length of a field */
#endif /* local variables moved into u.ap */
#endif /* local variables moved into u.aq */

  /* Assuming the record contains N fields, the record format looks
  ** like this:
  **
  ** ------------------------------------------------------------------------
  ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 |
  ** ------------------------------------------------------------------------
  **
  ** Data(0) is taken from register P1.  Data(1) comes from register P1+1
  ** and so froth.
  **
  ** Each type field is a varint representing the serial type of the
  ** corresponding data element (see sqlite3VdbeSerialType()). The
  ** hdr-size field is also a varint which is the offset from the beginning
  ** of the record to data0.
  */
  u.ap.nData = 0;         /* Number of bytes of data space */
  u.ap.nHdr = 0;          /* Number of bytes of header space */
  u.ap.nZero = 0;         /* Number of zero bytes at the end of the record */
  u.ap.nField = pOp->p1;
  u.ap.zAffinity = pOp->p4.z;
  assert( u.ap.nField>0 && pOp->p2>0 && pOp->p2+u.ap.nField<=p->nMem+1 );
  u.ap.pData0 = &aMem[u.ap.nField];
  u.ap.nField = pOp->p2;
  u.ap.pLast = &u.ap.pData0[u.ap.nField-1];
  u.ap.file_format = p->minWriteFileFormat;
  u.aq.nData = 0;         /* Number of bytes of data space */
  u.aq.nHdr = 0;          /* Number of bytes of header space */
  u.aq.nZero = 0;         /* Number of zero bytes at the end of the record */
  u.aq.nField = pOp->p1;
  u.aq.zAffinity = pOp->p4.z;
  assert( u.aq.nField>0 && pOp->p2>0 && pOp->p2+u.aq.nField<=p->nMem+1 );
  u.aq.pData0 = &aMem[u.aq.nField];
  u.aq.nField = pOp->p2;
  u.aq.pLast = &u.aq.pData0[u.aq.nField-1];
  u.aq.file_format = p->minWriteFileFormat;

  /* Identify the output register */
  assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
  pOut = &aMem[pOp->p3];
  memAboutToChange(p, pOut);

  /* Loop through the elements that will make up the record to figure
  ** out how much space is required for the new record.
  */
  for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){
    assert( memIsValid(u.ap.pRec) );
    if( u.ap.zAffinity ){
      applyAffinity(u.ap.pRec, u.ap.zAffinity[u.ap.pRec-u.ap.pData0], encoding);
  for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){
    assert( memIsValid(u.aq.pRec) );
    if( u.aq.zAffinity ){
      applyAffinity(u.aq.pRec, u.aq.zAffinity[u.aq.pRec-u.aq.pData0], encoding);
    }
    if( u.ap.pRec->flags&MEM_Zero && u.ap.pRec->n>0 ){
      sqlite3VdbeMemExpandBlob(u.ap.pRec);
    if( u.aq.pRec->flags&MEM_Zero && u.aq.pRec->n>0 ){
      sqlite3VdbeMemExpandBlob(u.aq.pRec);
    }
    u.ap.serial_type = sqlite3VdbeSerialType(u.ap.pRec, u.ap.file_format);
    u.ap.len = sqlite3VdbeSerialTypeLen(u.ap.serial_type);
    u.ap.nData += u.ap.len;
    u.ap.nHdr += sqlite3VarintLen(u.ap.serial_type);
    if( u.ap.pRec->flags & MEM_Zero ){
    u.aq.serial_type = sqlite3VdbeSerialType(u.aq.pRec, u.aq.file_format);
    u.aq.len = sqlite3VdbeSerialTypeLen(u.aq.serial_type);
    u.aq.nData += u.aq.len;
    u.aq.nHdr += sqlite3VarintLen(u.aq.serial_type);
    if( u.aq.pRec->flags & MEM_Zero ){
      /* Only pure zero-filled BLOBs can be input to this Opcode.
      ** We do not allow blobs with a prefix and a zero-filled tail. */
      u.ap.nZero += u.ap.pRec->u.nZero;
    }else if( u.ap.len ){
      u.ap.nZero = 0;
      u.aq.nZero += u.aq.pRec->u.nZero;
    }else if( u.aq.len ){
      u.aq.nZero = 0;
    }
  }

  /* Add the initial header varint and total the size */
  u.ap.nHdr += u.ap.nVarint = sqlite3VarintLen(u.ap.nHdr);
  if( u.ap.nVarint<sqlite3VarintLen(u.ap.nHdr) ){
    u.ap.nHdr++;
  u.aq.nHdr += u.aq.nVarint = sqlite3VarintLen(u.aq.nHdr);
  if( u.aq.nVarint<sqlite3VarintLen(u.aq.nHdr) ){
    u.aq.nHdr++;
  }
  u.ap.nByte = u.ap.nHdr+u.ap.nData-u.ap.nZero;
  if( u.ap.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
  u.aq.nByte = u.aq.nHdr+u.aq.nData-u.aq.nZero;
  if( u.aq.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
    goto too_big;
  }

  /* Make sure the output register has a buffer large enough to store
  ** the new record. The output register (pOp->p3) is not allowed to
  ** be one of the input registers (because the following call to
  ** sqlite3VdbeMemGrow() could clobber the value before it is used).
  */
  if( sqlite3VdbeMemGrow(pOut, (int)u.ap.nByte, 0) ){
  if( sqlite3VdbeMemGrow(pOut, (int)u.aq.nByte, 0) ){
    goto no_mem;
  }
  u.ap.zNewRecord = (u8 *)pOut->z;
  u.aq.zNewRecord = (u8 *)pOut->z;

  /* Write the record */
  u.ap.i = putVarint32(u.ap.zNewRecord, u.ap.nHdr);
  for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){
    u.ap.serial_type = sqlite3VdbeSerialType(u.ap.pRec, u.ap.file_format);
    u.ap.i += putVarint32(&u.ap.zNewRecord[u.ap.i], u.ap.serial_type);      /* serial type */
  u.aq.i = putVarint32(u.aq.zNewRecord, u.aq.nHdr);
  for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){
    u.aq.serial_type = sqlite3VdbeSerialType(u.aq.pRec, u.aq.file_format);
    u.aq.i += putVarint32(&u.aq.zNewRecord[u.aq.i], u.aq.serial_type);      /* serial type */
  }
  for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){  /* serial data */
    u.ap.i += sqlite3VdbeSerialPut(&u.ap.zNewRecord[u.ap.i], (int)(u.ap.nByte-u.ap.i), u.ap.pRec,u.ap.file_format);
  for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){  /* serial data */
    u.aq.i += sqlite3VdbeSerialPut(&u.aq.zNewRecord[u.aq.i], (int)(u.aq.nByte-u.aq.i), u.aq.pRec,u.aq.file_format);
  }
  assert( u.ap.i==u.ap.nByte );
  assert( u.aq.i==u.aq.nByte );

  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  pOut->n = (int)u.ap.nByte;
  pOut->n = (int)u.aq.nByte;
  pOut->flags = MEM_Blob | MEM_Dyn;
  pOut->xDel = 0;
  if( u.ap.nZero ){
    pOut->u.nZero = u.ap.nZero;
  if( u.aq.nZero ){
    pOut->u.nZero = u.aq.nZero;
    pOut->flags |= MEM_Zero;
  }
  pOut->enc = SQLITE_UTF8;  /* In case the blob is ever converted to text */
  REGISTER_TRACE(pOp->p3, pOut);
  UPDATE_MAX_BLOBSIZE(pOut);
  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
*/
#ifndef SQLITE_OMIT_BTREECOUNT
case OP_Count: {         /* out2-prerelease */
#if 0  /* local variables moved into u.aq */
#if 0  /* local variables moved into u.ar */
  i64 nEntry;
  BtCursor *pCrsr;
#endif /* local variables moved into u.aq */
#endif /* local variables moved into u.ar */

  u.aq.pCrsr = p->apCsr[pOp->p1]->pCursor;
  if( ALWAYS(u.aq.pCrsr) ){
    rc = sqlite3BtreeCount(u.aq.pCrsr, &u.aq.nEntry);
  u.ar.pCrsr = p->apCsr[pOp->p1]->pCursor;
  if( ALWAYS(u.ar.pCrsr) ){
    rc = sqlite3BtreeCount(u.ar.pCrsr, &u.ar.nEntry);
  }else{
    u.aq.nEntry = 0;
    u.ar.nEntry = 0;
  }
  pOut->u.i = u.aq.nEntry;
  pOut->u.i = u.ar.nEntry;
  break;
}
#endif

/* Opcode: Savepoint P1 * * P4 *
**
** Open, release or rollback the savepoint named by parameter P4, depending
** on the value of P1. To open a new savepoint, P1==0. To release (commit) an
** existing savepoint, P1==1, or to rollback an existing savepoint P1==2.
*/
case OP_Savepoint: {
#if 0  /* local variables moved into u.ar */
#if 0  /* local variables moved into u.as */
  int p1;                         /* Value of P1 operand */
  char *zName;                    /* Name of savepoint */
  int nName;
  Savepoint *pNew;
  Savepoint *pSavepoint;
  Savepoint *pTmp;
  int iSavepoint;
  int ii;
#endif /* local variables moved into u.ar */
#endif /* local variables moved into u.as */

  u.ar.p1 = pOp->p1;
  u.ar.zName = pOp->p4.z;
  u.as.p1 = pOp->p1;
  u.as.zName = pOp->p4.z;

  /* Assert that the u.ar.p1 parameter is valid. Also that if there is no open
  /* Assert that the u.as.p1 parameter is valid. Also that if there is no open
  ** transaction, then there cannot be any savepoints.
  */
  assert( db->pSavepoint==0 || db->autoCommit==0 );
  assert( u.ar.p1==SAVEPOINT_BEGIN||u.ar.p1==SAVEPOINT_RELEASE||u.ar.p1==SAVEPOINT_ROLLBACK );
  assert( u.as.p1==SAVEPOINT_BEGIN||u.as.p1==SAVEPOINT_RELEASE||u.as.p1==SAVEPOINT_ROLLBACK );
  assert( db->pSavepoint || db->isTransactionSavepoint==0 );
  assert( checkSavepointCount(db) );

  if( u.ar.p1==SAVEPOINT_BEGIN ){
  if( u.as.p1==SAVEPOINT_BEGIN ){
    if( db->writeVdbeCnt>0 ){
      /* A new savepoint cannot be created if there are active write
      ** statements (i.e. open read/write incremental blob handles).
      */
      sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - "
        "SQL statements in progress");
      rc = SQLITE_BUSY;
    }else{
      u.ar.nName = sqlite3Strlen30(u.ar.zName);
      u.as.nName = sqlite3Strlen30(u.as.zName);

#ifndef SQLITE_OMIT_VIRTUALTABLE
      /* This call is Ok even if this savepoint is actually a transaction
      ** savepoint (and therefore should not prompt xSavepoint()) callbacks.
      ** If this is a transaction savepoint being opened, it is guaranteed
      ** that the db->aVTrans[] array is empty.  */
      assert( db->autoCommit==0 || db->nVTrans==0 );
      rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN,
                                db->nStatement+db->nSavepoint);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;
#endif

      /* Create a new savepoint structure. */
      u.ar.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.ar.nName+1);
      if( u.ar.pNew ){
        u.ar.pNew->zName = (char *)&u.ar.pNew[1];
        memcpy(u.ar.pNew->zName, u.ar.zName, u.ar.nName+1);
      u.as.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.as.nName+1);
      if( u.as.pNew ){
        u.as.pNew->zName = (char *)&u.as.pNew[1];
        memcpy(u.as.pNew->zName, u.as.zName, u.as.nName+1);

        /* If there is no open transaction, then mark this as a special
        ** "transaction savepoint". */
        if( db->autoCommit ){
          db->autoCommit = 0;
          db->isTransactionSavepoint = 1;
        }else{
          db->nSavepoint++;
        }

        /* Link the new savepoint into the database handle's list. */
        u.ar.pNew->pNext = db->pSavepoint;
        db->pSavepoint = u.ar.pNew;
        u.ar.pNew->nDeferredCons = db->nDeferredCons;
        u.as.pNew->pNext = db->pSavepoint;
        db->pSavepoint = u.as.pNew;
        u.as.pNew->nDeferredCons = db->nDeferredCons;
      }
    }
  }else{
    u.ar.iSavepoint = 0;
    u.as.iSavepoint = 0;

    /* Find the named savepoint. If there is no such savepoint, then an
    ** an error is returned to the user.  */
    for(
      u.ar.pSavepoint = db->pSavepoint;
      u.ar.pSavepoint && sqlite3StrICmp(u.ar.pSavepoint->zName, u.ar.zName);
      u.ar.pSavepoint = u.ar.pSavepoint->pNext
      u.as.pSavepoint = db->pSavepoint;
      u.as.pSavepoint && sqlite3StrICmp(u.as.pSavepoint->zName, u.as.zName);
      u.as.pSavepoint = u.as.pSavepoint->pNext
    ){
      u.ar.iSavepoint++;
      u.as.iSavepoint++;
    }
    if( !u.ar.pSavepoint ){
      sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.ar.zName);
    if( !u.as.pSavepoint ){
      sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.as.zName);
      rc = SQLITE_ERROR;
    }else if( db->writeVdbeCnt>0 && u.ar.p1==SAVEPOINT_RELEASE ){
    }else if( db->writeVdbeCnt>0 && u.as.p1==SAVEPOINT_RELEASE ){
      /* It is not possible to release (commit) a savepoint if there are
      ** active write statements.
      */
      sqlite3SetString(&p->zErrMsg, db,
        "cannot release savepoint - SQL statements in progress"
      );
      rc = SQLITE_BUSY;
    }else{

      /* Determine whether or not this is a transaction savepoint. If so,
      ** and this is a RELEASE command, then the current transaction
      ** is committed.
      */
      int isTransaction = u.ar.pSavepoint->pNext==0 && db->isTransactionSavepoint;
      if( isTransaction && u.ar.p1==SAVEPOINT_RELEASE ){
      int isTransaction = u.as.pSavepoint->pNext==0 && db->isTransactionSavepoint;
      if( isTransaction && u.as.p1==SAVEPOINT_RELEASE ){
        if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
          goto vdbe_return;
        }
        db->autoCommit = 1;
        if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
          p->pc = pc;
          db->autoCommit = 0;
          p->rc = rc = SQLITE_BUSY;
          goto vdbe_return;
        }
        db->isTransactionSavepoint = 0;
        rc = p->rc;
      }else{
        u.ar.iSavepoint = db->nSavepoint - u.ar.iSavepoint - 1;
        if( u.ar.p1==SAVEPOINT_ROLLBACK ){
          for(u.ar.ii=0; u.ar.ii<db->nDb; u.ar.ii++){
            sqlite3BtreeTripAllCursors(db->aDb[u.ar.ii].pBt, SQLITE_ABORT);
        u.as.iSavepoint = db->nSavepoint - u.as.iSavepoint - 1;
        if( u.as.p1==SAVEPOINT_ROLLBACK ){
          for(u.as.ii=0; u.as.ii<db->nDb; u.as.ii++){
            sqlite3BtreeTripAllCursors(db->aDb[u.as.ii].pBt, SQLITE_ABORT);
          }
        }
        for(u.ar.ii=0; u.ar.ii<db->nDb; u.ar.ii++){
          rc = sqlite3BtreeSavepoint(db->aDb[u.ar.ii].pBt, u.ar.p1, u.ar.iSavepoint);
        for(u.as.ii=0; u.as.ii<db->nDb; u.as.ii++){
          rc = sqlite3BtreeSavepoint(db->aDb[u.as.ii].pBt, u.as.p1, u.as.iSavepoint);
          if( rc!=SQLITE_OK ){
            goto abort_due_to_error;
          }
        }
        if( u.ar.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
        if( u.as.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
          sqlite3ExpirePreparedStatements(db);
          sqlite3ResetAllSchemasOfConnection(db);
          db->flags = (db->flags | SQLITE_InternChanges);
        }
      }

      /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all
      ** savepoints nested inside of the savepoint being operated on. */
      while( db->pSavepoint!=u.ar.pSavepoint ){
        u.ar.pTmp = db->pSavepoint;
        db->pSavepoint = u.ar.pTmp->pNext;
        sqlite3DbFree(db, u.ar.pTmp);
      while( db->pSavepoint!=u.as.pSavepoint ){
        u.as.pTmp = db->pSavepoint;
        db->pSavepoint = u.as.pTmp->pNext;
        sqlite3DbFree(db, u.as.pTmp);
        db->nSavepoint--;
      }

      /* If it is a RELEASE, then destroy the savepoint being operated on
      ** too. If it is a ROLLBACK TO, then set the number of deferred
      ** constraint violations present in the database to the value stored
      ** when the savepoint was created.  */
      if( u.ar.p1==SAVEPOINT_RELEASE ){
        assert( u.ar.pSavepoint==db->pSavepoint );
        db->pSavepoint = u.ar.pSavepoint->pNext;
        sqlite3DbFree(db, u.ar.pSavepoint);
      if( u.as.p1==SAVEPOINT_RELEASE ){
        assert( u.as.pSavepoint==db->pSavepoint );
        db->pSavepoint = u.as.pSavepoint->pNext;
        sqlite3DbFree(db, u.as.pSavepoint);
        if( !isTransaction ){
          db->nSavepoint--;
        }
      }else{
        db->nDeferredCons = u.ar.pSavepoint->nDeferredCons;
        db->nDeferredCons = u.as.pSavepoint->nDeferredCons;
      }

      if( !isTransaction ){
        rc = sqlite3VtabSavepoint(db, u.ar.p1, u.ar.iSavepoint);
        rc = sqlite3VtabSavepoint(db, u.as.p1, u.as.iSavepoint);
        if( rc!=SQLITE_OK ) goto abort_due_to_error;
      }
    }
  }

  break;
}

/* Opcode: AutoCommit P1 P2 * * *
**
** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll
** back any currently active btree transactions. If there are any active
** VMs (apart from this one), then a ROLLBACK fails.  A COMMIT fails if
** there are active writing VMs or active VMs that use shared cache.
**
** This instruction causes the VM to halt.
*/
case OP_AutoCommit: {
#if 0  /* local variables moved into u.as */
#if 0  /* local variables moved into u.at */
  int desiredAutoCommit;
  int iRollback;
  int turnOnAC;
#endif /* local variables moved into u.as */
#endif /* local variables moved into u.at */

  u.as.desiredAutoCommit = pOp->p1;
  u.as.iRollback = pOp->p2;
  u.as.turnOnAC = u.as.desiredAutoCommit && !db->autoCommit;
  assert( u.as.desiredAutoCommit==1 || u.as.desiredAutoCommit==0 );
  assert( u.as.desiredAutoCommit==1 || u.as.iRollback==0 );
  u.at.desiredAutoCommit = pOp->p1;
  u.at.iRollback = pOp->p2;
  u.at.turnOnAC = u.at.desiredAutoCommit && !db->autoCommit;
  assert( u.at.desiredAutoCommit==1 || u.at.desiredAutoCommit==0 );
  assert( u.at.desiredAutoCommit==1 || u.at.iRollback==0 );
  assert( db->activeVdbeCnt>0 );  /* At least this one VM is active */

#if 0
  if( u.as.turnOnAC && u.as.iRollback && db->activeVdbeCnt>1 ){
  if( u.at.turnOnAC && u.at.iRollback && db->activeVdbeCnt>1 ){
    /* If this instruction implements a ROLLBACK and other VMs are
    ** still running, and a transaction is active, return an error indicating
    ** that the other VMs must complete first.
    */
    sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - "
        "SQL statements in progress");
    rc = SQLITE_BUSY;
  }else
#endif
  if( u.as.turnOnAC && !u.as.iRollback && db->writeVdbeCnt>0 ){
  if( u.at.turnOnAC && !u.at.iRollback && db->writeVdbeCnt>0 ){
    /* If this instruction implements a COMMIT and other VMs are writing
    ** return an error indicating that the other VMs must complete first.
    */
    sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - "
        "SQL statements in progress");
    rc = SQLITE_BUSY;
  }else if( u.as.desiredAutoCommit!=db->autoCommit ){
    if( u.as.iRollback ){
      assert( u.as.desiredAutoCommit==1 );
  }else if( u.at.desiredAutoCommit!=db->autoCommit ){
    if( u.at.iRollback ){
      assert( u.at.desiredAutoCommit==1 );
      sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
      db->autoCommit = 1;
    }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
      goto vdbe_return;
    }else{
      db->autoCommit = (u8)u.as.desiredAutoCommit;
      db->autoCommit = (u8)u.at.desiredAutoCommit;
      if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
        p->pc = pc;
        db->autoCommit = (u8)(1-u.as.desiredAutoCommit);
        db->autoCommit = (u8)(1-u.at.desiredAutoCommit);
        p->rc = rc = SQLITE_BUSY;
        goto vdbe_return;
      }
    }
    assert( db->nStatement==0 );
    sqlite3CloseSavepoints(db);
    if( p->rc==SQLITE_OK ){
      rc = SQLITE_DONE;
    }else{
      rc = SQLITE_ERROR;
    }
    goto vdbe_return;
  }else{
    sqlite3SetString(&p->zErrMsg, db,
        (!u.as.desiredAutoCommit)?"cannot start a transaction within a transaction":(
        (u.as.iRollback)?"cannot rollback - no transaction is active":
        (!u.at.desiredAutoCommit)?"cannot start a transaction within a transaction":(
        (u.at.iRollback)?"cannot rollback - no transaction is active":
                   "cannot commit - no transaction is active"));

    rc = SQLITE_ERROR;
  }
  break;
}

66483
66484
66485
66486
66487
66488
66489
66490

66491
66492

66493
66494
66495
66496

66497
66498
66499


66500
66501
66502
66503
66504
66505
66506
66507
66508
66509
66510
66511
66512

66513
66514
66515
66516
66517
66518
66519
66520
66521

66522
66523
66524
66525
66526
66527
66528
66638
66639
66640
66641
66642
66643
66644

66645
66646

66647
66648
66649
66650

66651
66652


66653
66654
66655
66656
66657
66658
66659
66660
66661
66662
66663
66664
66665
66666

66667
66668
66669
66670
66671
66672
66673
66674
66675

66676
66677
66678
66679
66680
66681
66682
66683







-
+

-
+



-
+

-
-
+
+












-
+








-
+







** VDBE to be rolled back after an error without having to roll back the
** entire transaction. If no error is encountered, the statement transaction
** will automatically commit when the VDBE halts.
**
** If P2 is zero, then a read-lock is obtained on the database file.
*/
case OP_Transaction: {
#if 0  /* local variables moved into u.at */
#if 0  /* local variables moved into u.au */
  Btree *pBt;
#endif /* local variables moved into u.at */
#endif /* local variables moved into u.au */

  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
  u.at.pBt = db->aDb[pOp->p1].pBt;
  u.au.pBt = db->aDb[pOp->p1].pBt;

  if( u.at.pBt ){
    rc = sqlite3BtreeBeginTrans(u.at.pBt, pOp->p2);
  if( u.au.pBt ){
    rc = sqlite3BtreeBeginTrans(u.au.pBt, pOp->p2);
    if( rc==SQLITE_BUSY ){
      p->pc = pc;
      p->rc = rc = SQLITE_BUSY;
      goto vdbe_return;
    }
    if( rc!=SQLITE_OK ){
      goto abort_due_to_error;
    }

    if( pOp->p2 && p->usesStmtJournal
     && (db->autoCommit==0 || db->activeVdbeCnt>1)
    ){
      assert( sqlite3BtreeIsInTrans(u.at.pBt) );
      assert( sqlite3BtreeIsInTrans(u.au.pBt) );
      if( p->iStatement==0 ){
        assert( db->nStatement>=0 && db->nSavepoint>=0 );
        db->nStatement++;
        p->iStatement = db->nSavepoint + db->nStatement;
      }

      rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1);
      if( rc==SQLITE_OK ){
        rc = sqlite3BtreeBeginStmt(u.at.pBt, p->iStatement);
        rc = sqlite3BtreeBeginStmt(u.au.pBt, p->iStatement);
      }

      /* Store the current value of the database handles deferred constraint
      ** counter. If the statement transaction needs to be rolled back,
      ** the value of this counter needs to be restored too.  */
      p->nStmtDefCons = db->nDeferredCons;
    }
66539
66540
66541
66542
66543
66544
66545
66546

66547
66548
66549
66550

66551
66552
66553


66554
66555
66556
66557



66558
66559
66560


66561
66562
66563
66564
66565
66566
66567
66568
66569
66570
66571
66572
66573
66574
66575

66576
66577

66578
66579
66580
66581
66582


66583
66584
66585
66586
66587

66588
66589
66590

66591
66592
66593
66594

66595
66596
66597
66598
66599
66600
66601
66694
66695
66696
66697
66698
66699
66700

66701
66702
66703
66704

66705
66706


66707
66708
66709



66710
66711
66712
66713


66714
66715
66716
66717
66718
66719
66720
66721
66722
66723
66724
66725
66726
66727
66728
66729

66730
66731

66732
66733
66734
66735


66736
66737
66738
66739
66740
66741

66742
66743
66744

66745
66746
66747
66748

66749
66750
66751
66752
66753
66754
66755
66756







-
+



-
+

-
-
+
+

-
-
-
+
+
+

-
-
+
+














-
+

-
+



-
-
+
+




-
+


-
+



-
+







** temporary tables.
**
** There must be a read-lock on the database (either a transaction
** must be started or there must be an open cursor) before
** executing this instruction.
*/
case OP_ReadCookie: {               /* out2-prerelease */
#if 0  /* local variables moved into u.au */
#if 0  /* local variables moved into u.av */
  int iMeta;
  int iDb;
  int iCookie;
#endif /* local variables moved into u.au */
#endif /* local variables moved into u.av */

  u.au.iDb = pOp->p1;
  u.au.iCookie = pOp->p3;
  u.av.iDb = pOp->p1;
  u.av.iCookie = pOp->p3;
  assert( pOp->p3<SQLITE_N_BTREE_META );
  assert( u.au.iDb>=0 && u.au.iDb<db->nDb );
  assert( db->aDb[u.au.iDb].pBt!=0 );
  assert( (p->btreeMask & (((yDbMask)1)<<u.au.iDb))!=0 );
  assert( u.av.iDb>=0 && u.av.iDb<db->nDb );
  assert( db->aDb[u.av.iDb].pBt!=0 );
  assert( (p->btreeMask & (((yDbMask)1)<<u.av.iDb))!=0 );

  sqlite3BtreeGetMeta(db->aDb[u.au.iDb].pBt, u.au.iCookie, (u32 *)&u.au.iMeta);
  pOut->u.i = u.au.iMeta;
  sqlite3BtreeGetMeta(db->aDb[u.av.iDb].pBt, u.av.iCookie, (u32 *)&u.av.iMeta);
  pOut->u.i = u.av.iMeta;
  break;
}

/* Opcode: SetCookie P1 P2 P3 * *
**
** Write the content of register P3 (interpreted as an integer)
** into cookie number P2 of database P1.  P2==1 is the schema version.  
** P2==2 is the database format. P2==3 is the recommended pager cache 
** size, and so forth.  P1==0 is the main database file and P1==1 is the 
** database file used to store temporary tables.
**
** A transaction must be started before executing this opcode.
*/
case OP_SetCookie: {       /* in3 */
#if 0  /* local variables moved into u.av */
#if 0  /* local variables moved into u.aw */
  Db *pDb;
#endif /* local variables moved into u.av */
#endif /* local variables moved into u.aw */
  assert( pOp->p2<SQLITE_N_BTREE_META );
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
  u.av.pDb = &db->aDb[pOp->p1];
  assert( u.av.pDb->pBt!=0 );
  u.aw.pDb = &db->aDb[pOp->p1];
  assert( u.aw.pDb->pBt!=0 );
  assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
  pIn3 = &aMem[pOp->p3];
  sqlite3VdbeMemIntegerify(pIn3);
  /* See note about index shifting on OP_ReadCookie */
  rc = sqlite3BtreeUpdateMeta(u.av.pDb->pBt, pOp->p2, (int)pIn3->u.i);
  rc = sqlite3BtreeUpdateMeta(u.aw.pDb->pBt, pOp->p2, (int)pIn3->u.i);
  if( pOp->p2==BTREE_SCHEMA_VERSION ){
    /* When the schema cookie changes, record the new cookie internally */
    u.av.pDb->pSchema->schema_cookie = (int)pIn3->u.i;
    u.aw.pDb->pSchema->schema_cookie = (int)pIn3->u.i;
    db->flags |= SQLITE_InternChanges;
  }else if( pOp->p2==BTREE_FILE_FORMAT ){
    /* Record changes in the file format */
    u.av.pDb->pSchema->file_format = (u8)pIn3->u.i;
    u.aw.pDb->pSchema->file_format = (u8)pIn3->u.i;
  }
  if( pOp->p1==1 ){
    /* Invalidate all prepared statements whenever the TEMP database
    ** schema is changed.  Ticket #1644 */
    sqlite3ExpirePreparedStatements(db);
    p->expired = 0;
  }
66617
66618
66619
66620
66621
66622
66623
66624

66625
66626
66627
66628

66629
66630
66631
66632
66633
66634
66635
66636




66637
66638

66639
66640

66641
66642
66643
66644
66645
66646
66647
66648
66649
66650
66651
66652
66653
66654
66655
66656

66657
66658
66659
66660
66661
66662
66663
66772
66773
66774
66775
66776
66777
66778

66779
66780
66781
66782

66783
66784
66785
66786
66787




66788
66789
66790
66791
66792

66793
66794

66795
66796
66797
66798
66799
66800
66801
66802
66803
66804
66805
66806
66807
66808
66809
66810

66811
66812
66813
66814
66815
66816
66817
66818







-
+



-
+




-
-
-
-
+
+
+
+

-
+

-
+















-
+







** and that the current process needs to reread the schema.
**
** Either a transaction needs to have been started or an OP_Open needs
** to be executed (to establish a read lock) before this opcode is
** invoked.
*/
case OP_VerifyCookie: {
#if 0  /* local variables moved into u.aw */
#if 0  /* local variables moved into u.ax */
  int iMeta;
  int iGen;
  Btree *pBt;
#endif /* local variables moved into u.aw */
#endif /* local variables moved into u.ax */

  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
  assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
  u.aw.pBt = db->aDb[pOp->p1].pBt;
  if( u.aw.pBt ){
    sqlite3BtreeGetMeta(u.aw.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.aw.iMeta);
    u.aw.iGen = db->aDb[pOp->p1].pSchema->iGeneration;
  u.ax.pBt = db->aDb[pOp->p1].pBt;
  if( u.ax.pBt ){
    sqlite3BtreeGetMeta(u.ax.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.ax.iMeta);
    u.ax.iGen = db->aDb[pOp->p1].pSchema->iGeneration;
  }else{
    u.aw.iGen = u.aw.iMeta = 0;
    u.ax.iGen = u.ax.iMeta = 0;
  }
  if( u.aw.iMeta!=pOp->p2 || u.aw.iGen!=pOp->p3 ){
  if( u.ax.iMeta!=pOp->p2 || u.ax.iGen!=pOp->p3 ){
    sqlite3DbFree(db, p->zErrMsg);
    p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
    /* If the schema-cookie from the database file matches the cookie
    ** stored with the in-memory representation of the schema, do
    ** not reload the schema from the database file.
    **
    ** If virtual-tables are in use, this is not just an optimization.
    ** Often, v-tables store their data in other SQLite tables, which
    ** are queried from within xNext() and other v-table methods using
    ** prepared queries. If such a query is out-of-date, we do not want to
    ** discard the database schema, as the user code implementing the
    ** v-table would have to be ready for the sqlite3_vtab structure itself
    ** to be invalidated whenever sqlite3_step() is called from within
    ** a v-table method.
    */
    if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.aw.iMeta ){
    if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.ax.iMeta ){
      sqlite3ResetOneSchema(db, pOp->p1);
    }

    p->expired = 1;
    rc = SQLITE_SCHEMA;
  }
  break;
66710
66711
66712
66713
66714
66715
66716
66717

66718
66719
66720
66721
66722
66723
66724
66725
66726

66727
66728
66729
66730
66731
66732
66733
66734
66735
66736
66737
66738
66739
66740
66741
66742
66743
66744









66745
66746
66747
66748
66749




66750
66751
66752

66753
66754
66755
66756
66757



66758
66759
66760
66761
66762
66763



66764
66765
66766

66767
66768
66769
66770
66771
66772
66773
66774



66775
66776

66777
66778
66779
66780
66781
66782
66783
66784






66785
66786

66787
66788
66789
66790
66791
66792
66793
66794
66795
66796
66797


66798
66799
66800
66801
66802
66803
66804
66865
66866
66867
66868
66869
66870
66871

66872
66873
66874
66875
66876
66877
66878
66879
66880

66881
66882
66883
66884
66885
66886
66887
66888
66889
66890









66891
66892
66893
66894
66895
66896
66897
66898
66899
66900




66901
66902
66903
66904
66905
66906

66907
66908
66909



66910
66911
66912
66913
66914
66915



66916
66917
66918
66919
66920

66921
66922
66923
66924
66925
66926



66927
66928
66929
66930

66931
66932
66933






66934
66935
66936
66937
66938
66939
66940

66941
66942
66943
66944
66945
66946
66947
66948
66949
66950


66951
66952
66953
66954
66955
66956
66957
66958
66959







-
+








-
+









-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+

-
-
-
-
+
+
+
+


-
+


-
-
-
+
+
+



-
-
-
+
+
+


-
+





-
-
-
+
+
+

-
+


-
-
-
-
-
-
+
+
+
+
+
+

-
+









-
-
+
+







** in read/write mode.  For a given table, there can be one or more read-only
** cursors or a single read/write cursor but not both.
**
** See also OpenRead.
*/
case OP_OpenRead:
case OP_OpenWrite: {
#if 0  /* local variables moved into u.ax */
#if 0  /* local variables moved into u.ay */
  int nField;
  KeyInfo *pKeyInfo;
  int p2;
  int iDb;
  int wrFlag;
  Btree *pX;
  VdbeCursor *pCur;
  Db *pDb;
#endif /* local variables moved into u.ax */
#endif /* local variables moved into u.ay */

  assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 );
  assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 );

  if( p->expired ){
    rc = SQLITE_ABORT;
    break;
  }

  u.ax.nField = 0;
  u.ax.pKeyInfo = 0;
  u.ax.p2 = pOp->p2;
  u.ax.iDb = pOp->p3;
  assert( u.ax.iDb>=0 && u.ax.iDb<db->nDb );
  assert( (p->btreeMask & (((yDbMask)1)<<u.ax.iDb))!=0 );
  u.ax.pDb = &db->aDb[u.ax.iDb];
  u.ax.pX = u.ax.pDb->pBt;
  assert( u.ax.pX!=0 );
  u.ay.nField = 0;
  u.ay.pKeyInfo = 0;
  u.ay.p2 = pOp->p2;
  u.ay.iDb = pOp->p3;
  assert( u.ay.iDb>=0 && u.ay.iDb<db->nDb );
  assert( (p->btreeMask & (((yDbMask)1)<<u.ay.iDb))!=0 );
  u.ay.pDb = &db->aDb[u.ay.iDb];
  u.ay.pX = u.ay.pDb->pBt;
  assert( u.ay.pX!=0 );
  if( pOp->opcode==OP_OpenWrite ){
    u.ax.wrFlag = 1;
    assert( sqlite3SchemaMutexHeld(db, u.ax.iDb, 0) );
    if( u.ax.pDb->pSchema->file_format < p->minWriteFileFormat ){
      p->minWriteFileFormat = u.ax.pDb->pSchema->file_format;
    u.ay.wrFlag = 1;
    assert( sqlite3SchemaMutexHeld(db, u.ay.iDb, 0) );
    if( u.ay.pDb->pSchema->file_format < p->minWriteFileFormat ){
      p->minWriteFileFormat = u.ay.pDb->pSchema->file_format;
    }
  }else{
    u.ax.wrFlag = 0;
    u.ay.wrFlag = 0;
  }
  if( pOp->p5 & OPFLAG_P2ISREG ){
    assert( u.ax.p2>0 );
    assert( u.ax.p2<=p->nMem );
    pIn2 = &aMem[u.ax.p2];
    assert( u.ay.p2>0 );
    assert( u.ay.p2<=p->nMem );
    pIn2 = &aMem[u.ay.p2];
    assert( memIsValid(pIn2) );
    assert( (pIn2->flags & MEM_Int)!=0 );
    sqlite3VdbeMemIntegerify(pIn2);
    u.ax.p2 = (int)pIn2->u.i;
    /* The u.ax.p2 value always comes from a prior OP_CreateTable opcode and
    ** that opcode will always set the u.ax.p2 value to 2 or more or else fail.
    u.ay.p2 = (int)pIn2->u.i;
    /* The u.ay.p2 value always comes from a prior OP_CreateTable opcode and
    ** that opcode will always set the u.ay.p2 value to 2 or more or else fail.
    ** If there were a failure, the prepared statement would have halted
    ** before reaching this instruction. */
    if( NEVER(u.ax.p2<2) ) {
    if( NEVER(u.ay.p2<2) ) {
      rc = SQLITE_CORRUPT_BKPT;
      goto abort_due_to_error;
    }
  }
  if( pOp->p4type==P4_KEYINFO ){
    u.ax.pKeyInfo = pOp->p4.pKeyInfo;
    u.ax.pKeyInfo->enc = ENC(p->db);
    u.ax.nField = u.ax.pKeyInfo->nField+1;
    u.ay.pKeyInfo = pOp->p4.pKeyInfo;
    u.ay.pKeyInfo->enc = ENC(p->db);
    u.ay.nField = u.ay.pKeyInfo->nField+1;
  }else if( pOp->p4type==P4_INT32 ){
    u.ax.nField = pOp->p4.i;
    u.ay.nField = pOp->p4.i;
  }
  assert( pOp->p1>=0 );
  u.ax.pCur = allocateCursor(p, pOp->p1, u.ax.nField, u.ax.iDb, 1);
  if( u.ax.pCur==0 ) goto no_mem;
  u.ax.pCur->nullRow = 1;
  u.ax.pCur->isOrdered = 1;
  rc = sqlite3BtreeCursor(u.ax.pX, u.ax.p2, u.ax.wrFlag, u.ax.pKeyInfo, u.ax.pCur->pCursor);
  u.ax.pCur->pKeyInfo = u.ax.pKeyInfo;
  u.ay.pCur = allocateCursor(p, pOp->p1, u.ay.nField, u.ay.iDb, 1);
  if( u.ay.pCur==0 ) goto no_mem;
  u.ay.pCur->nullRow = 1;
  u.ay.pCur->isOrdered = 1;
  rc = sqlite3BtreeCursor(u.ay.pX, u.ay.p2, u.ay.wrFlag, u.ay.pKeyInfo, u.ay.pCur->pCursor);
  u.ay.pCur->pKeyInfo = u.ay.pKeyInfo;
  assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
  sqlite3BtreeCursorHints(u.ax.pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));
  sqlite3BtreeCursorHints(u.ay.pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));

  /* Since it performs no memory allocation or IO, the only value that
  ** sqlite3BtreeCursor() may return is SQLITE_OK. */
  assert( rc==SQLITE_OK );

  /* Set the VdbeCursor.isTable and isIndex variables. Previous versions of
  ** SQLite used to check if the root-page flags were sane at this point
  ** and report database corruption if they were not, but this check has
  ** since moved into the btree layer.  */
  u.ax.pCur->isTable = pOp->p4type!=P4_KEYINFO;
  u.ax.pCur->isIndex = !u.ax.pCur->isTable;
  u.ay.pCur->isTable = pOp->p4type!=P4_KEYINFO;
  u.ay.pCur->isIndex = !u.ay.pCur->isTable;
  break;
}

/* Opcode: OpenEphemeral P1 P2 * P4 P5
**
** Open a new cursor P1 to a transient table.
** The cursor is always opened read/write even if 
66826
66827
66828
66829
66830
66831
66832
66833

66834
66835

66836
66837
66838
66839
66840
66841
66842
66843
66844
66845
66846
66847




66848
66849
66850

66851
66852
66853
66854
66855
66856
66857
66858
66859
66860
66861

66862
66863
66864
66865
66866
66867




66868
66869

66870
66871
66872


66873
66874
66875
66876


66877
66878
66879
66880
66881
66882
66883
66884
66885
66886
66887

66888
66889

66890
66891
66892
66893
66894
66895
66896
66897






66898
66899
66900
66901
66902
66903
66904
66981
66982
66983
66984
66985
66986
66987

66988
66989

66990
66991
66992
66993
66994
66995
66996
66997
66998




66999
67000
67001
67002
67003
67004

67005
67006
67007
67008
67009
67010
67011
67012
67013
67014
67015

67016
67017
67018




67019
67020
67021
67022
67023

67024
67025


67026
67027
67028
67029


67030
67031
67032
67033
67034
67035
67036
67037
67038
67039
67040
67041

67042
67043

67044
67045
67046






67047
67048
67049
67050
67051
67052
67053
67054
67055
67056
67057
67058
67059







-
+

-
+








-
-
-
-
+
+
+
+


-
+










-
+


-
-
-
-
+
+
+
+

-
+

-
-
+
+


-
-
+
+










-
+

-
+


-
-
-
-
-
-
+
+
+
+
+
+







** This opcode works the same as OP_OpenEphemeral.  It has a
** different name to distinguish its use.  Tables created using
** by this opcode will be used for automatically created transient
** indices in joins.
*/
case OP_OpenAutoindex: 
case OP_OpenEphemeral: {
#if 0  /* local variables moved into u.ay */
#if 0  /* local variables moved into u.az */
  VdbeCursor *pCx;
#endif /* local variables moved into u.ay */
#endif /* local variables moved into u.az */
  static const int vfsFlags =
      SQLITE_OPEN_READWRITE |
      SQLITE_OPEN_CREATE |
      SQLITE_OPEN_EXCLUSIVE |
      SQLITE_OPEN_DELETEONCLOSE |
      SQLITE_OPEN_TRANSIENT_DB;

  assert( pOp->p1>=0 );
  u.ay.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
  if( u.ay.pCx==0 ) goto no_mem;
  u.ay.pCx->nullRow = 1;
  rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.ay.pCx->pBt,
  u.az.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
  if( u.az.pCx==0 ) goto no_mem;
  u.az.pCx->nullRow = 1;
  rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.az.pCx->pBt,
                        BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
  if( rc==SQLITE_OK ){
    rc = sqlite3BtreeBeginTrans(u.ay.pCx->pBt, 1);
    rc = sqlite3BtreeBeginTrans(u.az.pCx->pBt, 1);
  }
  if( rc==SQLITE_OK ){
    /* If a transient index is required, create it by calling
    ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
    ** opening it. If a transient table is required, just use the
    ** automatically created table with root-page 1 (an BLOB_INTKEY table).
    */
    if( pOp->p4.pKeyInfo ){
      int pgno;
      assert( pOp->p4type==P4_KEYINFO );
      rc = sqlite3BtreeCreateTable(u.ay.pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5);
      rc = sqlite3BtreeCreateTable(u.az.pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5);
      if( rc==SQLITE_OK ){
        assert( pgno==MASTER_ROOT+1 );
        rc = sqlite3BtreeCursor(u.ay.pCx->pBt, pgno, 1,
                                (KeyInfo*)pOp->p4.z, u.ay.pCx->pCursor);
        u.ay.pCx->pKeyInfo = pOp->p4.pKeyInfo;
        u.ay.pCx->pKeyInfo->enc = ENC(p->db);
        rc = sqlite3BtreeCursor(u.az.pCx->pBt, pgno, 1,
                                (KeyInfo*)pOp->p4.z, u.az.pCx->pCursor);
        u.az.pCx->pKeyInfo = pOp->p4.pKeyInfo;
        u.az.pCx->pKeyInfo->enc = ENC(p->db);
      }
      u.ay.pCx->isTable = 0;
      u.az.pCx->isTable = 0;
    }else{
      rc = sqlite3BtreeCursor(u.ay.pCx->pBt, MASTER_ROOT, 1, 0, u.ay.pCx->pCursor);
      u.ay.pCx->isTable = 1;
      rc = sqlite3BtreeCursor(u.az.pCx->pBt, MASTER_ROOT, 1, 0, u.az.pCx->pCursor);
      u.az.pCx->isTable = 1;
    }
  }
  u.ay.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
  u.ay.pCx->isIndex = !u.ay.pCx->isTable;
  u.az.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
  u.az.pCx->isIndex = !u.az.pCx->isTable;
  break;
}

/* Opcode: OpenSorter P1 P2 * P4 *
**
** This opcode works like OP_OpenEphemeral except that it opens
** a transient index that is specifically designed to sort large
** tables using an external merge-sort algorithm.
*/
case OP_SorterOpen: {
#if 0  /* local variables moved into u.az */
#if 0  /* local variables moved into u.ba */
  VdbeCursor *pCx;
#endif /* local variables moved into u.az */
#endif /* local variables moved into u.ba */

#ifndef SQLITE_OMIT_MERGE_SORT
  u.az.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
  if( u.az.pCx==0 ) goto no_mem;
  u.az.pCx->pKeyInfo = pOp->p4.pKeyInfo;
  u.az.pCx->pKeyInfo->enc = ENC(p->db);
  u.az.pCx->isSorter = 1;
  rc = sqlite3VdbeSorterInit(db, u.az.pCx);
  u.ba.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
  if( u.ba.pCx==0 ) goto no_mem;
  u.ba.pCx->pKeyInfo = pOp->p4.pKeyInfo;
  u.ba.pCx->pKeyInfo->enc = ENC(p->db);
  u.ba.pCx->isSorter = 1;
  rc = sqlite3VdbeSorterInit(db, u.ba.pCx);
#else
  pOp->opcode = OP_OpenEphemeral;
  pc--;
#endif
  break;
}

66914
66915
66916
66917
66918
66919
66920
66921

66922
66923

66924
66925
66926
66927
66928
66929
66930
66931






66932
66933
66934
66935
66936
66937
66938
67069
67070
67071
67072
67073
67074
67075

67076
67077

67078
67079
67080






67081
67082
67083
67084
67085
67086
67087
67088
67089
67090
67091
67092
67093







-
+

-
+


-
-
-
-
-
-
+
+
+
+
+
+







** individual columns using the OP_Column opcode.  The OP_Column opcode
** is the only cursor opcode that works with a pseudo-table.
**
** P3 is the number of fields in the records that will be stored by
** the pseudo-table.
*/
case OP_OpenPseudo: {
#if 0  /* local variables moved into u.ba */
#if 0  /* local variables moved into u.bb */
  VdbeCursor *pCx;
#endif /* local variables moved into u.ba */
#endif /* local variables moved into u.bb */

  assert( pOp->p1>=0 );
  u.ba.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
  if( u.ba.pCx==0 ) goto no_mem;
  u.ba.pCx->nullRow = 1;
  u.ba.pCx->pseudoTableReg = pOp->p2;
  u.ba.pCx->isTable = 1;
  u.ba.pCx->isIndex = 0;
  u.bb.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
  if( u.bb.pCx==0 ) goto no_mem;
  u.bb.pCx->nullRow = 1;
  u.bb.pCx->pseudoTableReg = pOp->p2;
  u.bb.pCx->isTable = 1;
  u.bb.pCx->isIndex = 0;
  break;
}

/* Opcode: Close P1 * * * *
**
** Close a cursor previously opened as P1.  If P1 is not
** currently open, this instruction is a no-op.
66996
66997
66998
66999
67000
67001
67002
67003

67004
67005
67006
67007
67008
67009
67010

67011
67012
67013
67014
67015
67016



67017
67018
67019
67020
67021
67022
67023
67024





67025
67026
67027
67028
67029
67030
67031


67032
67033
67034
67035
67036
67037
67038
67039
67040
67041
67042
67043
67044
67045
67046

67047
67048
67049

67050
67051
67052


67053
67054
67055
67056
67057


67058
67059
67060
67061

67062
67063
67064
67065

67066
67067

67068
67069
67070
67071


67072
67073
67074

67075
67076
67077
67078
67079
67080



67081
67082
67083

67084
67085
67086
67087



67088
67089
67090
67091


67092
67093

67094
67095
67096
67097
67098
67099
67100





67101
67102

67103
67104

67105
67106
67107


67108
67109
67110
67111

67112
67113
67114


67115
67116
67117
67118
67119
67120



67121
67122

67123
67124

67125
67126
67127
67128
67129



67130
67131

67132
67133

67134
67135
67136

67137
67138
67139
67140

67141
67142
67143
67144
67145
67146
67147
67151
67152
67153
67154
67155
67156
67157

67158
67159
67160
67161
67162
67163
67164

67165
67166
67167
67168



67169
67170
67171
67172
67173
67174





67175
67176
67177
67178
67179
67180
67181
67182
67183
67184


67185
67186
67187
67188
67189
67190
67191
67192
67193
67194
67195
67196
67197
67198
67199
67200

67201
67202
67203

67204
67205


67206
67207
67208
67209
67210


67211
67212
67213
67214
67215

67216
67217
67218
67219

67220
67221

67222
67223
67224


67225
67226
67227
67228

67229
67230
67231
67232



67233
67234
67235
67236
67237

67238
67239



67240
67241
67242
67243
67244


67245
67246
67247

67248
67249
67250





67251
67252
67253
67254
67255
67256

67257
67258

67259
67260


67261
67262
67263
67264
67265

67266
67267


67268
67269
67270
67271
67272



67273
67274
67275
67276

67277
67278

67279
67280
67281



67282
67283
67284
67285

67286
67287

67288
67289
67290

67291
67292
67293
67294

67295
67296
67297
67298
67299
67300
67301
67302







-
+






-
+



-
-
-
+
+
+



-
-
-
-
-
+
+
+
+
+





-
-
+
+














-
+


-
+

-
-
+
+



-
-
+
+



-
+



-
+

-
+


-
-
+
+


-
+



-
-
-
+
+
+


-
+

-
-
-
+
+
+


-
-
+
+

-
+


-
-
-
-
-
+
+
+
+
+

-
+

-
+

-
-
+
+



-
+

-
-
+
+



-
-
-
+
+
+

-
+

-
+


-
-
-
+
+
+

-
+

-
+


-
+



-
+







**
** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt
*/
case OP_SeekLt:         /* jump, in3 */
case OP_SeekLe:         /* jump, in3 */
case OP_SeekGe:         /* jump, in3 */
case OP_SeekGt: {       /* jump, in3 */
#if 0  /* local variables moved into u.bb */
#if 0  /* local variables moved into u.bc */
  int res;
  int oc;
  VdbeCursor *pC;
  UnpackedRecord r;
  int nField;
  i64 iKey;      /* The rowid we are to seek to */
#endif /* local variables moved into u.bb */
#endif /* local variables moved into u.bc */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pOp->p2!=0 );
  u.bb.pC = p->apCsr[pOp->p1];
  assert( u.bb.pC!=0 );
  assert( u.bb.pC->pseudoTableReg==0 );
  u.bc.pC = p->apCsr[pOp->p1];
  assert( u.bc.pC!=0 );
  assert( u.bc.pC->pseudoTableReg==0 );
  assert( OP_SeekLe == OP_SeekLt+1 );
  assert( OP_SeekGe == OP_SeekLt+2 );
  assert( OP_SeekGt == OP_SeekLt+3 );
  assert( u.bb.pC->isOrdered );
  if( ALWAYS(u.bb.pC->pCursor!=0) ){
    u.bb.oc = pOp->opcode;
    u.bb.pC->nullRow = 0;
    if( u.bb.pC->isTable ){
  assert( u.bc.pC->isOrdered );
  if( ALWAYS(u.bc.pC->pCursor!=0) ){
    u.bc.oc = pOp->opcode;
    u.bc.pC->nullRow = 0;
    if( u.bc.pC->isTable ){
      /* The input value in P3 might be of any type: integer, real, string,
      ** blob, or NULL.  But it needs to be an integer before we can do
      ** the seek, so covert it. */
      pIn3 = &aMem[pOp->p3];
      applyNumericAffinity(pIn3);
      u.bb.iKey = sqlite3VdbeIntValue(pIn3);
      u.bb.pC->rowidIsValid = 0;
      u.bc.iKey = sqlite3VdbeIntValue(pIn3);
      u.bc.pC->rowidIsValid = 0;

      /* If the P3 value could not be converted into an integer without
      ** loss of information, then special processing is required... */
      if( (pIn3->flags & MEM_Int)==0 ){
        if( (pIn3->flags & MEM_Real)==0 ){
          /* If the P3 value cannot be converted into any kind of a number,
          ** then the seek is not possible, so jump to P2 */
          pc = pOp->p2 - 1;
          break;
        }
        /* If we reach this point, then the P3 value must be a floating
        ** point number. */
        assert( (pIn3->flags & MEM_Real)!=0 );

        if( u.bb.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bb.iKey || pIn3->r>0) ){
        if( u.bc.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bc.iKey || pIn3->r>0) ){
          /* The P3 value is too large in magnitude to be expressed as an
          ** integer. */
          u.bb.res = 1;
          u.bc.res = 1;
          if( pIn3->r<0 ){
            if( u.bb.oc>=OP_SeekGe ){  assert( u.bb.oc==OP_SeekGe || u.bb.oc==OP_SeekGt );
              rc = sqlite3BtreeFirst(u.bb.pC->pCursor, &u.bb.res);
            if( u.bc.oc>=OP_SeekGe ){  assert( u.bc.oc==OP_SeekGe || u.bc.oc==OP_SeekGt );
              rc = sqlite3BtreeFirst(u.bc.pC->pCursor, &u.bc.res);
              if( rc!=SQLITE_OK ) goto abort_due_to_error;
            }
          }else{
            if( u.bb.oc<=OP_SeekLe ){  assert( u.bb.oc==OP_SeekLt || u.bb.oc==OP_SeekLe );
              rc = sqlite3BtreeLast(u.bb.pC->pCursor, &u.bb.res);
            if( u.bc.oc<=OP_SeekLe ){  assert( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe );
              rc = sqlite3BtreeLast(u.bc.pC->pCursor, &u.bc.res);
              if( rc!=SQLITE_OK ) goto abort_due_to_error;
            }
          }
          if( u.bb.res ){
          if( u.bc.res ){
            pc = pOp->p2 - 1;
          }
          break;
        }else if( u.bb.oc==OP_SeekLt || u.bb.oc==OP_SeekGe ){
        }else if( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekGe ){
          /* Use the ceiling() function to convert real->int */
          if( pIn3->r > (double)u.bb.iKey ) u.bb.iKey++;
          if( pIn3->r > (double)u.bc.iKey ) u.bc.iKey++;
        }else{
          /* Use the floor() function to convert real->int */
          assert( u.bb.oc==OP_SeekLe || u.bb.oc==OP_SeekGt );
          if( pIn3->r < (double)u.bb.iKey ) u.bb.iKey--;
          assert( u.bc.oc==OP_SeekLe || u.bc.oc==OP_SeekGt );
          if( pIn3->r < (double)u.bc.iKey ) u.bc.iKey--;
        }
      }
      rc = sqlite3BtreeMovetoUnpacked(u.bb.pC->pCursor, 0, (u64)u.bb.iKey, 0, &u.bb.res);
      rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, 0, (u64)u.bc.iKey, 0, &u.bc.res);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
      if( u.bb.res==0 ){
        u.bb.pC->rowidIsValid = 1;
        u.bb.pC->lastRowid = u.bb.iKey;
      if( u.bc.res==0 ){
        u.bc.pC->rowidIsValid = 1;
        u.bc.pC->lastRowid = u.bc.iKey;
      }
    }else{
      u.bb.nField = pOp->p4.i;
      u.bc.nField = pOp->p4.i;
      assert( pOp->p4type==P4_INT32 );
      assert( u.bb.nField>0 );
      u.bb.r.pKeyInfo = u.bb.pC->pKeyInfo;
      u.bb.r.nField = (u16)u.bb.nField;
      assert( u.bc.nField>0 );
      u.bc.r.pKeyInfo = u.bc.pC->pKeyInfo;
      u.bc.r.nField = (u16)u.bc.nField;

      /* The next line of code computes as follows, only faster:
      **   if( u.bb.oc==OP_SeekGt || u.bb.oc==OP_SeekLe ){
      **     u.bb.r.flags = UNPACKED_INCRKEY;
      **   if( u.bc.oc==OP_SeekGt || u.bc.oc==OP_SeekLe ){
      **     u.bc.r.flags = UNPACKED_INCRKEY;
      **   }else{
      **     u.bb.r.flags = 0;
      **     u.bc.r.flags = 0;
      **   }
      */
      u.bb.r.flags = (u16)(UNPACKED_INCRKEY * (1 & (u.bb.oc - OP_SeekLt)));
      assert( u.bb.oc!=OP_SeekGt || u.bb.r.flags==UNPACKED_INCRKEY );
      assert( u.bb.oc!=OP_SeekLe || u.bb.r.flags==UNPACKED_INCRKEY );
      assert( u.bb.oc!=OP_SeekGe || u.bb.r.flags==0 );
      assert( u.bb.oc!=OP_SeekLt || u.bb.r.flags==0 );
      u.bc.r.flags = (u16)(UNPACKED_INCRKEY * (1 & (u.bc.oc - OP_SeekLt)));
      assert( u.bc.oc!=OP_SeekGt || u.bc.r.flags==UNPACKED_INCRKEY );
      assert( u.bc.oc!=OP_SeekLe || u.bc.r.flags==UNPACKED_INCRKEY );
      assert( u.bc.oc!=OP_SeekGe || u.bc.r.flags==0 );
      assert( u.bc.oc!=OP_SeekLt || u.bc.r.flags==0 );

      u.bb.r.aMem = &aMem[pOp->p3];
      u.bc.r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
      { int i; for(i=0; i<u.bb.r.nField; i++) assert( memIsValid(&u.bb.r.aMem[i]) ); }
      { int i; for(i=0; i<u.bc.r.nField; i++) assert( memIsValid(&u.bc.r.aMem[i]) ); }
#endif
      ExpandBlob(u.bb.r.aMem);
      rc = sqlite3BtreeMovetoUnpacked(u.bb.pC->pCursor, &u.bb.r, 0, 0, &u.bb.res);
      ExpandBlob(u.bc.r.aMem);
      rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, &u.bc.r, 0, 0, &u.bc.res);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
      u.bb.pC->rowidIsValid = 0;
      u.bc.pC->rowidIsValid = 0;
    }
    u.bb.pC->deferredMoveto = 0;
    u.bb.pC->cacheStatus = CACHE_STALE;
    u.bc.pC->deferredMoveto = 0;
    u.bc.pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_TEST
    sqlite3_search_count++;
#endif
    if( u.bb.oc>=OP_SeekGe ){  assert( u.bb.oc==OP_SeekGe || u.bb.oc==OP_SeekGt );
      if( u.bb.res<0 || (u.bb.res==0 && u.bb.oc==OP_SeekGt) ){
        rc = sqlite3BtreeNext(u.bb.pC->pCursor, &u.bb.res);
    if( u.bc.oc>=OP_SeekGe ){  assert( u.bc.oc==OP_SeekGe || u.bc.oc==OP_SeekGt );
      if( u.bc.res<0 || (u.bc.res==0 && u.bc.oc==OP_SeekGt) ){
        rc = sqlite3BtreeNext(u.bc.pC->pCursor, &u.bc.res);
        if( rc!=SQLITE_OK ) goto abort_due_to_error;
        u.bb.pC->rowidIsValid = 0;
        u.bc.pC->rowidIsValid = 0;
      }else{
        u.bb.res = 0;
        u.bc.res = 0;
      }
    }else{
      assert( u.bb.oc==OP_SeekLt || u.bb.oc==OP_SeekLe );
      if( u.bb.res>0 || (u.bb.res==0 && u.bb.oc==OP_SeekLt) ){
        rc = sqlite3BtreePrevious(u.bb.pC->pCursor, &u.bb.res);
      assert( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe );
      if( u.bc.res>0 || (u.bc.res==0 && u.bc.oc==OP_SeekLt) ){
        rc = sqlite3BtreePrevious(u.bc.pC->pCursor, &u.bc.res);
        if( rc!=SQLITE_OK ) goto abort_due_to_error;
        u.bb.pC->rowidIsValid = 0;
        u.bc.pC->rowidIsValid = 0;
      }else{
        /* u.bb.res might be negative because the table is empty.  Check to
        /* u.bc.res might be negative because the table is empty.  Check to
        ** see if this is the case.
        */
        u.bb.res = sqlite3BtreeEof(u.bb.pC->pCursor);
        u.bc.res = sqlite3BtreeEof(u.bc.pC->pCursor);
      }
    }
    assert( pOp->p2>0 );
    if( u.bb.res ){
    if( u.bc.res ){
      pc = pOp->p2 - 1;
    }
  }else{
    /* This happens when attempting to open the sqlite3_master table
    ** for read access returns SQLITE_EMPTY. In this case always
    ** take the jump (since there are no records in the table).
    */
67156
67157
67158
67159
67160
67161
67162
67163

67164
67165

67166
67167
67168
67169
67170
67171
67172





67173
67174
67175
67176



67177
67178
67179
67180
67181
67182
67183
67311
67312
67313
67314
67315
67316
67317

67318
67319

67320
67321
67322





67323
67324
67325
67326
67327
67328



67329
67330
67331
67332
67333
67334
67335
67336
67337
67338







-
+

-
+


-
-
-
-
-
+
+
+
+
+

-
-
-
+
+
+







** for P1 to move so that it points to the rowid given by P2.
**
** This is actually a deferred seek.  Nothing actually happens until
** the cursor is used to read a record.  That way, if no reads
** occur, no unnecessary I/O happens.
*/
case OP_Seek: {    /* in2 */
#if 0  /* local variables moved into u.bc */
#if 0  /* local variables moved into u.bd */
  VdbeCursor *pC;
#endif /* local variables moved into u.bc */
#endif /* local variables moved into u.bd */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bc.pC = p->apCsr[pOp->p1];
  assert( u.bc.pC!=0 );
  if( ALWAYS(u.bc.pC->pCursor!=0) ){
    assert( u.bc.pC->isTable );
    u.bc.pC->nullRow = 0;
  u.bd.pC = p->apCsr[pOp->p1];
  assert( u.bd.pC!=0 );
  if( ALWAYS(u.bd.pC->pCursor!=0) ){
    assert( u.bd.pC->isTable );
    u.bd.pC->nullRow = 0;
    pIn2 = &aMem[pOp->p2];
    u.bc.pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
    u.bc.pC->rowidIsValid = 0;
    u.bc.pC->deferredMoveto = 1;
    u.bd.pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
    u.bd.pC->rowidIsValid = 0;
    u.bd.pC->deferredMoveto = 1;
  }
  break;
}
  

/* Opcode: Found P1 P2 P3 P4 *
**
67201
67202
67203
67204
67205
67206
67207
67208

67209
67210
67211
67212
67213
67214
67215
67216

67217
67218
67219
67220
67221
67222

67223
67224
67225
67226


67227
67228

67229
67230

67231
67232
67233
67234



67235
67236

67237
67238
67239


67240
67241
67242


67243
67244

67245
67246
67247
67248


67249
67250

67251
67252

67253
67254
67255
67256
67257
67258
67259



67260
67261
67262

67263
67264

67265
67266
67267
67268
67269
67270
67271
67356
67357
67358
67359
67360
67361
67362

67363
67364
67365
67366
67367
67368
67369
67370

67371
67372
67373
67374
67375
67376

67377
67378
67379


67380
67381
67382

67383
67384

67385
67386



67387
67388
67389
67390

67391
67392


67393
67394
67395


67396
67397
67398

67399
67400
67401


67402
67403
67404

67405
67406

67407
67408
67409
67410
67411



67412
67413
67414
67415
67416

67417
67418

67419
67420
67421
67422
67423
67424
67425
67426







-
+







-
+





-
+


-
-
+
+

-
+

-
+

-
-
-
+
+
+

-
+

-
-
+
+

-
-
+
+

-
+


-
-
+
+

-
+

-
+




-
-
-
+
+
+


-
+

-
+







** falls through to the next instruction and P1 is left pointing at the
** matching entry.
**
** See also: Found, NotExists, IsUnique
*/
case OP_NotFound:       /* jump, in3 */
case OP_Found: {        /* jump, in3 */
#if 0  /* local variables moved into u.bd */
#if 0  /* local variables moved into u.be */
  int alreadyExists;
  VdbeCursor *pC;
  int res;
  char *pFree;
  UnpackedRecord *pIdxKey;
  UnpackedRecord r;
  char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
#endif /* local variables moved into u.bd */
#endif /* local variables moved into u.be */

#ifdef SQLITE_TEST
  sqlite3_found_count++;
#endif

  u.bd.alreadyExists = 0;
  u.be.alreadyExists = 0;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pOp->p4type==P4_INT32 );
  u.bd.pC = p->apCsr[pOp->p1];
  assert( u.bd.pC!=0 );
  u.be.pC = p->apCsr[pOp->p1];
  assert( u.be.pC!=0 );
  pIn3 = &aMem[pOp->p3];
  if( ALWAYS(u.bd.pC->pCursor!=0) ){
  if( ALWAYS(u.be.pC->pCursor!=0) ){

    assert( u.bd.pC->isTable==0 );
    assert( u.be.pC->isTable==0 );
    if( pOp->p4.i>0 ){
      u.bd.r.pKeyInfo = u.bd.pC->pKeyInfo;
      u.bd.r.nField = (u16)pOp->p4.i;
      u.bd.r.aMem = pIn3;
      u.be.r.pKeyInfo = u.be.pC->pKeyInfo;
      u.be.r.nField = (u16)pOp->p4.i;
      u.be.r.aMem = pIn3;
#ifdef SQLITE_DEBUG
      { int i; for(i=0; i<u.bd.r.nField; i++) assert( memIsValid(&u.bd.r.aMem[i]) ); }
      { int i; for(i=0; i<u.be.r.nField; i++) assert( memIsValid(&u.be.r.aMem[i]) ); }
#endif
      u.bd.r.flags = UNPACKED_PREFIX_MATCH;
      u.bd.pIdxKey = &u.bd.r;
      u.be.r.flags = UNPACKED_PREFIX_MATCH;
      u.be.pIdxKey = &u.be.r;
    }else{
      u.bd.pIdxKey = sqlite3VdbeAllocUnpackedRecord(
          u.bd.pC->pKeyInfo, u.bd.aTempRec, sizeof(u.bd.aTempRec), &u.bd.pFree
      u.be.pIdxKey = sqlite3VdbeAllocUnpackedRecord(
          u.be.pC->pKeyInfo, u.be.aTempRec, sizeof(u.be.aTempRec), &u.be.pFree
      );
      if( u.bd.pIdxKey==0 ) goto no_mem;
      if( u.be.pIdxKey==0 ) goto no_mem;
      assert( pIn3->flags & MEM_Blob );
      assert( (pIn3->flags & MEM_Zero)==0 );  /* zeroblobs already expanded */
      sqlite3VdbeRecordUnpack(u.bd.pC->pKeyInfo, pIn3->n, pIn3->z, u.bd.pIdxKey);
      u.bd.pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
      sqlite3VdbeRecordUnpack(u.be.pC->pKeyInfo, pIn3->n, pIn3->z, u.be.pIdxKey);
      u.be.pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
    }
    rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, u.bd.pIdxKey, 0, 0, &u.bd.res);
    rc = sqlite3BtreeMovetoUnpacked(u.be.pC->pCursor, u.be.pIdxKey, 0, 0, &u.be.res);
    if( pOp->p4.i==0 ){
      sqlite3DbFree(db, u.bd.pFree);
      sqlite3DbFree(db, u.be.pFree);
    }
    if( rc!=SQLITE_OK ){
      break;
    }
    u.bd.alreadyExists = (u.bd.res==0);
    u.bd.pC->deferredMoveto = 0;
    u.bd.pC->cacheStatus = CACHE_STALE;
    u.be.alreadyExists = (u.be.res==0);
    u.be.pC->deferredMoveto = 0;
    u.be.pC->cacheStatus = CACHE_STALE;
  }
  if( pOp->opcode==OP_Found ){
    if( u.bd.alreadyExists ) pc = pOp->p2 - 1;
    if( u.be.alreadyExists ) pc = pOp->p2 - 1;
  }else{
    if( !u.bd.alreadyExists ) pc = pOp->p2 - 1;
    if( !u.be.alreadyExists ) pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: IsUnique P1 P2 P3 P4 *
**
** Cursor P1 is open on an index b-tree - that is to say, a btree which
67289
67290
67291
67292
67293
67294
67295
67296

67297
67298
67299
67300
67301
67302
67303
67304

67305
67306
67307

67308
67309
67310
67311
67312
67313
67314
67315
67316
67317
67318





67319
67320
67321
67322
67323



67324
67325

67326
67327
67328
67329

67330
67331

67332
67333
67334
67335
67336




67337
67338

67339
67340
67341

67342
67343

67344
67345
67346
67347
67348
67349


67350
67351
67352

67353
67354
67355
67356
67357
67358
67359
67360
67361
67362
67363
67364
67365
67366
67367
67368
67369
67370
67371
67372
67373

67374
67375
67376
67377
67378

67379
67380
67381
67382
67383
67384
67385
67386
67387
67388
67389
67390
67391
67392
67393
67394
67395
67396
67397















67398
67399

67400
67401

67402
67403
67404
67405
67406
67407
67408


67409
67410
67411
67412
67413
67414
67415
67444
67445
67446
67447
67448
67449
67450

67451
67452
67453
67454
67455
67456
67457
67458

67459
67460
67461

67462
67463
67464
67465
67466
67467
67468





67469
67470
67471
67472
67473
67474
67475



67476
67477
67478
67479

67480
67481
67482
67483

67484
67485

67486
67487




67488
67489
67490
67491
67492

67493
67494
67495

67496
67497

67498
67499
67500
67501
67502


67503
67504
67505
67506

67507
67508
67509
67510
67511
67512
67513
67514
67515
67516
67517
67518
67519
67520
67521
67522
67523
67524
67525
67526
67527

67528
67529
67530
67531
67532

67533
67534
67535
67536
67537















67538
67539
67540
67541
67542
67543
67544
67545
67546
67547
67548
67549
67550
67551
67552
67553

67554
67555

67556
67557
67558
67559
67560
67561


67562
67563
67564
67565
67566
67567
67568
67569
67570







-
+







-
+


-
+






-
-
-
-
-
+
+
+
+
+


-
-
-
+
+
+

-
+



-
+

-
+

-
-
-
-
+
+
+
+

-
+


-
+

-
+




-
-
+
+


-
+




















-
+




-
+




-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+

-
+





-
-
+
+







** to instruction P2. Otherwise, the rowid of the conflicting index
** entry is copied to register P3 and control falls through to the next
** instruction.
**
** See also: NotFound, NotExists, Found
*/
case OP_IsUnique: {        /* jump, in3 */
#if 0  /* local variables moved into u.be */
#if 0  /* local variables moved into u.bf */
  u16 ii;
  VdbeCursor *pCx;
  BtCursor *pCrsr;
  u16 nField;
  Mem *aMx;
  UnpackedRecord r;                  /* B-Tree index search key */
  i64 R;                             /* Rowid stored in register P3 */
#endif /* local variables moved into u.be */
#endif /* local variables moved into u.bf */

  pIn3 = &aMem[pOp->p3];
  u.be.aMx = &aMem[pOp->p4.i];
  u.bf.aMx = &aMem[pOp->p4.i];
  /* Assert that the values of parameters P1 and P4 are in range. */
  assert( pOp->p4type==P4_INT32 );
  assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );

  /* Find the index cursor. */
  u.be.pCx = p->apCsr[pOp->p1];
  assert( u.be.pCx->deferredMoveto==0 );
  u.be.pCx->seekResult = 0;
  u.be.pCx->cacheStatus = CACHE_STALE;
  u.be.pCrsr = u.be.pCx->pCursor;
  u.bf.pCx = p->apCsr[pOp->p1];
  assert( u.bf.pCx->deferredMoveto==0 );
  u.bf.pCx->seekResult = 0;
  u.bf.pCx->cacheStatus = CACHE_STALE;
  u.bf.pCrsr = u.bf.pCx->pCursor;

  /* If any of the values are NULL, take the jump. */
  u.be.nField = u.be.pCx->pKeyInfo->nField;
  for(u.be.ii=0; u.be.ii<u.be.nField; u.be.ii++){
    if( u.be.aMx[u.be.ii].flags & MEM_Null ){
  u.bf.nField = u.bf.pCx->pKeyInfo->nField;
  for(u.bf.ii=0; u.bf.ii<u.bf.nField; u.bf.ii++){
    if( u.bf.aMx[u.bf.ii].flags & MEM_Null ){
      pc = pOp->p2 - 1;
      u.be.pCrsr = 0;
      u.bf.pCrsr = 0;
      break;
    }
  }
  assert( (u.be.aMx[u.be.nField].flags & MEM_Null)==0 );
  assert( (u.bf.aMx[u.bf.nField].flags & MEM_Null)==0 );

  if( u.be.pCrsr!=0 ){
  if( u.bf.pCrsr!=0 ){
    /* Populate the index search key. */
    u.be.r.pKeyInfo = u.be.pCx->pKeyInfo;
    u.be.r.nField = u.be.nField + 1;
    u.be.r.flags = UNPACKED_PREFIX_SEARCH;
    u.be.r.aMem = u.be.aMx;
    u.bf.r.pKeyInfo = u.bf.pCx->pKeyInfo;
    u.bf.r.nField = u.bf.nField + 1;
    u.bf.r.flags = UNPACKED_PREFIX_SEARCH;
    u.bf.r.aMem = u.bf.aMx;
#ifdef SQLITE_DEBUG
    { int i; for(i=0; i<u.be.r.nField; i++) assert( memIsValid(&u.be.r.aMem[i]) ); }
    { int i; for(i=0; i<u.bf.r.nField; i++) assert( memIsValid(&u.bf.r.aMem[i]) ); }
#endif

    /* Extract the value of u.be.R from register P3. */
    /* Extract the value of u.bf.R from register P3. */
    sqlite3VdbeMemIntegerify(pIn3);
    u.be.R = pIn3->u.i;
    u.bf.R = pIn3->u.i;

    /* Search the B-Tree index. If no conflicting record is found, jump
    ** to P2. Otherwise, copy the rowid of the conflicting record to
    ** register P3 and fall through to the next instruction.  */
    rc = sqlite3BtreeMovetoUnpacked(u.be.pCrsr, &u.be.r, 0, 0, &u.be.pCx->seekResult);
    if( (u.be.r.flags & UNPACKED_PREFIX_SEARCH) || u.be.r.rowid==u.be.R ){
    rc = sqlite3BtreeMovetoUnpacked(u.bf.pCrsr, &u.bf.r, 0, 0, &u.bf.pCx->seekResult);
    if( (u.bf.r.flags & UNPACKED_PREFIX_SEARCH) || u.bf.r.rowid==u.bf.R ){
      pc = pOp->p2 - 1;
    }else{
      pIn3->u.i = u.be.r.rowid;
      pIn3->u.i = u.bf.r.rowid;
    }
  }
  break;
}

/* Opcode: NotExists P1 P2 P3 * *
**
** 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 */
#if 0  /* local variables moved into u.bf */
#if 0  /* local variables moved into u.bg */
  VdbeCursor *pC;
  BtCursor *pCrsr;
  int res;
  u64 iKey;
#endif /* local variables moved into u.bf */
#endif /* local variables moved into u.bg */

  pIn3 = &aMem[pOp->p3];
  assert( pIn3->flags & MEM_Int );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bf.pC = p->apCsr[pOp->p1];
  assert( u.bf.pC!=0 );
  assert( u.bf.pC->isTable );
  assert( u.bf.pC->pseudoTableReg==0 );
  u.bf.pCrsr = u.bf.pC->pCursor;
  if( ALWAYS(u.bf.pCrsr!=0) ){
    u.bf.res = 0;
    u.bf.iKey = pIn3->u.i;
    rc = sqlite3BtreeMovetoUnpacked(u.bf.pCrsr, 0, u.bf.iKey, 0, &u.bf.res);
    u.bf.pC->lastRowid = pIn3->u.i;
    u.bf.pC->rowidIsValid = u.bf.res==0 ?1:0;
    u.bf.pC->nullRow = 0;
    u.bf.pC->cacheStatus = CACHE_STALE;
    u.bf.pC->deferredMoveto = 0;
    if( u.bf.res!=0 ){
  u.bg.pC = p->apCsr[pOp->p1];
  assert( u.bg.pC!=0 );
  assert( u.bg.pC->isTable );
  assert( u.bg.pC->pseudoTableReg==0 );
  u.bg.pCrsr = u.bg.pC->pCursor;
  if( ALWAYS(u.bg.pCrsr!=0) ){
    u.bg.res = 0;
    u.bg.iKey = pIn3->u.i;
    rc = sqlite3BtreeMovetoUnpacked(u.bg.pCrsr, 0, u.bg.iKey, 0, &u.bg.res);
    u.bg.pC->lastRowid = pIn3->u.i;
    u.bg.pC->rowidIsValid = u.bg.res==0 ?1:0;
    u.bg.pC->nullRow = 0;
    u.bg.pC->cacheStatus = CACHE_STALE;
    u.bg.pC->deferredMoveto = 0;
    if( u.bg.res!=0 ){
      pc = pOp->p2 - 1;
      assert( u.bf.pC->rowidIsValid==0 );
      assert( u.bg.pC->rowidIsValid==0 );
    }
    u.bf.pC->seekResult = u.bf.res;
    u.bg.pC->seekResult = u.bg.res;
  }else{
    /* This happens when an attempt to open a read cursor on the
    ** sqlite_master table returns SQLITE_EMPTY.
    */
    pc = pOp->p2 - 1;
    assert( u.bf.pC->rowidIsValid==0 );
    u.bf.pC->seekResult = 0;
    assert( u.bg.pC->rowidIsValid==0 );
    u.bg.pC->seekResult = 0;
  }
  break;
}

/* Opcode: Sequence P1 P2 * * *
**
** Find the next available sequence number for cursor P1.
67436
67437
67438
67439
67440
67441
67442
67443

67444
67445
67446
67447
67448
67449
67450

67451
67452
67453


67454
67455
67456
67457



67458
67459
67460
67461
67462
67463
67464
67465
67466
67467
67468
67469
67470
67471
67472
67473

67474
67475
67476
67477
67478
67479
67480
67481
67482
67483
67484
67485
67486
67487
67488




67489
67490
67491
67492
67493


67494
67495
67496


67497
67498
67499


67500
67501

67502
67503
67504
67505
67506
67507
67508
67509
67510
67511

67512
67513
67514


67515
67516
67517
67518
67519


67520
67521

67522
67523
67524
67525
67526




67527
67528
67529
67530
67531


67532
67533

67534
67535
67536
67537

67538
67539

67540
67541
67542
67543
67544
67545
67546
67547
67548
67549
67550
67551
67552
67553
67554








67555
67556
67557


67558
67559

67560
67561

67562
67563

67564
67565

67566
67567
67568
67569

67570
67571
67572
67573



67574
67575

67576
67577
67578
67579
67580
67581
67582
67591
67592
67593
67594
67595
67596
67597

67598
67599
67600
67601
67602
67603
67604

67605
67606


67607
67608
67609



67610
67611
67612
67613
67614
67615
67616
67617
67618
67619
67620
67621
67622
67623
67624
67625
67626
67627

67628
67629
67630
67631
67632
67633
67634
67635
67636
67637
67638
67639




67640
67641
67642
67643
67644
67645
67646


67647
67648
67649


67650
67651
67652


67653
67654
67655

67656
67657
67658
67659
67660
67661
67662
67663
67664
67665

67666
67667


67668
67669
67670
67671
67672


67673
67674
67675

67676
67677




67678
67679
67680
67681
67682
67683
67684


67685
67686
67687

67688
67689
67690
67691

67692
67693

67694
67695
67696
67697
67698
67699
67700
67701








67702
67703
67704
67705
67706
67707
67708
67709
67710


67711
67712
67713

67714
67715

67716
67717

67718
67719

67720
67721
67722
67723

67724
67725



67726
67727
67728
67729

67730
67731
67732
67733
67734
67735
67736
67737







-
+






-
+

-
-
+
+

-
-
-
+
+
+















-
+











-
-
-
-
+
+
+
+



-
-
+
+

-
-
+
+

-
-
+
+

-
+









-
+

-
-
+
+



-
-
+
+

-
+

-
-
-
-
+
+
+
+



-
-
+
+

-
+



-
+

-
+







-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+

-
-
+
+

-
+

-
+

-
+

-
+



-
+

-
-
-
+
+
+

-
+







** the largest previously generated record number. No new record numbers are
** allowed to be less than this value. When this value reaches its maximum, 
** an SQLITE_FULL error is generated. The P3 register is updated with the '
** generated record number. This P3 mechanism is used to help implement the
** AUTOINCREMENT feature.
*/
case OP_NewRowid: {           /* out2-prerelease */
#if 0  /* local variables moved into u.bg */
#if 0  /* local variables moved into u.bh */
  i64 v;                 /* The new rowid */
  VdbeCursor *pC;        /* Cursor of table to get the new rowid */
  int res;               /* Result of an sqlite3BtreeLast() */
  int cnt;               /* Counter to limit the number of searches */
  Mem *pMem;             /* Register holding largest rowid for AUTOINCREMENT */
  VdbeFrame *pFrame;     /* Root frame of VDBE */
#endif /* local variables moved into u.bg */
#endif /* local variables moved into u.bh */

  u.bg.v = 0;
  u.bg.res = 0;
  u.bh.v = 0;
  u.bh.res = 0;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bg.pC = p->apCsr[pOp->p1];
  assert( u.bg.pC!=0 );
  if( NEVER(u.bg.pC->pCursor==0) ){
  u.bh.pC = p->apCsr[pOp->p1];
  assert( u.bh.pC!=0 );
  if( NEVER(u.bh.pC->pCursor==0) ){
    /* The zero initialization above is all that is needed */
  }else{
    /* The next rowid or record number (different terms for the same
    ** thing) is obtained in a two-step algorithm.
    **
    ** First we attempt to find the largest existing rowid and add one
    ** to that.  But if the largest existing rowid is already the maximum
    ** positive integer, we have to fall through to the second
    ** probabilistic algorithm
    **
    ** The second algorithm is to select a rowid at random and see if
    ** it already exists in the table.  If it does not exist, we have
    ** succeeded.  If the random rowid does exist, we select a new one
    ** and try again, up to 100 times.
    */
    assert( u.bg.pC->isTable );
    assert( u.bh.pC->isTable );

#ifdef SQLITE_32BIT_ROWID
#   define MAX_ROWID 0x7fffffff
#else
    /* Some compilers complain about constants of the form 0x7fffffffffffffff.
    ** Others complain about 0x7ffffffffffffffffLL.  The following macro seems
    ** to provide the constant while making all compilers happy.
    */
#   define MAX_ROWID  (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff )
#endif

    if( !u.bg.pC->useRandomRowid ){
      u.bg.v = sqlite3BtreeGetCachedRowid(u.bg.pC->pCursor);
      if( u.bg.v==0 ){
        rc = sqlite3BtreeLast(u.bg.pC->pCursor, &u.bg.res);
    if( !u.bh.pC->useRandomRowid ){
      u.bh.v = sqlite3BtreeGetCachedRowid(u.bh.pC->pCursor);
      if( u.bh.v==0 ){
        rc = sqlite3BtreeLast(u.bh.pC->pCursor, &u.bh.res);
        if( rc!=SQLITE_OK ){
          goto abort_due_to_error;
        }
        if( u.bg.res ){
          u.bg.v = 1;   /* IMP: R-61914-48074 */
        if( u.bh.res ){
          u.bh.v = 1;   /* IMP: R-61914-48074 */
        }else{
          assert( sqlite3BtreeCursorIsValid(u.bg.pC->pCursor) );
          rc = sqlite3BtreeKeySize(u.bg.pC->pCursor, &u.bg.v);
          assert( sqlite3BtreeCursorIsValid(u.bh.pC->pCursor) );
          rc = sqlite3BtreeKeySize(u.bh.pC->pCursor, &u.bh.v);
          assert( rc==SQLITE_OK );   /* Cannot fail following BtreeLast() */
          if( u.bg.v>=MAX_ROWID ){
            u.bg.pC->useRandomRowid = 1;
          if( u.bh.v>=MAX_ROWID ){
            u.bh.pC->useRandomRowid = 1;
          }else{
            u.bg.v++;   /* IMP: R-29538-34987 */
            u.bh.v++;   /* IMP: R-29538-34987 */
          }
        }
      }

#ifndef SQLITE_OMIT_AUTOINCREMENT
      if( pOp->p3 ){
        /* Assert that P3 is a valid memory cell. */
        assert( pOp->p3>0 );
        if( p->pFrame ){
          for(u.bg.pFrame=p->pFrame; u.bg.pFrame->pParent; u.bg.pFrame=u.bg.pFrame->pParent);
          for(u.bh.pFrame=p->pFrame; u.bh.pFrame->pParent; u.bh.pFrame=u.bh.pFrame->pParent);
          /* Assert that P3 is a valid memory cell. */
          assert( pOp->p3<=u.bg.pFrame->nMem );
          u.bg.pMem = &u.bg.pFrame->aMem[pOp->p3];
          assert( pOp->p3<=u.bh.pFrame->nMem );
          u.bh.pMem = &u.bh.pFrame->aMem[pOp->p3];
        }else{
          /* Assert that P3 is a valid memory cell. */
          assert( pOp->p3<=p->nMem );
          u.bg.pMem = &aMem[pOp->p3];
          memAboutToChange(p, u.bg.pMem);
          u.bh.pMem = &aMem[pOp->p3];
          memAboutToChange(p, u.bh.pMem);
        }
        assert( memIsValid(u.bg.pMem) );
        assert( memIsValid(u.bh.pMem) );

        REGISTER_TRACE(pOp->p3, u.bg.pMem);
        sqlite3VdbeMemIntegerify(u.bg.pMem);
        assert( (u.bg.pMem->flags & MEM_Int)!=0 );  /* mem(P3) holds an integer */
        if( u.bg.pMem->u.i==MAX_ROWID || u.bg.pC->useRandomRowid ){
        REGISTER_TRACE(pOp->p3, u.bh.pMem);
        sqlite3VdbeMemIntegerify(u.bh.pMem);
        assert( (u.bh.pMem->flags & MEM_Int)!=0 );  /* mem(P3) holds an integer */
        if( u.bh.pMem->u.i==MAX_ROWID || u.bh.pC->useRandomRowid ){
          rc = SQLITE_FULL;   /* IMP: R-12275-61338 */
          goto abort_due_to_error;
        }
        if( u.bg.v<u.bg.pMem->u.i+1 ){
          u.bg.v = u.bg.pMem->u.i + 1;
        if( u.bh.v<u.bh.pMem->u.i+1 ){
          u.bh.v = u.bh.pMem->u.i + 1;
        }
        u.bg.pMem->u.i = u.bg.v;
        u.bh.pMem->u.i = u.bh.v;
      }
#endif

      sqlite3BtreeSetCachedRowid(u.bg.pC->pCursor, u.bg.v<MAX_ROWID ? u.bg.v+1 : 0);
      sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, u.bh.v<MAX_ROWID ? u.bh.v+1 : 0);
    }
    if( u.bg.pC->useRandomRowid ){
    if( u.bh.pC->useRandomRowid ){
      /* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the
      ** largest possible integer (9223372036854775807) then the database
      ** engine starts picking positive candidate ROWIDs at random until
      ** it finds one that is not previously used. */
      assert( pOp->p3==0 );  /* We cannot be in random rowid mode if this is
                             ** an AUTOINCREMENT table. */
      /* on the first attempt, simply do one more than previous */
      u.bg.v = lastRowid;
      u.bg.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
      u.bg.v++; /* ensure non-zero */
      u.bg.cnt = 0;
      while(   ((rc = sqlite3BtreeMovetoUnpacked(u.bg.pC->pCursor, 0, (u64)u.bg.v,
                                                 0, &u.bg.res))==SQLITE_OK)
            && (u.bg.res==0)
            && (++u.bg.cnt<100)){
      u.bh.v = lastRowid;
      u.bh.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
      u.bh.v++; /* ensure non-zero */
      u.bh.cnt = 0;
      while(   ((rc = sqlite3BtreeMovetoUnpacked(u.bh.pC->pCursor, 0, (u64)u.bh.v,
                                                 0, &u.bh.res))==SQLITE_OK)
            && (u.bh.res==0)
            && (++u.bh.cnt<100)){
        /* collision - try another random rowid */
        sqlite3_randomness(sizeof(u.bg.v), &u.bg.v);
        if( u.bg.cnt<5 ){
        sqlite3_randomness(sizeof(u.bh.v), &u.bh.v);
        if( u.bh.cnt<5 ){
          /* try "small" random rowids for the initial attempts */
          u.bg.v &= 0xffffff;
          u.bh.v &= 0xffffff;
        }else{
          u.bg.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
          u.bh.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
        }
        u.bg.v++; /* ensure non-zero */
        u.bh.v++; /* ensure non-zero */
      }
      if( rc==SQLITE_OK && u.bg.res==0 ){
      if( rc==SQLITE_OK && u.bh.res==0 ){
        rc = SQLITE_FULL;   /* IMP: R-38219-53002 */
        goto abort_due_to_error;
      }
      assert( u.bg.v>0 );  /* EV: R-40812-03570 */
      assert( u.bh.v>0 );  /* EV: R-40812-03570 */
    }
    u.bg.pC->rowidIsValid = 0;
    u.bg.pC->deferredMoveto = 0;
    u.bg.pC->cacheStatus = CACHE_STALE;
    u.bh.pC->rowidIsValid = 0;
    u.bh.pC->deferredMoveto = 0;
    u.bh.pC->cacheStatus = CACHE_STALE;
  }
  pOut->u.i = u.bg.v;
  pOut->u.i = u.bh.v;
  break;
}

/* Opcode: Insert P1 P2 P3 P4 P5
**
** Write an entry into the table of cursor P1.  A new entry is
** created if it doesn't already exist or the data for an existing
67618
67619
67620
67621
67622
67623
67624
67625

67626
67627
67628
67629
67630
67631
67632
67633
67634
67635

67636
67637

67638
67639
67640
67641
67642
67643
67644
67645







67646
67647
67648
67649
67650
67651
67652





67653
67654
67655

67656
67657
67658
67659
67660
67661
67662




67663
67664

67665
67666
67667
67668



67669
67670

67671
67672
67673
67674
67675




67676
67677
67678
67679



67680
67681
67682
67683
67684
67685
67686
67687
67688






67689
67690
67691
67692
67693
67694
67695
67773
67774
67775
67776
67777
67778
67779

67780
67781
67782
67783
67784
67785
67786
67787
67788
67789

67790
67791

67792
67793







67794
67795
67796
67797
67798
67799
67800
67801
67802





67803
67804
67805
67806
67807
67808
67809

67810
67811
67812
67813




67814
67815
67816
67817
67818

67819
67820



67821
67822
67823
67824

67825
67826




67827
67828
67829
67830
67831



67832
67833
67834
67835
67836
67837






67838
67839
67840
67841
67842
67843
67844
67845
67846
67847
67848
67849
67850







-
+









-
+

-
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+


-
-
-
-
-
+
+
+
+
+


-
+



-
-
-
-
+
+
+
+

-
+

-
-
-
+
+
+

-
+

-
-
-
-
+
+
+
+

-
-
-
+
+
+



-
-
-
-
-
-
+
+
+
+
+
+







/* Opcode: InsertInt P1 P2 P3 P4 P5
**
** This works exactly like OP_Insert except that the key is the
** integer value P3, not the value of the integer stored in register P3.
*/
case OP_Insert: 
case OP_InsertInt: {
#if 0  /* local variables moved into u.bh */
#if 0  /* local variables moved into u.bi */
  Mem *pData;       /* MEM cell holding data for the record to be inserted */
  Mem *pKey;        /* MEM cell holding key  for the record */
  i64 iKey;         /* The integer ROWID or key for the record to be inserted */
  VdbeCursor *pC;   /* Cursor to table into which insert is written */
  int nZero;        /* Number of zero-bytes to append */
  int seekResult;   /* Result of prior seek or 0 if no USESEEKRESULT flag */
  const char *zDb;  /* database name - used by the update hook */
  const char *zTbl; /* Table name - used by the opdate hook */
  int op;           /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
#endif /* local variables moved into u.bh */
#endif /* local variables moved into u.bi */

  u.bh.pData = &aMem[pOp->p2];
  u.bi.pData = &aMem[pOp->p2];
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( memIsValid(u.bh.pData) );
  u.bh.pC = p->apCsr[pOp->p1];
  assert( u.bh.pC!=0 );
  assert( u.bh.pC->pCursor!=0 );
  assert( u.bh.pC->pseudoTableReg==0 );
  assert( u.bh.pC->isTable );
  REGISTER_TRACE(pOp->p2, u.bh.pData);
  assert( memIsValid(u.bi.pData) );
  u.bi.pC = p->apCsr[pOp->p1];
  assert( u.bi.pC!=0 );
  assert( u.bi.pC->pCursor!=0 );
  assert( u.bi.pC->pseudoTableReg==0 );
  assert( u.bi.pC->isTable );
  REGISTER_TRACE(pOp->p2, u.bi.pData);

  if( pOp->opcode==OP_Insert ){
    u.bh.pKey = &aMem[pOp->p3];
    assert( u.bh.pKey->flags & MEM_Int );
    assert( memIsValid(u.bh.pKey) );
    REGISTER_TRACE(pOp->p3, u.bh.pKey);
    u.bh.iKey = u.bh.pKey->u.i;
    u.bi.pKey = &aMem[pOp->p3];
    assert( u.bi.pKey->flags & MEM_Int );
    assert( memIsValid(u.bi.pKey) );
    REGISTER_TRACE(pOp->p3, u.bi.pKey);
    u.bi.iKey = u.bi.pKey->u.i;
  }else{
    assert( pOp->opcode==OP_InsertInt );
    u.bh.iKey = pOp->p3;
    u.bi.iKey = pOp->p3;
  }

  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = u.bh.iKey;
  if( u.bh.pData->flags & MEM_Null ){
    u.bh.pData->z = 0;
    u.bh.pData->n = 0;
  if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = u.bi.iKey;
  if( u.bi.pData->flags & MEM_Null ){
    u.bi.pData->z = 0;
    u.bi.pData->n = 0;
  }else{
    assert( u.bh.pData->flags & (MEM_Blob|MEM_Str) );
    assert( u.bi.pData->flags & (MEM_Blob|MEM_Str) );
  }
  u.bh.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bh.pC->seekResult : 0);
  if( u.bh.pData->flags & MEM_Zero ){
    u.bh.nZero = u.bh.pData->u.nZero;
  u.bi.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bi.pC->seekResult : 0);
  if( u.bi.pData->flags & MEM_Zero ){
    u.bi.nZero = u.bi.pData->u.nZero;
  }else{
    u.bh.nZero = 0;
    u.bi.nZero = 0;
  }
  sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, 0);
  rc = sqlite3BtreeInsert(u.bh.pC->pCursor, 0, u.bh.iKey,
                          u.bh.pData->z, u.bh.pData->n, u.bh.nZero,
                          pOp->p5 & OPFLAG_APPEND, u.bh.seekResult
  sqlite3BtreeSetCachedRowid(u.bi.pC->pCursor, 0);
  rc = sqlite3BtreeInsert(u.bi.pC->pCursor, 0, u.bi.iKey,
                          u.bi.pData->z, u.bi.pData->n, u.bi.nZero,
                          pOp->p5 & OPFLAG_APPEND, u.bi.seekResult
  );
  u.bh.pC->rowidIsValid = 0;
  u.bh.pC->deferredMoveto = 0;
  u.bh.pC->cacheStatus = CACHE_STALE;
  u.bi.pC->rowidIsValid = 0;
  u.bi.pC->deferredMoveto = 0;
  u.bi.pC->cacheStatus = CACHE_STALE;

  /* Invoke the update-hook if required. */
  if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
    u.bh.zDb = db->aDb[u.bh.pC->iDb].zName;
    u.bh.zTbl = pOp->p4.z;
    u.bh.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
    assert( u.bh.pC->isTable );
    db->xUpdateCallback(db->pUpdateArg, u.bh.op, u.bh.zDb, u.bh.zTbl, u.bh.iKey);
    assert( u.bh.pC->iDb>=0 );
    u.bi.zDb = db->aDb[u.bi.pC->iDb].zName;
    u.bi.zTbl = pOp->p4.z;
    u.bi.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
    assert( u.bi.pC->isTable );
    db->xUpdateCallback(db->pUpdateArg, u.bi.op, u.bi.zDb, u.bi.zTbl, u.bi.iKey);
    assert( u.bi.pC->iDb>=0 );
  }
  break;
}

/* Opcode: Delete P1 P2 * P4 *
**
** Delete the record at which the P1 cursor is currently pointing.
67707
67708
67709
67710
67711
67712
67713
67714

67715
67716
67717

67718
67719

67720
67721
67722
67723



67724
67725

67726
67727
67728
67729
67730
67731



67732
67733
67734
67735
67736

67737
67738
67739
67740
67741
67742


67743
67744
67745
67746
67747



67748
67749
67750
67751

67752
67753
67754


67755
67756
67757
67758
67759
67760
67761
67862
67863
67864
67865
67866
67867
67868

67869
67870
67871

67872
67873

67874
67875



67876
67877
67878
67879

67880
67881
67882
67883



67884
67885
67886
67887
67888
67889
67890

67891
67892
67893
67894
67895


67896
67897
67898
67899



67900
67901
67902
67903
67904
67905

67906
67907


67908
67909
67910
67911
67912
67913
67914
67915
67916







-
+


-
+

-
+

-
-
-
+
+
+

-
+



-
-
-
+
+
+




-
+




-
-
+
+


-
-
-
+
+
+



-
+

-
-
+
+







**
** If P4 is not NULL, then it is the name of the table that P1 is
** pointing to.  The update hook will be invoked, if it exists.
** If P4 is not NULL then the P1 cursor must have been positioned
** using OP_NotFound prior to invoking this opcode.
*/
case OP_Delete: {
#if 0  /* local variables moved into u.bi */
#if 0  /* local variables moved into u.bj */
  i64 iKey;
  VdbeCursor *pC;
#endif /* local variables moved into u.bi */
#endif /* local variables moved into u.bj */

  u.bi.iKey = 0;
  u.bj.iKey = 0;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bi.pC = p->apCsr[pOp->p1];
  assert( u.bi.pC!=0 );
  assert( u.bi.pC->pCursor!=0 );  /* Only valid for real tables, no pseudotables */
  u.bj.pC = p->apCsr[pOp->p1];
  assert( u.bj.pC!=0 );
  assert( u.bj.pC->pCursor!=0 );  /* Only valid for real tables, no pseudotables */

  /* If the update-hook will be invoked, set u.bi.iKey to the rowid of the
  /* If the update-hook will be invoked, set u.bj.iKey to the rowid of the
  ** row being deleted.
  */
  if( db->xUpdateCallback && pOp->p4.z ){
    assert( u.bi.pC->isTable );
    assert( u.bi.pC->rowidIsValid );  /* lastRowid set by previous OP_NotFound */
    u.bi.iKey = u.bi.pC->lastRowid;
    assert( u.bj.pC->isTable );
    assert( u.bj.pC->rowidIsValid );  /* lastRowid set by previous OP_NotFound */
    u.bj.iKey = u.bj.pC->lastRowid;
  }

  /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or
  ** OP_Column on the same table without any intervening operations that
  ** might move or invalidate the cursor.  Hence cursor u.bi.pC is always pointing
  ** might move or invalidate the cursor.  Hence cursor u.bj.pC is always pointing
  ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation
  ** below is always a no-op and cannot fail.  We will run it anyhow, though,
  ** to guard against future changes to the code generator.
  **/
  assert( u.bi.pC->deferredMoveto==0 );
  rc = sqlite3VdbeCursorMoveto(u.bi.pC);
  assert( u.bj.pC->deferredMoveto==0 );
  rc = sqlite3VdbeCursorMoveto(u.bj.pC);
  if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;

  sqlite3BtreeSetCachedRowid(u.bi.pC->pCursor, 0);
  rc = sqlite3BtreeDelete(u.bi.pC->pCursor);
  u.bi.pC->cacheStatus = CACHE_STALE;
  sqlite3BtreeSetCachedRowid(u.bj.pC->pCursor, 0);
  rc = sqlite3BtreeDelete(u.bj.pC->pCursor);
  u.bj.pC->cacheStatus = CACHE_STALE;

  /* Invoke the update-hook if required. */
  if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
    const char *zDb = db->aDb[u.bi.pC->iDb].zName;
    const char *zDb = db->aDb[u.bj.pC->iDb].zName;
    const char *zTbl = pOp->p4.z;
    db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bi.iKey);
    assert( u.bi.pC->iDb>=0 );
    db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bj.iKey);
    assert( u.bj.pC->iDb>=0 );
  }
  if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
  break;
}
/* Opcode: ResetCount * * * * *
**
** The value of the change counter is copied to the database handle
67773
67774
67775
67776
67777
67778
67779
67780

67781
67782
67783

67784
67785
67786


67787
67788
67789


67790
67791
67792
67793
67794
67795
67796
67797
67798
67799
67800

67801
67802

67803
67804
67805
67806
67807
67808



67809
67810
67811
67812
67813
67814
67815
67928
67929
67930
67931
67932
67933
67934

67935
67936
67937

67938
67939


67940
67941
67942


67943
67944
67945
67946
67947
67948
67949
67950
67951
67952
67953
67954

67955
67956

67957
67958
67959
67960



67961
67962
67963
67964
67965
67966
67967
67968
67969
67970







-
+


-
+

-
-
+
+

-
-
+
+










-
+

-
+



-
-
-
+
+
+







**
** P1 is a sorter cursor. This instruction compares the record blob in 
** register P3 with the entry that the sorter cursor currently points to.
** If, excluding the rowid fields at the end, the two records are a match,
** fall through to the next instruction. Otherwise, jump to instruction P2.
*/
case OP_SorterCompare: {
#if 0  /* local variables moved into u.bj */
#if 0  /* local variables moved into u.bk */
  VdbeCursor *pC;
  int res;
#endif /* local variables moved into u.bj */
#endif /* local variables moved into u.bk */

  u.bj.pC = p->apCsr[pOp->p1];
  assert( isSorter(u.bj.pC) );
  u.bk.pC = p->apCsr[pOp->p1];
  assert( isSorter(u.bk.pC) );
  pIn3 = &aMem[pOp->p3];
  rc = sqlite3VdbeSorterCompare(u.bj.pC, pIn3, &u.bj.res);
  if( u.bj.res ){
  rc = sqlite3VdbeSorterCompare(u.bk.pC, pIn3, &u.bk.res);
  if( u.bk.res ){
    pc = pOp->p2-1;
  }
  break;
};

/* Opcode: SorterData P1 P2 * * *
**
** Write into register P2 the current sorter data for sorter cursor P1.
*/
case OP_SorterData: {
#if 0  /* local variables moved into u.bk */
#if 0  /* local variables moved into u.bl */
  VdbeCursor *pC;
#endif /* local variables moved into u.bk */
#endif /* local variables moved into u.bl */

#ifndef SQLITE_OMIT_MERGE_SORT
  pOut = &aMem[pOp->p2];
  u.bk.pC = p->apCsr[pOp->p1];
  assert( u.bk.pC->isSorter );
  rc = sqlite3VdbeSorterRowkey(u.bk.pC, pOut);
  u.bl.pC = p->apCsr[pOp->p1];
  assert( u.bl.pC->isSorter );
  rc = sqlite3VdbeSorterRowkey(u.bl.pC, pOut);
#else
  pOp->opcode = OP_RowKey;
  pc--;
#endif
  break;
}

67831
67832
67833
67834
67835
67836
67837
67838

67839
67840
67841
67842
67843

67844
67845
67846
67847
67848
67849
67850
67851
67852
67853
67854
67855
67856
67857
67858
67859










67860
67861
67862
67863
67864
67865
67866
67867


67868
67869
67870
67871
67872



67873
67874

67875
67876
67877

67878
67879

67880
67881

67882
67883
67884
67885

67886
67887
67888

67889
67890
67891


67892
67893

67894
67895
67896
67897
67898
67899
67900
67901
67902
67903
67904
67905
67906
67907
67908
67909
67910

67911
67912
67913
67914
67915

67916
67917
67918
67919
67920
67921




67922
67923
67924
67925


67926
67927
67928
67929
67930
67931
67932






67933
67934
67935
67936


67937
67938
67939


67940
67941

67942
67943
67944
67945

67946
67947
67948
67949
67950
67951
67952
67953
67954
67955
67956

67957
67958

67959
67960
67961
67962
67963
67964
67965
67966
67967







67968
67969
67970
67971
67972
67973
67974
67975
67976
67977
67978
67979
67980
67981

67982
67983
67984
67985

67986
67987
67988
67989
67990
67991
67992
67993






67994
67995
67996
67997
67998
67999





68000
68001
68002
68003
68004
68005
68006
67986
67987
67988
67989
67990
67991
67992

67993
67994
67995
67996
67997

67998
67999
68000
68001
68002
68003
68004










68005
68006
68007
68008
68009
68010
68011
68012
68013
68014
68015
68016
68017
68018
68019
68020


68021
68022
68023
68024



68025
68026
68027
68028

68029
68030
68031

68032
68033

68034
68035

68036
68037
68038
68039

68040
68041
68042

68043
68044


68045
68046
68047

68048
68049
68050
68051
68052
68053
68054
68055
68056
68057
68058
68059
68060
68061
68062
68063
68064

68065
68066
68067
68068
68069

68070
68071
68072




68073
68074
68075
68076
68077
68078


68079
68080
68081






68082
68083
68084
68085
68086
68087
68088
68089


68090
68091
68092


68093
68094
68095

68096
68097
68098
68099

68100
68101
68102
68103
68104
68105
68106
68107
68108
68109
68110

68111
68112

68113
68114
68115







68116
68117
68118
68119
68120
68121
68122
68123
68124
68125
68126
68127
68128
68129
68130
68131
68132
68133
68134
68135

68136
68137
68138
68139

68140
68141
68142






68143
68144
68145
68146
68147
68148
68149





68150
68151
68152
68153
68154
68155
68156
68157
68158
68159
68160
68161







-
+




-
+






-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+






-
-
+
+


-
-
-
+
+
+

-
+


-
+

-
+

-
+



-
+


-
+

-
-
+
+

-
+
















-
+




-
+


-
-
-
-
+
+
+
+


-
-
+
+

-
-
-
-
-
-
+
+
+
+
+
+


-
-
+
+

-
-
+
+

-
+



-
+










-
+

-
+


-
-
-
-
-
-
-
+
+
+
+
+
+
+













-
+



-
+


-
-
-
-
-
-
+
+
+
+
+
+

-
-
-
-
-
+
+
+
+
+







** it is found in the database file.
**
** If the P1 cursor must be pointing to a valid row (not a NULL row)
** of a real table, not a pseudo-table.
*/
case OP_RowKey:
case OP_RowData: {
#if 0  /* local variables moved into u.bl */
#if 0  /* local variables moved into u.bm */
  VdbeCursor *pC;
  BtCursor *pCrsr;
  u32 n;
  i64 n64;
#endif /* local variables moved into u.bl */
#endif /* local variables moved into u.bm */

  pOut = &aMem[pOp->p2];
  memAboutToChange(p, pOut);

  /* Note that RowKey and RowData are really exactly the same instruction */
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bl.pC = p->apCsr[pOp->p1];
  assert( u.bl.pC->isSorter==0 );
  assert( u.bl.pC->isTable || pOp->opcode!=OP_RowData );
  assert( u.bl.pC->isIndex || pOp->opcode==OP_RowData );
  assert( u.bl.pC!=0 );
  assert( u.bl.pC->nullRow==0 );
  assert( u.bl.pC->pseudoTableReg==0 );
  assert( u.bl.pC->pCursor!=0 );
  u.bl.pCrsr = u.bl.pC->pCursor;
  assert( sqlite3BtreeCursorIsValid(u.bl.pCrsr) );
  u.bm.pC = p->apCsr[pOp->p1];
  assert( u.bm.pC->isSorter==0 );
  assert( u.bm.pC->isTable || pOp->opcode!=OP_RowData );
  assert( u.bm.pC->isIndex || pOp->opcode==OP_RowData );
  assert( u.bm.pC!=0 );
  assert( u.bm.pC->nullRow==0 );
  assert( u.bm.pC->pseudoTableReg==0 );
  assert( u.bm.pC->pCursor!=0 );
  u.bm.pCrsr = u.bm.pC->pCursor;
  assert( sqlite3BtreeCursorIsValid(u.bm.pCrsr) );

  /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
  ** OP_Rewind/Op_Next with no intervening instructions that might invalidate
  ** the cursor.  Hence the following sqlite3VdbeCursorMoveto() call is always
  ** a no-op and can never fail.  But we leave it in place as a safety.
  */
  assert( u.bl.pC->deferredMoveto==0 );
  rc = sqlite3VdbeCursorMoveto(u.bl.pC);
  assert( u.bm.pC->deferredMoveto==0 );
  rc = sqlite3VdbeCursorMoveto(u.bm.pC);
  if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;

  if( u.bl.pC->isIndex ){
    assert( !u.bl.pC->isTable );
    VVA_ONLY(rc =) sqlite3BtreeKeySize(u.bl.pCrsr, &u.bl.n64);
  if( u.bm.pC->isIndex ){
    assert( !u.bm.pC->isTable );
    VVA_ONLY(rc =) sqlite3BtreeKeySize(u.bm.pCrsr, &u.bm.n64);
    assert( rc==SQLITE_OK );    /* True because of CursorMoveto() call above */
    if( u.bl.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
    if( u.bm.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
      goto too_big;
    }
    u.bl.n = (u32)u.bl.n64;
    u.bm.n = (u32)u.bm.n64;
  }else{
    VVA_ONLY(rc =) sqlite3BtreeDataSize(u.bl.pCrsr, &u.bl.n);
    VVA_ONLY(rc =) sqlite3BtreeDataSize(u.bm.pCrsr, &u.bm.n);
    assert( rc==SQLITE_OK );    /* DataSize() cannot fail */
    if( u.bl.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
    if( u.bm.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
      goto too_big;
    }
  }
  if( sqlite3VdbeMemGrow(pOut, u.bl.n, 0) ){
  if( sqlite3VdbeMemGrow(pOut, u.bm.n, 0) ){
    goto no_mem;
  }
  pOut->n = u.bl.n;
  pOut->n = u.bm.n;
  MemSetTypeFlag(pOut, MEM_Blob);
  if( u.bl.pC->isIndex ){
    rc = sqlite3BtreeKey(u.bl.pCrsr, 0, u.bl.n, pOut->z);
  if( u.bm.pC->isIndex ){
    rc = sqlite3BtreeKey(u.bm.pCrsr, 0, u.bm.n, pOut->z);
  }else{
    rc = sqlite3BtreeData(u.bl.pCrsr, 0, u.bl.n, pOut->z);
    rc = sqlite3BtreeData(u.bm.pCrsr, 0, u.bm.n, pOut->z);
  }
  pOut->enc = SQLITE_UTF8;  /* In case the blob is ever cast to text */
  UPDATE_MAX_BLOBSIZE(pOut);
  break;
}

/* Opcode: Rowid P1 P2 * * *
**
** Store in register P2 an integer which is the key of the table entry that
** P1 is currently point to.
**
** P1 can be either an ordinary table or a virtual table.  There used to
** be a separate OP_VRowid opcode for use with virtual tables, but this
** one opcode now works for both table types.
*/
case OP_Rowid: {                 /* out2-prerelease */
#if 0  /* local variables moved into u.bm */
#if 0  /* local variables moved into u.bn */
  VdbeCursor *pC;
  i64 v;
  sqlite3_vtab *pVtab;
  const sqlite3_module *pModule;
#endif /* local variables moved into u.bm */
#endif /* local variables moved into u.bn */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bm.pC = p->apCsr[pOp->p1];
  assert( u.bm.pC!=0 );
  assert( u.bm.pC->pseudoTableReg==0 );
  if( u.bm.pC->nullRow ){
  u.bn.pC = p->apCsr[pOp->p1];
  assert( u.bn.pC!=0 );
  assert( u.bn.pC->pseudoTableReg==0 );
  if( u.bn.pC->nullRow ){
    pOut->flags = MEM_Null;
    break;
  }else if( u.bm.pC->deferredMoveto ){
    u.bm.v = u.bm.pC->movetoTarget;
  }else if( u.bn.pC->deferredMoveto ){
    u.bn.v = u.bn.pC->movetoTarget;
#ifndef SQLITE_OMIT_VIRTUALTABLE
  }else if( u.bm.pC->pVtabCursor ){
    u.bm.pVtab = u.bm.pC->pVtabCursor->pVtab;
    u.bm.pModule = u.bm.pVtab->pModule;
    assert( u.bm.pModule->xRowid );
    rc = u.bm.pModule->xRowid(u.bm.pC->pVtabCursor, &u.bm.v);
    importVtabErrMsg(p, u.bm.pVtab);
  }else if( u.bn.pC->pVtabCursor ){
    u.bn.pVtab = u.bn.pC->pVtabCursor->pVtab;
    u.bn.pModule = u.bn.pVtab->pModule;
    assert( u.bn.pModule->xRowid );
    rc = u.bn.pModule->xRowid(u.bn.pC->pVtabCursor, &u.bn.v);
    importVtabErrMsg(p, u.bn.pVtab);
#endif /* SQLITE_OMIT_VIRTUALTABLE */
  }else{
    assert( u.bm.pC->pCursor!=0 );
    rc = sqlite3VdbeCursorMoveto(u.bm.pC);
    assert( u.bn.pC->pCursor!=0 );
    rc = sqlite3VdbeCursorMoveto(u.bn.pC);
    if( rc ) goto abort_due_to_error;
    if( u.bm.pC->rowidIsValid ){
      u.bm.v = u.bm.pC->lastRowid;
    if( u.bn.pC->rowidIsValid ){
      u.bn.v = u.bn.pC->lastRowid;
    }else{
      rc = sqlite3BtreeKeySize(u.bm.pC->pCursor, &u.bm.v);
      rc = sqlite3BtreeKeySize(u.bn.pC->pCursor, &u.bn.v);
      assert( rc==SQLITE_OK );  /* Always so because of CursorMoveto() above */
    }
  }
  pOut->u.i = u.bm.v;
  pOut->u.i = u.bn.v;
  break;
}

/* Opcode: NullRow P1 * * * *
**
** Move the cursor P1 to a null row.  Any OP_Column operations
** that occur while the cursor is on the null row will always
** write a NULL.
*/
case OP_NullRow: {
#if 0  /* local variables moved into u.bn */
#if 0  /* local variables moved into u.bo */
  VdbeCursor *pC;
#endif /* local variables moved into u.bn */
#endif /* local variables moved into u.bo */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bn.pC = p->apCsr[pOp->p1];
  assert( u.bn.pC!=0 );
  u.bn.pC->nullRow = 1;
  u.bn.pC->rowidIsValid = 0;
  assert( u.bn.pC->pCursor || u.bn.pC->pVtabCursor );
  if( u.bn.pC->pCursor ){
    sqlite3BtreeClearCursor(u.bn.pC->pCursor);
  u.bo.pC = p->apCsr[pOp->p1];
  assert( u.bo.pC!=0 );
  u.bo.pC->nullRow = 1;
  u.bo.pC->rowidIsValid = 0;
  assert( u.bo.pC->pCursor || u.bo.pC->pVtabCursor );
  if( u.bo.pC->pCursor ){
    sqlite3BtreeClearCursor(u.bo.pC->pCursor);
  }
  break;
}

/* Opcode: Last P1 P2 * * *
**
** The next use of the Rowid or Column or Next instruction for P1 
** will refer to the last entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Last: {        /* jump */
#if 0  /* local variables moved into u.bo */
#if 0  /* local variables moved into u.bp */
  VdbeCursor *pC;
  BtCursor *pCrsr;
  int res;
#endif /* local variables moved into u.bo */
#endif /* local variables moved into u.bp */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bo.pC = p->apCsr[pOp->p1];
  assert( u.bo.pC!=0 );
  u.bo.pCrsr = u.bo.pC->pCursor;
  u.bo.res = 0;
  if( ALWAYS(u.bo.pCrsr!=0) ){
    rc = sqlite3BtreeLast(u.bo.pCrsr, &u.bo.res);
  u.bp.pC = p->apCsr[pOp->p1];
  assert( u.bp.pC!=0 );
  u.bp.pCrsr = u.bp.pC->pCursor;
  u.bp.res = 0;
  if( ALWAYS(u.bp.pCrsr!=0) ){
    rc = sqlite3BtreeLast(u.bp.pCrsr, &u.bp.res);
  }
  u.bo.pC->nullRow = (u8)u.bo.res;
  u.bo.pC->deferredMoveto = 0;
  u.bo.pC->rowidIsValid = 0;
  u.bo.pC->cacheStatus = CACHE_STALE;
  if( pOp->p2>0 && u.bo.res ){
  u.bp.pC->nullRow = (u8)u.bp.res;
  u.bp.pC->deferredMoveto = 0;
  u.bp.pC->rowidIsValid = 0;
  u.bp.pC->cacheStatus = CACHE_STALE;
  if( pOp->p2>0 && u.bp.res ){
    pc = pOp->p2 - 1;
  }
  break;
}


/* Opcode: Sort P1 P2 * * *
68032
68033
68034
68035
68036
68037
68038
68039

68040
68041
68042
68043

68044
68045
68046
68047
68048
68049
68050
68051






68052
68053
68054
68055
68056
68057
68058
68059







68060
68061

68062
68063

68064
68065
68066
68067
68068
68069
68070
68187
68188
68189
68190
68191
68192
68193

68194
68195
68196
68197

68198
68199
68200






68201
68202
68203
68204
68205
68206
68207







68208
68209
68210
68211
68212
68213
68214
68215

68216
68217

68218
68219
68220
68221
68222
68223
68224
68225







-
+



-
+


-
-
-
-
-
-
+
+
+
+
+
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+

-
+

-
+







** The next use of the Rowid or Column or Next instruction for P1 
** will refer to the first entry in the database table or index.
** If the table or index is empty and P2>0, then jump immediately to P2.
** If P2 is 0 or if the table or index is not empty, fall through
** to the following instruction.
*/
case OP_Rewind: {        /* jump */
#if 0  /* local variables moved into u.bp */
#if 0  /* local variables moved into u.bq */
  VdbeCursor *pC;
  BtCursor *pCrsr;
  int res;
#endif /* local variables moved into u.bp */
#endif /* local variables moved into u.bq */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bp.pC = p->apCsr[pOp->p1];
  assert( u.bp.pC!=0 );
  assert( u.bp.pC->isSorter==(pOp->opcode==OP_SorterSort) );
  u.bp.res = 1;
  if( isSorter(u.bp.pC) ){
    rc = sqlite3VdbeSorterRewind(db, u.bp.pC, &u.bp.res);
  u.bq.pC = p->apCsr[pOp->p1];
  assert( u.bq.pC!=0 );
  assert( u.bq.pC->isSorter==(pOp->opcode==OP_SorterSort) );
  u.bq.res = 1;
  if( isSorter(u.bq.pC) ){
    rc = sqlite3VdbeSorterRewind(db, u.bq.pC, &u.bq.res);
  }else{
    u.bp.pCrsr = u.bp.pC->pCursor;
    assert( u.bp.pCrsr );
    rc = sqlite3BtreeFirst(u.bp.pCrsr, &u.bp.res);
    u.bp.pC->atFirst = u.bp.res==0 ?1:0;
    u.bp.pC->deferredMoveto = 0;
    u.bp.pC->cacheStatus = CACHE_STALE;
    u.bp.pC->rowidIsValid = 0;
    u.bq.pCrsr = u.bq.pC->pCursor;
    assert( u.bq.pCrsr );
    rc = sqlite3BtreeFirst(u.bq.pCrsr, &u.bq.res);
    u.bq.pC->atFirst = u.bq.res==0 ?1:0;
    u.bq.pC->deferredMoveto = 0;
    u.bq.pC->cacheStatus = CACHE_STALE;
    u.bq.pC->rowidIsValid = 0;
  }
  u.bp.pC->nullRow = (u8)u.bp.res;
  u.bq.pC->nullRow = (u8)u.bq.res;
  assert( pOp->p2>0 && pOp->p2<p->nOp );
  if( u.bp.res ){
  if( u.bq.res ){
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: Next P1 P2 * P4 P5
**
68100
68101
68102
68103
68104
68105
68106
68107

68108
68109
68110

68111
68112
68113
68114
68115
68116


68117
68118
68119
68120


68121
68122

68123
68124
68125
68126



68127
68128
68129

68130
68131
68132
68133



68134
68135
68136
68137
68138
68139
68140

68141
68142
68143
68144
68145
68146
68147
68148
68149
68150
68151
68152
68153
68154
68155
68156
68157
68158
68159
68160
68161

68162
68163
68164
68165
68166

68167
68168
68169
68170
68171



68172
68173
68174
68175
68176



68177
68178
68179
68180


68181
68182
68183
68184
68185




68186
68187
68188


68189
68190
68191
68192
68193
68194
68195
68196
68197
68198
68199
68200
68201
68202

68203
68204
68205
68206
68207

68208
68209
68210
68211
68212
68213
68214
68215
68216
68217
68218
68219








68220
68221

68222
68223
68224
68225



68226
68227
68228


68229
68230
68231
68232
68233
68234
68235
68236
68237
68238
68239
68240
68241
68242

68243
68244
68245
68246

68247
68248
68249
68250
68251



68252
68253
68254


68255
68256
68257
68258
68259




68260
68261
68262
68263

68264
68265
68266
68267
68268
68269
68270
68255
68256
68257
68258
68259
68260
68261

68262
68263
68264

68265
68266
68267
68268
68269


68270
68271
68272
68273


68274
68275
68276

68277
68278



68279
68280
68281
68282
68283

68284
68285



68286
68287
68288
68289
68290
68291
68292
68293
68294

68295
68296
68297
68298
68299
68300
68301
68302
68303
68304
68305
68306
68307
68308
68309
68310
68311
68312
68313
68314
68315

68316
68317
68318
68319
68320

68321
68322
68323



68324
68325
68326
68327
68328



68329
68330
68331
68332
68333


68334
68335
68336




68337
68338
68339
68340
68341


68342
68343
68344
68345
68346
68347
68348
68349
68350
68351
68352
68353
68354
68355
68356

68357
68358
68359
68360
68361

68362
68363
68364
68365
68366








68367
68368
68369
68370
68371
68372
68373
68374
68375

68376
68377



68378
68379
68380
68381


68382
68383
68384
68385
68386
68387
68388
68389
68390
68391
68392
68393
68394
68395
68396

68397
68398
68399
68400

68401
68402
68403



68404
68405
68406
68407


68408
68409
68410




68411
68412
68413
68414
68415
68416
68417

68418
68419
68420
68421
68422
68423
68424
68425







-
+


-
+




-
-
+
+


-
-
+
+

-
+

-
-
-
+
+
+


-
+

-
-
-
+
+
+






-
+




















-
+




-
+


-
-
-
+
+
+


-
-
-
+
+
+


-
-
+
+

-
-
-
-
+
+
+
+

-
-
+
+













-
+




-
+




-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+

-
+

-
-
-
+
+
+

-
-
+
+













-
+



-
+


-
-
-
+
+
+

-
-
+
+

-
-
-
-
+
+
+
+



-
+







*/
case OP_SorterNext:    /* jump */
#ifdef SQLITE_OMIT_MERGE_SORT
  pOp->opcode = OP_Next;
#endif
case OP_Prev:          /* jump */
case OP_Next: {        /* jump */
#if 0  /* local variables moved into u.bq */
#if 0  /* local variables moved into u.br */
  VdbeCursor *pC;
  int res;
#endif /* local variables moved into u.bq */
#endif /* local variables moved into u.br */

  CHECK_FOR_INTERRUPT;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pOp->p5<=ArraySize(p->aCounter) );
  u.bq.pC = p->apCsr[pOp->p1];
  if( u.bq.pC==0 ){
  u.br.pC = p->apCsr[pOp->p1];
  if( u.br.pC==0 ){
    break;  /* See ticket #2273 */
  }
  assert( u.bq.pC->isSorter==(pOp->opcode==OP_SorterNext) );
  if( isSorter(u.bq.pC) ){
  assert( u.br.pC->isSorter==(pOp->opcode==OP_SorterNext) );
  if( isSorter(u.br.pC) ){
    assert( pOp->opcode==OP_SorterNext );
    rc = sqlite3VdbeSorterNext(db, u.bq.pC, &u.bq.res);
    rc = sqlite3VdbeSorterNext(db, u.br.pC, &u.br.res);
  }else{
    u.bq.res = 1;
    assert( u.bq.pC->deferredMoveto==0 );
    assert( u.bq.pC->pCursor );
    u.br.res = 1;
    assert( u.br.pC->deferredMoveto==0 );
    assert( u.br.pC->pCursor );
    assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
    assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
    rc = pOp->p4.xAdvance(u.bq.pC->pCursor, &u.bq.res);
    rc = pOp->p4.xAdvance(u.br.pC->pCursor, &u.br.res);
  }
  u.bq.pC->nullRow = (u8)u.bq.res;
  u.bq.pC->cacheStatus = CACHE_STALE;
  if( u.bq.res==0 ){
  u.br.pC->nullRow = (u8)u.br.res;
  u.br.pC->cacheStatus = CACHE_STALE;
  if( u.br.res==0 ){
    pc = pOp->p2 - 1;
    if( pOp->p5 ) p->aCounter[pOp->p5-1]++;
#ifdef SQLITE_TEST
    sqlite3_search_count++;
#endif
  }
  u.bq.pC->rowidIsValid = 0;
  u.br.pC->rowidIsValid = 0;
  break;
}

/* Opcode: IdxInsert P1 P2 P3 * P5
**
** Register P2 holds an SQL index key made using the
** MakeRecord instructions.  This opcode writes that key
** into the index P1.  Data for the entry is nil.
**
** P3 is a flag that provides a hint to the b-tree layer that this
** insert is likely to be an append.
**
** This instruction only works for indices.  The equivalent instruction
** for tables is OP_Insert.
*/
case OP_SorterInsert:       /* in2 */
#ifdef SQLITE_OMIT_MERGE_SORT
  pOp->opcode = OP_IdxInsert;
#endif
case OP_IdxInsert: {        /* in2 */
#if 0  /* local variables moved into u.br */
#if 0  /* local variables moved into u.bs */
  VdbeCursor *pC;
  BtCursor *pCrsr;
  int nKey;
  const char *zKey;
#endif /* local variables moved into u.br */
#endif /* local variables moved into u.bs */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.br.pC = p->apCsr[pOp->p1];
  assert( u.br.pC!=0 );
  assert( u.br.pC->isSorter==(pOp->opcode==OP_SorterInsert) );
  u.bs.pC = p->apCsr[pOp->p1];
  assert( u.bs.pC!=0 );
  assert( u.bs.pC->isSorter==(pOp->opcode==OP_SorterInsert) );
  pIn2 = &aMem[pOp->p2];
  assert( pIn2->flags & MEM_Blob );
  u.br.pCrsr = u.br.pC->pCursor;
  if( ALWAYS(u.br.pCrsr!=0) ){
    assert( u.br.pC->isTable==0 );
  u.bs.pCrsr = u.bs.pC->pCursor;
  if( ALWAYS(u.bs.pCrsr!=0) ){
    assert( u.bs.pC->isTable==0 );
    rc = ExpandBlob(pIn2);
    if( rc==SQLITE_OK ){
      if( isSorter(u.br.pC) ){
        rc = sqlite3VdbeSorterWrite(db, u.br.pC, pIn2);
      if( isSorter(u.bs.pC) ){
        rc = sqlite3VdbeSorterWrite(db, u.bs.pC, pIn2);
      }else{
        u.br.nKey = pIn2->n;
        u.br.zKey = pIn2->z;
        rc = sqlite3BtreeInsert(u.br.pCrsr, u.br.zKey, u.br.nKey, "", 0, 0, pOp->p3,
            ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.br.pC->seekResult : 0)
        u.bs.nKey = pIn2->n;
        u.bs.zKey = pIn2->z;
        rc = sqlite3BtreeInsert(u.bs.pCrsr, u.bs.zKey, u.bs.nKey, "", 0, 0, pOp->p3,
            ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bs.pC->seekResult : 0)
            );
        assert( u.br.pC->deferredMoveto==0 );
        u.br.pC->cacheStatus = CACHE_STALE;
        assert( u.bs.pC->deferredMoveto==0 );
        u.bs.pC->cacheStatus = CACHE_STALE;
      }
    }
  }
  break;
}

/* Opcode: IdxDelete P1 P2 P3 * *
**
** The content of P3 registers starting at register P2 form
** an unpacked index key. This opcode removes that entry from the 
** index opened by cursor P1.
*/
case OP_IdxDelete: {
#if 0  /* local variables moved into u.bs */
#if 0  /* local variables moved into u.bt */
  VdbeCursor *pC;
  BtCursor *pCrsr;
  int res;
  UnpackedRecord r;
#endif /* local variables moved into u.bs */
#endif /* local variables moved into u.bt */

  assert( pOp->p3>0 );
  assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bs.pC = p->apCsr[pOp->p1];
  assert( u.bs.pC!=0 );
  u.bs.pCrsr = u.bs.pC->pCursor;
  if( ALWAYS(u.bs.pCrsr!=0) ){
    u.bs.r.pKeyInfo = u.bs.pC->pKeyInfo;
    u.bs.r.nField = (u16)pOp->p3;
    u.bs.r.flags = 0;
    u.bs.r.aMem = &aMem[pOp->p2];
  u.bt.pC = p->apCsr[pOp->p1];
  assert( u.bt.pC!=0 );
  u.bt.pCrsr = u.bt.pC->pCursor;
  if( ALWAYS(u.bt.pCrsr!=0) ){
    u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo;
    u.bt.r.nField = (u16)pOp->p3;
    u.bt.r.flags = 0;
    u.bt.r.aMem = &aMem[pOp->p2];
#ifdef SQLITE_DEBUG
    { int i; for(i=0; i<u.bs.r.nField; i++) assert( memIsValid(&u.bs.r.aMem[i]) ); }
    { int i; for(i=0; i<u.bt.r.nField; i++) assert( memIsValid(&u.bt.r.aMem[i]) ); }
#endif
    rc = sqlite3BtreeMovetoUnpacked(u.bs.pCrsr, &u.bs.r, 0, 0, &u.bs.res);
    if( rc==SQLITE_OK && u.bs.res==0 ){
      rc = sqlite3BtreeDelete(u.bs.pCrsr);
    rc = sqlite3BtreeMovetoUnpacked(u.bt.pCrsr, &u.bt.r, 0, 0, &u.bt.res);
    if( rc==SQLITE_OK && u.bt.res==0 ){
      rc = sqlite3BtreeDelete(u.bt.pCrsr);
    }
    assert( u.bs.pC->deferredMoveto==0 );
    u.bs.pC->cacheStatus = CACHE_STALE;
    assert( u.bt.pC->deferredMoveto==0 );
    u.bt.pC->cacheStatus = CACHE_STALE;
  }
  break;
}

/* Opcode: IdxRowid P1 P2 * * *
**
** Write into register P2 an integer which is the last entry in the record at
** the end of the index key pointed to by cursor P1.  This integer should be
** the rowid of the table entry to which this index entry points.
**
** See also: Rowid, MakeRecord.
*/
case OP_IdxRowid: {              /* out2-prerelease */
#if 0  /* local variables moved into u.bt */
#if 0  /* local variables moved into u.bu */
  BtCursor *pCrsr;
  VdbeCursor *pC;
  i64 rowid;
#endif /* local variables moved into u.bt */
#endif /* local variables moved into u.bu */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bt.pC = p->apCsr[pOp->p1];
  assert( u.bt.pC!=0 );
  u.bt.pCrsr = u.bt.pC->pCursor;
  u.bu.pC = p->apCsr[pOp->p1];
  assert( u.bu.pC!=0 );
  u.bu.pCrsr = u.bu.pC->pCursor;
  pOut->flags = MEM_Null;
  if( ALWAYS(u.bt.pCrsr!=0) ){
    rc = sqlite3VdbeCursorMoveto(u.bt.pC);
  if( ALWAYS(u.bu.pCrsr!=0) ){
    rc = sqlite3VdbeCursorMoveto(u.bu.pC);
    if( NEVER(rc) ) goto abort_due_to_error;
    assert( u.bt.pC->deferredMoveto==0 );
    assert( u.bt.pC->isTable==0 );
    if( !u.bt.pC->nullRow ){
      rc = sqlite3VdbeIdxRowid(db, u.bt.pCrsr, &u.bt.rowid);
    assert( u.bu.pC->deferredMoveto==0 );
    assert( u.bu.pC->isTable==0 );
    if( !u.bu.pC->nullRow ){
      rc = sqlite3VdbeIdxRowid(db, u.bu.pCrsr, &u.bu.rowid);
      if( rc!=SQLITE_OK ){
        goto abort_due_to_error;
      }
      pOut->u.i = u.bt.rowid;
      pOut->u.i = u.bu.rowid;
      pOut->flags = MEM_Int;
    }
  }
  break;
}

/* Opcode: IdxGE P1 P2 P3 P4 P5
68291
68292
68293
68294
68295
68296
68297
68298

68299
68300
68301
68302

68303
68304
68305
68306
68307
68308
68309





68310
68311
68312
68313


68314
68315

68316
68317

68318
68319

68320
68321

68322
68323

68324
68325

68326
68327
68328

68329
68330

68331
68332
68333
68334
68335
68336
68337
68446
68447
68448
68449
68450
68451
68452

68453
68454
68455
68456

68457
68458
68459





68460
68461
68462
68463
68464
68465
68466


68467
68468
68469

68470
68471

68472
68473

68474
68475

68476
68477

68478
68479

68480
68481
68482

68483
68484

68485
68486
68487
68488
68489
68490
68491
68492







-
+



-
+


-
-
-
-
-
+
+
+
+
+


-
-
+
+

-
+

-
+

-
+

-
+

-
+

-
+


-
+

-
+







** Otherwise fall through to the next instruction.
**
** If P5 is non-zero then the key value is increased by an epsilon prior 
** to the comparison.  This makes the opcode work like IdxLE.
*/
case OP_IdxLT:          /* jump */
case OP_IdxGE: {        /* jump */
#if 0  /* local variables moved into u.bu */
#if 0  /* local variables moved into u.bv */
  VdbeCursor *pC;
  int res;
  UnpackedRecord r;
#endif /* local variables moved into u.bu */
#endif /* local variables moved into u.bv */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bu.pC = p->apCsr[pOp->p1];
  assert( u.bu.pC!=0 );
  assert( u.bu.pC->isOrdered );
  if( ALWAYS(u.bu.pC->pCursor!=0) ){
    assert( u.bu.pC->deferredMoveto==0 );
  u.bv.pC = p->apCsr[pOp->p1];
  assert( u.bv.pC!=0 );
  assert( u.bv.pC->isOrdered );
  if( ALWAYS(u.bv.pC->pCursor!=0) ){
    assert( u.bv.pC->deferredMoveto==0 );
    assert( pOp->p5==0 || pOp->p5==1 );
    assert( pOp->p4type==P4_INT32 );
    u.bu.r.pKeyInfo = u.bu.pC->pKeyInfo;
    u.bu.r.nField = (u16)pOp->p4.i;
    u.bv.r.pKeyInfo = u.bv.pC->pKeyInfo;
    u.bv.r.nField = (u16)pOp->p4.i;
    if( pOp->p5 ){
      u.bu.r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH;
      u.bv.r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH;
    }else{
      u.bu.r.flags = UNPACKED_PREFIX_MATCH;
      u.bv.r.flags = UNPACKED_PREFIX_MATCH;
    }
    u.bu.r.aMem = &aMem[pOp->p3];
    u.bv.r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
    { int i; for(i=0; i<u.bu.r.nField; i++) assert( memIsValid(&u.bu.r.aMem[i]) ); }
    { int i; for(i=0; i<u.bv.r.nField; i++) assert( memIsValid(&u.bv.r.aMem[i]) ); }
#endif
    rc = sqlite3VdbeIdxKeyCompare(u.bu.pC, &u.bu.r, &u.bu.res);
    rc = sqlite3VdbeIdxKeyCompare(u.bv.pC, &u.bv.r, &u.bv.res);
    if( pOp->opcode==OP_IdxLT ){
      u.bu.res = -u.bu.res;
      u.bv.res = -u.bv.res;
    }else{
      assert( pOp->opcode==OP_IdxGE );
      u.bu.res++;
      u.bv.res++;
    }
    if( u.bu.res>0 ){
    if( u.bv.res>0 ){
      pc = pOp->p2 - 1 ;
    }
  }
  break;
}

/* Opcode: Destroy P1 P2 P3 * *
68351
68352
68353
68354
68355
68356
68357
68358

68359
68360
68361
68362
68363

68364
68365
68366
68367
68368
68369




68370
68371
68372
68373

68374
68375
68376

68377
68378
68379
68380
68381
68382
68383




68384
68385

68386
68387
68388


68389
68390
68391


68392
68393
68394
68395
68396
68397
68398
68506
68507
68508
68509
68510
68511
68512

68513
68514
68515
68516
68517

68518
68519
68520




68521
68522
68523
68524
68525
68526
68527

68528
68529
68530

68531
68532
68533
68534




68535
68536
68537
68538
68539

68540
68541


68542
68543
68544


68545
68546
68547
68548
68549
68550
68551
68552
68553







-
+




-
+


-
-
-
-
+
+
+
+



-
+


-
+



-
-
-
-
+
+
+
+

-
+

-
-
+
+

-
-
+
+







** movement was required (because the table being dropped was already 
** the last one in the database) then a zero is stored in register P2.
** If AUTOVACUUM is disabled then a zero is stored in register P2.
**
** See also: Clear
*/
case OP_Destroy: {     /* out2-prerelease */
#if 0  /* local variables moved into u.bv */
#if 0  /* local variables moved into u.bw */
  int iMoved;
  int iCnt;
  Vdbe *pVdbe;
  int iDb;
#endif /* local variables moved into u.bv */
#endif /* local variables moved into u.bw */

#ifndef SQLITE_OMIT_VIRTUALTABLE
  u.bv.iCnt = 0;
  for(u.bv.pVdbe=db->pVdbe; u.bv.pVdbe; u.bv.pVdbe = u.bv.pVdbe->pNext){
    if( u.bv.pVdbe->magic==VDBE_MAGIC_RUN && u.bv.pVdbe->inVtabMethod<2 && u.bv.pVdbe->pc>=0 ){
      u.bv.iCnt++;
  u.bw.iCnt = 0;
  for(u.bw.pVdbe=db->pVdbe; u.bw.pVdbe; u.bw.pVdbe = u.bw.pVdbe->pNext){
    if( u.bw.pVdbe->magic==VDBE_MAGIC_RUN && u.bw.pVdbe->inVtabMethod<2 && u.bw.pVdbe->pc>=0 ){
      u.bw.iCnt++;
    }
  }
#else
  u.bv.iCnt = db->activeVdbeCnt;
  u.bw.iCnt = db->activeVdbeCnt;
#endif
  pOut->flags = MEM_Null;
  if( u.bv.iCnt>1 ){
  if( u.bw.iCnt>1 ){
    rc = SQLITE_LOCKED;
    p->errorAction = OE_Abort;
  }else{
    u.bv.iDb = pOp->p3;
    assert( u.bv.iCnt==1 );
    assert( (p->btreeMask & (((yDbMask)1)<<u.bv.iDb))!=0 );
    rc = sqlite3BtreeDropTable(db->aDb[u.bv.iDb].pBt, pOp->p1, &u.bv.iMoved);
    u.bw.iDb = pOp->p3;
    assert( u.bw.iCnt==1 );
    assert( (p->btreeMask & (((yDbMask)1)<<u.bw.iDb))!=0 );
    rc = sqlite3BtreeDropTable(db->aDb[u.bw.iDb].pBt, pOp->p1, &u.bw.iMoved);
    pOut->flags = MEM_Int;
    pOut->u.i = u.bv.iMoved;
    pOut->u.i = u.bw.iMoved;
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( rc==SQLITE_OK && u.bv.iMoved!=0 ){
      sqlite3RootPageMoved(db, u.bv.iDb, u.bv.iMoved, pOp->p1);
    if( rc==SQLITE_OK && u.bw.iMoved!=0 ){
      sqlite3RootPageMoved(db, u.bw.iDb, u.bw.iMoved, pOp->p1);
      /* All OP_Destroy operations occur on the same btree */
      assert( resetSchemaOnFault==0 || resetSchemaOnFault==u.bv.iDb+1 );
      resetSchemaOnFault = u.bv.iDb+1;
      assert( resetSchemaOnFault==0 || resetSchemaOnFault==u.bw.iDb+1 );
      resetSchemaOnFault = u.bw.iDb+1;
    }
#endif
  }
  break;
}

/* Opcode: Clear P1 P2 P3
68410
68411
68412
68413
68414
68415
68416
68417

68418
68419

68420
68421

68422
68423
68424

68425
68426
68427

68428
68429
68430
68431

68432
68433
68434
68435
68436
68437
68438
68565
68566
68567
68568
68569
68570
68571

68572
68573

68574
68575

68576
68577
68578

68579
68580
68581

68582
68583
68584
68585

68586
68587
68588
68589
68590
68591
68592
68593







-
+

-
+

-
+


-
+


-
+



-
+







** count is incremented by the number of rows in the table being cleared. 
** If P3 is greater than zero, then the value stored in register P3 is
** also incremented by the number of rows in the table being cleared.
**
** See also: Destroy
*/
case OP_Clear: {
#if 0  /* local variables moved into u.bw */
#if 0  /* local variables moved into u.bx */
  int nChange;
#endif /* local variables moved into u.bw */
#endif /* local variables moved into u.bx */

  u.bw.nChange = 0;
  u.bx.nChange = 0;
  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 );
  rc = sqlite3BtreeClearTable(
      db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bw.nChange : 0)
      db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bx.nChange : 0)
  );
  if( pOp->p3 ){
    p->nChange += u.bw.nChange;
    p->nChange += u.bx.nChange;
    if( pOp->p3>0 ){
      assert( memIsValid(&aMem[pOp->p3]) );
      memAboutToChange(p, &aMem[pOp->p3]);
      aMem[pOp->p3].u.i += u.bw.nChange;
      aMem[pOp->p3].u.i += u.bx.nChange;
    }
  }
  break;
}

/* Opcode: CreateTable P1 P2 * * *
**
68454
68455
68456
68457
68458
68459
68460
68461

68462
68463
68464
68465

68466
68467

68468
68469
68470
68471


68472
68473
68474


68475
68476

68477
68478
68479


68480
68481
68482
68483
68484
68485
68486
68487
68488
68489
68490
68491
68492

68493
68494
68495
68496
68497

68498
68499
68500
68501
68502
68503
68504
68505


68506
68507
68508
68509
68510
68511



68512
68513
68514
68515
68516
68517





68518
68519
68520


68521
68522
68523
68524
68525

68526
68527
68528
68529



68530
68531
68532
68533
68534
68535
68536
68609
68610
68611
68612
68613
68614
68615

68616
68617
68618
68619

68620
68621

68622
68623
68624


68625
68626
68627


68628
68629
68630

68631
68632


68633
68634
68635
68636
68637
68638
68639
68640
68641
68642
68643
68644
68645
68646

68647
68648
68649
68650
68651

68652
68653
68654
68655
68656
68657
68658


68659
68660
68661
68662
68663



68664
68665
68666
68667





68668
68669
68670
68671
68672
68673


68674
68675
68676
68677
68678
68679

68680
68681



68682
68683
68684
68685
68686
68687
68688
68689
68690
68691







-
+



-
+

-
+


-
-
+
+

-
-
+
+

-
+

-
-
+
+












-
+




-
+






-
-
+
+



-
-
-
+
+
+

-
-
-
-
-
+
+
+
+
+

-
-
+
+




-
+

-
-
-
+
+
+







** P1>1.  Write the root page number of the new table into
** register P2.
**
** See documentation on OP_CreateTable for additional information.
*/
case OP_CreateIndex:            /* out2-prerelease */
case OP_CreateTable: {          /* out2-prerelease */
#if 0  /* local variables moved into u.bx */
#if 0  /* local variables moved into u.by */
  int pgno;
  int flags;
  Db *pDb;
#endif /* local variables moved into u.bx */
#endif /* local variables moved into u.by */

  u.bx.pgno = 0;
  u.by.pgno = 0;
  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
  u.bx.pDb = &db->aDb[pOp->p1];
  assert( u.bx.pDb->pBt!=0 );
  u.by.pDb = &db->aDb[pOp->p1];
  assert( u.by.pDb->pBt!=0 );
  if( pOp->opcode==OP_CreateTable ){
    /* u.bx.flags = BTREE_INTKEY; */
    u.bx.flags = BTREE_INTKEY;
    /* u.by.flags = BTREE_INTKEY; */
    u.by.flags = BTREE_INTKEY;
  }else{
    u.bx.flags = BTREE_BLOBKEY;
    u.by.flags = BTREE_BLOBKEY;
  }
  rc = sqlite3BtreeCreateTable(u.bx.pDb->pBt, &u.bx.pgno, u.bx.flags);
  pOut->u.i = u.bx.pgno;
  rc = sqlite3BtreeCreateTable(u.by.pDb->pBt, &u.by.pgno, u.by.flags);
  pOut->u.i = u.by.pgno;
  break;
}

/* Opcode: ParseSchema P1 * * P4 *
**
** Read and parse all entries from the SQLITE_MASTER table of database P1
** that match the WHERE clause P4. 
**
** This opcode invokes the parser to create a new virtual machine,
** then runs the new virtual machine.  It is thus a re-entrant opcode.
*/
case OP_ParseSchema: {
#if 0  /* local variables moved into u.by */
#if 0  /* local variables moved into u.bz */
  int iDb;
  const char *zMaster;
  char *zSql;
  InitData initData;
#endif /* local variables moved into u.by */
#endif /* local variables moved into u.bz */

  /* Any prepared statement that invokes this opcode will hold mutexes
  ** on every btree.  This is a prerequisite for invoking
  ** sqlite3InitCallback().
  */
#ifdef SQLITE_DEBUG
  for(u.by.iDb=0; u.by.iDb<db->nDb; u.by.iDb++){
    assert( u.by.iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[u.by.iDb].pBt) );
  for(u.bz.iDb=0; u.bz.iDb<db->nDb; u.bz.iDb++){
    assert( u.bz.iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[u.bz.iDb].pBt) );
  }
#endif

  u.by.iDb = pOp->p1;
  assert( u.by.iDb>=0 && u.by.iDb<db->nDb );
  assert( DbHasProperty(db, u.by.iDb, DB_SchemaLoaded) );
  u.bz.iDb = pOp->p1;
  assert( u.bz.iDb>=0 && u.bz.iDb<db->nDb );
  assert( DbHasProperty(db, u.bz.iDb, DB_SchemaLoaded) );
  /* Used to be a conditional */ {
    u.by.zMaster = SCHEMA_TABLE(u.by.iDb);
    u.by.initData.db = db;
    u.by.initData.iDb = pOp->p1;
    u.by.initData.pzErrMsg = &p->zErrMsg;
    u.by.zSql = sqlite3MPrintf(db,
    u.bz.zMaster = SCHEMA_TABLE(u.bz.iDb);
    u.bz.initData.db = db;
    u.bz.initData.iDb = pOp->p1;
    u.bz.initData.pzErrMsg = &p->zErrMsg;
    u.bz.zSql = sqlite3MPrintf(db,
       "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
       db->aDb[u.by.iDb].zName, u.by.zMaster, pOp->p4.z);
    if( u.by.zSql==0 ){
       db->aDb[u.bz.iDb].zName, u.bz.zMaster, pOp->p4.z);
    if( u.bz.zSql==0 ){
      rc = SQLITE_NOMEM;
    }else{
      assert( db->init.busy==0 );
      db->init.busy = 1;
      u.by.initData.rc = SQLITE_OK;
      u.bz.initData.rc = SQLITE_OK;
      assert( !db->mallocFailed );
      rc = sqlite3_exec(db, u.by.zSql, sqlite3InitCallback, &u.by.initData, 0);
      if( rc==SQLITE_OK ) rc = u.by.initData.rc;
      sqlite3DbFree(db, u.by.zSql);
      rc = sqlite3_exec(db, u.bz.zSql, sqlite3InitCallback, &u.bz.initData, 0);
      if( rc==SQLITE_OK ) rc = u.bz.initData.rc;
      sqlite3DbFree(db, u.bz.zSql);
      db->init.busy = 0;
    }
  }
  if( rc ) sqlite3ResetAllSchemasOfConnection(db);
  if( rc==SQLITE_NOMEM ){
    goto no_mem;
  }
68606
68607
68608
68609
68610
68611
68612
68613

68614
68615
68616
68617
68618
68619
68620

68621
68622
68623
68624
68625




68626
68627
68628
68629



68630
68631
68632


68633
68634

68635
68636
68637
68638
68639
68640




68641
68642
68643
68644



68645
68646
68647

68648
68649
68650
68651
68652
68653
68654
68761
68762
68763
68764
68765
68766
68767

68768
68769
68770
68771
68772
68773
68774

68775
68776




68777
68778
68779
68780
68781



68782
68783
68784
68785


68786
68787
68788

68789
68790
68791




68792
68793
68794
68795
68796



68797
68798
68799
68800
68801

68802
68803
68804
68805
68806
68807
68808
68809







-
+






-
+

-
-
-
-
+
+
+
+

-
-
-
+
+
+

-
-
+
+

-
+


-
-
-
-
+
+
+
+

-
-
-
+
+
+


-
+







**
** If P5 is not zero, the check is done on the auxiliary database
** file, not the main database file.
**
** This opcode is used to implement the integrity_check pragma.
*/
case OP_IntegrityCk: {
#if 0  /* local variables moved into u.bz */
#if 0  /* local variables moved into u.ca */
  int nRoot;      /* Number of tables to check.  (Number of root pages.) */
  int *aRoot;     /* Array of rootpage numbers for tables to be checked */
  int j;          /* Loop counter */
  int nErr;       /* Number of errors reported */
  char *z;        /* Text of the error report */
  Mem *pnErr;     /* Register keeping track of errors remaining */
#endif /* local variables moved into u.bz */
#endif /* local variables moved into u.ca */

  u.bz.nRoot = pOp->p2;
  assert( u.bz.nRoot>0 );
  u.bz.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.bz.nRoot+1) );
  if( u.bz.aRoot==0 ) goto no_mem;
  u.ca.nRoot = pOp->p2;
  assert( u.ca.nRoot>0 );
  u.ca.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.ca.nRoot+1) );
  if( u.ca.aRoot==0 ) goto no_mem;
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  u.bz.pnErr = &aMem[pOp->p3];
  assert( (u.bz.pnErr->flags & MEM_Int)!=0 );
  assert( (u.bz.pnErr->flags & (MEM_Str|MEM_Blob))==0 );
  u.ca.pnErr = &aMem[pOp->p3];
  assert( (u.ca.pnErr->flags & MEM_Int)!=0 );
  assert( (u.ca.pnErr->flags & (MEM_Str|MEM_Blob))==0 );
  pIn1 = &aMem[pOp->p1];
  for(u.bz.j=0; u.bz.j<u.bz.nRoot; u.bz.j++){
    u.bz.aRoot[u.bz.j] = (int)sqlite3VdbeIntValue(&pIn1[u.bz.j]);
  for(u.ca.j=0; u.ca.j<u.ca.nRoot; u.ca.j++){
    u.ca.aRoot[u.ca.j] = (int)sqlite3VdbeIntValue(&pIn1[u.ca.j]);
  }
  u.bz.aRoot[u.bz.j] = 0;
  u.ca.aRoot[u.ca.j] = 0;
  assert( pOp->p5<db->nDb );
  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 );
  u.bz.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.bz.aRoot, u.bz.nRoot,
                                 (int)u.bz.pnErr->u.i, &u.bz.nErr);
  sqlite3DbFree(db, u.bz.aRoot);
  u.bz.pnErr->u.i -= u.bz.nErr;
  u.ca.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.ca.aRoot, u.ca.nRoot,
                                 (int)u.ca.pnErr->u.i, &u.ca.nErr);
  sqlite3DbFree(db, u.ca.aRoot);
  u.ca.pnErr->u.i -= u.ca.nErr;
  sqlite3VdbeMemSetNull(pIn1);
  if( u.bz.nErr==0 ){
    assert( u.bz.z==0 );
  }else if( u.bz.z==0 ){
  if( u.ca.nErr==0 ){
    assert( u.ca.z==0 );
  }else if( u.ca.z==0 ){
    goto no_mem;
  }else{
    sqlite3VdbeMemSetStr(pIn1, u.bz.z, -1, SQLITE_UTF8, sqlite3_free);
    sqlite3VdbeMemSetStr(pIn1, u.ca.z, -1, SQLITE_UTF8, sqlite3_free);
  }
  UPDATE_MAX_BLOBSIZE(pIn1);
  sqlite3VdbeChangeEncoding(pIn1, encoding);
  break;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

68674
68675
68676
68677
68678
68679
68680
68681

68682
68683

68684
68685
68686
68687

68688
68689
68690
68691
68692
68693
68694

68695
68696
68697
68698
68699
68700
68701
68829
68830
68831
68832
68833
68834
68835

68836
68837

68838
68839
68840
68841

68842
68843
68844
68845
68846
68847
68848

68849
68850
68851
68852
68853
68854
68855
68856







-
+

-
+



-
+






-
+







/* Opcode: RowSetRead P1 P2 P3 * *
**
** Extract the smallest value from boolean index P1 and put that value into
** register P3.  Or, if boolean index P1 is initially empty, leave P3
** unchanged and jump to instruction P2.
*/
case OP_RowSetRead: {       /* jump, in1, out3 */
#if 0  /* local variables moved into u.ca */
#if 0  /* local variables moved into u.cb */
  i64 val;
#endif /* local variables moved into u.ca */
#endif /* local variables moved into u.cb */
  CHECK_FOR_INTERRUPT;
  pIn1 = &aMem[pOp->p1];
  if( (pIn1->flags & MEM_RowSet)==0
   || sqlite3RowSetNext(pIn1->u.pRowSet, &u.ca.val)==0
   || sqlite3RowSetNext(pIn1->u.pRowSet, &u.cb.val)==0
  ){
    /* The boolean index is empty */
    sqlite3VdbeMemSetNull(pIn1);
    pc = pOp->p2 - 1;
  }else{
    /* A value was pulled from the index */
    sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.ca.val);
    sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.cb.val);
  }
  break;
}

/* Opcode: RowSetTest P1 P2 P3 P4
**
** Register P3 is assumed to hold a 64-bit integer value. If register P1
68716
68717
68718
68719
68720
68721
68722
68723

68724
68725
68726

68727
68728
68729
68730

68731
68732
68733
68734
68735
68736
68737
68738
68739
68740
68741
68742
68743
68744
68745




68746
68747

68748
68749
68750
68751
68752

68753
68754
68755
68756
68757
68758
68759
68871
68872
68873
68874
68875
68876
68877

68878
68879
68880

68881
68882
68883
68884

68885
68886
68887
68888
68889
68890
68891
68892
68893
68894
68895
68896




68897
68898
68899
68900
68901

68902
68903
68904
68905
68906

68907
68908
68909
68910
68911
68912
68913
68914







-
+


-
+



-
+











-
-
-
-
+
+
+
+

-
+




-
+







** (b) when P4==-1 there is no need to insert the value, as it will
** never be tested for, and (c) when a value that is part of set X is
** inserted, there is no need to search to see if the same value was
** previously inserted as part of set X (only if it was previously
** inserted as part of some other set).
*/
case OP_RowSetTest: {                     /* jump, in1, in3 */
#if 0  /* local variables moved into u.cb */
#if 0  /* local variables moved into u.cc */
  int iSet;
  int exists;
#endif /* local variables moved into u.cb */
#endif /* local variables moved into u.cc */

  pIn1 = &aMem[pOp->p1];
  pIn3 = &aMem[pOp->p3];
  u.cb.iSet = pOp->p4.i;
  u.cc.iSet = pOp->p4.i;
  assert( pIn3->flags&MEM_Int );

  /* If there is anything other than a rowset object in memory cell P1,
  ** delete it now and initialize P1 with an empty rowset
  */
  if( (pIn1->flags & MEM_RowSet)==0 ){
    sqlite3VdbeMemSetRowSet(pIn1);
    if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
  }

  assert( pOp->p4type==P4_INT32 );
  assert( u.cb.iSet==-1 || u.cb.iSet>=0 );
  if( u.cb.iSet ){
    u.cb.exists = sqlite3RowSetTest(pIn1->u.pRowSet,
                               (u8)(u.cb.iSet>=0 ? u.cb.iSet & 0xf : 0xff),
  assert( u.cc.iSet==-1 || u.cc.iSet>=0 );
  if( u.cc.iSet ){
    u.cc.exists = sqlite3RowSetTest(pIn1->u.pRowSet,
                               (u8)(u.cc.iSet>=0 ? u.cc.iSet & 0xf : 0xff),
                               pIn3->u.i);
    if( u.cb.exists ){
    if( u.cc.exists ){
      pc = pOp->p2 - 1;
      break;
    }
  }
  if( u.cb.iSet>=0 ){
  if( u.cc.iSet>=0 ){
    sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
  }
  break;
}


#ifndef SQLITE_OMIT_TRIGGER
68768
68769
68770
68771
68772
68773
68774
68775

68776
68777
68778
68779
68780
68781
68782
68783
68784

68785
68786
68787
68788



68789
68790
68791
68792
68793
68794
68795
68796
68797
68798
68799
68800
68801
68802
68803
68804



68805
68806
68807
68808
68809
68810
68811
68812
68813

68814
68815

68816
68817

68818
68819
68820
68821

68822
68823
68824
68825
68826
68827
68828
68829







68830
68831
68832
68833
68834



68835
68836
68837
68838
68839
68840
68841
68842
68843
68844
68845
68846
68847
68848













68849
68850
68851
68852
68853




68854
68855
68856
68857
68858
68859




68860
68861
68862
68863
68864
68865



68866
68867
68868
68869
68870




68871
68872
68873


68874
68875

68876
68877
68878
68879
68880
68881
68882
68883
68884
68885
68886
68887
68888
68889
68890
68891
68892
68893
68894
68895

68896
68897
68898
68899
68900
68901




68902
68903
68904
68905
68906
68907
68908
68923
68924
68925
68926
68927
68928
68929

68930
68931
68932
68933
68934
68935
68936
68937
68938

68939
68940



68941
68942
68943
68944
68945
68946
68947
68948
68949
68950
68951
68952
68953
68954
68955
68956



68957
68958
68959
68960
68961
68962
68963
68964
68965
68966
68967

68968
68969

68970
68971

68972
68973
68974
68975

68976
68977







68978
68979
68980
68981
68982
68983
68984
68985
68986



68987
68988
68989
68990













68991
68992
68993
68994
68995
68996
68997
68998
68999
69000
69001
69002
69003
69004




69005
69006
69007
69008
69009
69010




69011
69012
69013
69014
69015
69016
69017



69018
69019
69020
69021




69022
69023
69024
69025
69026


69027
69028
69029

69030
69031
69032
69033
69034
69035
69036
69037
69038
69039
69040
69041
69042
69043
69044
69045
69046
69047
69048
69049

69050
69051
69052




69053
69054
69055
69056
69057
69058
69059
69060
69061
69062
69063







-
+








-
+

-
-
-
+
+
+













-
-
-
+
+
+








-
+

-
+

-
+



-
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+


-
-
-
+
+
+

-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
+
+
+
+


-
-
-
-
+
+
+
+



-
-
-
+
+
+

-
-
-
-
+
+
+
+

-
-
+
+

-
+



















-
+


-
-
-
-
+
+
+
+







** exception using the RAISE() function. Register P3 contains the address 
** of a memory cell in this (the parent) VM that is used to allocate the 
** memory required by the sub-vdbe at runtime.
**
** P4 is a pointer to the VM containing the trigger program.
*/
case OP_Program: {        /* jump */
#if 0  /* local variables moved into u.cc */
#if 0  /* local variables moved into u.cd */
  int nMem;               /* Number of memory registers for sub-program */
  int nByte;              /* Bytes of runtime space required for sub-program */
  Mem *pRt;               /* Register to allocate runtime space */
  Mem *pMem;              /* Used to iterate through memory cells */
  Mem *pEnd;              /* Last memory cell in new array */
  VdbeFrame *pFrame;      /* New vdbe frame to execute in */
  SubProgram *pProgram;   /* Sub-program to execute */
  void *t;                /* Token identifying trigger */
#endif /* local variables moved into u.cc */
#endif /* local variables moved into u.cd */

  u.cc.pProgram = pOp->p4.pProgram;
  u.cc.pRt = &aMem[pOp->p3];
  assert( u.cc.pProgram->nOp>0 );
  u.cd.pProgram = pOp->p4.pProgram;
  u.cd.pRt = &aMem[pOp->p3];
  assert( u.cd.pProgram->nOp>0 );

  /* If the p5 flag is clear, then recursive invocation of triggers is
  ** disabled for backwards compatibility (p5 is set if this sub-program
  ** is really a trigger, not a foreign key action, and the flag set
  ** and cleared by the "PRAGMA recursive_triggers" command is clear).
  **
  ** It is recursive invocation of triggers, at the SQL level, that is
  ** disabled. In some cases a single trigger may generate more than one
  ** SubProgram (if the trigger may be executed with more than one different
  ** ON CONFLICT algorithm). SubProgram structures associated with a
  ** single trigger all have the same value for the SubProgram.token
  ** variable.  */
  if( pOp->p5 ){
    u.cc.t = u.cc.pProgram->token;
    for(u.cc.pFrame=p->pFrame; u.cc.pFrame && u.cc.pFrame->token!=u.cc.t; u.cc.pFrame=u.cc.pFrame->pParent);
    if( u.cc.pFrame ) break;
    u.cd.t = u.cd.pProgram->token;
    for(u.cd.pFrame=p->pFrame; u.cd.pFrame && u.cd.pFrame->token!=u.cd.t; u.cd.pFrame=u.cd.pFrame->pParent);
    if( u.cd.pFrame ) break;
  }

  if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
    rc = SQLITE_ERROR;
    sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion");
    break;
  }

  /* Register u.cc.pRt is used to store the memory required to save the state
  /* Register u.cd.pRt is used to store the memory required to save the state
  ** of the current program, and the memory required at runtime to execute
  ** the trigger program. If this trigger has been fired before, then u.cc.pRt
  ** the trigger program. If this trigger has been fired before, then u.cd.pRt
  ** is already allocated. Otherwise, it must be initialized.  */
  if( (u.cc.pRt->flags&MEM_Frame)==0 ){
  if( (u.cd.pRt->flags&MEM_Frame)==0 ){
    /* SubProgram.nMem is set to the number of memory cells used by the
    ** program stored in SubProgram.aOp. As well as these, one memory
    ** cell is required for each cursor used by the program. Set local
    ** variable u.cc.nMem (and later, VdbeFrame.nChildMem) to this value.
    ** variable u.cd.nMem (and later, VdbeFrame.nChildMem) to this value.
    */
    u.cc.nMem = u.cc.pProgram->nMem + u.cc.pProgram->nCsr;
    u.cc.nByte = ROUND8(sizeof(VdbeFrame))
              + u.cc.nMem * sizeof(Mem)
              + u.cc.pProgram->nCsr * sizeof(VdbeCursor *)
              + u.cc.pProgram->nOnce * sizeof(u8);
    u.cc.pFrame = sqlite3DbMallocZero(db, u.cc.nByte);
    if( !u.cc.pFrame ){
    u.cd.nMem = u.cd.pProgram->nMem + u.cd.pProgram->nCsr;
    u.cd.nByte = ROUND8(sizeof(VdbeFrame))
              + u.cd.nMem * sizeof(Mem)
              + u.cd.pProgram->nCsr * sizeof(VdbeCursor *)
              + u.cd.pProgram->nOnce * sizeof(u8);
    u.cd.pFrame = sqlite3DbMallocZero(db, u.cd.nByte);
    if( !u.cd.pFrame ){
      goto no_mem;
    }
    sqlite3VdbeMemRelease(u.cc.pRt);
    u.cc.pRt->flags = MEM_Frame;
    u.cc.pRt->u.pFrame = u.cc.pFrame;
    sqlite3VdbeMemRelease(u.cd.pRt);
    u.cd.pRt->flags = MEM_Frame;
    u.cd.pRt->u.pFrame = u.cd.pFrame;

    u.cc.pFrame->v = p;
    u.cc.pFrame->nChildMem = u.cc.nMem;
    u.cc.pFrame->nChildCsr = u.cc.pProgram->nCsr;
    u.cc.pFrame->pc = pc;
    u.cc.pFrame->aMem = p->aMem;
    u.cc.pFrame->nMem = p->nMem;
    u.cc.pFrame->apCsr = p->apCsr;
    u.cc.pFrame->nCursor = p->nCursor;
    u.cc.pFrame->aOp = p->aOp;
    u.cc.pFrame->nOp = p->nOp;
    u.cc.pFrame->token = u.cc.pProgram->token;
    u.cc.pFrame->aOnceFlag = p->aOnceFlag;
    u.cc.pFrame->nOnceFlag = p->nOnceFlag;
    u.cd.pFrame->v = p;
    u.cd.pFrame->nChildMem = u.cd.nMem;
    u.cd.pFrame->nChildCsr = u.cd.pProgram->nCsr;
    u.cd.pFrame->pc = pc;
    u.cd.pFrame->aMem = p->aMem;
    u.cd.pFrame->nMem = p->nMem;
    u.cd.pFrame->apCsr = p->apCsr;
    u.cd.pFrame->nCursor = p->nCursor;
    u.cd.pFrame->aOp = p->aOp;
    u.cd.pFrame->nOp = p->nOp;
    u.cd.pFrame->token = u.cd.pProgram->token;
    u.cd.pFrame->aOnceFlag = p->aOnceFlag;
    u.cd.pFrame->nOnceFlag = p->nOnceFlag;

    u.cc.pEnd = &VdbeFrameMem(u.cc.pFrame)[u.cc.pFrame->nChildMem];
    for(u.cc.pMem=VdbeFrameMem(u.cc.pFrame); u.cc.pMem!=u.cc.pEnd; u.cc.pMem++){
      u.cc.pMem->flags = MEM_Invalid;
      u.cc.pMem->db = db;
    u.cd.pEnd = &VdbeFrameMem(u.cd.pFrame)[u.cd.pFrame->nChildMem];
    for(u.cd.pMem=VdbeFrameMem(u.cd.pFrame); u.cd.pMem!=u.cd.pEnd; u.cd.pMem++){
      u.cd.pMem->flags = MEM_Invalid;
      u.cd.pMem->db = db;
    }
  }else{
    u.cc.pFrame = u.cc.pRt->u.pFrame;
    assert( u.cc.pProgram->nMem+u.cc.pProgram->nCsr==u.cc.pFrame->nChildMem );
    assert( u.cc.pProgram->nCsr==u.cc.pFrame->nChildCsr );
    assert( pc==u.cc.pFrame->pc );
    u.cd.pFrame = u.cd.pRt->u.pFrame;
    assert( u.cd.pProgram->nMem+u.cd.pProgram->nCsr==u.cd.pFrame->nChildMem );
    assert( u.cd.pProgram->nCsr==u.cd.pFrame->nChildCsr );
    assert( pc==u.cd.pFrame->pc );
  }

  p->nFrame++;
  u.cc.pFrame->pParent = p->pFrame;
  u.cc.pFrame->lastRowid = lastRowid;
  u.cc.pFrame->nChange = p->nChange;
  u.cd.pFrame->pParent = p->pFrame;
  u.cd.pFrame->lastRowid = lastRowid;
  u.cd.pFrame->nChange = p->nChange;
  p->nChange = 0;
  p->pFrame = u.cc.pFrame;
  p->aMem = aMem = &VdbeFrameMem(u.cc.pFrame)[-1];
  p->nMem = u.cc.pFrame->nChildMem;
  p->nCursor = (u16)u.cc.pFrame->nChildCsr;
  p->pFrame = u.cd.pFrame;
  p->aMem = aMem = &VdbeFrameMem(u.cd.pFrame)[-1];
  p->nMem = u.cd.pFrame->nChildMem;
  p->nCursor = (u16)u.cd.pFrame->nChildCsr;
  p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
  p->aOp = aOp = u.cc.pProgram->aOp;
  p->nOp = u.cc.pProgram->nOp;
  p->aOp = aOp = u.cd.pProgram->aOp;
  p->nOp = u.cd.pProgram->nOp;
  p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
  p->nOnceFlag = u.cc.pProgram->nOnce;
  p->nOnceFlag = u.cd.pProgram->nOnce;
  pc = -1;
  memset(p->aOnceFlag, 0, p->nOnceFlag);

  break;
}

/* Opcode: Param P1 P2 * * *
**
** This opcode is only ever present in sub-programs called via the 
** OP_Program instruction. Copy a value currently stored in a memory 
** cell of the calling (parent) frame to cell P2 in the current frames 
** address space. This is used by trigger programs to access the new.* 
** and old.* values.
**
** The address of the cell in the parent frame is determined by adding
** the value of the P1 argument to the value of the P1 argument to the
** calling OP_Program instruction.
*/
case OP_Param: {           /* out2-prerelease */
#if 0  /* local variables moved into u.cd */
#if 0  /* local variables moved into u.ce */
  VdbeFrame *pFrame;
  Mem *pIn;
#endif /* local variables moved into u.cd */
  u.cd.pFrame = p->pFrame;
  u.cd.pIn = &u.cd.pFrame->aMem[pOp->p1 + u.cd.pFrame->aOp[u.cd.pFrame->pc].p1];
  sqlite3VdbeMemShallowCopy(pOut, u.cd.pIn, MEM_Ephem);
#endif /* local variables moved into u.ce */
  u.ce.pFrame = p->pFrame;
  u.ce.pIn = &u.ce.pFrame->aMem[pOp->p1 + u.ce.pFrame->aOp[u.ce.pFrame->pc].p1];
  sqlite3VdbeMemShallowCopy(pOut, u.ce.pIn, MEM_Ephem);
  break;
}

#endif /* #ifndef SQLITE_OMIT_TRIGGER */

#ifndef SQLITE_OMIT_FOREIGN_KEY
/* Opcode: FkCounter P1 P2 * * *
68950
68951
68952
68953
68954
68955
68956
68957

68958
68959
68960

68961
68962
68963


68964
68965

68966
68967
68968


68969
68970
68971
68972


68973
68974
68975
68976
68977
68978
68979
69105
69106
69107
69108
69109
69110
69111

69112
69113
69114

69115
69116


69117
69118
69119

69120
69121


69122
69123
69124
69125


69126
69127
69128
69129
69130
69131
69132
69133
69134







-
+


-
+

-
-
+
+

-
+

-
-
+
+


-
-
+
+







** within a sub-program). Set the value of register P1 to the maximum of 
** its current value and the value in register P2.
**
** This instruction throws an error if the memory cell is not initially
** an integer.
*/
case OP_MemMax: {        /* in2 */
#if 0  /* local variables moved into u.ce */
#if 0  /* local variables moved into u.cf */
  Mem *pIn1;
  VdbeFrame *pFrame;
#endif /* local variables moved into u.ce */
#endif /* local variables moved into u.cf */
  if( p->pFrame ){
    for(u.ce.pFrame=p->pFrame; u.ce.pFrame->pParent; u.ce.pFrame=u.ce.pFrame->pParent);
    u.ce.pIn1 = &u.ce.pFrame->aMem[pOp->p1];
    for(u.cf.pFrame=p->pFrame; u.cf.pFrame->pParent; u.cf.pFrame=u.cf.pFrame->pParent);
    u.cf.pIn1 = &u.cf.pFrame->aMem[pOp->p1];
  }else{
    u.ce.pIn1 = &aMem[pOp->p1];
    u.cf.pIn1 = &aMem[pOp->p1];
  }
  assert( memIsValid(u.ce.pIn1) );
  sqlite3VdbeMemIntegerify(u.ce.pIn1);
  assert( memIsValid(u.cf.pIn1) );
  sqlite3VdbeMemIntegerify(u.cf.pIn1);
  pIn2 = &aMem[pOp->p2];
  sqlite3VdbeMemIntegerify(pIn2);
  if( u.ce.pIn1->u.i<pIn2->u.i){
    u.ce.pIn1->u.i = pIn2->u.i;
  if( u.cf.pIn1->u.i<pIn2->u.i){
    u.cf.pIn1->u.i = pIn2->u.i;
  }
  break;
}
#endif /* SQLITE_OMIT_AUTOINCREMENT */

/* Opcode: IfPos P1 P2 * * *
**
69032
69033
69034
69035
69036
69037
69038
69039

69040
69041
69042
69043
69044
69045
69046

69047
69048
69049
69050
69051
69052
69053
69054
69055
69056
69057










69058
69059

69060
69061
69062
69063
69064
69065
69066
69067
69068
69069
69070
69071











69072
69073
69074
69075

69076
69077
69078
69079
69080




69081
69082

69083
69084
69085


69086
69087
69088

69089
69090
69091
69092
69093
69094
69095
69096
69097
69098
69099
69100
69101
69102
69103
69104
69105
69106

69107
69108

69109
69110
69111
69112



69113
69114

69115
69116
69117
69118



69119
69120
69121
69122
69123
69124
69125
69126
69127
69128
69129
69130
69131
69132
69133
69134
69135
69136
69137

69138
69139
69140
69141

69142
69143
69144


69145
69146
69147
69148
69149

69150
69151
69152

69153
69154
69155


69156
69157
69158
69159
69160
69161
69162
69163
69164
69165
69166
69167
69168
69169
69170
69171
69172
69173
69174

69175
69176
69177
69178
69179
69180
69181
69182

69183
69184
69185
69186
69187
69188
69189
69190
69191








69192
69193
69194
69195
69196
69197
69198
69199





69200
69201
69202

69203
69204
69205
69206
69207
69208
69209



69210
69211

69212
69213
69214
69215


69216
69217
69218
69219
69220
69221

69222
69223
69224
69225
69226

69227
69228
69229
69230
69231
69232

69233
69234

69235
69236

69237
69238
69239

69240
69241
69242
69243
69244
69245

69246
69247

69248
69249
69250
69251
69252
69253
69254

69255
69256

69257
69258
69259
69260

69261
69262
69263
69264
69265
69266
69267
69187
69188
69189
69190
69191
69192
69193

69194
69195
69196
69197
69198
69199
69200

69201
69202










69203
69204
69205
69206
69207
69208
69209
69210
69211
69212
69213

69214
69215











69216
69217
69218
69219
69220
69221
69222
69223
69224
69225
69226
69227
69228
69229

69230
69231




69232
69233
69234
69235
69236

69237
69238


69239
69240
69241
69242

69243
69244
69245
69246
69247
69248
69249
69250
69251
69252
69253
69254
69255
69256
69257
69258
69259
69260

69261
69262

69263
69264



69265
69266
69267
69268

69269
69270



69271
69272
69273
69274
69275
69276
69277
69278
69279
69280
69281
69282
69283
69284
69285
69286
69287
69288
69289
69290
69291

69292
69293
69294
69295

69296
69297


69298
69299
69300
69301
69302
69303

69304
69305
69306

69307
69308


69309
69310
69311
69312
69313
69314
69315
69316
69317
69318
69319
69320
69321
69322
69323
69324
69325
69326
69327
69328

69329
69330
69331
69332
69333
69334
69335
69336

69337
69338








69339
69340
69341
69342
69343
69344
69345
69346
69347
69348
69349





69350
69351
69352
69353
69354
69355
69356

69357
69358
69359
69360
69361



69362
69363
69364
69365

69366
69367
69368


69369
69370
69371
69372
69373
69374
69375

69376
69377
69378
69379
69380

69381
69382
69383
69384
69385
69386

69387
69388

69389
69390

69391
69392
69393

69394
69395
69396
69397
69398
69399

69400
69401

69402
69403
69404
69405
69406
69407
69408

69409
69410

69411
69412
69413
69414

69415
69416
69417
69418
69419
69420
69421
69422







-
+






-
+

-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+

-
+

-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+



-
+

-
-
-
-
+
+
+
+

-
+

-
-
+
+


-
+

















-
+

-
+

-
-
-
+
+
+

-
+

-
-
-
+
+
+


















-
+



-
+

-
-
+
+




-
+


-
+

-
-
+
+


















-
+







-
+

-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+



-
-
-
-
-
+
+
+
+
+


-
+




-
-
-
+
+
+

-
+


-
-
+
+





-
+




-
+





-
+

-
+

-
+


-
+





-
+

-
+






-
+

-
+



-
+







** structure that specifies the function.  Use register
** P3 as the accumulator.
**
** The P5 arguments are taken from register P2 and its
** successors.
*/
case OP_AggStep: {
#if 0  /* local variables moved into u.cf */
#if 0  /* local variables moved into u.cg */
  int n;
  int i;
  Mem *pMem;
  Mem *pRec;
  sqlite3_context ctx;
  sqlite3_value **apVal;
#endif /* local variables moved into u.cf */
#endif /* local variables moved into u.cg */

  u.cf.n = pOp->p5;
  assert( u.cf.n>=0 );
  u.cf.pRec = &aMem[pOp->p2];
  u.cf.apVal = p->apArg;
  assert( u.cf.apVal || u.cf.n==0 );
  for(u.cf.i=0; u.cf.i<u.cf.n; u.cf.i++, u.cf.pRec++){
    assert( memIsValid(u.cf.pRec) );
    u.cf.apVal[u.cf.i] = u.cf.pRec;
    memAboutToChange(p, u.cf.pRec);
    sqlite3VdbeMemStoreType(u.cf.pRec);
  u.cg.n = pOp->p5;
  assert( u.cg.n>=0 );
  u.cg.pRec = &aMem[pOp->p2];
  u.cg.apVal = p->apArg;
  assert( u.cg.apVal || u.cg.n==0 );
  for(u.cg.i=0; u.cg.i<u.cg.n; u.cg.i++, u.cg.pRec++){
    assert( memIsValid(u.cg.pRec) );
    u.cg.apVal[u.cg.i] = u.cg.pRec;
    memAboutToChange(p, u.cg.pRec);
    sqlite3VdbeMemStoreType(u.cg.pRec);
  }
  u.cf.ctx.pFunc = pOp->p4.pFunc;
  u.cg.ctx.pFunc = pOp->p4.pFunc;
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  u.cf.ctx.pMem = u.cf.pMem = &aMem[pOp->p3];
  u.cf.pMem->n++;
  u.cf.ctx.s.flags = MEM_Null;
  u.cf.ctx.s.z = 0;
  u.cf.ctx.s.zMalloc = 0;
  u.cf.ctx.s.xDel = 0;
  u.cf.ctx.s.db = db;
  u.cf.ctx.isError = 0;
  u.cf.ctx.pColl = 0;
  u.cf.ctx.skipFlag = 0;
  if( u.cf.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
  u.cg.ctx.pMem = u.cg.pMem = &aMem[pOp->p3];
  u.cg.pMem->n++;
  u.cg.ctx.s.flags = MEM_Null;
  u.cg.ctx.s.z = 0;
  u.cg.ctx.s.zMalloc = 0;
  u.cg.ctx.s.xDel = 0;
  u.cg.ctx.s.db = db;
  u.cg.ctx.isError = 0;
  u.cg.ctx.pColl = 0;
  u.cg.ctx.skipFlag = 0;
  if( u.cg.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
    assert( pOp>p->aOp );
    assert( pOp[-1].p4type==P4_COLLSEQ );
    assert( pOp[-1].opcode==OP_CollSeq );
    u.cf.ctx.pColl = pOp[-1].p4.pColl;
    u.cg.ctx.pColl = pOp[-1].p4.pColl;
  }
  (u.cf.ctx.pFunc->xStep)(&u.cf.ctx, u.cf.n, u.cf.apVal); /* IMP: R-24505-23230 */
  if( u.cf.ctx.isError ){
    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cf.ctx.s));
    rc = u.cf.ctx.isError;
  (u.cg.ctx.pFunc->xStep)(&u.cg.ctx, u.cg.n, u.cg.apVal); /* IMP: R-24505-23230 */
  if( u.cg.ctx.isError ){
    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cg.ctx.s));
    rc = u.cg.ctx.isError;
  }
  if( u.cf.ctx.skipFlag ){
  if( u.cg.ctx.skipFlag ){
    assert( pOp[-1].opcode==OP_CollSeq );
    u.cf.i = pOp[-1].p1;
    if( u.cf.i ) sqlite3VdbeMemSetInt64(&aMem[u.cf.i], 1);
    u.cg.i = pOp[-1].p1;
    if( u.cg.i ) sqlite3VdbeMemSetInt64(&aMem[u.cg.i], 1);
  }

  sqlite3VdbeMemRelease(&u.cf.ctx.s);
  sqlite3VdbeMemRelease(&u.cg.ctx.s);

  break;
}

/* Opcode: AggFinal P1 P2 * P4 *
**
** Execute the finalizer function for an aggregate.  P1 is
** the memory location that is the accumulator for the aggregate.
**
** P2 is the number of arguments that the step function takes and
** P4 is a pointer to the FuncDef for this function.  The P2
** argument is not used by this opcode.  It is only there to disambiguate
** functions that can take varying numbers of arguments.  The
** P4 argument is only needed for the degenerate case where
** the step function was not previously called.
*/
case OP_AggFinal: {
#if 0  /* local variables moved into u.cg */
#if 0  /* local variables moved into u.ch */
  Mem *pMem;
#endif /* local variables moved into u.cg */
#endif /* local variables moved into u.ch */
  assert( pOp->p1>0 && pOp->p1<=p->nMem );
  u.cg.pMem = &aMem[pOp->p1];
  assert( (u.cg.pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
  rc = sqlite3VdbeMemFinalize(u.cg.pMem, pOp->p4.pFunc);
  u.ch.pMem = &aMem[pOp->p1];
  assert( (u.ch.pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
  rc = sqlite3VdbeMemFinalize(u.ch.pMem, pOp->p4.pFunc);
  if( rc ){
    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cg.pMem));
    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.ch.pMem));
  }
  sqlite3VdbeChangeEncoding(u.cg.pMem, encoding);
  UPDATE_MAX_BLOBSIZE(u.cg.pMem);
  if( sqlite3VdbeMemTooBig(u.cg.pMem) ){
  sqlite3VdbeChangeEncoding(u.ch.pMem, encoding);
  UPDATE_MAX_BLOBSIZE(u.ch.pMem);
  if( sqlite3VdbeMemTooBig(u.ch.pMem) ){
    goto too_big;
  }
  break;
}

#ifndef SQLITE_OMIT_WAL
/* Opcode: Checkpoint P1 P2 P3 * *
**
** Checkpoint database P1. This is a no-op if P1 is not currently in
** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL
** or RESTART.  Write 1 or 0 into mem[P3] if the checkpoint returns
** SQLITE_BUSY or not, respectively.  Write the number of pages in the
** WAL after the checkpoint into mem[P3+1] and the number of pages
** in the WAL that have been checkpointed after the checkpoint
** completes into mem[P3+2].  However on an error, mem[P3+1] and
** mem[P3+2] are initialized to -1.
*/
case OP_Checkpoint: {
#if 0  /* local variables moved into u.ch */
#if 0  /* local variables moved into u.ci */
  int i;                          /* Loop counter */
  int aRes[3];                    /* Results */
  Mem *pMem;                      /* Write results here */
#endif /* local variables moved into u.ch */
#endif /* local variables moved into u.ci */

  u.ch.aRes[0] = 0;
  u.ch.aRes[1] = u.ch.aRes[2] = -1;
  u.ci.aRes[0] = 0;
  u.ci.aRes[1] = u.ci.aRes[2] = -1;
  assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
       || pOp->p2==SQLITE_CHECKPOINT_FULL
       || pOp->p2==SQLITE_CHECKPOINT_RESTART
  );
  rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.ch.aRes[1], &u.ch.aRes[2]);
  rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.ci.aRes[1], &u.ci.aRes[2]);
  if( rc==SQLITE_BUSY ){
    rc = SQLITE_OK;
    u.ch.aRes[0] = 1;
    u.ci.aRes[0] = 1;
  }
  for(u.ch.i=0, u.ch.pMem = &aMem[pOp->p3]; u.ch.i<3; u.ch.i++, u.ch.pMem++){
    sqlite3VdbeMemSetInt64(u.ch.pMem, (i64)u.ch.aRes[u.ch.i]);
  for(u.ci.i=0, u.ci.pMem = &aMem[pOp->p3]; u.ci.i<3; u.ci.i++, u.ci.pMem++){
    sqlite3VdbeMemSetInt64(u.ci.pMem, (i64)u.ci.aRes[u.ci.i]);
  }
  break;
};  
#endif

#ifndef SQLITE_OMIT_PRAGMA
/* Opcode: JournalMode P1 P2 P3 * P5
**
** Change the journal mode of database P1 to P3. P3 must be one of the
** PAGER_JOURNALMODE_XXX values. If changing between the various rollback
** modes (delete, truncate, persist, off and memory), this is a simple
** operation. No IO is required.
**
** If changing into or out of WAL mode the procedure is more complicated.
**
** Write a string containing the final journal-mode to register P2.
*/
case OP_JournalMode: {    /* out2-prerelease */
#if 0  /* local variables moved into u.ci */
#if 0  /* local variables moved into u.cj */
  Btree *pBt;                     /* Btree to change journal mode of */
  Pager *pPager;                  /* Pager associated with pBt */
  int eNew;                       /* New journal mode */
  int eOld;                       /* The old journal mode */
#ifndef SQLITE_OMIT_WAL
  const char *zFilename;          /* Name of database file for pPager */
#endif
#endif /* local variables moved into u.ci */
#endif /* local variables moved into u.cj */

  u.ci.eNew = pOp->p3;
  assert( u.ci.eNew==PAGER_JOURNALMODE_DELETE
       || u.ci.eNew==PAGER_JOURNALMODE_TRUNCATE
       || u.ci.eNew==PAGER_JOURNALMODE_PERSIST
       || u.ci.eNew==PAGER_JOURNALMODE_OFF
       || u.ci.eNew==PAGER_JOURNALMODE_MEMORY
       || u.ci.eNew==PAGER_JOURNALMODE_WAL
       || u.ci.eNew==PAGER_JOURNALMODE_QUERY
  u.cj.eNew = pOp->p3;
  assert( u.cj.eNew==PAGER_JOURNALMODE_DELETE
       || u.cj.eNew==PAGER_JOURNALMODE_TRUNCATE
       || u.cj.eNew==PAGER_JOURNALMODE_PERSIST
       || u.cj.eNew==PAGER_JOURNALMODE_OFF
       || u.cj.eNew==PAGER_JOURNALMODE_MEMORY
       || u.cj.eNew==PAGER_JOURNALMODE_WAL
       || u.cj.eNew==PAGER_JOURNALMODE_QUERY
  );
  assert( pOp->p1>=0 && pOp->p1<db->nDb );

  u.ci.pBt = db->aDb[pOp->p1].pBt;
  u.ci.pPager = sqlite3BtreePager(u.ci.pBt);
  u.ci.eOld = sqlite3PagerGetJournalMode(u.ci.pPager);
  if( u.ci.eNew==PAGER_JOURNALMODE_QUERY ) u.ci.eNew = u.ci.eOld;
  if( !sqlite3PagerOkToChangeJournalMode(u.ci.pPager) ) u.ci.eNew = u.ci.eOld;
  u.cj.pBt = db->aDb[pOp->p1].pBt;
  u.cj.pPager = sqlite3BtreePager(u.cj.pBt);
  u.cj.eOld = sqlite3PagerGetJournalMode(u.cj.pPager);
  if( u.cj.eNew==PAGER_JOURNALMODE_QUERY ) u.cj.eNew = u.cj.eOld;
  if( !sqlite3PagerOkToChangeJournalMode(u.cj.pPager) ) u.cj.eNew = u.cj.eOld;

#ifndef SQLITE_OMIT_WAL
  u.ci.zFilename = sqlite3PagerFilename(u.ci.pPager, 1);
  u.cj.zFilename = sqlite3PagerFilename(u.cj.pPager, 1);

  /* Do not allow a transition to journal_mode=WAL for a database
  ** in temporary storage or if the VFS does not support shared memory
  */
  if( u.ci.eNew==PAGER_JOURNALMODE_WAL
   && (sqlite3Strlen30(u.ci.zFilename)==0           /* Temp file */
       || !sqlite3PagerWalSupported(u.ci.pPager))   /* No shared-memory support */
  if( u.cj.eNew==PAGER_JOURNALMODE_WAL
   && (sqlite3Strlen30(u.cj.zFilename)==0           /* Temp file */
       || !sqlite3PagerWalSupported(u.cj.pPager))   /* No shared-memory support */
  ){
    u.ci.eNew = u.ci.eOld;
    u.cj.eNew = u.cj.eOld;
  }

  if( (u.ci.eNew!=u.ci.eOld)
   && (u.ci.eOld==PAGER_JOURNALMODE_WAL || u.ci.eNew==PAGER_JOURNALMODE_WAL)
  if( (u.cj.eNew!=u.cj.eOld)
   && (u.cj.eOld==PAGER_JOURNALMODE_WAL || u.cj.eNew==PAGER_JOURNALMODE_WAL)
  ){
    if( !db->autoCommit || db->activeVdbeCnt>1 ){
      rc = SQLITE_ERROR;
      sqlite3SetString(&p->zErrMsg, db,
          "cannot change %s wal mode from within a transaction",
          (u.ci.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
          (u.cj.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
      );
      break;
    }else{

      if( u.ci.eOld==PAGER_JOURNALMODE_WAL ){
      if( u.cj.eOld==PAGER_JOURNALMODE_WAL ){
        /* If leaving WAL mode, close the log file. If successful, the call
        ** to PagerCloseWal() checkpoints and deletes the write-ahead-log
        ** file. An EXCLUSIVE lock may still be held on the database file
        ** after a successful return.
        */
        rc = sqlite3PagerCloseWal(u.ci.pPager);
        rc = sqlite3PagerCloseWal(u.cj.pPager);
        if( rc==SQLITE_OK ){
          sqlite3PagerSetJournalMode(u.ci.pPager, u.ci.eNew);
          sqlite3PagerSetJournalMode(u.cj.pPager, u.cj.eNew);
        }
      }else if( u.ci.eOld==PAGER_JOURNALMODE_MEMORY ){
      }else if( u.cj.eOld==PAGER_JOURNALMODE_MEMORY ){
        /* Cannot transition directly from MEMORY to WAL.  Use mode OFF
        ** as an intermediate */
        sqlite3PagerSetJournalMode(u.ci.pPager, PAGER_JOURNALMODE_OFF);
        sqlite3PagerSetJournalMode(u.cj.pPager, PAGER_JOURNALMODE_OFF);
      }

      /* Open a transaction on the database file. Regardless of the journal
      ** mode, this transaction always uses a rollback journal.
      */
      assert( sqlite3BtreeIsInTrans(u.ci.pBt)==0 );
      assert( sqlite3BtreeIsInTrans(u.cj.pBt)==0 );
      if( rc==SQLITE_OK ){
        rc = sqlite3BtreeSetVersion(u.ci.pBt, (u.ci.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
        rc = sqlite3BtreeSetVersion(u.cj.pBt, (u.cj.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
      }
    }
  }
#endif /* ifndef SQLITE_OMIT_WAL */

  if( rc ){
    u.ci.eNew = u.ci.eOld;
    u.cj.eNew = u.cj.eOld;
  }
  u.ci.eNew = sqlite3PagerSetJournalMode(u.ci.pPager, u.ci.eNew);
  u.cj.eNew = sqlite3PagerSetJournalMode(u.cj.pPager, u.cj.eNew);

  pOut = &aMem[pOp->p2];
  pOut->flags = MEM_Str|MEM_Static|MEM_Term;
  pOut->z = (char *)sqlite3JournalModename(u.ci.eNew);
  pOut->z = (char *)sqlite3JournalModename(u.cj.eNew);
  pOut->n = sqlite3Strlen30(pOut->z);
  pOut->enc = SQLITE_UTF8;
  sqlite3VdbeChangeEncoding(pOut, encoding);
  break;
};
#endif /* SQLITE_OMIT_PRAGMA */

69282
69283
69284
69285
69286
69287
69288
69289

69290
69291

69292
69293
69294
69295
69296


69297
69298
69299
69300
69301
69302
69303
69437
69438
69439
69440
69441
69442
69443

69444
69445

69446
69447
69448
69449


69450
69451
69452
69453
69454
69455
69456
69457
69458







-
+

-
+



-
-
+
+







/* Opcode: IncrVacuum P1 P2 * * *
**
** Perform a single step of the incremental vacuum procedure on
** the P1 database. If the vacuum has finished, jump to instruction
** P2. Otherwise, fall through to the next instruction.
*/
case OP_IncrVacuum: {        /* jump */
#if 0  /* local variables moved into u.cj */
#if 0  /* local variables moved into u.ck */
  Btree *pBt;
#endif /* local variables moved into u.cj */
#endif /* local variables moved into u.ck */

  assert( pOp->p1>=0 && pOp->p1<db->nDb );
  assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
  u.cj.pBt = db->aDb[pOp->p1].pBt;
  rc = sqlite3BtreeIncrVacuum(u.cj.pBt);
  u.ck.pBt = db->aDb[pOp->p1].pBt;
  rc = sqlite3BtreeIncrVacuum(u.ck.pBt);
  if( rc==SQLITE_DONE ){
    pc = pOp->p2 - 1;
    rc = SQLITE_OK;
  }
  break;
}
#endif
69359
69360
69361
69362
69363
69364
69365
69366

69367
69368
69369
69370
69371




69372
69373
69374
69375
69376
69377
69378
69514
69515
69516
69517
69518
69519
69520

69521
69522




69523
69524
69525
69526
69527
69528
69529
69530
69531
69532
69533







-
+

-
-
-
-
+
+
+
+







** xBegin method for that table.
**
** Also, whether or not P4 is set, check that this is not being called from
** within a callback to a virtual table xSync() method. If it is, the error
** code will be set to SQLITE_LOCKED.
*/
case OP_VBegin: {
#if 0  /* local variables moved into u.ck */
#if 0  /* local variables moved into u.cl */
  VTable *pVTab;
#endif /* local variables moved into u.ck */
  u.ck.pVTab = pOp->p4.pVtab;
  rc = sqlite3VtabBegin(db, u.ck.pVTab);
  if( u.ck.pVTab ) importVtabErrMsg(p, u.ck.pVTab->pVtab);
#endif /* local variables moved into u.cl */
  u.cl.pVTab = pOp->p4.pVtab;
  rc = sqlite3VtabBegin(db, u.cl.pVTab);
  if( u.cl.pVTab ) importVtabErrMsg(p, u.cl.pVTab->pVtab);
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VCreate P1 * * P4 *
**
69403
69404
69405
69406
69407
69408
69409
69410

69411
69412
69413
69414
69415

69416
69417
69418
69419
69420
69421
69422
69423







69424
69425
69426

69427
69428
69429
69430
69431
69432




69433
69434
69435

69436
69437
69438
69439
69440
69441
69442
69558
69559
69560
69561
69562
69563
69564

69565
69566
69567
69568
69569

69570
69571







69572
69573
69574
69575
69576
69577
69578
69579
69580

69581
69582
69583




69584
69585
69586
69587
69588
69589

69590
69591
69592
69593
69594
69595
69596
69597







-
+




-
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+


-
+


-
-
-
-
+
+
+
+


-
+







/* Opcode: VOpen P1 * * P4 *
**
** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
** P1 is a cursor number.  This opcode opens a cursor to the virtual
** table and stores that cursor in P1.
*/
case OP_VOpen: {
#if 0  /* local variables moved into u.cl */
#if 0  /* local variables moved into u.cm */
  VdbeCursor *pCur;
  sqlite3_vtab_cursor *pVtabCursor;
  sqlite3_vtab *pVtab;
  sqlite3_module *pModule;
#endif /* local variables moved into u.cl */
#endif /* local variables moved into u.cm */

  u.cl.pCur = 0;
  u.cl.pVtabCursor = 0;
  u.cl.pVtab = pOp->p4.pVtab->pVtab;
  u.cl.pModule = (sqlite3_module *)u.cl.pVtab->pModule;
  assert(u.cl.pVtab && u.cl.pModule);
  rc = u.cl.pModule->xOpen(u.cl.pVtab, &u.cl.pVtabCursor);
  importVtabErrMsg(p, u.cl.pVtab);
  u.cm.pCur = 0;
  u.cm.pVtabCursor = 0;
  u.cm.pVtab = pOp->p4.pVtab->pVtab;
  u.cm.pModule = (sqlite3_module *)u.cm.pVtab->pModule;
  assert(u.cm.pVtab && u.cm.pModule);
  rc = u.cm.pModule->xOpen(u.cm.pVtab, &u.cm.pVtabCursor);
  importVtabErrMsg(p, u.cm.pVtab);
  if( SQLITE_OK==rc ){
    /* Initialize sqlite3_vtab_cursor base class */
    u.cl.pVtabCursor->pVtab = u.cl.pVtab;
    u.cm.pVtabCursor->pVtab = u.cm.pVtab;

    /* Initialise vdbe cursor object */
    u.cl.pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
    if( u.cl.pCur ){
      u.cl.pCur->pVtabCursor = u.cl.pVtabCursor;
      u.cl.pCur->pModule = u.cl.pVtabCursor->pVtab->pModule;
    u.cm.pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
    if( u.cm.pCur ){
      u.cm.pCur->pVtabCursor = u.cm.pVtabCursor;
      u.cm.pCur->pModule = u.cm.pVtabCursor->pVtab->pModule;
    }else{
      db->mallocFailed = 1;
      u.cl.pModule->xClose(u.cl.pVtabCursor);
      u.cm.pModule->xClose(u.cm.pVtabCursor);
    }
  }
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
69455
69456
69457
69458
69459
69460
69461
69462

69463
69464
69465
69466
69467
69468
69469
69470
69471
69472
69473
69474

69475
69476
69477
69478
69479
69480
69481
69482
69483
69484









69485
69486
69487
69488
69489



69490
69491
69492
69493
69494
69495
69496
69497





69498
69499
69500
69501

69502
69503

69504
69505

69506
69507
69508

69509
69510
69511
69512

69513
69514
69515
69516
69517
69518
69519
69520
69521
69522
69523
69524
69525
69526

69527
69528
69529
69530
69531

69532
69533
69534
69535
69536
69537


69538
69539

69540
69541
69542
69543
69544
69545




69546
69547
69548

69549
69550
69551
69552
69553


69554
69555
69556
69557
69558




69559
69560
69561
69562
69563

69564
69565
69566
69567
69568




69569
69570

69571
69572
69573
69574
69575
69576
69577
69578
69579
69580
69581
69582
69583
69584
69585

69586
69587
69588
69589
69590

69591
69592
69593
69594
69595




69596
69597
69598
69599
69600



69601
69602
69603
69604
69605
69606
69607
69608
69609

69610
69611

69612
69613

69614
69615
69616

69617
69618
69619
69620
69621
69622
69623
69624
69625
69626
69627
69628
69629
69630
69631
69632

69633
69634
69635

69636
69637
69638
69639
69640
69641
69642
69643
69644
69645
69646










69647
69648
69649


69650
69651
69652
69653
69654
69655
69656
69610
69611
69612
69613
69614
69615
69616

69617
69618
69619
69620
69621
69622
69623
69624
69625
69626
69627
69628

69629
69630









69631
69632
69633
69634
69635
69636
69637
69638
69639
69640
69641



69642
69643
69644
69645
69646
69647





69648
69649
69650
69651
69652
69653
69654
69655

69656
69657

69658
69659

69660
69661
69662

69663
69664
69665
69666

69667
69668
69669
69670
69671
69672
69673
69674
69675
69676
69677
69678
69679
69680

69681
69682
69683
69684
69685

69686
69687
69688
69689
69690


69691
69692
69693

69694
69695
69696




69697
69698
69699
69700
69701
69702

69703
69704
69705
69706


69707
69708
69709




69710
69711
69712
69713
69714
69715
69716
69717

69718
69719




69720
69721
69722
69723
69724

69725
69726
69727
69728
69729
69730
69731
69732
69733
69734
69735
69736
69737
69738
69739

69740
69741
69742
69743
69744

69745
69746




69747
69748
69749
69750
69751
69752



69753
69754
69755
69756
69757
69758
69759
69760
69761
69762
69763

69764
69765

69766
69767

69768
69769
69770

69771
69772
69773
69774
69775
69776
69777
69778
69779
69780
69781
69782
69783
69784
69785
69786

69787
69788
69789

69790
69791










69792
69793
69794
69795
69796
69797
69798
69799
69800
69801
69802


69803
69804
69805
69806
69807
69808
69809
69810
69811







-
+











-
+

-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+


-
-
-
+
+
+



-
-
-
-
-
+
+
+
+
+



-
+

-
+

-
+


-
+



-
+













-
+




-
+




-
-
+
+

-
+


-
-
-
-
+
+
+
+


-
+



-
-
+
+

-
-
-
-
+
+
+
+




-
+

-
-
-
-
+
+
+
+

-
+














-
+




-
+

-
-
-
-
+
+
+
+


-
-
-
+
+
+








-
+

-
+

-
+


-
+















-
+


-
+

-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+

-
-
+
+







** xFilter method. Registers P3+2..P3+1+argc are the argc
** additional parameters which are passed to
** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter.
**
** A jump is made to P2 if the result set after filtering would be empty.
*/
case OP_VFilter: {   /* jump */
#if 0  /* local variables moved into u.cm */
#if 0  /* local variables moved into u.cn */
  int nArg;
  int iQuery;
  const sqlite3_module *pModule;
  Mem *pQuery;
  Mem *pArgc;
  sqlite3_vtab_cursor *pVtabCursor;
  sqlite3_vtab *pVtab;
  VdbeCursor *pCur;
  int res;
  int i;
  Mem **apArg;
#endif /* local variables moved into u.cm */
#endif /* local variables moved into u.cn */

  u.cm.pQuery = &aMem[pOp->p3];
  u.cm.pArgc = &u.cm.pQuery[1];
  u.cm.pCur = p->apCsr[pOp->p1];
  assert( memIsValid(u.cm.pQuery) );
  REGISTER_TRACE(pOp->p3, u.cm.pQuery);
  assert( u.cm.pCur->pVtabCursor );
  u.cm.pVtabCursor = u.cm.pCur->pVtabCursor;
  u.cm.pVtab = u.cm.pVtabCursor->pVtab;
  u.cm.pModule = u.cm.pVtab->pModule;
  u.cn.pQuery = &aMem[pOp->p3];
  u.cn.pArgc = &u.cn.pQuery[1];
  u.cn.pCur = p->apCsr[pOp->p1];
  assert( memIsValid(u.cn.pQuery) );
  REGISTER_TRACE(pOp->p3, u.cn.pQuery);
  assert( u.cn.pCur->pVtabCursor );
  u.cn.pVtabCursor = u.cn.pCur->pVtabCursor;
  u.cn.pVtab = u.cn.pVtabCursor->pVtab;
  u.cn.pModule = u.cn.pVtab->pModule;

  /* Grab the index number and argc parameters */
  assert( (u.cm.pQuery->flags&MEM_Int)!=0 && u.cm.pArgc->flags==MEM_Int );
  u.cm.nArg = (int)u.cm.pArgc->u.i;
  u.cm.iQuery = (int)u.cm.pQuery->u.i;
  assert( (u.cn.pQuery->flags&MEM_Int)!=0 && u.cn.pArgc->flags==MEM_Int );
  u.cn.nArg = (int)u.cn.pArgc->u.i;
  u.cn.iQuery = (int)u.cn.pQuery->u.i;

  /* Invoke the xFilter method */
  {
    u.cm.res = 0;
    u.cm.apArg = p->apArg;
    for(u.cm.i = 0; u.cm.i<u.cm.nArg; u.cm.i++){
      u.cm.apArg[u.cm.i] = &u.cm.pArgc[u.cm.i+1];
      sqlite3VdbeMemStoreType(u.cm.apArg[u.cm.i]);
    u.cn.res = 0;
    u.cn.apArg = p->apArg;
    for(u.cn.i = 0; u.cn.i<u.cn.nArg; u.cn.i++){
      u.cn.apArg[u.cn.i] = &u.cn.pArgc[u.cn.i+1];
      sqlite3VdbeMemStoreType(u.cn.apArg[u.cn.i]);
    }

    p->inVtabMethod = 1;
    rc = u.cm.pModule->xFilter(u.cm.pVtabCursor, u.cm.iQuery, pOp->p4.z, u.cm.nArg, u.cm.apArg);
    rc = u.cn.pModule->xFilter(u.cn.pVtabCursor, u.cn.iQuery, pOp->p4.z, u.cn.nArg, u.cn.apArg);
    p->inVtabMethod = 0;
    importVtabErrMsg(p, u.cm.pVtab);
    importVtabErrMsg(p, u.cn.pVtab);
    if( rc==SQLITE_OK ){
      u.cm.res = u.cm.pModule->xEof(u.cm.pVtabCursor);
      u.cn.res = u.cn.pModule->xEof(u.cn.pVtabCursor);
    }

    if( u.cm.res ){
    if( u.cn.res ){
      pc = pOp->p2 - 1;
    }
  }
  u.cm.pCur->nullRow = 0;
  u.cn.pCur->nullRow = 0;

  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VColumn P1 P2 P3 * *
**
** Store the value of the P2-th column of
** the row of the virtual-table that the 
** P1 cursor is pointing to into register P3.
*/
case OP_VColumn: {
#if 0  /* local variables moved into u.cn */
#if 0  /* local variables moved into u.co */
  sqlite3_vtab *pVtab;
  const sqlite3_module *pModule;
  Mem *pDest;
  sqlite3_context sContext;
#endif /* local variables moved into u.cn */
#endif /* local variables moved into u.co */

  VdbeCursor *pCur = p->apCsr[pOp->p1];
  assert( pCur->pVtabCursor );
  assert( pOp->p3>0 && pOp->p3<=p->nMem );
  u.cn.pDest = &aMem[pOp->p3];
  memAboutToChange(p, u.cn.pDest);
  u.co.pDest = &aMem[pOp->p3];
  memAboutToChange(p, u.co.pDest);
  if( pCur->nullRow ){
    sqlite3VdbeMemSetNull(u.cn.pDest);
    sqlite3VdbeMemSetNull(u.co.pDest);
    break;
  }
  u.cn.pVtab = pCur->pVtabCursor->pVtab;
  u.cn.pModule = u.cn.pVtab->pModule;
  assert( u.cn.pModule->xColumn );
  memset(&u.cn.sContext, 0, sizeof(u.cn.sContext));
  u.co.pVtab = pCur->pVtabCursor->pVtab;
  u.co.pModule = u.co.pVtab->pModule;
  assert( u.co.pModule->xColumn );
  memset(&u.co.sContext, 0, sizeof(u.co.sContext));

  /* The output cell may already have a buffer allocated. Move
  ** the current contents to u.cn.sContext.s so in case the user-function
  ** the current contents to u.co.sContext.s so in case the user-function
  ** can use the already allocated buffer instead of allocating a
  ** new one.
  */
  sqlite3VdbeMemMove(&u.cn.sContext.s, u.cn.pDest);
  MemSetTypeFlag(&u.cn.sContext.s, MEM_Null);
  sqlite3VdbeMemMove(&u.co.sContext.s, u.co.pDest);
  MemSetTypeFlag(&u.co.sContext.s, MEM_Null);

  rc = u.cn.pModule->xColumn(pCur->pVtabCursor, &u.cn.sContext, pOp->p2);
  importVtabErrMsg(p, u.cn.pVtab);
  if( u.cn.sContext.isError ){
    rc = u.cn.sContext.isError;
  rc = u.co.pModule->xColumn(pCur->pVtabCursor, &u.co.sContext, pOp->p2);
  importVtabErrMsg(p, u.co.pVtab);
  if( u.co.sContext.isError ){
    rc = u.co.sContext.isError;
  }

  /* Copy the result of the function to the P3 register. We
  ** do this regardless of whether or not an error occurred to ensure any
  ** dynamic allocation in u.cn.sContext.s (a Mem struct) is  released.
  ** dynamic allocation in u.co.sContext.s (a Mem struct) is  released.
  */
  sqlite3VdbeChangeEncoding(&u.cn.sContext.s, encoding);
  sqlite3VdbeMemMove(u.cn.pDest, &u.cn.sContext.s);
  REGISTER_TRACE(pOp->p3, u.cn.pDest);
  UPDATE_MAX_BLOBSIZE(u.cn.pDest);
  sqlite3VdbeChangeEncoding(&u.co.sContext.s, encoding);
  sqlite3VdbeMemMove(u.co.pDest, &u.co.sContext.s);
  REGISTER_TRACE(pOp->p3, u.co.pDest);
  UPDATE_MAX_BLOBSIZE(u.co.pDest);

  if( sqlite3VdbeMemTooBig(u.cn.pDest) ){
  if( sqlite3VdbeMemTooBig(u.co.pDest) ){
    goto too_big;
  }
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VNext P1 P2 * * *
**
** Advance virtual table P1 to the next row in its result set and
** jump to instruction P2.  Or, if the virtual table has reached
** the end of its result set, then fall through to the next instruction.
*/
case OP_VNext: {   /* jump */
#if 0  /* local variables moved into u.co */
#if 0  /* local variables moved into u.cp */
  sqlite3_vtab *pVtab;
  const sqlite3_module *pModule;
  int res;
  VdbeCursor *pCur;
#endif /* local variables moved into u.co */
#endif /* local variables moved into u.cp */

  u.co.res = 0;
  u.co.pCur = p->apCsr[pOp->p1];
  assert( u.co.pCur->pVtabCursor );
  if( u.co.pCur->nullRow ){
  u.cp.res = 0;
  u.cp.pCur = p->apCsr[pOp->p1];
  assert( u.cp.pCur->pVtabCursor );
  if( u.cp.pCur->nullRow ){
    break;
  }
  u.co.pVtab = u.co.pCur->pVtabCursor->pVtab;
  u.co.pModule = u.co.pVtab->pModule;
  assert( u.co.pModule->xNext );
  u.cp.pVtab = u.cp.pCur->pVtabCursor->pVtab;
  u.cp.pModule = u.cp.pVtab->pModule;
  assert( u.cp.pModule->xNext );

  /* Invoke the xNext() method of the module. There is no way for the
  ** underlying implementation to return an error if one occurs during
  ** xNext(). Instead, if an error occurs, true is returned (indicating that
  ** data is available) and the error code returned when xColumn or
  ** some other method is next invoked on the save virtual table cursor.
  */
  p->inVtabMethod = 1;
  rc = u.co.pModule->xNext(u.co.pCur->pVtabCursor);
  rc = u.cp.pModule->xNext(u.cp.pCur->pVtabCursor);
  p->inVtabMethod = 0;
  importVtabErrMsg(p, u.co.pVtab);
  importVtabErrMsg(p, u.cp.pVtab);
  if( rc==SQLITE_OK ){
    u.co.res = u.co.pModule->xEof(u.co.pCur->pVtabCursor);
    u.cp.res = u.cp.pModule->xEof(u.cp.pCur->pVtabCursor);
  }

  if( !u.co.res ){
  if( !u.cp.res ){
    /* If there is data, jump to P2 */
    pc = pOp->p2 - 1;
  }
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VRename P1 * * P4 *
**
** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
** This opcode invokes the corresponding xRename method. The value
** in register P1 is passed as the zName argument to the xRename method.
*/
case OP_VRename: {
#if 0  /* local variables moved into u.cp */
#if 0  /* local variables moved into u.cq */
  sqlite3_vtab *pVtab;
  Mem *pName;
#endif /* local variables moved into u.cp */
#endif /* local variables moved into u.cq */

  u.cp.pVtab = pOp->p4.pVtab->pVtab;
  u.cp.pName = &aMem[pOp->p1];
  assert( u.cp.pVtab->pModule->xRename );
  assert( memIsValid(u.cp.pName) );
  REGISTER_TRACE(pOp->p1, u.cp.pName);
  assert( u.cp.pName->flags & MEM_Str );
  testcase( u.cp.pName->enc==SQLITE_UTF8 );
  testcase( u.cp.pName->enc==SQLITE_UTF16BE );
  testcase( u.cp.pName->enc==SQLITE_UTF16LE );
  rc = sqlite3VdbeChangeEncoding(u.cp.pName, SQLITE_UTF8);
  u.cq.pVtab = pOp->p4.pVtab->pVtab;
  u.cq.pName = &aMem[pOp->p1];
  assert( u.cq.pVtab->pModule->xRename );
  assert( memIsValid(u.cq.pName) );
  REGISTER_TRACE(pOp->p1, u.cq.pName);
  assert( u.cq.pName->flags & MEM_Str );
  testcase( u.cq.pName->enc==SQLITE_UTF8 );
  testcase( u.cq.pName->enc==SQLITE_UTF16BE );
  testcase( u.cq.pName->enc==SQLITE_UTF16LE );
  rc = sqlite3VdbeChangeEncoding(u.cq.pName, SQLITE_UTF8);
  if( rc==SQLITE_OK ){
    rc = u.cp.pVtab->pModule->xRename(u.cp.pVtab, u.cp.pName->z);
    importVtabErrMsg(p, u.cp.pVtab);
    rc = u.cq.pVtab->pModule->xRename(u.cq.pVtab, u.cq.pName->z);
    importVtabErrMsg(p, u.cq.pVtab);
    p->expired = 0;
  }
  break;
}
#endif

#ifndef SQLITE_OMIT_VIRTUALTABLE
69674
69675
69676
69677
69678
69679
69680
69681

69682
69683
69684
69685
69686
69687
69688
69689

69690
69691
69692
69693
69694
69695
69696



69697
69698

69699
69700
69701
69702
69703
69704
69705
69706
69707








69708
69709
69710

69711
69712

69713
69714
69715


69716
69717
69718
69719
69720
69721
69722
69829
69830
69831
69832
69833
69834
69835

69836
69837
69838
69839
69840
69841
69842
69843

69844
69845
69846
69847
69848



69849
69850
69851
69852

69853
69854








69855
69856
69857
69858
69859
69860
69861
69862
69863
69864

69865
69866

69867
69868


69869
69870
69871
69872
69873
69874
69875
69876
69877







-
+







-
+




-
-
-
+
+
+

-
+

-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+


-
+

-
+

-
-
+
+







** a row to delete.
**
** P1 is a boolean flag. If it is set to true and the xUpdate call
** is successful, then the value returned by sqlite3_last_insert_rowid() 
** is set to the value of the rowid for the row just inserted.
*/
case OP_VUpdate: {
#if 0  /* local variables moved into u.cq */
#if 0  /* local variables moved into u.cr */
  sqlite3_vtab *pVtab;
  sqlite3_module *pModule;
  int nArg;
  int i;
  sqlite_int64 rowid;
  Mem **apArg;
  Mem *pX;
#endif /* local variables moved into u.cq */
#endif /* local variables moved into u.cr */

  assert( pOp->p2==1        || pOp->p5==OE_Fail   || pOp->p5==OE_Rollback
       || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
  );
  u.cq.pVtab = pOp->p4.pVtab->pVtab;
  u.cq.pModule = (sqlite3_module *)u.cq.pVtab->pModule;
  u.cq.nArg = pOp->p2;
  u.cr.pVtab = pOp->p4.pVtab->pVtab;
  u.cr.pModule = (sqlite3_module *)u.cr.pVtab->pModule;
  u.cr.nArg = pOp->p2;
  assert( pOp->p4type==P4_VTAB );
  if( ALWAYS(u.cq.pModule->xUpdate) ){
  if( ALWAYS(u.cr.pModule->xUpdate) ){
    u8 vtabOnConflict = db->vtabOnConflict;
    u.cq.apArg = p->apArg;
    u.cq.pX = &aMem[pOp->p3];
    for(u.cq.i=0; u.cq.i<u.cq.nArg; u.cq.i++){
      assert( memIsValid(u.cq.pX) );
      memAboutToChange(p, u.cq.pX);
      sqlite3VdbeMemStoreType(u.cq.pX);
      u.cq.apArg[u.cq.i] = u.cq.pX;
      u.cq.pX++;
    u.cr.apArg = p->apArg;
    u.cr.pX = &aMem[pOp->p3];
    for(u.cr.i=0; u.cr.i<u.cr.nArg; u.cr.i++){
      assert( memIsValid(u.cr.pX) );
      memAboutToChange(p, u.cr.pX);
      sqlite3VdbeMemStoreType(u.cr.pX);
      u.cr.apArg[u.cr.i] = u.cr.pX;
      u.cr.pX++;
    }
    db->vtabOnConflict = pOp->p5;
    rc = u.cq.pModule->xUpdate(u.cq.pVtab, u.cq.nArg, u.cq.apArg, &u.cq.rowid);
    rc = u.cr.pModule->xUpdate(u.cr.pVtab, u.cr.nArg, u.cr.apArg, &u.cr.rowid);
    db->vtabOnConflict = vtabOnConflict;
    importVtabErrMsg(p, u.cq.pVtab);
    importVtabErrMsg(p, u.cr.pVtab);
    if( rc==SQLITE_OK && pOp->p1 ){
      assert( u.cq.nArg>1 && u.cq.apArg[0] && (u.cq.apArg[0]->flags&MEM_Null) );
      db->lastRowid = lastRowid = u.cq.rowid;
      assert( u.cr.nArg>1 && u.cr.apArg[0] && (u.cr.apArg[0]->flags&MEM_Null) );
      db->lastRowid = lastRowid = u.cr.rowid;
    }
    if( rc==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
      if( pOp->p5==OE_Ignore ){
        rc = SQLITE_OK;
      }else{
        p->errorAction = ((pOp->p5==OE_Replace) ? OE_Abort : pOp->p5);
      }
69768
69769
69770
69771
69772
69773
69774
69775

69776
69777
69778

69779
69780
69781
69782

69783
69784
69785
69786



69787
69788
69789
69790

69791
69792

69793
69794
69795
69796
69797
69798
69799
69923
69924
69925
69926
69927
69928
69929

69930
69931
69932

69933
69934
69935
69936

69937
69938



69939
69940
69941
69942
69943
69944

69945
69946

69947
69948
69949
69950
69951
69952
69953
69954







-
+


-
+



-
+

-
-
-
+
+
+



-
+

-
+







#ifndef SQLITE_OMIT_TRACE
/* Opcode: Trace * * * P4 *
**
** If tracing is enabled (by the sqlite3_trace()) interface, then
** the UTF-8 string contained in P4 is emitted on the trace callback.
*/
case OP_Trace: {
#if 0  /* local variables moved into u.cr */
#if 0  /* local variables moved into u.cs */
  char *zTrace;
  char *z;
#endif /* local variables moved into u.cr */
#endif /* local variables moved into u.cs */

  if( db->xTrace
   && !p->doingRerun
   && (u.cr.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
   && (u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
  ){
    u.cr.z = sqlite3VdbeExpandSql(p, u.cr.zTrace);
    db->xTrace(db->pTraceArg, u.cr.z);
    sqlite3DbFree(db, u.cr.z);
    u.cs.z = sqlite3VdbeExpandSql(p, u.cs.zTrace);
    db->xTrace(db->pTraceArg, u.cs.z);
    sqlite3DbFree(db, u.cs.z);
  }
#ifdef SQLITE_DEBUG
  if( (db->flags & SQLITE_SqlTrace)!=0
   && (u.cr.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
   && (u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
  ){
    sqlite3DebugPrintf("SQL-trace: %s\n", u.cr.zTrace);
    sqlite3DebugPrintf("SQL-trace: %s\n", u.cs.zTrace);
  }
#endif /* SQLITE_DEBUG */
  break;
}
#endif


72265
72266
72267
72268
72269
72270
72271
72272

72273
72274
72275
72276
72277
72278
72279
72420
72421
72422
72423
72424
72425
72426

72427
72428
72429
72430
72431
72432
72433
72434







-
+







  struct SrcList_item *pMatch = 0;  /* The matching pSrcList item */
  NameContext *pTopNC = pNC;        /* First namecontext in the list */
  Schema *pSchema = 0;              /* Schema of the expression */
  int isTrigger = 0;

  assert( pNC );     /* the name context cannot be NULL. */
  assert( zCol );    /* The Z in X.Y.Z cannot be NULL */
  assert( ~ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
  assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );

  /* Initialize the node to no-match */
  pExpr->iTable = -1;
  pExpr->pTab = 0;
  ExprSetIrreducible(pExpr);

  /* Start at the inner-most context and move outward until a match is found */
74269
74270
74271
74272
74273
74274
74275

74276
74277
74278
74279
74280
74281
74282
74424
74425
74426
74427
74428
74429
74430
74431
74432
74433
74434
74435
74436
74437
74438







+







  pNew = sqlite3DbMallocRaw(db, nByte );
  if( pNew==0 ) return 0;
  pNew->nSrc = pNew->nAlloc = p->nSrc;
  for(i=0; i<p->nSrc; i++){
    struct SrcList_item *pNewItem = &pNew->a[i];
    struct SrcList_item *pOldItem = &p->a[i];
    Table *pTab;
    pNewItem->pSchema = pOldItem->pSchema;
    pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
    pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
    pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
    pNewItem->jointype = pOldItem->jointype;
    pNewItem->iCursor = pOldItem->iCursor;
    pNewItem->addrFillSub = pOldItem->addrFillSub;
    pNewItem->regReturn = pOldItem->regReturn;
75405
75406
75407
75408
75409
75410
75411
75412

75413
75414
75415
75416
75417
75418
75419
75561
75562
75563
75564
75565
75566
75567

75568
75569
75570
75571
75572
75573
75574
75575







-
+







  assert( iReg>0 );  /* Register numbers are always positive */
  assert( iCol>=-1 && iCol<32768 );  /* Finite column numbers */

  /* The SQLITE_ColumnCache flag disables the column cache.  This is used
  ** for testing only - to verify that SQLite always gets the same answer
  ** with and without the column cache.
  */
  if( pParse->db->flags & SQLITE_ColumnCache ) return;
  if( OptimizationDisabled(pParse->db, SQLITE_ColumnCache) ) return;

  /* First replace any existing entry.
  **
  ** Actually, the way the column cache is currently used, we are guaranteed
  ** that the object will never already be in cache.  Verify this guarantee.
  */
#ifndef NDEBUG
75602
75603
75604
75605
75606
75607
75608
75609
75610


75611
75612
75613
75614
75615
75616
75617
75618
75619
75620
75621
75622
75623
75624
75625
75626
75627
75628
75629
75630
75631
75632
75633
75634
75635
75636
75637
75758
75759
75760
75761
75762
75763
75764


75765
75766
75767
75768
75769
75770
75771
75772
75773
75774












75775
75776
75777
75778
75779
75780
75781







-
-
+
+








-
-
-
-
-
-
-
-
-
-
-
-







/*
** Generate code to move content from registers iFrom...iFrom+nReg-1
** over to iTo..iTo+nReg-1. Keep the column cache up-to-date.
*/
SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
  int i;
  struct yColCache *p;
  if( NEVER(iFrom==iTo) ) return;
  sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
  assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo );
  sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg-1);
  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
    int x = p->iReg;
    if( x>=iFrom && x<iFrom+nReg ){
      p->iReg += iTo-iFrom;
    }
  }
}

/*
** Generate code to copy content from registers iFrom...iFrom+nReg-1
** over to iTo..iTo+nReg-1.
*/
SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, int iFrom, int iTo, int nReg){
  int i;
  if( NEVER(iFrom==iTo) ) return;
  for(i=0; i<nReg; i++){
    sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, iFrom+i, iTo+i);
  }
}

#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
/*
** Return true if any register in the range iFrom..iTo (inclusive)
** is used as part of the column cache.
**
** This routine is used within assert() and testcase() macros only
** and does not appear in a normal build.
76733
76734
76735
76736
76737
76738
76739
76740

76741
76742
76743
76744
76745
76746
76747
76877
76878
76879
76880
76881
76882
76883

76884
76885
76886
76887
76888
76889
76890
76891







-
+







** interface.  This allows test logic to verify that the same answer is
** obtained for queries regardless of whether or not constants are
** precomputed into registers or if they are inserted in-line.
*/
SQLITE_PRIVATE void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){
  Walker w;
  if( pParse->cookieGoto ) return;
  if( (pParse->db->flags & SQLITE_FactorOutConst)!=0 ) return;
  if( OptimizationDisabled(pParse->db, SQLITE_FactorOutConst) ) return;
  w.xExprCallback = evalConstExpr;
  w.xSelectCallback = 0;
  w.pParse = pParse;
  sqlite3WalkExpr(&w, pExpr);
}


77907
77908
77909
77910
77911
77912
77913
77914

77915
77916
77917
77918
77919
77920
77921
78051
78052
78053
78054
78055
78056
78057

78058
78059
78060
78061
78062
78063
78064
78065







-
+







  int savedDbFlags;         /* Saved value of db->flags */

  savedDbFlags = db->flags;  
  if( NEVER(db->mallocFailed) ) goto exit_rename_table;
  assert( pSrc->nSrc==1 );
  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );

  pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
  pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
  if( !pTab ) goto exit_rename_table;
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  zDb = db->aDb[iDb].zName;
  db->flags |= SQLITE_PreferBuiltin;

  /* Get a NULL terminated version of the new table name. */
  zName = sqlite3NameFromToken(db, pName);
78250
78251
78252
78253
78254
78255
78256
78257

78258
78259
78260
78261
78262
78263
78264
78394
78395
78396
78397
78398
78399
78400

78401
78402
78403
78404
78405
78406
78407
78408







-
+







  int nAlloc;
  sqlite3 *db = pParse->db;

  /* Look up the table being altered. */
  assert( pParse->pNewTable==0 );
  assert( sqlite3BtreeHoldsAllMutexes(db) );
  if( db->mallocFailed ) goto exit_begin_add_column;
  pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase);
  pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
  if( !pTab ) goto exit_begin_add_column;

#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( IsVirtual(pTab) ){
    sqlite3ErrorMsg(pParse, "virtual tables may not be altered");
    goto exit_begin_add_column;
  }
79881
79882
79883
79884
79885
79886
79887

79888
79889
79890
79891
79892
79893
79894
80025
80026
80027
80028
80029
80030
80031
80032
80033
80034
80035
80036
80037
80038
80039







+







  sqlite3 *db;

  if( NEVER(iDb<0) || iDb==1 ) return 0;
  db = pParse->db;
  assert( db->nDb>iDb );
  pFix->pParse = pParse;
  pFix->zDb = db->aDb[iDb].zName;
  pFix->pSchema = db->aDb[iDb].pSchema;
  pFix->zType = zType;
  pFix->pName = pName;
  return 1;
}

/*
** The following set of routines walk through the parse tree and assign
79911
79912
79913
79914
79915
79916
79917
79918

79919
79920
79921
79922
79923
79924
79925



79926
79927
79928
79929
79930
79931
79932
80056
80057
80058
80059
80060
80061
80062

80063


80064
80065
80066
80067
80068
80069
80070
80071
80072
80073
80074
80075
80076
80077
80078







-
+
-
-





+
+
+







  int i;
  const char *zDb;
  struct SrcList_item *pItem;

  if( NEVER(pList==0) ) return 0;
  zDb = pFix->zDb;
  for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
    if( pItem->zDatabase==0 ){
    if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
      pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb);
    }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){
      sqlite3ErrorMsg(pFix->pParse,
         "%s %T cannot reference objects in database %s",
         pFix->zType, pFix->pName, pItem->zDatabase);
      return 1;
    }
    sqlite3_free(pItem->zDatabase);
    pItem->zDatabase = 0;
    pItem->pSchema = pFix->pSchema;
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
    if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
    if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
#endif
  }
  return 0;
}
80575
80576
80577
80578
80579
80580
80581

























80582
80583
80584
80585
80586
80587
80588
80721
80722
80723
80724
80725
80726
80727
80728
80729
80730
80731
80732
80733
80734
80735
80736
80737
80738
80739
80740
80741
80742
80743
80744
80745
80746
80747
80748
80749
80750
80751
80752
80753
80754
80755
80756
80757
80758
80759







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    }else{
      sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
    }
    pParse->checkSchema = 1;
  }
  return p;
}

/*
** Locate the table identified by *p.
**
** This is a wrapper around sqlite3LocateTable(). The difference between
** sqlite3LocateTable() and this function is that this function restricts
** the search to schema (p->pSchema) if it is not NULL. p->pSchema may be
** non-NULL if it is part of a view or trigger program definition. See
** sqlite3FixSrcList() for details.
*/
SQLITE_PRIVATE Table *sqlite3LocateTableItem(
  Parse *pParse, 
  int isView, 
  struct SrcList_item *p
){
  const char *zDb;
  assert( p->pSchema==0 || p->zDatabase==0 );
  if( p->pSchema ){
    int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
    zDb = pParse->db->aDb[iDb].zName;
  }else{
    zDb = p->zDatabase;
  }
  return sqlite3LocateTable(pParse, isView, p->zName, zDb);
}

/*
** Locate the in-memory structure that describes 
** a particular index given the name of that index
** and the name of the database that contains the index.
** Return NULL if not found.
**
81552
81553
81554
81555
81556
81557
81558
81559

81560
81561
81562
81563
81564
81565
81566
81567
81568
81569
81723
81724
81725
81726
81727
81728
81729

81730



81731
81732
81733
81734
81735
81736
81737







-
+
-
-
-







  sqlite3 *db = pParse->db;
  u8 enc = ENC(db);
  u8 initbusy = db->init.busy;
  CollSeq *pColl;

  pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
  if( !initbusy && (!pColl || !pColl->xCmp) ){
    pColl = sqlite3GetCollSeq(db, enc, pColl, zName);
    pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName);
    if( !pColl ){
      sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
    }
  }

  return pColl;
}


/*
82254
82255
82256
82257
82258
82259
82260

82261
82262
82263
82264
82265
82266
82267
82422
82423
82424
82425
82426
82427
82428
82429
82430
82431
82432
82433
82434
82435
82436







+







        iLargest = iIdx;
      }
    }
    if( iLargest==0 ){
      return;
    }else{
      int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
      assert( iDb>=0 && iDb<pParse->db->nDb );
      destroyRootPage(pParse, iLargest, iDb);
      iDestroyed = iLargest;
    }
  }
#endif
}

82371
82372
82373
82374
82375
82376
82377
82378

82379
82380
82381
82382
82383
82384
82385
82386
82540
82541
82542
82543
82544
82545
82546

82547

82548
82549
82550
82551
82552
82553
82554







-
+
-








  if( db->mallocFailed ){
    goto exit_drop_table;
  }
  assert( pParse->nErr==0 );
  assert( pName->nSrc==1 );
  if( noErr ) db->suppressErr++;
  pTab = sqlite3LocateTable(pParse, isView, 
  pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
                            pName->a[0].zName, pName->a[0].zDatabase);
  if( noErr ) db->suppressErr--;

  if( pTab==0 ){
    if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
    goto exit_drop_table;
  }
  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
82812
82813
82814
82815
82816
82817
82818
82819
82820
82821



82822
82823
82824
82825
82826
82827
82828
82980
82981
82982
82983
82984
82985
82986



82987
82988
82989
82990
82991
82992
82993
82994
82995
82996







-
-
-
+
+
+







    if( sqlite3FixInit(&sFix, pParse, iDb, "index", pName) &&
        sqlite3FixSrcList(&sFix, pTblName)
    ){
      /* Because the parser constructs pTblName from a single identifier,
      ** sqlite3FixSrcList can never fail. */
      assert(0);
    }
    pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName, 
        pTblName->a[0].zDatabase);
    if( !pTab || db->mallocFailed ) goto exit_create_index;
    pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]);
    assert( db->mallocFailed==0 || pTab==0 );
    if( pTab==0 ) goto exit_create_index;
    assert( db->aDb[iDb].pSchema==pTab->pSchema );
  }else{
    assert( pName==0 );
    assert( pStart==0 );
    pTab = pParse->pNewTable;
    if( !pTab ) goto exit_create_index;
    iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
84173
84174
84175
84176
84177
84178
84179
84180

84181
84182
84183
84184
84185

84186
84187
84188
84189
84190

84191
84192
84193
84194
84195
84196
84197
84198
84199
84200
84201
84202
84203
84204
84205
84206



84207
84208
84209
84210
84211
84212
84213
84214
84215
84216
84217
84218
84219
84220
84221
84222
84223
84224
84225

84226
84227
84228
84229
84230
84231
84232
84233
84234
84235
84341
84342
84343
84344
84345
84346
84347

84348
84349
84350
84351
84352

84353
84354
84355
84356
84357
84358
84359
84360
84361
84362
84363
84364
84365
84366
84367
84368
84369
84370
84371
84372
84373
84374
84375
84376
84377
84378
84379
84380
84381
84382
84383
84384
84385
84386
84387
84388
84389
84390
84391
84392
84393
84394
84395
84396

84397
84398


84399
84400
84401
84402
84403
84404
84405







-
+




-
+





+
















+
+
+


















-
+

-
-







** requested collation sequence is not available in the desired encoding.
** 
** If it is not NULL, then pColl must point to the database native encoding 
** collation sequence with name zName, length nName.
**
** The return value is either the collation sequence to be used in database
** db for collation type name zName, length nName, or NULL, if no collation
** sequence can be found.
** sequence can be found.  If no collation is found, leave an error message.
**
** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
*/
SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(
  sqlite3* db,          /* The database connection */
  Parse *pParse,        /* Parsing context */
  u8 enc,               /* The desired encoding for the collating sequence */
  CollSeq *pColl,       /* Collating sequence with native encoding, or NULL */
  const char *zName     /* Collating sequence name */
){
  CollSeq *p;
  sqlite3 *db = pParse->db;

  p = pColl;
  if( !p ){
    p = sqlite3FindCollSeq(db, enc, zName, 0);
  }
  if( !p || !p->xCmp ){
    /* No collation sequence of this type for this encoding is registered.
    ** Call the collation factory to see if it can supply us with one.
    */
    callCollNeeded(db, enc, zName);
    p = sqlite3FindCollSeq(db, enc, zName, 0);
  }
  if( p && !p->xCmp && synthCollSeq(db, p) ){
    p = 0;
  }
  assert( !p || p->xCmp );
  if( p==0 ){
    sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
  }
  return p;
}

/*
** This routine is called on a collation sequence before it is used to
** check that it is defined. An undefined collation sequence exists when
** a database is loaded that contains references to collation sequences
** that have not been defined by sqlite3_create_collation() etc.
**
** If required, this routine calls the 'collation needed' callback to
** request a definition of the collating sequence. If this doesn't work, 
** an equivalent collating sequence that uses a text encoding different
** from the main database is substituted, if one is available.
*/
SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
  if( pColl ){
    const char *zName = pColl->zName;
    sqlite3 *db = pParse->db;
    CollSeq *p = sqlite3GetCollSeq(db, ENC(db), pColl, zName);
    CollSeq *p = sqlite3GetCollSeq(pParse, ENC(db), pColl, zName);
    if( !p ){
      sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
      pParse->nErr++;
      return SQLITE_ERROR;
    }
    assert( p==pColl );
  }
  return SQLITE_OK;
}

84608
84609
84610
84611
84612
84613
84614
84615

84616
84617
84618
84619
84620
84621
84622
84778
84779
84780
84781
84782
84783
84784

84785
84786
84787
84788
84789
84790
84791
84792







-
+







**    pSrc->a[0].pIndex     Pointer to the INDEXED BY index, if there is one
**
*/
SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
  struct SrcList_item *pItem = pSrc->a;
  Table *pTab;
  assert( pItem && pSrc->nSrc==1 );
  pTab = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
  pTab = sqlite3LocateTableItem(pParse, 0, pItem);
  sqlite3DeleteTable(pParse->db, pItem->pTab);
  pItem->pTab = pTab;
  if( pTab ){
    pTab->nRef++;
  }
  if( sqlite3IndexedByLookup(pParse, pItem) ){
    pTab = 0;
85214
85215
85216
85217
85218
85219
85220
85221



85222
85223
85224
85225
85226
85227
85228
85384
85385
85386
85387
85388
85389
85390

85391
85392
85393
85394
85395
85396
85397
85398
85399
85400







-
+
+
+







    }else{
      sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j);
      sqlite3ColumnDefault(v, pTab, idx, -1);
    }
  }
  if( doMakeRec ){
    const char *zAff;
    if( pTab->pSelect || (pParse->db->flags & SQLITE_IdxRealAsInt)!=0 ){
    if( pTab->pSelect
     || OptimizationDisabled(pParse->db, SQLITE_IdxRealAsInt)
    ){
      zAff = 0;
    }else{
      zAff = sqlite3IndexAffinityStr(v, pIdx);
    }
    sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
    sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT);
  }
89332
89333
89334
89335
89336
89337
89338



89339
89340
89341
89342
89343
89344
89345
89346
89347
89348
89349
89350
89351
89352
















89353
89354
89355
89356
89357
89358
89359
89504
89505
89506
89507
89508
89509
89510
89511
89512
89513














89514
89515
89516
89517
89518
89519
89520
89521
89522
89523
89524
89525
89526
89527
89528
89529
89530
89531
89532
89533
89534
89535
89536







+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







#ifndef SQLITE_OMIT_CHECK
  if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
    ExprList *pCheck = pTab->pCheck;
    pParse->ckBase = regData;
    onError = overrideError!=OE_Default ? overrideError : OE_Abort;
    for(i=0; i<pCheck->nExpr; i++){
      int allOk = sqlite3VdbeMakeLabel(v);
      Expr *pDup = sqlite3ExprDup(db, pCheck->a[i].pExpr, 0);
      if( !db->mallocFailed ){
        assert( pDup!=0 );
      sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
      if( onError==OE_Ignore ){
        sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
      }else{
        char *zConsName = pCheck->a[i].zName;
        if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
        if( zConsName ){
          zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
        }else{
          zConsName = 0;
        }
        sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
      }
      sqlite3VdbeResolveLabel(v, allOk);
        sqlite3ExprIfTrue(pParse, pDup, allOk, SQLITE_JUMPIFNULL);
        if( onError==OE_Ignore ){
          sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
        }else{
          char *zConsName = pCheck->a[i].zName;
          if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
          if( zConsName ){
            zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
          }else{
            zConsName = 0;
          }
          sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
        }
        sqlite3VdbeResolveLabel(v, allOk);
      }
      sqlite3ExprDelete(db, pDup);
    }
  }
#endif /* !defined(SQLITE_OMIT_CHECK) */

  /* If we have an INTEGER PRIMARY KEY, make sure the primary key
  ** of the new record does not previously exist.  Except, if this
  ** is an UPDATE and the primary key is not changing, that is OK.
89801
89802
89803
89804
89805
89806
89807
89808

89809
89810
89811
89812
89813
89814
89815
89978
89979
89980
89981
89982
89983
89984

89985
89986
89987
89988
89989
89990
89991
89992







-
+







  }

  /* At this point we have established that the statement is of the
  ** correct syntactic form to participate in this optimization.  Now
  ** we have to check the semantics.
  */
  pItem = pSelect->pSrc->a;
  pSrc = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
  pSrc = sqlite3LocateTableItem(pParse, 0, pItem);
  if( pSrc==0 ){
    return 0;   /* FROM clause does not contain a real table */
  }
  if( pSrc==pDest ){
    return 0;   /* tab1 and tab2 may not be the same table */
  }
#ifndef SQLITE_OMIT_VIRTUALTABLE
91579
91580
91581
91582
91583
91584
91585

91586
91587
91588
91589
91590
91591
91592
91756
91757
91758
91759
91760
91761
91762
91763
91764
91765
91766
91767
91768
91769
91770







+







  ** connection.  If it returns SQLITE_OK, then assume that the VFS
  ** handled the pragma and generate a no-op prepared statement.
  */
  aFcntl[0] = 0;
  aFcntl[1] = zLeft;
  aFcntl[2] = zRight;
  aFcntl[3] = 0;
  db->busyHandler.nBusy = 0;
  rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
  if( rc==SQLITE_OK ){
    if( aFcntl[0] ){
      int mem = ++pParse->nMem;
      sqlite3VdbeAddOp4(v, OP_String8, 0, mem, 0, aFcntl[0], 0);
      sqlite3VdbeSetNumCols(v, 1);
      sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC);
92456
92457
92458
92459
92460
92461
92462
92463

92464
92465
92466
92467
92468
92469
92470
92634
92635
92636
92637
92638
92639
92640

92641
92642
92643
92644
92645
92646
92647
92648







-
+







      /* Do the b-tree integrity checks */
      sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
      sqlite3VdbeChangeP5(v, (u8)i);
      addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2);
      sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
         sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
         P4_DYNAMIC);
      sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1);
      sqlite3VdbeAddOp2(v, OP_Move, 2, 4);
      sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
      sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
      sqlite3VdbeJumpHere(v, addr);

      /* Make sure all the indices are constructed correctly.
      */
      for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
92759
92760
92761
92762
92763
92764
92765
















92766
92767
92768
92769
92770
92771
92772
92773
92774
92775
92776
92777
92778
92779
92780
92781
92782
92783
92784
92785
92786
92787

92788
92789
92790
92791
92792
92793
92794
92937
92938
92939
92940
92941
92942
92943
92944
92945
92946
92947
92948
92949
92950
92951
92952
92953
92954
92955
92956
92957
92958
92959
92960
92961
92962
92963
92964
92965
92966
92967
92968
92969
92970
92971
92972
92973
92974

92975
92976
92977
92978
92979

92980
92981
92982
92983
92984
92985
92986
92987







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+















-





-
+







  ** This pragma attempts to free as much memory as possible from the
  ** current database connection.
  */
  if( sqlite3StrICmp(zLeft, "shrink_memory")==0 ){
    sqlite3_db_release_memory(db);
  }else

  /*
  **   PRAGMA busy_timeout
  **   PRAGMA busy_timeout = N
  **
  ** Call sqlite3_busy_timeout(db, N).  Return the current timeout value
  ** if one is set.  If no busy handler or a different busy handler is set
  ** then 0 is returned.  Setting the busy_timeout to 0 or negative
  ** disables the timeout.
  */
  if( sqlite3StrICmp(zLeft, "busy_timeout")==0 ){
    if( zRight ){
      sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
    }
    returnSingleInt(pParse, "timeout",  db->busyTimeout);
  }else

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
  /*
  ** Report the current state of file logs for all databases
  */
  if( sqlite3StrICmp(zLeft, "lock_status")==0 ){
    static const char *const azLockName[] = {
      "unlocked", "shared", "reserved", "pending", "exclusive"
    };
    int i;
    sqlite3VdbeSetNumCols(v, 2);
    pParse->nMem = 2;
    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", SQLITE_STATIC);
    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", SQLITE_STATIC);
    for(i=0; i<db->nDb; i++){
      Btree *pBt;
      Pager *pPager;
      const char *zState = "unknown";
      int j;
      if( db->aDb[i].zName==0 ) continue;
      sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, db->aDb[i].zName, P4_STATIC);
      pBt = db->aDb[i].pBt;
      if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){
      if( pBt==0 || sqlite3BtreePager(pBt)==0 ){
        zState = "closed";
      }else if( sqlite3_file_control(db, i ? db->aDb[i].zName : 0, 
                                     SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){
         zState = azLockName[j];
      }
      sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, zState, P4_STATIC);
      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
94246
94247
94248
94249
94250
94251
94252













94253
94254
94255
94256
94257
94258
94259
94260
94261
94262
94263
94264
94265
94266
94267
94268
94269

94270
94271
94272
94273
94274
94275
94276
94277
94278
94279
94280
94281
94282
94283
94284
94285

94286
94287
94288
94289
94290
94291
94292
94439
94440
94441
94442
94443
94444
94445
94446
94447
94448
94449
94450
94451
94452
94453
94454
94455
94456
94457
94458
94459
94460
94461
94462
94463
94464
94465
94466
94467
94468
94469
94470
94471
94472
94473
94474

94475
94476
94477
94478
94479
94480
94481
94482
94483
94484
94485
94486
94487
94488
94489
94490

94491
94492
94493
94494
94495
94496
94497
94498







+
+
+
+
+
+
+
+
+
+
+
+
+
















-
+















-
+







    return 1;
  }else{
    return 0;
  }
}
#endif

/*
** An instance of the following object is used to record information about
** how to process the DISTINCT keyword, to simplify passing that information
** into the selectInnerLoop() routine.
*/
typedef struct DistinctCtx DistinctCtx;
struct DistinctCtx {
  u8 isTnct;      /* True if the DISTINCT keyword is present */
  u8 eTnctType;   /* One of the WHERE_DISTINCT_* operators */
  int tabTnct;    /* Ephemeral table used for DISTINCT processing */
  int addrTnct;   /* Address of OP_OpenEphemeral opcode for tabTnct */
};

/*
** This routine generates the code for the inside of the inner loop
** of a SELECT.
**
** If srcTab and nColumn are both zero, then the pEList expressions
** are evaluated in order to get the data for this row.  If nColumn>0
** then data is pulled from srcTab and pEList is used only to get the
** datatypes for each column.
*/
static void selectInnerLoop(
  Parse *pParse,          /* The parser context */
  Select *p,              /* The complete select statement being coded */
  ExprList *pEList,       /* List of values being extracted */
  int srcTab,             /* Pull data from this table */
  int nColumn,            /* Number of columns in the source table */
  ExprList *pOrderBy,     /* If not NULL, sort results using this key */
  int distinct,           /* If >=0, make sure results are distinct */
  DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */
  SelectDest *pDest,      /* How to dispose of the results */
  int iContinue,          /* Jump here to continue with next row */
  int iBreak              /* Jump here to break out of the inner loop */
){
  Vdbe *v = pParse->pVdbe;
  int i;
  int hasDistinct;        /* True if the DISTINCT keyword is present */
  int regResult;              /* Start of memory holding result set */
  int eDest = pDest->eDest;   /* How to dispose of results */
  int iParm = pDest->iSDParm; /* First argument to disposal method */
  int nResultCol;             /* Number of result columns */

  assert( v );
  if( NEVER(v==0) ) return;
  assert( pEList!=0 );
  hasDistinct = distinct>=0;
  hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
  if( pOrderBy==0 && !hasDistinct ){
    codeOffset(v, p, iContinue);
  }

  /* Pull the requested columns.
  */
  if( nColumn>0 ){
94318
94319
94320
94321
94322
94323
94324













































94325




94326
94327
94328
94329
94330
94331
94332
94524
94525
94526
94527
94528
94529
94530
94531
94532
94533
94534
94535
94536
94537
94538
94539
94540
94541
94542
94543
94544
94545
94546
94547
94548
94549
94550
94551
94552
94553
94554
94555
94556
94557
94558
94559
94560
94561
94562
94563
94564
94565
94566
94567
94568
94569
94570
94571
94572
94573
94574
94575

94576
94577
94578
94579
94580
94581
94582
94583
94584
94585
94586







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+







  /* If the DISTINCT keyword was present on the SELECT statement
  ** and this row has been seen before, then do not make this row
  ** part of the result.
  */
  if( hasDistinct ){
    assert( pEList!=0 );
    assert( pEList->nExpr==nColumn );
    switch( pDistinct->eTnctType ){
      case WHERE_DISTINCT_ORDERED: {
        VdbeOp *pOp;            /* No longer required OpenEphemeral instr. */
        int iJump;              /* Jump destination */
        int regPrev;            /* Previous row content */

        /* Allocate space for the previous row */
        regPrev = pParse->nMem+1;
        pParse->nMem += nColumn;

        /* Change the OP_OpenEphemeral coded earlier to an OP_Null
        ** sets the MEM_Cleared bit on the first register of the
        ** previous value.  This will cause the OP_Ne below to always
        ** fail on the first iteration of the loop even if the first
        ** row is all NULLs.
        */
        sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct);
        pOp = sqlite3VdbeGetOp(v, pDistinct->addrTnct);
        pOp->opcode = OP_Null;
        pOp->p1 = 1;
        pOp->p2 = regPrev;

        iJump = sqlite3VdbeCurrentAddr(v) + nColumn;
        for(i=0; i<nColumn; i++){
          CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[i].pExpr);
          if( i<nColumn-1 ){
            sqlite3VdbeAddOp3(v, OP_Ne, regResult+i, iJump, regPrev+i);
          }else{
            sqlite3VdbeAddOp3(v, OP_Eq, regResult+i, iContinue, regPrev+i);
          }
          sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
          sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
        }
        assert( sqlite3VdbeCurrentAddr(v)==iJump );
        sqlite3VdbeAddOp3(v, OP_Copy, regResult, regPrev, nColumn-1);
        break;
      }

      case WHERE_DISTINCT_UNIQUE: {
        sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct);
        break;
      }

      default: {
        assert( pDistinct->eTnctType==WHERE_DISTINCT_UNORDERED );
    codeDistinct(pParse, distinct, iContinue, nColumn, regResult);
        codeDistinct(pParse, pDistinct->tabTnct, iContinue, nColumn, regResult);
        break;
      }
    }
    if( pOrderBy==0 ){
      codeOffset(v, p, iContinue);
    }
  }

  switch( eDest ){
    /* In this mode, write each query result to the key of the temporary
94376
94377
94378
94379
94380
94381
94382

94383

94384
94385
94386
94387
94388
94389
94390
94391
94392

94393
94394
94395
94396
94397
94398
94399
94630
94631
94632
94633
94634
94635
94636
94637

94638
94639
94640
94641
94642
94643
94644
94645
94646

94647
94648
94649
94650
94651
94652
94653
94654







+
-
+








-
+







#ifndef SQLITE_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: {
      assert( nColumn==1 );
      pDest->affSdst =
      p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst);
                  sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst);
      if( pOrderBy ){
        /* At first glance you would think we could optimize out the
        ** 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 */
        pushOntoSorter(pParse, pOrderBy, p, regResult);
      }else{
        int r1 = sqlite3GetTempReg(pParse);
        sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1);
        sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1);
        sqlite3ExprCacheAffinityChange(pParse, regResult, 1);
        sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
        sqlite3ReleaseTempReg(pParse, r1);
      }
      break;
    }

94652
94653
94654
94655
94656
94657
94658
94659


94660
94661
94662
94663
94664
94665
94666
94907
94908
94909
94910
94911
94912
94913

94914
94915
94916
94917
94918
94919
94920
94921
94922







-
+
+







      sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
      sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case SRT_Set: {
      assert( nColumn==1 );
      sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1);
      sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid,
                        &pDest->affSdst, 1);
      sqlite3ExprCacheAffinityChange(pParse, regRow, 1);
      sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid);
      break;
    }
    case SRT_Mem: {
      assert( nColumn==1 );
      sqlite3ExprCodeMove(pParse, regRow, iParm, 1);
95489
95490
95491
95492
95493
95494
95495
95496

95497
95498
95499
95500
95501
95502
95503
95745
95746
95747
95748
95749
95750
95751

95752
95753
95754
95755
95756
95757
95758
95759







-
+







        }
        iBreak = sqlite3VdbeMakeLabel(v);
        iCont = sqlite3VdbeMakeLabel(v);
        computeLimitRegisters(pParse, p, iBreak);
        sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak);
        iStart = sqlite3VdbeCurrentAddr(v);
        selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
                        0, -1, &dest, iCont, iBreak);
                        0, 0, &dest, iCont, iBreak);
        sqlite3VdbeResolveLabel(v, iCont);
        sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart);
        sqlite3VdbeResolveLabel(v, iBreak);
        sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
      }
      break;
    }
95567
95568
95569
95570
95571
95572
95573
95574

95575
95576
95577
95578
95579
95580
95581
95823
95824
95825
95826
95827
95828
95829

95830
95831
95832
95833
95834
95835
95836
95837







-
+







      computeLimitRegisters(pParse, p, iBreak);
      sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak);
      r1 = sqlite3GetTempReg(pParse);
      iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1);
      sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
      sqlite3ReleaseTempReg(pParse, r1);
      selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
                      0, -1, &dest, iCont, iBreak);
                      0, 0, &dest, iCont, iBreak);
      sqlite3VdbeResolveLabel(v, iCont);
      sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart);
      sqlite3VdbeResolveLabel(v, iBreak);
      sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
      sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
      break;
    }
95687
95688
95689
95690
95691
95692
95693
95694

95695
95696
95697
95698
95699
95700
95701
95943
95944
95945
95946
95947
95948
95949

95950
95951
95952
95953
95954
95955
95956
95957







-
+







  if( regPrev ){
    int j1, j2;
    j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev);
    j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
                              (char*)pKeyInfo, p4type);
    sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
    sqlite3VdbeJumpHere(v, j1);
    sqlite3ExprCodeCopy(pParse, pIn->iSdst, regPrev+1, pIn->nSdst);
    sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1);
    sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
  }
  if( pParse->db->mallocFailed ) return 0;

  /* Suppress the first OFFSET entries if there is an OFFSET clause
  */
  codeOffset(v, p, iContinue);
95722
95723
95724
95725
95726
95727
95728
95729

95730
95731
95732

95733
95734
95735
95736
95737
95738
95739
95978
95979
95980
95981
95982
95983
95984

95985
95986
95987

95988
95989
95990
95991
95992
95993
95994
95995







-
+


-
+







    /* 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;
      assert( pIn->nSdst==1 );
      p->affinity = 
      pDest->affSdst = 
         sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst);
      r1 = sqlite3GetTempReg(pParse);
      sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &p->affinity, 1);
      sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &pDest->affSdst,1);
      sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1);
      sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1);
      sqlite3ReleaseTempReg(pParse, r1);
      break;
    }

#if 0  /* Never occurs on an ORDER BY query */
96467
96468
96469
96470
96471
96472
96473
96474

96475
96476
96477
96478
96479
96480
96481
96723
96724
96725
96726
96727
96728
96729

96730
96731
96732
96733
96734
96735
96736
96737







-
+







  struct SrcList_item *pSubitem;   /* The subquery */
  sqlite3 *db = pParse->db;

  /* Check to see if flattening is permitted.  Return 0 if not.
  */
  assert( p!=0 );
  assert( p->pPrior==0 );  /* Unable to flatten compound queries */
  if( db->flags & SQLITE_QueryFlattener ) return 0;
  if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
  pSrc = p->pSrc;
  assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
  pSubitem = &pSrc->a[iFrom];
  iParent = pSubitem->iCursor;
  pSub = pSubitem->pSelect;
  assert( pSub!=0 );
  if( isAgg && subqueryIsAgg ) return 0;                 /* Restriction (1)  */
96990
96991
96992
96993
96994
96995
96996
96997

96998
96999
97000
97001
97002
97003
97004
97005
97246
97247
97248
97249
97250
97251
97252

97253

97254
97255
97256
97257
97258
97259
97260







-
+
-







      pTab->iPKey = -1;
      pTab->nRowEst = 1000000;
      pTab->tabFlags |= TF_Ephemeral;
#endif
    }else{
      /* An ordinary table or view name in the FROM clause */
      assert( pFrom->pTab==0 );
      pFrom->pTab = pTab = 
      pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
        sqlite3LocateTable(pParse,0,pFrom->zName,pFrom->zDatabase);
      if( pTab==0 ) return WRC_Abort;
      pTab->nRef++;
#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
      if( pTab->pSelect || IsVirtual(pTab) ){
        /* We reach here if the named table is a really a view */
        if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
        assert( pFrom->pSelect==0 );
97507
97508
97509
97510
97511
97512
97513
97514
97515
97516
97517
97518

97519
97520
97521
97522
97523
97524
97525
97762
97763
97764
97765
97766
97767
97768


97769
97770

97771
97772
97773
97774
97775
97776
97777
97778







-
-


-
+







  int isAgg;             /* True for select lists like "count(*)" */
  ExprList *pEList;      /* List of columns to extract. */
  SrcList *pTabList;     /* List of tables to select from */
  Expr *pWhere;          /* The WHERE clause.  May be NULL */
  ExprList *pOrderBy;    /* The ORDER BY clause.  May be NULL */
  ExprList *pGroupBy;    /* The GROUP BY clause.  May be NULL */
  Expr *pHaving;         /* The HAVING clause.  May be NULL */
  int isDistinct;        /* True if the DISTINCT keyword is present */
  int distinct;          /* Table to use for the distinct set */
  int rc = 1;            /* Value to return from this function */
  int addrSortIndex;     /* Address of an OP_OpenEphemeral instruction */
  int addrDistinctIndex; /* Address of an OP_OpenEphemeral instruction */
  DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */
  AggInfo sAggInfo;      /* Information used by aggregate queries */
  int iEnd;              /* Address of the end of the query */
  sqlite3 *db;           /* The database connection */

#ifndef SQLITE_OMIT_EXPLAIN
  int iRestoreSelectId = pParse->iSelectId;
  pParse->iSelectId = pParse->iNextSelectId++;
97637
97638
97639
97640
97641
97642
97643
97644

97645
97646
97647
97648
97649
97650
97651
97890
97891
97892
97893
97894
97895
97896

97897
97898
97899
97900
97901
97902
97903
97904







-
+







    }
  }
  pEList = p->pEList;
#endif
  pWhere = p->pWhere;
  pGroupBy = p->pGroupBy;
  pHaving = p->pHaving;
  isDistinct = (p->selFlags & SF_Distinct)!=0;
  sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0;

#ifndef SQLITE_OMIT_COMPOUND_SELECT
  /* If there is are a sequence of queries, do the earlier ones first.
  */
  if( p->pPrior ){
    if( p->pRightmost==0 ){
      Select *pLoop, *pRight = 0;
97672
97673
97674
97675
97676
97677
97678
97679

97680
97681
97682
97683
97684
97685
97686
97925
97926
97927
97928
97929
97930
97931

97932
97933
97934
97935
97936
97937
97938
97939







-
+







  ** identical, then disable the ORDER BY clause since the GROUP BY
  ** will cause elements to come out in the correct order.  This is
  ** an optimization - the correct answer should result regardless.
  ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER
  ** to disable this optimization for testing purposes.
  */
  if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0
         && (db->flags & SQLITE_GroupByOrder)==0 ){
         && OptimizationEnabled(db, SQLITE_GroupByOrder) ){
    pOrderBy = 0;
  }

  /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and 
  ** if the select-list is the same as the ORDER BY list, then this query
  ** can be rewritten as a GROUP BY. In other words, this:
  **
97698
97699
97700
97701
97702
97703
97704




97705
97706
97707
97708
97709
97710
97711
97951
97952
97953
97954
97955
97956
97957
97958
97959
97960
97961
97962
97963
97964
97965
97966
97967
97968







+
+
+
+







  if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct 
   && sqlite3ExprListCompare(pOrderBy, p->pEList)==0
  ){
    p->selFlags &= ~SF_Distinct;
    p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
    pGroupBy = p->pGroupBy;
    pOrderBy = 0;
    /* Notice that even thought SF_Distinct has been cleared from p->selFlags,
    ** the sDistinct.isTnct is still set.  Hence, isTnct represents the
    ** original setting of the SF_Distinct flag, not the current setting */
    assert( sDistinct.isTnct );
  }

  /* If there is an ORDER BY clause, then this sorting
  ** index might end up being unused if the data can be 
  ** extracted in pre-sorted order.  If that is the case, then the
  ** OP_OpenEphemeral instruction will be changed to an OP_Noop once
  ** we figure out that the sorting index is not needed.  The addrSortIndex
97738
97739
97740
97741
97742
97743
97744
97745
97746
97747




97748
97749

97750

97751
97752

97753
97754
97755
97756

97757

97758
97759
97760

97761
97762


97763
97764
97765
97766
97767
97768
97769
97770
97771
97772
97773
97774
97775
97776
97777
97778
97779
97780
97781
97782
97783
97784
97785
97786
97787
97788
97789
97790
97791
97792
97793
97794
97795
97796
97797
97798
97799
97800
97801
97802
97803
97804
97805
97806
97807
97808
97809
97810
97811
97812
97813
97814
97815
97816
97817
97818
97819
97820
97821
97822
97823
97824

97825
97826
97827
97828
97829
97830
97831


97832
97833
97834
97835
97836
97837
97838
97995
97996
97997
97998
97999
98000
98001



98002
98003
98004
98005


98006
98007
98008
98009

98010
98011
98012

98013
98014

98015
98016
98017

98018
98019
98020
98021
98022
98023
98024
98025
98026
98027
98028
98029
98030
98031
98032


















































98033

98034
98035
98036
98037
98038
98039
98040

98041
98042
98043
98044
98045
98046
98047
98048
98049







-
-
-
+
+
+
+
-
-
+

+

-
+


-

+
-
+


-
+


+
+










-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
+






-
+
+







    sqlite3VdbeGetOp(v, addrSortIndex)->opcode = OP_SorterOpen;
    p->selFlags |= SF_UseSorter;
  }

  /* Open a virtual index to use for the distinct set.
  */
  if( p->selFlags & SF_Distinct ){
    KeyInfo *pKeyInfo;
    distinct = pParse->nTab++;
    pKeyInfo = keyInfoFromExprList(pParse, p->pEList);
    sDistinct.tabTnct = pParse->nTab++;
    sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
                                sDistinct.tabTnct, 0, 0,
                                (char*)keyInfoFromExprList(pParse, p->pEList),
    addrDistinctIndex = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, distinct, 0, 0,
        (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
                                P4_KEYINFO_HANDOFF);
    sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
    sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
  }else{
    distinct = addrDistinctIndex = -1;
    sDistinct.eTnctType = WHERE_DISTINCT_NOOP;
  }

  /* Aggregate and non-aggregate queries are handled differently */
  if( !isAgg && pGroupBy==0 ){
    /* No aggregate functions and no GROUP BY clause */
    ExprList *pDist = (isDistinct ? p->pEList : 0);
    ExprList *pDist = (sDistinct.isTnct ? p->pEList : 0);

    /* Begin the database scan. */
    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pOrderBy, pDist, 0,0);
    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, pDist, 0,0);
    if( pWInfo==0 ) goto select_end;
    if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut;
    if( pWInfo->eDistinct ) sDistinct.eTnctType = pWInfo->eDistinct;
    if( pOrderBy && pWInfo->nOBSat==pOrderBy->nExpr ) pOrderBy = 0;

    /* If sorting index that was created by a prior OP_OpenEphemeral 
    ** instruction ended up not being needed, then change the OP_OpenEphemeral
    ** into an OP_Noop.
    */
    if( addrSortIndex>=0 && pOrderBy==0 ){
      sqlite3VdbeChangeToNoop(v, addrSortIndex);
      p->addrOpenEphm[2] = -1;
    }

    if( pWInfo->eDistinct ){
      VdbeOp *pOp;                /* No longer required OpenEphemeral instr. */
     
      assert( addrDistinctIndex>=0 );
      pOp = sqlite3VdbeGetOp(v, addrDistinctIndex);

      assert( isDistinct );
      assert( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED 
           || pWInfo->eDistinct==WHERE_DISTINCT_UNIQUE 
      );
      distinct = -1;
      if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED ){
        int iJump;
        int iExpr;
        int nExpr = pEList->nExpr;
        int iBase = pParse->nMem+1;
        int iBase2 = iBase + nExpr;
        pParse->nMem += (pEList->nExpr*2);

        /* Change the OP_OpenEphemeral coded earlier to an OP_Null
        ** sets the MEM_Cleared bit on the first register of the
        ** previous value.  This will cause the OP_Ne below to always
        ** fail on the first iteration of the loop even if the first
        ** row is all NULLs.
        */
        pOp->opcode = OP_Null;
        pOp->p1 = 1;
        pOp->p2 = iBase2;
        pOp->p3 = iBase2 + nExpr - 1;

        sqlite3ExprCodeExprList(pParse, pEList, iBase, 1);
        iJump = sqlite3VdbeCurrentAddr(v) + pEList->nExpr;
        for(iExpr=0; iExpr<nExpr; iExpr++){
          CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[iExpr].pExpr);
          if( iExpr<nExpr-1 ){
            sqlite3VdbeAddOp3(v, OP_Ne, iBase+iExpr, iJump, iBase2+iExpr);
          }else{
            sqlite3VdbeAddOp3(v, OP_Eq, iBase+iExpr, pWInfo->iContinue,
                              iBase2+iExpr);
          }
          sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
          sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
        }
        assert( sqlite3VdbeCurrentAddr(v)==iJump );
        sqlite3VdbeAddOp3(v, OP_Move, iBase, iBase2, pEList->nExpr);
      }else{
        pOp->opcode = OP_Noop;
      }
    }

    /* Use the standard inner loop. */
    selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, pDest,
    selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, &sDistinct, pDest,
                    pWInfo->iContinue, pWInfo->iBreak);

    /* End the database scan loop.
    */
    sqlite3WhereEnd(pWInfo);
  }else{
    /* This is the processing for aggregate queries */
    /* This case when there exist aggregate functions or a GROUP BY clause
    ** or both */
    NameContext sNC;    /* Name context for processing aggregate information */
    int iAMem;          /* First Mem address for storing current GROUP BY */
    int iBMem;          /* First Mem address for previous GROUP BY */
    int iUseFlag;       /* Mem address holding flag indicating that at least
                        ** one row of the input to the aggregator has been
                        ** processed */
    int iAbortFlag;     /* Mem address which causes query abort if positive */
97932
97933
97934
97935
97936
97937
97938
97939

97940
97941

97942
97943
97944
97945
97946
97947
97948
97949
97950
97951
97952
97953
97954
97955
97956
97957
97958
97959
97960


97961
97962
97963
97964
97965
97966
97967
98143
98144
98145
98146
98147
98148
98149

98150
98151

98152
98153
98154
98155
98156

98157
98158
98159
98160
98161
98162
98163
98164
98165
98166
98167
98168
98169

98170
98171
98172
98173
98174
98175
98176
98177
98178







-
+

-
+




-













-
+
+








      /* Begin a loop that will extract all source rows in GROUP BY order.
      ** This might involve two separate loops with an OP_Sort in between, or
      ** it might be a single loop that uses an index to extract information
      ** in the right order to begin with.
      */
      sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0, 0, 0);
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 0, 0);
      if( pWInfo==0 ) goto select_end;
      if( pGroupBy==0 ){
      if( pWInfo->nOBSat==pGroupBy->nExpr ){
        /* The optimizer is able to deliver rows in group by order so
        ** we do not have to sort.  The OP_OpenEphemeral table will be
        ** cancelled later because we still need to use the pKeyInfo
        */
        pGroupBy = p->pGroupBy;
        groupBySort = 0;
      }else{
        /* Rows are coming out in undetermined order.  We have to push
        ** each row into a sorting index, terminate the first loop,
        ** then loop over the sorting index in order to get the output
        ** in sorted order
        */
        int regBase;
        int regRecord;
        int nCol;
        int nGroupBy;

        explainTempTable(pParse, 
            isDistinct && !(p->selFlags&SF_Distinct)?"DISTINCT":"GROUP BY");
            (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ?
                    "DISTINCT" : "GROUP BY");

        groupBySort = 1;
        nGroupBy = pGroupBy->nExpr;
        nCol = nGroupBy + 1;
        j = nGroupBy+1;
        for(i=0; i<sAggInfo.nColumn; i++){
          if( sAggInfo.aCol[i].iSorterColumn>=j ){
98085
98086
98087
98088
98089
98090
98091
98092

98093
98094
98095
98096
98097
98098
98099
98296
98297
98298
98299
98300
98301
98302

98303
98304
98305
98306
98307
98308
98309
98310







-
+







      addrOutputRow = sqlite3VdbeCurrentAddr(v);
      sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2);
      VdbeComment((v, "Groupby result generator entry point"));
      sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
      finalizeAggFunctions(pParse, &sAggInfo);
      sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
      selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
                      distinct, pDest,
                      &sDistinct, pDest,
                      addrOutputRow+1, addrSetAbort);
      sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
      VdbeComment((v, "end groupby result generator"));

      /* Generate a subroutine that will reset the group-by accumulator
      */
      sqlite3VdbeResolveLabel(v, addrReset);
98188
98189
98190
98191
98192
98193
98194

98195
98196
98197
98198
98199
98200
98201
98202
98203
98204
98205
98206
98207
98208

98209
98210
98211
98212
98213
98214


98215
98216
98217
98218
98219
98220
98221
98222
98223
98224
98225

98226
98227
98228
98229
98230
98231
98232
98233

98234
98235
98236
98237
98238
98239
98240
98399
98400
98401
98402
98403
98404
98405
98406
98407
98408
98409
98410
98411
98412
98413
98414
98415
98416
98417
98418
98419

98420
98421
98422
98423
98424
98425

98426
98427
98428
98429
98430
98431
98432
98433
98434
98435
98436
98437

98438
98439
98440
98441
98442
98443
98444
98445

98446
98447
98448
98449
98450
98451
98452
98453







+













-
+





-
+
+










-
+







-
+







        **     satisfying the 'ORDER BY' clause than it does in other cases.
        **     Refer to code and comments in where.c for details.
        */
        ExprList *pMinMax = 0;
        u8 flag = minMaxQuery(p);
        if( flag ){
          assert( !ExprHasProperty(p->pEList->a[0].pExpr, EP_xIsSelect) );
          assert( p->pEList->a[0].pExpr->x.pList->nExpr==1 );
          pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->x.pList,0);
          pDel = pMinMax;
          if( pMinMax && !db->mallocFailed ){
            pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
            pMinMax->a[0].pExpr->op = TK_COLUMN;
          }
        }
  
        /* This case runs if the aggregate has no GROUP BY clause.  The
        ** processing is much simpler since there is only a single row
        ** of output.
        */
        resetAccumulator(pParse, &sAggInfo);
        pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pMinMax,0,flag,0);
        pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax,0,flag,0);
        if( pWInfo==0 ){
          sqlite3ExprListDelete(db, pDel);
          goto select_end;
        }
        updateAccumulator(pParse, &sAggInfo);
        if( !pMinMax && flag ){
        assert( pMinMax==0 || pMinMax->nExpr==1 );
        if( pWInfo->nOBSat>0 ){
          sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak);
          VdbeComment((v, "%s() by index",
                (flag==WHERE_ORDERBY_MIN?"min":"max")));
        }
        sqlite3WhereEnd(pWInfo);
        finalizeAggFunctions(pParse, &sAggInfo);
      }

      pOrderBy = 0;
      sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
      selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1, 
      selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, 0, 
                      pDest, addrEnd, addrEnd);
      sqlite3ExprListDelete(db, pDel);
    }
    sqlite3VdbeResolveLabel(v, addrEnd);
    
  } /* endif aggregate query */

  if( distinct>=0 ){
  if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){
    explainTempTable(pParse, "DISTINCT");
  }

  /* If there is an ORDER BY clause, then we need to sort the results
  ** and send them to the callback one by one.
  */
  if( pOrderBy ){
100975
100976
100977
100978
100979
100980
100981
100982

100983
100984
100985
100986
100987
100988
100989
101188
101189
101190
101191
101192
101193
101194

101195
101196
101197
101198
101199
101200
101201
101202







-
+







** database connection.
*/
SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){
  if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p);
  if( p->azModuleArg ){
    int i;
    for(i=0; i<p->nModuleArg; i++){
      sqlite3DbFree(db, p->azModuleArg[i]);
      if( i!=1 ) sqlite3DbFree(db, p->azModuleArg[i]);
    }
    sqlite3DbFree(db, p->azModuleArg);
  }
}

/*
** Add a new module argument to pTable->azModuleArg[].
101035
101036
101037
101038
101039
101040
101041
101042

101043
101044
101045
101046
101047
101048
101049
101248
101249
101250
101251
101252
101253
101254

101255
101256
101257
101258
101259
101260
101261
101262







-
+







  db = pParse->db;
  iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
  assert( iDb>=0 );

  pTable->tabFlags |= TF_Virtual;
  pTable->nModuleArg = 0;
  addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
  addModuleArgument(db, pTable, sqlite3DbStrDup(db, db->aDb[iDb].zName));
  addModuleArgument(db, pTable, 0);
  addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
  pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z);

#ifndef SQLITE_OMIT_AUTHORIZATION
  /* Creating a virtual table invokes the authorization callback twice.
  ** The first invocation, to obtain permission to INSERT a row into the
  ** sqlite_master table, has already been made by sqlite3StartTable().
101192
101193
101194
101195
101196
101197
101198

101199
101200
101201
101202
101203
101204
101205
101206
101207
101208
101209
101210
101211




101212
101213
101214
101215
101216
101217
101218
101219
101220
101221

101222
101223
101224
101225
101226
101227
101228
101405
101406
101407
101408
101409
101410
101411
101412
101413
101414
101415
101416
101417
101418
101419
101420
101421
101422
101423
101424
101425
101426
101427
101428
101429
101430
101431
101432
101433
101434
101435
101436
101437
101438
101439
101440
101441
101442
101443
101444
101445
101446
101447







+













+
+
+
+










+







  VtabCtx sCtx, *pPriorCtx;
  VTable *pVTable;
  int rc;
  const char *const*azArg = (const char *const*)pTab->azModuleArg;
  int nArg = pTab->nModuleArg;
  char *zErr = 0;
  char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
  int iDb;

  if( !zModuleName ){
    return SQLITE_NOMEM;
  }

  pVTable = sqlite3DbMallocZero(db, sizeof(VTable));
  if( !pVTable ){
    sqlite3DbFree(db, zModuleName);
    return SQLITE_NOMEM;
  }
  pVTable->db = db;
  pVTable->pMod = pMod;

  assert( pTab->azModuleArg[1]==0 );
  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  pTab->azModuleArg[1] = db->aDb[iDb].zName;

  /* Invoke the virtual table constructor */
  assert( &db->pVtabCtx );
  assert( xConstruct );
  sCtx.pTab = pTab;
  sCtx.pVTable = pVTable;
  pPriorCtx = db->pVtabCtx;
  db->pVtabCtx = &sCtx;
  rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
  db->pVtabCtx = pPriorCtx;
  if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
  pTab->azModuleArg[1] = 0;

  if( SQLITE_OK!=rc ){
    if( zErr==0 ){
      *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName);
    }else {
      *pzErr = sqlite3MPrintf(db, "%s", zErr);
      sqlite3_free(zErr);
101831
101832
101833
101834
101835
101836
101837
101838

101839
101840


101841
101842
101843
101844
101845
101846
101847
102050
102051
102052
102053
102054
102055
102056

102057
102058

102059
102060
102061
102062
102063
102064
102065
102066
102067







-
+

-
+
+







*/


/*
** Trace output macros
*/
#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
SQLITE_PRIVATE int sqlite3WhereTrace = 0;
/***/ int sqlite3WhereTrace = 0;
#endif
#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
#if defined(SQLITE_DEBUG) \
    && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE))
# define WHERETRACE(X)  if(sqlite3WhereTrace) sqlite3DebugPrintf X
#else
# define WHERETRACE(X)
#endif

/* Forward reference
*/
102064
102065
102066
102067
102068
102069
102070
102071
102072
102073
102074





102075
102076
102077
102078
102079

































102080
102081
102082
102083
102084
102085
102086
102284
102285
102286
102287
102288
102289
102290




102291
102292
102293
102294
102295
102296
102297
102298
102299
102300
102301
102302
102303
102304
102305
102306
102307
102308
102309
102310
102311
102312
102313
102314
102315
102316
102317
102318
102319
102320
102321
102322
102323
102324
102325
102326
102327
102328
102329
102330
102331
102332
102333
102334
102335
102336
102337
102338
102339
102340







-
-
-
-
+
+
+
+
+





+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







#define WHERE_COLUMN_NULL  0x00080000  /* x IS NULL */
#define WHERE_INDEXED      0x000f0000  /* Anything that uses an index */
#define WHERE_NOT_FULLSCAN 0x100f3000  /* Does not do a full table scan */
#define WHERE_IN_ABLE      0x000f1000  /* Able to support an IN operator */
#define WHERE_TOP_LIMIT    0x00100000  /* x<EXPR or x<=EXPR constraint */
#define WHERE_BTM_LIMIT    0x00200000  /* x>EXPR or x>=EXPR constraint */
#define WHERE_BOTH_LIMIT   0x00300000  /* Both x>EXPR and x<EXPR */
#define WHERE_IDX_ONLY     0x00800000  /* Use index only - omit table */
#define WHERE_ORDERBY      0x01000000  /* Output will appear in correct order */
#define WHERE_REVERSE      0x02000000  /* Scan in reverse order */
#define WHERE_UNIQUE       0x04000000  /* Selects no more than one row */
#define WHERE_IDX_ONLY     0x00400000  /* Use index only - omit table */
#define WHERE_ORDERED      0x00800000  /* Output will appear in correct order */
#define WHERE_REVERSE      0x01000000  /* Scan in reverse order */
#define WHERE_UNIQUE       0x02000000  /* Selects no more than one row */
#define WHERE_ALL_UNIQUE   0x04000000  /* This and all prior have one row */
#define WHERE_VIRTUALTABLE 0x08000000  /* Use virtual-table processing */
#define WHERE_MULTI_OR     0x10000000  /* OR using multiple indices */
#define WHERE_TEMP_INDEX   0x20000000  /* Uses an ephemeral index */
#define WHERE_DISTINCT     0x40000000  /* Correct order for DISTINCT */
#define WHERE_COVER_SCAN   0x80000000  /* Full scan of a covering index */

/*
** This module contains many separate subroutines that work together to
** find the best indices to use for accessing a particular table in a query.
** An instance of the following structure holds context information about the
** index search so that it can be more easily passed between the various
** routines.
*/
typedef struct WhereBestIdx WhereBestIdx;
struct WhereBestIdx {
  Parse *pParse;                  /* Parser context */
  WhereClause *pWC;               /* The WHERE clause */
  struct SrcList_item *pSrc;      /* The FROM clause term to search */
  Bitmask notReady;               /* Mask of cursors not available */
  Bitmask notValid;               /* Cursors not available for any purpose */
  ExprList *pOrderBy;             /* The ORDER BY clause */
  ExprList *pDistinct;            /* The select-list if query is DISTINCT */
  sqlite3_index_info **ppIdxInfo; /* Index information passed to xBestIndex */
  int i, n;                       /* Which loop is being coded; # of loops */
  WhereLevel *aLevel;             /* Info about outer loops */
  WhereCost cost;                 /* Lowest cost query plan */
};

/*
** Return TRUE if the probe cost is less than the baseline cost
*/
static int compareCost(const WhereCost *pProbe, const WhereCost *pBaseline){
  if( pProbe->rCost<pBaseline->rCost ) return 1;
  if( pProbe->rCost>pBaseline->rCost ) return 0;
  if( pProbe->plan.nOBSat>pBaseline->plan.nOBSat ) return 1;
  if( pProbe->plan.nRow<pBaseline->plan.nRow ) return 1;
  return 0;
}

/*
** Initialize a preallocated WhereClause structure.
*/
static void whereClauseInit(
  WhereClause *pWC,        /* The WhereClause to be initialized */
  Parse *pParse,           /* The parsing context */
103215
103216
103217
103218
103219
103220
103221
103222
103223
103224
103225
103226
103227
103228
103229
103230
103231
103232
103233
103234
103235
103236
103237
103238
103239
103240
103241
103242
103243
103244
103245
103246
103247
103469
103470
103471
103472
103473
103474
103475



















103476
103477
103478
103479
103480
103481
103482







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








  /* Prevent ON clause terms of a LEFT JOIN from being used to drive
  ** an index for tables to the left of the join.
  */
  pTerm->prereqRight |= extraRight;
}

/*
** Return TRUE if any of the expressions in pList->a[iFirst...] contain
** a reference to any table other than the iBase table.
*/
static int referencesOtherTables(
  ExprList *pList,          /* Search expressions in ths list */
  WhereMaskSet *pMaskSet,   /* Mapping from tables to bitmaps */
  int iFirst,               /* Be searching with the iFirst-th expression */
  int iBase                 /* Ignore references to this table */
){
  Bitmask allowed = ~getMask(pMaskSet, iBase);
  while( iFirst<pList->nExpr ){
    if( (exprTableUsage(pMaskSet, pList->a[iFirst++].pExpr)&allowed)!=0 ){
      return 1;
    }
  }
  return 0;
}

/*
** This function searches the expression list passed as the second argument
** for an expression of type TK_COLUMN that refers to the same column and
** uses the same collation sequence as the iCol'th column of index pIdx.
** Argument iBase is the cursor number used for the table that pIdx refers
** to.
**
103293
103294
103295
103296
103297
103298
103299

103300

103301
103302
103303
103304
103305
103306
103307
103528
103529
103530
103531
103532
103533
103534
103535

103536
103537
103538
103539
103540
103541
103542
103543







+
-
+







  int base,                       /* Cursor number for the table pIdx is on */
  ExprList *pDistinct,            /* The DISTINCT expressions */
  int nEqCol                      /* Number of index columns with == */
){
  Bitmask mask = 0;               /* Mask of unaccounted for pDistinct exprs */
  int i;                          /* Iterator variable */

  assert( pDistinct!=0 );
  if( pIdx->zName==0 || pDistinct==0 || pDistinct->nExpr>=BMS ) return 0;
  if( pIdx->zName==0 || pDistinct->nExpr>=BMS ) return 0;
  testcase( pDistinct->nExpr==BMS-1 );

  /* Loop through all the expressions in the distinct list. If any of them
  ** are not simple column references, return early. Otherwise, test if the
  ** WHERE clause contains a "col=X" clause. If it does, the expression
  ** can be ignored. If it does not, and the column does not belong to the
  ** same table as index pIdx, return early. Finally, if there is no
103395
103396
103397
103398
103399
103400
103401
103402
103403
103404
103405
103406
103407
103408
103409
103410
103411
103412
103413
103414
103415
103416
103417
103418
103419
103420
103421
103422
103423
103424
103425
103426
103427
103428
103429
103430
103431
103432
103433
103434
103435
103436
103437
103438
103439
103440
103441
103442
103443
103444
103445
103446
103447
103448
103449
103450
103451
103452
103453
103454
103455
103456
103457
103458
103459
103460
103461
103462
103463
103464
103465
103466
103467
103468
103469
103470
103471
103472
103473
103474
103475
103476
103477
103478
103479
103480
103481
103482
103483
103484
103485
103486
103487
103488
103489
103490
103491
103492
103493
103494
103495
103496
103497
103498
103499
103500
103501
103502
103503
103504
103505
103506
103507
103508
103509
103510
103511
103512
103513
103514
103515
103516
103517
103518
103519
103520
103521
103522
103523
103524
103525
103526
103527
103528
103529
103530
103531
103532
103533
103534
103535
103536
103537
103538
103539
103540
103541
103542
103543
103544
103545
103546
103547
103548
103549
103550
103551
103552
103553
103554
103555
103556
103557
103558
103559
103560
103561
103562
103563
103564
103565
103566
103567
103631
103632
103633
103634
103635
103636
103637































































































































































103638
103639
103640
103641
103642
103643
103644







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







      return 1;
    }
  }

  return 0;
}

/*
** This routine decides if pIdx can be used to satisfy the ORDER BY
** clause.  If it can, it returns 1.  If pIdx cannot satisfy the
** ORDER BY clause, this routine returns 0.
**
** pOrderBy is an ORDER BY clause from a SELECT statement.  pTab is the
** left-most table in the FROM clause of that same SELECT statement and
** the table has a cursor number of "base".  pIdx is an index on pTab.
**
** nEqCol is the number of columns of pIdx that are used as equality
** constraints.  Any of these columns may be missing from the ORDER BY
** clause and the match can still be a success.
**
** All terms of the ORDER BY that match against the index must be either
** ASC or DESC.  (Terms of the ORDER BY clause past the end of a UNIQUE
** index do not need to satisfy this constraint.)  The *pbRev value is
** set to 1 if the ORDER BY clause is all DESC and it is set to 0 if
** the ORDER BY clause is all ASC.
*/
static int isSortingIndex(
  Parse *pParse,          /* Parsing context */
  WhereMaskSet *pMaskSet, /* Mapping from table cursor numbers to bitmaps */
  Index *pIdx,            /* The index we are testing */
  int base,               /* Cursor number for the table to be sorted */
  ExprList *pOrderBy,     /* The ORDER BY clause */
  int nEqCol,             /* Number of index columns with == constraints */
  int wsFlags,            /* Index usages flags */
  int *pbRev              /* Set to 1 if ORDER BY is DESC */
){
  int i, j;                       /* Loop counters */
  int sortOrder = 0;              /* XOR of index and ORDER BY sort direction */
  int nTerm;                      /* Number of ORDER BY terms */
  struct ExprList_item *pTerm;    /* A term of the ORDER BY clause */
  sqlite3 *db = pParse->db;

  if( !pOrderBy ) return 0;
  if( wsFlags & WHERE_COLUMN_IN ) return 0;
  if( pIdx->bUnordered ) return 0;

  nTerm = pOrderBy->nExpr;
  assert( nTerm>0 );

  /* Argument pIdx must either point to a 'real' named index structure, 
  ** or an index structure allocated on the stack by bestBtreeIndex() to
  ** represent the rowid index that is part of every table.  */
  assert( pIdx->zName || (pIdx->nColumn==1 && pIdx->aiColumn[0]==-1) );

  /* Match terms of the ORDER BY clause against columns of
  ** the index.
  **
  ** Note that indices have pIdx->nColumn regular columns plus
  ** one additional column containing the rowid.  The rowid column
  ** of the index is also allowed to match against the ORDER BY
  ** clause.
  */
  for(i=j=0, pTerm=pOrderBy->a; j<nTerm && i<=pIdx->nColumn; i++){
    Expr *pExpr;       /* The expression of the ORDER BY pTerm */
    CollSeq *pColl;    /* The collating sequence of pExpr */
    int termSortOrder; /* Sort order for this term */
    int iColumn;       /* The i-th column of the index.  -1 for rowid */
    int iSortOrder;    /* 1 for DESC, 0 for ASC on the i-th index term */
    const char *zColl; /* Name of the collating sequence for i-th index term */

    pExpr = pTerm->pExpr;
    if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){
      /* Can not use an index sort on anything that is not a column in the
      ** left-most table of the FROM clause */
      break;
    }
    pColl = sqlite3ExprCollSeq(pParse, pExpr);
    if( !pColl ){
      pColl = db->pDfltColl;
    }
    if( pIdx->zName && i<pIdx->nColumn ){
      iColumn = pIdx->aiColumn[i];
      if( iColumn==pIdx->pTable->iPKey ){
        iColumn = -1;
      }
      iSortOrder = pIdx->aSortOrder[i];
      zColl = pIdx->azColl[i];
    }else{
      iColumn = -1;
      iSortOrder = 0;
      zColl = pColl->zName;
    }
    if( pExpr->iColumn!=iColumn || sqlite3StrICmp(pColl->zName, zColl) ){
      /* Term j of the ORDER BY clause does not match column i of the index */
      if( i<nEqCol ){
        /* If an index column that is constrained by == fails to match an
        ** ORDER BY term, that is OK.  Just ignore that column of the index
        */
        continue;
      }else if( i==pIdx->nColumn ){
        /* Index column i is the rowid.  All other terms match. */
        break;
      }else{
        /* If an index column fails to match and is not constrained by ==
        ** then the index cannot satisfy the ORDER BY constraint.
        */
        return 0;
      }
    }
    assert( pIdx->aSortOrder!=0 || iColumn==-1 );
    assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 );
    assert( iSortOrder==0 || iSortOrder==1 );
    termSortOrder = iSortOrder ^ pTerm->sortOrder;
    if( i>nEqCol ){
      if( termSortOrder!=sortOrder ){
        /* Indices can only be used if all ORDER BY terms past the
        ** equality constraints are all either DESC or ASC. */
        return 0;
      }
    }else{
      sortOrder = termSortOrder;
    }
    j++;
    pTerm++;
    if( iColumn<0 && !referencesOtherTables(pOrderBy, pMaskSet, j, base) ){
      /* If the indexed column is the primary key and everything matches
      ** so far and none of the ORDER BY terms to the right reference other
      ** tables in the join, then we are assured that the index can be used 
      ** to sort because the primary key is unique and so none of the other
      ** columns will make any difference
      */
      j = nTerm;
    }
  }

  *pbRev = sortOrder!=0;
  if( j>=nTerm ){
    /* All terms of the ORDER BY clause are covered by this index so
    ** this index can be used for sorting. */
    return 1;
  }
  if( pIdx->onError!=OE_None && i==pIdx->nColumn
      && (wsFlags & WHERE_COLUMN_NULL)==0
      && !referencesOtherTables(pOrderBy, pMaskSet, j, base) 
  ){
    Column *aCol = pIdx->pTable->aCol;

    /* All terms of this index match some prefix of the ORDER BY clause,
    ** the index is UNIQUE, and no terms on the tail of the ORDER BY
    ** refer to other tables in a join. So, assuming that the index entries
    ** visited contain no NULL values, then this index delivers rows in
    ** the required order.
    **
    ** It is not possible for any of the first nEqCol index fields to be
    ** NULL (since the corresponding "=" operator in the WHERE clause would 
    ** not be true). So if all remaining index columns have NOT NULL 
    ** constaints attached to them, we can be confident that the visited
    ** index entries are free of NULLs.  */
    for(i=nEqCol; i<pIdx->nColumn; i++){
      if( aCol[pIdx->aiColumn[i]].notNull==0 ) break;
    }
    return (i==pIdx->nColumn);
  }
  return 0;
}

/*
** Prepare a crude estimate of the logarithm of the input value.
** The results need not be exact.  This is only used for estimating
** the total cost of performing operations with O(logN) or O(NlogN)
** complexity.  Because N is just a guess, it is no great tragedy if
** logN is a little off.
*/
103618
103619
103620
103621
103622
103623
103624
103625

103626
103627
103628
103629
103630
103631
103632
103633
103634
103635
103636

103637
103638
103639
103640
103641
103642
103643
103644
103645


103646

103647
103648
103649

103650
103651
103652
103653
103654
103655
103656
103657
103658
103659
103660
103661
103662
103663

103664
103665
103666
103667
103668
103669
103670
103671
103672

103673




103674
103675
103676
103677
103678
103679
103680
103681


103682
103683
103684
103685
103686
103687
103688
103689
103690

103691

103692
103693
103694
103695
103696
103697
103698




103699
103700
103701
103702
103703

103704
103705
103706
103707
103708
103709
103710
103711
103712
103713
103714
103715
103716
103717
103718







103719
103720
103721
103722
103723
103724
103725
103695
103696
103697
103698
103699
103700
103701

103702


103703
103704
103705
103706
103707
103708
103709
103710

103711








103712
103713
103714

103715
103716
103717

103718
103719
103720
103721
103722
103723
103724
103725
103726
103727
103728
103729
103730
103731

103732
103733
103734
103735
103736
103737
103738
103739
103740
103741
103742
103743
103744
103745
103746
103747
103748

103749
103750
103751
103752


103753
103754
103755
103756
103757
103758
103759
103760
103761
103762
103763
103764

103765
103766
103767
103768




103769
103770
103771
103772
103773
103774
103775
103776

103777
103778
103779
103780
103781
103782
103783
103784
103785
103786






103787
103788
103789
103790
103791
103792
103793
103794
103795
103796
103797
103798
103799
103800







-
+
-
-








-
+
-
-
-
-
-
-
-
-

+
+
-
+


-
+













-
+









+

+
+
+
+

-




-
-
+
+









+
-
+



-
-
-
-
+
+
+
+




-
+









-
-
-
-
-
-
+
+
+
+
+
+
+







#define TRACE_IDX_INPUTS(A)
#define TRACE_IDX_OUTPUTS(A)
#endif

/* 
** Required because bestIndex() is called by bestOrClauseIndex() 
*/
static void bestIndex(
static void bestIndex(WhereBestIdx*);
    Parse*, WhereClause*, struct SrcList_item*,
    Bitmask, Bitmask, ExprList*, WhereCost*);

/*
** This routine attempts to find an scanning strategy that can be used 
** to optimize an 'OR' expression that is part of a WHERE clause. 
**
** The table associated with FROM clause term pSrc may be either a
** regular B-Tree table or a virtual table.
*/
static void bestOrClauseIndex(
static void bestOrClauseIndex(WhereBestIdx *p){
  Parse *pParse,              /* The parsing context */
  WhereClause *pWC,           /* The WHERE clause */
  struct SrcList_item *pSrc,  /* The FROM clause term to search */
  Bitmask notReady,           /* Mask of cursors not available for indexing */
  Bitmask notValid,           /* Cursors not available for any purpose */
  ExprList *pOrderBy,         /* The ORDER BY clause */
  WhereCost *pCost            /* Lowest cost query plan */
){
#ifndef SQLITE_OMIT_OR_OPTIMIZATION
  WhereClause *pWC = p->pWC;           /* The WHERE clause */
  struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */
  const int iCur = pSrc->iCursor;   /* The cursor of the table to be accessed */
  const int iCur = pSrc->iCursor;      /* The cursor of the table  */
  const Bitmask maskSrc = getMask(pWC->pMaskSet, iCur);  /* Bitmask for pSrc */
  WhereTerm * const pWCEnd = &pWC->a[pWC->nTerm];        /* End of pWC->a[] */
  WhereTerm *pTerm;                 /* A single term of the WHERE clause */
  WhereTerm *pTerm;                    /* A single term of the WHERE clause */

  /* The OR-clause optimization is disallowed if the INDEXED BY or
  ** NOT INDEXED clauses are used or if the WHERE_AND_ONLY bit is set. */
  if( pSrc->notIndexed || pSrc->pIndex!=0 ){
    return;
  }
  if( pWC->wctrlFlags & WHERE_AND_ONLY ){
    return;
  }

  /* Search the WHERE clause terms for a usable WO_OR term. */
  for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
    if( pTerm->eOperator==WO_OR 
     && ((pTerm->prereqAll & ~maskSrc) & notReady)==0
     && ((pTerm->prereqAll & ~maskSrc) & p->notReady)==0
     && (pTerm->u.pOrInfo->indexable & maskSrc)!=0 
    ){
      WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
      WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
      WhereTerm *pOrTerm;
      int flags = WHERE_MULTI_OR;
      double rTotal = 0;
      double nRow = 0;
      Bitmask used = 0;
      WhereBestIdx sBOI;

      sBOI = *p;
      sBOI.pOrderBy = 0;
      sBOI.pDistinct = 0;
      sBOI.ppIdxInfo = 0;
      for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
        WhereCost sTermCost;
        WHERETRACE(("... Multi-index OR testing for term %d of %d....\n", 
          (pOrTerm - pOrWC->a), (pTerm - pWC->a)
        ));
        if( pOrTerm->eOperator==WO_AND ){
          WhereClause *pAndWC = &pOrTerm->u.pAndInfo->wc;
          bestIndex(pParse, pAndWC, pSrc, notReady, notValid, 0, &sTermCost);
          sBOI.pWC = &pOrTerm->u.pAndInfo->wc;
          bestIndex(&sBOI);
        }else if( pOrTerm->leftCursor==iCur ){
          WhereClause tempWC;
          tempWC.pParse = pWC->pParse;
          tempWC.pMaskSet = pWC->pMaskSet;
          tempWC.pOuter = pWC;
          tempWC.op = TK_AND;
          tempWC.a = pOrTerm;
          tempWC.wctrlFlags = 0;
          tempWC.nTerm = 1;
          sBOI.pWC = &tempWC;
          bestIndex(pParse, &tempWC, pSrc, notReady, notValid, 0, &sTermCost);
          bestIndex(&sBOI);
        }else{
          continue;
        }
        rTotal += sTermCost.rCost;
        nRow += sTermCost.plan.nRow;
        used |= sTermCost.used;
        if( rTotal>=pCost->rCost ) break;
        rTotal += sBOI.cost.rCost;
        nRow += sBOI.cost.plan.nRow;
        used |= sBOI.cost.used;
        if( rTotal>=p->cost.rCost ) break;
      }

      /* If there is an ORDER BY clause, increase the scan cost to account 
      ** for the cost of the sort. */
      if( pOrderBy!=0 ){
      if( p->pOrderBy!=0 ){
        WHERETRACE(("... sorting increases OR cost %.9g to %.9g\n",
                    rTotal, rTotal+nRow*estLog(nRow)));
        rTotal += nRow*estLog(nRow);
      }

      /* If the cost of scanning using this OR term for optimization is
      ** less than the current cost stored in pCost, replace the contents
      ** of pCost. */
      WHERETRACE(("... multi-index OR cost=%.9g nrow=%.9g\n", rTotal, nRow));
      if( rTotal<pCost->rCost ){
        pCost->rCost = rTotal;
        pCost->used = used;
        pCost->plan.nRow = nRow;
        pCost->plan.wsFlags = flags;
        pCost->plan.u.pTerm = pTerm;
      if( rTotal<p->cost.rCost ){
        p->cost.rCost = rTotal;
        p->cost.used = used;
        p->cost.plan.nRow = nRow;
        p->cost.plan.nOBSat = p->i ? p->aLevel[p->i-1].plan.nOBSat : 0;
        p->cost.plan.wsFlags = flags;
        p->cost.plan.u.pTerm = pTerm;
      }
    }
  }
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
}

#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
103748
103749
103750
103751
103752
103753
103754
103755
103756
103757
103758




103759
103760
103761
103762
103763


103764
103765
103766
103767
103768
103769
103770
103771
103772
103773
103774
103775
103776
103777

103778
103779
103780
103781
103782
103783
103784
103785
103786
103787
103788
103789
103790
103791
103792
103793
103794
103795

103796
103797
103798
103799
103800
103801
103802
103803
103804

103805
103806
103807
103808
103809
103810





103811
103812
103813
103814
103815
103816

103817
103818
103819
103820
103821
103822
103823
103823
103824
103825
103826
103827
103828
103829




103830
103831
103832
103833





103834
103835
103836
103837
103838
103839
103840
103841
103842
103843
103844
103845
103846
103847
103848

103849
103850
103851
103852
103853
103854
103855
103856
103857
103858
103859
103860
103861
103862
103863
103864
103865
103866

103867
103868
103869
103870
103871
103872
103873
103874
103875

103876
103877





103878
103879
103880
103881
103882
103883
103884
103885
103886
103887

103888
103889
103890
103891
103892
103893
103894
103895







-
-
-
-
+
+
+
+
-
-
-
-
-
+
+













-
+

















-
+








-
+

-
-
-
-
-
+
+
+
+
+





-
+







** If the query plan for pSrc specified in pCost is a full table scan
** and indexing is allows (if there is no NOT INDEXED clause) and it
** possible to construct a transient index that would perform better
** than a full table scan even when the cost of constructing the index
** is taken into account, then alter the query plan to use the
** transient index.
*/
static void bestAutomaticIndex(
  Parse *pParse,              /* The parsing context */
  WhereClause *pWC,           /* The WHERE clause */
  struct SrcList_item *pSrc,  /* The FROM clause term to search */
static void bestAutomaticIndex(WhereBestIdx *p){
  Parse *pParse = p->pParse;            /* The parsing context */
  WhereClause *pWC = p->pWC;            /* The WHERE clause */
  struct SrcList_item *pSrc = p->pSrc;  /* The FROM clause term to search */
  Bitmask notReady,           /* Mask of cursors that are not available */
  WhereCost *pCost            /* Lowest cost query plan */
){
  double nTableRow;           /* Rows in the input table */
  double logN;                /* log(nTableRow) */
  double nTableRow;                     /* Rows in the input table */
  double logN;                          /* log(nTableRow) */
  double costTempIdx;         /* per-query cost of the transient index */
  WhereTerm *pTerm;           /* A single term of the WHERE clause */
  WhereTerm *pWCEnd;          /* End of pWC->a[] */
  Table *pTable;              /* Table tht might be indexed */

  if( pParse->nQueryLoop<=(double)1 ){
    /* There is no point in building an automatic index for a single scan */
    return;
  }
  if( (pParse->db->flags & SQLITE_AutoIndex)==0 ){
    /* Automatic indices are disabled at run-time */
    return;
  }
  if( (pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 ){
  if( (p->cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 ){
    /* We already have some kind of index in use for this query. */
    return;
  }
  if( pSrc->notIndexed ){
    /* The NOT INDEXED clause appears in the SQL. */
    return;
  }
  if( pSrc->isCorrelated ){
    /* The source is a correlated sub-query. No point in indexing it. */
    return;
  }

  assert( pParse->nQueryLoop >= (double)1 );
  pTable = pSrc->pTab;
  nTableRow = pTable->nRowEst;
  logN = estLog(nTableRow);
  costTempIdx = 2*logN*(nTableRow/pParse->nQueryLoop + 1);
  if( costTempIdx>=pCost->rCost ){
  if( costTempIdx>=p->cost.rCost ){
    /* The cost of creating the transient table would be greater than
    ** doing the full table scan */
    return;
  }

  /* Search for any equality comparison term */
  pWCEnd = &pWC->a[pWC->nTerm];
  for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
    if( termCanDriveIndex(pTerm, pSrc, notReady) ){
    if( termCanDriveIndex(pTerm, pSrc, p->notReady) ){
      WHERETRACE(("auto-index reduces cost from %.1f to %.1f\n",
                    pCost->rCost, costTempIdx));
      pCost->rCost = costTempIdx;
      pCost->plan.nRow = logN + 1;
      pCost->plan.wsFlags = WHERE_TEMP_INDEX;
      pCost->used = pTerm->prereqRight;
                    p->cost.rCost, costTempIdx));
      p->cost.rCost = costTempIdx;
      p->cost.plan.nRow = logN + 1;
      p->cost.plan.wsFlags = WHERE_TEMP_INDEX;
      p->cost.used = pTerm->prereqRight;
      break;
    }
  }
}
#else
# define bestAutomaticIndex(A,B,C,D,E)  /* no-op */
# define bestAutomaticIndex(A)  /* no-op */
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */


#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
/*
** Generate code to construct the Index object for an automatic index
** and to set up the WhereLevel object pLevel so that the code generator
103970
103971
103972
103973
103974
103975
103976
103977
103978
103979
103980
103981





103982
103983
103984
103985
103986
103987
103988
103989
104042
104043
104044
104045
104046
104047
104048





104049
104050
104051
104052
104053

104054
104055
104056
104057
104058
104059
104060







-
-
-
-
-
+
+
+
+
+
-








#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Allocate and populate an sqlite3_index_info structure. It is the 
** responsibility of the caller to eventually release the structure
** by passing the pointer returned by this function to sqlite3_free().
*/
static sqlite3_index_info *allocateIndexInfo(
  Parse *pParse, 
  WhereClause *pWC,
  struct SrcList_item *pSrc,
  ExprList *pOrderBy
static sqlite3_index_info *allocateIndexInfo(WhereBestIdx *p){
  Parse *pParse = p->pParse; 
  WhereClause *pWC = p->pWC;
  struct SrcList_item *pSrc = p->pSrc;
  ExprList *pOrderBy = p->pOrderBy;
){
  int i, j;
  int nTerm;
  struct sqlite3_index_constraint *pIdxCons;
  struct sqlite3_index_orderby *pIdxOrderBy;
  struct sqlite3_index_constraint_usage *pUsage;
  WhereTerm *pTerm;
  int nOrderBy;
104005
104006
104007
104008
104009
104010
104011

104012

104013
104014
104015
104016
104017


104018
104019
104020
104021
104022
104023
104024
104076
104077
104078
104079
104080
104081
104082
104083

104084
104085
104086
104087


104088
104089
104090
104091
104092
104093
104094
104095
104096







+
-
+



-
-
+
+








  /* If the ORDER BY clause contains only columns in the current 
  ** virtual table then allocate space for the aOrderBy part of
  ** the sqlite3_index_info structure.
  */
  nOrderBy = 0;
  if( pOrderBy ){
    int n = pOrderBy->nExpr;
    for(i=0; i<pOrderBy->nExpr; i++){
    for(i=0; i<n; i++){
      Expr *pExpr = pOrderBy->a[i].pExpr;
      if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break;
    }
    if( i==pOrderBy->nExpr ){
      nOrderBy = pOrderBy->nExpr;
    if( i==n){
      nOrderBy = n;
    }
  }

  /* Allocate the sqlite3_index_info structure
  */
  pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo)
                           + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm
104134
104135
104136
104137
104138
104139
104140
104141
104142
104143
104144




104145
104146
104147
104148
104149
104150
104151
104152
104153
104154
104155
104156
104157
104158
104159
104160
104161
104162
104163
104164
104165


104166
104167
104168
104169
104170

104171
104172

104173
104174
104175
104176
104177
104178
104179
104206
104207
104208
104209
104210
104211
104212




104213
104214
104215
104216






104217
104218
104219
104220
104221
104222
104223
104224
104225
104226
104227
104228
104229


104230
104231
104232
104233
104234
104235

104236
104237

104238
104239
104240
104241
104242
104243
104244
104245







-
-
-
-
+
+
+
+
-
-
-
-
-
-













-
-
+
+




-
+

-
+







** same virtual table.  The sqlite3_index_info structure is created
** and initialized on the first invocation and reused on all subsequent
** invocations.  The sqlite3_index_info structure is also used when
** code is generated to access the virtual table.  The whereInfoDelete() 
** routine takes care of freeing the sqlite3_index_info structure after
** everybody has finished with it.
*/
static void bestVirtualIndex(
  Parse *pParse,                  /* The parsing context */
  WhereClause *pWC,               /* The WHERE clause */
  struct SrcList_item *pSrc,      /* The FROM clause term to search */
static void bestVirtualIndex(WhereBestIdx *p){
  Parse *pParse = p->pParse;      /* The parsing context */
  WhereClause *pWC = p->pWC;      /* The WHERE clause */
  struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */
  Bitmask notReady,               /* Mask of cursors not available for index */
  Bitmask notValid,               /* Cursors not valid for any purpose */
  ExprList *pOrderBy,             /* The order by clause */
  WhereCost *pCost,               /* Lowest cost query plan */
  sqlite3_index_info **ppIdxInfo  /* Index information passed to xBestIndex */
){
  Table *pTab = pSrc->pTab;
  sqlite3_index_info *pIdxInfo;
  struct sqlite3_index_constraint *pIdxCons;
  struct sqlite3_index_constraint_usage *pUsage;
  WhereTerm *pTerm;
  int i, j;
  int nOrderBy;
  double rCost;

  /* Make sure wsFlags is initialized to some sane value. Otherwise, if the 
  ** malloc in allocateIndexInfo() fails and this function returns leaving
  ** wsFlags in an uninitialized state, the caller may behave unpredictably.
  */
  memset(pCost, 0, sizeof(*pCost));
  pCost->plan.wsFlags = WHERE_VIRTUALTABLE;
  memset(&p->cost, 0, sizeof(p->cost));
  p->cost.plan.wsFlags = WHERE_VIRTUALTABLE;

  /* If the sqlite3_index_info structure has not been previously
  ** allocated and initialized, then allocate and initialize it now.
  */
  pIdxInfo = *ppIdxInfo;
  pIdxInfo = *p->ppIdxInfo;
  if( pIdxInfo==0 ){
    *ppIdxInfo = pIdxInfo = allocateIndexInfo(pParse, pWC, pSrc, pOrderBy);
    *p->ppIdxInfo = pIdxInfo = allocateIndexInfo(p);
  }
  if( pIdxInfo==0 ){
    return;
  }

  /* At this point, the sqlite3_index_info structure that pIdxInfo points
  ** to will have been initialized, either during the current invocation or
104210
104211
104212
104213
104214
104215
104216
104217

104218
104219
104220
104221
104222
104223
104224
104225
104226
104227
104228
104229
104230

104231
104232
104233
104234
104235
104236
104237
104238
104239
104240
104241

104242
104243
104244
104245
104246
104247
104248
104249
104250

104251
104252
104253
104254
104255
104256
104257
104258
104259
104260
104261
104262

104263
104264

104265
104266

104267
104268




104269
104270

104271
104272
104273
104274
104275
104276

104277
104278
104279
104280
104281
104282
104283
104276
104277
104278
104279
104280
104281
104282

104283
104284
104285
104286
104287
104288
104289
104290
104291
104292
104293
104294
104295

104296
104297
104298
104299
104300
104301
104302
104303
104304
104305
104306

104307
104308
104309
104310
104311
104312
104313
104314
104315

104316
104317
104318
104319
104320
104321
104322
104323
104324
104325
104326
104327

104328
104329

104330
104331

104332
104333

104334
104335
104336
104337
104338

104339
104340
104341
104342
104343
104344

104345
104346
104347
104348
104349
104350
104351
104352







-
+












-
+










-
+








-
+











-
+

-
+

-
+

-
+
+
+
+

-
+





-
+







  ** each time.
  */
  pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
  pUsage = pIdxInfo->aConstraintUsage;
  for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
    j = pIdxCons->iTermOffset;
    pTerm = &pWC->a[j];
    pIdxCons->usable = (pTerm->prereqRight&notReady) ? 0 : 1;
    pIdxCons->usable = (pTerm->prereqRight&p->notReady) ? 0 : 1;
  }
  memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
  if( pIdxInfo->needToFreeIdxStr ){
    sqlite3_free(pIdxInfo->idxStr);
  }
  pIdxInfo->idxStr = 0;
  pIdxInfo->idxNum = 0;
  pIdxInfo->needToFreeIdxStr = 0;
  pIdxInfo->orderByConsumed = 0;
  /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
  pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
  nOrderBy = pIdxInfo->nOrderBy;
  if( !pOrderBy ){
  if( !p->pOrderBy ){
    pIdxInfo->nOrderBy = 0;
  }

  if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
    return;
  }

  pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
  for(i=0; i<pIdxInfo->nConstraint; i++){
    if( pUsage[i].argvIndex>0 ){
      pCost->used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight;
      p->cost.used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight;
    }
  }

  /* If there is an ORDER BY clause, and the selected virtual table index
  ** does not satisfy it, increase the cost of the scan accordingly. This
  ** matches the processing for non-virtual tables in bestBtreeIndex().
  */
  rCost = pIdxInfo->estimatedCost;
  if( pOrderBy && pIdxInfo->orderByConsumed==0 ){
  if( p->pOrderBy && pIdxInfo->orderByConsumed==0 ){
    rCost += estLog(rCost)*rCost;
  }

  /* The cost is not allowed to be larger than SQLITE_BIG_DBL (the
  ** inital value of lowestCost in this loop. If it is, then the
  ** (cost<lowestCost) test below will never be true.
  ** 
  ** Use "(double)2" instead of "2.0" in case OMIT_FLOATING_POINT 
  ** is defined.
  */
  if( (SQLITE_BIG_DBL/((double)2))<rCost ){
    pCost->rCost = (SQLITE_BIG_DBL/((double)2));
    p->cost.rCost = (SQLITE_BIG_DBL/((double)2));
  }else{
    pCost->rCost = rCost;
    p->cost.rCost = rCost;
  }
  pCost->plan.u.pVtabIdx = pIdxInfo;
  p->cost.plan.u.pVtabIdx = pIdxInfo;
  if( pIdxInfo->orderByConsumed ){
    pCost->plan.wsFlags |= WHERE_ORDERBY;
    p->cost.plan.wsFlags |= WHERE_ORDERED;
    p->cost.plan.nOBSat = nOrderBy;
  }else{
    p->cost.plan.nOBSat = p->i ? p->aLevel[p->i-1].plan.nOBSat : 0;
  }
  pCost->plan.nEq = 0;
  p->cost.plan.nEq = 0;
  pIdxInfo->nOrderBy = nOrderBy;

  /* Try to find a more efficient access pattern by using multiple indexes
  ** to optimize an OR expression within the WHERE clause. 
  */
  bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost);
  bestOrClauseIndex(p);
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifdef SQLITE_ENABLE_STAT3
/*
** Estimate the location of a particular key among all keys in an
** index.  Store the results in aStat as follows:
104357
104358
104359
104360
104361
104362
104363
104364

104365
104366
104367
104368
104369
104370
104371
104372
104373
104374
104426
104427
104428
104429
104430
104431
104432

104433
104434


104435
104436
104437
104438
104439
104440
104441







-
+

-
-







      CollSeq *pColl;
      const u8 *z;
      if( eType==SQLITE_BLOB ){
        z = (const u8 *)sqlite3_value_blob(pVal);
        pColl = db->pDfltColl;
        assert( pColl->enc==SQLITE_UTF8 );
      }else{
        pColl = sqlite3GetCollSeq(db, SQLITE_UTF8, 0, *pIdx->azColl);
        pColl = sqlite3GetCollSeq(pParse, SQLITE_UTF8, 0, *pIdx->azColl);
        if( pColl==0 ){
          sqlite3ErrorMsg(pParse, "no such collation sequence: %s",
                          *pIdx->azColl);
          return SQLITE_ERROR;
        }
        z = (const u8 *)sqlite3ValueText(pVal, pColl->enc);
        if( !z ){
          return SQLITE_NOMEM;
        }
        assert( z && pColl && pColl->xCmp );
104668
104669
104670
104671
104672
104673
104674









































































































































































































































































104675
104676
104677
104678

104679
104680
104681
104682
104683
104684
104685
104686
104735
104736
104737
104738
104739
104740
104741
104742
104743
104744
104745
104746
104747
104748
104749
104750
104751
104752
104753
104754
104755
104756
104757
104758
104759
104760
104761
104762
104763
104764
104765
104766
104767
104768
104769
104770
104771
104772
104773
104774
104775
104776
104777
104778
104779
104780
104781
104782
104783
104784
104785
104786
104787
104788
104789
104790
104791
104792
104793
104794
104795
104796
104797
104798
104799
104800
104801
104802
104803
104804
104805
104806
104807
104808
104809
104810
104811
104812
104813
104814
104815
104816
104817
104818
104819
104820
104821
104822
104823
104824
104825
104826
104827
104828
104829
104830
104831
104832
104833
104834
104835
104836
104837
104838
104839
104840
104841
104842
104843
104844
104845
104846
104847
104848
104849
104850
104851
104852
104853
104854
104855
104856
104857
104858
104859
104860
104861
104862
104863
104864
104865
104866
104867
104868
104869
104870
104871
104872
104873
104874
104875
104876
104877
104878
104879
104880
104881
104882
104883
104884
104885
104886
104887
104888
104889
104890
104891
104892
104893
104894
104895
104896
104897
104898
104899
104900
104901
104902
104903
104904
104905
104906
104907
104908
104909
104910
104911
104912
104913
104914
104915
104916
104917
104918
104919
104920
104921
104922
104923
104924
104925
104926
104927
104928
104929
104930
104931
104932
104933
104934
104935
104936
104937
104938
104939
104940
104941
104942
104943
104944
104945
104946
104947
104948
104949
104950
104951
104952
104953
104954
104955
104956
104957
104958
104959
104960
104961
104962
104963
104964
104965
104966
104967
104968
104969
104970
104971
104972
104973
104974
104975
104976
104977
104978
104979
104980
104981
104982
104983
104984
104985
104986
104987
104988
104989
104990
104991
104992
104993
104994
104995
104996
104997
104998
104999
105000
105001
105002
105003
105004
105005
105006
105007
105008
105009

105010

105011
105012
105013
105014
105015
105016
105017







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
+
-







    *pnRow = nRowEst;
    WHERETRACE(("IN row estimate: est=%g\n", nRowEst));
  }
  return rc;
}
#endif /* defined(SQLITE_ENABLE_STAT3) */

/*
** Check to see if column iCol of the table with cursor iTab will appear
** in sorted order according to the current query plan.
**
** Return values:
**
**    0   iCol is not ordered
**    1   iCol has only a single value
**    2   iCol is in ASC order
**    3   iCol is in DESC order
*/
static int isOrderedColumn(
  WhereBestIdx *p,
  int iTab,
  int iCol
){
  int i, j;
  WhereLevel *pLevel = &p->aLevel[p->i-1];
  Index *pIdx;
  u8 sortOrder;
  for(i=p->i-1; i>=0; i--, pLevel--){
    if( pLevel->iTabCur!=iTab ) continue;
    if( (pLevel->plan.wsFlags & WHERE_ALL_UNIQUE)!=0 ){
      return 1;
    }
    assert( (pLevel->plan.wsFlags & WHERE_ORDERED)!=0 );
    if( (pIdx = pLevel->plan.u.pIdx)!=0 ){
      if( iCol<0 ){
        sortOrder = 0;
        testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 );
      }else{
        int n = pIdx->nColumn;
        for(j=0; j<n; j++){
          if( iCol==pIdx->aiColumn[j] ) break;
        }
        if( j>=n ) return 0;
        sortOrder = pIdx->aSortOrder[j];
        testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 );
      }
    }else{
      if( iCol!=(-1) ) return 0;
      sortOrder = 0;
      testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 );
    }
    if( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 ){
      assert( sortOrder==0 || sortOrder==1 );
      testcase( sortOrder==1 );
      sortOrder = 1 - sortOrder;
    }
    return sortOrder+2;
  }
  return 0;
}

/*
** This routine decides if pIdx can be used to satisfy the ORDER BY
** clause, either in whole or in part.  The return value is the 
** cumulative number of terms in the ORDER BY clause that are satisfied
** by the index pIdx and other indices in outer loops.
**
** The table being queried has a cursor number of "base".  pIdx is the
** index that is postulated for use to access the table.
**
** The *pbRev value is set to 0 order 1 depending on whether or not
** pIdx should be run in the forward order or in reverse order.
*/
static int isSortingIndex(
  WhereBestIdx *p,    /* Best index search context */
  Index *pIdx,        /* The index we are testing */
  int base,           /* Cursor number for the table to be sorted */
  int *pbRev          /* Set to 1 for reverse-order scan of pIdx */
){
  int i;                        /* Number of pIdx terms used */
  int j;                        /* Number of ORDER BY terms satisfied */
  int sortOrder = 2;            /* 0: forward.  1: backward.  2: unknown */
  int nTerm;                    /* Number of ORDER BY terms */
  struct ExprList_item *pOBItem;/* A term of the ORDER BY clause */
  Table *pTab = pIdx->pTable;   /* Table that owns index pIdx */
  ExprList *pOrderBy;           /* The ORDER BY clause */
  Parse *pParse = p->pParse;    /* Parser context */
  sqlite3 *db = pParse->db;     /* Database connection */
  int nPriorSat;                /* ORDER BY terms satisfied by outer loops */
  int seenRowid = 0;            /* True if an ORDER BY rowid term is seen */
  int uniqueNotNull;            /* pIdx is UNIQUE with all terms are NOT NULL */

  if( p->i==0 ){
    nPriorSat = 0;
  }else{
    nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
    if( (p->aLevel[p->i-1].plan.wsFlags & WHERE_ORDERED)==0 ){
      /* This loop cannot be ordered unless the next outer loop is
      ** also ordered */
      return nPriorSat;
    }
    if( OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ){
      /* Only look at the outer-most loop if the OrderByIdxJoin
      ** optimization is disabled */
      return nPriorSat;
    }
  }
  pOrderBy = p->pOrderBy;
  assert( pOrderBy!=0 );
  if( pIdx->bUnordered ){
    /* Hash indices (indicated by the "unordered" tag on sqlite_stat1) cannot
    ** be used for sorting */
    return nPriorSat;
  }
  nTerm = pOrderBy->nExpr;
  uniqueNotNull = pIdx->onError!=OE_None;
  assert( nTerm>0 );

  /* Argument pIdx must either point to a 'real' named index structure, 
  ** or an index structure allocated on the stack by bestBtreeIndex() to
  ** represent the rowid index that is part of every table.  */
  assert( pIdx->zName || (pIdx->nColumn==1 && pIdx->aiColumn[0]==-1) );

  /* Match terms of the ORDER BY clause against columns of
  ** the index.
  **
  ** Note that indices have pIdx->nColumn regular columns plus
  ** one additional column containing the rowid.  The rowid column
  ** of the index is also allowed to match against the ORDER BY
  ** clause.
  */
  j = nPriorSat;
  for(i=0,pOBItem=&pOrderBy->a[j]; j<nTerm && i<=pIdx->nColumn; i++){
    Expr *pOBExpr;          /* The expression of the ORDER BY pOBItem */
    CollSeq *pColl;         /* The collating sequence of pOBExpr */
    int termSortOrder;      /* Sort order for this term */
    int iColumn;            /* The i-th column of the index.  -1 for rowid */
    int iSortOrder;         /* 1 for DESC, 0 for ASC on the i-th index term */
    int isEq;               /* Subject to an == or IS NULL constraint */
    int isMatch;            /* ORDER BY term matches the index term */
    const char *zColl;      /* Name of collating sequence for i-th index term */
    WhereTerm *pConstraint; /* A constraint in the WHERE clause */

    /* If the next term of the ORDER BY clause refers to anything other than
    ** a column in the "base" table, then this index will not be of any
    ** further use in handling the ORDER BY. */
    pOBExpr = pOBItem->pExpr;
    if( pOBExpr->op!=TK_COLUMN || pOBExpr->iTable!=base ){
      break;
    }

    /* Find column number and collating sequence for the next entry
    ** in the index */
    if( pIdx->zName && i<pIdx->nColumn ){
      iColumn = pIdx->aiColumn[i];
      if( iColumn==pIdx->pTable->iPKey ){
        iColumn = -1;
      }
      iSortOrder = pIdx->aSortOrder[i];
      zColl = pIdx->azColl[i];
      assert( zColl!=0 );
    }else{
      iColumn = -1;
      iSortOrder = 0;
      zColl = 0;
    }

    /* Check to see if the column number and collating sequence of the
    ** index match the column number and collating sequence of the ORDER BY
    ** clause entry.  Set isMatch to 1 if they both match. */
    if( pOBExpr->iColumn==iColumn ){
      if( zColl ){
        pColl = sqlite3ExprCollSeq(pParse, pOBExpr);
        if( !pColl ) pColl = db->pDfltColl;
        isMatch = sqlite3StrICmp(pColl->zName, zColl)==0;
      }else{
        isMatch = 1;
      }
    }else{
      isMatch = 0;
    }

    /* termSortOrder is 0 or 1 for whether or not the access loop should
    ** run forward or backwards (respectively) in order to satisfy this 
    ** term of the ORDER BY clause. */
    assert( pOBItem->sortOrder==0 || pOBItem->sortOrder==1 );
    assert( iSortOrder==0 || iSortOrder==1 );
    termSortOrder = iSortOrder ^ pOBItem->sortOrder;

    /* If X is the column in the index and ORDER BY clause, check to see
    ** if there are any X= or X IS NULL constraints in the WHERE clause. */
    pConstraint = findTerm(p->pWC, base, iColumn, p->notReady,
                           WO_EQ|WO_ISNULL|WO_IN, pIdx);
    if( pConstraint==0 ){
      isEq = 0;
    }else if( pConstraint->eOperator==WO_IN ){
      /* Constraints of the form: "X IN ..." cannot be used with an ORDER BY
      ** because we do not know in what order the values on the RHS of the IN
      ** operator will occur. */
      break;
    }else if( pConstraint->eOperator==WO_ISNULL ){
      uniqueNotNull = 0;
      isEq = 1;  /* "X IS NULL" means X has only a single value */
    }else if( pConstraint->prereqRight==0 ){
      isEq = 1;  /* Constraint "X=constant" means X has only a single value */
    }else{
      Expr *pRight = pConstraint->pExpr->pRight;
      if( pRight->op==TK_COLUMN ){
        WHERETRACE(("       .. isOrderedColumn(tab=%d,col=%d)",
                    pRight->iTable, pRight->iColumn));
        isEq = isOrderedColumn(p, pRight->iTable, pRight->iColumn);
        WHERETRACE((" -> isEq=%d\n", isEq));

        /* If the constraint is of the form X=Y where Y is an ordered value
        ** in an outer loop, then make sure the sort order of Y matches the
        ** sort order required for X. */
        if( isMatch && isEq>=2 && isEq!=pOBItem->sortOrder+2 ){
          testcase( isEq==2 );
          testcase( isEq==3 );
          break;
        }
      }else{
        isEq = 0;  /* "X=expr" places no ordering constraints on X */
      }
    }
    if( !isMatch ){
      if( isEq==0 ){
        break;
      }else{
        continue;
      }
    }else if( isEq!=1 ){
      if( sortOrder==2 ){
        sortOrder = termSortOrder;
      }else if( termSortOrder!=sortOrder ){
        break;
      }
    }
    j++;
    pOBItem++;
    if( iColumn<0 ){
      seenRowid = 1;
      break;
    }else if( pTab->aCol[iColumn].notNull==0 && isEq!=1 ){
      testcase( isEq==0 );
      testcase( isEq==2 );
      testcase( isEq==3 );
      uniqueNotNull = 0;
    }
  }

  /* If we have not found at least one ORDER BY term that matches the
  ** index, then show no progress. */
  if( pOBItem==&pOrderBy->a[nPriorSat] ) return nPriorSat;

  /* Return the necessary scan order back to the caller */
  *pbRev = sortOrder & 1;

  /* If there was an "ORDER BY rowid" term that matched, or it is only
  ** possible for a single row from this table to match, then skip over
  ** any additional ORDER BY terms dealing with this table.
  */
  if( seenRowid || (uniqueNotNull && i>=pIdx->nColumn) ){
    /* Advance j over additional ORDER BY terms associated with base */
    WhereMaskSet *pMS = p->pWC->pMaskSet;
    Bitmask m = ~getMask(pMS, base);
    while( j<nTerm && (exprTableUsage(pMS, pOrderBy->a[j].pExpr)&m)==0 ){
      j++;
    }
  }
  return j;
}

/*
** Find the best query plan for accessing a particular table.  Write the
** best query plan and its cost into the WhereCost object supplied as the
** best query plan and its cost into the p->cost.
** last parameter.
**
** The lowest cost plan wins.  The cost is an estimate of the amount of
** CPU and disk I/O needed to process the requested result.
** Factors that influence cost include:
**
**    *  The estimated number of rows that will be retrieved.  (The
**       fewer the better.)
104697
104698
104699
104700
104701
104702
104703
104704
104705
104706
104707




104708
104709
104710
104711
104712
104713
104714
104715
104716
104717
104718
104719
104720
104721
104722

104723
104724
104725
104726


104727
104728
104729
104730
104731
104732
104733
105028
105029
105030
105031
105032
105033
105034




105035
105036
105037
105038






105039
105040
105041
105042
105043
105044
105045
105046

105047
105048
105049


105050
105051
105052
105053
105054
105055
105056
105057
105058







-
-
-
-
+
+
+
+
-
-
-
-
-
-








-
+


-
-
+
+







** then the cost is calculated in the usual way.
**
** If a NOT INDEXED clause (pSrc->notIndexed!=0) was attached to the table 
** in the SELECT statement, then no indexes are considered. However, the 
** selected plan may still take advantage of the built-in rowid primary key
** index.
*/
static void bestBtreeIndex(
  Parse *pParse,              /* The parsing context */
  WhereClause *pWC,           /* The WHERE clause */
  struct SrcList_item *pSrc,  /* The FROM clause term to search */
static void bestBtreeIndex(WhereBestIdx *p){
  Parse *pParse = p->pParse;  /* The parsing context */
  WhereClause *pWC = p->pWC;  /* The WHERE clause */
  struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */
  Bitmask notReady,           /* Mask of cursors not available for indexing */
  Bitmask notValid,           /* Cursors not available for any purpose */
  ExprList *pOrderBy,         /* The ORDER BY clause */
  ExprList *pDistinct,        /* The select-list if query is DISTINCT */
  WhereCost *pCost            /* Lowest cost query plan */
){
  int iCur = pSrc->iCursor;   /* The cursor of the table to be accessed */
  Index *pProbe;              /* An index we are evaluating */
  Index *pIdx;                /* Copy of pProbe, or zero for IPK index */
  int eqTermMask;             /* Current mask of valid equality operators */
  int idxEqTermMask;          /* Index mask of valid equality operators */
  Index sPk;                  /* A fake index object for the primary key */
  tRowcnt aiRowEstPk[2];      /* The aiRowEst[] value for the sPk index */
  int aiColumnPk = -1;        /* The aColumn[] value for the sPk index */
  int wsFlagMask;             /* Allowed flags in pCost->plan.wsFlag */
  int wsFlagMask;             /* Allowed flags in p->cost.plan.wsFlag */

  /* Initialize the cost to a worst-case value */
  memset(pCost, 0, sizeof(*pCost));
  pCost->rCost = SQLITE_BIG_DBL;
  memset(&p->cost, 0, sizeof(p->cost));
  p->cost.rCost = SQLITE_BIG_DBL;

  /* If the pSrc table is the right table of a LEFT JOIN then we may not
  ** use an index to satisfy IS NULL constraints on that table.  This is
  ** because columns might end up being NULL if the table does not match -
  ** a circumstance which the index cannot help us discover.  Ticket #2177.
  */
  if( pSrc->jointype & JT_LEFT ){
104769
104770
104771
104772
104773
104774
104775
104776

104777
104778
104779
104780
104781
104782
104783
104784
104785
104786
104787

104788
104789
104790
104791
104792
104793
104794
105094
105095
105096
105097
105098
105099
105100

105101

105102



105103
105104
105105
105106
105107

105108
105109
105110
105111
105112
105113
105114
105115







-
+
-

-
-
-





-
+







    pIdx = 0;
  }

  /* Loop over all indices looking for the best one to use
  */
  for(; pProbe; pIdx=pProbe=pProbe->pNext){
    const tRowcnt * const aiRowEst = pProbe->aiRowEst;
    double cost;                /* Cost of using pProbe */
    WhereCost pc;               /* Cost of using pProbe */
    double nRow;                /* Estimated number of rows in result set */
    double log10N = (double)1;  /* base-10 logarithm of nRow (inexact) */
    int rev;                    /* True to scan in reverse order */
    int wsFlags = 0;
    Bitmask used = 0;

    /* The following variables are populated based on the properties of
    ** index being evaluated. They are then used to determine the expected
    ** cost and number of rows returned.
    **
    **  nEq: 
    **  pc.plan.nEq: 
    **    Number of equality terms that can be implemented using the index.
    **    In other words, the number of initial fields in the index that
    **    are used in == or IN or NOT NULL constraints of the WHERE clause.
    **
    **  nInMul:  
    **    The "in-multiplier". This is an estimate of how many seek operations 
    **    SQLite must perform on the index in question. For example, if the 
104823
104824
104825
104826
104827
104828
104829




104830
104831
104832
104833
104834
104835
104836
104837
104838
104839
104840
104841
104842
104843
104844
104845
104846
104847
104848
104849
104850
104851


104852


104853
104854
104855
104856
104857
















104858
104859
104860
104861




104862
104863

104864
104865
104866
104867

104868
104869
104870
104871
104872
104873
104874
104875
104876
104877

104878
104879
104880

104881
104882

104883
104884
104885
104886
104887
104888
104889
104890
104891

104892
104893
104894
104895
104896
104897
104898
104899









104900

104901
104902
104903
104904
104905






104906
104907
104908
104909


104910
104911
104912
104913
104914
104915


104916
104917
104918

104919
104920
104921
104922
104923
104924
104925
104926
104927
104928
104929
104930
104931

















104932
104933
104934
104935
104936
104937
104938




104939
104940
104941

104942
104943
104944
104945
104946
104947
104948

104949
104950
104951
104952
104953
104954
104955
104956
104957
104958
104959

104960
104961
104962
104963
104964
104965
104966
104967
104968
104969
104970
104971
104972




104973
104974
104975
104976
104977
104978
104979
104980
104981

104982

104983
104984
104985
104986
104987


104988
104989
104990


104991
104992
104993
104994
104995
104996
104997
104998
104999


105000
105001
105002
105003
105004
105005
105006
105007
105008
105009
105010
105011
105012
105013
105014

105015
105016
105017
105018

105019
105020
105021
105022
105023
105024
105025
105026
105027



105028
105029
105030
105031
105032
105033
105034
105035
105036
105037
105038






105039
105040
105041

105042
105043
105044
105045
105046
105047
105048
105049

105050
105051
105052
105053
105054
105055

105056
105057
105058
105059
105060
105061
105062

105063
105064
105065
105066
105067
105068
105069
105070
105071
105072


105073

105074
105075
105076

105077
105078
105079
105080
105081
105082
105083
105084
105085
105086
105087
105088
105089
105090
105091
105092
105093
105094
105095
105096
105097

105098
105099

105100
105101
105102
105103
105104

105105
105106

105107
105108
105109

105110
105111
105112
105113
105114
105115

105116
105117
105118
105119
105120
105121
105122
105123
105124
105125
105126
105127
105128
105129

105130
105131
105132
105133

105134
105135
105136

105137
105138
105139
105140
105141
105142
105143
105144
105145






105146
105147
105148
105149

105150
105151

105152
105153
105154

105155
105156
105157

105158
105159

105160
105161
105162
105163
105164
105165
105166
105167
105168
105169
105170
105171
105172
105173
105174
105175
105176
105177


105178
105179
105180
105181


105182
105183
105184


105185
105186
105187

105188
105189

105190
105191
105192
105193
105194



105195
105196
105197
105198
105199
105200
105201






105202
105203

105204
105205
105206
105207
105208
105209
105210
105211
105212
105213
105214
105215
105216
105217






105218
105219

105220
105221
105222
105223

105224
105225
105226
105227
105228
105229
105230
105144
105145
105146
105147
105148
105149
105150
105151
105152
105153
105154
105155
105156
105157
105158
105159
105160
105161
105162
105163
105164
105165
105166
105167
105168
105169

105170
105171
105172
105173


105174
105175
105176
105177
105178
105179
105180
105181
105182
105183
105184
105185
105186
105187
105188
105189
105190
105191
105192
105193
105194
105195
105196
105197
105198
105199




105200
105201
105202
105203
105204

105205
105206
105207
105208

105209
105210
105211
105212
105213
105214
105215
105216
105217
105218

105219
105220
105221

105222
105223

105224
105225
105226
105227
105228
105229
105230
105231
105232

105233
105234
105235






105236
105237
105238
105239
105240
105241
105242
105243
105244
105245
105246





105247
105248
105249
105250
105251
105252
105253
105254


105255
105256
105257
105258
105259
105260


105261
105262
105263
105264

105265
105266
105267
105268
105269
105270








105271
105272
105273
105274
105275
105276
105277
105278
105279
105280
105281
105282
105283
105284
105285
105286
105287
105288
105289
105290
105291



105292
105293
105294
105295
105296
105297

105298
105299
105300
105301
105302
105303
105304

105305
105306
105307
105308
105309
105310
105311
105312
105313
105314
105315

105316
105317
105318
105319
105320
105321
105322
105323
105324
105325




105326
105327
105328
105329
105330
105331
105332
105333
105334
105335
105336
105337
105338
105339

105340
105341
105342
105343
105344

105345
105346
105347
105348

105349
105350
105351
105352
105353
105354
105355
105356
105357


105358
105359
105360
105361
105362
105363
105364
105365
105366
105367
105368
105369
105370
105371
105372
105373

105374
105375
105376


105377

105378
105379
105380
105381
105382



105383
105384
105385
105386
105387
105388
105389
105390
105391
105392
105393
105394


105395
105396
105397
105398
105399
105400
105401
105402

105403
105404
105405
105406
105407
105408
105409
105410

105411
105412
105413
105414
105415
105416

105417
105418
105419
105420
105421
105422
105423

105424
105425
105426
105427
105428
105429
105430
105431
105432
105433
105434
105435
105436

105437
105438
105439

105440
105441
105442
105443
105444
105445
105446
105447
105448
105449
105450
105451
105452
105453
105454
105455
105456
105457
105458
105459
105460

105461
105462

105463
105464
105465
105466
105467

105468
105469

105470
105471
105472

105473
105474
105475
105476
105477
105478

105479
105480
105481
105482
105483
105484
105485
105486
105487
105488
105489
105490
105491
105492

105493
105494
105495
105496

105497
105498
105499

105500
105501
105502
105503
105504





105505
105506
105507
105508
105509
105510
105511
105512
105513

105514
105515

105516



105517



105518


105519
105520
105521
105522
105523
105524
105525
105526
105527
105528
105529
105530
105531
105532
105533
105534
105535


105536
105537
105538
105539


105540
105541
105542


105543
105544
105545
105546

105547


105548

105549



105550
105551
105552
105553
105554
105555
105556
105557
105558
105559
105560
105561
105562
105563
105564
105565
105566

105567








105568





105569
105570
105571
105572
105573
105574
105575

105576
105577
105578
105579

105580
105581
105582
105583
105584
105585
105586
105587







+
+
+
+















-




-
-
+
+

+
+





+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+

-
+



-
+









-
+


-
+

-
+








-
+


-
-
-
-
-
-
+
+
+
+
+
+
+
+
+

+
-
-
-
-
-
+
+
+
+
+
+


-
-
+
+




-
-
+
+


-
+





-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




-
-
-
+
+
+
+


-
+






-
+










-
+









-
-
-
-
+
+
+
+









+
-
+




-
+
+


-
+
+







-
-
+
+














-
+


-
-
+
-





-
-
-
+
+
+









-
-
+
+
+
+
+
+


-
+







-
+





-
+






-
+










+
+
-
+


-
+




















-
+

-
+




-
+

-
+


-
+





-
+













-
+



-
+


-
+




-
-
-
-
-
+
+
+
+
+
+



-
+

-
+
-
-
-
+
-
-
-
+
-
-
+
















-
-
+
+


-
-
+
+

-
-
+
+


-
+
-
-
+
-

-
-
-
+
+
+







+
+
+
+
+
+

-
+
-
-
-
-
-
-
-
-

-
-
-
-
-
+
+
+
+
+
+

-
+



-
+







    **    space to 1/16th of its original size (rangeDiv==16).
    **
    **  bSort:   
    **    Boolean. True if there is an ORDER BY clause that will require an 
    **    external sort (i.e. scanning the index being evaluated will not 
    **    correctly order records).
    **
    **  bDist:
    **    Boolean. True if there is a DISTINCT clause that will require an 
    **    external btree.
    **
    **  bLookup: 
    **    Boolean. True if a table lookup is required for each index entry
    **    visited.  In other words, true if this is not a covering index.
    **    This is always false for the rowid primary key index of a table.
    **    For other indexes, it is true unless all the columns of the table
    **    used by the SELECT statement are present in the index (such an
    **    index is sometimes described as a covering index).
    **    For example, given the index on (a, b), the second of the following 
    **    two queries requires table b-tree lookups in order to find the value
    **    of column c, but the first does not because columns a and b are
    **    both available in the index.
    **
    **             SELECT a, b    FROM tbl WHERE a = 1;
    **             SELECT a, b, c FROM tbl WHERE a = 1;
    */
    int nEq;                      /* Number of == or IN terms matching index */
    int bInEst = 0;               /* True if "x IN (SELECT...)" seen */
    int nInMul = 1;               /* Number of distinct equalities to lookup */
    double rangeDiv = (double)1;  /* Estimated reduction in search space */
    int nBound = 0;               /* Number of range constraints seen */
    int bSort = !!pOrderBy;       /* True if external sort required */
    int bDist = !!pDistinct;      /* True if index cannot help with DISTINCT */
    int bSort;                    /* True if external sort required */
    int bDist;                    /* True if index cannot help with DISTINCT */
    int bLookup = 0;              /* True if not a covering index */
    int nPriorSat;                /* ORDER BY terms satisfied by outer loops */
    int nOrderBy;                 /* Number of ORDER BY terms */
    WhereTerm *pTerm;             /* A single term of the WHERE clause */
#ifdef SQLITE_ENABLE_STAT3
    WhereTerm *pFirstTerm = 0;    /* First term matching the index */
#endif

    WHERETRACE((
      "   %s(%s):\n",
      pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk")
    ));
    memset(&pc, 0, sizeof(pc));
    nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0;
    if( p->i ){
      nPriorSat = pc.plan.nOBSat = p->aLevel[p->i-1].plan.nOBSat;
      bSort = nPriorSat<nOrderBy;
      bDist = 0;
    }else{
      nPriorSat = pc.plan.nOBSat = 0;
      bSort = nOrderBy>0;
      bDist = p->pDistinct!=0;
    }

    /* Determine the values of nEq and nInMul */
    for(nEq=0; nEq<pProbe->nColumn; nEq++){
      int j = pProbe->aiColumn[nEq];
      pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pIdx);
    /* Determine the values of pc.plan.nEq and nInMul */
    for(pc.plan.nEq=0; pc.plan.nEq<pProbe->nColumn; pc.plan.nEq++){
      int j = pProbe->aiColumn[pc.plan.nEq];
      pTerm = findTerm(pWC, iCur, j, p->notReady, eqTermMask, pIdx);
      if( pTerm==0 ) break;
      wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ);
      pc.plan.wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ);
      testcase( pTerm->pWC!=pWC );
      if( pTerm->eOperator & WO_IN ){
        Expr *pExpr = pTerm->pExpr;
        wsFlags |= WHERE_COLUMN_IN;
        pc.plan.wsFlags |= WHERE_COLUMN_IN;
        if( ExprHasProperty(pExpr, EP_xIsSelect) ){
          /* "x IN (SELECT ...)":  Assume the SELECT returns 25 rows */
          nInMul *= 25;
          bInEst = 1;
        }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
          /* "x IN (value, value, ...)" */
          nInMul *= pExpr->x.pList->nExpr;
        }
      }else if( pTerm->eOperator & WO_ISNULL ){
        wsFlags |= WHERE_COLUMN_NULL;
        pc.plan.wsFlags |= WHERE_COLUMN_NULL;
      }
#ifdef SQLITE_ENABLE_STAT3
      if( nEq==0 && pProbe->aSample ) pFirstTerm = pTerm;
      if( pc.plan.nEq==0 && pProbe->aSample ) pFirstTerm = pTerm;
#endif
      used |= pTerm->prereqRight;
      pc.used |= pTerm->prereqRight;
    }
 
    /* If the index being considered is UNIQUE, and there is an equality 
    ** constraint for all columns in the index, then this search will find
    ** at most a single row. In this case set the WHERE_UNIQUE flag to 
    ** indicate this to the caller.
    **
    ** Otherwise, if the search may find more than one row, test to see if
    ** there is a range constraint on indexed column (nEq+1) that can be 
    ** there is a range constraint on indexed column (pc.plan.nEq+1) that can be 
    ** optimized using the index. 
    */
    if( nEq==pProbe->nColumn && pProbe->onError!=OE_None ){
      testcase( wsFlags & WHERE_COLUMN_IN );
      testcase( wsFlags & WHERE_COLUMN_NULL );
      if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){
        wsFlags |= WHERE_UNIQUE;
      }
    if( pc.plan.nEq==pProbe->nColumn && pProbe->onError!=OE_None ){
      testcase( pc.plan.wsFlags & WHERE_COLUMN_IN );
      testcase( pc.plan.wsFlags & WHERE_COLUMN_NULL );
      if( (pc.plan.wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){
        pc.plan.wsFlags |= WHERE_UNIQUE;
        if( p->i==0 || (p->aLevel[p->i-1].plan.wsFlags & WHERE_ALL_UNIQUE)!=0 ){
          pc.plan.wsFlags |= WHERE_ALL_UNIQUE;
        }
      }
    }else if( pProbe->bUnordered==0 ){
      int j;
      int j = (nEq==pProbe->nColumn ? -1 : pProbe->aiColumn[nEq]);
      if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
        WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx);
        WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx);
        whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &rangeDiv);
      j = (pc.plan.nEq==pProbe->nColumn ? -1 : pProbe->aiColumn[pc.plan.nEq]);
      if( findTerm(pWC, iCur, j, p->notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
        WhereTerm *pTop, *pBtm;
        pTop = findTerm(pWC, iCur, j, p->notReady, WO_LT|WO_LE, pIdx);
        pBtm = findTerm(pWC, iCur, j, p->notReady, WO_GT|WO_GE, pIdx);
        whereRangeScanEst(pParse, pProbe, pc.plan.nEq, pBtm, pTop, &rangeDiv);
        if( pTop ){
          nBound = 1;
          wsFlags |= WHERE_TOP_LIMIT;
          used |= pTop->prereqRight;
          pc.plan.wsFlags |= WHERE_TOP_LIMIT;
          pc.used |= pTop->prereqRight;
          testcase( pTop->pWC!=pWC );
        }
        if( pBtm ){
          nBound++;
          wsFlags |= WHERE_BTM_LIMIT;
          used |= pBtm->prereqRight;
          pc.plan.wsFlags |= WHERE_BTM_LIMIT;
          pc.used |= pBtm->prereqRight;
          testcase( pBtm->pWC!=pWC );
        }
        wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE);
        pc.plan.wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE);
      }
    }

    /* If there is an ORDER BY clause and the index being considered will
    ** naturally scan rows in the required order, set the appropriate flags
    ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index
    ** will scan rows in a different order, set the bSort variable.  */
    if( isSortingIndex(
          pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy, nEq, wsFlags, &rev)
    ){
      bSort = 0;
      wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY;
      wsFlags |= (rev ? WHERE_REVERSE : 0);
    ** in pc.plan.wsFlags. Otherwise, if there is an ORDER BY clause but
    ** the index will scan rows in a different order, set the bSort
    ** variable.  */
    if( bSort && (pSrc->jointype & JT_LEFT)==0 ){
      int bRev = 2;
      WHERETRACE(("      --> before isSortingIndex: nPriorSat=%d\n",nPriorSat));
      pc.plan.nOBSat = isSortingIndex(p, pProbe, iCur, &bRev);
      WHERETRACE(("      --> after  isSortingIndex: bRev=%d nOBSat=%d\n",
                  bRev, pc.plan.nOBSat));
      if( nPriorSat<pc.plan.nOBSat || (pc.plan.wsFlags & WHERE_UNIQUE)!=0 ){
        pc.plan.wsFlags |= WHERE_ORDERED;
      }
      if( nOrderBy==pc.plan.nOBSat ){
        bSort = 0;
        pc.plan.wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE;
      }
      if( bRev & 1 ) pc.plan.wsFlags |= WHERE_REVERSE;
    }

    /* If there is a DISTINCT qualifier and this index will scan rows in
    ** order of the DISTINCT expressions, clear bDist and set the appropriate
    ** flags in wsFlags. */
    if( isDistinctIndex(pParse, pWC, pProbe, iCur, pDistinct, nEq)
     && (wsFlags & WHERE_COLUMN_IN)==0
    ** flags in pc.plan.wsFlags. */
    if( bDist
     && isDistinctIndex(pParse, pWC, pProbe, iCur, p->pDistinct, pc.plan.nEq)
     && (pc.plan.wsFlags & WHERE_COLUMN_IN)==0
    ){
      bDist = 0;
      wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_DISTINCT;
      pc.plan.wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_DISTINCT;
    }

    /* If currently calculating the cost of using an index (not the IPK
    ** index), determine if all required column data may be obtained without 
    ** using the main table (i.e. if the index is a covering
    ** index for this query). If it is, set the WHERE_IDX_ONLY flag in
    ** wsFlags. Otherwise, set the bLookup variable to true.  */
    ** pc.plan.wsFlags. Otherwise, set the bLookup variable to true.  */
    if( pIdx ){
      Bitmask m = pSrc->colUsed;
      int j;
      for(j=0; j<pIdx->nColumn; j++){
        int x = pIdx->aiColumn[j];
        if( x<BMS-1 ){
          m &= ~(((Bitmask)1)<<x);
        }
      }
      if( m==0 ){
        wsFlags |= WHERE_IDX_ONLY;
        pc.plan.wsFlags |= WHERE_IDX_ONLY;
      }else{
        bLookup = 1;
      }
    }

    /*
    ** Estimate the number of rows of output.  For an "x IN (SELECT...)"
    ** constraint, do not let the estimate exceed half the rows in the table.
    */
    nRow = (double)(aiRowEst[nEq] * nInMul);
    if( bInEst && nRow*2>aiRowEst[0] ){
      nRow = aiRowEst[0]/2;
      nInMul = (int)(nRow / aiRowEst[nEq]);
    pc.plan.nRow = (double)(aiRowEst[pc.plan.nEq] * nInMul);
    if( bInEst && pc.plan.nRow*2>aiRowEst[0] ){
      pc.plan.nRow = aiRowEst[0]/2;
      nInMul = (int)(pc.plan.nRow / aiRowEst[pc.plan.nEq]);
    }

#ifdef SQLITE_ENABLE_STAT3
    /* If the constraint is of the form x=VALUE or x IN (E1,E2,...)
    ** and we do not think that values of x are unique and if histogram
    ** data is available for column x, then it might be possible
    ** to get a better estimate on the number of rows based on
    ** VALUE and how common that value is according to the histogram.
    */
    if( pc.plan.nRow>(double)1 && pc.plan.nEq==1
    if( nRow>(double)1 && nEq==1 && pFirstTerm!=0 && aiRowEst[1]>1 ){
     && pFirstTerm!=0 && aiRowEst[1]>1 ){
      assert( (pFirstTerm->eOperator & (WO_EQ|WO_ISNULL|WO_IN))!=0 );
      if( pFirstTerm->eOperator & (WO_EQ|WO_ISNULL) ){
        testcase( pFirstTerm->eOperator==WO_EQ );
        testcase( pFirstTerm->eOperator==WO_ISNULL );
        whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight, &nRow);
        whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight,
                          &pc.plan.nRow);
      }else if( bInEst==0 ){
        assert( pFirstTerm->eOperator==WO_IN );
        whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList, &nRow);
        whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList,
                       &pc.plan.nRow);
      }
    }
#endif /* SQLITE_ENABLE_STAT3 */

    /* Adjust the number of output rows and downward to reflect rows
    ** that are excluded by range constraints.
    */
    nRow = nRow/rangeDiv;
    if( nRow<1 ) nRow = 1;
    pc.plan.nRow = pc.plan.nRow/rangeDiv;
    if( pc.plan.nRow<1 ) pc.plan.nRow = 1;

    /* Experiments run on real SQLite databases show that the time needed
    ** to do a binary search to locate a row in a table or index is roughly
    ** log10(N) times the time to move from one row to the next row within
    ** a table or index.  The actual times can vary, with the size of
    ** records being an important factor.  Both moves and searches are
    ** slower with larger records, presumably because fewer records fit
    ** on one page and hence more pages have to be fetched.
    **
    ** The ANALYZE command and the sqlite_stat1 and sqlite_stat3 tables do
    ** not give us data on the relative sizes of table and index records.
    ** So this computation assumes table records are about twice as big
    ** as index records
    */
    if( wsFlags==WHERE_IDX_ONLY
    if( (pc.plan.wsFlags&~(WHERE_REVERSE|WHERE_ORDERED))==WHERE_IDX_ONLY
     && (pWC->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
     && sqlite3GlobalConfig.bUseCis
#ifndef SQLITE_OMIT_BUILTIN_TEST
     && (pParse->db->flags & SQLITE_CoverIdxScan)==0
     && OptimizationEnabled(pParse->db, SQLITE_CoverIdxScan)
#endif
    ){
      /* This index is not useful for indexing, but it is a covering index.
      ** A full-scan of the index might be a little faster than a full-scan
      ** of the table, so give this case a cost slightly less than a table
      ** scan. */
      cost = aiRowEst[0]*3 + pProbe->nColumn;
      wsFlags |= WHERE_COVER_SCAN|WHERE_COLUMN_RANGE;
    }else if( (wsFlags & WHERE_NOT_FULLSCAN)==0 ){
      pc.rCost = aiRowEst[0]*3 + pProbe->nColumn;
      pc.plan.wsFlags |= WHERE_COVER_SCAN|WHERE_COLUMN_RANGE;
    }else if( (pc.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){
      /* The cost of a full table scan is a number of move operations equal
      ** to the number of rows in the table.
      **
      ** We add an additional 4x penalty to full table scans.  This causes
      ** the cost function to err on the side of choosing an index over
      ** choosing a full scan.  This 4x full-scan penalty is an arguable
      ** decision and one which we expect to revisit in the future.  But
      ** it seems to be working well enough at the moment.
      */
      cost = aiRowEst[0]*4;
      wsFlags &= ~WHERE_IDX_ONLY;
      pc.rCost = aiRowEst[0]*4;
      pc.plan.wsFlags &= ~WHERE_IDX_ONLY;
      if( pIdx ){
        pc.plan.wsFlags &= ~WHERE_ORDERED;
        pc.plan.nOBSat = nPriorSat;
      }
    }else{
      log10N = estLog(aiRowEst[0]);
      cost = nRow;
      pc.rCost = pc.plan.nRow;
      if( pIdx ){
        if( bLookup ){
          /* For an index lookup followed by a table lookup:
          **    nInMul index searches to find the start of each index range
          **  + nRow steps through the index
          **  + nRow table searches to lookup the table entry using the rowid
          */
          cost += (nInMul + nRow)*log10N;
          pc.rCost += (nInMul + pc.plan.nRow)*log10N;
        }else{
          /* For a covering index:
          **     nInMul index searches to find the initial entry 
          **   + nRow steps through the index
          */
          cost += nInMul*log10N;
          pc.rCost += nInMul*log10N;
        }
      }else{
        /* For a rowid primary key lookup:
        **    nInMult table searches to find the initial entry for each range
        **  + nRow steps through the table
        */
        cost += nInMul*log10N;
        pc.rCost += nInMul*log10N;
      }
    }

    /* Add in the estimated cost of sorting the result.  Actual experimental
    ** measurements of sorting performance in SQLite show that sorting time
    ** adds C*N*log10(N) to the cost, where N is the number of rows to be 
    ** sorted and C is a factor between 1.95 and 4.3.  We will split the
    ** difference and select C of 3.0.
    */
    if( bSort ){
      double m = estLog(pc.plan.nRow*(nOrderBy - pc.plan.nOBSat)/nOrderBy);
      m *= (double)(pc.plan.nOBSat ? 2 : 3);
      cost += nRow*estLog(nRow)*3;
      pc.rCost += pc.plan.nRow*m;
    }
    if( bDist ){
      cost += nRow*estLog(nRow)*3;
      pc.rCost += pc.plan.nRow*estLog(pc.plan.nRow)*3;
    }

    /**** Cost of using this index has now been computed ****/

    /* If there are additional constraints on this table that cannot
    ** be used with the current index, but which might lower the number
    ** of output rows, adjust the nRow value accordingly.  This only 
    ** matters if the current index is the least costly, so do not bother
    ** with this step if we already know this index will not be chosen.
    ** Also, never reduce the output row count below 2 using this step.
    **
    ** It is critical that the notValid mask be used here instead of
    ** the notReady mask.  When computing an "optimal" index, the notReady
    ** mask will only have one bit set - the bit for the current table.
    ** The notValid mask, on the other hand, always has all bits set for
    ** tables that are not in outer loops.  If notReady is used here instead
    ** of notValid, then a optimal index that depends on inner joins loops
    ** might be selected even when there exists an optimal index that has
    ** no such dependency.
    */
    if( nRow>2 && cost<=pCost->rCost ){
    if( pc.plan.nRow>2 && pc.rCost<=p->cost.rCost ){
      int k;                       /* Loop counter */
      int nSkipEq = nEq;           /* Number of == constraints to skip */
      int nSkipEq = pc.plan.nEq;   /* Number of == constraints to skip */
      int nSkipRange = nBound;     /* Number of < constraints to skip */
      Bitmask thisTab;             /* Bitmap for pSrc */

      thisTab = getMask(pWC->pMaskSet, iCur);
      for(pTerm=pWC->a, k=pWC->nTerm; nRow>2 && k; k--, pTerm++){
      for(pTerm=pWC->a, k=pWC->nTerm; pc.plan.nRow>2 && k; k--, pTerm++){
        if( pTerm->wtFlags & TERM_VIRTUAL ) continue;
        if( (pTerm->prereqAll & notValid)!=thisTab ) continue;
        if( (pTerm->prereqAll & p->notValid)!=thisTab ) continue;
        if( pTerm->eOperator & (WO_EQ|WO_IN|WO_ISNULL) ){
          if( nSkipEq ){
            /* Ignore the first nEq equality matches since the index
            /* Ignore the first pc.plan.nEq equality matches since the index
            ** has already accounted for these */
            nSkipEq--;
          }else{
            /* Assume each additional equality match reduces the result
            ** set size by a factor of 10 */
            nRow /= 10;
            pc.plan.nRow /= 10;
          }
        }else if( pTerm->eOperator & (WO_LT|WO_LE|WO_GT|WO_GE) ){
          if( nSkipRange ){
            /* Ignore the first nSkipRange range constraints since the index
            ** has already accounted for these */
            nSkipRange--;
          }else{
            /* Assume each additional range constraint reduces the result
            ** set size by a factor of 3.  Indexed range constraints reduce
            ** the search space by a larger factor: 4.  We make indexed range
            ** more selective intentionally because of the subjective 
            ** observation that indexed range constraints really are more
            ** selective in practice, on average. */
            nRow /= 3;
            pc.plan.nRow /= 3;
          }
        }else if( pTerm->eOperator!=WO_NOOP ){
          /* Any other expression lowers the output row count by half */
          nRow /= 2;
          pc.plan.nRow /= 2;
        }
      }
      if( nRow<2 ) nRow = 2;
      if( pc.plan.nRow<2 ) pc.plan.nRow = 2;
    }


    WHERETRACE((
      "%s(%s): nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%x\n"
      "         notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f used=0x%llx\n",
      pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"), 
      nEq, nInMul, (int)rangeDiv, bSort, bLookup, wsFlags,
      notReady, log10N, nRow, cost, used
      "      nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%08x\n"
      "      notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f\n"
      "      used=0x%llx nOBSat=%d\n",
      pc.plan.nEq, nInMul, (int)rangeDiv, bSort, bLookup, pc.plan.wsFlags,
      p->notReady, log10N, pc.plan.nRow, pc.rCost, pc.used,
      pc.plan.nOBSat
    ));

    /* If this index is the best we have seen so far, then record this
    ** index and its cost in the pCost structure.
    ** index and its cost in the p->cost structure.
    */
    if( (!pIdx || wsFlags)
    if( (!pIdx || pc.plan.wsFlags) && compareCost(&pc, &p->cost) ){
     && (cost<pCost->rCost || (cost<=pCost->rCost && nRow<pCost->plan.nRow))
    ){
      pCost->rCost = cost;
      p->cost = pc;
      pCost->used = used;
      pCost->plan.nRow = nRow;
      pCost->plan.wsFlags = (wsFlags&wsFlagMask);
      p->cost.plan.wsFlags &= wsFlagMask;
      pCost->plan.nEq = nEq;
      pCost->plan.u.pIdx = pIdx;
      p->cost.plan.u.pIdx = pIdx;
    }

    /* If there was an INDEXED BY clause, then only that one index is
    ** considered. */
    if( pSrc->pIndex ) break;

    /* Reset masks for the next index in the loop */
    wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE);
    eqTermMask = idxEqTermMask;
  }

  /* If there is no ORDER BY clause and the SQLITE_ReverseOrder flag
  ** is set, then reverse the order that the index will be scanned
  ** in. This is used for application testing, to help find cases
  ** where application behaviour depends on the (undefined) order that
  ** SQLite outputs rows in in the absence of an ORDER BY clause.  */
  if( !pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){
    pCost->plan.wsFlags |= WHERE_REVERSE;
  if( !p->pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){
    p->cost.plan.wsFlags |= WHERE_REVERSE;
  }

  assert( pOrderBy || (pCost->plan.wsFlags&WHERE_ORDERBY)==0 );
  assert( pCost->plan.u.pIdx==0 || (pCost->plan.wsFlags&WHERE_ROWID_EQ)==0 );
  assert( p->pOrderBy || (p->cost.plan.wsFlags&WHERE_ORDERED)==0 );
  assert( p->cost.plan.u.pIdx==0 || (p->cost.plan.wsFlags&WHERE_ROWID_EQ)==0 );
  assert( pSrc->pIndex==0 
       || pCost->plan.u.pIdx==0 
       || pCost->plan.u.pIdx==pSrc->pIndex 
       || p->cost.plan.u.pIdx==0 
       || p->cost.plan.u.pIdx==pSrc->pIndex 
  );

  WHERETRACE(("best index is: %s\n", 
  WHERETRACE(("   best index is: %s\n",
    ((pCost->plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ? "none" : 
         pCost->plan.u.pIdx ? pCost->plan.u.pIdx->zName : "ipk")
         p->cost.plan.u.pIdx ? p->cost.plan.u.pIdx->zName : "ipk"));
  ));
  
  bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost);
  bestAutomaticIndex(pParse, pWC, pSrc, notReady, pCost);
  pCost->plan.wsFlags |= eqTermMask;
  bestOrClauseIndex(p);
  bestAutomaticIndex(p);
  p->cost.plan.wsFlags |= eqTermMask;
}

/*
** Find the query plan for accessing table pSrc->pTab. Write the
** best query plan and its cost into the WhereCost object supplied 
** as the last parameter. This function may calculate the cost of
** both real and virtual table scans.
**
** This function does not take ORDER BY or DISTINCT into account.  Nor
** does it remember the virtual table query plan.  All it does is compute
** the cost while determining if an OR optimization is applicable.  The
** details will be reconsidered later if the optimization is found to be
** applicable.
*/
static void bestIndex(
static void bestIndex(WhereBestIdx *p){
  Parse *pParse,              /* The parsing context */
  WhereClause *pWC,           /* The WHERE clause */
  struct SrcList_item *pSrc,  /* The FROM clause term to search */
  Bitmask notReady,           /* Mask of cursors not available for indexing */
  Bitmask notValid,           /* Cursors not available for any purpose */
  ExprList *pOrderBy,         /* The ORDER BY clause */
  WhereCost *pCost            /* Lowest cost query plan */
){
#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( IsVirtual(pSrc->pTab) ){
    sqlite3_index_info *p = 0;
    bestVirtualIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost,&p);
    if( p->needToFreeIdxStr ){
      sqlite3_free(p->idxStr);
  if( IsVirtual(p->pSrc->pTab) ){
    sqlite3_index_info *pIdxInfo = 0;
    p->ppIdxInfo = &pIdxInfo;
    bestVirtualIndex(p);
    if( pIdxInfo->needToFreeIdxStr ){
      sqlite3_free(pIdxInfo->idxStr);
    }
    sqlite3DbFree(pParse->db, p);
    sqlite3DbFree(p->pParse->db, pIdxInfo);
  }else
#endif
  {
    bestBtreeIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, 0, pCost);
    bestBtreeIndex(p);
  }
}

/*
** Disable a term in the WHERE clause.  Except, do not disable the term
** if it controls a LEFT OUTER JOIN and it did not originate in the ON
** or USING clause of that join.
105912
105913
105914
105915
105916
105917
105918
105919

105920
105921
105922
105923
105924
105925
105926
106269
106270
106271
106272
106273
106274
106275

106276
106277
106278
106279
106280
106281
106282
106283







-
+







    ** query, then the caller will only allow the loop to run for
    ** a single iteration. This means that the first row returned
    ** should not have a NULL value stored in 'x'. If column 'x' is
    ** the first one after the nEq equality constraints in the index,
    ** this requires some special handling.
    */
    if( (wctrlFlags&WHERE_ORDERBY_MIN)!=0
     && (pLevel->plan.wsFlags&WHERE_ORDERBY)
     && (pLevel->plan.wsFlags&WHERE_ORDERED)
     && (pIdx->nColumn>nEq)
    ){
      /* assert( pOrderBy->nExpr==1 ); */
      /* assert( pOrderBy->a[0].pExpr->iColumn==pIdx->aiColumn[nEq] ); */
      isMinQuery = 1;
      nExtraReg = 1;
    }
106275
106276
106277
106278
106279
106280
106281
106282

106283
106284
106285
106286
106287
106288
106289
106632
106633
106634
106635
106636
106637
106638

106639
106640
106641
106642
106643
106644
106645
106646







-
+








          /* Finish the loop through table entries that match term pOrTerm. */
          sqlite3WhereEnd(pSubWInfo);
        }
      }
    }
    pLevel->u.pCovidx = pCov;
    pLevel->iIdxCur = iCovCur;
    if( pCov ) pLevel->iIdxCur = iCovCur;
    if( pAndExpr ){
      pAndExpr->pLeft = 0;
      sqlite3ExprDelete(pParse->db, pAndExpr);
    }
    sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
    sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
    sqlite3VdbeResolveLabel(v, iLoopBody);
106474
106475
106476
106477
106478
106479
106480
106481

106482
106483

106484
106485
106486
106487
106488
106489



106490
106491
106492

106493
106494
106495
106496
106497
106498

106499
106500
106501
106502
106503
106504
106505
106506
106507
106508

106509
106510
106511
106512
106513


106514

106515
106516





106517
106518
106519
106520
106521
106522
106523
106831
106832
106833
106834
106835
106836
106837

106838
106839

106840
106841
106842
106843



106844
106845
106846
106847
106848

106849
106850
106851
106852
106853
106854

106855
106856
106857
106858
106859

106860
106861
106862
106863
106864
106865
106866




106867
106868
106869
106870
106871
106872
106873
106874
106875
106876
106877
106878
106879
106880
106881
106882
106883
106884







-
+

-
+



-
-
-
+
+
+


-
+





-
+




-





+

-
-
-
-
+
+

+


+
+
+
+
+







**        move the row2 cursor to a null row
**        goto start
**      fi
**    end
**
** ORDER BY CLAUSE PROCESSING
**
** *ppOrderBy is a pointer to the ORDER BY clause of a SELECT statement,
** pOrderBy is a pointer to the ORDER BY clause of a SELECT statement,
** if there is one.  If there is no ORDER BY clause or if this routine
** is called from an UPDATE or DELETE statement, then ppOrderBy is NULL.
** is called from an UPDATE or DELETE statement, then pOrderBy is NULL.
**
** If an index can be used so that the natural output order of the table
** scan is correct for the ORDER BY clause, then that index is used and
** *ppOrderBy is set to NULL.  This is an optimization that prevents an
** unnecessary sort of the result set if an index appropriate for the
** ORDER BY clause already exists.
** the returned WhereInfo.nOBSat field is set to pOrderBy->nExpr.  This
** is an optimization that prevents an unnecessary sort of the result set
** if an index appropriate for the ORDER BY clause already exists.
**
** If the where clause loops cannot be arranged to provide the correct
** output order, then the *ppOrderBy is unchanged.
** output order, then WhereInfo.nOBSat is 0.
*/
SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
  Parse *pParse,        /* The parser context */
  SrcList *pTabList,    /* A list of all tables to be scanned */
  Expr *pWhere,         /* The WHERE clause */
  ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */
  ExprList *pOrderBy,   /* An ORDER BY clause, or NULL */
  ExprList *pDistinct,  /* The select-list for DISTINCT queries - or NULL */
  u16 wctrlFlags,       /* One of the WHERE_* flags defined in sqliteInt.h */
  int iIdxCur           /* If WHERE_ONETABLE_ONLY is set, index cursor number */
){
  int i;                     /* Loop counter */
  int nByteWInfo;            /* Num. bytes allocated for WhereInfo struct */
  int nTabList;              /* Number of elements in pTabList */
  WhereInfo *pWInfo;         /* Will become the return value of this function */
  Vdbe *v = pParse->pVdbe;   /* The virtual database engine */
  Bitmask notReady;          /* Cursors that are not yet positioned */
  WhereBestIdx sWBI;         /* Best index search context */
  WhereMaskSet *pMaskSet;    /* The expression mask set */
  WhereClause *pWC;               /* Decomposition of the WHERE clause */
  struct SrcList_item *pTabItem;  /* A single entry from pTabList */
  WhereLevel *pLevel;             /* A single level in the pWInfo list */
  int iFrom;                      /* First unused FROM clause element */
  WhereLevel *pLevel;        /* A single level in pWInfo->a[] */
  int iFrom;                 /* First unused FROM clause element */
  int andFlags;              /* AND-ed combination of all pWC->a[].wtFlags */
  int ii;                    /* Loop counter */
  sqlite3 *db;               /* Database connection */


  /* Variable initialization */
  memset(&sWBI, 0, sizeof(sWBI));
  sWBI.pParse = pParse;

  /* The number of tables in the FROM clause is limited by the number of
  ** bits in a Bitmask 
  */
  testcase( pTabList->nSrc==BMS );
  if( pTabList->nSrc>BMS ){
    sqlite3ErrorMsg(pParse, "at most %d tables in a join", BMS);
    return 0;
106549
106550
106551
106552
106553
106554
106555
106556

106557
106558
106559


106560
106561
106562
106563

106564
106565
106566
106567
106568
106569

106570
106571

106572
106573
106574
106575
106576
106577
106578
106910
106911
106912
106913
106914
106915
106916

106917
106918
106919

106920
106921
106922
106923
106924

106925
106926
106927
106928
106929
106930

106931
106932

106933
106934
106935
106936
106937
106938
106939
106940







-
+


-
+
+



-
+





-
+

-
+







    pWInfo = 0;
    goto whereBeginError;
  }
  pWInfo->nLevel = nTabList;
  pWInfo->pParse = pParse;
  pWInfo->pTabList = pTabList;
  pWInfo->iBreak = sqlite3VdbeMakeLabel(v);
  pWInfo->pWC = pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo];
  pWInfo->pWC = sWBI.pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo];
  pWInfo->wctrlFlags = wctrlFlags;
  pWInfo->savedNQueryLoop = pParse->nQueryLoop;
  pMaskSet = (WhereMaskSet*)&pWC[1];
  pMaskSet = (WhereMaskSet*)&sWBI.pWC[1];
  sWBI.aLevel = pWInfo->a;

  /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via
  ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */
  if( db->flags & SQLITE_DistinctOpt ) pDistinct = 0;
  if( OptimizationDisabled(db, SQLITE_DistinctOpt) ) pDistinct = 0;

  /* Split the WHERE clause into separate subexpressions where each
  ** subexpression is separated by an AND operator.
  */
  initMaskSet(pMaskSet);
  whereClauseInit(pWC, pParse, pMaskSet, wctrlFlags);
  whereClauseInit(sWBI.pWC, pParse, pMaskSet, wctrlFlags);
  sqlite3ExprCodeConstants(pParse, pWhere);
  whereSplit(pWC, pWhere, TK_AND);   /* IMP: R-15842-53296 */
  whereSplit(sWBI.pWC, pWhere, TK_AND);   /* IMP: R-15842-53296 */
    
  /* Special case: a WHERE clause that is constant.  Evaluate the
  ** expression and either jump over all of the code or fall thru.
  */
  if( pWhere && (nTabList==0 || sqlite3ExprIsConstantNotJoin(pWhere)) ){
    sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, SQLITE_JUMPIFNULL);
    pWhere = 0;
106595
106596
106597
106598
106599
106600
106601
106602
106603
106604



106605
106606
106607


106608
106609
106610
106611
106612
106613
106614
106615


106616
106617
106618
106619
106620
106621
106622
106623
106624
106625
106626
106627

106628
106629
106630
106631
106632
106633
106634
106635
106636

106637
106638
106639
106640
106641
106642
106643
106644
106645
106646
106647
106648
106649
106650
106651
106652
106653
106654
106655
106656




106657
106658
106659

106660
106661
106662
106663
106664
106665
106666
106667
106668
106669
106670
106671

106672
106673
106674
106675
106676
106677
106678
106679
106680
106681
106682
106683
106684
106685
106686
106687
106688


106689
106690
106691
106692
106693
106694
106695
106957
106958
106959
106960
106961
106962
106963



106964
106965
106966
106967


106968
106969
106970
106971
106972
106973
106974
106975


106976
106977
106978
106979
106980
106981
106982
106983
106984
106985
106986
106987
106988

106989
106990
106991
106992
106993
106994
106995
106996
106997

106998
106999
107000
107001
107002
107003
107004
107005
107006
107007
107008
107009
107010
107011
107012
107013
107014
107015
107016
107017

107018
107019
107020
107021
107022
107023

107024
107025
107026
107027
107028
107029
107030
107031
107032
107033
107034
107035

107036
107037
107038
107039
107040
107041
107042
107043
107044
107045
107046
107047
107048
107049
107050
107051


107052
107053
107054
107055
107056
107057
107058
107059
107060







-
-
-
+
+
+

-
-
+
+






-
-
+
+











-
+








-
+



















-
+
+
+
+


-
+











-
+















-
-
+
+







  ** with virtual tables.
  **
  ** Note that bitmasks are created for all pTabList->nSrc tables in
  ** pTabList, not just the first nTabList tables.  nTabList is normally
  ** equal to pTabList->nSrc but might be shortened to 1 if the
  ** WHERE_ONETABLE_ONLY flag is set.
  */
  assert( pWC->vmask==0 && pMaskSet->n==0 );
  for(i=0; i<pTabList->nSrc; i++){
    createMask(pMaskSet, pTabList->a[i].iCursor);
  assert( sWBI.pWC->vmask==0 && pMaskSet->n==0 );
  for(ii=0; ii<pTabList->nSrc; ii++){
    createMask(pMaskSet, pTabList->a[ii].iCursor);
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( ALWAYS(pTabList->a[i].pTab) && IsVirtual(pTabList->a[i].pTab) ){
      pWC->vmask |= ((Bitmask)1 << i);
    if( ALWAYS(pTabList->a[ii].pTab) && IsVirtual(pTabList->a[ii].pTab) ){
      sWBI.pWC->vmask |= ((Bitmask)1 << ii);
    }
#endif
  }
#ifndef NDEBUG
  {
    Bitmask toTheLeft = 0;
    for(i=0; i<pTabList->nSrc; i++){
      Bitmask m = getMask(pMaskSet, pTabList->a[i].iCursor);
    for(ii=0; ii<pTabList->nSrc; ii++){
      Bitmask m = getMask(pMaskSet, pTabList->a[ii].iCursor);
      assert( (m-1)==toTheLeft );
      toTheLeft |= m;
    }
  }
#endif

  /* Analyze all of the subexpressions.  Note that exprAnalyze() might
  ** add new virtual terms onto the end of the WHERE clause.  We do not
  ** want to analyze these virtual terms, so start analyzing at the end
  ** and work forward so that the added virtual terms are never processed.
  */
  exprAnalyzeAll(pTabList, pWC);
  exprAnalyzeAll(pTabList, sWBI.pWC);
  if( db->mallocFailed ){
    goto whereBeginError;
  }

  /* Check if the DISTINCT qualifier, if there is one, is redundant. 
  ** If it is, then set pDistinct to NULL and WhereInfo.eDistinct to
  ** WHERE_DISTINCT_UNIQUE to tell the caller to ignore the DISTINCT.
  */
  if( pDistinct && isDistinctRedundant(pParse, pTabList, pWC, pDistinct) ){
  if( pDistinct && isDistinctRedundant(pParse, pTabList, sWBI.pWC, pDistinct) ){
    pDistinct = 0;
    pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
  }

  /* Chose the best index to use for each table in the FROM clause.
  **
  ** This loop fills in the following fields:
  **
  **   pWInfo->a[].pIdx      The index to use for this level of the loop.
  **   pWInfo->a[].wsFlags   WHERE_xxx flags associated with pIdx
  **   pWInfo->a[].nEq       The number of == and IN constraints
  **   pWInfo->a[].iFrom     Which term of the FROM clause is being coded
  **   pWInfo->a[].iTabCur   The VDBE cursor for the database table
  **   pWInfo->a[].iIdxCur   The VDBE cursor for the index
  **   pWInfo->a[].pTerm     When wsFlags==WO_OR, the OR-clause term
  **
  ** This loop also figures out the nesting order of tables in the FROM
  ** clause.
  */
  notReady = ~(Bitmask)0;
  sWBI.notValid = ~(Bitmask)0;
  sWBI.pOrderBy = pOrderBy;
  sWBI.n = nTabList;
  sWBI.pDistinct = pDistinct;
  andFlags = ~0;
  WHERETRACE(("*** Optimizer Start ***\n"));
  for(i=iFrom=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){
  for(sWBI.i=iFrom=0, pLevel=pWInfo->a; sWBI.i<nTabList; sWBI.i++, pLevel++){
    WhereCost bestPlan;         /* Most efficient plan seen so far */
    Index *pIdx;                /* Index for FROM table at pTabItem */
    int j;                      /* For looping over FROM tables */
    int bestJ = -1;             /* The value of j */
    Bitmask m;                  /* Bitmask value for j or bestJ */
    int isOptimal;              /* Iterator for optimal/non-optimal search */
    int nUnconstrained;         /* Number tables without INDEXED BY */
    Bitmask notIndexed;         /* Mask of tables that cannot use an index */

    memset(&bestPlan, 0, sizeof(bestPlan));
    bestPlan.rCost = SQLITE_BIG_DBL;
    WHERETRACE(("*** Begin search for loop %d ***\n", i));
    WHERETRACE(("*** Begin search for loop %d ***\n", sWBI.i));

    /* Loop through the remaining entries in the FROM clause to find the
    ** next nested loop. The loop tests all FROM clause entries
    ** either once or twice. 
    **
    ** The first test is always performed if there are two or more entries
    ** remaining and never performed if there is only one FROM clause entry
    ** to choose from.  The first test looks for an "optimal" scan.  In
    ** this context an optimal scan is one that uses the same strategy
    ** for the given FROM clause entry as would be selected if the entry
    ** were used as the innermost nested loop.  In other words, a table
    ** is chosen such that the cost of running that table cannot be reduced
    ** by waiting for other tables to run first.  This "optimal" test works
    ** by first assuming that the FROM clause is on the inner loop and finding
    ** its query plan, then checking to see if that query plan uses any
    ** other FROM clause terms that are notReady.  If no notReady terms are
    ** used then the "optimal" query plan works.
    ** other FROM clause terms that are sWBI.notValid.  If no notValid terms
    ** are used then the "optimal" query plan works.
    **
    ** Note that the WhereCost.nRow parameter for an optimal scan might
    ** not be as small as it would be if the table really were the innermost
    ** join.  The nRow value can be reduced by WHERE clause constraints
    ** that do not use indices.  But this nRow reduction only happens if the
    ** table really is the innermost join.  
    **
106712
106713
106714
106715
106716
106717
106718
106719
106720

106721
106722
106723
106724
106725
106726

106727
106728
106729


106730
106731
106732
106733

106734
106735
106736

106737
106738
106739
106740



106741
106742
106743
106744



106745
106746
106747
106748
106749

106750
106751
106752

106753
106754
106755
106756
106757
106758



106759
106760

106761
106762
106763
106764
106765
106766
106767


106768
106769
106770
106771
106772
106773
106774
106775
106776
106777
106778
106779
106780
106781
106782


106783
106784
106785


106786
106787
106788
106789
106790




106791
106792
106793
106794
106795
106796
106797






106798
106799
106800
106801
106802
106803
106804
106805
106806
106807





106808
106809

106810
106811
106812
106813
106814
106815
106816
106817

106818
106819
106820
106821
106822
106823
106824
106825
106826
106827
106828
106829
106830
106831

106832
106833
106834
106835
106836
106837
106838
107077
107078
107079
107080
107081
107082
107083


107084
107085



107086

107087
107088


107089
107090
107091
107092
107093

107094



107095
107096



107097
107098
107099
107100



107101
107102
107103

107104
107105
107106

107107

107108

107109
107110
107111
107112



107113
107114
107115
107116

107117
107118
107119
107120
107121
107122
107123

107124
107125
107126
107127
107128
107129
107130
107131
107132
107133
107134
107135
107136
107137
107138


107139
107140
107141


107142
107143
107144




107145
107146
107147
107148


107149




107150
107151
107152
107153
107154
107155
107156
107157
107158
107159
107160
107161




107162
107163
107164
107165
107166


107167


107168
107169
107170
107171
107172
107173
107174
107175
107176
107177
107178
107179
107180
107181
107182
107183
107184
107185
107186
107187

107188
107189
107190
107191
107192
107193
107194
107195







-
-
+

-
-
-

-
+

-
-
+
+



-
+
-
-
-
+

-
-
-
+
+
+

-
-
-
+
+
+
-



-
+
-

-
+



-
-
-
+
+
+

-
+






-
+
+













-
-
+
+

-
-
+
+

-
-
-
-
+
+
+
+
-
-

-
-
-
-
+
+
+
+
+
+






-
-
-
-
+
+
+
+
+
-
-
+
-
-






+













-
+







    ** as the cost of a linear scan through table t1, a simple greedy 
    ** algorithm may choose to use t2 for the outer loop, which is a much
    ** costlier approach.
    */
    nUnconstrained = 0;
    notIndexed = 0;
    for(isOptimal=(iFrom<nTabList-1); isOptimal>=0 && bestJ<0; isOptimal--){
      Bitmask mask;             /* Mask of tables not yet ready */
      for(j=iFrom, pTabItem=&pTabList->a[j]; j<nTabList; j++, pTabItem++){
      for(j=iFrom, sWBI.pSrc=&pTabList->a[j]; j<nTabList; j++, sWBI.pSrc++){
        int doNotReorder;    /* True if this table should not be reordered */
        WhereCost sCost;     /* Cost information from best[Virtual]Index() */
        ExprList *pOrderBy;  /* ORDER BY clause for index to optimize */
        ExprList *pDist;     /* DISTINCT clause for index to optimize */
  
        doNotReorder =  (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0;
        doNotReorder =  (sWBI.pSrc->jointype & (JT_LEFT|JT_CROSS))!=0;
        if( j!=iFrom && doNotReorder ) break;
        m = getMask(pMaskSet, pTabItem->iCursor);
        if( (m & notReady)==0 ){
        m = getMask(pMaskSet, sWBI.pSrc->iCursor);
        if( (m & sWBI.notValid)==0 ){
          if( j==iFrom ) iFrom++;
          continue;
        }
        mask = (isOptimal ? m : notReady);
        sWBI.notReady = (isOptimal ? m : sWBI.notValid);
        pOrderBy = ((i==0 && ppOrderBy )?*ppOrderBy:0);
        pDist = (i==0 ? pDistinct : 0);
        if( pTabItem->pIndex==0 ) nUnconstrained++;
        if( sWBI.pSrc->pIndex==0 ) nUnconstrained++;
  
        WHERETRACE(("=== trying table %d with isOptimal=%d ===\n",
                    j, isOptimal));
        assert( pTabItem->pTab );
        WHERETRACE(("   === trying table %d (%s) with isOptimal=%d ===\n",
                    j, sWBI.pSrc->pTab->zName, isOptimal));
        assert( sWBI.pSrc->pTab );
#ifndef SQLITE_OMIT_VIRTUALTABLE
        if( IsVirtual(pTabItem->pTab) ){
          sqlite3_index_info **pp = &pWInfo->a[j].pIdxInfo;
          bestVirtualIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy,
        if( IsVirtual(sWBI.pSrc->pTab) ){
          sWBI.ppIdxInfo = &pWInfo->a[j].pIdxInfo;
          bestVirtualIndex(&sWBI);
                           &sCost, pp);
        }else 
#endif
        {
          bestBtreeIndex(pParse, pWC, pTabItem, mask, notReady, pOrderBy,
          bestBtreeIndex(&sWBI);
              pDist, &sCost);
        }
        assert( isOptimal || (sCost.used&notReady)==0 );
        assert( isOptimal || (sWBI.cost.used&sWBI.notValid)==0 );

        /* If an INDEXED BY clause is present, then the plan must use that
        ** index if it uses any index at all */
        assert( pTabItem->pIndex==0 
                  || (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
                  || sCost.plan.u.pIdx==pTabItem->pIndex );
        assert( sWBI.pSrc->pIndex==0 
                  || (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
                  || sWBI.cost.plan.u.pIdx==sWBI.pSrc->pIndex );

        if( isOptimal && (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){
        if( isOptimal && (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){
          notIndexed |= m;
        }

        /* Conditions under which this table becomes the best so far:
        **
        **   (1) The table must not depend on other tables that have not
        **       yet run.
        **       yet run.  (In other words, it must not depend on tables
        **       in inner loops.)
        **
        **   (2) A full-table-scan plan cannot supercede indexed plan unless
        **       the full-table-scan is an "optimal" plan as defined above.
        **
        **   (3) All tables have an INDEXED BY clause or this table lacks an
        **       INDEXED BY clause or this table uses the specific
        **       index specified by its INDEXED BY clause.  This rule ensures
        **       that a best-so-far is always selected even if an impossible
        **       combination of INDEXED BY clauses are given.  The error
        **       will be detected and relayed back to the application later.
        **       The NEVER() comes about because rule (2) above prevents
        **       An indexable full-table-scan from reaching rule (3).
        **
        **   (4) The plan cost must be lower than prior plans or else the
        **       cost must be the same and the number of rows must be lower.
        **   (4) The plan cost must be lower than prior plans, where "cost"
        **       is defined by the compareCost() function above. 
        */
        if( (sCost.used&notReady)==0                       /* (1) */
            && (bestJ<0 || (notIndexed&m)!=0               /* (2) */
        if( (sWBI.cost.used&sWBI.notValid)==0                    /* (1) */
            && (bestJ<0 || (notIndexed&m)!=0                     /* (2) */
                || (bestPlan.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
                || (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)
            && (nUnconstrained==0 || pTabItem->pIndex==0   /* (3) */
                || NEVER((sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0))
            && (bestJ<0 || sCost.rCost<bestPlan.rCost      /* (4) */
                || (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)
            && (nUnconstrained==0 || sWBI.pSrc->pIndex==0        /* (3) */
                || NEVER((sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0))
            && (bestJ<0 || compareCost(&sWBI.cost, &bestPlan))   /* (4) */
                || (sCost.rCost<=bestPlan.rCost 
                 && sCost.plan.nRow<bestPlan.plan.nRow))
        ){
          WHERETRACE(("=== table %d is best so far"
                      " with cost=%g and nRow=%g\n",
                      j, sCost.rCost, sCost.plan.nRow));
          bestPlan = sCost;
          WHERETRACE(("   === table %d (%s) is best so far\n"
                      "       cost=%.1f, nRow=%.1f, nOBSat=%d, wsFlags=%08x\n",
                      j, sWBI.pSrc->pTab->zName,
                      sWBI.cost.rCost, sWBI.cost.plan.nRow,
                      sWBI.cost.plan.nOBSat, sWBI.cost.plan.wsFlags));
          bestPlan = sWBI.cost;
          bestJ = j;
        }
        if( doNotReorder ) break;
      }
    }
    assert( bestJ>=0 );
    assert( notReady & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
    WHERETRACE(("*** Optimizer selects table %d for loop %d"
                " with cost=%g and nRow=%g\n",
                bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow));
    assert( sWBI.notValid & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
    WHERETRACE(("*** Optimizer selects table %d (%s) for loop %d with:\n"
                "    cost=%.1f, nRow=%.1f, nOBSat=%d, wsFlags=0x%08x\n",
                bestJ, pTabList->a[bestJ].pTab->zName,
                pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow,
    /* The ALWAYS() that follows was added to hush up clang scan-build */
    if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 && ALWAYS(ppOrderBy) ){
                bestPlan.plan.nOBSat, bestPlan.plan.wsFlags));
      *ppOrderBy = 0;
    }
    if( (bestPlan.plan.wsFlags & WHERE_DISTINCT)!=0 ){
      assert( pWInfo->eDistinct==0 );
      pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
    }
    andFlags &= bestPlan.plan.wsFlags;
    pLevel->plan = bestPlan.plan;
    pLevel->iTabCur = pTabList->a[bestJ].iCursor;
    testcase( bestPlan.plan.wsFlags & WHERE_INDEXED );
    testcase( bestPlan.plan.wsFlags & WHERE_TEMP_INDEX );
    if( bestPlan.plan.wsFlags & (WHERE_INDEXED|WHERE_TEMP_INDEX) ){
      if( (wctrlFlags & WHERE_ONETABLE_ONLY) 
       && (bestPlan.plan.wsFlags & WHERE_TEMP_INDEX)==0 
      ){
        pLevel->iIdxCur = iIdxCur;
      }else{
        pLevel->iIdxCur = pParse->nTab++;
      }
    }else{
      pLevel->iIdxCur = -1;
    }
    notReady &= ~getMask(pMaskSet, pTabList->a[bestJ].iCursor);
    sWBI.notValid &= ~getMask(pMaskSet, pTabList->a[bestJ].iCursor);
    pLevel->iFrom = (u8)bestJ;
    if( bestPlan.plan.nRow>=(double)1 ){
      pParse->nQueryLoop *= bestPlan.plan.nRow;
    }

    /* Check that if the table scanned by this loop iteration had an
    ** INDEXED BY clause attached to it, that the named index is being
106852
106853
106854
106855
106856
106857
106858






106859
106860
106861
106862
106863
106864



106865
106866
106867
106868
106869
106870
106871
106872
106873
106874
106875
106876
106877
106878
106879
106880
106881
106882
106883
106884

106885
106886

106887
106888
106889
106890
106891
106892
106893
106894
106895
106896
106897
107209
107210
107211
107212
107213
107214
107215
107216
107217
107218
107219
107220
107221
107222
107223
107224
107225


107226
107227
107228
107229
107230
107231
107232
107233
107234
107235
107236
107237
107238
107239
107240
107241
107242
107243
107244
107245
107246
107247

107248
107249
107250
107251
107252
107253
107254

107255
107256
107257
107258
107259
107260
107261







+
+
+
+
+
+




-
-
+
+
+



















-
+


+



-







      }
    }
  }
  WHERETRACE(("*** Optimizer Finished ***\n"));
  if( pParse->nErr || db->mallocFailed ){
    goto whereBeginError;
  }
  if( nTabList ){
    pLevel--;
    pWInfo->nOBSat = pLevel->plan.nOBSat;
  }else{
    pWInfo->nOBSat = 0;
  }

  /* If the total query only selects a single row, then the ORDER BY
  ** clause is irrelevant.
  */
  if( (andFlags & WHERE_UNIQUE)!=0 && ppOrderBy ){
    *ppOrderBy = 0;
  if( (andFlags & WHERE_UNIQUE)!=0 && pOrderBy ){
    assert( nTabList==0 || (pLevel->plan.wsFlags & WHERE_ALL_UNIQUE)!=0 );
    pWInfo->nOBSat = pOrderBy->nExpr;
  }

  /* If the caller is an UPDATE or DELETE statement that is requesting
  ** to use a one-pass algorithm, determine if this is appropriate.
  ** The one-pass algorithm only works if the WHERE clause constraints
  ** the statement to update a single row.
  */
  assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
  if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 && (andFlags & WHERE_UNIQUE)!=0 ){
    pWInfo->okOnePass = 1;
    pWInfo->a[0].plan.wsFlags &= ~WHERE_IDX_ONLY;
  }

  /* Open all tables in the pTabList and any indices selected for
  ** searching those tables.
  */
  sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
  notReady = ~(Bitmask)0;
  pWInfo->nRowOut = (double)1;
  for(i=0, pLevel=pWInfo->a; i<nTabList; i++, pLevel++){
  for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){
    Table *pTab;     /* Table to open */
    int iDb;         /* Index of database containing table/index */
    struct SrcList_item *pTabItem;

    pTabItem = &pTabList->a[pLevel->iFrom];
    pTab = pTabItem->pTab;
    pLevel->iTabCur = pTabItem->iCursor;
    pWInfo->nRowOut *= pLevel->plan.nRow;
    iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
    if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){
      /* Do nothing */
    }else
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
106915
106916
106917
106918
106919
106920
106921
106922

106923
106924
106925
106926
106927
106928
106929
106930
106931
106932
106933
106934
106935
106936

106937
106938
106939
106940
106941
106942
106943
106944
106945
106946
106947
106948
106949




106950
106951
106952
106953
106954
106955
106956
106957
106958
106959
106960

106961
106962
106963


106964

106965
106966
106967
106968
106969
106970
106971
107279
107280
107281
107282
107283
107284
107285

107286
107287
107288
107289
107290
107291
107292
107293
107294
107295
107296
107297
107298
107299

107300
107301
107302
107303
107304
107305
107306
107307
107308
107309




107310
107311
107312
107313
107314
107315
107316
107317
107318
107319
107320
107321
107322
107323

107324
107325
107326
107327
107328
107329

107330
107331
107332
107333
107334
107335
107336
107337







-
+













-
+









-
-
-
-
+
+
+
+










-
+



+
+
-
+







        assert( n<=pTab->nCol );
      }
    }else{
      sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
    }
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
    if( (pLevel->plan.wsFlags & WHERE_TEMP_INDEX)!=0 ){
      constructAutomaticIndex(pParse, pWC, pTabItem, notReady, pLevel);
      constructAutomaticIndex(pParse, sWBI.pWC, pTabItem, notReady, pLevel);
    }else
#endif
    if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
      Index *pIx = pLevel->plan.u.pIdx;
      KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
      int iIndexCur = pLevel->iIdxCur;
      assert( pIx->pSchema==pTab->pSchema );
      assert( iIndexCur>=0 );
      sqlite3VdbeAddOp4(v, OP_OpenRead, iIndexCur, pIx->tnum, iDb,
                        (char*)pKey, P4_KEYINFO_HANDOFF);
      VdbeComment((v, "%s", pIx->zName));
    }
    sqlite3CodeVerifySchema(pParse, iDb);
    notReady &= ~getMask(pWC->pMaskSet, pTabItem->iCursor);
    notReady &= ~getMask(sWBI.pWC->pMaskSet, pTabItem->iCursor);
  }
  pWInfo->iTop = sqlite3VdbeCurrentAddr(v);
  if( db->mallocFailed ) goto whereBeginError;

  /* Generate the code to do the search.  Each iteration of the for
  ** loop below generates code for a single nested loop of the VM
  ** program.
  */
  notReady = ~(Bitmask)0;
  for(i=0; i<nTabList; i++){
    pLevel = &pWInfo->a[i];
    explainOneScan(pParse, pTabList, pLevel, i, pLevel->iFrom, wctrlFlags);
    notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady);
  for(ii=0; ii<nTabList; ii++){
    pLevel = &pWInfo->a[ii];
    explainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags);
    notReady = codeOneLoopStart(pWInfo, ii, wctrlFlags, notReady);
    pWInfo->iContinue = pLevel->addrCont;
  }

#ifdef SQLITE_TEST  /* For testing and debugging use only */
  /* Record in the query plan information about the current table
  ** and the index used to access it (if any).  If the table itself
  ** is not used, its name is just '{}'.  If no index is used
  ** the index is listed as "{}".  If the primary key is used the
  ** index name is '*'.
  */
  for(i=0; i<nTabList; i++){
  for(ii=0; ii<nTabList; ii++){
    char *z;
    int n;
    int w;
    struct SrcList_item *pTabItem;

    pLevel = &pWInfo->a[i];
    pLevel = &pWInfo->a[ii];
    w = pLevel->plan.wsFlags;
    pTabItem = &pTabList->a[pLevel->iFrom];
    z = pTabItem->zAlias;
    if( z==0 ) z = pTabItem->pTab->zName;
    n = sqlite3Strlen30(z);
    if( n+nQPlan < sizeof(sqlite3_query_plan)-10 ){
      if( (w & WHERE_IDX_ONLY)!=0 && (w & WHERE_COVER_SCAN)==0 ){
110362
110363
110364
110365
110366
110367
110368

110369
110370
110371
110372
110373
110374
110375
110728
110729
110730
110731
110732
110733
110734
110735
110736
110737
110738
110739
110740
110741
110742







+







      /* (318) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==318);
      /* (320) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==320);
      /* (324) anylist ::= */ yytestcase(yyruleno==324);
      /* (325) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==325);
      /* (326) anylist ::= anylist ANY */ yytestcase(yyruleno==326);
        break;
  };
  assert( yyruleno>=0 && yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
  yygoto = yyRuleInfo[yyruleno].lhs;
  yysize = yyRuleInfo[yyruleno].nrhs;
  yypParser->yyidx -= yysize;
  yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
  if( yyact < YYNSTATE ){
#ifdef NDEBUG
    /* If we are not debugging and the reduce action popped at least
112916
112917
112918
112919
112920
112921
112922

112923
112924
112925
112926
112927
112928
112929
113283
113284
113285
113286
113287
113288
113289
113290
113291
113292
113293
113294
113295
113296
113297







+







  int (*xBusy)(void*,int),
  void *pArg
){
  sqlite3_mutex_enter(db->mutex);
  db->busyHandler.xFunc = xBusy;
  db->busyHandler.pArg = pArg;
  db->busyHandler.nBusy = 0;
  db->busyTimeout = 0;
  sqlite3_mutex_leave(db->mutex);
  return SQLITE_OK;
}

#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/*
** This routine sets the progress callback for an Sqlite database to the
112953
112954
112955
112956
112957
112958
112959
112960
112961

112962
112963
112964
112965
112966
112967
112968
113321
113322
113323
113324
113325
113326
113327

113328
113329
113330
113331
113332
113333
113334
113335
113336







-

+








/*
** This routine installs a default busy handler that waits for the
** specified number of milliseconds before returning 0.
*/
SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){
  if( ms>0 ){
    db->busyTimeout = ms;
    sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
    db->busyTimeout = ms;
  }else{
    sqlite3_busy_handler(db, 0, 0);
  }
  return SQLITE_OK;
}

/*
114813
114814
114815
114816
114817
114818
114819
114820

114821
114822
114823
114824
114825
114826
114827
114828
115181
115182
115183
115184
115185
115186
115187

115188

115189
115190
115191
115192
115193
115194
115195







-
+
-







    ** operation N should be 0.  The idea is that a test program (like the
    ** SQL Logic Test or SLT test module) can run the same SQL multiple times
    ** with various optimizations disabled to verify that the same answer
    ** is obtained in every case.
    */
    case SQLITE_TESTCTRL_OPTIMIZATIONS: {
      sqlite3 *db = va_arg(ap, sqlite3*);
      int x = va_arg(ap,int);
      db->dbOptFlags = (u8)(va_arg(ap, int) & 0xff);
      db->flags = (x & SQLITE_OptMask) | (db->flags & ~SQLITE_OptMask);
      break;
    }

#ifdef SQLITE_N_KEYWORD
    /* sqlite3_test_control(SQLITE_TESTCTRL_ISKEYWORD, const char *zWord)
    **
    ** If zWord is a keyword recognized by the parser, then return the
135068
135069
135070
135071
135072
135073
135074
135075

135076
135077
135078
135079
135080
135081
135082
135435
135436
135437
135438
135439
135440
135441

135442
135443
135444
135445
135446
135447
135448
135449







-
+







}

/*
** Remove the entry with rowid=iDelete from the r-tree structure.
*/
static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
  int rc;                         /* Return code */
  RtreeNode *pLeaf;               /* Leaf node containing record iDelete */
  RtreeNode *pLeaf = 0;           /* Leaf node containing record iDelete */
  int iCell;                      /* Index of iDelete cell in pLeaf */
  RtreeNode *pRoot;               /* Root node of rtree structure */


  /* Obtain a reference to the root node to initialise Rtree.iDepth */
  rc = nodeAcquire(pRtree, 1, 0, &pRoot);

135271
135272
135273
135274
135275
135276
135277
135278

135279
135280
135281
135282
135283
135284
135285
135638
135639
135640
135641
135642
135643
135644

135645
135646
135647
135648
135649
135650
135651
135652







-
+








  /* If the azData[] array contains more than one element, elements
  ** (azData[2]..azData[argc-1]) contain a new record to insert into
  ** the r-tree structure.
  */
  if( rc==SQLITE_OK && nData>1 ){
    /* Insert the new record into the r-tree */
    RtreeNode *pLeaf;
    RtreeNode *pLeaf = 0;

    /* Figure out the rowid of the new row. */
    if( bHaveRowid==0 ){
      rc = newRowid(pRtree, &cell.iRowid);
    }
    *pRowid = cell.iRowid;

Changes to SQLite.Interop/src/core/sqlite3.h.

105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119







-
+







**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.7.15"
#define SQLITE_VERSION_NUMBER 3007015
#define SQLITE_SOURCE_ID      "2012-09-19 21:15:46 94b48064db3cbb43e911fdf7183218b08146ec10"
#define SQLITE_SOURCE_ID      "2012-10-12 18:06:07 de784399ed1f0e27fc875e32719643d19819c8fb"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
853
854
855
856
857
858
859











860
861
862
863
864
865
866
867
868
869
870
871
872
873
874

875
876
877
878
879
880
881
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893







+
+
+
+
+
+
+
+
+
+
+















+







** prepared statement.  ^If the [SQLITE_FCNTL_PRAGMA] file control returns
** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means
** that the VFS encountered an error while handling the [PRAGMA] and the
** compilation of the PRAGMA fails with an error.  ^The [SQLITE_FCNTL_PRAGMA]
** file control occurs at the beginning of pragma statement analysis and so
** it is able to override built-in [PRAGMA] statements.
** </ul>
**
** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
** ^This file-control may be invoked by SQLite on the database file handle
** shortly after it is opened in order to provide a custom VFS with access
** to the connections busy-handler callback. The argument is of type (void **)
** - an array of two (void *) values. The first (void *) actually points
** to a function of type (int (*)(void *)). In order to invoke the connections
** busy-handler, this function should be invoked with the second (void *) in
** the array as the only argument. If it returns non-zero, then the operation
** should be retried. If it returns zero, the custom VFS should abandon the
** current operation.
*/
#define SQLITE_FCNTL_LOCKSTATE               1
#define SQLITE_GET_LOCKPROXYFILE             2
#define SQLITE_SET_LOCKPROXYFILE             3
#define SQLITE_LAST_ERRNO                    4
#define SQLITE_FCNTL_SIZE_HINT               5
#define SQLITE_FCNTL_CHUNK_SIZE              6
#define SQLITE_FCNTL_FILE_POINTER            7
#define SQLITE_FCNTL_SYNC_OMITTED            8
#define SQLITE_FCNTL_WIN32_AV_RETRY          9
#define SQLITE_FCNTL_PERSIST_WAL            10
#define SQLITE_FCNTL_OVERWRITE              11
#define SQLITE_FCNTL_VFSNAME                12
#define SQLITE_FCNTL_POWERSAFE_OVERWRITE    13
#define SQLITE_FCNTL_PRAGMA                 14
#define SQLITE_FCNTL_BUSYHANDLER            15

/*
** CAPI3REF: Mutex Handle
**
** The mutex module within SQLite defines [sqlite3_mutex] to be an
** abstract type for a mutex object.  The SQLite core never looks
** at the internal representation of an [sqlite3_mutex].  It only
4747
4748
4749
4750
4751
4752
4753



4754
4755
4756
4757
4758
4759
4760
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775







+
+
+







**
** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled
** successfully.  An [error code] is returned otherwise.)^
**
** ^Shared cache is disabled by default. But this might change in
** future releases of SQLite.  Applications that care about shared
** cache setting should set it explicitly.
**
** This interface is threadsafe on processors where writing a
** 32-bit integer is atomic.
**
** See Also:  [SQLite Shared-Cache Mode]
*/
SQLITE_API int sqlite3_enable_shared_cache(int);

/*
** CAPI3REF: Attempt To Free Heap Memory

Changes to System.Data.SQLite/SQLite3.cs.

317
318
319
320
321
322
323






324
325


326
327
328
329
330
331
332





333
334
335
336



337
338
339

340
341
342

343
344


345
346
347
348
349
350
351
317
318
319
320
321
322
323
324
325
326
327
328
329


330
331
332
333





334
335
336
337
338
339



340
341
342
343
344

345
346
347

348


349
350
351
352
353
354
355
356
357







+
+
+
+
+
+
-
-
+
+


-
-
-
-
-
+
+
+
+
+

-
-
-
+
+
+


-
+


-
+
-
-
+
+







#if !NET_COMPACT_20 && TRACE_CONNECTION
        Trace.WriteLine(String.Format("Open (Pool): {0}", (_sql != null) ? _sql.ToString() : "<null>"));
#endif
      }

      if (_sql == null)
      {
        try
        {
            // do nothing.
        }
        finally /* NOTE: Thread.Abort() protection. */
        {
        IntPtr db;
        SQLiteErrorCode n;
          IntPtr db;
          SQLiteErrorCode n;

#if !SQLITE_STANDARD
        if ((connectionFlags & SQLiteConnectionFlags.NoExtensionFunctions) != SQLiteConnectionFlags.NoExtensionFunctions)
        {
          n = UnsafeNativeMethods.sqlite3_open_interop(ToUTF8(strFilename), openFlags, out db);
        }
        else
          if ((connectionFlags & SQLiteConnectionFlags.NoExtensionFunctions) != SQLiteConnectionFlags.NoExtensionFunctions)
          {
            n = UnsafeNativeMethods.sqlite3_open_interop(ToUTF8(strFilename), openFlags, out db);
          }
          else
#endif
        {
          n = UnsafeNativeMethods.sqlite3_open_v2(ToUTF8(strFilename), out db, openFlags, IntPtr.Zero);
        }
          {
            n = UnsafeNativeMethods.sqlite3_open_v2(ToUTF8(strFilename), out db, openFlags, IntPtr.Zero);
          }

#if !NET_COMPACT_20 && TRACE_CONNECTION
        Trace.WriteLine(String.Format("Open: {0}", db));
          Trace.WriteLine(String.Format("Open: {0}", db));
#endif

        if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null);
          if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null);

        _sql = new SQLiteConnectionHandle(db);
          _sql = new SQLiteConnectionHandle(db);
        }
        lock (_sql) { /* HACK: Force the SyncBlock to be "created" now. */ }
      }
      // Bind functions to this connection.  If any previous functions of the same name
      // were already bound, then the new bindings replace the old.
      _functionsArray = SQLiteFunction.BindFunctions(this, connectionFlags);
      SetTimeout(0);
      GC.KeepAlive(_sql);
512
513
514
515
516
517
518

519
520
521
522






523
524

525
526
527


528
529
530
531

532




533
534
535
536
537
538
539
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536

537
538


539
540
541
542
543

544
545
546
547
548
549
550
551
552
553
554
555
556







+




+
+
+
+
+
+

-
+

-
-
+
+



-
+

+
+
+
+







      string typedefs = null;
      SQLiteStatement cmd = null;
      Random rnd = null;
      uint starttick = (uint)Environment.TickCount;

      GCHandle handle = GCHandle.Alloc(b, GCHandleType.Pinned);
      IntPtr psql = handle.AddrOfPinnedObject();
      SQLiteStatementHandle statementHandle = null;
      try
      {
        while ((n == SQLiteErrorCode.Schema || n == SQLiteErrorCode.Locked || n == SQLiteErrorCode.Busy) && retries < 3)
        {
          try
          {
            // do nothing.
          }
          finally /* NOTE: Thread.Abort() protection. */
          {
#if !SQLITE_STANDARD
          n = UnsafeNativeMethods.sqlite3_prepare_interop(_sql, psql, b.Length - 1, out stmt, out ptr, out len);
            n = UnsafeNativeMethods.sqlite3_prepare_interop(_sql, psql, b.Length - 1, out stmt, out ptr, out len);
#else
          n = UnsafeNativeMethods.sqlite3_prepare(_sql, psql, b.Length - 1, out stmt, out ptr);
          len = -1;
            n = UnsafeNativeMethods.sqlite3_prepare(_sql, psql, b.Length - 1, out stmt, out ptr);
            len = -1;
#endif

#if !NET_COMPACT_20 && TRACE_STATEMENT
          Trace.WriteLine(String.Format("Prepare ({0}): {1}", n, stmt));
            Trace.WriteLine(String.Format("Prepare ({0}): {1}", n, stmt));
#endif

            if ((n == SQLiteErrorCode.Ok) && (stmt != IntPtr.Zero))
              statementHandle = new SQLiteStatementHandle(_sql, stmt);
          }

          if (n == SQLiteErrorCode.Schema)
            retries++;
          else if (n == SQLiteErrorCode.Error)
          {
            if (String.Compare(GetLastError(), "near \"TYPES\": syntax error", StringComparison.OrdinalIgnoreCase) == 0)
            {
602
603
604
605
606
607
608
609

610
611
612
613
614
615
616
619
620
621
622
623
624
625

626
627
628
629
630
631
632
633







-
+







          }
        }

        if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());

        strRemain = UTF8ToString(ptr, len);

        if (stmt != IntPtr.Zero) cmd = new SQLiteStatement(this, flags, new SQLiteStatementHandle(_sql, stmt), strSql.Substring(0, strSql.Length - strRemain.Length), previous);
        if (statementHandle != null) cmd = new SQLiteStatement(this, flags, statementHandle, strSql.Substring(0, strSql.Length - strRemain.Length), previous);

        return cmd;
      }
      finally
      {
        handle.Free();
      }
1491
1492
1493
1494
1495
1496
1497
1498

1499
1500
1501
1502
1503
1504
1505
1508
1509
1510
1511
1512
1513
1514

1515
1516
1517
1518
1519
1520
1521
1522







-
+







    /// Gets the last SQLite extended error code
    internal override SQLiteErrorCode ExtendedResultCode()
    {
      return UnsafeNativeMethods.sqlite3_extended_errcode(_sql);
    }

    /// Add a log message via the SQLite sqlite3_log interface.
    internal override void LogMessage(int iErrCode, string zMessage)
    internal override void LogMessage(SQLiteErrorCode iErrCode, string zMessage)
    {
      UnsafeNativeMethods.sqlite3_log(iErrCode, ToUTF8(zMessage));
    }

#if INTEROP_CODEC
    internal override void SetPassword(byte[] passwordBytes)
    {
1595
1596
1597
1598
1599
1600
1601








1602
1603


1604
1605
1606


1607



1608
1609
1610


1611
1612
1613
1614
1615
1616
1617
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626


1627
1628
1629


1630
1631
1632
1633
1634
1635
1636


1637
1638
1639
1640
1641
1642
1643
1644
1645







+
+
+
+
+
+
+
+
-
-
+
+

-
-
+
+

+
+
+

-
-
+
+







        if (sourceHandle == null)
            throw new InvalidOperationException(
                "Source connection has an invalid handle.");

        byte[] zDestName = ToUTF8(destName);
        byte[] zSourceName = ToUTF8(sourceName);

        SQLiteBackupHandle backupHandle = null;

        try
        {
            // do nothing.
        }
        finally /* NOTE: Thread.Abort() protection. */
        {
        IntPtr backup = UnsafeNativeMethods.sqlite3_backup_init(
            destHandle, zDestName, sourceHandle, zSourceName);
            IntPtr backup = UnsafeNativeMethods.sqlite3_backup_init(
                destHandle, zDestName, sourceHandle, zSourceName);

        if (backup == IntPtr.Zero)
            throw new SQLiteException(ResultCode(), GetLastError());
            if (backup == IntPtr.Zero)
                throw new SQLiteException(ResultCode(), GetLastError());

            backupHandle = new SQLiteBackupHandle(destHandle, backup);
        }

        return new SQLiteBackup(
            this, new SQLiteBackupHandle(destHandle, backup),
            destHandle, zDestName, sourceHandle, zSourceName);
            this, backupHandle, destHandle, zDestName, sourceHandle,
            zSourceName);
    }

    /// <summary>
    /// Copies up to N pages from the source database to the destination
    /// database associated with the specified backup object.
    /// </summary>
    /// <param name="backup">The backup object to use.</param>

Changes to System.Data.SQLite/SQLite3_UTF16.cs.

99
100
101
102
103
104
105
106

107
108
109
110
111






112
113


114
115
116
117
118
119
120





121
122
123
124
125
126
127
128
129
130









131
132
133


134
135
136

137
138
139

140
141


142
143
144
145
146
147
148
99
100
101
102
103
104
105

106
107
108
109
110
111
112
113
114
115
116
117


118
119
120
121





122
123
124
125
126
127









128
129
130
131
132
133
134
135
136
137


138
139
140
141

142
143
144

145


146
147
148
149
150
151
152
153
154







-
+





+
+
+
+
+
+
-
-
+
+


-
-
-
-
-
+
+
+
+
+

-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+

-
-
+
+


-
+


-
+
-
-
+
+







      _fileName = strFilename;

      if (usePool)
      {
        _sql = SQLiteConnectionPool.Remove(strFilename, maxPoolSize, out _poolVersion);

#if !NET_COMPACT_20 && TRACE_CONNECTION
        Trace.WriteLine(String.Format("Open (Pool): {0}", (_sql != null) ? _sql.ToString() : "<null>"));
        Trace.WriteLine(String.Format("Open16 (Pool): {0}", (_sql != null) ? _sql.ToString() : "<null>"));
#endif
      }

      if (_sql == null)
      {
        try
        {
            // do nothing.
        }
        finally /* NOTE: Thread.Abort() protection. */
        {
        IntPtr db;
        SQLiteErrorCode n;
          IntPtr db;
          SQLiteErrorCode n;

#if !SQLITE_STANDARD
        if ((connectionFlags & SQLiteConnectionFlags.NoExtensionFunctions) != SQLiteConnectionFlags.NoExtensionFunctions)
        {
          n = UnsafeNativeMethods.sqlite3_open16_interop(ToUTF8(strFilename), openFlags, out db);
        }
        else
          if ((connectionFlags & SQLiteConnectionFlags.NoExtensionFunctions) != SQLiteConnectionFlags.NoExtensionFunctions)
          {
            n = UnsafeNativeMethods.sqlite3_open16_interop(ToUTF8(strFilename), openFlags, out db);
          }
          else
#endif
        {
          //
          // NOTE: This flag check is designed to enforce the constraint that opening
          //       a database file that does not already exist requires specifying the
          //       "Create" flag, even when a native API is used that does not accept
          //       a flags parameter.
          //
          if (((openFlags & SQLiteOpenFlagsEnum.Create) != SQLiteOpenFlagsEnum.Create) && !File.Exists(strFilename))
            throw new SQLiteException(SQLiteErrorCode.CantOpen, strFilename);
          {
            //
            // NOTE: This flag check is designed to enforce the constraint that opening
            //       a database file that does not already exist requires specifying the
            //       "Create" flag, even when a native API is used that does not accept
            //       a flags parameter.
            //
            if (((openFlags & SQLiteOpenFlagsEnum.Create) != SQLiteOpenFlagsEnum.Create) && !File.Exists(strFilename))
              throw new SQLiteException(SQLiteErrorCode.CantOpen, strFilename);

          n = UnsafeNativeMethods.sqlite3_open16(strFilename, out db);
        }
            n = UnsafeNativeMethods.sqlite3_open16(strFilename, out db);
          }

#if !NET_COMPACT_20 && TRACE_CONNECTION
        Trace.WriteLine(String.Format("Open: {0}", db));
          Trace.WriteLine(String.Format("Open16: {0}", db));
#endif

        if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null);
          if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null);

        _sql = new SQLiteConnectionHandle(db);
          _sql = new SQLiteConnectionHandle(db);
        }
        lock (_sql) { /* HACK: Force the SyncBlock to be "created" now. */ }
      }
      _functionsArray = SQLiteFunction.BindFunctions(this, connectionFlags);
      SetTimeout(0);
      GC.KeepAlive(_sql);
    }

Changes to System.Data.SQLite/SQLiteBase.cs.

232
233
234
235
236
237
238
239

240
241
242
243
244
245
246
232
233
234
235
236
237
238

239
240
241
242
243
244
245
246







-
+







    /// Add a log message via the SQLite sqlite3_log interface.
    /// </summary>
    /// <param name="iErrCode">Error code to be logged with the message.</param>
    /// <param name="zMessage">String to be logged.  Unlike the SQLite sqlite3_log() 
    /// interface, this should be pre-formatted.  Consider using the 
    /// String.Format() function.</param>
    /// <returns></returns>
    internal abstract void LogMessage(int iErrCode, string zMessage);
    internal abstract void LogMessage(SQLiteErrorCode iErrCode, string zMessage);

#if INTEROP_CODEC
    internal abstract void SetPassword(byte[] passwordBytes);
    internal abstract void ChangePassword(byte[] newPasswordBytes);
#endif

    internal abstract void SetUpdateHook(SQLiteUpdateCallback func);
469
470
471
472
473
474
475








476
477

478
479

480
481
482


483
484

485
486
487


488
489

490
491
492



493
494
495






496
497
498
499
500







501
502

503
504

505
506

507
508

509
510

511
512


513
514
515
516
517
518







519
520

521
522

523
524

525
526

527
528

529
530


531
532
533
534
535
536







537
538

539
540

541
542

543
544

545
546

547
548

549
550
551
552
553
554
555
556
557








558
559


560
561
562
563
564
565









566
567

568
569

570
571
572
573



574
575
576


577
578

579
580
581
582
583
584
585
586
587









588
589

590
591

592
593
594


595



596
597
598
599
600
601
602

















603
604


605
606
607
608
609

610
611
612
613
614










615
616

617
618

619
620
621
622
623




624
625
626



627
628
629
630
631
632
633
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484

485
486

487
488


489
490


491
492


493
494
495

496
497


498
499
500



501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519

520
521

522
523

524
525

526
527

528
529

530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545

546
547

548
549

550
551

552
553

554
555

556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571

572
573

574
575

576
577

578
579

580
581

582
583








584
585
586
587
588
589
590
591
592

593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610

611
612

613
614



615
616
617
618


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
672
673
674
675
676
677
678
679
680
681

682
683

684
685




686
687
688
689



690
691
692
693
694
695
696
697
698
699







+
+
+
+
+
+
+
+

-
+

-
+

-
-
+
+
-
-
+

-
-
+
+

-
+

-
-
+
+
+
-
-
-
+
+
+
+
+
+





+
+
+
+
+
+
+

-
+

-
+

-
+

-
+

-
+

-
+
+






+
+
+
+
+
+
+

-
+

-
+

-
+

-
+

-
+

-
+
+






+
+
+
+
+
+
+

-
+

-
+

-
+

-
+

-
+

-
+

-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+

-
+
+






+
+
+
+
+
+
+
+
+

-
+

-
+

-
-
-
+
+
+

-
-
+
+

-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+

-
+

-
+

-
-
+
+

+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+




-
+




-
+
+
+
+
+
+
+
+
+
+

-
+

-
+

-
-
-
-
+
+
+
+
-
-
-
+
+
+







    }

    internal static string GetLastError(SQLiteConnectionHandle hdl, IntPtr db)
    {
        if ((hdl == null) || (db == IntPtr.Zero))
            return "null connection or database handle";

        string result = null;

        try
        {
            // do nothing.
        }
        finally /* NOTE: Thread.Abort() protection. */
        {
#if PLATFORM_COMPACTFRAMEWORK
        lock (hdl.syncRoot)
            lock (hdl.syncRoot)
#else
        lock (hdl)
            lock (hdl)
#endif
        {
            if (hdl.IsInvalid || hdl.IsClosed)
            {
                if (!hdl.IsInvalid && !hdl.IsClosed)
                return "closed or invalid connection handle";

                {
#if !SQLITE_STANDARD
            int len;
            return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg_interop(db, out len), len);
                    int len;
                    result = UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg_interop(db, out len), len);
#else
            return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg(db), -1);
                    result = UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg(db), -1);
#endif
        }

                }
                else
                {
#pragma warning disable 162
        GC.KeepAlive(hdl); /* NOTE: Unreachable code. */
#pragma warning restore 162
                    result = "closed or invalid connection handle";
                }
            }
        }
        GC.KeepAlive(hdl);
        return result;
    }

    internal static void FinishBackup(SQLiteConnectionHandle hdl, IntPtr backup)
    {
        if ((hdl == null) || (backup == IntPtr.Zero)) return;

        try
        {
            // do nothing.
        }
        finally /* NOTE: Thread.Abort() protection. */
        {
#if PLATFORM_COMPACTFRAMEWORK
        lock (hdl.syncRoot)
            lock (hdl.syncRoot)
#else
        lock (hdl)
            lock (hdl)
#endif
        {
            {
#if !SQLITE_STANDARD
            SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_backup_finish_interop(backup);
                SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_backup_finish_interop(backup);
#else
            SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_backup_finish(backup);
                SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_backup_finish(backup);
#endif
            if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null);
                if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null);
            }
        }
    }

    internal static void FinalizeStatement(SQLiteConnectionHandle hdl, IntPtr stmt)
    {
        if ((hdl == null) || (stmt == IntPtr.Zero)) return;

        try
        {
            // do nothing.
        }
        finally /* NOTE: Thread.Abort() protection. */
        {
#if PLATFORM_COMPACTFRAMEWORK
        lock (hdl.syncRoot)
            lock (hdl.syncRoot)
#else
        lock (hdl)
            lock (hdl)
#endif
        {
            {
#if !SQLITE_STANDARD
            SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_finalize_interop(stmt);
                SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_finalize_interop(stmt);
#else
            SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_finalize(stmt);
                SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_finalize(stmt);
#endif
            if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null);
                if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null);
            }
        }
    }

    internal static void CloseConnection(SQLiteConnectionHandle hdl, IntPtr db)
    {
        if ((hdl == null) || (db == IntPtr.Zero)) return;

        try
        {
            // do nothing.
        }
        finally /* NOTE: Thread.Abort() protection. */
        {
#if PLATFORM_COMPACTFRAMEWORK
        lock (hdl.syncRoot)
            lock (hdl.syncRoot)
#else
        lock (hdl)
            lock (hdl)
#endif
        {
            {
#if !SQLITE_STANDARD
            SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_close_interop(db);
                SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_close_interop(db);
#else
            ResetConnection(hdl, db);
                ResetConnection(hdl, db);

            SQLiteErrorCode n;
                SQLiteErrorCode n;

            try
            {
                n = UnsafeNativeMethods.sqlite3_close_v2(db);
            }
            catch (EntryPointNotFoundException)
            {
                n = UnsafeNativeMethods.sqlite3_close(db);
            }
                try
                {
                    n = UnsafeNativeMethods.sqlite3_close_v2(db);
                }
                catch (EntryPointNotFoundException)
                {
                    n = UnsafeNativeMethods.sqlite3_close(db);
                }
#endif
            if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError(hdl, db));
                if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError(hdl, db));
            }
        }
    }

    internal static bool ResetConnection(SQLiteConnectionHandle hdl, IntPtr db, bool canThrow)
    {
        if ((hdl == null) || (db == IntPtr.Zero)) return false;

        bool result = false;

        try
        {
            // do nothing.
        }
        finally /* NOTE: Thread.Abort() protection. */
        {
#if PLATFORM_COMPACTFRAMEWORK
        lock (hdl.syncRoot)
            lock (hdl.syncRoot)
#else
        lock (hdl)
            lock (hdl)
#endif
        {
            if (canThrow && hdl.IsInvalid)
                throw new InvalidOperationException("The connection handle is invalid.");
            {
                if (canThrow && hdl.IsInvalid)
                    throw new InvalidOperationException("The connection handle is invalid.");

            if (canThrow && hdl.IsClosed)
                throw new InvalidOperationException("The connection handle is closed.");
                if (canThrow && hdl.IsClosed)
                    throw new InvalidOperationException("The connection handle is closed.");

            if (!canThrow && (hdl.IsInvalid || hdl.IsClosed))
                if (!hdl.IsInvalid && !hdl.IsClosed)
                return false;

            IntPtr stmt = IntPtr.Zero;
            SQLiteErrorCode n;
            do
            {
                stmt = UnsafeNativeMethods.sqlite3_next_stmt(db, stmt);
                if (stmt != IntPtr.Zero)
                {
                {
                    IntPtr stmt = IntPtr.Zero;
                    SQLiteErrorCode n;

                    do
                    {
                        stmt = UnsafeNativeMethods.sqlite3_next_stmt(db, stmt);
                        if (stmt != IntPtr.Zero)
                        {
#if !SQLITE_STANDARD
                    n = UnsafeNativeMethods.sqlite3_reset_interop(stmt);
                            n = UnsafeNativeMethods.sqlite3_reset_interop(stmt);
#else
                    n = UnsafeNativeMethods.sqlite3_reset(stmt);
                            n = UnsafeNativeMethods.sqlite3_reset(stmt);
#endif
                }
            } while (stmt != IntPtr.Zero);
                        }
                    } while (stmt != IntPtr.Zero);

                    //
                    // NOTE: Is a transaction NOT pending on the connection?
                    //
            if (IsAutocommit(hdl, db) == false) // a transaction is pending on the connection
            {
                n = UnsafeNativeMethods.sqlite3_exec(db, ToUTF8("ROLLBACK"), IntPtr.Zero, IntPtr.Zero, out stmt);
                if (n != SQLiteErrorCode.Ok)
                {
                    if (canThrow)
                        throw new SQLiteException(n, GetLastError(hdl, db));
                    if (IsAutocommit(hdl, db))
                    {
                        result = true;
                    }
                    else
                    {
                        n = UnsafeNativeMethods.sqlite3_exec(
                            db, ToUTF8("ROLLBACK"), IntPtr.Zero, IntPtr.Zero,
                            out stmt);

                        if (n == SQLiteErrorCode.Ok)
                        {
                            result = true;
                        }
                        else if (canThrow)
                        {
                            throw new SQLiteException(n, GetLastError(hdl, db));
                    else
                        return false;
                        }
                    }
                }
            }
        }
        GC.KeepAlive(hdl);
        return true;
        return result;
    }

    internal static bool IsAutocommit(SQLiteConnectionHandle hdl, IntPtr db)
    {
      if (db == IntPtr.Zero) return false;
        if ((hdl == null) || (db == IntPtr.Zero)) return false;

        bool result = false;

        try
        {
            // do nothing.
        }
        finally /* NOTE: Thread.Abort() protection. */
        {
#if PLATFORM_COMPACTFRAMEWORK
      lock (hdl.syncRoot)
            lock (hdl.syncRoot)
#else
      lock (hdl)
            lock (hdl)
#endif
      {
          if (hdl.IsInvalid || hdl.IsClosed) return false;
          return (UnsafeNativeMethods.sqlite3_get_autocommit(db) == 1);
      }
            {
                if (!hdl.IsInvalid && !hdl.IsClosed)
                    result = (UnsafeNativeMethods.sqlite3_get_autocommit(db) == 1);
            }
#pragma warning disable 162
      GC.KeepAlive(hdl); /* NOTE: Unreachable code. */
#pragma warning restore 162
        }
        GC.KeepAlive(hdl); /* NOTE: Unreachable code. */
        return result;
    }
  }

  internal interface ISQLiteSchemaExtensions
  {
    void BuildTempSchema(SQLiteConnection cnn);
  }

Changes to System.Data.SQLite/SQLiteConnection.cs.

1930
1931
1932
1933
1934
1935
1936
1937

1938
1939
1940
1941
1942
1943
1944
1945











1946
1947
1948
1949
1950
1951
1952
1930
1931
1932
1933
1934
1935
1936

1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963







-
+








+
+
+
+
+
+
+
+
+
+
+








      if (_sql == null)
        throw new InvalidOperationException("Database connection not valid for getting extended result code.");
      return _sql.ExtendedResultCode();
    }

    /// Add a log message via the SQLite sqlite3_log interface.
    public void LogMessage(int iErrCode, string zMessage)
    public void LogMessage(SQLiteErrorCode iErrCode, string zMessage)
    {
      CheckDisposed();

      if (_sql == null)
          throw new InvalidOperationException("Database connection not valid for logging message.");

      _sql.LogMessage(iErrCode, zMessage);
    }

    /// Add a log message via the SQLite sqlite3_log interface.
    public void LogMessage(int iErrCode, string zMessage)
    {
      CheckDisposed();

      if (_sql == null)
          throw new InvalidOperationException("Database connection not valid for logging message.");

      _sql.LogMessage((SQLiteErrorCode)iErrCode, zMessage);
    }

#if INTEROP_CODEC
    /// <summary>
    /// Change the password (or assign a password) to an open database.
    /// </summary>
    /// <remarks>
    /// No readers or writers may be active for this process.  The database must already be open

Changes to System.Data.SQLite/UnsafeNativeMethods.cs.

1336
1337
1338
1339
1340
1341
1342
1343

1344
1345
1346
1347
1348
1349
1350
1336
1337
1338
1339
1340
1341
1342

1343
1344
1345
1346
1347
1348
1349
1350







-
+







    // for all possible calls.  For now, we are only exposing a single string, and 
    // depend on the caller to format the string.
#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern void sqlite3_log(int iErrCode, byte[] zFormat);
    internal static extern void sqlite3_log(SQLiteErrorCode iErrCode, byte[] zFormat);

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern SQLiteErrorCode sqlite3_file_control(IntPtr db, byte[] zDbName, int op, IntPtr pArg);

Changes to Tests/basic.eagle.

1441
1442
1443
1444
1445
1446
1447
1448
1449

1450
1451
1452
1453
1454
1455
1456
1441
1442
1443
1444
1445
1446
1447


1448
1449
1450
1451
1452
1453
1454
1455







-
-
+







###############################################################################

runTest {test data-1.28 {SetMemoryStatus method} -setup {
  #
  # NOTE: Make sure that SQLite core library is completely shutdown prior to
  #       starting this test.
  #
  object invoke -flags +NonPublic System.Data.SQLite.UnsafeNativeMethods \
      sqlite3_shutdown
  shutdownSQLite $test_channel

  #
  # NOTE: Create an instance of the core SQLite library interop wrapper class.
  #
  set sqlite3 [object create -flags +NonPublic System.Data.SQLite.SQLite3 \
      Default Unspecified]
} -body {
1499
1500
1501
1502
1503
1504
1505
1506
1507

1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524


1525
1526
1527
1528
1529
1530
1531
1498
1499
1500
1501
1502
1503
1504


1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520


1521
1522
1523
1524
1525
1526
1527
1528
1529







-
-
+















-
-
+
+







      [expr {$result(after4) < $result(after3)}]
} -cleanup {
  catch {
    #
    # NOTE: Make sure that SQLite core library is completely shutdown prior
    #       to attempting to reconfigure the memory status setting.
    #
    object invoke -flags +NonPublic System.Data.SQLite.UnsafeNativeMethods \
        sqlite3_shutdown
    shutdownSQLite $test_channel

    #
    # NOTE: Attempt to make sure the default value for the process-wide
    #       memory usage tracking setting is restored.  This is not 100%
    #       reliable because we have no idea what the original value was
    #       upon entry into this test (i.e. because the underlying core
    #       library property is currently write-only).
    #
    object invoke -flags +NonPublic System.Data.SQLite.UnsafeNativeMethods \
        sqlite3_config_int SQLITE_CONFIG_MEMSTATUS 1
  }

  unset -nocomplain result sqlite3
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^Ok Misuse Ok Ok System#IntPtr#\d+ System#IntPtr#\d+ \d+ \d+ \d+\
\d+ \d+ True True True True True True$}}
regexp -result {^Ok Misuse Ok Ok System#IntPtr#\d+ System#IntPtr#\d+ \d+ \d+\
\d+ \d+ \d+ True True True True True True$}}

###############################################################################

runTest {test data-1.29 {SQLiteConnection.Open with SetDefaults=False} -setup {
  setupDb [set fileName data-1.29.db] "" "" "" "" SetDefaults=False
} -body {
  set result [list]

Changes to Tests/common.eagle.

684
685
686
687
688
689
690











691
692
693
694
695
696
697
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708







+
+
+
+
+
+
+
+
+
+
+







    proc isMemoryDb { fileName } {
      #
      # NOTE: Is the specified database file name really an in-memory database?
      #
      return [expr {$fileName eq ":memory:" || \
          [string range $fileName 0 12] eq "file::memory:"}]
    }

    proc executeSql { sql {execute none} {fileName ""} } {
      if {[string length $fileName] == 0} then {set fileName :memory:}
      setupDb $fileName "" "" "" "" "" false false false false memDb

      try {
        return [sql execute -execute $execute $memDb $sql]
      } finally {
        cleanupDb $fileName memDb false false
      }
    }

    proc setupDb {
            fileName {mode ""} {dateTimeFormat ""} {dateTimeKind ""} {flags ""}
            {extra ""} {qualify true} {delete true} {uri false}
            {temporary true} {varName db} } {
      #
      # NOTE: First, see if our caller has requested an in-memory database.
821
822
823
824
825
826
827
828

829
830

831
832
833
834
835
836
837
832
833
834
835
836
837
838

839
840

841
842
843
844
845
846
847
848







-
+

-
+







      #
      set db [sql open -type SQLite [subst $connection]]

      #
      # NOTE: Configure the temporary directory for the newly opened database
      #       connection now unless our caller forbids it.
      #
      if {$temporary} then {
      if {$temporary && ![info exists ::no(setTemporaryDirectory)]} then {
        sql execute $db [appendArgs \
            "PRAGMA temp_store_directory = \"" [getTemporaryDirectory] "\";"]
            "PRAGMA temp_store_directory = \"" [getTemporaryDirectory] \"\;]
      }

      #
      # NOTE: Always return the connection handle upon success.
      #
      return $db
    }
1036
1037
1038
1039
1040
1041
1042

























1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060

1061
1062
1063
1064
1065
1066
1067
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095

1096
1097
1098
1099
1100
1101
1102
1103







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

















-
+







      #
      if {[catch {object invoke GC GetTotalMemory true} error]} then {
        tputs $channel [appendArgs \
            "==== WARNING: failed full garbage collection, error: " \
            \n\t $error \n]
      }
    }

    proc shutdownSQLite { channel {force false} {quiet false} } {
      #
      # NOTE: Make sure that SQLite core library is completely shutdown.  This
      #       is used by tests that change configuration options and/or those
      #       that need to make sure logging is initialized (i.e. just in case
      #       the SQLite core library was initialized in the process prior to
      #       the SQLiteLog class being able to setup its logging callback).
      #
      if {$force || [haveConstraint SQLite]} then {
        if {[catch {object invoke -flags +NonPublic \
              System.Data.SQLite.UnsafeNativeMethods \
              sqlite3_shutdown} result] == 0} then {
          if {!$quiet} then {
            tputs $channel [appendArgs \
                "---- call sqlite3_shutdown()... ok: " $result \n]
          }
        } else {
          if {!$quiet} then {
            tputs $channel [appendArgs \
                "---- call sqlite3_shutdown()... error: " \n\t $result \n]
          }
        }
      }
    }

    proc reportSQLiteResources { channel {quiet false} {collect true} } {
      #
      # NOTE: Skip all output if we are running in "quiet" mode.
      #
      if {!$quiet} then {
        tputs $channel "---- current memory in use by SQLite... "
      }

      if {[catch {object invoke -flags +NonPublic \
              System.Data.SQLite.UnsafeNativeMethods \
              sqlite3_memory_used} memory] == 0} then {
        if {!$quiet} then {
          tputs $channel [appendArgs $memory " bytes\n"]
        }
      } else {
        #
        # NOTE: Maybe the SQLite native library is unavailable?
        # NOTE: Maybe the SQLite core library is unavailable?
        #
        set memory unknown

        if {!$quiet} then {
          tputs $channel [appendArgs $memory \n]
        }
      }
1076
1077
1078
1079
1080
1081
1082
1083

1084
1085
1086
1087
1088
1089
1090
1112
1113
1114
1115
1116
1117
1118

1119
1120
1121
1122
1123
1124
1125
1126







-
+







              System.Data.SQLite.UnsafeNativeMethods \
              sqlite3_memory_highwater 0} memory] == 0} then {
        if {!$quiet} then {
          tputs $channel [appendArgs $memory " bytes\n"]
        }
      } else {
        #
        # NOTE: Maybe the SQLite native library is unavailable?
        # NOTE: Maybe the SQLite core library is unavailable?
        #
        set memory unknown

        if {!$quiet} then {
          tputs $channel [appendArgs $memory \n]
        }
      }
1115
1116
1117
1118
1119
1120
1121





































































































1122
1123
1124
1125
1126
1127
1128
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







        if {!$quiet} then {
          tputs $channel [appendArgs $memory \n]
        }
      }

      return $result
    }

    proc checkForSQLiteDirectories { channel {reset false} } {
      #
      # NOTE: Check if the sqlite3_win32_set_directory function is available.
      #
      tputs $channel \
          "---- checking for function sqlite3_win32_set_directory... "

      #
      # NOTE: This call to the sqlite3_win32_set_directory function uses the
      #       invalid value 0 for the first argument.  This code is designed
      #       to check if calling the function will raise an exception (i.e.
      #       the actual result of the function does not matter as long as no
      #       directory is changed).
      #
      if {[catch {
              object invoke -flags +NonPublic \
              System.Data.SQLite.UnsafeNativeMethods \
              sqlite3_win32_set_directory 0 null}] == 0} then {
        #
        # NOTE: Calling the sqlite3_win32_set_directory function does not
        #       cause an exception; therefore, it must be available (i.e.
        #       even though it should return a failure return code in this
        #       case).
        #
        addConstraint sqlite3_win32_set_directory

        tputs $channel yes\n

        #
        # NOTE: Does our caller want to reset the directories?
        #
        if {$reset} then {
          #
          # NOTE: Now make sure the database and temporary directories are
          #       reset their default values, which should be null for both.
          #       Since the sqlite3_win32_set_directory function is available,
          #       use it.
          #
          for {set index 1} {$index < 3} {incr index} {
            if {[catch {
                    object invoke -flags +NonPublic \
                    System.Data.SQLite.UnsafeNativeMethods \
                    sqlite3_win32_set_directory $index null} \
                    result] == 0} then {
              tputs $channel [appendArgs \
                  "---- call sqlite3_win32_set_directory(" $index \
                  ", null)... ok: " $result \n]
            } else {
              tputs $channel [appendArgs \
                  "---- call sqlite3_win32_set_directory(" $index \
                  ", null)... error: " \n\t $result \n]
            }
          }
        }
      } else {
        tputs $channel no\n

        #
        # NOTE: Does our caller want to reset the directories?
        #
        if {$reset} then {
          #
          # NOTE: Now make sure the database and temporary directories are
          #       reset their default values, which should be null for both.
          #       Since the sqlite3_win32_set_directory function does not
          #       appear to be available, use the associated PRAGMA commands
          #       instead.
          #
          foreach directory [list data_store_directory temp_store_directory] {
            set sql [appendArgs "PRAGMA " $directory " = \"\";"]

            if {[catch {executeSql $sql} result] == 0} then {
              tputs $channel [appendArgs \
                  "---- execute PRAGMA " $directory "... ok: " \
                  $result \n]
            } else {
              tputs $channel [appendArgs \
                  "---- execute PRAGMA " $directory "... error: " \
                  \n\t $result \n]
            }
          }
        }
      }

      #
      # NOTE: Finally, show the current value of the database and temporary
      #       directories.
      #
      foreach directory [list data_store_directory temp_store_directory] {
        tputs $channel [appendArgs "---- checking " $directory "... "]

        set sql [appendArgs "PRAGMA " $directory \;]

        if {[catch {executeSql $sql scalar} result] == 0} then {
          tputs $channel [appendArgs "ok: \"" $result \"\n]
        } else {
          tputs $channel [appendArgs "error: " \n\t $result \n]
        }
      }
    }

    proc runSQLiteTestPrologue {} {
      #
      # NOTE: Skip running our custom prologue if the main one has been skipped.
      #
      if {![info exists ::no(prologue.eagle)]} then {
        #
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230

1231
1232
1233
1234
1235

1236
1237
1238
1239
1240
1241
1242
1243
1244
1245

1246
1247
1248
1249
1250
1251
1252
1253
1356
1357
1358
1359
1360
1361
1362





1363





1364










1365

1366
1367
1368
1369
1370
1371
1372







-
-
-
-
-
+
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
-







        #       load without it; however, it cannot do anything useful without
        #       it).  If we are using the mixed-mode assembly and we already
        #       found it (above), this should always succeed.
        #
        checkForSQLite $::test_channel

        #
        # NOTE: Check if the sqlite3_win32_set_directory function is available.
        #
        tputs $::test_channel \
            "---- checking for function sqlite3_win32_set_directory... "

        # NOTE: Check the SQLite database and temporary directories.
        if {[catch {
                object invoke -flags +NonPublic \
                System.Data.SQLite.UnsafeNativeMethods \
                sqlite3_win32_set_directory 0 null}] == 0} then {
          #
        #
          # NOTE: Calling the sqlite3_win32_set_directory function does not
          #       cause an exception; therefore, it must be available (i.e.
          #       even though it should return a failure return code in this
          #       case).
          #
          addConstraint sqlite3_win32_set_directory

          tputs $::test_channel yes\n
        } else {
          tputs $::test_channel no\n
        checkForSQLiteDirectories $::test_channel
        }

        #
        # NOTE: Attempt to determine if the custom extension functions were
        #       compiled into the SQLite interop assembly.
        #
        checkForSQLiteDefineConstant $::test_channel \
            CHECK_STATE

Changes to Tests/stress.eagle.

16
17
18
19
20
21
22








23
24
25


26
27
28
29
30
31
32
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41







+
+
+
+
+
+
+
+


-
+
+







###############################################################################

package require System.Data.SQLite.Test
runSQLiteTestPrologue

###############################################################################

#
# NOTE: Make sure that SQLite core library is completely shutdown prior to
#       starting any of the tests in this file.
#
shutdownSQLite $test_channel

###############################################################################

runTest {test stress-1.1 {multithreaded stress testing} -setup {
  unset -nocomplain result thread index workload noWorkload srcDb db \
      fileName compiled options count
      fileName compiled options count times logFileName logListener \
      connection

  #############################################################################

  proc expectedError { error } {
    return [expr {[regexp -- {\sno such table: t1\s} $error] || \
        [regexp -- {\sdatabase is locked\s} $error]}]
  }
47
48
49
50
51
52
53





















































54
55
56


57
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
56
57
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



+
+








+
+





+
+














+
+
+
+
+
+







        \n [info level $level] ": " $error \n]

    exit Failure; # halt all testing now.
  }

  #############################################################################

  proc setupLogging { fileName } {
    if {![info exists ::logListener]} then {
      set ::logListener [object create -alias \
          System.Diagnostics.TextWriterTraceListener $fileName]
    }

    object invoke System.Diagnostics.Trace.Listeners Add $::logListener
    object invoke System.Data.SQLite.SQLiteLog Initialize

    tputs $::test_channel [appendArgs \
        "---- enabled SQLite trace logging to file \"" $fileName \"\n]
  }

  #############################################################################

  proc cleanupLogging { fileName } {
    if {[info exists ::logListener]} then {
      object invoke System.Diagnostics.Trace.Listeners Remove $::logListener
      $::logListener Close
    }

    #
    # NOTE: Copy the trace listener log file to the main test log file.
    #
    tlog "---- BEGIN TRACE LISTENER OUTPUT\n"
    tlog [readFile $fileName]
    tlog "\n---- END TRACE LISTENER OUTPUT\n"

    #
    # NOTE: Delete the trace listener log file because its contents have
    #       been copied to the main test log file.
    #
    cleanupFile $fileName

    tputs $::test_channel [appendArgs \
        "---- disabled SQLite trace logging to file \"" $fileName \"\n]
  }

  #############################################################################

  #
  # NOTE: The trace listener used with the SQLiteLog class to capture output
  #       from the core SQLite library requires its own log file because the
  #       TextWriterTraceListener class opens and locks the log file it uses
  #       as the basis of the output stream.  Before this test is complete,
  #       the entire contents of this trace log file will be copied into the
  #       main test log file and then deleted.
  #
  set logFileName [appendArgs $test_log .trace]
  setupLogging $logFileName

  #############################################################################

  set count(0) 1
  set count(1) 5
  set count(2) 300
  set count(3) 57
  set count(4) 10000000
  set noWorkload [list]

  if {[info exists argv] && [llength $argv] > 0} then {
    parse options -flags \
        {-StopOnUnknownOption +IgnoreOnUnknownOption SkipOnUnknownOption} -- \
        [list [list null MustHaveIntegerValue -1 -1 -count0 $count(0)] \
        [list null MustHaveIntegerValue -1 -1 -count1 $count(1)] \
        [list null MustHaveIntegerValue -1 -1 -count2 $count(2)] \
        [list null MustHaveIntegerValue -1 -1 -count3 $count(3)] \
        [list null MustHaveIntegerValue -1 -1 -count4 $count(4)] \
        [list null MustHaveListValue -1 -1 -noWorkload $noWorkload]] $argv

    set count(0) $options(-count0,value)
    set count(1) $options(-count1,value)
    set count(2) $options(-count2,value)
    set count(3) $options(-count3,value)
    set count(4) $options(-count4,value)
    set noWorkload $options(-noWorkload,value)
  }

  #############################################################################

  tputs $test_channel [appendArgs \
      "---- workloads will repeat " $count(0) " time(s)...\n"]

  tputs $test_channel [appendArgs \
      "---- workloads will have " $count(1) " iteration(s)...\n"]

  tputs $test_channel [appendArgs \
      "---- workloads will wait at least " $count(2) " millisecond(s)...\n"]

  tputs $test_channel [appendArgs \
      "---- workload \"small\" chunk size is " $count(3) " byte(s)...\n"]

  tputs $test_channel [appendArgs \
      "---- workload \"big\" chunk size is " $count(4) " byte(s)...\n"]

  if {[llength $noWorkload] > 0} then {
    tputs $test_channel [appendArgs \
        "---- workloads to be skipped... " $noWorkload \n]
  }

  #############################################################################

116
117
118
119
120
121
122







123
124
125
126
127
128
129
130


131
132
133

134
135
136
137
138
139






140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155


156
157
158

159
160
161
162
163
164






165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180


181
182
183

184
185
186
187
188
189






190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205


206
207
208

209
210
211
212
213
214






215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230


231
232
233
234

235
236

237
238
239
240
241
242






243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258


259
260
261
262
263


264
265
266
267
268
269






270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285


286
287

288
289

290
291
292
293
294
295






296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311


312
313
314
315




316
317
318
319
320
321






322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337


338
339
340

341
342
343
344
345
346






347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362


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


388
389

390
391
392
393
394
395






396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411

412









413
414
415
416
417
418
419
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209


210
211
212
213

214






215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234


235
236
237
238

239






240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259


260
261
262
263

264






265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284


285
286
287
288

289






290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309


310
311
312
313
314

315
316

317






318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337


338
339
340
341
342


343
344






345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
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
388
389
390


391
392
393



394
395
396
397






398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417


418
419
420
421

422






423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442


443
444
445
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
490
491
492
493
494

495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510







+
+
+
+
+
+
+






-
-
+
+


-
+
-
-
-
-
-
-
+
+
+
+
+
+














-
-
+
+


-
+
-
-
-
-
-
-
+
+
+
+
+
+














-
-
+
+


-
+
-
-
-
-
-
-
+
+
+
+
+
+














-
-
+
+


-
+
-
-
-
-
-
-
+
+
+
+
+
+














-
-
+
+



-
+

-
+
-
-
-
-
-
-
+
+
+
+
+
+














-
-
+
+



-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+














-
-
+
+

-
+

-
+
-
-
-
-
-
-
+
+
+
+
+
+














-
-
+
+

-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+














-
-
+
+


-
+
-
-
-
-
-
-
+
+
+
+
+
+














-
-
+
+


-
+
-
-
-
-
-
-
+
+
+
+
+
+














-
-
+
+

-
+
-
-
-
-
-
-
+
+
+
+
+
+
















+
-
+
+
+
+
+
+
+
+
+







  #############################################################################

  setupDb $fileName(1) "" "" "" "" "" false false true true srcDb
  setupDb $fileName(2)

  #############################################################################

  set connection [getDbConnection]

  $connection LogMessage Ok [appendArgs \
      "starting stress test using database \"" $fileName(2) "\"..."]

  #############################################################################

  set workload(1) [list [list srcFileName dstFileName table count] {
    #
    # NOTE: Workload #1, CREATE TABLE statements.
    #
    lappend ::times(1) [lindex [time {
      setupDb $dstFileName "" "" "" "" "" true false
      if {[catch {
        for {set index 2} {$index <= $count} {incr index} {
      for {set index 2} {$index <= $count} {incr index} {
        if {[catch {
          sql execute $db [appendArgs \
              "CREATE TABLE IF NOT EXISTS t" $index "(x PRIMARY KEY, y, z);"]
          showTest 1
          showTest A
        }
      } error]} then {
        if {[expectedError $error]} then {
          showTest *
        } else {
          failTest $error
        } error]} then {
          if {[expectedError $error]} then {
            showTest a
          } else {
            failTest $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
    }] 0]
  }]

  #############################################################################

  set workload(2) [list [list srcFileName dstFileName table count] {
    #
    # NOTE: Workload #2, DROP TABLE statements.
    #
    lappend ::times(2) [lindex [time {
      setupDb $dstFileName "" "" "" "" "" true false
      if {[catch {
        for {set index 2} {$index <= $count} {incr index} {
      for {set index 2} {$index <= $count} {incr index} {
        if {[catch {
          sql execute $db [appendArgs \
              "DROP TABLE IF EXISTS t" $index \;]
          showTest 2
          showTest B
        }
      } error]} then {
        if {[expectedError $error]} then {
          showTest *
        } else {
          failTest $error
        } error]} then {
          if {[expectedError $error]} then {
            showTest b
          } else {
            failTest $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
    }] 0]
  }]

  #############################################################################

  set workload(3) [list [list srcFileName dstFileName table count] {
    #
    # NOTE: Workload #3, "small" SELECT statements.
    #
    lappend ::times(3) [lindex [time {
      setupDb $dstFileName "" "" "" "" "" true false
      if {[catch {
        for {set index 1} {$index <= $count} {incr index} {
      for {set index 1} {$index <= $count} {incr index} {
        if {[catch {
          sql execute -execute reader $db [appendArgs \
              "SELECT x, y FROM " $table " WHERE z = 'small';"]
          showTest 3
          showTest C
        }
      } error]} then {
        if {[expectedError $error]} then {
          showTest *
        } else {
          failTest $error
        } error]} then {
          if {[expectedError $error]} then {
            showTest c
          } else {
            failTest $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
    }] 0]
  }]

  #############################################################################

  set workload(4) [list [list srcFileName dstFileName table count] {
    #
    # NOTE: Workload #4, "big" SELECT statements.
    #
    lappend ::times(4) [lindex [time {
      setupDb $dstFileName "" "" "" "" "" true false
      if {[catch {
        for {set index 1} {$index <= $count} {incr index} {
      for {set index 1} {$index <= $count} {incr index} {
        if {[catch {
          sql execute -execute reader $db [appendArgs \
              "SELECT x, y FROM " $table " WHERE z = 'big';"]
          showTest 4
          showTest D
        }
      } error]} then {
        if {[expectedError $error]} then {
          showTest *
        } else {
          failTest $error
        } error]} then {
          if {[expectedError $error]} then {
            showTest d
          } else {
            failTest $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
    }] 0]
  }]

  #############################################################################

  set workload(5) [list [list srcFileName dstFileName table count] {
    #
    # NOTE: Workload #5, "small" INSERT statements.
    #
    lappend ::times(5) [lindex [time {
      setupDb $dstFileName "" "" "" "" "" true false
      if {[catch {
        for {set index 1} {$index <= $count} {incr index} {
      for {set index 1} {$index <= $count} {incr index} {
        if {[catch {
          sql execute $db [appendArgs \
              "INSERT INTO " $table "(x, y, z) VALUES('" \
              [format %lX [expr {random()}]] "', '" \
              [base64 encode -- [expr {randstr(10000)}]] \
              [base64 encode -- [expr {randstr($::count(3))}]] \
              "', 'small');"]
          showTest 5
          showTest E
        }
      } error]} then {
        if {[expectedError $error]} then {
          showTest *
        } else {
          failTest $error
        } error]} then {
          if {[expectedError $error]} then {
            showTest e
          } else {
            failTest $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
    }] 0]
  }]

  #############################################################################

  set workload(6) [list [list srcFileName dstFileName table count] {
    #
    # NOTE: Workload #6, "big" INSERT statements.
    #
    lappend ::times(6) [lindex [time {
      setupDb $dstFileName "" "" "" "" "" true false
      if {[catch {
        for {set index 1} {$index <= $count} {incr index} {
      for {set index 1} {$index <= $count} {incr index} {
        if {[catch {
          sql execute $db [appendArgs \
              "INSERT INTO " $table "(x, y, z) VALUES('" \
              [format %lX [expr {random()}]] \
              "', RANDOMBLOB(10000000), 'big');"]
          showTest 6
              "', RANDOMBLOB(" $::count(4) "), 'big');"]
          showTest F
        }
      } error]} then {
        if {[expectedError $error]} then {
          showTest *
        } else {
          failTest $error
        } error]} then {
          if {[expectedError $error]} then {
            showTest f
          } else {
            failTest $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
    }] 0]
  }]

  #############################################################################

  set workload(7) [list [list srcFileName dstFileName table count] {
    #
    # NOTE: Workload #7, "small" UPDATE statements.
    #
    lappend ::times(7) [lindex [time {
      setupDb $dstFileName "" "" "" "" "" true false
      if {[catch {
        for {set index 1} {$index <= $count} {incr index} {
      for {set index 1} {$index <= $count} {incr index} {
        if {[catch {
          sql execute $db [appendArgs "UPDATE " $table \
              " SET y = '" [base64 encode -- [expr {randstr(10000)}]] \
              " SET y = '" [base64 encode -- [expr {randstr($::count(3))}]] \
              "' WHERE x LIKE '" [format %X $index] "%' AND z = 'small';"]
          showTest 7
          showTest G
        }
      } error]} then {
        if {[expectedError $error]} then {
          showTest *
        } else {
          failTest $error
        } error]} then {
          if {[expectedError $error]} then {
            showTest g
          } else {
            failTest $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
    }] 0]
  }]

  #############################################################################

  set workload(8) [list [list srcFileName dstFileName table count] {
    #
    # NOTE: Workload #8, "big" UPDATE statements.
    #
    lappend ::times(8) [lindex [time {
      setupDb $dstFileName "" "" "" "" "" true false
      if {[catch {
        for {set index 1} {$index <= $count} {incr index} {
      for {set index 1} {$index <= $count} {incr index} {
        if {[catch {
          sql execute $db [appendArgs "UPDATE " $table \
              " SET y = RANDOMBLOB(10000000) WHERE x LIKE '" \
              [format %X $index] "%' AND z = 'big';"]
          showTest 8
              " SET y = RANDOMBLOB(" $::count(4) \
              ") WHERE x LIKE '" [format %X $index] \
              "%' AND z = 'big';"]
          showTest H
        }
      } error]} then {
        if {[expectedError $error]} then {
          showTest *
        } else {
          failTest $error
        } error]} then {
          if {[expectedError $error]} then {
            showTest h
          } else {
            failTest $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
    }] 0]
  }]

  #############################################################################

  set workload(9) [list [list srcFileName dstFileName table count] {
    #
    # NOTE: Workload #9, "small" DELETE statements.
    #
    lappend ::times(9) [lindex [time {
      setupDb $dstFileName "" "" "" "" "" true false
      if {[catch {
        for {set index 1} {$index <= $count} {incr index} {
      for {set index 1} {$index <= $count} {incr index} {
        if {[catch {
          sql execute $db [appendArgs "DELETE FROM " $table \
              " WHERE x LIKE '" [format %X $index] "%' AND z = 'small';"]
          showTest 9
          showTest I
        }
      } error]} then {
        if {[expectedError $error]} then {
          showTest *
        } else {
          failTest $error
        } error]} then {
          if {[expectedError $error]} then {
            showTest i
          } else {
            failTest $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
    }] 0]
  }]

  #############################################################################

  set workload(10) [list [list srcFileName dstFileName table count] {
    #
    # NOTE: Workload #10, "big" DELETE statements.
    #
    lappend ::times(10) [lindex [time {
      setupDb $dstFileName "" "" "" "" "" true false
      if {[catch {
        for {set index 1} {$index <= $count} {incr index} {
      for {set index 1} {$index <= $count} {incr index} {
        if {[catch {
          sql execute $db [appendArgs "DELETE FROM " $table \
              " WHERE x LIKE '" [format %X $index] "%' AND z = 'big';"]
          showTest A
          showTest J
        }
      } error]} then {
        if {[expectedError $error]} then {
          showTest *
        } else {
          failTest $error
        } error]} then {
          if {[expectedError $error]} then {
            showTest j
          } else {
            failTest $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
    }] 0]
  }]

  #############################################################################

  set workload(11) [list [list srcFileName dstFileName table count] {
    #
    # NOTE: Workload #11, VACUUM statement.
    #
    lappend ::times(11) [lindex [time {
      setupDb $dstFileName "" "" "" "" "" true false
      if {[catch {
        for {set index 1} {$index <= $count} {incr index} {
      for {set index 1} {$index <= $count} {incr index} {
        if {[catch {
          sql execute $db "VACUUM;"
          showTest B
          showTest K
        }
      } error]} then {
        if {[expectedError $error]} then {
          showTest *
        } else {
          failTest $error
        } error]} then {
          if {[expectedError $error]} then {
            showTest k
          } else {
            failTest $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
    }] 0]
  }]

  #############################################################################

  set workload(12) [list [list srcFileName dstFileName table count] {
    #
    # NOTE: Workload #12, backup to in-memory database.
    #
    lappend ::times(12) [lindex [time {
      for {set index 1} {$index <= $count} {incr index} {
        if {[string is integer -strict $::compiled(12)]} then {
          set id $::compiled(12); # NOTE: Already compiled.
          if {[catch {
          object invoke _Dynamic${id}.Test${id} BackupAndGetData
            object invoke _Dynamic${id}.Test${id} BackupAndGetData
            showTest L
          } error]} then {
            if {[expectedError $error]} then {
              showTest l
            } else {
              failTest $error
            }
          }
        } else {
          set id [object invoke Interpreter.GetActive NextId]
          set code [compileCSharpWith [subst {
            using System;
            using System.Data.SQLite;
            using System.Text;

445
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
536
537
538
539
540
541
542
543

544
545
546
547
548
549
550
551
552
553
554
555
556

557
558
559
560
561
562
563
564
565
566
567
568
569
570
571

572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587







+
-
+
+
+
+
+
+
+
+
+




-














+
-
+
+
+
+
+
+
+
+
+







                  // do nothing.
                }
              }
            }
          }] true true true results errors System.Data.SQLite.dll]
          if {$code eq "Ok"} then {
            set ::compiled(12) $id; # NOTE: Compiled OK.
            if {[catch {
            object invoke _Dynamic${id}.Test${id} BackupAndGetData
              object invoke _Dynamic${id}.Test${id} BackupAndGetData
              showTest L
            } error]} then {
              if {[expectedError $error]} then {
                showTest l
              } else {
                failTest $error
              }
            }
          } else {
            error $errors
          }
        }
        showTest C
      }
    }] 0]
  }]

  #############################################################################

  set workload(13) [list [list srcFileName dstFileName table count] {
    #
    # NOTE: Workload #13, backup from an in-memory database.
    #
    lappend ::times(13) [lindex [time {
      for {set index 1} {$index <= $count} {incr index} {
        if {[string is integer -strict $::compiled(13)]} then {
          set id $::compiled(13); # NOTE: Already compiled.
          if {[catch {
          object invoke _Dynamic${id}.Test${id} BackupAndGetData
            object invoke _Dynamic${id}.Test${id} BackupAndGetData
            showTest M
          } error]} then {
            if {[expectedError $error]} then {
              showTest m
            } else {
              failTest $error
            }
          }
        } else {
          set id [object invoke Interpreter.GetActive NextId]
          set code [compileCSharpWith [subst {
            using System;
            using System.Data.SQLite;
            using System.Text;

505
506
507
508
509
510
511

512









513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531


532
533
534
535

536
537
538
539
540
541
542
543
544






545
546
547
548
549
550
551
552
553
554
555
556
557
558
559


560
561

562
563
564
565
566
567






568
569
570
571
572
573
574
613
614
615
616
617
618
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
672
673


674
675
676

677






678
679
680
681
682
683
684
685
686
687
688
689
690







+
-
+
+
+
+
+
+
+
+
+




-












-
-
+
+



-
+



-
-
-
-
-
-
+
+
+
+
+
+













-
-
+
+

-
+
-
-
-
-
-
-
+
+
+
+
+
+







                  // do nothing.
                }
              }
            }
          }] true true true results errors System.Data.SQLite.dll]
          if {$code eq "Ok"} then {
            set ::compiled(13) $id; # NOTE: Compiled OK.
            if {[catch {
            object invoke _Dynamic${id}.Test${id} BackupAndGetData
              object invoke _Dynamic${id}.Test${id} BackupAndGetData
              showTest M
            } error]} then {
              if {[expectedError $error]} then {
                showTest m
              } else {
                failTest $error
              }
            }
          } else {
            error $errors
          }
        }
        showTest D
      }
    }] 0]
  }]

  #############################################################################

  set workload(14) [list [list srcFileName dstFileName table count] {
    #
    # NOTE: Workload #14, PRAGMA integrity check statement.
    #
    lappend ::times(14) [lindex [time {
      setupDb $dstFileName "" "" "" "" "" true false
      if {[catch {
        for {set index 1} {$index <= $count} {incr index} {
      for {set index 1} {$index <= $count} {incr index} {
        if {[catch {
          set result [sql execute -execute scalar $db \
              "PRAGMA integrity_check;"]
          if {$result eq "ok"} then {
            showTest E
            showTest N
          } else {
            error [appendArgs "integrity check failed: " $result]
          }
        }
      } error]} then {
        if {[expectedError $error]} then {
          showTest *
        } else {
          failTest $error
        } error]} then {
          if {[expectedError $error]} then {
            showTest n
          } else {
            failTest $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
    }] 0]
  }]

  #############################################################################

  set workload(15) [list [list srcFileName dstFileName table count] {
    #
    # NOTE: Workload #15, force managed garbage collection
    #
    lappend ::times(15) [lindex [time {
      if {[catch {
        for {set index 1} {$index <= $count} {incr index} {
      for {set index 1} {$index <= $count} {incr index} {
        if {[catch {
          collectGarbage $::test_channel
          showTest F
          showTest O
        }
      } error]} then {
        if {[expectedError $error]} then {
          showTest *
        } else {
          failTest $error
        } error]} then {
          if {[expectedError $error]} then {
            showTest o
          } else {
            failTest $error
          }
        }
      }
    }] 0]
  }]
} -body {
  for {set index(0) 0} {$index(0) < $count(0)} {incr index(0)} {
    sql execute $db "CREATE TABLE IF NOT EXISTS t1(x PRIMARY KEY, y, z);"
634
635
636
637
638
639
640







641
642


643
644
645
646
647
648
649
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764

765
766
767
768
769
770
771
772
773







+
+
+
+
+
+
+

-
+
+







  foreach index(0) [array names workload] {
    catch {
      object removecallback [list apply $workload($index(0)) $fileName(1) \
          $fileName(2) t1 $count(1)]
    }
  }

  freeDbConnection

  cleanupLogging $logFileName

  rename cleanupLogging ""
  rename setupLogging ""

  unset -nocomplain result thread index workload noWorkload srcDb db \
      fileName compiled options count times
      fileName compiled options count times logFileName logListener \
      connection
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result {}}

###############################################################################

runSQLiteTestEpilogue
runTestEpilogue

Added Tests/thread.eagle.






















































































































































































































































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
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
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
###############################################################################
#
# thread.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require Eagle.Library
package require Eagle.Test

runTestPrologue

###############################################################################

package require System.Data.SQLite.Test
runSQLiteTestPrologue

###############################################################################

checkForSQLiteDirectories $test_channel true
set memory_used [reportSQLiteResources $test_channel true]

###############################################################################

#
# NOTE: How many test threads should be created and used for these tests?  This
#       value must be at least two.  The first test thread (at index 0) just
#       repeatedly calls the Thread.Abort() method on the other test threads
#       that appear to be alive until all test threads appear to be dead.  All
#       other threads will attempt to open a connection, execute one or more
#       queries against it, and then close it.
#
set count 10

###############################################################################

runTest {test thread-1.1 {Thread.Abort() impact on native resources} -setup {
  setupDb [set fileName thread-1.1.db]

  tputs $test_channel [appendArgs \
      "---- using a total of " $count " threads...\n"]
} -body {
  sql execute $db {
    CREATE TABLE t1(x INTEGER PRIMARY KEY, y BLOB);
    INSERT INTO t1 (y) VALUES(RANDOMBLOB(1000));
    INSERT INTO t1 (y) VALUES(RANDOMBLOB(1000));
    INSERT INTO t1 (y) VALUES(RANDOMBLOB(1000));
    INSERT INTO t1 (y) VALUES(RANDOMBLOB(1000));
    INSERT INTO t1 (y) VALUES(RANDOMBLOB(1000));
  }

  #
  # NOTE: The temporary directory must be reset here because it allocates
  #       some SQLite memory and this test requires an extremely accurate
  #       reading.
  #
  sql execute $db {
    PRAGMA temp_store_directory = "";
  }

  #
  # NOTE: Close the database now, freeing any native SQLite memory and/or
  #       resources that it may be using at this point; however, do not
  #       actually delete the database file because it is needed in the C#
  #       code for this test.
  #
  cleanupDb $fileName db true false false; unset -nocomplain db

  #
  # NOTE: Setup the variables used in the dynamically substituted C# code
  #       for the main body of this test (below).
  #
  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getDatabaseDirectory] $fileName]

  set sql { \
    SELECT x, y FROM t1 ORDER BY x; \
  }

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System;
    using System.Collections.Generic;
    using System.Data.SQLite;
    using System.Diagnostics;
    using System.Threading;
    using Eagle._Containers.Public;

    namespace _Dynamic${id}
    {
      public static class Test${id}
      {
        public static IntList RunTestThreads()
        {
          //
          // NOTE: This is the total number of data bytes seen in the second
          //       column of the query result rows seen by all test threads.
          //       This value will vary greatly based upon how many loop
          //       iterations are performed prior to each test thread being
          //       aborted.
          //
          int sum = 0;

          //
          // NOTE: This is the total number of query result rows seen by all
          //       the test threads.
          //
          int rows = 0;

          //
          // NOTE: This is the total number of exceptions caught by all the
          //       test threads.
          //
          int errors = 0;

          //
          // NOTE: This is the total number of test threads to create.
          //
          int count = ${count};

          //
          // NOTE: Create the array of thread objects.
          //
          Thread\[\] thread = new Thread\[count\];

          //
          // NOTE: Create a random number generator suitable for waiting a
          //       random number of milliseconds between each loop iteration
          //       and then selecting a random thread index.
          //
          Random random = new Random();

          //
          // NOTE: Create the event that will be used to synchronize all the
          //       created threads so that they start doing their actual test
          //       "work" at approximately the same time.  This is also used
          //       to make sure that all test threads are inside of a try
          //       block before attempting to abort them.
          //
          using (ManualResetEvent goEvent = new ManualResetEvent(false))
          {
            //
            // NOTE: Create a (reusable) delegate that will contain the code
            //       that most of the created test threads are to execute.
            //       This code will open, use, and close a single database
            //       connection.  Multiple commands and data readers will also
            //       be used.
            //
            ThreadStart threadStart1 = delegate()
            {
              try
              {
                //
                // NOTE: Wait forever for the "GO" signal so that all threads
                //       can start working at approximately the same time.
                //       This is also used to make sure that all test threads
                //       are inside of a try block before attempting to abort
                //       them.
                //
                goEvent.WaitOne();

                //
                // NOTE: Create a new connection object.  We purposely avoid
                //       putting this inside a "using" block to help test our
                //       cleanup via the garbage collector.
                //
                SQLiteConnection connection = new SQLiteConnection(
                    "Data Source=${dataSource};");

                //
                // NOTE: Open the connection.  After this point, native memory
                //       and resources have been allocated by this thread.
                //
                connection.Open();

                //
                // NOTE: Loop forever until the first thread signals us to stop
                //       via calling Thread.Abort() method on our associated
                //       thread object.
                //
                while (true)
                {
                  //
                  // NOTE: Create a dictionary to temporarily hold the values
                  //       from the data reader for this loop iteration.
                  //
                  Dictionary<long, byte\[\]> results =
                      new Dictionary<long, byte\[\]>();

                  //
                  // NOTE: Create a new command object using the connection
                  //       object for this thread.  Again, avoid putting this
                  //       inside a "using" block to help test our cleanup via
                  //       the garbage collector.
                  //
                  SQLiteCommand command = new SQLiteCommand("${sql}",
                      connection);

                  //
                  // NOTE: Execute the query and get the resulting data reader
                  //       object.  Again, avoid putting this inside a "using"
                  //       block to help test our cleanup via the garbage
                  //       collector.
                  //
                  SQLiteDataReader reader = command.ExecuteReader();

                  //
                  // NOTE: Start processing each available query result row.
                  //       This processing (or any of the above processing)
                  //       may be stopped at any time due to this test thread
                  //       being aborted.
                  //
                  while (reader.Read())
                  {
                    results.Add((long)reader\["x"\],
                        reader\["y"\] as byte\[\]);

                    Interlocked.Add(ref sum,
                        results\[(long)reader\["x"\]\].Length);

                    Interlocked.Increment(ref rows);
                  }

                  //
                  // NOTE: Close the data reader for this loop iteration as we
                  //       are done with it.
                  //
                  reader.Close();
                  reader = null;

                  //
                  // NOTE: Dispose the command for this loop iteration as we
                  //       are done with it.
                  //
                  command.Dispose();
                  command = null;
                }

                //
                // NOTE: Close the connection for this test thread as we are
                //       done with it.  Since the above loop is infinite, it
                //       should only be exited via this test thread being
                //       aborted; therefore, execution should never reach this
                //       point.
                //
                connection.Close();
                connection = null;
              }
              catch (Exception e)
              {
                Interlocked.Increment(ref errors);
                Trace.WriteLine(e);
              }
            };

            //
            // NOTE: Create a (reusable) delegate that will contain the code
            //       that half the created threads are to execute.  This code
            //       will repeatedly call the Thread.Abort() method on all the
            //       other test threads until they all appear to be dead.
            //
            ThreadStart threadStart2 = delegate()
            {
              try
              {
                //
                // NOTE: Wait forever for the "GO" signal so that all threads
                //       can start working at approximately the same time.
                //       This is also used to make sure that all test threads
                //       are inside of a try block before attempting to abort
                //       them.
                //
                goEvent.WaitOne();

                //
                // NOTE: Give the other test threads a slight head start to
                //       make sure that they are fully alive prior to trying
                //       to abort any of them.
                //
                Thread.Sleep(1000);

                //
                // NOTE: Loop forever until all test threads appear to be dead.
                //
                while (true)
                {
                  //
                  // NOTE: Wait a random number of milliseconds, up to a full
                  //       second.
                  //
                  Thread.Sleep(random.Next(0, 1000));

                  //
                  // NOTE: Select a random thread to abort.
                  //
                  int index = random.Next(1, count);

                  //
                  // NOTE: If the thread appears to be alive, try to abort
                  //       it.
                  //
                  try
                  {
                    if (thread\[index\].IsAlive)
                      thread\[index\].Abort();
                  }
                  catch (Exception e)
                  {
                    Trace.WriteLine(e);
                  }

                  //
                  // NOTE: If all the other threads are dead, presumably due
                  //       to being aborted, stop now.  This check is simpler,
                  //       and possibly more reliable, than checking if any of
                  //       the test threads are still alive via their IsAlive
                  //       property.
                  //
                  if (Interlocked.Increment(ref errors) == count)
                    break;
                  else
                    Interlocked.Decrement(ref errors);
                }
              }
              catch (Exception e)
              {
                Interlocked.Increment(ref errors);
                Trace.WriteLine(e);
              }
            };

            //
            // NOTE: Create each of the test threads with a suitable stack
            //       size.  We must specify a stack size here because the
            //       default one for the process would be the same as the
            //       parent executable (the Eagle shell), which is 16MB,
            //       too large to be useful.
            //
            for (int index = 0; index < count; index++)
            {
              //
              // NOTE: Figure out what kind of thread to create (i.e. one
              //       that uses a connection or one that calls the GC).
              //
              ThreadStart threadStart;

              if (index == 0)
                threadStart = threadStart2;
              else
                threadStart = threadStart1;

              thread\[index\] = new Thread(threadStart, 1048576);

              //
              // NOTE: Name each thread for a better debugging experience.
              //
              thread\[index\].Name = String.Format(
                  "[file rootname ${fileName}] #{0}", index);
            }

            //
            // NOTE: Start all the threads now.  They should not actually do
            //       any of the test "work" until we signal the event.
            //
            for (int index = 0; index < count; index++)
              thread\[index\].Start();

            //
            // NOTE: Send the signal that all threads should start doing
            //       their test "work" now.
            //
            goEvent.Set(); /* GO */

            //
            // NOTE: Wait forever for each thread to finish its test "work"
            //       and then die.
            //
            for (int index = 0; index < count; index++)
              thread\[index\].Join();
          }

          //
          // NOTE: Return a list of integers with total number of data bytes
          //       seen, total number of query result rows seen, and the total
          //       number of exceptions caught by all the test threads.
          //
          IntList counts = new IntList();

          counts.Add(sum);
          counts.Add(rows);
          counts.Add(errors);

          return counts;
        }

        ///////////////////////////////////////////////////////////////////////

        public static void Main()
        {
          // do nothing.
        }
      }
    }
  }] true true true results errors [list System.Data.SQLite.dll Eagle.dll]]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} RunTestThreads
      } result] : [set result ""]}] $result \
      [collectGarbage $test_channel] \
      [reportSQLiteResources $test_channel true]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result results errors code sql dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result [appendArgs "^Ok System#CodeDom#Compiler#CompilerResults#\\d+\
\\{\\} 0 \\{\\d+ \\d+ " $count "\\} \\{\\} " $memory_used \$]}

###############################################################################

unset -nocomplain count

###############################################################################

unset -nocomplain memory_used

###############################################################################

runSQLiteTestEpilogue
runTestEpilogue

Changes to Tests/tkt-2ce0870fad.eagle.

20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
20
21
22
23
24
25
26



27

28
29
30
31
32
33
34







-
-
-
+
-








###############################################################################

#
# NOTE: Make sure that SQLite core library is completely shutdown prior to
#       starting any of the tests in this file.
#
if {[haveConstraint SQLite]} then {
  object invoke -flags +NonPublic System.Data.SQLite.UnsafeNativeMethods \
      sqlite3_shutdown
shutdownSQLite $test_channel
}

###############################################################################

for {set i 1} {$i < 3} {incr i} {
  runTest {test [appendArgs tkt-2ce0870fad-1. $i] {logging setup} -setup \
      [getAppDomainPreamble {
    set i {$i}

Changes to Tests/tkt-996d13cd87.eagle.

122
123
124
125
126
127
128
129
130
131




132
133
134
135
136
137
138
139
140
141
142
143
144
145
146



147
148
149
150
151
152
153
122
123
124
125
126
127
128



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144



145
146
147
148
149
150
151
152
153
154







-
-
-
+
+
+
+












-
-
-
+
+
+







            //       created threads so that they start doing their actual test
            //       "work" at approximately the same time.
            //
            using (ManualResetEvent goEvent = new ManualResetEvent(false))
            {
              //
              // NOTE: Create a (reusable) delegate that will contain the code
              //       that half the created threads are to execute.  This code
              //       will repeatedly create, open, and close a single database
              //       connection with (or without) pooling enabled.
              //       that most of the created test threads are going to
              //       execute.  The code in this delegate will create, open,
              //       use, and close a single database connection with (or
              //       without) pooling enabled.
              //
              ThreadStart threadStart1 = delegate()
              {
                try
                {
                  //
                  // NOTE: Wait forever for the "GO" signal so that all threads
                  //       can start working at approximately the same time.
                  //
                  goEvent.WaitOne();

                  //
                  // NOTE: Repeatedly try to create, open, and close a pooled
                  //       database connection and then wait a random number of
                  //       milliseconds before doing it again.
                  // NOTE: Try to create, open, and close a database connection
                  //       and then wait a random number of milliseconds before
                  //       doing it again.
                  //
                  Thread.Sleep(random.Next(0, 500));

                  SQLiteConnection connection = new SQLiteConnection(
                      "Data Source=${dataSource};Pooling=${pooling};");

                  connection.Open();
166
167
168
169
170
171
172
173
174



175
176
177
178
179
180
181
167
168
169
170
171
172
173


174
175
176
177
178
179
180
181
182
183







-
-
+
+
+







                  Interlocked.Increment(ref errors);
                  Trace.WriteLine(e);
                }
              };

              //
              // NOTE: Create a (reusable) delegate that will contain the code
              //       that half the created threads are to execute.  This code
              //       will repeatedly force a full garbage collection.
              //       that the garbage collection thread is to execute.  The
              //       code in this delegate will attempt to force a full round
              //       of garbage collection several times.
              //
              ThreadStart threadStart2 = delegate()
              {
                try
                {
                  //
                  // NOTE: Wait forever for the "GO" signal so that all threads

Changes to Tests/tkt-b4a7ddc83f.eagle.

20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37
20
21
22
23
24
25
26



27

28
29
30
31
32
33
34







-
-
-
+
-








###############################################################################

#
# NOTE: Make sure that SQLite core library is completely shutdown prior to
#       starting any of the tests in this file.
#
if {[haveConstraint SQLite]} then {
  object invoke -flags +NonPublic System.Data.SQLite.UnsafeNativeMethods \
      sqlite3_shutdown
shutdownSQLite $test_channel
}

###############################################################################

for {set i 1} {$i < 3} {incr i} {
  runTest {test [appendArgs tkt-b4a7ddc83f-1. $i] {logging shutdown} -setup \
      [getAppDomainPreamble {
    set appDomainId(1) {[object invoke AppDomain.CurrentDomain Id]}

Changes to readme.htm.

192
193
194
195
196
197
198
199


200
201
202
203
204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
192
193
194
195
196
197
198

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222







-
+
+














+







<ul>
    <li>Updated to <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.7.15</a>.</li>
    <li>Add Visual Studio 2012 support to all the applicable solution/project files, their associated supporting files, and the test suite.</li>
    <li>Add Visual Studio 2012 support to the redesigned designer support installer.</li>
    <li>Allow opened connections to skip adding the extension functions included in the interop assembly via the new NoExtensionFunctions connection flag.</li>
    <li>Support loading of SQLite extensions via the new EnableExtensions and LoadExtension methods of the SQLiteConnection class. Pursuant to [17045010df].</li>
    <li>Add notifications before and after any connection is opened and closed, as well as other related notifications, via the new static Changed event.</li>
    <li>Add an overload of the SQLiteLog.LogMessage method that takes a single string argument.</li>
    <li>Add an overload of the SQLiteLog.LogMessage method that takes a single string parameter.</li>
    <li>Add an overload of the SQLiteConnection.LogMessage method that takes a SQLiteErrorCode parameter.</li>
    <li>All applicable calls into the SQLite core library now return a SQLiteErrorCode instead of an integer error code.</li>
    <li>Make sure the error code of the SQLiteException class gets serialized.</li>
    <li>Make the test project for the .NET Compact Framework more flexible.</li>
    <li>When available, the new sqlite3_errstr function from the core library is used to get the error message for a specific return code.</li>
    <li>The SetMemoryStatus, Shutdown, ResultCode, ExtendedResultCode, and SetAvRetry methods of the SQLiteConnection class now return a SQLiteErrorCode instead of an integer error code.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>The public constructor for the SQLiteException now takes a SQLiteErrorCode instead of an integer error code.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>The ErrorCode property of the SQLiteException is now an Int32, to allow the property inherited from the base class to be properly overridden.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>The ErrorCode field of the LogEventArgs is now an object instead of an integer.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>The names and messages associated with the SQLiteErrorCode enumeration values have been normalized to match those in the SQLite core library.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Implement more robust locking semantics for the CriticalHandle derived classes when compiled for the .NET Compact Framework.</li>
    <li>Cache column indexes are they are looked up when using the SQLiteDataReader to improve performance.</li>
    <li>Prevent the SQLiteConnection.Close method from throwing non-fatal exceptions during its disposal.</li>
    <li>Rename the interop assembly functions sqlite3_cursor_rowid, sqlite3_context_collcompare, sqlite3_context_collseq, sqlite3_cursor_rowid, and sqlite3_table_cursor to include an &quot;_interop&quot; suffix.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Prevent the LastInsertRowId, MemoryUsed, and MemoryHighwater connection properties from throwing NotSupportedException when running on the .NET Compact Framework. Fix for [dd45aba387].</li>
    <li>Add protection against ThreadAbortException asynchronously interrupting native resource initialization and finalization.</li>
    <li>Add test automation for the Windows CE binaries.</li>
</ul>
<p>
    <b>1.0.82.0 - September 3, 2012</b>
</p>
<ul>
    <li>Updated to <a href="http://www.sqlite.org/releaselog/3_7_14.html">SQLite 3.7.14</a>.</li>

Changes to test/TestCases.cs.

1653
1654
1655
1656
1657
1658
1659
1660

1661
1662
1663
1664
1665
1666
1667
1653
1654
1655
1656
1657
1658
1659

1660
1661
1662
1663
1664
1665
1666
1667







-
+








            sqlite_fact.Log += logHandler;

            cnn.Open();

            logevents = 0;

            cnn.LogMessage(1, "test log event");
            cnn.LogMessage(SQLiteErrorCode.Error, "test log event");

            if (logevents != 1)
                throw new Exception(String.Format(
                    "Log event count {0} incorrect.", logevents));

            cnn.Close();

Changes to www/news.wiki.

8
9
10
11
12
13
14
15


16
17
18
19
20
21
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38







-
+
+














+







<ul>
    <li>Updated to [http://www.sqlite.org/src/info/trunk|SQLite 3.7.15].</li>
    <li>Add Visual Studio 2012 support to all the applicable solution/project files, their associated supporting files, and the test suite.</li>
    <li>Add Visual Studio 2012 support to the redesigned designer support installer.</li>
    <li>Allow opened connections to skip adding the extension functions included in the interop assembly via the new NoExtensionFunctions connection flag.</li>
    <li>Support loading of SQLite extensions via the new EnableExtensions and LoadExtension methods of the SQLiteConnection class. Pursuant to [17045010df].</li>
    <li>Add notifications before and after any connection is opened and closed, as well as other related notifications, via the new static Changed event.</li>
    <li>Add an overload of the SQLiteLog.LogMessage method that takes a single string argument.</li>
    <li>Add an overload of the SQLiteLog.LogMessage method that takes a single string parameter.</li>
    <li>Add an overload of the SQLiteConnection.LogMessage method that takes a SQLiteErrorCode parameter.</li>
    <li>All applicable calls into the SQLite core library now return a SQLiteErrorCode instead of an integer error code.</li>
    <li>Make sure the error code of the SQLiteException class gets serialized.</li>
    <li>Make the test project for the .NET Compact Framework more flexible.</li>
    <li>When available, the new sqlite3_errstr function from the core library is used to get the error message for a specific return code.</li>
    <li>The SetMemoryStatus, Shutdown, ResultCode, ExtendedResultCode, and SetAvRetry methods of the SQLiteConnection class now return a SQLiteErrorCode instead of an integer error code.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>The public constructor for the SQLiteException now takes a SQLiteErrorCode instead of an integer error code.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>The ErrorCode property of the SQLiteException is now an Int32, to allow the property inherited from the base class to be properly overridden.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>The ErrorCode field of the LogEventArgs is now an object instead of an integer.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>The names and messages associated with the SQLiteErrorCode enumeration values have been normalized to match those in the SQLite core library.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Implement more robust locking semantics for the CriticalHandle derived classes when compiled for the .NET Compact Framework.</li>
    <li>Cache column indexes are they are looked up when using the SQLiteDataReader to improve performance.</li>
    <li>Prevent the SQLiteConnection.Close method from throwing non-fatal exceptions during its disposal.</li>
    <li>Rename the interop assembly functions sqlite3_cursor_rowid, sqlite3_context_collcompare, sqlite3_context_collseq, sqlite3_cursor_rowid, and sqlite3_table_cursor to include an &quot;_interop&quot; suffix.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Prevent the LastInsertRowId, MemoryUsed, and MemoryHighwater connection properties from throwing NotSupportedException when running on the .NET Compact Framework. Fix for [dd45aba387].</li>
    <li>Add protection against ThreadAbortException asynchronously interrupting native resource initialization and finalization.</li>
    <li>Add test automation for the Windows CE binaries.</li>
</ul>
<p>
    <b>1.0.82.0 - September 3, 2012</b>
</p>
<ul>
    <li>Updated to [http://www.sqlite.org/releaselog/3_7_14.html|SQLite 3.7.14].</li>