System.Data.SQLite
Check-in [1462b42fc2]
Not logged in

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

Overview
Comment:Update core SQLite library to the latest trunk. Merge support for the sqlite3_close_v2 API. Add missing test contraints for the dynamic SQLite core library detection, the USE_INTEROP_DLL compile-time define, and the System.Data.SQLite.dll / System.Data.SQLite.Linq.dll file detection. Fix several #if statements to include USE_INTEROP_DLL in addition to INTEROP_EXTENSION_FUNCTIONS.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1462b42fc2ebbcb64c96d5e077dc2c4f5352aa7d
User & Date: mistachkin 2012-06-22 20:12:02
Context
2012-06-22
20:13
Update sqlite3_close_v2 availability version number check. check-in: d8bf1bb3b9 user: mistachkin tags: trunk
20:12
Update core SQLite library to the latest trunk. Merge support for the sqlite3_close_v2 API. Add missing test contraints for the dynamic SQLite core library detection, the USE_INTEROP_DLL compile-time define, and the System.Data.SQLite.dll / System.Data.SQLite.Linq.dll file detection. Fix several #if statements to include USE_INTEROP_DLL in addition to INTEROP_EXTENSION_FUNCTIONS. check-in: 1462b42fc2 user: mistachkin tags: trunk
2012-06-20
11:13
Improve documentation for the connection string properties and the DateTime formats. check-in: c09a59295c user: mistachkin tags: trunk
2012-06-18
11:10
Merge testing and doc updates from trunk. Closed-Leaf check-in: a2f8c25b8a user: mistachkin tags: deferred-close
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

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

     5      5    *
     6      6    * Written by Joe Mistachkin.
     7      7    * Released to the public domain, use at your own risk!
     8      8    *
     9      9   -->
    10     10   <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
    11     11     <PropertyGroup Label="UserMacros">
    12         -    <SQLITE_MANIFEST_VERSION>3.7.13</SQLITE_MANIFEST_VERSION>
    13         -    <SQLITE_RC_VERSION>3,7,13</SQLITE_RC_VERSION>
           12  +    <SQLITE_MANIFEST_VERSION>3.7.14</SQLITE_MANIFEST_VERSION>
           13  +    <SQLITE_RC_VERSION>3,7,14</SQLITE_RC_VERSION>
    14     14       <SQLITE_COMMON_DEFINES>SQLITE_THREADSAFE=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>
    15     15       <SQLITE_EXTRA_DEFINES>SQLITE_HAS_CODEC=1</SQLITE_EXTRA_DEFINES>
    16     16       <SQLITE_WINCE_DEFINES>SQLITE_OMIT_WAL=1</SQLITE_WINCE_DEFINES>
    17     17       <SQLITE_DEBUG_DEFINES>SQLITE_DEBUG=1;SQLITE_MEMDEBUG=1</SQLITE_DEBUG_DEFINES>
    18     18       <SQLITE_RELEASE_DEFINES>SQLITE_WIN32_MALLOC=1</SQLITE_RELEASE_DEFINES>
    19     19       <SQLITE_DISABLE_WARNINGS>4018;4055;4057;4090;4100;4127;4132;4146;4152;4210;4232;4244;4245;4389;4701;4706;4996</SQLITE_DISABLE_WARNINGS>
    20     20       <SQLITE_DISABLE_X64_WARNINGS>4232;4267;4306</SQLITE_DISABLE_X64_WARNINGS>

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

    10     10   <VisualStudioPropertySheet
    11     11   	ProjectType="Visual C++"
    12     12   	Version="8.00"
    13     13   	Name="sqlite3"
    14     14   	>
    15     15   	<UserMacro
    16     16   		Name="SQLITE_MANIFEST_VERSION"
    17         -		Value="3.7.13"
           17  +		Value="3.7.14"
    18     18   		PerformEnvironmentSet="true"
    19     19   	/>
    20     20   	<UserMacro
    21     21   		Name="SQLITE_RC_VERSION"
    22         -		Value="3,7,13"
           22  +		Value="3,7,14"
    23     23   		PerformEnvironmentSet="true"
    24     24   	/>
    25     25   	<UserMacro
    26     26   		Name="SQLITE_COMMON_DEFINES"
    27     27   		Value="SQLITE_THREADSAFE=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"
    28     28   		PerformEnvironmentSet="true"
    29     29   	/>

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

     1      1   /******************************************************************************
     2      2   ** This file is an amalgamation of many separate C source files from SQLite
     3         -** version 3.7.13.  By combining all the individual C code files into this 
            3  +** version 3.7.14.  By combining all the individual C code files into this 
     4      4   ** single large file, the entire code can be compiled as a single translation
     5      5   ** unit.  This allows many compilers to do optimizations that would not be
     6      6   ** possible if the files were compiled separately.  Performance improvements
     7      7   ** of 5% or more are commonly seen when SQLite is compiled as a single
     8      8   ** translation unit.
     9      9   **
    10     10   ** This file is all you need to compile SQLite.  To use SQLite in other
................................................................................
   385    385   
   386    386   /*
   387    387   ** Exactly one of the following macros must be defined in order to
   388    388   ** specify which memory allocation subsystem to use.
   389    389   **
   390    390   **     SQLITE_SYSTEM_MALLOC          // Use normal system malloc()
   391    391   **     SQLITE_WIN32_MALLOC           // Use Win32 native heap API
          392  +**     SQLITE_ZERO_MALLOC            // Use a stub allocator that always fails
   392    393   **     SQLITE_MEMDEBUG               // Debugging version of system malloc()
   393    394   **
   394    395   ** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the
   395    396   ** assert() macro is enabled, each call into the Win32 native heap subsystem
   396    397   ** will cause HeapValidate to be called.  If heap validation should fail, an
   397    398   ** assertion will be triggered.
   398    399   **
   399    400   ** (Historical note:  There used to be several other options, but we've
   400    401   ** pared it down to just these three.)
   401    402   **
   402    403   ** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
   403    404   ** the default.
   404    405   */
   405         -#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)>1
   406         -# error "At most one of the following compile-time configuration options\
   407         - is allows: SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG"
          406  +#if defined(SQLITE_SYSTEM_MALLOC) \
          407  +  + defined(SQLITE_WIN32_MALLOC) \
          408  +  + defined(SQLITE_ZERO_MALLOC) \
          409  +  + defined(SQLITE_MEMDEBUG)>1
          410  +# error "Two or more of the following compile-time configuration options\
          411  + are defined but at most one is allowed:\
          412  + SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG,\
          413  + SQLITE_ZERO_MALLOC"
   408    414   #endif
   409         -#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)==0
          415  +#if defined(SQLITE_SYSTEM_MALLOC) \
          416  +  + defined(SQLITE_WIN32_MALLOC) \
          417  +  + defined(SQLITE_ZERO_MALLOC) \
          418  +  + defined(SQLITE_MEMDEBUG)==0
   410    419   # define SQLITE_SYSTEM_MALLOC 1
   411    420   #endif
   412    421   
   413    422   /*
   414    423   ** If SQLITE_MALLOC_SOFT_LIMIT is not zero, then try to keep the
   415    424   ** sizes of memory allocations below this value where possible.
   416    425   */
................................................................................
   660    669   ** string contains the date and time of the check-in (UTC) and an SHA1
   661    670   ** hash of the entire source tree.
   662    671   **
   663    672   ** See also: [sqlite3_libversion()],
   664    673   ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
   665    674   ** [sqlite_version()] and [sqlite_source_id()].
   666    675   */
   667         -#define SQLITE_VERSION        "3.7.13"
   668         -#define SQLITE_VERSION_NUMBER 3007013
   669         -#define SQLITE_SOURCE_ID      "2012-06-08 14:01:53 025227be5495f950c466dfabac140cba69e498be"
          676  +#define SQLITE_VERSION        "3.7.14"
          677  +#define SQLITE_VERSION_NUMBER 3007014
          678  +#define SQLITE_SOURCE_ID      "2012-06-21 17:21:52 d5e6880279210ca63e2d5e7f6d009f30566f1242"
   670    679   
   671    680   /*
   672    681   ** CAPI3REF: Run-Time Library Version Numbers
   673    682   ** KEYWORDS: sqlite3_version, sqlite3_sourceid
   674    683   **
   675    684   ** These interfaces provide the same information as the [SQLITE_VERSION],
   676    685   ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
................................................................................
   772    781   ** CAPI3REF: Database Connection Handle
   773    782   ** KEYWORDS: {database connection} {database connections}
   774    783   **
   775    784   ** Each open SQLite database is represented by a pointer to an instance of
   776    785   ** the opaque structure named "sqlite3".  It is useful to think of an sqlite3
   777    786   ** pointer as an object.  The [sqlite3_open()], [sqlite3_open16()], and
   778    787   ** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
   779         -** is its destructor.  There are many other interfaces (such as
          788  +** and [sqlite3_close_v2()] are its destructors.  There are many other
          789  +** interfaces (such as
   780    790   ** [sqlite3_prepare_v2()], [sqlite3_create_function()], and
   781    791   ** [sqlite3_busy_timeout()] to name but three) that are methods on an
   782    792   ** sqlite3 object.
   783    793   */
   784    794   typedef struct sqlite3 sqlite3;
   785    795   
   786    796   /*
................................................................................
   819    829   #ifdef SQLITE_OMIT_FLOATING_POINT
   820    830   # define double sqlite3_int64
   821    831   #endif
   822    832   
   823    833   /*
   824    834   ** CAPI3REF: Closing A Database Connection
   825    835   **
   826         -** ^The sqlite3_close() routine is the destructor for the [sqlite3] object.
   827         -** ^Calls to sqlite3_close() return SQLITE_OK if the [sqlite3] object is
   828         -** successfully destroyed and all associated resources are deallocated.
          836  +** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
          837  +** for the [sqlite3] object.
          838  +** ^Calls to sqlite3_close() and sqlite3_close_v2() return SQLITE_OK if
          839  +** the [sqlite3] object is successfully destroyed and all associated
          840  +** resources are deallocated.
   829    841   **
   830         -** Applications must [sqlite3_finalize | finalize] all [prepared statements]
   831         -** and [sqlite3_blob_close | close] all [BLOB handles] associated with
   832         -** the [sqlite3] object prior to attempting to close the object.  ^If
          842  +** ^If the database connection is associated with unfinalized prepared
          843  +** statements or unfinished sqlite3_backup objects then sqlite3_close()
          844  +** will leave the database connection open and return [SQLITE_BUSY].
          845  +** ^If sqlite3_close_v2() is called with unfinalized prepared statements
          846  +** and unfinished sqlite3_backups, then the database connection becomes
          847  +** an unusable "zombie" which will automatically be deallocated when the
          848  +** last prepared statement is finalized or the last sqlite3_backup is
          849  +** finished.  The sqlite3_close_v2() interface is intended for use with
          850  +** host languages that are garbage collected, and where the order in which
          851  +** destructors are called is arbitrary.
          852  +**
          853  +** Applications should [sqlite3_finalize | finalize] all [prepared statements],
          854  +** [sqlite3_blob_close | close] all [BLOB handles], and 
          855  +** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
          856  +** with the [sqlite3] object prior to attempting to close the object.  ^If
   833    857   ** sqlite3_close() is called on a [database connection] that still has
   834         -** outstanding [prepared statements] or [BLOB handles], then it returns
   835         -** SQLITE_BUSY.
          858  +** outstanding [prepared statements], [BLOB handles], and/or
          859  +** [sqlite3_backup] objects then it returns SQLITE_OK but the deallocation
          860  +** of resources is deferred until all [prepared statements], [BLOB handles],
          861  +** and [sqlite3_backup] objects are also destroyed.
   836    862   **
   837         -** ^If [sqlite3_close()] is invoked while a transaction is open,
          863  +** ^If an [sqlite3] object is destroyed while a transaction is open,
   838    864   ** the transaction is automatically rolled back.
   839    865   **
   840         -** The C parameter to [sqlite3_close(C)] must be either a NULL
          866  +** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
          867  +** must be either a NULL
   841    868   ** pointer or an [sqlite3] object pointer obtained
   842    869   ** from [sqlite3_open()], [sqlite3_open16()], or
   843    870   ** [sqlite3_open_v2()], and not previously closed.
   844         -** ^Calling sqlite3_close() with a NULL pointer argument is a 
   845         -** harmless no-op.
          871  +** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
          872  +** argument is a harmless no-op.
   846    873   */
   847         -SQLITE_API int sqlite3_close(sqlite3 *);
          874  +SQLITE_API int sqlite3_close(sqlite3*);
          875  +SQLITE_API int sqlite3_close_v2(sqlite3*);
   848    876   
   849    877   /*
   850    878   ** The type for a callback function.
   851    879   ** This is legacy and deprecated.  It is included for historical
   852    880   ** compatibility and is not documented.
   853    881   */
   854    882   typedef int (*sqlite3_callback)(void*,int,char**, char**);
................................................................................
  6047   6075   **
  6048   6076   ** The SQLite source code contains multiple implementations
  6049   6077   ** of these mutex routines.  An appropriate implementation
  6050   6078   ** is selected automatically at compile-time.  ^(The following
  6051   6079   ** implementations are available in the SQLite core:
  6052   6080   **
  6053   6081   ** <ul>
  6054         -** <li>   SQLITE_MUTEX_OS2
  6055   6082   ** <li>   SQLITE_MUTEX_PTHREADS
  6056   6083   ** <li>   SQLITE_MUTEX_W32
  6057   6084   ** <li>   SQLITE_MUTEX_NOOP
  6058   6085   ** </ul>)^
  6059   6086   **
  6060   6087   ** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
  6061   6088   ** that does no real locking and is appropriate for use in
  6062         -** a single-threaded application.  ^The SQLITE_MUTEX_OS2,
  6063         -** SQLITE_MUTEX_PTHREADS, and SQLITE_MUTEX_W32 implementations
  6064         -** are appropriate for use on OS/2, Unix, and Windows.
         6089  +** a single-threaded application.  ^The SQLITE_MUTEX_PTHREADS and
         6090  +** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
         6091  +** and Windows.
  6065   6092   **
  6066   6093   ** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
  6067   6094   ** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
  6068   6095   ** implementation is included with the library. In this case the
  6069   6096   ** application must supply a custom mutex implementation using the
  6070   6097   ** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
  6071   6098   ** before calling sqlite3_initialize() or any other public sqlite3_
................................................................................
  9286   9313   */
  9287   9314   #ifndef _SQLITE_OS_H_
  9288   9315   #define _SQLITE_OS_H_
  9289   9316   
  9290   9317   /*
  9291   9318   ** Figure out if we are dealing with Unix, Windows, or some other
  9292   9319   ** operating system.  After the following block of preprocess macros,
  9293         -** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_OS2, and SQLITE_OS_OTHER 
         9320  +** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, and SQLITE_OS_OTHER 
  9294   9321   ** will defined to either 1 or 0.  One of the four will be 1.  The other 
  9295   9322   ** three will be 0.
  9296   9323   */
  9297   9324   #if defined(SQLITE_OS_OTHER)
  9298   9325   # if SQLITE_OS_OTHER==1
  9299   9326   #   undef SQLITE_OS_UNIX
  9300   9327   #   define SQLITE_OS_UNIX 0
  9301   9328   #   undef SQLITE_OS_WIN
  9302   9329   #   define SQLITE_OS_WIN 0
  9303         -#   undef SQLITE_OS_OS2
  9304         -#   define SQLITE_OS_OS2 0
  9305   9330   # else
  9306   9331   #   undef SQLITE_OS_OTHER
  9307   9332   # endif
  9308   9333   #endif
  9309   9334   #if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER)
  9310   9335   # define SQLITE_OS_OTHER 0
  9311   9336   # ifndef SQLITE_OS_WIN
  9312   9337   #   if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
  9313   9338   #     define SQLITE_OS_WIN 1
  9314   9339   #     define SQLITE_OS_UNIX 0
  9315         -#     define SQLITE_OS_OS2 0
  9316         -#   elif defined(__EMX__) || defined(_OS2) || defined(OS2) || defined(_OS2_) || defined(__OS2__)
  9317         -#     define SQLITE_OS_WIN 0
  9318         -#     define SQLITE_OS_UNIX 0
  9319         -#     define SQLITE_OS_OS2 1
  9320   9340   #   else
  9321   9341   #     define SQLITE_OS_WIN 0
  9322   9342   #     define SQLITE_OS_UNIX 1
  9323         -#     define SQLITE_OS_OS2 0
  9324   9343   #  endif
  9325   9344   # else
  9326   9345   #  define SQLITE_OS_UNIX 0
  9327         -#  define SQLITE_OS_OS2 0
  9328   9346   # endif
  9329   9347   #else
  9330   9348   # ifndef SQLITE_OS_WIN
  9331   9349   #  define SQLITE_OS_WIN 0
  9332   9350   # endif
  9333   9351   #endif
  9334   9352   
  9335   9353   #if SQLITE_OS_WIN
  9336   9354   # include <windows.h>
  9337   9355   #endif
  9338   9356   
  9339         -#if SQLITE_OS_OS2
  9340         -# if (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 3) && defined(OS2_HIGH_MEMORY)
  9341         -#  include <os2safe.h> /* has to be included before os2.h for linking to work */
  9342         -# endif
  9343         -# define INCL_DOSDATETIME
  9344         -# define INCL_DOSFILEMGR
  9345         -# define INCL_DOSERRORS
  9346         -# define INCL_DOSMISC
  9347         -# define INCL_DOSPROCESS
  9348         -# define INCL_DOSMODULEMGR
  9349         -# define INCL_DOSSEMAPHORES
  9350         -# include <os2.h>
  9351         -# include <uconv.h>
  9352         -#endif
  9353         -
  9354   9357   /*
  9355   9358   ** Determine if we are dealing with Windows NT.
  9356   9359   **
  9357   9360   ** We ought to be able to determine if we are compiling for win98 or winNT
  9358   9361   ** using the _WIN32_WINNT macro as follows:
  9359   9362   **
  9360   9363   ** #if defined(_WIN32_WINNT)
................................................................................
  9616   9619   **                             mutual exclusion is provided.  But this
  9617   9620   **                             implementation can be overridden at
  9618   9621   **                             start-time.
  9619   9622   **
  9620   9623   **   SQLITE_MUTEX_PTHREADS     For multi-threaded applications on Unix.
  9621   9624   **
  9622   9625   **   SQLITE_MUTEX_W32          For multi-threaded applications on Win32.
  9623         -**
  9624         -**   SQLITE_MUTEX_OS2          For multi-threaded applications on OS/2.
  9625   9626   */
  9626   9627   #if !SQLITE_THREADSAFE
  9627   9628   # define SQLITE_MUTEX_OMIT
  9628   9629   #endif
  9629   9630   #if SQLITE_THREADSAFE && !defined(SQLITE_MUTEX_NOOP)
  9630   9631   #  if SQLITE_OS_UNIX
  9631   9632   #    define SQLITE_MUTEX_PTHREADS
  9632   9633   #  elif SQLITE_OS_WIN
  9633   9634   #    define SQLITE_MUTEX_W32
  9634         -#  elif SQLITE_OS_OS2
  9635         -#    define SQLITE_MUTEX_OS2
  9636   9635   #  else
  9637   9636   #    define SQLITE_MUTEX_NOOP
  9638   9637   #  endif
  9639   9638   #endif
  9640   9639   
  9641   9640   #ifdef SQLITE_MUTEX_OMIT
  9642   9641   /*
................................................................................
  9949   9948   ** than being distinct from one another.
  9950   9949   */
  9951   9950   #define SQLITE_MAGIC_OPEN     0xa029a697  /* Database is open */
  9952   9951   #define SQLITE_MAGIC_CLOSED   0x9f3c2d33  /* Database is closed */
  9953   9952   #define SQLITE_MAGIC_SICK     0x4b771290  /* Error and awaiting close */
  9954   9953   #define SQLITE_MAGIC_BUSY     0xf03b7906  /* Database currently in use */
  9955   9954   #define SQLITE_MAGIC_ERROR    0xb5357930  /* An SQLITE_MISUSE error occurred */
         9955  +#define SQLITE_MAGIC_ZOMBIE   0x64cffc7f  /* Close with last statement close */
  9956   9956   
  9957   9957   /*
  9958   9958   ** Each SQL function is defined by an instance of the following
  9959   9959   ** structure.  A pointer to this structure is stored in the sqlite.aFunc
  9960   9960   ** hash table.  When multiple functions have the same name, the hash table
  9961   9961   ** points to a linked list of these structures.
  9962   9962   */
................................................................................
 11810  11810   SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int);
 11811  11811   SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
 11812  11812   SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int);
 11813  11813   SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*);
 11814  11814   SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*);
 11815  11815   SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
 11816  11816   SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
        11817  +SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
 11817  11818   SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
 11818  11819   SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
 11819  11820   SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*);
 11820  11821   SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
 11821  11822   SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
 11822  11823   SQLITE_PRIVATE void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
 11823  11824   SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
................................................................................
 17715  17716   SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
 17716  17717     return sqlite3NoopMutex();
 17717  17718   }
 17718  17719   #endif /* defined(SQLITE_MUTEX_NOOP) */
 17719  17720   #endif /* !defined(SQLITE_MUTEX_OMIT) */
 17720  17721   
 17721  17722   /************** End of mutex_noop.c ******************************************/
 17722         -/************** Begin file mutex_os2.c ***************************************/
 17723         -/*
 17724         -** 2007 August 28
 17725         -**
 17726         -** The author disclaims copyright to this source code.  In place of
 17727         -** a legal notice, here is a blessing:
 17728         -**
 17729         -**    May you do good and not evil.
 17730         -**    May you find forgiveness for yourself and forgive others.
 17731         -**    May you share freely, never taking more than you give.
 17732         -**
 17733         -*************************************************************************
 17734         -** This file contains the C functions that implement mutexes for OS/2
 17735         -*/
 17736         -
 17737         -/*
 17738         -** The code in this file is only used if SQLITE_MUTEX_OS2 is defined.
 17739         -** See the mutex.h file for details.
 17740         -*/
 17741         -#ifdef SQLITE_MUTEX_OS2
 17742         -
 17743         -/********************** OS/2 Mutex Implementation **********************
 17744         -**
 17745         -** This implementation of mutexes is built using the OS/2 API.
 17746         -*/
 17747         -
 17748         -/*
 17749         -** The mutex object
 17750         -** Each recursive mutex is an instance of the following structure.
 17751         -*/
 17752         -struct sqlite3_mutex {
 17753         -  HMTX mutex;       /* Mutex controlling the lock */
 17754         -  int  id;          /* Mutex type */
 17755         -#ifdef SQLITE_DEBUG
 17756         - int   trace;       /* True to trace changes */
 17757         -#endif
 17758         -};
 17759         -
 17760         -#ifdef SQLITE_DEBUG
 17761         -#define SQLITE3_MUTEX_INITIALIZER { 0, 0, 0 }
 17762         -#else
 17763         -#define SQLITE3_MUTEX_INITIALIZER { 0, 0 }
 17764         -#endif
 17765         -
 17766         -/*
 17767         -** Initialize and deinitialize the mutex subsystem.
 17768         -*/
 17769         -static int os2MutexInit(void){ return SQLITE_OK; }
 17770         -static int os2MutexEnd(void){ return SQLITE_OK; }
 17771         -
 17772         -/*
 17773         -** The sqlite3_mutex_alloc() routine allocates a new
 17774         -** mutex and returns a pointer to it.  If it returns NULL
 17775         -** that means that a mutex could not be allocated. 
 17776         -** SQLite will unwind its stack and return an error.  The argument
 17777         -** to sqlite3_mutex_alloc() is one of these integer constants:
 17778         -**
 17779         -** <ul>
 17780         -** <li>  SQLITE_MUTEX_FAST
 17781         -** <li>  SQLITE_MUTEX_RECURSIVE
 17782         -** <li>  SQLITE_MUTEX_STATIC_MASTER
 17783         -** <li>  SQLITE_MUTEX_STATIC_MEM
 17784         -** <li>  SQLITE_MUTEX_STATIC_MEM2
 17785         -** <li>  SQLITE_MUTEX_STATIC_PRNG
 17786         -** <li>  SQLITE_MUTEX_STATIC_LRU
 17787         -** <li>  SQLITE_MUTEX_STATIC_LRU2
 17788         -** </ul>
 17789         -**
 17790         -** The first two constants cause sqlite3_mutex_alloc() to create
 17791         -** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
 17792         -** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
 17793         -** The mutex implementation does not need to make a distinction
 17794         -** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
 17795         -** not want to.  But SQLite will only request a recursive mutex in
 17796         -** cases where it really needs one.  If a faster non-recursive mutex
 17797         -** implementation is available on the host platform, the mutex subsystem
 17798         -** might return such a mutex in response to SQLITE_MUTEX_FAST.
 17799         -**
 17800         -** The other allowed parameters to sqlite3_mutex_alloc() each return
 17801         -** a pointer to a static preexisting mutex.  Six static mutexes are
 17802         -** used by the current version of SQLite.  Future versions of SQLite
 17803         -** may add additional static mutexes.  Static mutexes are for internal
 17804         -** use by SQLite only.  Applications that use SQLite mutexes should
 17805         -** use only the dynamic mutexes returned by SQLITE_MUTEX_FAST or
 17806         -** SQLITE_MUTEX_RECURSIVE.
 17807         -**
 17808         -** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
 17809         -** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
 17810         -** returns a different mutex on every call.  But for the static
 17811         -** mutex types, the same mutex is returned on every call that has
 17812         -** the same type number.
 17813         -*/
 17814         -static sqlite3_mutex *os2MutexAlloc(int iType){
 17815         -  sqlite3_mutex *p = NULL;
 17816         -  switch( iType ){
 17817         -    case SQLITE_MUTEX_FAST:
 17818         -    case SQLITE_MUTEX_RECURSIVE: {
 17819         -      p = sqlite3MallocZero( sizeof(*p) );
 17820         -      if( p ){
 17821         -        p->id = iType;
 17822         -        if( DosCreateMutexSem( 0, &p->mutex, 0, FALSE ) != NO_ERROR ){
 17823         -          sqlite3_free( p );
 17824         -          p = NULL;
 17825         -        }
 17826         -      }
 17827         -      break;
 17828         -    }
 17829         -    default: {
 17830         -      static volatile int isInit = 0;
 17831         -      static sqlite3_mutex staticMutexes[6] = {
 17832         -        SQLITE3_MUTEX_INITIALIZER,
 17833         -        SQLITE3_MUTEX_INITIALIZER,
 17834         -        SQLITE3_MUTEX_INITIALIZER,
 17835         -        SQLITE3_MUTEX_INITIALIZER,
 17836         -        SQLITE3_MUTEX_INITIALIZER,
 17837         -        SQLITE3_MUTEX_INITIALIZER,
 17838         -      };
 17839         -      if ( !isInit ){
 17840         -        APIRET rc;
 17841         -        PTIB ptib;
 17842         -        PPIB ppib;
 17843         -        HMTX mutex;
 17844         -        char name[32];
 17845         -        DosGetInfoBlocks( &ptib, &ppib );
 17846         -        sqlite3_snprintf( sizeof(name), name, "\\SEM32\\SQLITE%04x",
 17847         -                          ppib->pib_ulpid );
 17848         -        while( !isInit ){
 17849         -          mutex = 0;
 17850         -          rc = DosCreateMutexSem( name, &mutex, 0, FALSE);
 17851         -          if( rc == NO_ERROR ){
 17852         -            unsigned int i;
 17853         -            if( !isInit ){
 17854         -              for( i = 0; i < sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++ ){
 17855         -                DosCreateMutexSem( 0, &staticMutexes[i].mutex, 0, FALSE );
 17856         -              }
 17857         -              isInit = 1;
 17858         -            }
 17859         -            DosCloseMutexSem( mutex );
 17860         -          }else if( rc == ERROR_DUPLICATE_NAME ){
 17861         -            DosSleep( 1 );
 17862         -          }else{
 17863         -            return p;
 17864         -          }
 17865         -        }
 17866         -      }
 17867         -      assert( iType-2 >= 0 );
 17868         -      assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
 17869         -      p = &staticMutexes[iType-2];
 17870         -      p->id = iType;
 17871         -      break;
 17872         -    }
 17873         -  }
 17874         -  return p;
 17875         -}
 17876         -
 17877         -
 17878         -/*
 17879         -** This routine deallocates a previously allocated mutex.
 17880         -** SQLite is careful to deallocate every mutex that it allocates.
 17881         -*/
 17882         -static void os2MutexFree(sqlite3_mutex *p){
 17883         -#ifdef SQLITE_DEBUG
 17884         -  TID tid;
 17885         -  PID pid;
 17886         -  ULONG ulCount;
 17887         -  DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
 17888         -  assert( ulCount==0 );
 17889         -  assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
 17890         -#endif
 17891         -  DosCloseMutexSem( p->mutex );
 17892         -  sqlite3_free( p );
 17893         -}
 17894         -
 17895         -#ifdef SQLITE_DEBUG
 17896         -/*
 17897         -** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
 17898         -** intended for use inside assert() statements.
 17899         -*/
 17900         -static int os2MutexHeld(sqlite3_mutex *p){
 17901         -  TID tid;
 17902         -  PID pid;
 17903         -  ULONG ulCount;
 17904         -  PTIB ptib;
 17905         -  DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
 17906         -  if( ulCount==0 || ( ulCount>1 && p->id!=SQLITE_MUTEX_RECURSIVE ) )
 17907         -    return 0;
 17908         -  DosGetInfoBlocks(&ptib, NULL);
 17909         -  return tid==ptib->tib_ptib2->tib2_ultid;
 17910         -}
 17911         -static int os2MutexNotheld(sqlite3_mutex *p){
 17912         -  TID tid;
 17913         -  PID pid;
 17914         -  ULONG ulCount;
 17915         -  PTIB ptib;
 17916         -  DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
 17917         -  if( ulCount==0 )
 17918         -    return 1;
 17919         -  DosGetInfoBlocks(&ptib, NULL);
 17920         -  return tid!=ptib->tib_ptib2->tib2_ultid;
 17921         -}
 17922         -static void os2MutexTrace(sqlite3_mutex *p, char *pAction){
 17923         -  TID   tid;
 17924         -  PID   pid;
 17925         -  ULONG ulCount;
 17926         -  DosQueryMutexSem(p->mutex, &pid, &tid, &ulCount);
 17927         -  printf("%s mutex %p (%d) with nRef=%ld\n", pAction, (void*)p, p->trace, ulCount);
 17928         -}
 17929         -#endif
 17930         -
 17931         -/*
 17932         -** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
 17933         -** to enter a mutex.  If another thread is already within the mutex,
 17934         -** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
 17935         -** SQLITE_BUSY.  The sqlite3_mutex_try() interface returns SQLITE_OK
 17936         -** upon successful entry.  Mutexes created using SQLITE_MUTEX_RECURSIVE can
 17937         -** be entered multiple times by the same thread.  In such cases the,
 17938         -** mutex must be exited an equal number of times before another thread
 17939         -** can enter.  If the same thread tries to enter any other kind of mutex
 17940         -** more than once, the behavior is undefined.
 17941         -*/
 17942         -static void os2MutexEnter(sqlite3_mutex *p){
 17943         -  assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) );
 17944         -  DosRequestMutexSem(p->mutex, SEM_INDEFINITE_WAIT);
 17945         -#ifdef SQLITE_DEBUG
 17946         -  if( p->trace ) os2MutexTrace(p, "enter");
 17947         -#endif
 17948         -}
 17949         -static int os2MutexTry(sqlite3_mutex *p){
 17950         -  int rc = SQLITE_BUSY;
 17951         -  assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) );
 17952         -  if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR ) {
 17953         -    rc = SQLITE_OK;
 17954         -#ifdef SQLITE_DEBUG
 17955         -    if( p->trace ) os2MutexTrace(p, "try");
 17956         -#endif
 17957         -  }
 17958         -  return rc;
 17959         -}
 17960         -
 17961         -/*
 17962         -** The sqlite3_mutex_leave() routine exits a mutex that was
 17963         -** previously entered by the same thread.  The behavior
 17964         -** is undefined if the mutex is not currently entered or
 17965         -** is not currently allocated.  SQLite will never do either.
 17966         -*/
 17967         -static void os2MutexLeave(sqlite3_mutex *p){
 17968         -  assert( os2MutexHeld(p) );
 17969         -  DosReleaseMutexSem(p->mutex);
 17970         -#ifdef SQLITE_DEBUG
 17971         -  if( p->trace ) os2MutexTrace(p, "leave");
 17972         -#endif
 17973         -}
 17974         -
 17975         -SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
 17976         -  static const sqlite3_mutex_methods sMutex = {
 17977         -    os2MutexInit,
 17978         -    os2MutexEnd,
 17979         -    os2MutexAlloc,
 17980         -    os2MutexFree,
 17981         -    os2MutexEnter,
 17982         -    os2MutexTry,
 17983         -    os2MutexLeave,
 17984         -#ifdef SQLITE_DEBUG
 17985         -    os2MutexHeld,
 17986         -    os2MutexNotheld
 17987         -#else
 17988         -    0,
 17989         -    0
 17990         -#endif
 17991         -  };
 17992         -
 17993         -  return &sMutex;
 17994         -}
 17995         -#endif /* SQLITE_MUTEX_OS2 */
 17996         -
 17997         -/************** End of mutex_os2.c *******************************************/
 17998  17723   /************** Begin file mutex_unix.c **************************************/
 17999  17724   /*
 18000  17725   ** 2007 August 28
 18001  17726   **
 18002  17727   ** The author disclaims copyright to this source code.  In place of
 18003  17728   ** a legal notice, here is a blessing:
 18004  17729   **
................................................................................
 18455  18180   /* As winMutexInit() and winMutexEnd() are called as part
 18456  18181   ** of the sqlite3_initialize and sqlite3_shutdown()
 18457  18182   ** processing, the "interlocked" magic is probably not
 18458  18183   ** strictly necessary.
 18459  18184   */
 18460  18185   static long winMutex_lock = 0;
 18461  18186   
 18462         -SQLITE_API extern void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
        18187  +SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
 18463  18188   
 18464  18189   static int winMutexInit(void){ 
 18465  18190     /* The first to increment to 1 does actual initialization */
 18466  18191     if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
 18467  18192       int i;
 18468  18193       for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
 18469  18194   #if SQLITE_OS_WINRT
................................................................................
 19598  19323   ** The counter *cnt is incremented each time.  After counter exceeds
 19599  19324   ** 16 (the number of significant digits in a 64-bit float) '0' is
 19600  19325   ** always returned.
 19601  19326   */
 19602  19327   static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
 19603  19328     int digit;
 19604  19329     LONGDOUBLE_TYPE d;
 19605         -  if( (*cnt)++ >= 16 ) return '0';
        19330  +  if( (*cnt)<=0 ) return '0';
        19331  +  (*cnt)--;
 19606  19332     digit = (int)*val;
 19607  19333     d = digit;
 19608  19334     digit += '0';
 19609  19335     *val = (*val - d)*10.0;
 19610  19336     return (char)digit;
 19611  19337   }
 19612  19338   #endif /* SQLITE_OMIT_FLOATING_POINT */
................................................................................
 19902  19628           exp = 0;
 19903  19629           if( sqlite3IsNaN((double)realvalue) ){
 19904  19630             bufpt = "NaN";
 19905  19631             length = 3;
 19906  19632             break;
 19907  19633           }
 19908  19634           if( realvalue>0.0 ){
 19909         -          while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; }
 19910         -          while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
 19911         -          while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
        19635  +          LONGDOUBLE_TYPE scale = 1.0;
        19636  +          while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;}
        19637  +          while( realvalue>=1e64*scale && exp<=350 ){ scale *= 1e64; exp+=64; }
        19638  +          while( realvalue>=1e8*scale && exp<=350 ){ scale *= 1e8; exp+=8; }
        19639  +          while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; }
        19640  +          realvalue /= scale;
 19912  19641             while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
 19913  19642             while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
 19914  19643             if( exp>350 ){
 19915  19644               if( prefix=='-' ){
 19916  19645                 bufpt = "-Inf";
 19917  19646               }else if( prefix=='+' ){
 19918  19647                 bufpt = "+Inf";
................................................................................
 19937  19666             if( exp<-4 || exp>precision ){
 19938  19667               xtype = etEXP;
 19939  19668             }else{
 19940  19669               precision = precision - exp;
 19941  19670               xtype = etFLOAT;
 19942  19671             }
 19943  19672           }else{
 19944         -          flag_rtz = 0;
        19673  +          flag_rtz = flag_altform2;
 19945  19674           }
 19946  19675           if( xtype==etEXP ){
 19947  19676             e2 = 0;
 19948  19677           }else{
 19949  19678             e2 = exp;
 19950  19679           }
 19951  19680           if( e2+precision+width > etBUFSIZE - 15 ){
................................................................................
 19952  19681             bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 );
 19953  19682             if( bufpt==0 ){
 19954  19683               pAccum->mallocFailed = 1;
 19955  19684               return;
 19956  19685             }
 19957  19686           }
 19958  19687           zOut = bufpt;
 19959         -        nsd = 0;
        19688  +        nsd = 16 + flag_altform2*10;
 19960  19689           flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
 19961  19690           /* The sign in front of the number */
 19962  19691           if( prefix ){
 19963  19692             *(bufpt++) = prefix;
 19964  19693           }
 19965  19694           /* Digits prior to the decimal point */
 19966  19695           if( e2<0 ){
................................................................................
 21525  21254   
 21526  21255       /* adjust the sign of significand */
 21527  21256       s = sign<0 ? -s : s;
 21528  21257   
 21529  21258       /* if exponent, scale significand as appropriate
 21530  21259       ** and store in result. */
 21531  21260       if( e ){
 21532         -      double scale = 1.0;
        21261  +      LONGDOUBLE_TYPE scale = 1.0;
 21533  21262         /* attempt to handle extremely small/large numbers better */
 21534  21263         if( e>307 && e<342 ){
 21535  21264           while( e%308 ) { scale *= 1.0e+1; e -= 1; }
 21536  21265           if( esign<0 ){
 21537  21266             result = s / scale;
 21538  21267             result /= 1.0e+308;
 21539  21268           }else{
................................................................................
 22780  22509        /* 150 */ "Explain",
 22781  22510     };
 22782  22511     return azName[i];
 22783  22512   }
 22784  22513   #endif
 22785  22514   
 22786  22515   /************** End of opcodes.c *********************************************/
 22787         -/************** Begin file os_os2.c ******************************************/
 22788         -/*
 22789         -** 2006 Feb 14
 22790         -**
 22791         -** The author disclaims copyright to this source code.  In place of
 22792         -** a legal notice, here is a blessing:
 22793         -**
 22794         -**    May you do good and not evil.
 22795         -**    May you find forgiveness for yourself and forgive others.
 22796         -**    May you share freely, never taking more than you give.
 22797         -**
 22798         -******************************************************************************
 22799         -**
 22800         -** This file contains code that is specific to OS/2.
 22801         -*/
 22802         -
 22803         -
 22804         -#if SQLITE_OS_OS2
 22805         -
 22806         -/*
 22807         -** A Note About Memory Allocation:
 22808         -**
 22809         -** This driver uses malloc()/free() directly rather than going through
 22810         -** the SQLite-wrappers sqlite3_malloc()/sqlite3_free().  Those wrappers
 22811         -** are designed for use on embedded systems where memory is scarce and
 22812         -** malloc failures happen frequently.  OS/2 does not typically run on
 22813         -** embedded systems, and when it does the developers normally have bigger
 22814         -** problems to worry about than running out of memory.  So there is not
 22815         -** a compelling need to use the wrappers.
 22816         -**
 22817         -** But there is a good reason to not use the wrappers.  If we use the
 22818         -** wrappers then we will get simulated malloc() failures within this
 22819         -** driver.  And that causes all kinds of problems for our tests.  We
 22820         -** could enhance SQLite to deal with simulated malloc failures within
 22821         -** the OS driver, but the code to deal with those failure would not
 22822         -** be exercised on Linux (which does not need to malloc() in the driver)
 22823         -** and so we would have difficulty writing coverage tests for that
 22824         -** code.  Better to leave the code out, we think.
 22825         -**
 22826         -** The point of this discussion is as follows:  When creating a new
 22827         -** OS layer for an embedded system, if you use this file as an example,
 22828         -** avoid the use of malloc()/free().  Those routines work ok on OS/2
 22829         -** desktops but not so well in embedded systems.
 22830         -*/
 22831         -
 22832         -/*
 22833         -** Macros used to determine whether or not to use threads.
 22834         -*/
 22835         -#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE
 22836         -# define SQLITE_OS2_THREADS 1
 22837         -#endif
 22838         -
 22839         -/*
 22840         -** Include code that is common to all os_*.c files
 22841         -*/
 22842         -/************** Include os_common.h in the middle of os_os2.c ****************/
 22843         -/************** Begin file os_common.h ***************************************/
 22844         -/*
 22845         -** 2004 May 22
 22846         -**
 22847         -** The author disclaims copyright to this source code.  In place of
 22848         -** a legal notice, here is a blessing:
 22849         -**
 22850         -**    May you do good and not evil.
 22851         -**    May you find forgiveness for yourself and forgive others.
 22852         -**    May you share freely, never taking more than you give.
 22853         -**
 22854         -******************************************************************************
 22855         -**
 22856         -** This file contains macros and a little bit of code that is common to
 22857         -** all of the platform-specific files (os_*.c) and is #included into those
 22858         -** files.
 22859         -**
 22860         -** This file should be #included by the os_*.c files only.  It is not a
 22861         -** general purpose header file.
 22862         -*/
 22863         -#ifndef _OS_COMMON_H_
 22864         -#define _OS_COMMON_H_
 22865         -
 22866         -/*
 22867         -** At least two bugs have slipped in because we changed the MEMORY_DEBUG
 22868         -** macro to SQLITE_DEBUG and some older makefiles have not yet made the
 22869         -** switch.  The following code should catch this problem at compile-time.
 22870         -*/
 22871         -#ifdef MEMORY_DEBUG
 22872         -# error "The MEMORY_DEBUG macro is obsolete.  Use SQLITE_DEBUG instead."
 22873         -#endif
 22874         -
 22875         -#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
 22876         -# ifndef SQLITE_DEBUG_OS_TRACE
 22877         -#   define SQLITE_DEBUG_OS_TRACE 0
 22878         -# endif
 22879         -  int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
 22880         -# define OSTRACE(X)          if( sqlite3OSTrace ) sqlite3DebugPrintf X
 22881         -#else
 22882         -# define OSTRACE(X)
 22883         -#endif
 22884         -
 22885         -/*
 22886         -** Macros for performance tracing.  Normally turned off.  Only works
 22887         -** on i486 hardware.
 22888         -*/
 22889         -#ifdef SQLITE_PERFORMANCE_TRACE
 22890         -
 22891         -/* 
 22892         -** hwtime.h contains inline assembler code for implementing 
 22893         -** high-performance timing routines.
 22894         -*/
 22895         -/************** Include hwtime.h in the middle of os_common.h ****************/
 22896         -/************** Begin file hwtime.h ******************************************/
 22897         -/*
 22898         -** 2008 May 27
 22899         -**
 22900         -** The author disclaims copyright to this source code.  In place of
 22901         -** a legal notice, here is a blessing:
 22902         -**
 22903         -**    May you do good and not evil.
 22904         -**    May you find forgiveness for yourself and forgive others.
 22905         -**    May you share freely, never taking more than you give.
 22906         -**
 22907         -******************************************************************************
 22908         -**
 22909         -** This file contains inline asm code for retrieving "high-performance"
 22910         -** counters for x86 class CPUs.
 22911         -*/
 22912         -#ifndef _HWTIME_H_
 22913         -#define _HWTIME_H_
 22914         -
 22915         -/*
 22916         -** The following routine only works on pentium-class (or newer) processors.
 22917         -** It uses the RDTSC opcode to read the cycle count value out of the
 22918         -** processor and returns that value.  This can be used for high-res
 22919         -** profiling.
 22920         -*/
 22921         -#if (defined(__GNUC__) || defined(_MSC_VER)) && \
 22922         -      (defined(i386) || defined(__i386__) || defined(_M_IX86))
 22923         -
 22924         -  #if defined(__GNUC__)
 22925         -
 22926         -  __inline__ sqlite_uint64 sqlite3Hwtime(void){
 22927         -     unsigned int lo, hi;
 22928         -     __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
 22929         -     return (sqlite_uint64)hi << 32 | lo;
 22930         -  }
 22931         -
 22932         -  #elif defined(_MSC_VER)
 22933         -
 22934         -  __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
 22935         -     __asm {
 22936         -        rdtsc
 22937         -        ret       ; return value at EDX:EAX
 22938         -     }
 22939         -  }
 22940         -
 22941         -  #endif
 22942         -
 22943         -#elif (defined(__GNUC__) && defined(__x86_64__))
 22944         -
 22945         -  __inline__ sqlite_uint64 sqlite3Hwtime(void){
 22946         -      unsigned long val;
 22947         -      __asm__ __volatile__ ("rdtsc" : "=A" (val));
 22948         -      return val;
 22949         -  }
 22950         - 
 22951         -#elif (defined(__GNUC__) && defined(__ppc__))
 22952         -
 22953         -  __inline__ sqlite_uint64 sqlite3Hwtime(void){
 22954         -      unsigned long long retval;
 22955         -      unsigned long junk;
 22956         -      __asm__ __volatile__ ("\n\
 22957         -          1:      mftbu   %1\n\
 22958         -                  mftb    %L0\n\
 22959         -                  mftbu   %0\n\
 22960         -                  cmpw    %0,%1\n\
 22961         -                  bne     1b"
 22962         -                  : "=r" (retval), "=r" (junk));
 22963         -      return retval;
 22964         -  }
 22965         -
 22966         -#else
 22967         -
 22968         -  #error Need implementation of sqlite3Hwtime() for your platform.
 22969         -
 22970         -  /*
 22971         -  ** To compile without implementing sqlite3Hwtime() for your platform,
 22972         -  ** you can remove the above #error and use the following
 22973         -  ** stub function.  You will lose timing support for many
 22974         -  ** of the debugging and testing utilities, but it should at
 22975         -  ** least compile and run.
 22976         -  */
 22977         -SQLITE_PRIVATE   sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
 22978         -
 22979         -#endif
 22980         -
 22981         -#endif /* !defined(_HWTIME_H_) */
 22982         -
 22983         -/************** End of hwtime.h **********************************************/
 22984         -/************** Continuing where we left off in os_common.h ******************/
 22985         -
 22986         -static sqlite_uint64 g_start;
 22987         -static sqlite_uint64 g_elapsed;
 22988         -#define TIMER_START       g_start=sqlite3Hwtime()
 22989         -#define TIMER_END         g_elapsed=sqlite3Hwtime()-g_start
 22990         -#define TIMER_ELAPSED     g_elapsed
 22991         -#else
 22992         -#define TIMER_START
 22993         -#define TIMER_END
 22994         -#define TIMER_ELAPSED     ((sqlite_uint64)0)
 22995         -#endif
 22996         -
 22997         -/*
 22998         -** If we compile with the SQLITE_TEST macro set, then the following block
 22999         -** of code will give us the ability to simulate a disk I/O error.  This
 23000         -** is used for testing the I/O recovery logic.
 23001         -*/
 23002         -#ifdef SQLITE_TEST
 23003         -SQLITE_API int sqlite3_io_error_hit = 0;            /* Total number of I/O Errors */
 23004         -SQLITE_API int sqlite3_io_error_hardhit = 0;        /* Number of non-benign errors */
 23005         -SQLITE_API int sqlite3_io_error_pending = 0;        /* Count down to first I/O error */
 23006         -SQLITE_API int sqlite3_io_error_persist = 0;        /* True if I/O errors persist */
 23007         -SQLITE_API int sqlite3_io_error_benign = 0;         /* True if errors are benign */
 23008         -SQLITE_API int sqlite3_diskfull_pending = 0;
 23009         -SQLITE_API int sqlite3_diskfull = 0;
 23010         -#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X)
 23011         -#define SimulateIOError(CODE)  \
 23012         -  if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \
 23013         -       || sqlite3_io_error_pending-- == 1 )  \
 23014         -              { local_ioerr(); CODE; }
 23015         -static void local_ioerr(){
 23016         -  IOTRACE(("IOERR\n"));
 23017         -  sqlite3_io_error_hit++;
 23018         -  if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++;
 23019         -}
 23020         -#define SimulateDiskfullError(CODE) \
 23021         -   if( sqlite3_diskfull_pending ){ \
 23022         -     if( sqlite3_diskfull_pending == 1 ){ \
 23023         -       local_ioerr(); \
 23024         -       sqlite3_diskfull = 1; \
 23025         -       sqlite3_io_error_hit = 1; \
 23026         -       CODE; \
 23027         -     }else{ \
 23028         -       sqlite3_diskfull_pending--; \
 23029         -     } \
 23030         -   }
 23031         -#else
 23032         -#define SimulateIOErrorBenign(X)
 23033         -#define SimulateIOError(A)
 23034         -#define SimulateDiskfullError(A)
 23035         -#endif
 23036         -
 23037         -/*
 23038         -** When testing, keep a count of the number of open files.
 23039         -*/
 23040         -#ifdef SQLITE_TEST
 23041         -SQLITE_API int sqlite3_open_file_count = 0;
 23042         -#define OpenCounter(X)  sqlite3_open_file_count+=(X)
 23043         -#else
 23044         -#define OpenCounter(X)
 23045         -#endif
 23046         -
 23047         -#endif /* !defined(_OS_COMMON_H_) */
 23048         -
 23049         -/************** End of os_common.h *******************************************/
 23050         -/************** Continuing where we left off in os_os2.c *********************/
 23051         -
 23052         -/* Forward references */
 23053         -typedef struct os2File os2File;         /* The file structure */
 23054         -typedef struct os2ShmNode os2ShmNode;   /* A shared descritive memory node */
 23055         -typedef struct os2ShmLink os2ShmLink;   /* A connection to shared-memory */
 23056         -
 23057         -/*
 23058         -** The os2File structure is subclass of sqlite3_file specific for the OS/2
 23059         -** protability layer.
 23060         -*/
 23061         -struct os2File {
 23062         -  const sqlite3_io_methods *pMethod;  /* Always the first entry */
 23063         -  HFILE h;                  /* Handle for accessing the file */
 23064         -  int flags;                /* Flags provided to os2Open() */
 23065         -  int locktype;             /* Type of lock currently held on this file */
 23066         -  int szChunk;              /* Chunk size configured by FCNTL_CHUNK_SIZE */
 23067         -  char *zFullPathCp;        /* Full path name of this file */
 23068         -  os2ShmLink *pShmLink;     /* Instance of shared memory on this file */
 23069         -};
 23070         -
 23071         -#define LOCK_TIMEOUT 10L /* the default locking timeout */
 23072         -
 23073         -/*
 23074         -** Missing from some versions of the OS/2 toolkit -
 23075         -** used to allocate from high memory if possible
 23076         -*/
 23077         -#ifndef OBJ_ANY
 23078         -# define OBJ_ANY 0x00000400
 23079         -#endif
 23080         -
 23081         -/*****************************************************************************
 23082         -** The next group of routines implement the I/O methods specified
 23083         -** by the sqlite3_io_methods object.
 23084         -******************************************************************************/
 23085         -
 23086         -/*
 23087         -** Close a file.
 23088         -*/
 23089         -static int os2Close( sqlite3_file *id ){
 23090         -  APIRET rc;
 23091         -  os2File *pFile = (os2File*)id;
 23092         -
 23093         -  assert( id!=0 );
 23094         -  OSTRACE(( "CLOSE %d (%s)\n", pFile->h, pFile->zFullPathCp ));
 23095         -
 23096         -  rc = DosClose( pFile->h );
 23097         -
 23098         -  if( pFile->flags & SQLITE_OPEN_DELETEONCLOSE )
 23099         -    DosForceDelete( (PSZ)pFile->zFullPathCp );
 23100         -
 23101         -  free( pFile->zFullPathCp );
 23102         -  pFile->zFullPathCp = NULL;
 23103         -  pFile->locktype = NO_LOCK;
 23104         -  pFile->h = (HFILE)-1;
 23105         -  pFile->flags = 0;
 23106         -
 23107         -  OpenCounter( -1 );
 23108         -  return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
 23109         -}
 23110         -
 23111         -/*
 23112         -** Read data from a file into a buffer.  Return SQLITE_OK if all
 23113         -** bytes were read successfully and SQLITE_IOERR if anything goes
 23114         -** wrong.
 23115         -*/
 23116         -static int os2Read(
 23117         -  sqlite3_file *id,               /* File to read from */
 23118         -  void *pBuf,                     /* Write content into this buffer */
 23119         -  int amt,                        /* Number of bytes to read */
 23120         -  sqlite3_int64 offset            /* Begin reading at this offset */
 23121         -){
 23122         -  ULONG fileLocation = 0L;
 23123         -  ULONG got;
 23124         -  os2File *pFile = (os2File*)id;
 23125         -  assert( id!=0 );
 23126         -  SimulateIOError( return SQLITE_IOERR_READ );
 23127         -  OSTRACE(( "READ %d lock=%d\n", pFile->h, pFile->locktype ));
 23128         -  if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){
 23129         -    return SQLITE_IOERR;
 23130         -  }
 23131         -  if( DosRead( pFile->h, pBuf, amt, &got ) != NO_ERROR ){
 23132         -    return SQLITE_IOERR_READ;
 23133         -  }
 23134         -  if( got == (ULONG)amt )
 23135         -    return SQLITE_OK;
 23136         -  else {
 23137         -    /* Unread portions of the input buffer must be zero-filled */
 23138         -    memset(&((char*)pBuf)[got], 0, amt-got);
 23139         -    return SQLITE_IOERR_SHORT_READ;
 23140         -  }
 23141         -}
 23142         -
 23143         -/*
 23144         -** Write data from a buffer into a file.  Return SQLITE_OK on success
 23145         -** or some other error code on failure.
 23146         -*/
 23147         -static int os2Write(
 23148         -  sqlite3_file *id,               /* File to write into */
 23149         -  const void *pBuf,               /* The bytes to be written */
 23150         -  int amt,                        /* Number of bytes to write */
 23151         -  sqlite3_int64 offset            /* Offset into the file to begin writing at */
 23152         -){
 23153         -  ULONG fileLocation = 0L;
 23154         -  APIRET rc = NO_ERROR;
 23155         -  ULONG wrote;
 23156         -  os2File *pFile = (os2File*)id;
 23157         -  assert( id!=0 );
 23158         -  SimulateIOError( return SQLITE_IOERR_WRITE );
 23159         -  SimulateDiskfullError( return SQLITE_FULL );
 23160         -  OSTRACE(( "WRITE %d lock=%d\n", pFile->h, pFile->locktype ));
 23161         -  if( DosSetFilePtr(pFile->h, offset, FILE_BEGIN, &fileLocation) != NO_ERROR ){
 23162         -    return SQLITE_IOERR;
 23163         -  }
 23164         -  assert( amt>0 );
 23165         -  while( amt > 0 &&
 23166         -         ( rc = DosWrite( pFile->h, (PVOID)pBuf, amt, &wrote ) ) == NO_ERROR &&
 23167         -         wrote > 0
 23168         -  ){
 23169         -    amt -= wrote;
 23170         -    pBuf = &((char*)pBuf)[wrote];
 23171         -  }
 23172         -
 23173         -  return ( rc != NO_ERROR || amt > (int)wrote ) ? SQLITE_FULL : SQLITE_OK;
 23174         -}
 23175         -
 23176         -/*
 23177         -** Truncate an open file to a specified size
 23178         -*/
 23179         -static int os2Truncate( sqlite3_file *id, i64 nByte ){
 23180         -  APIRET rc;
 23181         -  os2File *pFile = (os2File*)id;
 23182         -  assert( id!=0 );
 23183         -  OSTRACE(( "TRUNCATE %d %lld\n", pFile->h, nByte ));
 23184         -  SimulateIOError( return SQLITE_IOERR_TRUNCATE );
 23185         -
 23186         -  /* If the user has configured a chunk-size for this file, truncate the
 23187         -  ** file so that it consists of an integer number of chunks (i.e. the
 23188         -  ** actual file size after the operation may be larger than the requested
 23189         -  ** size).
 23190         -  */
 23191         -  if( pFile->szChunk ){
 23192         -    nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
 23193         -  }
 23194         -  
 23195         -  rc = DosSetFileSize( pFile->h, nByte );
 23196         -  return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_TRUNCATE;
 23197         -}
 23198         -
 23199         -#ifdef SQLITE_TEST
 23200         -/*
 23201         -** Count the number of fullsyncs and normal syncs.  This is used to test
 23202         -** that syncs and fullsyncs are occuring at the right times.
 23203         -*/
 23204         -SQLITE_API int sqlite3_sync_count = 0;
 23205         -SQLITE_API int sqlite3_fullsync_count = 0;
 23206         -#endif
 23207         -
 23208         -/*
 23209         -** Make sure all writes to a particular file are committed to disk.
 23210         -*/
 23211         -static int os2Sync( sqlite3_file *id, int flags ){
 23212         -  os2File *pFile = (os2File*)id;
 23213         -  OSTRACE(( "SYNC %d lock=%d\n", pFile->h, pFile->locktype ));
 23214         -#ifdef SQLITE_TEST
 23215         -  if( flags & SQLITE_SYNC_FULL){
 23216         -    sqlite3_fullsync_count++;
 23217         -  }
 23218         -  sqlite3_sync_count++;
 23219         -#endif
 23220         -  /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
 23221         -  ** no-op
 23222         -  */
 23223         -#ifdef SQLITE_NO_SYNC
 23224         -  UNUSED_PARAMETER(pFile);
 23225         -  return SQLITE_OK;
 23226         -#else
 23227         -  return DosResetBuffer( pFile->h ) == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
 23228         -#endif
 23229         -}
 23230         -
 23231         -/*
 23232         -** Determine the current size of a file in bytes
 23233         -*/
 23234         -static int os2FileSize( sqlite3_file *id, sqlite3_int64 *pSize ){
 23235         -  APIRET rc = NO_ERROR;
 23236         -  FILESTATUS3 fsts3FileInfo;
 23237         -  memset(&fsts3FileInfo, 0, sizeof(fsts3FileInfo));
 23238         -  assert( id!=0 );
 23239         -  SimulateIOError( return SQLITE_IOERR_FSTAT );
 23240         -  rc = DosQueryFileInfo( ((os2File*)id)->h, FIL_STANDARD, &fsts3FileInfo, sizeof(FILESTATUS3) );
 23241         -  if( rc == NO_ERROR ){
 23242         -    *pSize = fsts3FileInfo.cbFile;
 23243         -    return SQLITE_OK;
 23244         -  }else{
 23245         -    return SQLITE_IOERR_FSTAT;
 23246         -  }
 23247         -}
 23248         -
 23249         -/*
 23250         -** Acquire a reader lock.
 23251         -*/
 23252         -static int getReadLock( os2File *pFile ){
 23253         -  FILELOCK  LockArea,
 23254         -            UnlockArea;
 23255         -  APIRET res;
 23256         -  memset(&LockArea, 0, sizeof(LockArea));
 23257         -  memset(&UnlockArea, 0, sizeof(UnlockArea));
 23258         -  LockArea.lOffset = SHARED_FIRST;
 23259         -  LockArea.lRange = SHARED_SIZE;
 23260         -  UnlockArea.lOffset = 0L;
 23261         -  UnlockArea.lRange = 0L;
 23262         -  res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L );
 23263         -  OSTRACE(( "GETREADLOCK %d res=%d\n", pFile->h, res ));
 23264         -  return res;
 23265         -}
 23266         -
 23267         -/*
 23268         -** Undo a readlock
 23269         -*/
 23270         -static int unlockReadLock( os2File *id ){
 23271         -  FILELOCK  LockArea,
 23272         -            UnlockArea;
 23273         -  APIRET res;
 23274         -  memset(&LockArea, 0, sizeof(LockArea));
 23275         -  memset(&UnlockArea, 0, sizeof(UnlockArea));
 23276         -  LockArea.lOffset = 0L;
 23277         -  LockArea.lRange = 0L;
 23278         -  UnlockArea.lOffset = SHARED_FIRST;
 23279         -  UnlockArea.lRange = SHARED_SIZE;
 23280         -  res = DosSetFileLocks( id->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 1L );
 23281         -  OSTRACE(( "UNLOCK-READLOCK file handle=%d res=%d?\n", id->h, res ));
 23282         -  return res;
 23283         -}
 23284         -
 23285         -/*
 23286         -** Lock the file with the lock specified by parameter locktype - one
 23287         -** of the following:
 23288         -**
 23289         -**     (1) SHARED_LOCK
 23290         -**     (2) RESERVED_LOCK
 23291         -**     (3) PENDING_LOCK
 23292         -**     (4) EXCLUSIVE_LOCK
 23293         -**
 23294         -** Sometimes when requesting one lock state, additional lock states
 23295         -** are inserted in between.  The locking might fail on one of the later
 23296         -** transitions leaving the lock state different from what it started but
 23297         -** still short of its goal.  The following chart shows the allowed
 23298         -** transitions and the inserted intermediate states:
 23299         -**
 23300         -**    UNLOCKED -> SHARED
 23301         -**    SHARED -> RESERVED
 23302         -**    SHARED -> (PENDING) -> EXCLUSIVE
 23303         -**    RESERVED -> (PENDING) -> EXCLUSIVE
 23304         -**    PENDING -> EXCLUSIVE
 23305         -**
 23306         -** This routine will only increase a lock.  The os2Unlock() routine
 23307         -** erases all locks at once and returns us immediately to locking level 0.
 23308         -** It is not possible to lower the locking level one step at a time.  You
 23309         -** must go straight to locking level 0.
 23310         -*/
 23311         -static int os2Lock( sqlite3_file *id, int locktype ){
 23312         -  int rc = SQLITE_OK;       /* Return code from subroutines */
 23313         -  APIRET res = NO_ERROR;    /* Result of an OS/2 lock call */
 23314         -  int newLocktype;       /* Set pFile->locktype to this value before exiting */
 23315         -  int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
 23316         -  FILELOCK  LockArea,
 23317         -            UnlockArea;
 23318         -  os2File *pFile = (os2File*)id;
 23319         -  memset(&LockArea, 0, sizeof(LockArea));
 23320         -  memset(&UnlockArea, 0, sizeof(UnlockArea));
 23321         -  assert( pFile!=0 );
 23322         -  OSTRACE(( "LOCK %d %d was %d\n", pFile->h, locktype, pFile->locktype ));
 23323         -
 23324         -  /* If there is already a lock of this type or more restrictive on the
 23325         -  ** os2File, do nothing. Don't use the end_lock: exit path, as
 23326         -  ** sqlite3_mutex_enter() hasn't been called yet.
 23327         -  */
 23328         -  if( pFile->locktype>=locktype ){
 23329         -    OSTRACE(( "LOCK %d %d ok (already held)\n", pFile->h, locktype ));
 23330         -    return SQLITE_OK;
 23331         -  }
 23332         -
 23333         -  /* Make sure the locking sequence is correct
 23334         -  */
 23335         -  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
 23336         -  assert( locktype!=PENDING_LOCK );
 23337         -  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
 23338         -
 23339         -  /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
 23340         -  ** a SHARED lock.  If we are acquiring a SHARED lock, the acquisition of
 23341         -  ** the PENDING_LOCK byte is temporary.
 23342         -  */
 23343         -  newLocktype = pFile->locktype;
 23344         -  if( pFile->locktype==NO_LOCK
 23345         -      || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
 23346         -  ){
 23347         -    LockArea.lOffset = PENDING_BYTE;
 23348         -    LockArea.lRange = 1L;
 23349         -    UnlockArea.lOffset = 0L;
 23350         -    UnlockArea.lRange = 0L;
 23351         -
 23352         -    /* wait longer than LOCK_TIMEOUT here not to have to try multiple times */
 23353         -    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, 100L, 0L );
 23354         -    if( res == NO_ERROR ){
 23355         -      gotPendingLock = 1;
 23356         -      OSTRACE(( "LOCK %d pending lock boolean set.  res=%d\n", pFile->h, res ));
 23357         -    }
 23358         -  }
 23359         -
 23360         -  /* Acquire a shared lock
 23361         -  */
 23362         -  if( locktype==SHARED_LOCK && res == NO_ERROR ){
 23363         -    assert( pFile->locktype==NO_LOCK );
 23364         -    res = getReadLock(pFile);
 23365         -    if( res == NO_ERROR ){
 23366         -      newLocktype = SHARED_LOCK;
 23367         -    }
 23368         -    OSTRACE(( "LOCK %d acquire shared lock. res=%d\n", pFile->h, res ));
 23369         -  }
 23370         -
 23371         -  /* Acquire a RESERVED lock
 23372         -  */
 23373         -  if( locktype==RESERVED_LOCK && res == NO_ERROR ){
 23374         -    assert( pFile->locktype==SHARED_LOCK );
 23375         -    LockArea.lOffset = RESERVED_BYTE;
 23376         -    LockArea.lRange = 1L;
 23377         -    UnlockArea.lOffset = 0L;
 23378         -    UnlockArea.lRange = 0L;
 23379         -    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
 23380         -    if( res == NO_ERROR ){
 23381         -      newLocktype = RESERVED_LOCK;
 23382         -    }
 23383         -    OSTRACE(( "LOCK %d acquire reserved lock. res=%d\n", pFile->h, res ));
 23384         -  }
 23385         -
 23386         -  /* Acquire a PENDING lock
 23387         -  */
 23388         -  if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){
 23389         -    newLocktype = PENDING_LOCK;
 23390         -    gotPendingLock = 0;
 23391         -    OSTRACE(( "LOCK %d acquire pending lock. pending lock boolean unset.\n",
 23392         -               pFile->h ));
 23393         -  }
 23394         -
 23395         -  /* Acquire an EXCLUSIVE lock
 23396         -  */
 23397         -  if( locktype==EXCLUSIVE_LOCK && res == NO_ERROR ){
 23398         -    assert( pFile->locktype>=SHARED_LOCK );
 23399         -    res = unlockReadLock(pFile);
 23400         -    OSTRACE(( "unreadlock = %d\n", res ));
 23401         -    LockArea.lOffset = SHARED_FIRST;
 23402         -    LockArea.lRange = SHARED_SIZE;
 23403         -    UnlockArea.lOffset = 0L;
 23404         -    UnlockArea.lRange = 0L;
 23405         -    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
 23406         -    if( res == NO_ERROR ){
 23407         -      newLocktype = EXCLUSIVE_LOCK;
 23408         -    }else{
 23409         -      OSTRACE(( "OS/2 error-code = %d\n", res ));
 23410         -      getReadLock(pFile);
 23411         -    }
 23412         -    OSTRACE(( "LOCK %d acquire exclusive lock.  res=%d\n", pFile->h, res ));
 23413         -  }
 23414         -
 23415         -  /* If we are holding a PENDING lock that ought to be released, then
 23416         -  ** release it now.
 23417         -  */
 23418         -  if( gotPendingLock && locktype==SHARED_LOCK ){
 23419         -    int r;
 23420         -    LockArea.lOffset = 0L;
 23421         -    LockArea.lRange = 0L;
 23422         -    UnlockArea.lOffset = PENDING_BYTE;
 23423         -    UnlockArea.lRange = 1L;
 23424         -    r = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
 23425         -    OSTRACE(( "LOCK %d unlocking pending/is shared. r=%d\n", pFile->h, r ));
 23426         -  }
 23427         -
 23428         -  /* Update the state of the lock has held in the file descriptor then
 23429         -  ** return the appropriate result code.
 23430         -  */
 23431         -  if( res == NO_ERROR ){
 23432         -    rc = SQLITE_OK;
 23433         -  }else{
 23434         -    OSTRACE(( "LOCK FAILED %d trying for %d but got %d\n", pFile->h,
 23435         -              locktype, newLocktype ));
 23436         -    rc = SQLITE_BUSY;
 23437         -  }
 23438         -  pFile->locktype = newLocktype;
 23439         -  OSTRACE(( "LOCK %d now %d\n", pFile->h, pFile->locktype ));
 23440         -  return rc;
 23441         -}
 23442         -
 23443         -/*
 23444         -** This routine checks if there is a RESERVED lock held on the specified
 23445         -** file by this or any other process. If such a lock is held, return
 23446         -** non-zero, otherwise zero.
 23447         -*/
 23448         -static int os2CheckReservedLock( sqlite3_file *id, int *pOut ){
 23449         -  int r = 0;
 23450         -  os2File *pFile = (os2File*)id;
 23451         -  assert( pFile!=0 );
 23452         -  if( pFile->locktype>=RESERVED_LOCK ){
 23453         -    r = 1;
 23454         -    OSTRACE(( "TEST WR-LOCK %d %d (local)\n", pFile->h, r ));
 23455         -  }else{
 23456         -    FILELOCK  LockArea,
 23457         -              UnlockArea;
 23458         -    APIRET rc = NO_ERROR;
 23459         -    memset(&LockArea, 0, sizeof(LockArea));
 23460         -    memset(&UnlockArea, 0, sizeof(UnlockArea));
 23461         -    LockArea.lOffset = RESERVED_BYTE;
 23462         -    LockArea.lRange = 1L;
 23463         -    UnlockArea.lOffset = 0L;
 23464         -    UnlockArea.lRange = 0L;
 23465         -    rc = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
 23466         -    OSTRACE(( "TEST WR-LOCK %d lock reserved byte rc=%d\n", pFile->h, rc ));
 23467         -    if( rc == NO_ERROR ){
 23468         -      APIRET rcu = NO_ERROR; /* return code for unlocking */
 23469         -      LockArea.lOffset = 0L;
 23470         -      LockArea.lRange = 0L;
 23471         -      UnlockArea.lOffset = RESERVED_BYTE;
 23472         -      UnlockArea.lRange = 1L;
 23473         -      rcu = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
 23474         -      OSTRACE(( "TEST WR-LOCK %d unlock reserved byte r=%d\n", pFile->h, rcu ));
 23475         -    }
 23476         -    r = !(rc == NO_ERROR);
 23477         -    OSTRACE(( "TEST WR-LOCK %d %d (remote)\n", pFile->h, r ));
 23478         -  }
 23479         -  *pOut = r;
 23480         -  return SQLITE_OK;
 23481         -}
 23482         -
 23483         -/*
 23484         -** Lower the locking level on file descriptor id to locktype.  locktype
 23485         -** must be either NO_LOCK or SHARED_LOCK.
 23486         -**
 23487         -** If the locking level of the file descriptor is already at or below
 23488         -** the requested locking level, this routine is a no-op.
 23489         -**
 23490         -** It is not possible for this routine to fail if the second argument
 23491         -** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine
 23492         -** might return SQLITE_IOERR;
 23493         -*/
 23494         -static int os2Unlock( sqlite3_file *id, int locktype ){
 23495         -  int type;
 23496         -  os2File *pFile = (os2File*)id;
 23497         -  APIRET rc = SQLITE_OK;
 23498         -  APIRET res = NO_ERROR;
 23499         -  FILELOCK  LockArea,
 23500         -            UnlockArea;
 23501         -  memset(&LockArea, 0, sizeof(LockArea));
 23502         -  memset(&UnlockArea, 0, sizeof(UnlockArea));
 23503         -  assert( pFile!=0 );
 23504         -  assert( locktype<=SHARED_LOCK );
 23505         -  OSTRACE(( "UNLOCK %d to %d was %d\n", pFile->h, locktype, pFile->locktype ));
 23506         -  type = pFile->locktype;
 23507         -  if( type>=EXCLUSIVE_LOCK ){
 23508         -    LockArea.lOffset = 0L;
 23509         -    LockArea.lRange = 0L;
 23510         -    UnlockArea.lOffset = SHARED_FIRST;
 23511         -    UnlockArea.lRange = SHARED_SIZE;
 23512         -    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
 23513         -    OSTRACE(( "UNLOCK %d exclusive lock res=%d\n", pFile->h, res ));
 23514         -    if( locktype==SHARED_LOCK && getReadLock(pFile) != NO_ERROR ){
 23515         -      /* This should never happen.  We should always be able to
 23516         -      ** reacquire the read lock */
 23517         -      OSTRACE(( "UNLOCK %d to %d getReadLock() failed\n", pFile->h, locktype ));
 23518         -      rc = SQLITE_IOERR_UNLOCK;
 23519         -    }
 23520         -  }
 23521         -  if( type>=RESERVED_LOCK ){
 23522         -    LockArea.lOffset = 0L;
 23523         -    LockArea.lRange = 0L;
 23524         -    UnlockArea.lOffset = RESERVED_BYTE;
 23525         -    UnlockArea.lRange = 1L;
 23526         -    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
 23527         -    OSTRACE(( "UNLOCK %d reserved res=%d\n", pFile->h, res ));
 23528         -  }
 23529         -  if( locktype==NO_LOCK && type>=SHARED_LOCK ){
 23530         -    res = unlockReadLock(pFile);
 23531         -    OSTRACE(( "UNLOCK %d is %d want %d res=%d\n",
 23532         -              pFile->h, type, locktype, res ));
 23533         -  }
 23534         -  if( type>=PENDING_LOCK ){
 23535         -    LockArea.lOffset = 0L;
 23536         -    LockArea.lRange = 0L;
 23537         -    UnlockArea.lOffset = PENDING_BYTE;
 23538         -    UnlockArea.lRange = 1L;
 23539         -    res = DosSetFileLocks( pFile->h, &UnlockArea, &LockArea, LOCK_TIMEOUT, 0L );
 23540         -    OSTRACE(( "UNLOCK %d pending res=%d\n", pFile->h, res ));
 23541         -  }
 23542         -  pFile->locktype = locktype;
 23543         -  OSTRACE(( "UNLOCK %d now %d\n", pFile->h, pFile->locktype ));
 23544         -  return rc;
 23545         -}
 23546         -
 23547         -/*
 23548         -** Control and query of the open file handle.
 23549         -*/
 23550         -static int os2FileControl(sqlite3_file *id, int op, void *pArg){
 23551         -  switch( op ){
 23552         -    case SQLITE_FCNTL_LOCKSTATE: {
 23553         -      *(int*)pArg = ((os2File*)id)->locktype;
 23554         -      OSTRACE(( "FCNTL_LOCKSTATE %d lock=%d\n",
 23555         -                ((os2File*)id)->h, ((os2File*)id)->locktype ));
 23556         -      return SQLITE_OK;
 23557         -    }
 23558         -    case SQLITE_FCNTL_CHUNK_SIZE: {
 23559         -      ((os2File*)id)->szChunk = *(int*)pArg;
 23560         -      return SQLITE_OK;
 23561         -    }
 23562         -    case SQLITE_FCNTL_SIZE_HINT: {
 23563         -      sqlite3_int64 sz = *(sqlite3_int64*)pArg;
 23564         -      SimulateIOErrorBenign(1);
 23565         -      os2Truncate(id, sz);
 23566         -      SimulateIOErrorBenign(0);
 23567         -      return SQLITE_OK;
 23568         -    }
 23569         -    case SQLITE_FCNTL_SYNC_OMITTED: {
 23570         -      return SQLITE_OK;
 23571         -    }
 23572         -  }
 23573         -  return SQLITE_NOTFOUND;
 23574         -}
 23575         -
 23576         -/*
 23577         -** Return the sector size in bytes of the underlying block device for
 23578         -** the specified file. This is almost always 512 bytes, but may be
 23579         -** larger for some devices.
 23580         -**
 23581         -** SQLite code assumes this function cannot fail. It also assumes that
 23582         -** if two files are created in the same file-system directory (i.e.
 23583         -** a database and its journal file) that the sector size will be the
 23584         -** same for both.
 23585         -*/
 23586         -static int os2SectorSize(sqlite3_file *id){
 23587         -  UNUSED_PARAMETER(id);
 23588         -  return SQLITE_DEFAULT_SECTOR_SIZE;
 23589         -}
 23590         -
 23591         -/*
 23592         -** Return a vector of device characteristics.
 23593         -*/
 23594         -static int os2DeviceCharacteristics(sqlite3_file *id){
 23595         -  UNUSED_PARAMETER(id);
 23596         -  return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN;
 23597         -}
 23598         -
 23599         -
 23600         -/*
 23601         -** Character set conversion objects used by conversion routines.
 23602         -*/
 23603         -static UconvObject ucUtf8 = NULL; /* convert between UTF-8 and UCS-2 */
 23604         -static UconvObject uclCp = NULL;  /* convert between local codepage and UCS-2 */
 23605         -
 23606         -/*
 23607         -** Helper function to initialize the conversion objects from and to UTF-8.
 23608         -*/
 23609         -static void initUconvObjects( void ){
 23610         -  if( UniCreateUconvObject( UTF_8, &ucUtf8 ) != ULS_SUCCESS )
 23611         -    ucUtf8 = NULL;
 23612         -  if ( UniCreateUconvObject( (UniChar *)L"@path=yes", &uclCp ) != ULS_SUCCESS )
 23613         -    uclCp = NULL;
 23614         -}
 23615         -
 23616         -/*
 23617         -** Helper function to free the conversion objects from and to UTF-8.
 23618         -*/
 23619         -static void freeUconvObjects( void ){
 23620         -  if ( ucUtf8 )
 23621         -    UniFreeUconvObject( ucUtf8 );
 23622         -  if ( uclCp )
 23623         -    UniFreeUconvObject( uclCp );
 23624         -  ucUtf8 = NULL;
 23625         -  uclCp = NULL;
 23626         -}
 23627         -
 23628         -/*
 23629         -** Helper function to convert UTF-8 filenames to local OS/2 codepage.
 23630         -** The two-step process: first convert the incoming UTF-8 string
 23631         -** into UCS-2 and then from UCS-2 to the current codepage.
 23632         -** The returned char pointer has to be freed.
 23633         -*/
 23634         -static char *convertUtf8PathToCp( const char *in ){
 23635         -  UniChar tempPath[CCHMAXPATH];
 23636         -  char *out = (char *)calloc( CCHMAXPATH, 1 );
 23637         -
 23638         -  if( !out )
 23639         -    return NULL;
 23640         -
 23641         -  if( !ucUtf8 || !uclCp )
 23642         -    initUconvObjects();
 23643         -
 23644         -  /* determine string for the conversion of UTF-8 which is CP1208 */
 23645         -  if( UniStrToUcs( ucUtf8, tempPath, (char *)in, CCHMAXPATH ) != ULS_SUCCESS )
 23646         -    return out; /* if conversion fails, return the empty string */
 23647         -
 23648         -  /* conversion for current codepage which can be used for paths */
 23649         -  UniStrFromUcs( uclCp, out, tempPath, CCHMAXPATH );
 23650         -
 23651         -  return out;
 23652         -}
 23653         -
 23654         -/*
 23655         -** Helper function to convert filenames from local codepage to UTF-8.
 23656         -** The two-step process: first convert the incoming codepage-specific
 23657         -** string into UCS-2 and then from UCS-2 to the codepage of UTF-8.
 23658         -** The returned char pointer has to be freed.
 23659         -**
 23660         -** This function is non-static to be able to use this in shell.c and
 23661         -** similar applications that take command line arguments.
 23662         -*/
 23663         -char *convertCpPathToUtf8( const char *in ){
 23664         -  UniChar tempPath[CCHMAXPATH];
 23665         -  char *out = (char *)calloc( CCHMAXPATH, 1 );
 23666         -
 23667         -  if( !out )
 23668         -    return NULL;
 23669         -
 23670         -  if( !ucUtf8 || !uclCp )
 23671         -    initUconvObjects();
 23672         -
 23673         -  /* conversion for current codepage which can be used for paths */
 23674         -  if( UniStrToUcs( uclCp, tempPath, (char *)in, CCHMAXPATH ) != ULS_SUCCESS )
 23675         -    return out; /* if conversion fails, return the empty string */
 23676         -
 23677         -  /* determine string for the conversion of UTF-8 which is CP1208 */
 23678         -  UniStrFromUcs( ucUtf8, out, tempPath, CCHMAXPATH );
 23679         -
 23680         -  return out;
 23681         -}
 23682         -
 23683         -
 23684         -#ifndef SQLITE_OMIT_WAL
 23685         -
 23686         -/*
 23687         -** Use main database file for interprocess locking. If un-defined
 23688         -** a separate file is created for this purpose. The file will be
 23689         -** used only to set file locks. There will be no data written to it.
 23690         -*/
 23691         -#define SQLITE_OS2_NO_WAL_LOCK_FILE     
 23692         -
 23693         -#if 0
 23694         -static void _ERR_TRACE( const char *fmt, ... ) {
 23695         -  va_list  ap;
 23696         -  va_start(ap, fmt);
 23697         -  vfprintf(stderr, fmt, ap);
 23698         -  fflush(stderr);
 23699         -}
 23700         -#define ERR_TRACE(rc, msg)        \
 23701         -        if( (rc) != SQLITE_OK ) _ERR_TRACE msg;
 23702         -#else
 23703         -#define ERR_TRACE(rc, msg)
 23704         -#endif
 23705         -
 23706         -/*
 23707         -** Helper functions to obtain and relinquish the global mutex. The
 23708         -** global mutex is used to protect os2ShmNodeList.
 23709         -**
 23710         -** Function os2ShmMutexHeld() is used to assert() that the global mutex 
 23711         -** is held when required. This function is only used as part of assert() 
 23712         -** statements. e.g.
 23713         -**
 23714         -**   os2ShmEnterMutex()
 23715         -**     assert( os2ShmMutexHeld() );
 23716         -**   os2ShmLeaveMutex()
 23717         -*/
 23718         -static void os2ShmEnterMutex(void){
 23719         -  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
 23720         -}
 23721         -static void os2ShmLeaveMutex(void){
 23722         -  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
 23723         -}
 23724         -#ifdef SQLITE_DEBUG
 23725         -static int os2ShmMutexHeld(void) {
 23726         -  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
 23727         -}
 23728         -int GetCurrentProcessId(void) {
 23729         -  PPIB pib;
 23730         -  DosGetInfoBlocks(NULL, &pib);
 23731         -  return (int)pib->pib_ulpid;
 23732         -}
 23733         -#endif
 23734         -
 23735         -/*
 23736         -** Object used to represent a the shared memory area for a single log file.
 23737         -** When multiple threads all reference the same log-summary, each thread has
 23738         -** its own os2File object, but they all point to a single instance of this 
 23739         -** object.  In other words, each log-summary is opened only once per process.
 23740         -**
 23741         -** os2ShmMutexHeld() must be true when creating or destroying
 23742         -** this object or while reading or writing the following fields:
 23743         -**
 23744         -**      nRef
 23745         -**      pNext 
 23746         -**
 23747         -** The following fields are read-only after the object is created:
 23748         -** 
 23749         -**      szRegion
 23750         -**      hLockFile
 23751         -**      shmBaseName
 23752         -**
 23753         -** Either os2ShmNode.mutex must be held or os2ShmNode.nRef==0 and
 23754         -** os2ShmMutexHeld() is true when reading or writing any other field
 23755         -** in this structure.
 23756         -**
 23757         -*/
 23758         -struct os2ShmNode {
 23759         -  sqlite3_mutex *mutex;      /* Mutex to access this object */
 23760         -  os2ShmNode *pNext;         /* Next in list of all os2ShmNode objects */
 23761         -
 23762         -  int szRegion;              /* Size of shared-memory regions */
 23763         -
 23764         -  int nRegion;               /* Size of array apRegion */
 23765         -  void **apRegion;           /* Array of pointers to shared-memory regions */
 23766         -
 23767         -  int nRef;                  /* Number of os2ShmLink objects pointing to this */
 23768         -  os2ShmLink *pFirst;        /* First os2ShmLink object pointing to this */
 23769         -
 23770         -  HFILE hLockFile;           /* File used for inter-process memory locking */
 23771         -  char shmBaseName[1];       /* Name of the memory object !!! must last !!! */
 23772         -};
 23773         -
 23774         -
 23775         -/*
 23776         -** Structure used internally by this VFS to record the state of an
 23777         -** open shared memory connection.
 23778         -**
 23779         -** The following fields are initialized when this object is created and
 23780         -** are read-only thereafter:
 23781         -**
 23782         -**    os2Shm.pShmNode
 23783         -**    os2Shm.id
 23784         -**
 23785         -** All other fields are read/write.  The os2Shm.pShmNode->mutex must be held
 23786         -** while accessing any read/write fields.
 23787         -*/
 23788         -struct os2ShmLink {
 23789         -  os2ShmNode *pShmNode;      /* The underlying os2ShmNode object */
 23790         -  os2ShmLink *pNext;         /* Next os2Shm with the same os2ShmNode */
 23791         -  u32 sharedMask;            /* Mask of shared locks held */
 23792         -  u32 exclMask;              /* Mask of exclusive locks held */
 23793         -#ifdef SQLITE_DEBUG
 23794         -  u8 id;                     /* Id of this connection with its os2ShmNode */
 23795         -#endif
 23796         -};
 23797         -
 23798         -
 23799         -/*
 23800         -** A global list of all os2ShmNode objects.
 23801         -**
 23802         -** The os2ShmMutexHeld() must be true while reading or writing this list.
 23803         -*/
 23804         -static os2ShmNode *os2ShmNodeList = NULL;
 23805         -
 23806         -/*
 23807         -** Constants used for locking
 23808         -*/
 23809         -#ifdef  SQLITE_OS2_NO_WAL_LOCK_FILE
 23810         -#define OS2_SHM_BASE   (PENDING_BYTE + 0x10000)         /* first lock byte */
 23811         -#else
 23812         -#define OS2_SHM_BASE   ((22+SQLITE_SHM_NLOCK)*4)        /* first lock byte */
 23813         -#endif
 23814         -
 23815         -#define OS2_SHM_DMS    (OS2_SHM_BASE+SQLITE_SHM_NLOCK)  /* deadman switch */
 23816         -
 23817         -/*
 23818         -** Apply advisory locks for all n bytes beginning at ofst.
 23819         -*/
 23820         -#define _SHM_UNLCK  1   /* no lock */
 23821         -#define _SHM_RDLCK  2   /* shared lock, no wait */
 23822         -#define _SHM_WRLCK  3   /* exlusive lock, no wait */
 23823         -#define _SHM_WRLCK_WAIT 4 /* exclusive lock, wait */
 23824         -static int os2ShmSystemLock(
 23825         -  os2ShmNode *pNode,    /* Apply locks to this open shared-memory segment */
 23826         -  int lockType,         /* _SHM_UNLCK, _SHM_RDLCK, _SHM_WRLCK or _SHM_WRLCK_WAIT */
 23827         -  int ofst,             /* Offset to first byte to be locked/unlocked */
 23828         -  int nByte             /* Number of bytes to lock or unlock */
 23829         -){
 23830         -  APIRET rc;
 23831         -  FILELOCK area;
 23832         -  ULONG mode, timeout;
 23833         -
 23834         -  /* Access to the os2ShmNode object is serialized by the caller */
 23835         -  assert( sqlite3_mutex_held(pNode->mutex) || pNode->nRef==0 );
 23836         -
 23837         -  mode = 1;     /* shared lock */
 23838         -  timeout = 0;  /* no wait */
 23839         -  area.lOffset = ofst;
 23840         -  area.lRange = nByte;
 23841         -
 23842         -  switch( lockType ) {
 23843         -    case _SHM_WRLCK_WAIT:
 23844         -      timeout = (ULONG)-1;      /* wait forever */
 23845         -    case _SHM_WRLCK:
 23846         -      mode = 0;                 /* exclusive lock */
 23847         -    case _SHM_RDLCK:
 23848         -      rc = DosSetFileLocks(pNode->hLockFile, 
 23849         -                           NULL, &area, timeout, mode);
 23850         -      break;
 23851         -    /* case _SHM_UNLCK: */
 23852         -    default:
 23853         -      rc = DosSetFileLocks(pNode->hLockFile, 
 23854         -                           &area, NULL, 0, 0);
 23855         -      break;
 23856         -  }
 23857         -                          
 23858         -  OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n", 
 23859         -           pNode->hLockFile,
 23860         -           rc==SQLITE_OK ? "ok" : "failed",
 23861         -           lockType==_SHM_UNLCK ? "Unlock" : "Lock",
 23862         -           rc));
 23863         -
 23864         -  ERR_TRACE(rc, ("os2ShmSystemLock: %d %s\n", rc, pNode->shmBaseName))
 23865         -
 23866         -  return ( rc == 0 ) ?  SQLITE_OK : SQLITE_BUSY;
 23867         -}
 23868         -
 23869         -/*
 23870         -** Find an os2ShmNode in global list or allocate a new one, if not found.
 23871         -**
 23872         -** This is not a VFS shared-memory method; it is a utility function called
 23873         -** by VFS shared-memory methods.
 23874         -*/
 23875         -static int os2OpenSharedMemory( os2File *fd, int szRegion ) {
 23876         -  os2ShmLink *pLink;
 23877         -  os2ShmNode *pNode;
 23878         -  int cbShmName, rc = SQLITE_OK;
 23879         -  char shmName[CCHMAXPATH + 30];
 23880         -#ifndef SQLITE_OS2_NO_WAL_LOCK_FILE
 23881         -  ULONG action;
 23882         -#endif
 23883         -  
 23884         -  /* We need some additional space at the end to append the region number */
 23885         -  cbShmName = sprintf(shmName, "\\SHAREMEM\\%s", fd->zFullPathCp );
 23886         -  if( cbShmName >= CCHMAXPATH-8 )
 23887         -    return SQLITE_IOERR_SHMOPEN; 
 23888         -
 23889         -  /* Replace colon in file name to form a valid shared memory name */
 23890         -  shmName[10+1] = '!';
 23891         -
 23892         -  /* Allocate link object (we free it later in case of failure) */
 23893         -  pLink = sqlite3_malloc( sizeof(*pLink) );
 23894         -  if( !pLink )
 23895         -    return SQLITE_NOMEM;
 23896         -
 23897         -  /* Access node list */
 23898         -  os2ShmEnterMutex();
 23899         -
 23900         -  /* Find node by it's shared memory base name */
 23901         -  for( pNode = os2ShmNodeList; 
 23902         -       pNode && stricmp(shmName, pNode->shmBaseName) != 0; 
 23903         -       pNode = pNode->pNext )   ;
 23904         -
 23905         -  /* Not found: allocate a new node */
 23906         -  if( !pNode ) {
 23907         -    pNode = sqlite3_malloc( sizeof(*pNode) + cbShmName );
 23908         -    if( pNode ) {
 23909         -      memset(pNode, 0, sizeof(*pNode) );
 23910         -      pNode->szRegion = szRegion;
 23911         -      pNode->hLockFile = (HFILE)-1;      
 23912         -      strcpy(pNode->shmBaseName, shmName);
 23913         -
 23914         -#ifdef SQLITE_OS2_NO_WAL_LOCK_FILE
 23915         -      if( DosDupHandle(fd->h, &pNode->hLockFile) != 0 ) {
 23916         -#else
 23917         -      sprintf(shmName, "%s-lck", fd->zFullPathCp);
 23918         -      if( DosOpen((PSZ)shmName, &pNode->hLockFile, &action, 0, FILE_NORMAL, 
 23919         -                  OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW,
 23920         -                  OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | 
 23921         -                  OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR,
 23922         -                  NULL) != 0 ) {
 23923         -#endif
 23924         -        sqlite3_free(pNode);  
 23925         -        rc = SQLITE_IOERR;
 23926         -      } else {
 23927         -        pNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
 23928         -        if( !pNode->mutex ) {
 23929         -          sqlite3_free(pNode);  
 23930         -          rc = SQLITE_NOMEM;
 23931         -        }
 23932         -      }   
 23933         -    } else {
 23934         -      rc = SQLITE_NOMEM;
 23935         -    }
 23936         -    
 23937         -    if( rc == SQLITE_OK ) {
 23938         -      pNode->pNext = os2ShmNodeList;
 23939         -      os2ShmNodeList = pNode;
 23940         -    } else {
 23941         -      pNode = NULL;
 23942         -    }
 23943         -  } else if( pNode->szRegion != szRegion ) {
 23944         -    rc = SQLITE_IOERR_SHMSIZE;
 23945         -    pNode = NULL;
 23946         -  }
 23947         -
 23948         -  if( pNode ) {
 23949         -    sqlite3_mutex_enter(pNode->mutex);
 23950         -
 23951         -    memset(pLink, 0, sizeof(*pLink));
 23952         -
 23953         -    pLink->pShmNode = pNode;
 23954         -    pLink->pNext = pNode->pFirst;
 23955         -    pNode->pFirst = pLink;
 23956         -    pNode->nRef++;
 23957         -
 23958         -    fd->pShmLink = pLink;
 23959         -
 23960         -    sqlite3_mutex_leave(pNode->mutex);
 23961         -    
 23962         -  } else {
 23963         -    /* Error occured. Free our link object. */
 23964         -    sqlite3_free(pLink);  
 23965         -  }
 23966         -
 23967         -  os2ShmLeaveMutex();
 23968         -
 23969         -  ERR_TRACE(rc, ("os2OpenSharedMemory: %d  %s\n", rc, fd->zFullPathCp))  
 23970         -  
 23971         -  return rc;
 23972         -}
 23973         -
 23974         -/*
 23975         -** Purge the os2ShmNodeList list of all entries with nRef==0.
 23976         -**
 23977         -** This is not a VFS shared-memory method; it is a utility function called
 23978         -** by VFS shared-memory methods.
 23979         -*/
 23980         -static void os2PurgeShmNodes( int deleteFlag ) {
 23981         -  os2ShmNode *pNode;
 23982         -  os2ShmNode **ppNode;
 23983         -
 23984         -  os2ShmEnterMutex();
 23985         -  
 23986         -  ppNode = &os2ShmNodeList;
 23987         -
 23988         -  while( *ppNode ) {
 23989         -    pNode = *ppNode;
 23990         -
 23991         -    if( pNode->nRef == 0 ) {
 23992         -      *ppNode = pNode->pNext;   
 23993         -     
 23994         -      if( pNode->apRegion ) {
 23995         -        /* Prevent other processes from resizing the shared memory */
 23996         -        os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1);
 23997         -
 23998         -        while( pNode->nRegion-- ) {
 23999         -#ifdef SQLITE_DEBUG
 24000         -          int rc = 
 24001         -#endif          
 24002         -          DosFreeMem(pNode->apRegion[pNode->nRegion]);
 24003         -
 24004         -          OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n",
 24005         -                  (int)GetCurrentProcessId(), pNode->nRegion,
 24006         -                  rc == 0 ? "ok" : "failed"));
 24007         -        }
 24008         -
 24009         -        /* Allow other processes to resize the shared memory */
 24010         -        os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1);
 24011         -
 24012         -        sqlite3_free(pNode->apRegion);
 24013         -      }  
 24014         -
 24015         -      DosClose(pNode->hLockFile);
 24016         -      
 24017         -#ifndef SQLITE_OS2_NO_WAL_LOCK_FILE
 24018         -      if( deleteFlag ) {
 24019         -         char fileName[CCHMAXPATH];
 24020         -         /* Skip "\\SHAREMEM\\" */
 24021         -         sprintf(fileName, "%s-lck", pNode->shmBaseName + 10);
 24022         -         /* restore colon */
 24023         -         fileName[1] = ':';
 24024         -         
 24025         -         DosForceDelete(fileName); 
 24026         -      }
 24027         -#endif
 24028         -
 24029         -      sqlite3_mutex_free(pNode->mutex);
 24030         -
 24031         -      sqlite3_free(pNode);
 24032         -      
 24033         -    } else {
 24034         -      ppNode = &pNode->pNext;
 24035         -    }
 24036         -  } 
 24037         -
 24038         -  os2ShmLeaveMutex();
 24039         -}
 24040         -
 24041         -/*
 24042         -** This function is called to obtain a pointer to region iRegion of the
 24043         -** shared-memory associated with the database file id. Shared-memory regions
 24044         -** are numbered starting from zero. Each shared-memory region is szRegion
 24045         -** bytes in size.
 24046         -**
 24047         -** If an error occurs, an error code is returned and *pp is set to NULL.
 24048         -**
 24049         -** Otherwise, if the bExtend parameter is 0 and the requested shared-memory
 24050         -** region has not been allocated (by any client, including one running in a
 24051         -** separate process), then *pp is set to NULL and SQLITE_OK returned. If
 24052         -** bExtend is non-zero and the requested shared-memory region has not yet
 24053         -** been allocated, it is allocated by this function.
 24054         -**
 24055         -** If the shared-memory region has already been allocated or is allocated by
 24056         -** this call as described above, then it is mapped into this processes
 24057         -** address space (if it is not already), *pp is set to point to the mapped
 24058         -** memory and SQLITE_OK returned.
 24059         -*/
 24060         -static int os2ShmMap(
 24061         -  sqlite3_file *id,               /* Handle open on database file */
 24062         -  int iRegion,                    /* Region to retrieve */
 24063         -  int szRegion,                   /* Size of regions */
 24064         -  int bExtend,                    /* True to extend block if necessary */
 24065         -  void volatile **pp              /* OUT: Mapped memory */
 24066         -){
 24067         -  PVOID pvTemp;
 24068         -  void **apRegion;
 24069         -  os2ShmNode *pNode;
 24070         -  int n, rc = SQLITE_OK;
 24071         -  char shmName[CCHMAXPATH];
 24072         -  os2File *pFile = (os2File*)id;
 24073         -  
 24074         -  *pp = NULL;
 24075         -
 24076         -  if( !pFile->pShmLink )
 24077         -    rc = os2OpenSharedMemory( pFile, szRegion );
 24078         -  
 24079         -  if( rc == SQLITE_OK ) {
 24080         -    pNode = pFile->pShmLink->pShmNode ;
 24081         -    
 24082         -    sqlite3_mutex_enter(pNode->mutex);
 24083         -    
 24084         -    assert( szRegion==pNode->szRegion );
 24085         -
 24086         -    /* Unmapped region ? */
 24087         -    if( iRegion >= pNode->nRegion ) {
 24088         -      /* Prevent other processes from resizing the shared memory */
 24089         -      os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1);
 24090         -
 24091         -      apRegion = sqlite3_realloc(
 24092         -        pNode->apRegion, (iRegion + 1) * sizeof(apRegion[0]));
 24093         -
 24094         -      if( apRegion ) {
 24095         -        pNode->apRegion = apRegion;
 24096         -
 24097         -        while( pNode->nRegion <= iRegion ) {
 24098         -          sprintf(shmName, "%s-%u", 
 24099         -                  pNode->shmBaseName, pNode->nRegion);
 24100         -
 24101         -          if( DosGetNamedSharedMem(&pvTemp, (PSZ)shmName, 
 24102         -                PAG_READ | PAG_WRITE) != NO_ERROR ) {
 24103         -            if( !bExtend )
 24104         -              break;
 24105         -
 24106         -            if( DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion,
 24107         -                  PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_ANY) != NO_ERROR && 
 24108         -                DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion,
 24109         -                  PAG_READ | PAG_WRITE | PAG_COMMIT) != NO_ERROR ) { 
 24110         -              rc = SQLITE_NOMEM;
 24111         -              break;
 24112         -            }
 24113         -          }
 24114         -
 24115         -          apRegion[pNode->nRegion++] = pvTemp;
 24116         -        }
 24117         -
 24118         -        /* zero out remaining entries */ 
 24119         -        for( n = pNode->nRegion; n <= iRegion; n++ )
 24120         -          pNode->apRegion[n] = NULL;
 24121         -
 24122         -        /* Return this region (maybe zero) */
 24123         -        *pp = pNode->apRegion[iRegion];
 24124         -      } else {
 24125         -        rc = SQLITE_NOMEM;
 24126         -      }
 24127         -
 24128         -      /* Allow other processes to resize the shared memory */
 24129         -      os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1);
 24130         -      
 24131         -    } else {
 24132         -      /* Region has been mapped previously */
 24133         -      *pp = pNode->apRegion[iRegion];
 24134         -    }
 24135         -
 24136         -    sqlite3_mutex_leave(pNode->mutex);
 24137         -  } 
 24138         -
 24139         -  ERR_TRACE(rc, ("os2ShmMap: %s iRgn = %d, szRgn = %d, bExt = %d : %d\n", 
 24140         -                 pFile->zFullPathCp, iRegion, szRegion, bExtend, rc))
 24141         -          
 24142         -  return rc;
 24143         -}
 24144         -
 24145         -/*
 24146         -** Close a connection to shared-memory.  Delete the underlying
 24147         -** storage if deleteFlag is true.
 24148         -**
 24149         -** If there is no shared memory associated with the connection then this
 24150         -** routine is a harmless no-op.
 24151         -*/
 24152         -static int os2ShmUnmap(
 24153         -  sqlite3_file *id,               /* The underlying database file */
 24154         -  int deleteFlag                  /* Delete shared-memory if true */
 24155         -){
 24156         -  os2File *pFile = (os2File*)id;
 24157         -  os2ShmLink *pLink = pFile->pShmLink;
 24158         -  
 24159         -  if( pLink ) {
 24160         -    int nRef = -1;
 24161         -    os2ShmLink **ppLink;
 24162         -    os2ShmNode *pNode = pLink->pShmNode;
 24163         -
 24164         -    sqlite3_mutex_enter(pNode->mutex);
 24165         -    
 24166         -    for( ppLink = &pNode->pFirst;
 24167         -         *ppLink && *ppLink != pLink;
 24168         -         ppLink = &(*ppLink)->pNext )   ;
 24169         -         
 24170         -    assert(*ppLink);
 24171         -
 24172         -    if( *ppLink ) {
 24173         -      *ppLink = pLink->pNext;
 24174         -      nRef = --pNode->nRef;
 24175         -    } else {
 24176         -      ERR_TRACE(1, ("os2ShmUnmap: link not found ! %s\n", 
 24177         -                    pNode->shmBaseName))
 24178         -    }
 24179         -    
 24180         -    pFile->pShmLink = NULL;
 24181         -    sqlite3_free(pLink);
 24182         -
 24183         -    sqlite3_mutex_leave(pNode->mutex);
 24184         -    
 24185         -    if( nRef == 0 )
 24186         -      os2PurgeShmNodes( deleteFlag );
 24187         -  }
 24188         -
 24189         -  return SQLITE_OK;
 24190         -}
 24191         -
 24192         -/*
 24193         -** Change the lock state for a shared-memory segment.
 24194         -**
 24195         -** Note that the relationship between SHAREd and EXCLUSIVE locks is a little
 24196         -** different here than in posix.  In xShmLock(), one can go from unlocked
 24197         -** to shared and back or from unlocked to exclusive and back.  But one may
 24198         -** not go from shared to exclusive or from exclusive to shared.
 24199         -*/
 24200         -static int os2ShmLock(
 24201         -  sqlite3_file *id,          /* Database file holding the shared memory */
 24202         -  int ofst,                  /* First lock to acquire or release */
 24203         -  int n,                     /* Number of locks to acquire or release */
 24204         -  int flags                  /* What to do with the lock */
 24205         -){
 24206         -  u32 mask;                             /* Mask of locks to take or release */
 24207         -  int rc = SQLITE_OK;                   /* Result code */
 24208         -  os2File *pFile = (os2File*)id;
 24209         -  os2ShmLink *p = pFile->pShmLink;      /* The shared memory being locked */
 24210         -  os2ShmLink *pX;                       /* For looping over all siblings */
 24211         -  os2ShmNode *pShmNode = p->pShmNode;   /* Our node */
 24212         -  
 24213         -  assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
 24214         -  assert( n>=1 );
 24215         -  assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
 24216         -       || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
 24217         -       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
 24218         -       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
 24219         -  assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
 24220         -
 24221         -  mask = (u32)((1U<<(ofst+n)) - (1U<<ofst));
 24222         -  assert( n>1 || mask==(1<<ofst) );
 24223         -
 24224         -
 24225         -  sqlite3_mutex_enter(pShmNode->mutex);
 24226         -
 24227         -  if( flags & SQLITE_SHM_UNLOCK ){
 24228         -    u32 allMask = 0; /* Mask of locks held by siblings */
 24229         -
 24230         -    /* See if any siblings hold this same lock */
 24231         -    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
 24232         -      if( pX==p ) continue;
 24233         -      assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
 24234         -      allMask |= pX->sharedMask;
 24235         -    }
 24236         -
 24237         -    /* Unlock the system-level locks */
 24238         -    if( (mask & allMask)==0 ){
 24239         -      rc = os2ShmSystemLock(pShmNode, _SHM_UNLCK, ofst+OS2_SHM_BASE, n);
 24240         -    }else{
 24241         -      rc = SQLITE_OK;
 24242         -    }
 24243         -
 24244         -    /* Undo the local locks */
 24245         -    if( rc==SQLITE_OK ){
 24246         -      p->exclMask &= ~mask;
 24247         -      p->sharedMask &= ~mask;
 24248         -    } 
 24249         -  }else if( flags & SQLITE_SHM_SHARED ){
 24250         -    u32 allShared = 0;  /* Union of locks held by connections other than "p" */
 24251         -
 24252         -    /* Find out which shared locks are already held by sibling connections.
 24253         -    ** If any sibling already holds an exclusive lock, go ahead and return
 24254         -    ** SQLITE_BUSY.
 24255         -    */
 24256         -    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
 24257         -      if( (pX->exclMask & mask)!=0 ){
 24258         -        rc = SQLITE_BUSY;
 24259         -        break;
 24260         -      }
 24261         -      allShared |= pX->sharedMask;
 24262         -    }
 24263         -
 24264         -    /* Get shared locks at the system level, if necessary */
 24265         -    if( rc==SQLITE_OK ){
 24266         -      if( (allShared & mask)==0 ){
 24267         -        rc = os2ShmSystemLock(pShmNode, _SHM_RDLCK, ofst+OS2_SHM_BASE, n);
 24268         -      }else{
 24269         -        rc = SQLITE_OK;
 24270         -      }
 24271         -    }
 24272         -
 24273         -    /* Get the local shared locks */
 24274         -    if( rc==SQLITE_OK ){
 24275         -      p->sharedMask |= mask;
 24276         -    }
 24277         -  }else{
 24278         -    /* Make sure no sibling connections hold locks that will block this
 24279         -    ** lock.  If any do, return SQLITE_BUSY right away.
 24280         -    */
 24281         -    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
 24282         -      if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
 24283         -        rc = SQLITE_BUSY;
 24284         -        break;
 24285         -      }
 24286         -    }
 24287         -  
 24288         -    /* Get the exclusive locks at the system level.  Then if successful
 24289         -    ** also mark the local connection as being locked.
 24290         -    */
 24291         -    if( rc==SQLITE_OK ){
 24292         -      rc = os2ShmSystemLock(pShmNode, _SHM_WRLCK, ofst+OS2_SHM_BASE, n);
 24293         -      if( rc==SQLITE_OK ){
 24294         -        assert( (p->sharedMask & mask)==0 );
 24295         -        p->exclMask |= mask;
 24296         -      }
 24297         -    }
 24298         -  }
 24299         -
 24300         -  sqlite3_mutex_leave(pShmNode->mutex);
 24301         -  
 24302         -  OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n",
 24303         -           p->id, (int)GetCurrentProcessId(), p->sharedMask, p->exclMask,
 24304         -           rc ? "failed" : "ok"));
 24305         -
 24306         -  ERR_TRACE(rc, ("os2ShmLock: ofst = %d, n = %d, flags = 0x%x -> %d \n", 
 24307         -                 ofst, n, flags, rc))
 24308         -                  
 24309         -  return rc; 
 24310         -}
 24311         -
 24312         -/*
 24313         -** Implement a memory barrier or memory fence on shared memory.
 24314         -**
 24315         -** All loads and stores begun before the barrier must complete before
 24316         -** any load or store begun after the barrier.
 24317         -*/
 24318         -static void os2ShmBarrier(
 24319         -  sqlite3_file *id                /* Database file holding the shared memory */
 24320         -){
 24321         -  UNUSED_PARAMETER(id);
 24322         -  os2ShmEnterMutex();
 24323         -  os2ShmLeaveMutex();
 24324         -}
 24325         -
 24326         -#else
 24327         -# define os2ShmMap     0
 24328         -# define os2ShmLock    0
 24329         -# define os2ShmBarrier 0
 24330         -# define os2ShmUnmap   0
 24331         -#endif /* #ifndef SQLITE_OMIT_WAL */
 24332         -
 24333         -
 24334         -/*
 24335         -** This vector defines all the methods that can operate on an
 24336         -** sqlite3_file for os2.
 24337         -*/
 24338         -static const sqlite3_io_methods os2IoMethod = {
 24339         -  2,                              /* iVersion */
 24340         -  os2Close,                       /* xClose */
 24341         -  os2Read,                        /* xRead */
 24342         -  os2Write,                       /* xWrite */
 24343         -  os2Truncate,                    /* xTruncate */
 24344         -  os2Sync,                        /* xSync */
 24345         -  os2FileSize,                    /* xFileSize */
 24346         -  os2Lock,                        /* xLock */
 24347         -  os2Unlock,                      /* xUnlock */
 24348         -  os2CheckReservedLock,           /* xCheckReservedLock */
 24349         -  os2FileControl,                 /* xFileControl */
 24350         -  os2SectorSize,                  /* xSectorSize */
 24351         -  os2DeviceCharacteristics,       /* xDeviceCharacteristics */
 24352         -  os2ShmMap,                      /* xShmMap */
 24353         -  os2ShmLock,                     /* xShmLock */
 24354         -  os2ShmBarrier,                  /* xShmBarrier */
 24355         -  os2ShmUnmap                     /* xShmUnmap */
 24356         -};
 24357         -
 24358         -
 24359         -/***************************************************************************
 24360         -** Here ends the I/O methods that form the sqlite3_io_methods object.
 24361         -**
 24362         -** The next block of code implements the VFS methods.
 24363         -****************************************************************************/
 24364         -
 24365         -/*
 24366         -** Create a temporary file name in zBuf.  zBuf must be big enough to
 24367         -** hold at pVfs->mxPathname characters.
 24368         -*/
 24369         -static int getTempname(int nBuf, char *zBuf ){
 24370         -  static const char zChars[] =
 24371         -    "abcdefghijklmnopqrstuvwxyz"
 24372         -    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 24373         -    "0123456789";
 24374         -  int i, j;
 24375         -  PSZ zTempPathCp;      
 24376         -  char zTempPath[CCHMAXPATH];
 24377         -  ULONG ulDriveNum, ulDriveMap;
 24378         -  
 24379         -  /* It's odd to simulate an io-error here, but really this is just
 24380         -  ** using the io-error infrastructure to test that SQLite handles this
 24381         -  ** function failing. 
 24382         -  */
 24383         -  SimulateIOError( return SQLITE_IOERR );
 24384         -
 24385         -  if( sqlite3_temp_directory ) {
 24386         -    sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", sqlite3_temp_directory);
 24387         -  } else if( DosScanEnv( (PSZ)"TEMP",   &zTempPathCp ) == NO_ERROR ||
 24388         -             DosScanEnv( (PSZ)"TMP",    &zTempPathCp ) == NO_ERROR ||
 24389         -             DosScanEnv( (PSZ)"TMPDIR", &zTempPathCp ) == NO_ERROR ) {
 24390         -    char *zTempPathUTF = convertCpPathToUtf8( (char *)zTempPathCp );
 24391         -    sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", zTempPathUTF);
 24392         -    free( zTempPathUTF );
 24393         -  } else if( DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ) == NO_ERROR ) {
 24394         -    zTempPath[0] = (char)('A' + ulDriveNum - 1);
 24395         -    zTempPath[1] = ':'; 
 24396         -    zTempPath[2] = '\0'; 
 24397         -  } else {
 24398         -    zTempPath[0] = '\0'; 
 24399         -  }
 24400         -  
 24401         -  /* Strip off a trailing slashes or backslashes, otherwise we would get *
 24402         -   * multiple (back)slashes which causes DosOpen() to fail.              *
 24403         -   * Trailing spaces are not allowed, either.                            */
 24404         -  j = sqlite3Strlen30(zTempPath);
 24405         -  while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/' || 
 24406         -                    zTempPath[j-1] == ' ' ) ){
 24407         -    j--;
 24408         -  }
 24409         -  zTempPath[j] = '\0';
 24410         -  
 24411         -  /* We use 20 bytes to randomize the name */
 24412         -  sqlite3_snprintf(nBuf-22, zBuf,
 24413         -                   "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
 24414         -  j = sqlite3Strlen30(zBuf);
 24415         -  sqlite3_randomness( 20, &zBuf[j] );
 24416         -  for( i = 0; i < 20; i++, j++ ){
 24417         -    zBuf[j] = zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
 24418         -  }
 24419         -  zBuf[j] = 0;
 24420         -
 24421         -  OSTRACE(( "TEMP FILENAME: %s\n", zBuf ));
 24422         -  return SQLITE_OK;
 24423         -}
 24424         -
 24425         -
 24426         -/*
 24427         -** Turn a relative pathname into a full pathname.  Write the full
 24428         -** pathname into zFull[].  zFull[] will be at least pVfs->mxPathname
 24429         -** bytes in size.
 24430         -*/
 24431         -static int os2FullPathname(
 24432         -  sqlite3_vfs *pVfs,          /* Pointer to vfs object */
 24433         -  const char *zRelative,      /* Possibly relative input path */
 24434         -  int nFull,                  /* Size of output buffer in bytes */
 24435         -  char *zFull                 /* Output buffer */
 24436         -){
 24437         -  char *zRelativeCp = convertUtf8PathToCp( zRelative );
 24438         -  char zFullCp[CCHMAXPATH] = "\0";
 24439         -  char *zFullUTF;
 24440         -  APIRET rc = DosQueryPathInfo( (PSZ)zRelativeCp, FIL_QUERYFULLNAME, 
 24441         -                                zFullCp, CCHMAXPATH );
 24442         -  free( zRelativeCp );
 24443         -  zFullUTF = convertCpPathToUtf8( zFullCp );
 24444         -  sqlite3_snprintf( nFull, zFull, zFullUTF );
 24445         -  free( zFullUTF );
 24446         -  return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
 24447         -}
 24448         -
 24449         -
 24450         -/*
 24451         -** Open a file.
 24452         -*/
 24453         -static int os2Open(
 24454         -  sqlite3_vfs *pVfs,            /* Not used */
 24455         -  const char *zName,            /* Name of the file (UTF-8) */
 24456         -  sqlite3_file *id,             /* Write the SQLite file handle here */
 24457         -  int flags,                    /* Open mode flags */
 24458         -  int *pOutFlags                /* Status return flags */
 24459         -){
 24460         -  HFILE h;
 24461         -  ULONG ulOpenFlags = 0;
 24462         -  ULONG ulOpenMode = 0;
 24463         -  ULONG ulAction = 0;
 24464         -  ULONG rc;
 24465         -  os2File *pFile = (os2File*)id;
 24466         -  const char *zUtf8Name = zName;
 24467         -  char *zNameCp;
 24468         -  char  zTmpname[CCHMAXPATH];
 24469         -
 24470         -  int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
 24471         -  int isCreate     = (flags & SQLITE_OPEN_CREATE);
 24472         -  int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
 24473         -#ifndef NDEBUG
 24474         -  int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
 24475         -  int isReadonly   = (flags & SQLITE_OPEN_READONLY);
 24476         -  int eType        = (flags & 0xFFFFFF00);
 24477         -  int isOpenJournal = (isCreate && (
 24478         -        eType==SQLITE_OPEN_MASTER_JOURNAL 
 24479         -     || eType==SQLITE_OPEN_MAIN_JOURNAL 
 24480         -     || eType==SQLITE_OPEN_WAL
 24481         -  ));
 24482         -#endif
 24483         -
 24484         -  UNUSED_PARAMETER(pVfs);
 24485         -  assert( id!=0 );
 24486         -
 24487         -  /* Check the following statements are true: 
 24488         -  **
 24489         -  **   (a) Exactly one of the READWRITE and READONLY flags must be set, and 
 24490         -  **   (b) if CREATE is set, then READWRITE must also be set, and
 24491         -  **   (c) if EXCLUSIVE is set, then CREATE must also be set.
 24492         -  **   (d) if DELETEONCLOSE is set, then CREATE must also be set.
 24493         -  */
 24494         -  assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
 24495         -  assert(isCreate==0 || isReadWrite);
 24496         -  assert(isExclusive==0 || isCreate);
 24497         -  assert(isDelete==0 || isCreate);
 24498         -
 24499         -  /* The main DB, main journal, WAL file and master journal are never 
 24500         -  ** automatically deleted. Nor are they ever temporary files.  */
 24501         -  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
 24502         -  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
 24503         -  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
 24504         -  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL );
 24505         -
 24506         -  /* Assert that the upper layer has set one of the "file-type" flags. */
 24507         -  assert( eType==SQLITE_OPEN_MAIN_DB      || eType==SQLITE_OPEN_TEMP_DB 
 24508         -       || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL 
 24509         -       || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_MASTER_JOURNAL 
 24510         -       || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
 24511         -  );
 24512         -
 24513         -  memset( pFile, 0, sizeof(*pFile) );
 24514         -  pFile->h = (HFILE)-1;
 24515         -
 24516         -  /* If the second argument to this function is NULL, generate a 
 24517         -  ** temporary file name to use 
 24518         -  */
 24519         -  if( !zUtf8Name ){
 24520         -    assert(isDelete && !isOpenJournal);
 24521         -    rc = getTempname(CCHMAXPATH, zTmpname);
 24522         -    if( rc!=SQLITE_OK ){
 24523         -      return rc;
 24524         -    }
 24525         -    zUtf8Name = zTmpname;
 24526         -  }
 24527         -
 24528         -  if( isReadWrite ){
 24529         -    ulOpenMode |= OPEN_ACCESS_READWRITE;
 24530         -  }else{
 24531         -    ulOpenMode |= OPEN_ACCESS_READONLY;
 24532         -  }
 24533         -
 24534         -  /* Open in random access mode for possibly better speed.  Allow full
 24535         -  ** sharing because file locks will provide exclusive access when needed.
 24536         -  ** The handle should not be inherited by child processes and we don't 
 24537         -  ** want popups from the critical error handler.
 24538         -  */
 24539         -  ulOpenMode |= OPEN_FLAGS_RANDOM | OPEN_SHARE_DENYNONE | 
 24540         -                OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR;
 24541         -
 24542         -  /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is 
 24543         -  ** created. SQLite doesn't use it to indicate "exclusive access" 
 24544         -  ** as it is usually understood.
 24545         -  */
 24546         -  if( isExclusive ){
 24547         -    /* Creates a new file, only if it does not already exist. */
 24548         -    /* If the file exists, it fails. */
 24549         -    ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_FAIL_IF_EXISTS;
 24550         -  }else if( isCreate ){
 24551         -    /* Open existing file, or create if it doesn't exist */
 24552         -    ulOpenFlags |= OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
 24553         -  }else{
 24554         -    /* Opens a file, only if it exists. */
 24555         -    ulOpenFlags |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
 24556         -  }
 24557         -
 24558         -  zNameCp = convertUtf8PathToCp( zUtf8Name );
 24559         -  rc = DosOpen( (PSZ)zNameCp,
 24560         -                &h,
 24561         -                &ulAction,
 24562         -                0L,
 24563         -                FILE_NORMAL,
 24564         -                ulOpenFlags,
 24565         -                ulOpenMode,
 24566         -                (PEAOP2)NULL );
 24567         -  free( zNameCp );
 24568         -
 24569         -  if( rc != NO_ERROR ){
 24570         -    OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulFlags=%#lx, ulMode=%#lx\n",
 24571         -              rc, zUtf8Name, ulAction, ulOpenFlags, ulOpenMode ));
 24572         -
 24573         -    if( isReadWrite ){
 24574         -      return os2Open( pVfs, zName, id,
 24575         -                      ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
 24576         -                      pOutFlags );
 24577         -    }else{
 24578         -      return SQLITE_CANTOPEN;
 24579         -    }
 24580         -  }
 24581         -
 24582         -  if( pOutFlags ){
 24583         -    *pOutFlags = isReadWrite ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY;
 24584         -  }
 24585         -
 24586         -  os2FullPathname( pVfs, zUtf8Name, sizeof( zTmpname ), zTmpname );
 24587         -  pFile->zFullPathCp = convertUtf8PathToCp( zTmpname );
 24588         -  pFile->pMethod = &os2IoMethod;
 24589         -  pFile->flags = flags;
 24590         -  pFile->h = h;
 24591         -
 24592         -  OpenCounter(+1);
 24593         -  OSTRACE(( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags ));
 24594         -  return SQLITE_OK;
 24595         -}
 24596         -
 24597         -/*
 24598         -** Delete the named file.
 24599         -*/
 24600         -static int os2Delete(
 24601         -  sqlite3_vfs *pVfs,                     /* Not used on os2 */
 24602         -  const char *zFilename,                 /* Name of file to delete */
 24603         -  int syncDir                            /* Not used on os2 */
 24604         -){
 24605         -  APIRET rc;
 24606         -  char *zFilenameCp;
 24607         -  SimulateIOError( return SQLITE_IOERR_DELETE );
 24608         -  zFilenameCp = convertUtf8PathToCp( zFilename );
 24609         -  rc = DosDelete( (PSZ)zFilenameCp );
 24610         -  free( zFilenameCp );
 24611         -  OSTRACE(( "DELETE \"%s\"\n", zFilename ));
 24612         -  return (rc == NO_ERROR ||
 24613         -          rc == ERROR_FILE_NOT_FOUND ||
 24614         -          rc == ERROR_PATH_NOT_FOUND ) ? SQLITE_OK : SQLITE_IOERR_DELETE;
 24615         -}
 24616         -
 24617         -/*
 24618         -** Check the existance and status of a file.
 24619         -*/
 24620         -static int os2Access(
 24621         -  sqlite3_vfs *pVfs,        /* Not used on os2 */
 24622         -  const char *zFilename,    /* Name of file to check */
 24623         -  int flags,                /* Type of test to make on this file */
 24624         -  int *pOut                 /* Write results here */
 24625         -){
 24626         -  APIRET rc;
 24627         -  FILESTATUS3 fsts3ConfigInfo;
 24628         -  char *zFilenameCp;
 24629         -
 24630         -  UNUSED_PARAMETER(pVfs);
 24631         -  SimulateIOError( return SQLITE_IOERR_ACCESS; );
 24632         -  
 24633         -  zFilenameCp = convertUtf8PathToCp( zFilename );
 24634         -  rc = DosQueryPathInfo( (PSZ)zFilenameCp, FIL_STANDARD,
 24635         -                         &fsts3ConfigInfo, sizeof(FILESTATUS3) );
 24636         -  free( zFilenameCp );
 24637         -  OSTRACE(( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n",
 24638         -            fsts3ConfigInfo.attrFile, flags, rc ));
 24639         -
 24640         -  switch( flags ){
 24641         -    case SQLITE_ACCESS_EXISTS:
 24642         -      /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
 24643         -      ** as if it does not exist.
 24644         -      */
 24645         -      if( fsts3ConfigInfo.cbFile == 0 ) 
 24646         -        rc = ERROR_FILE_NOT_FOUND;
 24647         -      break;
 24648         -    case SQLITE_ACCESS_READ:
 24649         -      break;
 24650         -    case SQLITE_ACCESS_READWRITE:
 24651         -      if( fsts3ConfigInfo.attrFile & FILE_READONLY )
 24652         -        rc = ERROR_ACCESS_DENIED;
 24653         -      break;
 24654         -    default:
 24655         -      rc = ERROR_FILE_NOT_FOUND;
 24656         -      assert( !"Invalid flags argument" );
 24657         -  }
 24658         -
 24659         -  *pOut = (rc == NO_ERROR);
 24660         -  OSTRACE(( "ACCESS %s flags %d: rc=%d\n", zFilename, flags, *pOut ));
 24661         -
 24662         -  return SQLITE_OK;
 24663         -}
 24664         -
 24665         -
 24666         -#ifndef SQLITE_OMIT_LOAD_EXTENSION
 24667         -/*
 24668         -** Interfaces for opening a shared library, finding entry points
 24669         -** within the shared library, and closing the shared library.
 24670         -*/
 24671         -/*
 24672         -** Interfaces for opening a shared library, finding entry points
 24673         -** within the shared library, and closing the shared library.
 24674         -*/
 24675         -static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){
 24676         -  HMODULE hmod;
 24677         -  APIRET rc;
 24678         -  char *zFilenameCp = convertUtf8PathToCp(zFilename);
 24679         -  rc = DosLoadModule(NULL, 0, (PSZ)zFilenameCp, &hmod);
 24680         -  free(zFilenameCp);
 24681         -  return rc != NO_ERROR ? 0 : (void*)hmod;
 24682         -}
 24683         -/*
 24684         -** A no-op since the error code is returned on the DosLoadModule call.
 24685         -** os2Dlopen returns zero if DosLoadModule is not successful.
 24686         -*/
 24687         -static void os2DlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
 24688         -/* no-op */
 24689         -}
 24690         -static void (*os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
 24691         -  PFN pfn;
 24692         -  APIRET rc;
 24693         -  rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)zSymbol, &pfn);
 24694         -  if( rc != NO_ERROR ){
 24695         -    /* if the symbol itself was not found, search again for the same
 24696         -     * symbol with an extra underscore, that might be needed depending
 24697         -     * on the calling convention */
 24698         -    char _zSymbol[256] = "_";
 24699         -    strncat(_zSymbol, zSymbol, 254);
 24700         -    rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)_zSymbol, &pfn);
 24701         -  }
 24702         -  return rc != NO_ERROR ? 0 : (void(*)(void))pfn;
 24703         -}
 24704         -static void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){
 24705         -  DosFreeModule((HMODULE)pHandle);
 24706         -}
 24707         -#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
 24708         -  #define os2DlOpen 0
 24709         -  #define os2DlError 0
 24710         -  #define os2DlSym 0
 24711         -  #define os2DlClose 0
 24712         -#endif
 24713         -
 24714         -
 24715         -/*
 24716         -** Write up to nBuf bytes of randomness into zBuf.
 24717         -*/
 24718         -static int os2Randomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf ){
 24719         -  int n = 0;
 24720         -#if defined(SQLITE_TEST)
 24721         -  n = nBuf;
 24722         -  memset(zBuf, 0, nBuf);
 24723         -#else
 24724         -  int i;                           
 24725         -  PPIB ppib;
 24726         -  PTIB ptib;
 24727         -  DATETIME dt; 
 24728         -  static unsigned c = 0;
 24729         -  /* Ordered by variation probability */
 24730         -  static ULONG svIdx[6] = { QSV_MS_COUNT, QSV_TIME_LOW,
 24731         -                            QSV_MAXPRMEM, QSV_MAXSHMEM,
 24732         -                            QSV_TOTAVAILMEM, QSV_TOTRESMEM };
 24733         -
 24734         -  /* 8 bytes; timezone and weekday don't increase the randomness much */
 24735         -  if( (int)sizeof(dt)-3 <= nBuf - n ){
 24736         -    c += 0x0100;
 24737         -    DosGetDateTime(&dt);
 24738         -    dt.year = (USHORT)((dt.year - 1900) | c);
 24739         -    memcpy(&zBuf[n], &dt, sizeof(dt)-3);
 24740         -    n += sizeof(dt)-3;
 24741         -  }
 24742         -
 24743         -  /* 4 bytes; PIDs and TIDs are 16 bit internally, so combine them */
 24744         -  if( (int)sizeof(ULONG) <= nBuf - n ){
 24745         -    DosGetInfoBlocks(&ptib, &ppib);
 24746         -    *(PULONG)&zBuf[n] = MAKELONG(ppib->pib_ulpid,
 24747         -                                 ptib->tib_ptib2->tib2_ultid);
 24748         -    n += sizeof(ULONG);
 24749         -  }
 24750         -
 24751         -  /* Up to 6 * 4 bytes; variables depend on the system state */
 24752         -  for( i = 0; i < 6 && (int)sizeof(ULONG) <= nBuf - n; i++ ){
 24753         -    DosQuerySysInfo(svIdx[i], svIdx[i], 
 24754         -                    (PULONG)&zBuf[n], sizeof(ULONG));
 24755         -    n += sizeof(ULONG);
 24756         -  } 
 24757         -#endif
 24758         -
 24759         -  return n;
 24760         -}
 24761         -
 24762         -/*
 24763         -** Sleep for a little while.  Return the amount of time slept.
 24764         -** The argument is the number of microseconds we want to sleep.
 24765         -** The return value is the number of microseconds of sleep actually
 24766         -** requested from the underlying operating system, a number which
 24767         -** might be greater than or equal to the argument, but not less
 24768         -** than the argument.
 24769         -*/
 24770         -static int os2Sleep( sqlite3_vfs *pVfs, int microsec ){
 24771         -  DosSleep( (microsec/1000) );
 24772         -  return microsec;
 24773         -}
 24774         -
 24775         -/*
 24776         -** The following variable, if set to a non-zero value, becomes the result
 24777         -** returned from sqlite3OsCurrentTime().  This is used for testing.
 24778         -*/
 24779         -#ifdef SQLITE_TEST
 24780         -SQLITE_API int sqlite3_current_time = 0;
 24781         -#endif
 24782         -
 24783         -/*
 24784         -** Find the current time (in Universal Coordinated Time).  Write into *piNow
 24785         -** the current time and date as a Julian Day number times 86_400_000.  In
 24786         -** other words, write into *piNow the number of milliseconds since the Julian
 24787         -** epoch of noon in Greenwich on November 24, 4714 B.C according to the
 24788         -** proleptic Gregorian calendar.
 24789         -**
 24790         -** On success, return 0.  Return 1 if the time and date cannot be found.
 24791         -*/
 24792         -static int os2CurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
 24793         -#ifdef SQLITE_TEST
 24794         -  static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
 24795         -#endif
 24796         -  int year, month, datepart, timepart;
 24797         - 
 24798         -  DATETIME dt;
 24799         -  DosGetDateTime( &dt );
 24800         -
 24801         -  year = dt.year;
 24802         -  month = dt.month;
 24803         -
 24804         -  /* Calculations from http://www.astro.keele.ac.uk/~rno/Astronomy/hjd.html
 24805         -  ** http://www.astro.keele.ac.uk/~rno/Astronomy/hjd-0.1.c
 24806         -  ** Calculate the Julian days
 24807         -  */
 24808         -  datepart = (int)dt.day - 32076 +
 24809         -    1461*(year + 4800 + (month - 14)/12)/4 +
 24810         -    367*(month - 2 - (month - 14)/12*12)/12 -
 24811         -    3*((year + 4900 + (month - 14)/12)/100)/4;
 24812         -
 24813         -  /* Time in milliseconds, hours to noon added */
 24814         -  timepart = 12*3600*1000 + dt.hundredths*10 + dt.seconds*1000 +
 24815         -    ((int)dt.minutes + dt.timezone)*60*1000 + dt.hours*3600*1000;
 24816         -
 24817         -  *piNow = (sqlite3_int64)datepart*86400*1000 + timepart;
 24818         -   
 24819         -#ifdef SQLITE_TEST
 24820         -  if( sqlite3_current_time ){
 24821         -    *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
 24822         -  }
 24823         -#endif
 24824         -
 24825         -  UNUSED_PARAMETER(pVfs);
 24826         -  return 0;
 24827         -}
 24828         -
 24829         -/*
 24830         -** Find the current time (in Universal Coordinated Time).  Write the
 24831         -** current time and date as a Julian Day number into *prNow and
 24832         -** return 0.  Return 1 if the time and date cannot be found.
 24833         -*/
 24834         -static int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){
 24835         -  int rc;
 24836         -  sqlite3_int64 i;
 24837         -  rc = os2CurrentTimeInt64(pVfs, &i);
 24838         -  if( !rc ){
 24839         -    *prNow = i/86400000.0;
 24840         -  }
 24841         -  return rc;
 24842         -}
 24843         -
 24844         -/*
 24845         -** The idea is that this function works like a combination of
 24846         -** GetLastError() and FormatMessage() on windows (or errno and
 24847         -** strerror_r() on unix). After an error is returned by an OS
 24848         -** function, SQLite calls this function with zBuf pointing to
 24849         -** a buffer of nBuf bytes. The OS layer should populate the
 24850         -** buffer with a nul-terminated UTF-8 encoded error message
 24851         -** describing the last IO error to have occurred within the calling
 24852         -** thread.
 24853         -**
 24854         -** If the error message is too large for the supplied buffer,
 24855         -** it should be truncated. The return value of xGetLastError
 24856         -** is zero if the error message fits in the buffer, or non-zero
 24857         -** otherwise (if the message was truncated). If non-zero is returned,
 24858         -** then it is not necessary to include the nul-terminator character
 24859         -** in the output buffer.
 24860         -**
 24861         -** Not supplying an error message will have no adverse effect
 24862         -** on SQLite. It is fine to have an implementation that never
 24863         -** returns an error message:
 24864         -**
 24865         -**   int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
 24866         -**     assert(zBuf[0]=='\0');
 24867         -**     return 0;
 24868         -**   }
 24869         -**
 24870         -** However if an error message is supplied, it will be incorporated
 24871         -** by sqlite into the error message available to the user using
 24872         -** sqlite3_errmsg(), possibly making IO errors easier to debug.
 24873         -*/
 24874         -static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
 24875         -  assert(zBuf[0]=='\0');
 24876         -  return 0;
 24877         -}
 24878         -
 24879         -/*
 24880         -** Initialize and deinitialize the operating system interface.
 24881         -*/
 24882         -SQLITE_API int sqlite3_os_init(void){
 24883         -  static sqlite3_vfs os2Vfs = {
 24884         -    3,                 /* iVersion */
 24885         -    sizeof(os2File),   /* szOsFile */
 24886         -    CCHMAXPATH,        /* mxPathname */
 24887         -    0,                 /* pNext */
 24888         -    "os2",             /* zName */
 24889         -    0,                 /* pAppData */
 24890         -
 24891         -    os2Open,           /* xOpen */
 24892         -    os2Delete,         /* xDelete */
 24893         -    os2Access,         /* xAccess */
 24894         -    os2FullPathname,   /* xFullPathname */
 24895         -    os2DlOpen,         /* xDlOpen */
 24896         -    os2DlError,        /* xDlError */
 24897         -    os2DlSym,          /* xDlSym */
 24898         -    os2DlClose,        /* xDlClose */
 24899         -    os2Randomness,     /* xRandomness */
 24900         -    os2Sleep,          /* xSleep */
 24901         -    os2CurrentTime,    /* xCurrentTime */
 24902         -    os2GetLastError,   /* xGetLastError */
 24903         -    os2CurrentTimeInt64, /* xCurrentTimeInt64 */
 24904         -    0,                 /* xSetSystemCall */
 24905         -    0,                 /* xGetSystemCall */
 24906         -    0                  /* xNextSystemCall */
 24907         -  };
 24908         -  sqlite3_vfs_register(&os2Vfs, 1);
 24909         -  initUconvObjects();
 24910         -/*  sqlite3OSTrace = 1; */
 24911         -  return SQLITE_OK;
 24912         -}
 24913         -SQLITE_API int sqlite3_os_end(void){
 24914         -  freeUconvObjects();
 24915         -  return SQLITE_OK;
 24916         -}
 24917         -
 24918         -#endif /* SQLITE_OS_OS2 */
 24919         -
 24920         -/************** End of os_os2.c **********************************************/
 24921  22516   /************** Begin file os_unix.c *****************************************/
 24922  22517   /*
 24923  22518   ** 2004 May 22
 24924  22519   **
 24925  22520   ** The author disclaims copyright to this source code.  In place of
 24926  22521   ** a legal notice, here is a blessing:
 24927  22522   **
................................................................................
 59053  56648   }
 59054  56649   
 59055  56650   /*
 59056  56651   ** Release all resources associated with an sqlite3_backup* handle.
 59057  56652   */
 59058  56653   SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
 59059  56654     sqlite3_backup **pp;                 /* Ptr to head of pagers backup list */
 59060         -  MUTEX_LOGIC( sqlite3_mutex *mutex; ) /* Mutex to protect source database */
        56655  +  sqlite3 *pSrcDb;                     /* Source database connection */
 59061  56656     int rc;                              /* Value to return */
 59062  56657   
 59063  56658     /* Enter the mutexes */
 59064  56659     if( p==0 ) return SQLITE_OK;
 59065         -  sqlite3_mutex_enter(p->pSrcDb->mutex);
        56660  +  pSrcDb = p->pSrcDb;
        56661  +  sqlite3_mutex_enter(pSrcDb->mutex);
 59066  56662     sqlite3BtreeEnter(p->pSrc);
 59067         -  MUTEX_LOGIC( mutex = p->pSrcDb->mutex; )
 59068  56663     if( p->pDestDb ){
 59069  56664       sqlite3_mutex_enter(p->pDestDb->mutex);
 59070  56665     }
 59071  56666   
 59072  56667     /* Detach this backup from the source pager. */
 59073  56668     if( p->pDestDb ){
 59074  56669       p->pSrc->nBackup--;
................................................................................
 59086  56681   
 59087  56682     /* Set the error code of the destination database handle. */
 59088  56683     rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
 59089  56684     sqlite3Error(p->pDestDb, rc, 0);
 59090  56685   
 59091  56686     /* Exit the mutexes and free the backup context structure. */
 59092  56687     if( p->pDestDb ){
 59093         -    sqlite3_mutex_leave(p->pDestDb->mutex);
        56688  +    sqlite3LeaveMutexAndCloseZombie(p->pDestDb);
 59094  56689     }
 59095  56690     sqlite3BtreeLeave(p->pSrc);
 59096  56691     if( p->pDestDb ){
 59097  56692       /* EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
 59098  56693       ** call to sqlite3_backup_init() and is destroyed by a call to
 59099  56694       ** sqlite3_backup_finish(). */
 59100  56695       sqlite3_free(p);
 59101  56696     }
 59102         -  sqlite3_mutex_leave(mutex);
        56697  +  sqlite3LeaveMutexAndCloseZombie(pSrcDb);
 59103  56698     return rc;
 59104  56699   }
 59105  56700   
 59106  56701   /*
 59107  56702   ** Return the number of pages still to be backed up as of the most recent
 59108  56703   ** call to sqlite3_backup_step().
 59109  56704   */
................................................................................
 62859  60454   ** Delete an entire VDBE.
 62860  60455   */
 62861  60456   SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
 62862  60457     sqlite3 *db;
 62863  60458   
 62864  60459     if( NEVER(p==0) ) return;
 62865  60460     db = p->db;
        60461  +  assert( sqlite3_mutex_held(db->mutex) );
 62866  60462     if( p->pPrev ){
 62867  60463       p->pPrev->pNext = p->pNext;
 62868  60464     }else{
 62869  60465       assert( db->pVdbe==p );
 62870  60466       db->pVdbe = p->pNext;
 62871  60467     }
 62872  60468     if( p->pNext ){
................................................................................
 63698  61294     if( pStmt==0 ){
 63699  61295       /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL
 63700  61296       ** pointer is a harmless no-op. */
 63701  61297       rc = SQLITE_OK;
 63702  61298     }else{
 63703  61299       Vdbe *v = (Vdbe*)pStmt;
 63704  61300       sqlite3 *db = v->db;
 63705         -#if SQLITE_THREADSAFE
 63706         -    sqlite3_mutex *mutex;
 63707         -#endif
 63708  61301       if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT;
 63709         -#if SQLITE_THREADSAFE
 63710         -    mutex = v->db->mutex;
 63711         -#endif
 63712         -    sqlite3_mutex_enter(mutex);
        61302  +    sqlite3_mutex_enter(db->mutex);
 63713  61303       rc = sqlite3VdbeFinalize(v);
 63714  61304       rc = sqlite3ApiExit(db, rc);
 63715         -    sqlite3_mutex_leave(mutex);
        61305  +    sqlite3LeaveMutexAndCloseZombie(db);
 63716  61306     }
 63717  61307     return rc;
 63718  61308   }
 63719  61309   
 63720  61310   /*
 63721  61311   ** Terminate the current execution of an SQL statement and reset it
 63722  61312   ** back to its starting state so that it can be reused. A success code from
................................................................................
 88017  85607   ** "NULL".  Otherwise, the argument is enclosed in single quotes with
 88018  85608   ** single-quote escapes.
 88019  85609   */
 88020  85610   static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
 88021  85611     assert( argc==1 );
 88022  85612     UNUSED_PARAMETER(argc);
 88023  85613     switch( sqlite3_value_type(argv[0]) ){
 88024         -    case SQLITE_INTEGER:
 88025  85614       case SQLITE_FLOAT: {
        85615  +      double r1, r2;
        85616  +      char zBuf[50];
        85617  +      r1 = sqlite3_value_double(argv[0]);
        85618  +      sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1);
        85619  +      sqlite3AtoF(zBuf, &r2, 20, SQLITE_UTF8);
        85620  +      if( r1!=r2 ){
        85621  +        sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.20e", r1);
        85622  +      }
        85623  +      sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
        85624  +      break;
        85625  +    }
        85626  +    case SQLITE_INTEGER: {
 88026  85627         sqlite3_result_value(context, argv[0]);
 88027  85628         break;
 88028  85629       }
 88029  85630       case SQLITE_BLOB: {
 88030  85631         char *zText = 0;
 88031  85632         char const *zBlob = sqlite3_value_blob(argv[0]);
 88032  85633         int nBlob = sqlite3_value_bytes(argv[0]);
................................................................................
114345 111946       }
114346 111947     }
114347 111948     sqlite3BtreeLeaveAll(db);
114348 111949   #else
114349 111950     UNUSED_PARAMETER(db);
114350 111951   #endif
114351 111952   }
       111953  +
       111954  +/*
       111955  +** Return TRUE if database connection db has unfinalized prepared
       111956  +** statements or unfinished sqlite3_backup objects.  
       111957  +*/
       111958  +static int connectionIsBusy(sqlite3 *db){
       111959  +  int j;
       111960  +  assert( sqlite3_mutex_held(db->mutex) );
       111961  +  if( db->pVdbe ) return 1;
       111962  +  for(j=0; j<db->nDb; j++){
       111963  +    Btree *pBt = db->aDb[j].pBt;
       111964  +    if( pBt && sqlite3BtreeIsInBackup(pBt) ) return 1;
       111965  +  }
       111966  +  return 0;
       111967  +}
114352 111968   
114353 111969   /*
114354 111970   ** Close an existing SQLite database
114355 111971   */
114356         -SQLITE_API int sqlite3_close(sqlite3 *db){
114357         -  HashElem *i;                    /* Hash table iterator */
114358         -  int j;
114359         -
       111972  +static int sqlite3Close(sqlite3 *db, int forceZombie){
114360 111973     if( !db ){
114361 111974       return SQLITE_OK;
114362 111975     }
114363 111976     if( !sqlite3SafetyCheckSickOrOk(db) ){
114364 111977       return SQLITE_MISUSE_BKPT;
114365 111978     }
114366 111979     sqlite3_mutex_enter(db->mutex);
................................................................................
114373 111986     ** tables in the db->aVTrans[] array. The following sqlite3VtabRollback()
114374 111987     ** call will do so. We need to do this before the check for active
114375 111988     ** SQL statements below, as the v-table implementation may be storing
114376 111989     ** some prepared statements internally.
114377 111990     */
114378 111991     sqlite3VtabRollback(db);
114379 111992   
114380         -  /* If there are any outstanding VMs, return SQLITE_BUSY. */
114381         -  if( db->pVdbe ){
114382         -    sqlite3Error(db, SQLITE_BUSY, 
114383         -        "unable to close due to unfinalised statements");
       111993  +  /* Legacy behavior (sqlite3_close() behavior) is to return
       111994  +  ** SQLITE_BUSY if the connection can not be closed immediately.
       111995  +  */
       111996  +  if( !forceZombie && connectionIsBusy(db) ){
       111997  +    sqlite3Error(db, SQLITE_BUSY, "unable to close due to unfinalized "
       111998  +       "statements or unfinished backups");
114384 111999       sqlite3_mutex_leave(db->mutex);
114385 112000       return SQLITE_BUSY;
114386 112001     }
114387         -  assert( sqlite3SafetyCheckSickOrOk(db) );
114388         -
114389         -  for(j=0; j<db->nDb; j++){
114390         -    Btree *pBt = db->aDb[j].pBt;
114391         -    if( pBt && sqlite3BtreeIsInBackup(pBt) ){
114392         -      sqlite3Error(db, SQLITE_BUSY, 
114393         -          "unable to close due to unfinished backup operation");
114394         -      sqlite3_mutex_leave(db->mutex);
114395         -      return SQLITE_BUSY;
114396         -    }
114397         -  }
       112002  +
       112003  +  /* Convert the connection into a zombie and then close it.
       112004  +  */
       112005  +  db->magic = SQLITE_MAGIC_ZOMBIE;
       112006  +  sqlite3LeaveMutexAndCloseZombie(db);
       112007  +  return SQLITE_OK;
       112008  +}
       112009  +
       112010  +/*
       112011  +** Two variations on the public interface for closing a database
       112012  +** connection. The sqlite3_close() version returns SQLITE_BUSY and
       112013  +** leaves the connection option if there are unfinalized prepared
       112014  +** statements or unfinished sqlite3_backups.  The sqlite3_close_v2()
       112015  +** version forces the connection to become a zombie if there are
       112016  +** unclosed resources, and arranges for deallocation when the last
       112017  +** prepare statement or sqlite3_backup closes.
       112018  +*/
       112019  +SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
       112020  +SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
       112021  +
       112022  +
       112023  +/*
       112024  +** Close the mutex on database connection db.
       112025  +**
       112026  +** Furthermore, if database connection db is a zombie (meaning that there
       112027  +** has been a prior call to sqlite3_close(db) or sqlite3_close_v2(db)) and
       112028  +** every sqlite3_stmt has now been finalized and every sqlite3_backup has
       112029  +** finished, then free all resources.
       112030  +*/
       112031  +SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
       112032  +  HashElem *i;                    /* Hash table iterator */
       112033  +  int j;
       112034  +
       112035  +  /* If there are outstanding sqlite3_stmt or sqlite3_backup objects
       112036  +  ** or if the connection has not yet been closed by sqlite3_close_v2(),
       112037  +  ** then just leave the mutex and return.
       112038  +  */
       112039  +  if( db->magic!=SQLITE_MAGIC_ZOMBIE || connectionIsBusy(db) ){
       112040  +    sqlite3_mutex_leave(db->mutex);
       112041  +    return;
       112042  +  }
       112043  +
       112044  +  /* If we reach this point, it means that the database connection has
       112045  +  ** closed all sqlite3_stmt and sqlite3_backup objects and has been
       112046  +  ** pased to sqlite3_close (meaning that it is a zombie).  Therefore,
       112047  +  ** go ahead and free all resources.
       112048  +  */
114398 112049   
114399 112050     /* Free any outstanding Savepoint structures. */
114400 112051     sqlite3CloseSavepoints(db);
114401 112052   
114402 112053     /* Close all database connections */
114403 112054     for(j=0; j<db->nDb; j++){
114404 112055       struct Db *pDb = &db->aDb[j];
................................................................................
114479 112130     db->magic = SQLITE_MAGIC_CLOSED;
114480 112131     sqlite3_mutex_free(db->mutex);
114481 112132     assert( db->lookaside.nOut==0 );  /* Fails on a lookaside memory leak */
114482 112133     if( db->lookaside.bMalloced ){
114483 112134       sqlite3_free(db->lookaside.pStart);
114484 112135     }
114485 112136     sqlite3_free(db);
114486         -  return SQLITE_OK;
114487 112137   }
114488 112138   
114489 112139   /*
114490 112140   ** Rollback all database files.  If tripCode is not SQLITE_OK, then
114491 112141   ** any open cursors are invalidated ("tripped" - as in "tripping a circuit
114492 112142   ** breaker") and made to return tripCode if there are any further
114493 112143   ** attempts to use that cursor.
................................................................................
133895 131545           iLo = iTest+1;
133896 131546         }else{
133897 131547           iHi = iTest-1;
133898 131548         }
133899 131549       }
133900 131550       assert( aEntry[0]<key );
133901 131551       assert( key>=aEntry[iRes] );
133902         -    return (c >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
       131552  +    return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
133903 131553     }
133904 131554     return 1;
133905 131555   }
133906 131556   
133907 131557   
133908 131558   /*
133909 131559   ** If the argument is a codepoint corresponding to a lowercase letter
................................................................................
138175 135825       iEnd = ubrk_next(pCsr->pIter);
138176 135826       if( iEnd==UBRK_DONE ){
138177 135827         return SQLITE_DONE;
138178 135828       }
138179 135829   
138180 135830       while( iStart<iEnd ){
138181 135831         int iWhite = iStart;
138182         -      U8_NEXT(pCsr->aChar, iWhite, pCsr->nChar, c);
       135832  +      U16_NEXT(pCsr->aChar, iWhite, pCsr->nChar, c);
138183 135833         if( u_isspace(c) ){
138184 135834           iStart = iWhite;
138185 135835         }else{
138186 135836           break;
138187 135837         }
138188 135838       }
138189 135839       assert(iStart<=iEnd);

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

   103    103   ** string contains the date and time of the check-in (UTC) and an SHA1
   104    104   ** hash of the entire source tree.
   105    105   **
   106    106   ** See also: [sqlite3_libversion()],
   107    107   ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
   108    108   ** [sqlite_version()] and [sqlite_source_id()].
   109    109   */
   110         -#define SQLITE_VERSION        "3.7.13"
   111         -#define SQLITE_VERSION_NUMBER 3007013
   112         -#define SQLITE_SOURCE_ID      "2012-06-08 14:01:53 025227be5495f950c466dfabac140cba69e498be"
          110  +#define SQLITE_VERSION        "3.7.14"
          111  +#define SQLITE_VERSION_NUMBER 3007014
          112  +#define SQLITE_SOURCE_ID      "2012-06-21 17:21:52 d5e6880279210ca63e2d5e7f6d009f30566f1242"
   113    113   
   114    114   /*
   115    115   ** CAPI3REF: Run-Time Library Version Numbers
   116    116   ** KEYWORDS: sqlite3_version, sqlite3_sourceid
   117    117   **
   118    118   ** These interfaces provide the same information as the [SQLITE_VERSION],
   119    119   ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
................................................................................
   215    215   ** CAPI3REF: Database Connection Handle
   216    216   ** KEYWORDS: {database connection} {database connections}
   217    217   **
   218    218   ** Each open SQLite database is represented by a pointer to an instance of
   219    219   ** the opaque structure named "sqlite3".  It is useful to think of an sqlite3
   220    220   ** pointer as an object.  The [sqlite3_open()], [sqlite3_open16()], and
   221    221   ** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
   222         -** is its destructor.  There are many other interfaces (such as
          222  +** and [sqlite3_close_v2()] are its destructors.  There are many other
          223  +** interfaces (such as
   223    224   ** [sqlite3_prepare_v2()], [sqlite3_create_function()], and
   224    225   ** [sqlite3_busy_timeout()] to name but three) that are methods on an
   225    226   ** sqlite3 object.
   226    227   */
   227    228   typedef struct sqlite3 sqlite3;
   228    229   
   229    230   /*
................................................................................
   262    263   #ifdef SQLITE_OMIT_FLOATING_POINT
   263    264   # define double sqlite3_int64
   264    265   #endif
   265    266   
   266    267   /*
   267    268   ** CAPI3REF: Closing A Database Connection
   268    269   **
   269         -** ^The sqlite3_close() routine is the destructor for the [sqlite3] object.
   270         -** ^Calls to sqlite3_close() return SQLITE_OK if the [sqlite3] object is
   271         -** successfully destroyed and all associated resources are deallocated.
          270  +** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
          271  +** for the [sqlite3] object.
          272  +** ^Calls to sqlite3_close() and sqlite3_close_v2() return SQLITE_OK if
          273  +** the [sqlite3] object is successfully destroyed and all associated
          274  +** resources are deallocated.
   272    275   **
   273         -** Applications must [sqlite3_finalize | finalize] all [prepared statements]
   274         -** and [sqlite3_blob_close | close] all [BLOB handles] associated with
   275         -** the [sqlite3] object prior to attempting to close the object.  ^If
          276  +** ^If the database connection is associated with unfinalized prepared
          277  +** statements or unfinished sqlite3_backup objects then sqlite3_close()
          278  +** will leave the database connection open and return [SQLITE_BUSY].
          279  +** ^If sqlite3_close_v2() is called with unfinalized prepared statements
          280  +** and unfinished sqlite3_backups, then the database connection becomes
          281  +** an unusable "zombie" which will automatically be deallocated when the
          282  +** last prepared statement is finalized or the last sqlite3_backup is
          283  +** finished.  The sqlite3_close_v2() interface is intended for use with
          284  +** host languages that are garbage collected, and where the order in which
          285  +** destructors are called is arbitrary.
          286  +**
          287  +** Applications should [sqlite3_finalize | finalize] all [prepared statements],
          288  +** [sqlite3_blob_close | close] all [BLOB handles], and 
          289  +** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
          290  +** with the [sqlite3] object prior to attempting to close the object.  ^If
   276    291   ** sqlite3_close() is called on a [database connection] that still has
   277         -** outstanding [prepared statements] or [BLOB handles], then it returns
   278         -** SQLITE_BUSY.
          292  +** outstanding [prepared statements], [BLOB handles], and/or
          293  +** [sqlite3_backup] objects then it returns SQLITE_OK but the deallocation
          294  +** of resources is deferred until all [prepared statements], [BLOB handles],
          295  +** and [sqlite3_backup] objects are also destroyed.
   279    296   **
   280         -** ^If [sqlite3_close()] is invoked while a transaction is open,
          297  +** ^If an [sqlite3] object is destroyed while a transaction is open,
   281    298   ** the transaction is automatically rolled back.
   282    299   **
   283         -** The C parameter to [sqlite3_close(C)] must be either a NULL
          300  +** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
          301  +** must be either a NULL
   284    302   ** pointer or an [sqlite3] object pointer obtained
   285    303   ** from [sqlite3_open()], [sqlite3_open16()], or
   286    304   ** [sqlite3_open_v2()], and not previously closed.
   287         -** ^Calling sqlite3_close() with a NULL pointer argument is a 
   288         -** harmless no-op.
          305  +** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
          306  +** argument is a harmless no-op.
   289    307   */
   290         -SQLITE_API int sqlite3_close(sqlite3 *);
          308  +SQLITE_API int sqlite3_close(sqlite3*);
          309  +SQLITE_API int sqlite3_close_v2(sqlite3*);
   291    310   
   292    311   /*
   293    312   ** The type for a callback function.
   294    313   ** This is legacy and deprecated.  It is included for historical
   295    314   ** compatibility and is not documented.
   296    315   */
   297    316   typedef int (*sqlite3_callback)(void*,int,char**, char**);
................................................................................
  5490   5509   **
  5491   5510   ** The SQLite source code contains multiple implementations
  5492   5511   ** of these mutex routines.  An appropriate implementation
  5493   5512   ** is selected automatically at compile-time.  ^(The following
  5494   5513   ** implementations are available in the SQLite core:
  5495   5514   **
  5496   5515   ** <ul>
  5497         -** <li>   SQLITE_MUTEX_OS2
  5498   5516   ** <li>   SQLITE_MUTEX_PTHREADS
  5499   5517   ** <li>   SQLITE_MUTEX_W32
  5500   5518   ** <li>   SQLITE_MUTEX_NOOP
  5501   5519   ** </ul>)^
  5502   5520   **
  5503   5521   ** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
  5504   5522   ** that does no real locking and is appropriate for use in
  5505         -** a single-threaded application.  ^The SQLITE_MUTEX_OS2,
  5506         -** SQLITE_MUTEX_PTHREADS, and SQLITE_MUTEX_W32 implementations
  5507         -** are appropriate for use on OS/2, Unix, and Windows.
         5523  +** a single-threaded application.  ^The SQLITE_MUTEX_PTHREADS and
         5524  +** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
         5525  +** and Windows.
  5508   5526   **
  5509   5527   ** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
  5510   5528   ** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
  5511   5529   ** implementation is included with the library. In this case the
  5512   5530   ** application must supply a custom mutex implementation using the
  5513   5531   ** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
  5514   5532   ** before calling sqlite3_initialize() or any other public sqlite3_

Changes to SQLite.Interop/src/win/interop.c.

    58     58       statement's memory is preserved, and marked as BAD, but we can still manage to finalize everything and forcibly close the database.  Later when the 
    59     59       GC gets around to calling finalize_interop() on the "bad" statement, we detect that and finish deallocating the pointer.
    60     60   */
    61     61   SQLITE_API int WINAPI sqlite3_close_interop(sqlite3 *db)
    62     62   {
    63     63     int ret;
    64     64     
           65  +#if SQLITE_VERSION_NUMBER >= 3007013
           66  +  ret = sqlite3_close_v2(db);
           67  +#else
    65     68     ret = sqlite3_close(db);
    66     69   
    67     70     if (ret == SQLITE_BUSY)
    68     71     {
    69     72       sqlite3_mutex_enter(db->mutex);
    70     73   
    71     74       if (!db->pVdbe)
................................................................................
   109    112           ZeroMemory(po, sizeof(Vdbe));
   110    113           po->magic = VDBE_MAGIC_DEAD;
   111    114         }
   112    115       }
   113    116       sqlite3_mutex_leave(db->mutex);
   114    117       ret = sqlite3_close(db);
   115    118     }
          119  +#endif
   116    120   
   117    121     return ret;
   118    122   }
   119    123   
   120    124   SQLITE_API int WINAPI sqlite3_open_interop(const char*filename, int flags, sqlite3 **ppdb)
   121    125   {
   122    126     int ret;
................................................................................
   240    244     const void *pval = sqlite3_column_text16(stmt, iCol);
   241    245     *plen = (pval != 0) ? wcslen((wchar_t *)pval) * sizeof(wchar_t): 0;
   242    246     return pval;
   243    247   }
   244    248   
   245    249   SQLITE_API int WINAPI sqlite3_finalize_interop(sqlite3_stmt *stmt)
   246    250   {
          251  +#if SQLITE_VERSION_NUMBER >= 3007013
          252  +  return sqlite3_finalize(stmt);
          253  +#else
   247    254     Vdbe *p;
   248    255     int ret = SQLITE_OK;
   249    256   
   250    257     p = (Vdbe *)stmt;
   251    258     if (p)
   252    259     {
   253    260       sqlite3 *db = p->db;
................................................................................
   265    272       }
   266    273   
   267    274       if (db != NULL)
   268    275         sqlite3_mutex_leave(db->mutex);
   269    276     }
   270    277   
   271    278     return ret;
          279  +#endif
   272    280   }
   273    281   
   274    282   SQLITE_API int WINAPI sqlite3_reset_interop(sqlite3_stmt *stmt)
   275    283   {
   276    284     int ret;
   277    285   
   278    286     if (((Vdbe *)stmt)->magic == VDBE_MAGIC_DEAD) return SQLITE_SCHEMA;

Changes to System.Data.SQLite.Linq/SQL Generation/DmlSqlGenerator.cs.

   193    193   
   194    194         // from
   195    195         commandText.Append("FROM ");
   196    196         tree.Target.Expression.Accept(translator);
   197    197         commandText.AppendLine();
   198    198   
   199    199         // where
   200         -#if INTEROP_EXTENSION_FUNCTIONS
          200  +#if USE_INTEROP_DLL && INTEROP_EXTENSION_FUNCTIONS
   201    201         commandText.Append("WHERE last_rows_affected() > 0");
   202    202   #else
   203    203         commandText.Append("WHERE changes() > 0");
   204    204   #endif
   205    205         EntitySetBase table = ((DbScanExpression)tree.Target.Expression).Target;
   206    206         bool identity = false;
   207    207         foreach (EdmMember keyMember in table.ElementType.KeyMembers)

Changes to System.Data.SQLite.Linq/SQL Generation/SqlGenerator.cs.

   325    325       /// All special non-aggregate canonical functions and their handlers
   326    326       /// </summary>
   327    327       /// <returns></returns>
   328    328       private static Dictionary<string, FunctionHandler> InitializeCanonicalFunctionHandlers()
   329    329       {
   330    330         Dictionary<string, FunctionHandler> functionHandlers = new Dictionary<string, FunctionHandler>(16, StringComparer.Ordinal);
   331    331   
   332         -#if INTEROP_EXTENSION_FUNCTIONS
          332  +#if USE_INTEROP_DLL && INTEROP_EXTENSION_FUNCTIONS
   333    333         functionHandlers.Add("IndexOf", HandleCanonicalFunctionIndexOf);
   334    334   #endif
   335    335   
   336    336         functionHandlers.Add("Length", HandleCanonicalFunctionLength);
   337    337         functionHandlers.Add("NewGuid", HandleCanonicalFunctionNewGuid);
   338    338         functionHandlers.Add("Round", HandleCanonicalFunctionRound);
   339    339         functionHandlers.Add("ToLower", HandleCanonicalFunctionToLower);
................................................................................
  2861   2861         }
  2862   2862   
  2863   2863         result.Append(") AS integer)");
  2864   2864   
  2865   2865         return result;
  2866   2866       }
  2867   2867   
  2868         -#if INTEROP_EXTENSION_FUNCTIONS
         2868  +#if USE_INTEROP_DLL && INTEROP_EXTENSION_FUNCTIONS
  2869   2869       /// <summary>
  2870   2870       ///  Function rename IndexOf -> CHARINDEX
  2871   2871       /// </summary>
  2872   2872       /// <param name="sqlgen"></param>
  2873   2873       /// <param name="e"></param>
  2874   2874       /// <returns></returns>
  2875   2875       private static ISqlFragment HandleCanonicalFunctionIndexOf(SqlGenerator sqlgen, DbFunctionExpression e)

Changes to System.Data.SQLite/SQLiteBase.cs.

   414    414           if ((hdl == null) || (db == IntPtr.Zero)) return;
   415    415           lock (hdl)
   416    416           {
   417    417   #if !SQLITE_STANDARD
   418    418               int n = UnsafeNativeMethods.sqlite3_close_interop(db);
   419    419   #else
   420    420               ResetConnection(hdl, db);
   421         -            int n = UnsafeNativeMethods.sqlite3_close(db);
          421  +
          422  +            int n;
          423  +
          424  +            try
          425  +            {
          426  +                n = UnsafeNativeMethods.sqlite3_close_v2(db);
          427  +            }
          428  +            catch (EntryPointNotFoundException)
          429  +            {
          430  +                n = UnsafeNativeMethods.sqlite3_close(db);
          431  +            }
   422    432   #endif
   423    433               if (n > 0) throw new SQLiteException(n, GetLastError(hdl, db));
   424    434           }
   425    435       }
   426    436   
   427    437       internal static void ResetConnection(SQLiteConnectionHandle hdl, IntPtr db)
   428    438       {

Changes to System.Data.SQLite/UnsafeNativeMethods.cs.

   590    590   #if !PLATFORM_COMPACTFRAMEWORK
   591    591       [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
   592    592   #else
   593    593       [DllImport(SQLITE_DLL)]
   594    594   #endif
   595    595       internal static extern int sqlite3_close(IntPtr db);
   596    596   
          597  +#if !PLATFORM_COMPACTFRAMEWORK
          598  +    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
          599  +#else
          600  +    [DllImport(SQLITE_DLL)]
          601  +#endif
          602  +    internal static extern int sqlite3_close_v2(IntPtr db);
          603  +
   597    604   #if !PLATFORM_COMPACTFRAMEWORK
   598    605       [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
   599    606   #else
   600    607       [DllImport(SQLITE_DLL)]
   601    608   #endif
   602    609       internal static extern int sqlite3_create_function(IntPtr db, byte[] strName, int nArgs, int nType, IntPtr pvUser, SQLiteCallback func, SQLiteCallback fstep, SQLiteFinalCallback ffinal);
   603    610   

Changes to Tests/basic.eagle.

    86     86     tlog "\n---- END STDOUT OUTPUT\n"
    87     87   
    88     88     list $code [expr {$code == 0 ? "" : $error}]
    89     89   } -cleanup {
    90     90     cleanupDb $fileName
    91     91   
    92     92     unset -nocomplain code output error fileName
    93         -} -constraints {eagle file_System.Data.SQLite.dll file_test.exe} -result {0 {}}}
           93  +} -constraints {eagle SQLite file_System.Data.SQLite.dll file_test.exe} \
           94  +-result {0 {}}}
    94     95   
    95     96   ###############################################################################
    96     97   
    97     98   runTest {test data-1.2 {unit tests from the 'testlinq' project} -setup {
    98     99     #
    99    100     # NOTE: Re-copy the reference database file used for this unit test to the
   100    101     #       build directory in case it has been changed by a previous test run.
................................................................................
   125    126     list $code [string equal $output [readFile $testLinqOutFile]] \
   126    127         [expr {$code == 0 ? "" : $error}]
   127    128   } -cleanup {
   128    129     catch {object invoke Console OutputEncoding $savedEncoding}
   129    130   
   130    131     unset -nocomplain code output error savedEncoding encoding
   131    132   } -constraints \
   132         -{eagle monoToDo file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll\
   133         -file_testlinq.exe file_northwindEF.db file_testlinq.out} -result {0 True {}}}
          133  +{eagle monoToDo SQLite file_System.Data.SQLite.dll\
          134  +file_System.Data.SQLite.Linq.dll file_testlinq.exe file_northwindEF.db\
          135  +file_testlinq.out} -result {0 True {}}}
   134    136   
   135    137   ###############################################################################
   136    138   
   137    139   runTest {test data-1.3 {SELECT scalar/reader, CREATE, INSERT} -setup {
   138    140     setupDb [set fileName data-1.3.db]
   139    141   } -body {
   140    142     set result [list]
................................................................................
  1407   1409     object invoke -flags +NonPublic -type \
  1408   1410         System.Data.SQLite.ISQLiteSchemaExtensions $providerServices \
  1409   1411         BuildTempSchema $connection
  1410   1412   } -cleanup {
  1411   1413     cleanupDb $fileName
  1412   1414   
  1413   1415     unset -nocomplain providerServices connection db fileName
  1414         -} -constraints {eagle System.Data.SQLite System.Data.SQLite.Linq} -result {}}
         1416  +} -constraints {eagle SQLite System.Data.SQLite System.Data.SQLite.Linq} \
         1417  +-result {}}
  1415   1418   
  1416   1419   ###############################################################################
  1417   1420   
  1418   1421   runTest {test data-1.27 {VARCHAR / NVARCHAR types with spaces} -body {
  1419   1422     list [object invoke -flags +NonPublic System.Data.SQLite.SQLiteConvert \
  1420   1423         TypeNameToDbType "VARCHAR"] \
  1421   1424         [object invoke -flags +NonPublic System.Data.SQLite.SQLiteConvert \

Changes to Tests/common.eagle.

   910    910           #
   911    911           checkForSQLite $::test_channel
   912    912   
   913    913           #
   914    914           # NOTE: Attempt to determine if the custom extension functions were
   915    915           #       compiled into the SQLite interop assembly.
   916    916           #
          917  +        checkForSQLiteDefineConstant $::test_channel \
          918  +            USE_INTEROP_DLL
          919  +
   917    920           checkForSQLiteDefineConstant $::test_channel \
   918    921               INTEROP_EXTENSION_FUNCTIONS
   919    922   
   920    923           #
   921    924           # NOTE: Report the resource usage prior to running any tests.
   922    925           #
   923    926           reportSQLiteResources $::test_channel

Changes to Tests/installer.eagle.

    21     21   ###############################################################################
    22     22   
    23     23   #
    24     24   # NOTE: Setup the variables that refer to the various files required by the
    25     25   #       tests in this file.
    26     26   #
    27     27   set systemDataSQLiteDllFile [getBuildFileName System.Data.SQLite.dll]
           28  +set systemDataSQLiteLinqDllFile [getBuildFileName System.Data.SQLite.Linq.dll]
    28     29   set installerExeFile [getBuildFileName Installer.exe]
    29     30   
    30     31   #
    31     32   # NOTE: The various install/uninstall log files used to test the design-time
    32     33   #       component installer.
    33     34   #
    34     35   set testInstallVs2005LogFile [file nativename [file join $path \
................................................................................
    48     49   
    49     50   set testUninstallVs2010LogFile [file nativename [file join $path \
    50     51       Uninstaller_Test_Vs2010.log]]
    51     52   
    52     53   #
    53     54   # NOTE: Setup the test constraints specific to the tests in this file.
    54     55   #
           56  +if {![haveConstraint [appendArgs file_ \
           57  +    [file tail $systemDataSQLiteDllFile]]]} then {
           58  +  checkForFile $test_channel $systemDataSQLiteDllFile
           59  +}
           60  +
           61  +if {![haveConstraint [appendArgs file_ \
           62  +    [file tail $systemDataSQLiteLinqDllFile]]]} then {
           63  +  checkForFile $test_channel $systemDataSQLiteLinqDllFile
           64  +}
           65  +
    55     66   if {![haveConstraint [appendArgs file_ \
    56     67       [file tail $installerExeFile]]]} then {
    57     68     checkForFile $test_channel $installerExeFile
    58     69   }
    59     70   
    60     71   if {![haveConstraint [appendArgs file_ \
    61     72       [file tail $testInstallVs2005LogFile]]]} then {
................................................................................
   116    127         [subst -nobackslashes [readFile $testInstallVs2005LogFile]]] : $error}]
   117    128   } -cleanup {
   118    129     cleanupFile $fileName
   119    130   
   120    131     unset -nocomplain wow64 code output error fileName
   121    132   } -constraints {eagle administrator visualStudio2005\
   122    133   System.Data.SQLite.dll_v2.0.50727 file_Installer.exe\
          134  +file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll\
   123    135   file_Installer_Test_Vs2005.log} -result {0 True}}
   124    136   
   125    137   ###############################################################################
   126    138   
   127    139   runTest {test installer-1.2 {uninstaller tool / Visual Studio 2005} -setup {
   128    140     set fileName [file join [getTemporaryPath] [file tail [string map [list \
   129    141         .log [appendArgs _ [pid] .log]] $testUninstallVs2005LogFile]]]
................................................................................
   151    163         [subst -nobackslashes [readFile $testUninstallVs2005LogFile]]] : $error}]
   152    164   } -cleanup {
   153    165     cleanupFile $fileName
   154    166   
   155    167     unset -nocomplain wow64 code output error fileName
   156    168   } -constraints {eagle administrator visualStudio2005\
   157    169   System.Data.SQLite.dll_v2.0.50727 file_Installer.exe\
          170  +file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll\
   158    171   file_Uninstaller_Test_Vs2005.log} -result {0 True}}
   159    172   
   160    173   ###############################################################################
   161    174   
   162    175   runTest {test installer-1.3 {installer tool / Visual Studio 2008} -setup {
   163    176     set fileName [file join [getTemporaryPath] [file tail [string map [list \
   164    177         .log [appendArgs _ [pid] .log]] $testInstallVs2008LogFile]]]
................................................................................
   186    199         [subst -nobackslashes [readFile $testInstallVs2008LogFile]]] : $error}]
   187    200   } -cleanup {
   188    201     cleanupFile $fileName
   189    202   
   190    203     unset -nocomplain wow64 code output error fileName
   191    204   } -constraints {eagle administrator visualStudio2008\
   192    205   System.Data.SQLite.dll_v2.0.50727 file_Installer.exe\
          206  +file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll\
   193    207   file_Installer_Test_Vs2008.log} -result {0 True}}
   194    208   
   195    209   ###############################################################################
   196    210   
   197    211   runTest {test installer-1.4 {uninstaller tool / Visual Studio 2008} -setup {
   198    212     set fileName [file join [getTemporaryPath] [file tail [string map [list \
   199    213         .log [appendArgs _ [pid] .log]] $testUninstallVs2008LogFile]]]
................................................................................
   221    235         [subst -nobackslashes [readFile $testUninstallVs2008LogFile]]] : $error}]
   222    236   } -cleanup {
   223    237     cleanupFile $fileName
   224    238   
   225    239     unset -nocomplain wow64 code output error fileName
   226    240   } -constraints {eagle administrator visualStudio2008\
   227    241   System.Data.SQLite.dll_v2.0.50727 file_Installer.exe\
          242  +file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll\
   228    243   file_Uninstaller_Test_Vs2008.log} -result {0 True}}
   229    244   
   230    245   ###############################################################################
   231    246   
   232    247   runTest {test installer-1.5 {installer tool / Visual Studio 2010} -setup {
   233    248     set fileName [file join [getTemporaryPath] [file tail [string map [list \
   234    249         .log [appendArgs _ [pid] .log]] $testInstallVs2010LogFile]]]
................................................................................
   256    271         [subst -nobackslashes [readFile $testInstallVs2010LogFile]]] : $error}]
   257    272   } -cleanup {
   258    273     cleanupFile $fileName
   259    274   
   260    275     unset -nocomplain wow64 code output error fileName
   261    276   } -constraints {eagle administrator visualStudio2010\
   262    277   System.Data.SQLite.dll_v4.0.30319 file_Installer.exe\
          278  +file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll\
   263    279   file_Installer_Test_Vs2010.log} -result {0 True}}
   264    280   
   265    281   ###############################################################################
   266    282   
   267    283   runTest {test installer-1.6 {uninstaller tool / Visual Studio 2010} -setup {
   268    284     set fileName [file join [getTemporaryPath] [file tail [string map [list \
   269    285         .log [appendArgs _ [pid] .log]] $testUninstallVs2010LogFile]]]
................................................................................
   291    307         [subst -nobackslashes [readFile $testUninstallVs2010LogFile]]] : $error}]
   292    308   } -cleanup {
   293    309     cleanupFile $fileName
   294    310   
   295    311     unset -nocomplain wow64 code output error fileName
   296    312   } -constraints {eagle administrator visualStudio2010\
   297    313   System.Data.SQLite.dll_v4.0.30319 file_Installer.exe\
          314  +file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll\
   298    315   file_Uninstaller_Test_Vs2010.log} -result {0 True}}
   299    316   
   300    317   ###############################################################################
   301    318   
   302    319   unset -nocomplain testUninstallVs2010LogFile testUninstallVs2008LogFile \
   303    320       testUninstallVs2005LogFile testInstallVs2010LogFile \
   304    321       testInstallVs2008LogFile testInstallVs2005LogFile installerExeFile \
   305         -    systemDataSQLiteDllFile
          322  +    systemDataSQLiteLinqDllFile systemDataSQLiteDllFile
   306    323   
   307    324   ###############################################################################
   308    325   
   309    326   runSQLiteTestEpilogue
   310    327   runTestEpilogue

Changes to Tests/tkt-00f86f9739.eagle.

    78     78       }
    79     79     }
    80     80   
    81     81     set result
    82     82   } -cleanup {
    83     83     unset -nocomplain code output error result value
    84     84   } -constraints \
    85         -{eagle monoToDo defineConstant.System.Data.SQLite.INTEROP_EXTENSION_FUNCTIONS\
           85  +{eagle monoToDo defineConstant.System.Data.SQLite.USE_INTEROP_DLL\
           86  +defineConstant.System.Data.SQLite.INTEROP_EXTENSION_FUNCTIONS SQLite\
    86     87   file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll file_testlinq.exe\
    87     88   file_northwindEF.db} -result {0 {} 0 {DRACD OLDWO RATTC} 0 {ALFKI CACTU CHOPS\
    88     89   FOLKO GALED KOENE LILAS MAGAA MAISD OCEAN RANCH SAVEA THECR} 0 {} 0 {} 0 {} 0\
    89     90   {}}}
    90     91   
    91     92   ###############################################################################
    92     93   

Changes to Tests/tkt-59edc1018b.eagle.

    78     78       }
    79     79     }
    80     80   
    81     81     set result
    82     82   } -cleanup {
    83     83     unset -nocomplain code output error result value
    84     84   } -constraints \
    85         -{eagle monoToDo defineConstant.System.Data.SQLite.INTEROP_EXTENSION_FUNCTIONS\
           85  +{eagle monoToDo defineConstant.System.Data.SQLite.USE_INTEROP_DLL\
           86  +defineConstant.System.Data.SQLite.INTEROP_EXTENSION_FUNCTIONS SQLite\
    86     87   file_System.Data.SQLite.dll file_System.Data.SQLite.Linq.dll file_testlinq.exe\
    87     88   file_northwindEF.db} -result {0 {} 0 {FURIB GALED GODOS LAZYK LINOD PRINI REGGC\
    88     89   WOLZA} 0 {} 0 ERNSH 0 {} 0 {AROUT BSBEV CONSH EASTC NORTS SEVES} 0 {}}}
    89     90   
    90     91   ###############################################################################
    91     92   
    92     93   unset -nocomplain systemDataSQLiteDllFile systemDataSQLiteLinqDllFile \
    93     94       testLinqExeFile northwindEfDbFile
    94     95   
    95     96   ###############################################################################
    96     97   
    97     98   runSQLiteTestEpilogue
    98     99   runTestEpilogue

Changes to Tests/tkt-8b7d179c3c.eagle.

    77     77         lappend result [string trim $error]
    78     78       }
    79     79     }
    80     80   
    81     81     set result
    82     82   } -cleanup {
    83     83     unset -nocomplain code output error result pageSize
    84         -} -constraints {eagle monoToDo file_System.Data.SQLite.dll\
           84  +} -constraints {eagle monoToDo SQLite file_System.Data.SQLite.dll\
    85     85   file_System.Data.SQLite.Linq.dll file_testlinq.exe file_northwindEF.db} \
    86     86   -result {0 {} 0 {DRACD RATTC OLDWO GALED LILAS MAGAA ALFKI CHOPS SAVEA KOENE\
    87     87   MAISD FOLKO CACTU OCEAN RANCH THECR GOURL GROSR SUPRD HUNGO ISLAT QUICK HUNGC\
    88     88   GREAL LEHMS RICSU ERNSH WILMK LINOD TRAIH SIMOB OTTIK SPLIR MORGK FOLIG FURIB\
    89     89   PRINI AROUT BSBEV CONSH EASTC NORTS SEVES BERGS VICTE BOLID FISSA ROMEY BLAUS\
    90     90   BONAP MEREP ANATR ANTON CENTC PERIC TORTU FRANK TOMSP DUMON FRANR WARTH PARIS\
    91     91   SPECD LONEP THEBI REGGC VINET WELLI HANAR QUEDE RICAR PICCO HILAA LETSS COMMI\

Changes to Tests/tkt-ccfa69fc32.eagle.

    77     77         lappend result [string trim $error]
    78     78       }
    79     79     }
    80     80   
    81     81     set result
    82     82   } -cleanup {
    83     83     unset -nocomplain code output error result add
    84         -} -constraints {eagle monoToDo file_System.Data.SQLite.dll\
           84  +} -constraints {eagle monoToDo SQLite file_System.Data.SQLite.dll\
    85     85   file_System.Data.SQLite.Linq.dll file_testlinq.exe file_northwindEF.db} -match \
    86     86   glob -result {0 {1581 1730 1833 2116 2139} 0 {System.Data.UpdateException: *\
    87     87   ---> System.Data.SQLite.SQLiteException: Abort due to constraint violation
    88     88   PRIMARY KEY must be unique
    89     89   *} 0 {1 2 3 4 5 6 7 8 9 10 1576 1577 1578 1579 1580 1581 1730 1833 2116 2139}}}
    90     90   
    91     91   ###############################################################################

Changes to test/TestCases.cs.

   217    217           using (DbDataReader reader = cmd.ExecuteReader())
   218    218           {
   219    219             reader.Read();
   220    220           }
   221    221         }
   222    222       }
   223    223   
   224         -#if INTEROP_EXTENSION_FUNCTIONS
          224  +#if USE_INTEROP_DLL && INTEROP_EXTENSION_FUNCTIONS
   225    225       [Test(Sequence = 8)]
   226    226       internal void FunctionWithCollation()
   227    227       {
   228    228         CheckSQLite();
   229    229         using (DbCommand cmd = _cnn.CreateCommand())
   230    230         {
   231    231           cmd.CommandText = "SELECT CHARINDEX('pat', 'thepat'), CHARINDEX('pat', 'THEPAT'), CHARINDEX('pat' COLLATE NOCASE, 'THEPAT' COLLATE NOCASE)";
................................................................................
   233    233           {
   234    234             reader.Read();
   235    235             if (reader.GetInt64(0) != reader.GetInt64(2) || reader.GetInt64(1) != 0 || reader.GetInt64(0) != 4)
   236    236               throw new Exception("CharIndex returned wrong results!");
   237    237           }
   238    238         }
   239    239       }
   240         -#endif
   241    240   
   242    241       [Test(Sequence = 9)]
   243    242       internal void FunctionWithCollation2()
   244    243       {
   245    244         CheckSQLite();
   246    245         using (DbCommand cmd = _cnn.CreateCommand())
   247    246         {
................................................................................
   250    249           {
   251    250             reader.Read();
   252    251             if (reader.GetInt64(0) != reader.GetInt64(2) || reader.GetInt64(1) != 1 || reader.GetInt64(0) != 0)
   253    252               throw new Exception("CharIndex returned wrong results!");
   254    253           }
   255    254         }
   256    255       }
          256  +#endif
   257    257   
   258    258       [Test]
   259    259       internal void DataTypesSchema()
   260    260       {
   261    261         using (DataTable tbl = _cnn.GetSchema("DataTypes"))
   262    262         {
   263    263         }