Fossil SCM

Update the built-in SQLite version to the 3.7.6 release.

drh 2011-04-12 02:25 trunk
Commit 4dde79b9e645d2f4feddecbb124eb7b2f24f8764
2 files changed +981 -199 +1 -1
+981 -199
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -650,11 +650,11 @@
650650
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
651651
** [sqlite_version()] and [sqlite_source_id()].
652652
*/
653653
#define SQLITE_VERSION "3.7.6"
654654
#define SQLITE_VERSION_NUMBER 3007006
655
-#define SQLITE_SOURCE_ID "2011-04-07 15:24:08 bf78acb9dfacde0f08a5b3ceac13480f12a06168"
655
+#define SQLITE_SOURCE_ID "2011-04-12 01:58:40 f9d43fa363d54beab6f45db005abac0a7c0c47a7"
656656
657657
/*
658658
** CAPI3REF: Run-Time Library Version Numbers
659659
** KEYWORDS: sqlite3_version, sqlite3_sourceid
660660
**
@@ -9808,10 +9808,11 @@
98089808
unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
98099809
Table *pTable; /* The SQL table being indexed */
98109810
int tnum; /* Page containing root of this index in database file */
98119811
u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
98129812
u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */
9813
+ u8 bUnordered; /* Use this index for == or IN queries only */
98139814
char *zColAff; /* String defining the affinity of each column */
98149815
Index *pNext; /* The next index associated with the same table */
98159816
Schema *pSchema; /* Schema containing this index */
98169817
u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */
98179818
char **azColl; /* Array of collation sequence names for index */
@@ -11099,10 +11100,11 @@
1109911100
SQLITE_PRIVATE void sqlite3PrngSaveState(void);
1110011101
SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
1110111102
SQLITE_PRIVATE void sqlite3PrngResetState(void);
1110211103
SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*);
1110311104
SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int);
11105
+SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
1110411106
SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int);
1110511107
SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*);
1110611108
SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*);
1110711109
SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
1110811110
SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
@@ -12078,13 +12080,10 @@
1207812080
"OMIT_TRIGGER",
1207912081
#endif
1208012082
#ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
1208112083
"OMIT_TRUNCATE_OPTIMIZATION",
1208212084
#endif
12083
-#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT
12084
- "OMIT_UNIQUE_ENFORCEMENT",
12085
-#endif
1208612085
#ifdef SQLITE_OMIT_UTF16
1208712086
"OMIT_UTF16",
1208812087
#endif
1208912088
#ifdef SQLITE_OMIT_VACUUM
1209012089
"OMIT_VACUUM",
@@ -16972,11 +16971,11 @@
1697216971
#ifdef SQLITE_DEBUG
1697316972
if( p->trace ) os2MutexTrace(p, "leave");
1697416973
#endif
1697516974
}
1697616975
16977
-SQLITE_PRIVATE SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
16976
+SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
1697816977
static const sqlite3_mutex_methods sMutex = {
1697916978
os2MutexInit,
1698016979
os2MutexEnd,
1698116980
os2MutexAlloc,
1698216981
os2MutexFree,
@@ -20224,12 +20223,12 @@
2022420223
/*
2022520224
** Routine needed to support the testcase() macro.
2022620225
*/
2022720226
#ifdef SQLITE_COVERAGE_TEST
2022820227
SQLITE_PRIVATE void sqlite3Coverage(int x){
20229
- static int dummy = 0;
20230
- dummy += x;
20228
+ static unsigned dummy = 0;
20229
+ dummy += (unsigned)x;
2023120230
}
2023220231
#endif
2023320232
2023420233
#ifndef SQLITE_OMIT_FLOATING_POINT
2023520234
/*
@@ -22045,48 +22044,66 @@
2204522044
#endif /* !defined(_OS_COMMON_H_) */
2204622045
2204722046
/************** End of os_common.h *******************************************/
2204822047
/************** Continuing where we left off in os_os2.c *********************/
2204922048
22049
+/* Forward references */
22050
+typedef struct os2File os2File; /* The file structure */
22051
+typedef struct os2ShmNode os2ShmNode; /* A shared descritive memory node */
22052
+typedef struct os2ShmLink os2ShmLink; /* A connection to shared-memory */
22053
+
2205022054
/*
2205122055
** The os2File structure is subclass of sqlite3_file specific for the OS/2
2205222056
** protability layer.
2205322057
*/
22054
-typedef struct os2File os2File;
2205522058
struct os2File {
2205622059
const sqlite3_io_methods *pMethod; /* Always the first entry */
2205722060
HFILE h; /* Handle for accessing the file */
22058
- char* pathToDel; /* Name of file to delete on close, NULL if not */
22059
- unsigned char locktype; /* Type of lock currently held on this file */
22061
+ int flags; /* Flags provided to os2Open() */
22062
+ int locktype; /* Type of lock currently held on this file */
22063
+ int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */
22064
+ char *zFullPathCp; /* Full path name of this file */
22065
+ os2ShmLink *pShmLink; /* Instance of shared memory on this file */
2206022066
};
2206122067
2206222068
#define LOCK_TIMEOUT 10L /* the default locking timeout */
2206322069
22070
+/*
22071
+** Missing from some versions of the OS/2 toolkit -
22072
+** used to allocate from high memory if possible
22073
+*/
22074
+#ifndef OBJ_ANY
22075
+# define OBJ_ANY 0x00000400
22076
+#endif
22077
+
2206422078
/*****************************************************************************
2206522079
** The next group of routines implement the I/O methods specified
2206622080
** by the sqlite3_io_methods object.
2206722081
******************************************************************************/
2206822082
2206922083
/*
2207022084
** Close a file.
2207122085
*/
2207222086
static int os2Close( sqlite3_file *id ){
22073
- APIRET rc = NO_ERROR;
22074
- os2File *pFile;
22075
- if( id && (pFile = (os2File*)id) != 0 ){
22076
- OSTRACE(( "CLOSE %d\n", pFile->h ));
22077
- rc = DosClose( pFile->h );
22078
- pFile->locktype = NO_LOCK;
22079
- if( pFile->pathToDel != NULL ){
22080
- rc = DosForceDelete( (PSZ)pFile->pathToDel );
22081
- free( pFile->pathToDel );
22082
- pFile->pathToDel = NULL;
22083
- }
22084
- id = 0;
22085
- OpenCounter( -1 );
22086
- }
22087
-
22087
+ APIRET rc;
22088
+ os2File *pFile = (os2File*)id;
22089
+
22090
+ assert( id!=0 );
22091
+ OSTRACE(( "CLOSE %d (%s)\n", pFile->h, pFile->zFullPathCp ));
22092
+
22093
+ rc = DosClose( pFile->h );
22094
+
22095
+ if( pFile->flags & SQLITE_OPEN_DELETEONCLOSE )
22096
+ DosForceDelete( (PSZ)pFile->zFullPathCp );
22097
+
22098
+ free( pFile->zFullPathCp );
22099
+ pFile->zFullPathCp = NULL;
22100
+ pFile->locktype = NO_LOCK;
22101
+ pFile->h = (HFILE)-1;
22102
+ pFile->flags = 0;
22103
+
22104
+ OpenCounter( -1 );
2208822105
return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
2208922106
}
2209022107
2209122108
/*
2209222109
** Read data from a file into a buffer. Return SQLITE_OK if all
@@ -22155,14 +22172,25 @@
2215522172
2215622173
/*
2215722174
** Truncate an open file to a specified size
2215822175
*/
2215922176
static int os2Truncate( sqlite3_file *id, i64 nByte ){
22160
- APIRET rc = NO_ERROR;
22177
+ APIRET rc;
2216122178
os2File *pFile = (os2File*)id;
22179
+ assert( id!=0 );
2216222180
OSTRACE(( "TRUNCATE %d %lld\n", pFile->h, nByte ));
2216322181
SimulateIOError( return SQLITE_IOERR_TRUNCATE );
22182
+
22183
+ /* If the user has configured a chunk-size for this file, truncate the
22184
+ ** file so that it consists of an integer number of chunks (i.e. the
22185
+ ** actual file size after the operation may be larger than the requested
22186
+ ** size).
22187
+ */
22188
+ if( pFile->szChunk ){
22189
+ nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
22190
+ }
22191
+
2216422192
rc = DosSetFileSize( pFile->h, nByte );
2216522193
return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_TRUNCATE;
2216622194
}
2216722195
2216822196
#ifdef SQLITE_TEST
@@ -22522,10 +22550,24 @@
2252222550
*(int*)pArg = ((os2File*)id)->locktype;
2252322551
OSTRACE(( "FCNTL_LOCKSTATE %d lock=%d\n",
2252422552
((os2File*)id)->h, ((os2File*)id)->locktype ));
2252522553
return SQLITE_OK;
2252622554
}
22555
+ case SQLITE_FCNTL_CHUNK_SIZE: {
22556
+ ((os2File*)id)->szChunk = *(int*)pArg;
22557
+ return SQLITE_OK;
22558
+ }
22559
+ case SQLITE_FCNTL_SIZE_HINT: {
22560
+ sqlite3_int64 sz = *(sqlite3_int64*)pArg;
22561
+ SimulateIOErrorBenign(1);
22562
+ os2Truncate(id, sz);
22563
+ SimulateIOErrorBenign(0);
22564
+ return SQLITE_OK;
22565
+ }
22566
+ case SQLITE_FCNTL_SYNC_OMITTED: {
22567
+ return SQLITE_OK;
22568
+ }
2252722569
}
2252822570
return SQLITE_NOTFOUND;
2252922571
}
2253022572
2253122573
/*
@@ -22537,18 +22579,20 @@
2253722579
** if two files are created in the same file-system directory (i.e.
2253822580
** a database and its journal file) that the sector size will be the
2253922581
** same for both.
2254022582
*/
2254122583
static int os2SectorSize(sqlite3_file *id){
22584
+ UNUSED_PARAMETER(id);
2254222585
return SQLITE_DEFAULT_SECTOR_SIZE;
2254322586
}
2254422587
2254522588
/*
2254622589
** Return a vector of device characteristics.
2254722590
*/
2254822591
static int os2DeviceCharacteristics(sqlite3_file *id){
22549
- return 0;
22592
+ UNUSED_PARAMETER(id);
22593
+ return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN;
2255022594
}
2255122595
2255222596
2255322597
/*
2255422598
** Character set conversion objects used by conversion routines.
@@ -22630,17 +22674,668 @@
2263022674
/* determine string for the conversion of UTF-8 which is CP1208 */
2263122675
UniStrFromUcs( ucUtf8, out, tempPath, CCHMAXPATH );
2263222676
2263322677
return out;
2263422678
}
22679
+
22680
+
22681
+#ifndef SQLITE_OMIT_WAL
22682
+
22683
+/*
22684
+** Use main database file for interprocess locking. If un-defined
22685
+** a separate file is created for this purpose. The file will be
22686
+** used only to set file locks. There will be no data written to it.
22687
+*/
22688
+#define SQLITE_OS2_NO_WAL_LOCK_FILE
22689
+
22690
+#if 0
22691
+static void _ERR_TRACE( const char *fmt, ... ) {
22692
+ va_list ap;
22693
+ va_start(ap, fmt);
22694
+ vfprintf(stderr, fmt, ap);
22695
+ fflush(stderr);
22696
+}
22697
+#define ERR_TRACE(rc, msg) \
22698
+ if( (rc) != SQLITE_OK ) _ERR_TRACE msg;
22699
+#else
22700
+#define ERR_TRACE(rc, msg)
22701
+#endif
22702
+
22703
+/*
22704
+** Helper functions to obtain and relinquish the global mutex. The
22705
+** global mutex is used to protect os2ShmNodeList.
22706
+**
22707
+** Function os2ShmMutexHeld() is used to assert() that the global mutex
22708
+** is held when required. This function is only used as part of assert()
22709
+** statements. e.g.
22710
+**
22711
+** os2ShmEnterMutex()
22712
+** assert( os2ShmMutexHeld() );
22713
+** os2ShmLeaveMutex()
22714
+*/
22715
+static void os2ShmEnterMutex(void){
22716
+ sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
22717
+}
22718
+static void os2ShmLeaveMutex(void){
22719
+ sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
22720
+}
22721
+#ifdef SQLITE_DEBUG
22722
+static int os2ShmMutexHeld(void) {
22723
+ return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
22724
+}
22725
+int GetCurrentProcessId(void) {
22726
+ PPIB pib;
22727
+ DosGetInfoBlocks(NULL, &pib);
22728
+ return (int)pib->pib_ulpid;
22729
+}
22730
+#endif
22731
+
22732
+/*
22733
+** Object used to represent a the shared memory area for a single log file.
22734
+** When multiple threads all reference the same log-summary, each thread has
22735
+** its own os2File object, but they all point to a single instance of this
22736
+** object. In other words, each log-summary is opened only once per process.
22737
+**
22738
+** os2ShmMutexHeld() must be true when creating or destroying
22739
+** this object or while reading or writing the following fields:
22740
+**
22741
+** nRef
22742
+** pNext
22743
+**
22744
+** The following fields are read-only after the object is created:
22745
+**
22746
+** szRegion
22747
+** hLockFile
22748
+** shmBaseName
22749
+**
22750
+** Either os2ShmNode.mutex must be held or os2ShmNode.nRef==0 and
22751
+** os2ShmMutexHeld() is true when reading or writing any other field
22752
+** in this structure.
22753
+**
22754
+*/
22755
+struct os2ShmNode {
22756
+ sqlite3_mutex *mutex; /* Mutex to access this object */
22757
+ os2ShmNode *pNext; /* Next in list of all os2ShmNode objects */
22758
+
22759
+ int szRegion; /* Size of shared-memory regions */
22760
+
22761
+ int nRegion; /* Size of array apRegion */
22762
+ void **apRegion; /* Array of pointers to shared-memory regions */
22763
+
22764
+ int nRef; /* Number of os2ShmLink objects pointing to this */
22765
+ os2ShmLink *pFirst; /* First os2ShmLink object pointing to this */
22766
+
22767
+ HFILE hLockFile; /* File used for inter-process memory locking */
22768
+ char shmBaseName[1]; /* Name of the memory object !!! must last !!! */
22769
+};
22770
+
22771
+
22772
+/*
22773
+** Structure used internally by this VFS to record the state of an
22774
+** open shared memory connection.
22775
+**
22776
+** The following fields are initialized when this object is created and
22777
+** are read-only thereafter:
22778
+**
22779
+** os2Shm.pShmNode
22780
+** os2Shm.id
22781
+**
22782
+** All other fields are read/write. The os2Shm.pShmNode->mutex must be held
22783
+** while accessing any read/write fields.
22784
+*/
22785
+struct os2ShmLink {
22786
+ os2ShmNode *pShmNode; /* The underlying os2ShmNode object */
22787
+ os2ShmLink *pNext; /* Next os2Shm with the same os2ShmNode */
22788
+ u32 sharedMask; /* Mask of shared locks held */
22789
+ u32 exclMask; /* Mask of exclusive locks held */
22790
+#ifdef SQLITE_DEBUG
22791
+ u8 id; /* Id of this connection with its os2ShmNode */
22792
+#endif
22793
+};
22794
+
22795
+
22796
+/*
22797
+** A global list of all os2ShmNode objects.
22798
+**
22799
+** The os2ShmMutexHeld() must be true while reading or writing this list.
22800
+*/
22801
+static os2ShmNode *os2ShmNodeList = NULL;
22802
+
22803
+/*
22804
+** Constants used for locking
22805
+*/
22806
+#ifdef SQLITE_OS2_NO_WAL_LOCK_FILE
22807
+#define OS2_SHM_BASE (PENDING_BYTE + 0x10000) /* first lock byte */
22808
+#else
22809
+#define OS2_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */
22810
+#endif
22811
+
22812
+#define OS2_SHM_DMS (OS2_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */
22813
+
22814
+/*
22815
+** Apply advisory locks for all n bytes beginning at ofst.
22816
+*/
22817
+#define _SHM_UNLCK 1 /* no lock */
22818
+#define _SHM_RDLCK 2 /* shared lock, no wait */
22819
+#define _SHM_WRLCK 3 /* exlusive lock, no wait */
22820
+#define _SHM_WRLCK_WAIT 4 /* exclusive lock, wait */
22821
+static int os2ShmSystemLock(
22822
+ os2ShmNode *pNode, /* Apply locks to this open shared-memory segment */
22823
+ int lockType, /* _SHM_UNLCK, _SHM_RDLCK, _SHM_WRLCK or _SHM_WRLCK_WAIT */
22824
+ int ofst, /* Offset to first byte to be locked/unlocked */
22825
+ int nByte /* Number of bytes to lock or unlock */
22826
+){
22827
+ APIRET rc;
22828
+ FILELOCK area;
22829
+ ULONG mode, timeout;
22830
+
22831
+ /* Access to the os2ShmNode object is serialized by the caller */
22832
+ assert( sqlite3_mutex_held(pNode->mutex) || pNode->nRef==0 );
22833
+
22834
+ mode = 1; /* shared lock */
22835
+ timeout = 0; /* no wait */
22836
+ area.lOffset = ofst;
22837
+ area.lRange = nByte;
22838
+
22839
+ switch( lockType ) {
22840
+ case _SHM_WRLCK_WAIT:
22841
+ timeout = (ULONG)-1; /* wait forever */
22842
+ case _SHM_WRLCK:
22843
+ mode = 0; /* exclusive lock */
22844
+ case _SHM_RDLCK:
22845
+ rc = DosSetFileLocks(pNode->hLockFile,
22846
+ NULL, &area, timeout, mode);
22847
+ break;
22848
+ /* case _SHM_UNLCK: */
22849
+ default:
22850
+ rc = DosSetFileLocks(pNode->hLockFile,
22851
+ &area, NULL, 0, 0);
22852
+ break;
22853
+ }
22854
+
22855
+ OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n",
22856
+ pNode->hLockFile,
22857
+ rc==SQLITE_OK ? "ok" : "failed",
22858
+ lockType==_SHM_UNLCK ? "Unlock" : "Lock",
22859
+ rc));
22860
+
22861
+ ERR_TRACE(rc, ("os2ShmSystemLock: %d %s\n", rc, pNode->shmBaseName))
22862
+
22863
+ return ( rc == 0 ) ? SQLITE_OK : SQLITE_BUSY;
22864
+}
22865
+
22866
+/*
22867
+** Find an os2ShmNode in global list or allocate a new one, if not found.
22868
+**
22869
+** This is not a VFS shared-memory method; it is a utility function called
22870
+** by VFS shared-memory methods.
22871
+*/
22872
+static int os2OpenSharedMemory( os2File *fd, int szRegion ) {
22873
+ os2ShmLink *pLink;
22874
+ os2ShmNode *pNode;
22875
+ int cbShmName, rc = SQLITE_OK;
22876
+ char shmName[CCHMAXPATH + 30];
22877
+#ifndef SQLITE_OS2_NO_WAL_LOCK_FILE
22878
+ ULONG action;
22879
+#endif
22880
+
22881
+ /* We need some additional space at the end to append the region number */
22882
+ cbShmName = sprintf(shmName, "\\SHAREMEM\\%s", fd->zFullPathCp );
22883
+ if( cbShmName >= CCHMAXPATH-8 )
22884
+ return SQLITE_IOERR_SHMOPEN;
22885
+
22886
+ /* Replace colon in file name to form a valid shared memory name */
22887
+ shmName[10+1] = '!';
22888
+
22889
+ /* Allocate link object (we free it later in case of failure) */
22890
+ pLink = sqlite3_malloc( sizeof(*pLink) );
22891
+ if( !pLink )
22892
+ return SQLITE_NOMEM;
22893
+
22894
+ /* Access node list */
22895
+ os2ShmEnterMutex();
22896
+
22897
+ /* Find node by it's shared memory base name */
22898
+ for( pNode = os2ShmNodeList;
22899
+ pNode && stricmp(shmName, pNode->shmBaseName) != 0;
22900
+ pNode = pNode->pNext ) ;
22901
+
22902
+ /* Not found: allocate a new node */
22903
+ if( !pNode ) {
22904
+ pNode = sqlite3_malloc( sizeof(*pNode) + cbShmName );
22905
+ if( pNode ) {
22906
+ memset(pNode, 0, sizeof(*pNode) );
22907
+ pNode->szRegion = szRegion;
22908
+ pNode->hLockFile = (HFILE)-1;
22909
+ strcpy(pNode->shmBaseName, shmName);
22910
+
22911
+#ifdef SQLITE_OS2_NO_WAL_LOCK_FILE
22912
+ if( DosDupHandle(fd->h, &pNode->hLockFile) != 0 ) {
22913
+#else
22914
+ sprintf(shmName, "%s-lck", fd->zFullPathCp);
22915
+ if( DosOpen((PSZ)shmName, &pNode->hLockFile, &action, 0, FILE_NORMAL,
22916
+ OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW,
22917
+ OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE |
22918
+ OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR,
22919
+ NULL) != 0 ) {
22920
+#endif
22921
+ sqlite3_free(pNode);
22922
+ rc = SQLITE_IOERR;
22923
+ } else {
22924
+ pNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
22925
+ if( !pNode->mutex ) {
22926
+ sqlite3_free(pNode);
22927
+ rc = SQLITE_NOMEM;
22928
+ }
22929
+ }
22930
+ } else {
22931
+ rc = SQLITE_NOMEM;
22932
+ }
22933
+
22934
+ if( rc == SQLITE_OK ) {
22935
+ pNode->pNext = os2ShmNodeList;
22936
+ os2ShmNodeList = pNode;
22937
+ } else {
22938
+ pNode = NULL;
22939
+ }
22940
+ } else if( pNode->szRegion != szRegion ) {
22941
+ rc = SQLITE_IOERR_SHMSIZE;
22942
+ pNode = NULL;
22943
+ }
22944
+
22945
+ if( pNode ) {
22946
+ sqlite3_mutex_enter(pNode->mutex);
22947
+
22948
+ memset(pLink, 0, sizeof(*pLink));
22949
+
22950
+ pLink->pShmNode = pNode;
22951
+ pLink->pNext = pNode->pFirst;
22952
+ pNode->pFirst = pLink;
22953
+ pNode->nRef++;
22954
+
22955
+ fd->pShmLink = pLink;
22956
+
22957
+ sqlite3_mutex_leave(pNode->mutex);
22958
+
22959
+ } else {
22960
+ /* Error occured. Free our link object. */
22961
+ sqlite3_free(pLink);
22962
+ }
22963
+
22964
+ os2ShmLeaveMutex();
22965
+
22966
+ ERR_TRACE(rc, ("os2OpenSharedMemory: %d %s\n", rc, fd->zFullPathCp))
22967
+
22968
+ return rc;
22969
+}
22970
+
22971
+/*
22972
+** Purge the os2ShmNodeList list of all entries with nRef==0.
22973
+**
22974
+** This is not a VFS shared-memory method; it is a utility function called
22975
+** by VFS shared-memory methods.
22976
+*/
22977
+static void os2PurgeShmNodes( int deleteFlag ) {
22978
+ os2ShmNode *pNode;
22979
+ os2ShmNode **ppNode;
22980
+
22981
+ os2ShmEnterMutex();
22982
+
22983
+ ppNode = &os2ShmNodeList;
22984
+
22985
+ while( *ppNode ) {
22986
+ pNode = *ppNode;
22987
+
22988
+ if( pNode->nRef == 0 ) {
22989
+ *ppNode = pNode->pNext;
22990
+
22991
+ if( pNode->apRegion ) {
22992
+ /* Prevent other processes from resizing the shared memory */
22993
+ os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1);
22994
+
22995
+ while( pNode->nRegion-- ) {
22996
+#ifdef SQLITE_DEBUG
22997
+ int rc =
22998
+#endif
22999
+ DosFreeMem(pNode->apRegion[pNode->nRegion]);
23000
+
23001
+ OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n",
23002
+ (int)GetCurrentProcessId(), pNode->nRegion,
23003
+ rc == 0 ? "ok" : "failed"));
23004
+ }
23005
+
23006
+ /* Allow other processes to resize the shared memory */
23007
+ os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1);
23008
+
23009
+ sqlite3_free(pNode->apRegion);
23010
+ }
23011
+
23012
+ DosClose(pNode->hLockFile);
23013
+
23014
+#ifndef SQLITE_OS2_NO_WAL_LOCK_FILE
23015
+ if( deleteFlag ) {
23016
+ char fileName[CCHMAXPATH];
23017
+ /* Skip "\\SHAREMEM\\" */
23018
+ sprintf(fileName, "%s-lck", pNode->shmBaseName + 10);
23019
+ /* restore colon */
23020
+ fileName[1] = ':';
23021
+
23022
+ DosForceDelete(fileName);
23023
+ }
23024
+#endif
23025
+
23026
+ sqlite3_mutex_free(pNode->mutex);
23027
+
23028
+ sqlite3_free(pNode);
23029
+
23030
+ } else {
23031
+ ppNode = &pNode->pNext;
23032
+ }
23033
+ }
23034
+
23035
+ os2ShmLeaveMutex();
23036
+}
23037
+
23038
+/*
23039
+** This function is called to obtain a pointer to region iRegion of the
23040
+** shared-memory associated with the database file id. Shared-memory regions
23041
+** are numbered starting from zero. Each shared-memory region is szRegion
23042
+** bytes in size.
23043
+**
23044
+** If an error occurs, an error code is returned and *pp is set to NULL.
23045
+**
23046
+** Otherwise, if the bExtend parameter is 0 and the requested shared-memory
23047
+** region has not been allocated (by any client, including one running in a
23048
+** separate process), then *pp is set to NULL and SQLITE_OK returned. If
23049
+** bExtend is non-zero and the requested shared-memory region has not yet
23050
+** been allocated, it is allocated by this function.
23051
+**
23052
+** If the shared-memory region has already been allocated or is allocated by
23053
+** this call as described above, then it is mapped into this processes
23054
+** address space (if it is not already), *pp is set to point to the mapped
23055
+** memory and SQLITE_OK returned.
23056
+*/
23057
+static int os2ShmMap(
23058
+ sqlite3_file *id, /* Handle open on database file */
23059
+ int iRegion, /* Region to retrieve */
23060
+ int szRegion, /* Size of regions */
23061
+ int bExtend, /* True to extend block if necessary */
23062
+ void volatile **pp /* OUT: Mapped memory */
23063
+){
23064
+ PVOID pvTemp;
23065
+ void **apRegion;
23066
+ os2ShmNode *pNode;
23067
+ int n, rc = SQLITE_OK;
23068
+ char shmName[CCHMAXPATH];
23069
+ os2File *pFile = (os2File*)id;
23070
+
23071
+ *pp = NULL;
23072
+
23073
+ if( !pFile->pShmLink )
23074
+ rc = os2OpenSharedMemory( pFile, szRegion );
23075
+
23076
+ if( rc == SQLITE_OK ) {
23077
+ pNode = pFile->pShmLink->pShmNode ;
23078
+
23079
+ sqlite3_mutex_enter(pNode->mutex);
23080
+
23081
+ assert( szRegion==pNode->szRegion );
23082
+
23083
+ /* Unmapped region ? */
23084
+ if( iRegion >= pNode->nRegion ) {
23085
+ /* Prevent other processes from resizing the shared memory */
23086
+ os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1);
23087
+
23088
+ apRegion = sqlite3_realloc(
23089
+ pNode->apRegion, (iRegion + 1) * sizeof(apRegion[0]));
23090
+
23091
+ if( apRegion ) {
23092
+ pNode->apRegion = apRegion;
23093
+
23094
+ while( pNode->nRegion <= iRegion ) {
23095
+ sprintf(shmName, "%s-%u",
23096
+ pNode->shmBaseName, pNode->nRegion);
23097
+
23098
+ if( DosGetNamedSharedMem(&pvTemp, (PSZ)shmName,
23099
+ PAG_READ | PAG_WRITE) != NO_ERROR ) {
23100
+ if( !bExtend )
23101
+ break;
23102
+
23103
+ if( DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion,
23104
+ PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_ANY) != NO_ERROR &&
23105
+ DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion,
23106
+ PAG_READ | PAG_WRITE | PAG_COMMIT) != NO_ERROR ) {
23107
+ rc = SQLITE_NOMEM;
23108
+ break;
23109
+ }
23110
+ }
23111
+
23112
+ apRegion[pNode->nRegion++] = pvTemp;
23113
+ }
23114
+
23115
+ /* zero out remaining entries */
23116
+ for( n = pNode->nRegion; n <= iRegion; n++ )
23117
+ pNode->apRegion[n] = NULL;
23118
+
23119
+ /* Return this region (maybe zero) */
23120
+ *pp = pNode->apRegion[iRegion];
23121
+ } else {
23122
+ rc = SQLITE_NOMEM;
23123
+ }
23124
+
23125
+ /* Allow other processes to resize the shared memory */
23126
+ os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1);
23127
+
23128
+ } else {
23129
+ /* Region has been mapped previously */
23130
+ *pp = pNode->apRegion[iRegion];
23131
+ }
23132
+
23133
+ sqlite3_mutex_leave(pNode->mutex);
23134
+ }
23135
+
23136
+ ERR_TRACE(rc, ("os2ShmMap: %s iRgn = %d, szRgn = %d, bExt = %d : %d\n",
23137
+ pFile->zFullPathCp, iRegion, szRegion, bExtend, rc))
23138
+
23139
+ return rc;
23140
+}
23141
+
23142
+/*
23143
+** Close a connection to shared-memory. Delete the underlying
23144
+** storage if deleteFlag is true.
23145
+**
23146
+** If there is no shared memory associated with the connection then this
23147
+** routine is a harmless no-op.
23148
+*/
23149
+static int os2ShmUnmap(
23150
+ sqlite3_file *id, /* The underlying database file */
23151
+ int deleteFlag /* Delete shared-memory if true */
23152
+){
23153
+ os2File *pFile = (os2File*)id;
23154
+ os2ShmLink *pLink = pFile->pShmLink;
23155
+
23156
+ if( pLink ) {
23157
+ int nRef = -1;
23158
+ os2ShmLink **ppLink;
23159
+ os2ShmNode *pNode = pLink->pShmNode;
23160
+
23161
+ sqlite3_mutex_enter(pNode->mutex);
23162
+
23163
+ for( ppLink = &pNode->pFirst;
23164
+ *ppLink && *ppLink != pLink;
23165
+ ppLink = &(*ppLink)->pNext ) ;
23166
+
23167
+ assert(*ppLink);
23168
+
23169
+ if( *ppLink ) {
23170
+ *ppLink = pLink->pNext;
23171
+ nRef = --pNode->nRef;
23172
+ } else {
23173
+ ERR_TRACE(1, ("os2ShmUnmap: link not found ! %s\n",
23174
+ pNode->shmBaseName))
23175
+ }
23176
+
23177
+ pFile->pShmLink = NULL;
23178
+ sqlite3_free(pLink);
23179
+
23180
+ sqlite3_mutex_leave(pNode->mutex);
23181
+
23182
+ if( nRef == 0 )
23183
+ os2PurgeShmNodes( deleteFlag );
23184
+ }
23185
+
23186
+ return SQLITE_OK;
23187
+}
23188
+
23189
+/*
23190
+** Change the lock state for a shared-memory segment.
23191
+**
23192
+** Note that the relationship between SHAREd and EXCLUSIVE locks is a little
23193
+** different here than in posix. In xShmLock(), one can go from unlocked
23194
+** to shared and back or from unlocked to exclusive and back. But one may
23195
+** not go from shared to exclusive or from exclusive to shared.
23196
+*/
23197
+static int os2ShmLock(
23198
+ sqlite3_file *id, /* Database file holding the shared memory */
23199
+ int ofst, /* First lock to acquire or release */
23200
+ int n, /* Number of locks to acquire or release */
23201
+ int flags /* What to do with the lock */
23202
+){
23203
+ u32 mask; /* Mask of locks to take or release */
23204
+ int rc = SQLITE_OK; /* Result code */
23205
+ os2File *pFile = (os2File*)id;
23206
+ os2ShmLink *p = pFile->pShmLink; /* The shared memory being locked */
23207
+ os2ShmLink *pX; /* For looping over all siblings */
23208
+ os2ShmNode *pShmNode = p->pShmNode; /* Our node */
23209
+
23210
+ assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
23211
+ assert( n>=1 );
23212
+ assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
23213
+ || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
23214
+ || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
23215
+ || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
23216
+ assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
23217
+
23218
+ mask = (u32)((1U<<(ofst+n)) - (1U<<ofst));
23219
+ assert( n>1 || mask==(1<<ofst) );
23220
+
23221
+
23222
+ sqlite3_mutex_enter(pShmNode->mutex);
23223
+
23224
+ if( flags & SQLITE_SHM_UNLOCK ){
23225
+ u32 allMask = 0; /* Mask of locks held by siblings */
23226
+
23227
+ /* See if any siblings hold this same lock */
23228
+ for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
23229
+ if( pX==p ) continue;
23230
+ assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
23231
+ allMask |= pX->sharedMask;
23232
+ }
23233
+
23234
+ /* Unlock the system-level locks */
23235
+ if( (mask & allMask)==0 ){
23236
+ rc = os2ShmSystemLock(pShmNode, _SHM_UNLCK, ofst+OS2_SHM_BASE, n);
23237
+ }else{
23238
+ rc = SQLITE_OK;
23239
+ }
23240
+
23241
+ /* Undo the local locks */
23242
+ if( rc==SQLITE_OK ){
23243
+ p->exclMask &= ~mask;
23244
+ p->sharedMask &= ~mask;
23245
+ }
23246
+ }else if( flags & SQLITE_SHM_SHARED ){
23247
+ u32 allShared = 0; /* Union of locks held by connections other than "p" */
23248
+
23249
+ /* Find out which shared locks are already held by sibling connections.
23250
+ ** If any sibling already holds an exclusive lock, go ahead and return
23251
+ ** SQLITE_BUSY.
23252
+ */
23253
+ for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
23254
+ if( (pX->exclMask & mask)!=0 ){
23255
+ rc = SQLITE_BUSY;
23256
+ break;
23257
+ }
23258
+ allShared |= pX->sharedMask;
23259
+ }
23260
+
23261
+ /* Get shared locks at the system level, if necessary */
23262
+ if( rc==SQLITE_OK ){
23263
+ if( (allShared & mask)==0 ){
23264
+ rc = os2ShmSystemLock(pShmNode, _SHM_RDLCK, ofst+OS2_SHM_BASE, n);
23265
+ }else{
23266
+ rc = SQLITE_OK;
23267
+ }
23268
+ }
23269
+
23270
+ /* Get the local shared locks */
23271
+ if( rc==SQLITE_OK ){
23272
+ p->sharedMask |= mask;
23273
+ }
23274
+ }else{
23275
+ /* Make sure no sibling connections hold locks that will block this
23276
+ ** lock. If any do, return SQLITE_BUSY right away.
23277
+ */
23278
+ for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
23279
+ if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
23280
+ rc = SQLITE_BUSY;
23281
+ break;
23282
+ }
23283
+ }
23284
+
23285
+ /* Get the exclusive locks at the system level. Then if successful
23286
+ ** also mark the local connection as being locked.
23287
+ */
23288
+ if( rc==SQLITE_OK ){
23289
+ rc = os2ShmSystemLock(pShmNode, _SHM_WRLCK, ofst+OS2_SHM_BASE, n);
23290
+ if( rc==SQLITE_OK ){
23291
+ assert( (p->sharedMask & mask)==0 );
23292
+ p->exclMask |= mask;
23293
+ }
23294
+ }
23295
+ }
23296
+
23297
+ sqlite3_mutex_leave(pShmNode->mutex);
23298
+
23299
+ OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n",
23300
+ p->id, (int)GetCurrentProcessId(), p->sharedMask, p->exclMask,
23301
+ rc ? "failed" : "ok"));
23302
+
23303
+ ERR_TRACE(rc, ("os2ShmLock: ofst = %d, n = %d, flags = 0x%x -> %d \n",
23304
+ ofst, n, flags, rc))
23305
+
23306
+ return rc;
23307
+}
23308
+
23309
+/*
23310
+** Implement a memory barrier or memory fence on shared memory.
23311
+**
23312
+** All loads and stores begun before the barrier must complete before
23313
+** any load or store begun after the barrier.
23314
+*/
23315
+static void os2ShmBarrier(
23316
+ sqlite3_file *id /* Database file holding the shared memory */
23317
+){
23318
+ UNUSED_PARAMETER(id);
23319
+ os2ShmEnterMutex();
23320
+ os2ShmLeaveMutex();
23321
+}
23322
+
23323
+#else
23324
+# define os2ShmMap 0
23325
+# define os2ShmLock 0
23326
+# define os2ShmBarrier 0
23327
+# define os2ShmUnmap 0
23328
+#endif /* #ifndef SQLITE_OMIT_WAL */
23329
+
2263523330
2263623331
/*
2263723332
** This vector defines all the methods that can operate on an
2263823333
** sqlite3_file for os2.
2263923334
*/
2264023335
static const sqlite3_io_methods os2IoMethod = {
22641
- 1, /* iVersion */
23336
+ 2, /* iVersion */
2264223337
os2Close, /* xClose */
2264323338
os2Read, /* xRead */
2264423339
os2Write, /* xWrite */
2264523340
os2Truncate, /* xTruncate */
2264623341
os2Sync, /* xSync */
@@ -22649,15 +23344,16 @@
2264923344
os2Unlock, /* xUnlock */
2265023345
os2CheckReservedLock, /* xCheckReservedLock */
2265123346
os2FileControl, /* xFileControl */
2265223347
os2SectorSize, /* xSectorSize */
2265323348
os2DeviceCharacteristics, /* xDeviceCharacteristics */
22654
- 0, /* xShmMap */
22655
- 0, /* xShmLock */
22656
- 0, /* xShmBarrier */
22657
- 0 /* xShmUnmap */
23349
+ os2ShmMap, /* xShmMap */
23350
+ os2ShmLock, /* xShmLock */
23351
+ os2ShmBarrier, /* xShmBarrier */
23352
+ os2ShmUnmap /* xShmUnmap */
2265823353
};
23354
+
2265923355
2266023356
/***************************************************************************
2266123357
** Here ends the I/O methods that form the sqlite3_io_methods object.
2266223358
**
2266323359
** The next block of code implements the VFS methods.
@@ -22666,54 +23362,61 @@
2266623362
/*
2266723363
** Create a temporary file name in zBuf. zBuf must be big enough to
2266823364
** hold at pVfs->mxPathname characters.
2266923365
*/
2267023366
static int getTempname(int nBuf, char *zBuf ){
22671
- static const unsigned char zChars[] =
23367
+ static const char zChars[] =
2267223368
"abcdefghijklmnopqrstuvwxyz"
2267323369
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
2267423370
"0123456789";
2267523371
int i, j;
22676
- char zTempPathBuf[3];
22677
- PSZ zTempPath = (PSZ)&zTempPathBuf;
22678
- if( sqlite3_temp_directory ){
22679
- zTempPath = sqlite3_temp_directory;
22680
- }else{
22681
- if( DosScanEnv( (PSZ)"TEMP", &zTempPath ) ){
22682
- if( DosScanEnv( (PSZ)"TMP", &zTempPath ) ){
22683
- if( DosScanEnv( (PSZ)"TMPDIR", &zTempPath ) ){
22684
- ULONG ulDriveNum = 0, ulDriveMap = 0;
22685
- DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap );
22686
- sprintf( (char*)zTempPath, "%c:", (char)( 'A' + ulDriveNum - 1 ) );
22687
- }
22688
- }
22689
- }
22690
- }
23372
+ PSZ zTempPathCp;
23373
+ char zTempPath[CCHMAXPATH];
23374
+ ULONG ulDriveNum, ulDriveMap;
23375
+
23376
+ /* It's odd to simulate an io-error here, but really this is just
23377
+ ** using the io-error infrastructure to test that SQLite handles this
23378
+ ** function failing.
23379
+ */
23380
+ SimulateIOError( return SQLITE_IOERR );
23381
+
23382
+ if( sqlite3_temp_directory ) {
23383
+ sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", sqlite3_temp_directory);
23384
+ } else if( DosScanEnv( (PSZ)"TEMP", &zTempPathCp ) == NO_ERROR ||
23385
+ DosScanEnv( (PSZ)"TMP", &zTempPathCp ) == NO_ERROR ||
23386
+ DosScanEnv( (PSZ)"TMPDIR", &zTempPathCp ) == NO_ERROR ) {
23387
+ char *zTempPathUTF = convertCpPathToUtf8( (char *)zTempPathCp );
23388
+ sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", zTempPathUTF);
23389
+ free( zTempPathUTF );
23390
+ } else if( DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ) == NO_ERROR ) {
23391
+ zTempPath[0] = (char)('A' + ulDriveNum - 1);
23392
+ zTempPath[1] = ':';
23393
+ zTempPath[2] = '\0';
23394
+ } else {
23395
+ zTempPath[0] = '\0';
23396
+ }
23397
+
2269123398
/* Strip off a trailing slashes or backslashes, otherwise we would get *
2269223399
* multiple (back)slashes which causes DosOpen() to fail. *
2269323400
* Trailing spaces are not allowed, either. */
2269423401
j = sqlite3Strlen30(zTempPath);
22695
- while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/'
22696
- || zTempPath[j-1] == ' ' ) ){
23402
+ while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/' ||
23403
+ zTempPath[j-1] == ' ' ) ){
2269723404
j--;
2269823405
}
2269923406
zTempPath[j] = '\0';
22700
- if( !sqlite3_temp_directory ){
22701
- char *zTempPathUTF = convertCpPathToUtf8( zTempPath );
22702
- sqlite3_snprintf( nBuf-30, zBuf,
22703
- "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPathUTF );
22704
- free( zTempPathUTF );
22705
- }else{
22706
- sqlite3_snprintf( nBuf-30, zBuf,
22707
- "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath );
22708
- }
22709
- j = sqlite3Strlen30( zBuf );
23407
+
23408
+ /* We use 20 bytes to randomize the name */
23409
+ sqlite3_snprintf(nBuf-22, zBuf,
23410
+ "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
23411
+ j = sqlite3Strlen30(zBuf);
2271023412
sqlite3_randomness( 20, &zBuf[j] );
2271123413
for( i = 0; i < 20; i++, j++ ){
22712
- zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
23414
+ zBuf[j] = zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
2271323415
}
2271423416
zBuf[j] = 0;
23417
+
2271523418
OSTRACE(( "TEMP FILENAME: %s\n", zBuf ));
2271623419
return SQLITE_OK;
2271723420
}
2271823421
2271923422
@@ -22729,12 +23432,12 @@
2272923432
char *zFull /* Output buffer */
2273023433
){
2273123434
char *zRelativeCp = convertUtf8PathToCp( zRelative );
2273223435
char zFullCp[CCHMAXPATH] = "\0";
2273323436
char *zFullUTF;
22734
- APIRET rc = DosQueryPathInfo( zRelativeCp, FIL_QUERYFULLNAME, zFullCp,
22735
- CCHMAXPATH );
23437
+ APIRET rc = DosQueryPathInfo( (PSZ)zRelativeCp, FIL_QUERYFULLNAME,
23438
+ zFullCp, CCHMAXPATH );
2273623439
free( zRelativeCp );
2273723440
zFullUTF = convertCpPathToUtf8( zFullCp );
2273823441
sqlite3_snprintf( nFull, zFull, zFullUTF );
2273923442
free( zFullUTF );
2274023443
return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
@@ -22760,14 +23463,14 @@
2276023463
const char *zUtf8Name = zName;
2276123464
char *zNameCp;
2276223465
char zTmpname[CCHMAXPATH];
2276323466
2276423467
int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
22765
- int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE);
2276623468
int isCreate = (flags & SQLITE_OPEN_CREATE);
2276723469
int isReadWrite = (flags & SQLITE_OPEN_READWRITE);
2276823470
#ifndef NDEBUG
23471
+ int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE);
2276923472
int isReadonly = (flags & SQLITE_OPEN_READONLY);
2277023473
int eType = (flags & 0xFFFFFF00);
2277123474
int isOpenJournal = (isCreate && (
2277223475
eType==SQLITE_OPEN_MASTER_JOURNAL
2277323476
|| eType==SQLITE_OPEN_MAIN_JOURNAL
@@ -22803,11 +23506,11 @@
2280323506
|| eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL
2280423507
|| eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
2280523508
);
2280623509
2280723510
memset( pFile, 0, sizeof(*pFile) );
22808
- pFile->pMethod = &os2IoMethod;
23511
+ pFile->h = (HFILE)-1;
2280923512
2281023513
/* If the second argument to this function is NULL, generate a
2281123514
** temporary file name to use
2281223515
*/
2281323516
if( !zUtf8Name ){
@@ -22825,15 +23528,15 @@
2282523528
ulOpenMode |= OPEN_ACCESS_READONLY;
2282623529
}
2282723530
2282823531
/* Open in random access mode for possibly better speed. Allow full
2282923532
** sharing because file locks will provide exclusive access when needed.
23533
+ ** The handle should not be inherited by child processes and we don't
23534
+ ** want popups from the critical error handler.
2283023535
*/
22831
- ulOpenMode |= OPEN_FLAGS_RANDOM;
22832
- ulOpenMode |= OPEN_FLAGS_FAIL_ON_ERROR;
22833
- ulOpenMode |= OPEN_FLAGS_NOINHERIT;
22834
- ulOpenMode |= OPEN_SHARE_DENYNONE;
23536
+ ulOpenMode |= OPEN_FLAGS_RANDOM | OPEN_SHARE_DENYNONE |
23537
+ OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR;
2283523538
2283623539
/* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is
2283723540
** created. SQLite doesn't use it to indicate "exclusive access"
2283823541
** as it is usually understood.
2283923542
*/
@@ -22847,17 +23550,10 @@
2284723550
}else{
2284823551
/* Opens a file, only if it exists. */
2284923552
ulOpenFlags |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
2285023553
}
2285123554
22852
- /* For DELETEONCLOSE, save a pointer to the converted filename */
22853
- if( isDelete ){
22854
- char pathUtf8[CCHMAXPATH];
22855
- os2FullPathname( pVfs, zUtf8Name, CCHMAXPATH, pathUtf8 );
22856
- pFile->pathToDel = convertUtf8PathToCp( pathUtf8 );
22857
- }
22858
-
2285923555
zNameCp = convertUtf8PathToCp( zUtf8Name );
2286023556
rc = DosOpen( (PSZ)zNameCp,
2286123557
&h,
2286223558
&ulAction,
2286323559
0L,
@@ -22868,13 +23564,10 @@
2286823564
free( zNameCp );
2286923565
2287023566
if( rc != NO_ERROR ){
2287123567
OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulFlags=%#lx, ulMode=%#lx\n",
2287223568
rc, zUtf8Name, ulAction, ulOpenFlags, ulOpenMode ));
22873
- if( pFile->pathToDel )
22874
- free( pFile->pathToDel );
22875
- pFile->pathToDel = NULL;
2287623569
2287723570
if( isReadWrite ){
2287823571
return os2Open( pVfs, zName, id,
2287923572
((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
2288023573
pOutFlags );
@@ -22885,11 +23578,16 @@
2288523578
2288623579
if( pOutFlags ){
2288723580
*pOutFlags = isReadWrite ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY;
2288823581
}
2288923582
23583
+ os2FullPathname( pVfs, zUtf8Name, sizeof( zTmpname ), zTmpname );
23584
+ pFile->zFullPathCp = convertUtf8PathToCp( zTmpname );
23585
+ pFile->pMethod = &os2IoMethod;
23586
+ pFile->flags = flags;
2289023587
pFile->h = h;
23588
+
2289123589
OpenCounter(+1);
2289223590
OSTRACE(( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags ));
2289323591
return SQLITE_OK;
2289423592
}
2289523593
@@ -22920,34 +23618,46 @@
2292023618
sqlite3_vfs *pVfs, /* Not used on os2 */
2292123619
const char *zFilename, /* Name of file to check */
2292223620
int flags, /* Type of test to make on this file */
2292323621
int *pOut /* Write results here */
2292423622
){
23623
+ APIRET rc;
2292523624
FILESTATUS3 fsts3ConfigInfo;
22926
- APIRET rc = NO_ERROR;
22927
- char *zFilenameCp = convertUtf8PathToCp( zFilename );
23625
+ char *zFilenameCp;
2292823626
22929
- memset( &fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo) );
23627
+ UNUSED_PARAMETER(pVfs);
23628
+ SimulateIOError( return SQLITE_IOERR_ACCESS; );
23629
+
23630
+ zFilenameCp = convertUtf8PathToCp( zFilename );
2293023631
rc = DosQueryPathInfo( (PSZ)zFilenameCp, FIL_STANDARD,
2293123632
&fsts3ConfigInfo, sizeof(FILESTATUS3) );
2293223633
free( zFilenameCp );
2293323634
OSTRACE(( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n",
2293423635
fsts3ConfigInfo.attrFile, flags, rc ));
23636
+
2293523637
switch( flags ){
22936
- case SQLITE_ACCESS_READ:
2293723638
case SQLITE_ACCESS_EXISTS:
22938
- rc = (rc == NO_ERROR);
22939
- OSTRACE(( "ACCESS %s access of read and exists rc=%d\n", zFilename, rc));
23639
+ /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
23640
+ ** as if it does not exist.
23641
+ */
23642
+ if( fsts3ConfigInfo.cbFile == 0 )
23643
+ rc = ERROR_FILE_NOT_FOUND;
23644
+ break;
23645
+ case SQLITE_ACCESS_READ:
2294023646
break;
2294123647
case SQLITE_ACCESS_READWRITE:
22942
- rc = (rc == NO_ERROR) && ( (fsts3ConfigInfo.attrFile & FILE_READONLY) == 0 );
22943
- OSTRACE(( "ACCESS %s access of read/write rc=%d\n", zFilename, rc ));
23648
+ if( fsts3ConfigInfo.attrFile & FILE_READONLY )
23649
+ rc = ERROR_ACCESS_DENIED;
2294423650
break;
2294523651
default:
23652
+ rc = ERROR_FILE_NOT_FOUND;
2294623653
assert( !"Invalid flags argument" );
2294723654
}
22948
- *pOut = rc;
23655
+
23656
+ *pOut = (rc == NO_ERROR);
23657
+ OSTRACE(( "ACCESS %s flags %d: rc=%d\n", zFilename, flags, *pOut ));
23658
+
2294923659
return SQLITE_OK;
2295023660
}
2295123661
2295223662
2295323663
#ifndef SQLITE_OMIT_LOAD_EXTENSION
@@ -22958,15 +23668,14 @@
2295823668
/*
2295923669
** Interfaces for opening a shared library, finding entry points
2296023670
** within the shared library, and closing the shared library.
2296123671
*/
2296223672
static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){
22963
- UCHAR loadErr[256];
2296423673
HMODULE hmod;
2296523674
APIRET rc;
2296623675
char *zFilenameCp = convertUtf8PathToCp(zFilename);
22967
- rc = DosLoadModule((PSZ)loadErr, sizeof(loadErr), zFilenameCp, &hmod);
23676
+ rc = DosLoadModule(NULL, 0, (PSZ)zFilenameCp, &hmod);
2296823677
free(zFilenameCp);
2296923678
return rc != NO_ERROR ? 0 : (void*)hmod;
2297023679
}
2297123680
/*
2297223681
** A no-op since the error code is returned on the DosLoadModule call.
@@ -22976,18 +23685,18 @@
2297623685
/* no-op */
2297723686
}
2297823687
static void (*os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
2297923688
PFN pfn;
2298023689
APIRET rc;
22981
- rc = DosQueryProcAddr((HMODULE)pHandle, 0L, zSymbol, &pfn);
23690
+ rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)zSymbol, &pfn);
2298223691
if( rc != NO_ERROR ){
2298323692
/* if the symbol itself was not found, search again for the same
2298423693
* symbol with an extra underscore, that might be needed depending
2298523694
* on the calling convention */
2298623695
char _zSymbol[256] = "_";
22987
- strncat(_zSymbol, zSymbol, 255);
22988
- rc = DosQueryProcAddr((HMODULE)pHandle, 0L, _zSymbol, &pfn);
23696
+ strncat(_zSymbol, zSymbol, 254);
23697
+ rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)_zSymbol, &pfn);
2298923698
}
2299023699
return rc != NO_ERROR ? 0 : (void(*)(void))pfn;
2299123700
}
2299223701
static void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){
2299323702
DosFreeModule((HMODULE)pHandle);
@@ -23007,58 +23716,43 @@
2300723716
int n = 0;
2300823717
#if defined(SQLITE_TEST)
2300923718
n = nBuf;
2301023719
memset(zBuf, 0, nBuf);
2301123720
#else
23012
- int sizeofULong = sizeof(ULONG);
23013
- if( (int)sizeof(DATETIME) <= nBuf - n ){
23014
- DATETIME x;
23015
- DosGetDateTime(&x);
23016
- memcpy(&zBuf[n], &x, sizeof(x));
23017
- n += sizeof(x);
23018
- }
23019
-
23020
- if( sizeofULong <= nBuf - n ){
23021
- PPIB ppib;
23022
- DosGetInfoBlocks(NULL, &ppib);
23023
- memcpy(&zBuf[n], &ppib->pib_ulpid, sizeofULong);
23024
- n += sizeofULong;
23025
- }
23026
-
23027
- if( sizeofULong <= nBuf - n ){
23028
- PTIB ptib;
23029
- DosGetInfoBlocks(&ptib, NULL);
23030
- memcpy(&zBuf[n], &ptib->tib_ptib2->tib2_ultid, sizeofULong);
23031
- n += sizeofULong;
23032
- }
23033
-
23034
- /* if we still haven't filled the buffer yet the following will */
23035
- /* grab everything once instead of making several calls for a single item */
23036
- if( sizeofULong <= nBuf - n ){
23037
- ULONG ulSysInfo[QSV_MAX];
23038
- DosQuerySysInfo(1L, QSV_MAX, ulSysInfo, sizeofULong * QSV_MAX);
23039
-
23040
- memcpy(&zBuf[n], &ulSysInfo[QSV_MS_COUNT - 1], sizeofULong);
23041
- n += sizeofULong;
23042
-
23043
- if( sizeofULong <= nBuf - n ){
23044
- memcpy(&zBuf[n], &ulSysInfo[QSV_TIMER_INTERVAL - 1], sizeofULong);
23045
- n += sizeofULong;
23046
- }
23047
- if( sizeofULong <= nBuf - n ){
23048
- memcpy(&zBuf[n], &ulSysInfo[QSV_TIME_LOW - 1], sizeofULong);
23049
- n += sizeofULong;
23050
- }
23051
- if( sizeofULong <= nBuf - n ){
23052
- memcpy(&zBuf[n], &ulSysInfo[QSV_TIME_HIGH - 1], sizeofULong);
23053
- n += sizeofULong;
23054
- }
23055
- if( sizeofULong <= nBuf - n ){
23056
- memcpy(&zBuf[n], &ulSysInfo[QSV_TOTAVAILMEM - 1], sizeofULong);
23057
- n += sizeofULong;
23058
- }
23059
- }
23721
+ int i;
23722
+ PPIB ppib;
23723
+ PTIB ptib;
23724
+ DATETIME dt;
23725
+ static unsigned c = 0;
23726
+ /* Ordered by variation probability */
23727
+ static ULONG svIdx[6] = { QSV_MS_COUNT, QSV_TIME_LOW,
23728
+ QSV_MAXPRMEM, QSV_MAXSHMEM,
23729
+ QSV_TOTAVAILMEM, QSV_TOTRESMEM };
23730
+
23731
+ /* 8 bytes; timezone and weekday don't increase the randomness much */
23732
+ if( (int)sizeof(dt)-3 <= nBuf - n ){
23733
+ c += 0x0100;
23734
+ DosGetDateTime(&dt);
23735
+ dt.year = (USHORT)((dt.year - 1900) | c);
23736
+ memcpy(&zBuf[n], &dt, sizeof(dt)-3);
23737
+ n += sizeof(dt)-3;
23738
+ }
23739
+
23740
+ /* 4 bytes; PIDs and TIDs are 16 bit internally, so combine them */
23741
+ if( (int)sizeof(ULONG) <= nBuf - n ){
23742
+ DosGetInfoBlocks(&ptib, &ppib);
23743
+ *(PULONG)&zBuf[n] = MAKELONG(ppib->pib_ulpid,
23744
+ ptib->tib_ptib2->tib2_ultid);
23745
+ n += sizeof(ULONG);
23746
+ }
23747
+
23748
+ /* Up to 6 * 4 bytes; variables depend on the system state */
23749
+ for( i = 0; i < 6 && (int)sizeof(ULONG) <= nBuf - n; i++ ){
23750
+ DosQuerySysInfo(svIdx[i], svIdx[i],
23751
+ (PULONG)&zBuf[n], sizeof(ULONG));
23752
+ n += sizeof(ULONG);
23753
+ }
2306023754
#endif
2306123755
2306223756
return n;
2306323757
}
2306423758
@@ -23082,68 +23776,102 @@
2308223776
#ifdef SQLITE_TEST
2308323777
SQLITE_API int sqlite3_current_time = 0;
2308423778
#endif
2308523779
2308623780
/*
23087
-** Find the current time (in Universal Coordinated Time). Write the
23088
-** current time and date as a Julian Day number into *prNow and
23089
-** return 0. Return 1 if the time and date cannot be found.
23781
+** Find the current time (in Universal Coordinated Time). Write into *piNow
23782
+** the current time and date as a Julian Day number times 86_400_000. In
23783
+** other words, write into *piNow the number of milliseconds since the Julian
23784
+** epoch of noon in Greenwich on November 24, 4714 B.C according to the
23785
+** proleptic Gregorian calendar.
23786
+**
23787
+** On success, return 0. Return 1 if the time and date cannot be found.
2309023788
*/
23091
-int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){
23092
- double now;
23093
- SHORT minute; /* needs to be able to cope with negative timezone offset */
23094
- USHORT hundredths, second, hour,
23095
- day, month, year;
23789
+static int os2CurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
23790
+#ifdef SQLITE_TEST
23791
+ static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
23792
+#endif
23793
+ int year, month, datepart, timepart;
23794
+
2309623795
DATETIME dt;
2309723796
DosGetDateTime( &dt );
23098
- hundredths = (USHORT)dt.hundredths;
23099
- second = (USHORT)dt.seconds;
23100
- minute = (SHORT)dt.minutes + dt.timezone;
23101
- hour = (USHORT)dt.hours;
23102
- day = (USHORT)dt.day;
23103
- month = (USHORT)dt.month;
23104
- year = (USHORT)dt.year;
23797
+
23798
+ year = dt.year;
23799
+ month = dt.month;
2310523800
2310623801
/* Calculations from http://www.astro.keele.ac.uk/~rno/Astronomy/hjd.html
23107
- http://www.astro.keele.ac.uk/~rno/Astronomy/hjd-0.1.c */
23108
- /* Calculate the Julian days */
23109
- now = day - 32076 +
23802
+ ** http://www.astro.keele.ac.uk/~rno/Astronomy/hjd-0.1.c
23803
+ ** Calculate the Julian days
23804
+ */
23805
+ datepart = (int)dt.day - 32076 +
2311023806
1461*(year + 4800 + (month - 14)/12)/4 +
2311123807
367*(month - 2 - (month - 14)/12*12)/12 -
2311223808
3*((year + 4900 + (month - 14)/12)/100)/4;
2311323809
23114
- /* Add the fractional hours, mins and seconds */
23115
- now += (hour + 12.0)/24.0;
23116
- now += minute/1440.0;
23117
- now += second/86400.0;
23118
- now += hundredths/8640000.0;
23119
- *prNow = now;
23810
+ /* Time in milliseconds, hours to noon added */
23811
+ timepart = 12*3600*1000 + dt.hundredths*10 + dt.seconds*1000 +
23812
+ ((int)dt.minutes + dt.timezone)*60*1000 + dt.hours*3600*1000;
23813
+
23814
+ *piNow = (sqlite3_int64)datepart*86400*1000 + timepart;
23815
+
2312023816
#ifdef SQLITE_TEST
2312123817
if( sqlite3_current_time ){
23122
- *prNow = sqlite3_current_time/86400.0 + 2440587.5;
23818
+ *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
2312323819
}
2312423820
#endif
23821
+
23822
+ UNUSED_PARAMETER(pVfs);
2312523823
return 0;
2312623824
}
2312723825
2312823826
/*
23129
-** Find the current time (in Universal Coordinated Time). Write into *piNow
23130
-** the current time and date as a Julian Day number times 86_400_000. In
23131
-** other words, write into *piNow the number of milliseconds since the Julian
23132
-** epoch of noon in Greenwich on November 24, 4714 B.C according to the
23133
-** proleptic Gregorian calendar.
23134
-**
23135
-** On success, return 0. Return 1 if the time and date cannot be found.
23136
-*/
23137
-static int os2CurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
23138
- double now;
23139
- os2CurrentTime(pVfs, &now);
23140
- *piNow = now * 86400000;
23141
- return 0;
23142
-}
23143
-
23827
+** Find the current time (in Universal Coordinated Time). Write the
23828
+** current time and date as a Julian Day number into *prNow and
23829
+** return 0. Return 1 if the time and date cannot be found.
23830
+*/
23831
+static int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){
23832
+ int rc;
23833
+ sqlite3_int64 i;
23834
+ rc = os2CurrentTimeInt64(pVfs, &i);
23835
+ if( !rc ){
23836
+ *prNow = i/86400000.0;
23837
+ }
23838
+ return rc;
23839
+}
23840
+
23841
+/*
23842
+** The idea is that this function works like a combination of
23843
+** GetLastError() and FormatMessage() on windows (or errno and
23844
+** strerror_r() on unix). After an error is returned by an OS
23845
+** function, SQLite calls this function with zBuf pointing to
23846
+** a buffer of nBuf bytes. The OS layer should populate the
23847
+** buffer with a nul-terminated UTF-8 encoded error message
23848
+** describing the last IO error to have occurred within the calling
23849
+** thread.
23850
+**
23851
+** If the error message is too large for the supplied buffer,
23852
+** it should be truncated. The return value of xGetLastError
23853
+** is zero if the error message fits in the buffer, or non-zero
23854
+** otherwise (if the message was truncated). If non-zero is returned,
23855
+** then it is not necessary to include the nul-terminator character
23856
+** in the output buffer.
23857
+**
23858
+** Not supplying an error message will have no adverse effect
23859
+** on SQLite. It is fine to have an implementation that never
23860
+** returns an error message:
23861
+**
23862
+** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
23863
+** assert(zBuf[0]=='\0');
23864
+** return 0;
23865
+** }
23866
+**
23867
+** However if an error message is supplied, it will be incorporated
23868
+** by sqlite into the error message available to the user using
23869
+** sqlite3_errmsg(), possibly making IO errors easier to debug.
23870
+*/
2314423871
static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
23872
+ assert(zBuf[0]=='\0');
2314523873
return 0;
2314623874
}
2314723875
2314823876
/*
2314923877
** Initialize and deinitialize the operating system interface.
@@ -23167,17 +23895,18 @@
2316723895
os2DlClose, /* xDlClose */
2316823896
os2Randomness, /* xRandomness */
2316923897
os2Sleep, /* xSleep */
2317023898
os2CurrentTime, /* xCurrentTime */
2317123899
os2GetLastError, /* xGetLastError */
23172
- os2CurrentTimeInt64 /* xCurrentTimeInt64 */
23900
+ os2CurrentTimeInt64, /* xCurrentTimeInt64 */
2317323901
0, /* xSetSystemCall */
2317423902
0, /* xGetSystemCall */
23175
- 0, /* xNextSystemCall */
23903
+ 0 /* xNextSystemCall */
2317623904
};
2317723905
sqlite3_vfs_register(&os2Vfs, 1);
2317823906
initUconvObjects();
23907
+/* sqlite3OSTrace = 1; */
2317923908
return SQLITE_OK;
2318023909
}
2318123910
SQLITE_API int sqlite3_os_end(void){
2318223911
freeUconvObjects();
2318323912
return SQLITE_OK;
@@ -23752,12 +24481,14 @@
2375224481
{ "pwrite64", (sqlite3_syscall_ptr)0, 0 },
2375324482
#endif
2375424483
#define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
2375524484
aSyscall[13].pCurrent)
2375624485
24486
+#if SQLITE_ENABLE_LOCKING_STYLE
2375724487
{ "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
2375824488
#define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
24489
+#endif
2375924490
2376024491
#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
2376124492
{ "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 },
2376224493
#else
2376324494
{ "fallocate", (sqlite3_syscall_ptr)0, 0 },
@@ -54608,10 +55339,14 @@
5460855339
Pager * const pDestPager = sqlite3BtreePager(p->pDest);
5460955340
const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
5461055341
int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
5461155342
const int nCopy = MIN(nSrcPgsz, nDestPgsz);
5461255343
const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
55344
+#ifdef SQLITE_HAS_CODEC
55345
+ int nSrcReserve = sqlite3BtreeGetReserve(p->pSrc);
55346
+ int nDestReserve = sqlite3BtreeGetReserve(p->pDest);
55347
+#endif
5461355348
5461455349
int rc = SQLITE_OK;
5461555350
i64 iOff;
5461655351
5461755352
assert( p->bDestLocked );
@@ -54626,15 +55361,26 @@
5462655361
rc = SQLITE_READONLY;
5462755362
}
5462855363
5462955364
#ifdef SQLITE_HAS_CODEC
5463055365
/* Backup is not possible if the page size of the destination is changing
54631
- ** a a codec is in use.
55366
+ ** and a codec is in use.
5463255367
*/
5463355368
if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){
5463455369
rc = SQLITE_READONLY;
5463555370
}
55371
+
55372
+ /* Backup is not possible if the number of bytes of reserve space differ
55373
+ ** between source and destination. If there is a difference, try to
55374
+ ** fix the destination to agree with the source. If that is not possible,
55375
+ ** then the backup cannot proceed.
55376
+ */
55377
+ if( nSrcReserve!=nDestReserve ){
55378
+ u32 newPgsz = nSrcPgsz;
55379
+ rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
55380
+ if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY;
55381
+ }
5463655382
#endif
5463755383
5463855384
/* This loop runs once for each destination page spanned by the source
5463955385
** page. For each iteration, variable iOff is set to the byte offset
5464055386
** of the destination page.
@@ -54996,11 +55742,15 @@
5499655742
if( !isFatalError(p->rc) && iPage<p->iNext ){
5499755743
/* The backup process p has already copied page iPage. But now it
5499855744
** has been modified by a transaction on the source pager. Copy
5499955745
** the new data into the backup.
5500055746
*/
55001
- int rc = backupOnePage(p, iPage, aData);
55747
+ int rc;
55748
+ assert( p->pDestDb );
55749
+ sqlite3_mutex_enter(p->pDestDb->mutex);
55750
+ rc = backupOnePage(p, iPage, aData);
55751
+ sqlite3_mutex_leave(p->pDestDb->mutex);
5500255752
assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
5500355753
if( rc!=SQLITE_OK ){
5500455754
p->rc = rc;
5500555755
}
5500655756
}
@@ -74977,10 +75727,14 @@
7497775727
}
7497875728
if( i==0 ) pTable->nRowEst = v;
7497975729
if( pIndex==0 ) break;
7498075730
pIndex->aiRowEst[i] = v;
7498175731
if( *z==' ' ) z++;
75732
+ if( memcmp(z, "unordered", 10)==0 ){
75733
+ pIndex->bUnordered = 1;
75734
+ break;
75735
+ }
7498275736
}
7498375737
return 0;
7498475738
}
7498575739
7498675740
/*
@@ -75322,11 +76076,13 @@
7532276076
break;
7532376077
7532476078
case SQLITE_NULL:
7532576079
/* No key specified. Use the key from the main database */
7532676080
sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
75327
- rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
76081
+ if( nKey>0 || sqlite3BtreeGetReserve(db->aDb[0].pBt)>0 ){
76082
+ rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
76083
+ }
7532876084
break;
7532976085
}
7533076086
}
7533176087
#endif
7533276088
@@ -76753,10 +77509,13 @@
7675377509
}
7675477510
pTable = sqlite3FindTable(db, zName, zDb);
7675577511
if( pTable ){
7675677512
if( !noErr ){
7675777513
sqlite3ErrorMsg(pParse, "table %T already exists", pName);
77514
+ }else{
77515
+ assert( !db->init.busy );
77516
+ sqlite3CodeVerifySchema(pParse, iDb);
7675877517
}
7675977518
goto begin_table_error;
7676077519
}
7676177520
if( sqlite3FindIndex(db, zName, zDb)!=0 ){
7676277521
sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);
@@ -77940,10 +78699,11 @@
7794078699
pTab = sqlite3LocateTable(pParse, isView,
7794178700
pName->a[0].zName, pName->a[0].zDatabase);
7794278701
if( noErr ) db->suppressErr--;
7794378702
7794478703
if( pTab==0 ){
78704
+ if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
7794578705
goto exit_drop_table;
7794678706
}
7794778707
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
7794878708
assert( iDb>=0 && iDb<db->nDb );
7794978709
@@ -78458,10 +79218,13 @@
7845879218
}
7845979219
}
7846079220
if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){
7846179221
if( !ifNotExist ){
7846279222
sqlite3ErrorMsg(pParse, "index %s already exists", zName);
79223
+ }else{
79224
+ assert( !db->init.busy );
79225
+ sqlite3CodeVerifySchema(pParse, iDb);
7846379226
}
7846479227
goto exit_create_index;
7846579228
}
7846679229
}else{
7846779230
int n;
@@ -78851,10 +79614,12 @@
7885179614
}
7885279615
pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
7885379616
if( pIndex==0 ){
7885479617
if( !ifExists ){
7885579618
sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);
79619
+ }else{
79620
+ sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
7885679621
}
7885779622
pParse->checkSchema = 1;
7885879623
goto exit_drop_index;
7885979624
}
7886079625
if( pIndex->autoIndex ){
@@ -79439,10 +80204,25 @@
7943980204
sqlite3OpenTempDatabase(pToplevel);
7944080205
}
7944180206
}
7944280207
}
7944380208
}
80209
+
80210
+/*
80211
+** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each
80212
+** attached database. Otherwise, invoke it for the database named zDb only.
80213
+*/
80214
+SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){
80215
+ sqlite3 *db = pParse->db;
80216
+ int i;
80217
+ for(i=0; i<db->nDb; i++){
80218
+ Db *pDb = &db->aDb[i];
80219
+ if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zName)) ){
80220
+ sqlite3CodeVerifySchema(pParse, i);
80221
+ }
80222
+ }
80223
+}
7944480224
7944580225
/*
7944680226
** Generate VDBE code that prepares for doing an operation that
7944780227
** might change the database.
7944880228
**
@@ -84872,13 +85652,12 @@
8487285652
** index and making sure that duplicate entries do not already exist.
8487385653
** Add the new records to the indices as we go.
8487485654
*/
8487585655
for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
8487685656
int regIdx;
84877
-#ifndef SQLITE_OMIT_UNIQUE_ENFORCEMENT
8487885657
int regR;
84879
-#endif
85658
+
8488085659
if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */
8488185660
8488285661
/* Create a key for accessing the index entry */
8488385662
regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
8488485663
for(i=0; i<pIdx->nColumn; i++){
@@ -84892,15 +85671,10 @@
8489285671
sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
8489385672
sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
8489485673
sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
8489585674
sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);
8489685675
84897
-#ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT
84898
- sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
84899
- continue; /* Treat pIdx as if it is not a UNIQUE index */
84900
-#else
84901
-
8490285676
/* Find out what action to take in case there is an indexing conflict */
8490385677
onError = pIdx->onError;
8490485678
if( onError==OE_None ){
8490585679
sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
8490685680
continue; /* pIdx is not a UNIQUE index */
@@ -84970,11 +85744,10 @@
8497085744
break;
8497185745
}
8497285746
}
8497385747
sqlite3VdbeJumpHere(v, j3);
8497485748
sqlite3ReleaseTempReg(pParse, regR);
84975
-#endif
8497685749
}
8497785750
8497885751
if( pbMayReplace ){
8497985752
*pbMayReplace = seenReplace;
8498085753
}
@@ -88180,11 +88953,11 @@
8818088953
if( zExtra ){
8818188954
*pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg,
8818288955
"%s - %s", *pData->pzErrMsg, zExtra);
8818388956
}
8818488957
}
88185
- pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT;
88958
+ pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT;
8818688959
}
8818788960
8818888961
/*
8818988962
** This is the callback routine for the code that initializes the
8819088963
** database. See sqlite3Init() below for additional information.
@@ -93841,10 +94614,13 @@
9384194614
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
9384294615
if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),
9384394616
zName, sqlite3Strlen30(zName)) ){
9384494617
if( !noErr ){
9384594618
sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
94619
+ }else{
94620
+ assert( !db->init.busy );
94621
+ sqlite3CodeVerifySchema(pParse, iDb);
9384694622
}
9384794623
goto trigger_cleanup;
9384894624
}
9384994625
9385094626
/* Do not create a trigger on a system table */
@@ -94169,10 +94945,12 @@
9416994945
if( pTrigger ) break;
9417094946
}
9417194947
if( !pTrigger ){
9417294948
if( !noErr ){
9417394949
sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
94950
+ }else{
94951
+ sqlite3CodeVerifyNamedSchema(pParse, zDb);
9417494952
}
9417594953
pParse->checkSchema = 1;
9417694954
goto drop_trigger_cleanup;
9417794955
}
9417894956
sqlite3DropTriggerPtr(pParse, pTrigger);
@@ -98075,11 +98853,14 @@
9807598853
** Note that the virtual term must be tagged with TERM_VNULL. This
9807698854
** TERM_VNULL tag will suppress the not-null check at the beginning
9807798855
** of the loop. Without the TERM_VNULL flag, the not-null check at
9807898856
** the start of the loop will prevent any results from being returned.
9807998857
*/
98080
- if( pExpr->op==TK_NOTNULL && pExpr->pLeft->iColumn>=0 ){
98858
+ if( pExpr->op==TK_NOTNULL
98859
+ && pExpr->pLeft->op==TK_COLUMN
98860
+ && pExpr->pLeft->iColumn>=0
98861
+ ){
9808198862
Expr *pNewExpr;
9808298863
Expr *pLeft = pExpr->pLeft;
9808398864
int idxNew;
9808498865
WhereTerm *pNewTerm;
9808598866
@@ -99265,11 +100046,11 @@
99265100046
** This routine can fail if it is unable to load a collating sequence
99266100047
** required for string comparison, or if unable to allocate memory
99267100048
** for a UTF conversion required for comparison. The error is stored
99268100049
** in the pParse structure.
99269100050
*/
99270
-int whereEqualScanEst(
100051
+static int whereEqualScanEst(
99271100052
Parse *pParse, /* Parsing & code generating context */
99272100053
Index *p, /* The index whose left-most column is pTerm */
99273100054
Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */
99274100055
double *pnRow /* Write the revised row estimate here */
99275100056
){
@@ -99322,11 +100103,11 @@
99322100103
** This routine can fail if it is unable to load a collating sequence
99323100104
** required for string comparison, or if unable to allocate memory
99324100105
** for a UTF conversion required for comparison. The error is stored
99325100106
** in the pParse structure.
99326100107
*/
99327
-int whereInScanEst(
100108
+static int whereInScanEst(
99328100109
Parse *pParse, /* Parsing & code generating context */
99329100110
Index *p, /* The index whose left-most column is pTerm */
99330100111
ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
99331100112
double *pnRow /* Write the revised row estimate here */
99332100113
){
@@ -99593,11 +100374,11 @@
99593100374
#endif
99594100375
used |= pTerm->prereqRight;
99595100376
}
99596100377
99597100378
/* Determine the value of estBound. */
99598
- if( nEq<pProbe->nColumn ){
100379
+ if( nEq<pProbe->nColumn && pProbe->bUnordered==0 ){
99599100380
int j = pProbe->aiColumn[nEq];
99600100381
if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
99601100382
WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx);
99602100383
WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx);
99603100384
whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &estBound);
@@ -99625,10 +100406,11 @@
99625100406
** naturally scan rows in the required order, set the appropriate flags
99626100407
** in wsFlags. Otherwise, if there is an ORDER BY clause but the index
99627100408
** will scan rows in a different order, set the bSort variable. */
99628100409
if( pOrderBy ){
99629100410
if( (wsFlags & WHERE_COLUMN_IN)==0
100411
+ && pProbe->bUnordered==0
99630100412
&& isSortingIndex(pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy,
99631100413
nEq, wsFlags, &rev)
99632100414
){
99633100415
wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY;
99634100416
wsFlags |= (rev ? WHERE_REVERSE : 0);
99635100417
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -650,11 +650,11 @@
650 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
651 ** [sqlite_version()] and [sqlite_source_id()].
652 */
653 #define SQLITE_VERSION "3.7.6"
654 #define SQLITE_VERSION_NUMBER 3007006
655 #define SQLITE_SOURCE_ID "2011-04-07 15:24:08 bf78acb9dfacde0f08a5b3ceac13480f12a06168"
656
657 /*
658 ** CAPI3REF: Run-Time Library Version Numbers
659 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
660 **
@@ -9808,10 +9808,11 @@
9808 unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
9809 Table *pTable; /* The SQL table being indexed */
9810 int tnum; /* Page containing root of this index in database file */
9811 u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
9812 u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */
 
9813 char *zColAff; /* String defining the affinity of each column */
9814 Index *pNext; /* The next index associated with the same table */
9815 Schema *pSchema; /* Schema containing this index */
9816 u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */
9817 char **azColl; /* Array of collation sequence names for index */
@@ -11099,10 +11100,11 @@
11099 SQLITE_PRIVATE void sqlite3PrngSaveState(void);
11100 SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
11101 SQLITE_PRIVATE void sqlite3PrngResetState(void);
11102 SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*);
11103 SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int);
 
11104 SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int);
11105 SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*);
11106 SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*);
11107 SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
11108 SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
@@ -12078,13 +12080,10 @@
12078 "OMIT_TRIGGER",
12079 #endif
12080 #ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
12081 "OMIT_TRUNCATE_OPTIMIZATION",
12082 #endif
12083 #ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT
12084 "OMIT_UNIQUE_ENFORCEMENT",
12085 #endif
12086 #ifdef SQLITE_OMIT_UTF16
12087 "OMIT_UTF16",
12088 #endif
12089 #ifdef SQLITE_OMIT_VACUUM
12090 "OMIT_VACUUM",
@@ -16972,11 +16971,11 @@
16972 #ifdef SQLITE_DEBUG
16973 if( p->trace ) os2MutexTrace(p, "leave");
16974 #endif
16975 }
16976
16977 SQLITE_PRIVATE SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
16978 static const sqlite3_mutex_methods sMutex = {
16979 os2MutexInit,
16980 os2MutexEnd,
16981 os2MutexAlloc,
16982 os2MutexFree,
@@ -20224,12 +20223,12 @@
20224 /*
20225 ** Routine needed to support the testcase() macro.
20226 */
20227 #ifdef SQLITE_COVERAGE_TEST
20228 SQLITE_PRIVATE void sqlite3Coverage(int x){
20229 static int dummy = 0;
20230 dummy += x;
20231 }
20232 #endif
20233
20234 #ifndef SQLITE_OMIT_FLOATING_POINT
20235 /*
@@ -22045,48 +22044,66 @@
22045 #endif /* !defined(_OS_COMMON_H_) */
22046
22047 /************** End of os_common.h *******************************************/
22048 /************** Continuing where we left off in os_os2.c *********************/
22049
 
 
 
 
 
22050 /*
22051 ** The os2File structure is subclass of sqlite3_file specific for the OS/2
22052 ** protability layer.
22053 */
22054 typedef struct os2File os2File;
22055 struct os2File {
22056 const sqlite3_io_methods *pMethod; /* Always the first entry */
22057 HFILE h; /* Handle for accessing the file */
22058 char* pathToDel; /* Name of file to delete on close, NULL if not */
22059 unsigned char locktype; /* Type of lock currently held on this file */
 
 
 
22060 };
22061
22062 #define LOCK_TIMEOUT 10L /* the default locking timeout */
22063
 
 
 
 
 
 
 
 
22064 /*****************************************************************************
22065 ** The next group of routines implement the I/O methods specified
22066 ** by the sqlite3_io_methods object.
22067 ******************************************************************************/
22068
22069 /*
22070 ** Close a file.
22071 */
22072 static int os2Close( sqlite3_file *id ){
22073 APIRET rc = NO_ERROR;
22074 os2File *pFile;
22075 if( id && (pFile = (os2File*)id) != 0 ){
22076 OSTRACE(( "CLOSE %d\n", pFile->h ));
22077 rc = DosClose( pFile->h );
22078 pFile->locktype = NO_LOCK;
22079 if( pFile->pathToDel != NULL ){
22080 rc = DosForceDelete( (PSZ)pFile->pathToDel );
22081 free( pFile->pathToDel );
22082 pFile->pathToDel = NULL;
22083 }
22084 id = 0;
22085 OpenCounter( -1 );
22086 }
22087
 
 
 
22088 return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
22089 }
22090
22091 /*
22092 ** Read data from a file into a buffer. Return SQLITE_OK if all
@@ -22155,14 +22172,25 @@
22155
22156 /*
22157 ** Truncate an open file to a specified size
22158 */
22159 static int os2Truncate( sqlite3_file *id, i64 nByte ){
22160 APIRET rc = NO_ERROR;
22161 os2File *pFile = (os2File*)id;
 
22162 OSTRACE(( "TRUNCATE %d %lld\n", pFile->h, nByte ));
22163 SimulateIOError( return SQLITE_IOERR_TRUNCATE );
 
 
 
 
 
 
 
 
 
 
22164 rc = DosSetFileSize( pFile->h, nByte );
22165 return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_TRUNCATE;
22166 }
22167
22168 #ifdef SQLITE_TEST
@@ -22522,10 +22550,24 @@
22522 *(int*)pArg = ((os2File*)id)->locktype;
22523 OSTRACE(( "FCNTL_LOCKSTATE %d lock=%d\n",
22524 ((os2File*)id)->h, ((os2File*)id)->locktype ));
22525 return SQLITE_OK;
22526 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22527 }
22528 return SQLITE_NOTFOUND;
22529 }
22530
22531 /*
@@ -22537,18 +22579,20 @@
22537 ** if two files are created in the same file-system directory (i.e.
22538 ** a database and its journal file) that the sector size will be the
22539 ** same for both.
22540 */
22541 static int os2SectorSize(sqlite3_file *id){
 
22542 return SQLITE_DEFAULT_SECTOR_SIZE;
22543 }
22544
22545 /*
22546 ** Return a vector of device characteristics.
22547 */
22548 static int os2DeviceCharacteristics(sqlite3_file *id){
22549 return 0;
 
22550 }
22551
22552
22553 /*
22554 ** Character set conversion objects used by conversion routines.
@@ -22630,17 +22674,668 @@
22630 /* determine string for the conversion of UTF-8 which is CP1208 */
22631 UniStrFromUcs( ucUtf8, out, tempPath, CCHMAXPATH );
22632
22633 return out;
22634 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22635
22636 /*
22637 ** This vector defines all the methods that can operate on an
22638 ** sqlite3_file for os2.
22639 */
22640 static const sqlite3_io_methods os2IoMethod = {
22641 1, /* iVersion */
22642 os2Close, /* xClose */
22643 os2Read, /* xRead */
22644 os2Write, /* xWrite */
22645 os2Truncate, /* xTruncate */
22646 os2Sync, /* xSync */
@@ -22649,15 +23344,16 @@
22649 os2Unlock, /* xUnlock */
22650 os2CheckReservedLock, /* xCheckReservedLock */
22651 os2FileControl, /* xFileControl */
22652 os2SectorSize, /* xSectorSize */
22653 os2DeviceCharacteristics, /* xDeviceCharacteristics */
22654 0, /* xShmMap */
22655 0, /* xShmLock */
22656 0, /* xShmBarrier */
22657 0 /* xShmUnmap */
22658 };
 
22659
22660 /***************************************************************************
22661 ** Here ends the I/O methods that form the sqlite3_io_methods object.
22662 **
22663 ** The next block of code implements the VFS methods.
@@ -22666,54 +23362,61 @@
22666 /*
22667 ** Create a temporary file name in zBuf. zBuf must be big enough to
22668 ** hold at pVfs->mxPathname characters.
22669 */
22670 static int getTempname(int nBuf, char *zBuf ){
22671 static const unsigned char zChars[] =
22672 "abcdefghijklmnopqrstuvwxyz"
22673 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
22674 "0123456789";
22675 int i, j;
22676 char zTempPathBuf[3];
22677 PSZ zTempPath = (PSZ)&zTempPathBuf;
22678 if( sqlite3_temp_directory ){
22679 zTempPath = sqlite3_temp_directory;
22680 }else{
22681 if( DosScanEnv( (PSZ)"TEMP", &zTempPath ) ){
22682 if( DosScanEnv( (PSZ)"TMP", &zTempPath ) ){
22683 if( DosScanEnv( (PSZ)"TMPDIR", &zTempPath ) ){
22684 ULONG ulDriveNum = 0, ulDriveMap = 0;
22685 DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap );
22686 sprintf( (char*)zTempPath, "%c:", (char)( 'A' + ulDriveNum - 1 ) );
22687 }
22688 }
22689 }
22690 }
 
 
 
 
 
 
 
 
 
 
 
22691 /* Strip off a trailing slashes or backslashes, otherwise we would get *
22692 * multiple (back)slashes which causes DosOpen() to fail. *
22693 * Trailing spaces are not allowed, either. */
22694 j = sqlite3Strlen30(zTempPath);
22695 while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/'
22696 || zTempPath[j-1] == ' ' ) ){
22697 j--;
22698 }
22699 zTempPath[j] = '\0';
22700 if( !sqlite3_temp_directory ){
22701 char *zTempPathUTF = convertCpPathToUtf8( zTempPath );
22702 sqlite3_snprintf( nBuf-30, zBuf,
22703 "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPathUTF );
22704 free( zTempPathUTF );
22705 }else{
22706 sqlite3_snprintf( nBuf-30, zBuf,
22707 "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath );
22708 }
22709 j = sqlite3Strlen30( zBuf );
22710 sqlite3_randomness( 20, &zBuf[j] );
22711 for( i = 0; i < 20; i++, j++ ){
22712 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
22713 }
22714 zBuf[j] = 0;
 
22715 OSTRACE(( "TEMP FILENAME: %s\n", zBuf ));
22716 return SQLITE_OK;
22717 }
22718
22719
@@ -22729,12 +23432,12 @@
22729 char *zFull /* Output buffer */
22730 ){
22731 char *zRelativeCp = convertUtf8PathToCp( zRelative );
22732 char zFullCp[CCHMAXPATH] = "\0";
22733 char *zFullUTF;
22734 APIRET rc = DosQueryPathInfo( zRelativeCp, FIL_QUERYFULLNAME, zFullCp,
22735 CCHMAXPATH );
22736 free( zRelativeCp );
22737 zFullUTF = convertCpPathToUtf8( zFullCp );
22738 sqlite3_snprintf( nFull, zFull, zFullUTF );
22739 free( zFullUTF );
22740 return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
@@ -22760,14 +23463,14 @@
22760 const char *zUtf8Name = zName;
22761 char *zNameCp;
22762 char zTmpname[CCHMAXPATH];
22763
22764 int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
22765 int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE);
22766 int isCreate = (flags & SQLITE_OPEN_CREATE);
22767 int isReadWrite = (flags & SQLITE_OPEN_READWRITE);
22768 #ifndef NDEBUG
 
22769 int isReadonly = (flags & SQLITE_OPEN_READONLY);
22770 int eType = (flags & 0xFFFFFF00);
22771 int isOpenJournal = (isCreate && (
22772 eType==SQLITE_OPEN_MASTER_JOURNAL
22773 || eType==SQLITE_OPEN_MAIN_JOURNAL
@@ -22803,11 +23506,11 @@
22803 || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL
22804 || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
22805 );
22806
22807 memset( pFile, 0, sizeof(*pFile) );
22808 pFile->pMethod = &os2IoMethod;
22809
22810 /* If the second argument to this function is NULL, generate a
22811 ** temporary file name to use
22812 */
22813 if( !zUtf8Name ){
@@ -22825,15 +23528,15 @@
22825 ulOpenMode |= OPEN_ACCESS_READONLY;
22826 }
22827
22828 /* Open in random access mode for possibly better speed. Allow full
22829 ** sharing because file locks will provide exclusive access when needed.
 
 
22830 */
22831 ulOpenMode |= OPEN_FLAGS_RANDOM;
22832 ulOpenMode |= OPEN_FLAGS_FAIL_ON_ERROR;
22833 ulOpenMode |= OPEN_FLAGS_NOINHERIT;
22834 ulOpenMode |= OPEN_SHARE_DENYNONE;
22835
22836 /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is
22837 ** created. SQLite doesn't use it to indicate "exclusive access"
22838 ** as it is usually understood.
22839 */
@@ -22847,17 +23550,10 @@
22847 }else{
22848 /* Opens a file, only if it exists. */
22849 ulOpenFlags |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
22850 }
22851
22852 /* For DELETEONCLOSE, save a pointer to the converted filename */
22853 if( isDelete ){
22854 char pathUtf8[CCHMAXPATH];
22855 os2FullPathname( pVfs, zUtf8Name, CCHMAXPATH, pathUtf8 );
22856 pFile->pathToDel = convertUtf8PathToCp( pathUtf8 );
22857 }
22858
22859 zNameCp = convertUtf8PathToCp( zUtf8Name );
22860 rc = DosOpen( (PSZ)zNameCp,
22861 &h,
22862 &ulAction,
22863 0L,
@@ -22868,13 +23564,10 @@
22868 free( zNameCp );
22869
22870 if( rc != NO_ERROR ){
22871 OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulFlags=%#lx, ulMode=%#lx\n",
22872 rc, zUtf8Name, ulAction, ulOpenFlags, ulOpenMode ));
22873 if( pFile->pathToDel )
22874 free( pFile->pathToDel );
22875 pFile->pathToDel = NULL;
22876
22877 if( isReadWrite ){
22878 return os2Open( pVfs, zName, id,
22879 ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
22880 pOutFlags );
@@ -22885,11 +23578,16 @@
22885
22886 if( pOutFlags ){
22887 *pOutFlags = isReadWrite ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY;
22888 }
22889
 
 
 
 
22890 pFile->h = h;
 
22891 OpenCounter(+1);
22892 OSTRACE(( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags ));
22893 return SQLITE_OK;
22894 }
22895
@@ -22920,34 +23618,46 @@
22920 sqlite3_vfs *pVfs, /* Not used on os2 */
22921 const char *zFilename, /* Name of file to check */
22922 int flags, /* Type of test to make on this file */
22923 int *pOut /* Write results here */
22924 ){
 
22925 FILESTATUS3 fsts3ConfigInfo;
22926 APIRET rc = NO_ERROR;
22927 char *zFilenameCp = convertUtf8PathToCp( zFilename );
22928
22929 memset( &fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo) );
 
 
 
22930 rc = DosQueryPathInfo( (PSZ)zFilenameCp, FIL_STANDARD,
22931 &fsts3ConfigInfo, sizeof(FILESTATUS3) );
22932 free( zFilenameCp );
22933 OSTRACE(( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n",
22934 fsts3ConfigInfo.attrFile, flags, rc ));
 
22935 switch( flags ){
22936 case SQLITE_ACCESS_READ:
22937 case SQLITE_ACCESS_EXISTS:
22938 rc = (rc == NO_ERROR);
22939 OSTRACE(( "ACCESS %s access of read and exists rc=%d\n", zFilename, rc));
 
 
 
 
 
22940 break;
22941 case SQLITE_ACCESS_READWRITE:
22942 rc = (rc == NO_ERROR) && ( (fsts3ConfigInfo.attrFile & FILE_READONLY) == 0 );
22943 OSTRACE(( "ACCESS %s access of read/write rc=%d\n", zFilename, rc ));
22944 break;
22945 default:
 
22946 assert( !"Invalid flags argument" );
22947 }
22948 *pOut = rc;
 
 
 
22949 return SQLITE_OK;
22950 }
22951
22952
22953 #ifndef SQLITE_OMIT_LOAD_EXTENSION
@@ -22958,15 +23668,14 @@
22958 /*
22959 ** Interfaces for opening a shared library, finding entry points
22960 ** within the shared library, and closing the shared library.
22961 */
22962 static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){
22963 UCHAR loadErr[256];
22964 HMODULE hmod;
22965 APIRET rc;
22966 char *zFilenameCp = convertUtf8PathToCp(zFilename);
22967 rc = DosLoadModule((PSZ)loadErr, sizeof(loadErr), zFilenameCp, &hmod);
22968 free(zFilenameCp);
22969 return rc != NO_ERROR ? 0 : (void*)hmod;
22970 }
22971 /*
22972 ** A no-op since the error code is returned on the DosLoadModule call.
@@ -22976,18 +23685,18 @@
22976 /* no-op */
22977 }
22978 static void (*os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
22979 PFN pfn;
22980 APIRET rc;
22981 rc = DosQueryProcAddr((HMODULE)pHandle, 0L, zSymbol, &pfn);
22982 if( rc != NO_ERROR ){
22983 /* if the symbol itself was not found, search again for the same
22984 * symbol with an extra underscore, that might be needed depending
22985 * on the calling convention */
22986 char _zSymbol[256] = "_";
22987 strncat(_zSymbol, zSymbol, 255);
22988 rc = DosQueryProcAddr((HMODULE)pHandle, 0L, _zSymbol, &pfn);
22989 }
22990 return rc != NO_ERROR ? 0 : (void(*)(void))pfn;
22991 }
22992 static void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){
22993 DosFreeModule((HMODULE)pHandle);
@@ -23007,58 +23716,43 @@
23007 int n = 0;
23008 #if defined(SQLITE_TEST)
23009 n = nBuf;
23010 memset(zBuf, 0, nBuf);
23011 #else
23012 int sizeofULong = sizeof(ULONG);
23013 if( (int)sizeof(DATETIME) <= nBuf - n ){
23014 DATETIME x;
23015 DosGetDateTime(&x);
23016 memcpy(&zBuf[n], &x, sizeof(x));
23017 n += sizeof(x);
23018 }
23019
23020 if( sizeofULong <= nBuf - n ){
23021 PPIB ppib;
23022 DosGetInfoBlocks(NULL, &ppib);
23023 memcpy(&zBuf[n], &ppib->pib_ulpid, sizeofULong);
23024 n += sizeofULong;
23025 }
23026
23027 if( sizeofULong <= nBuf - n ){
23028 PTIB ptib;
23029 DosGetInfoBlocks(&ptib, NULL);
23030 memcpy(&zBuf[n], &ptib->tib_ptib2->tib2_ultid, sizeofULong);
23031 n += sizeofULong;
23032 }
23033
23034 /* if we still haven't filled the buffer yet the following will */
23035 /* grab everything once instead of making several calls for a single item */
23036 if( sizeofULong <= nBuf - n ){
23037 ULONG ulSysInfo[QSV_MAX];
23038 DosQuerySysInfo(1L, QSV_MAX, ulSysInfo, sizeofULong * QSV_MAX);
23039
23040 memcpy(&zBuf[n], &ulSysInfo[QSV_MS_COUNT - 1], sizeofULong);
23041 n += sizeofULong;
23042
23043 if( sizeofULong <= nBuf - n ){
23044 memcpy(&zBuf[n], &ulSysInfo[QSV_TIMER_INTERVAL - 1], sizeofULong);
23045 n += sizeofULong;
23046 }
23047 if( sizeofULong <= nBuf - n ){
23048 memcpy(&zBuf[n], &ulSysInfo[QSV_TIME_LOW - 1], sizeofULong);
23049 n += sizeofULong;
23050 }
23051 if( sizeofULong <= nBuf - n ){
23052 memcpy(&zBuf[n], &ulSysInfo[QSV_TIME_HIGH - 1], sizeofULong);
23053 n += sizeofULong;
23054 }
23055 if( sizeofULong <= nBuf - n ){
23056 memcpy(&zBuf[n], &ulSysInfo[QSV_TOTAVAILMEM - 1], sizeofULong);
23057 n += sizeofULong;
23058 }
23059 }
23060 #endif
23061
23062 return n;
23063 }
23064
@@ -23082,68 +23776,102 @@
23082 #ifdef SQLITE_TEST
23083 SQLITE_API int sqlite3_current_time = 0;
23084 #endif
23085
23086 /*
23087 ** Find the current time (in Universal Coordinated Time). Write the
23088 ** current time and date as a Julian Day number into *prNow and
23089 ** return 0. Return 1 if the time and date cannot be found.
 
 
 
 
23090 */
23091 int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){
23092 double now;
23093 SHORT minute; /* needs to be able to cope with negative timezone offset */
23094 USHORT hundredths, second, hour,
23095 day, month, year;
 
23096 DATETIME dt;
23097 DosGetDateTime( &dt );
23098 hundredths = (USHORT)dt.hundredths;
23099 second = (USHORT)dt.seconds;
23100 minute = (SHORT)dt.minutes + dt.timezone;
23101 hour = (USHORT)dt.hours;
23102 day = (USHORT)dt.day;
23103 month = (USHORT)dt.month;
23104 year = (USHORT)dt.year;
23105
23106 /* Calculations from http://www.astro.keele.ac.uk/~rno/Astronomy/hjd.html
23107 http://www.astro.keele.ac.uk/~rno/Astronomy/hjd-0.1.c */
23108 /* Calculate the Julian days */
23109 now = day - 32076 +
 
23110 1461*(year + 4800 + (month - 14)/12)/4 +
23111 367*(month - 2 - (month - 14)/12*12)/12 -
23112 3*((year + 4900 + (month - 14)/12)/100)/4;
23113
23114 /* Add the fractional hours, mins and seconds */
23115 now += (hour + 12.0)/24.0;
23116 now += minute/1440.0;
23117 now += second/86400.0;
23118 now += hundredths/8640000.0;
23119 *prNow = now;
23120 #ifdef SQLITE_TEST
23121 if( sqlite3_current_time ){
23122 *prNow = sqlite3_current_time/86400.0 + 2440587.5;
23123 }
23124 #endif
 
 
23125 return 0;
23126 }
23127
23128 /*
23129 ** Find the current time (in Universal Coordinated Time). Write into *piNow
23130 ** the current time and date as a Julian Day number times 86_400_000. In
23131 ** other words, write into *piNow the number of milliseconds since the Julian
23132 ** epoch of noon in Greenwich on November 24, 4714 B.C according to the
23133 ** proleptic Gregorian calendar.
23134 **
23135 ** On success, return 0. Return 1 if the time and date cannot be found.
23136 */
23137 static int os2CurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
23138 double now;
23139 os2CurrentTime(pVfs, &now);
23140 *piNow = now * 86400000;
23141 return 0;
23142 }
23143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23144 static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
 
23145 return 0;
23146 }
23147
23148 /*
23149 ** Initialize and deinitialize the operating system interface.
@@ -23167,17 +23895,18 @@
23167 os2DlClose, /* xDlClose */
23168 os2Randomness, /* xRandomness */
23169 os2Sleep, /* xSleep */
23170 os2CurrentTime, /* xCurrentTime */
23171 os2GetLastError, /* xGetLastError */
23172 os2CurrentTimeInt64 /* xCurrentTimeInt64 */
23173 0, /* xSetSystemCall */
23174 0, /* xGetSystemCall */
23175 0, /* xNextSystemCall */
23176 };
23177 sqlite3_vfs_register(&os2Vfs, 1);
23178 initUconvObjects();
 
23179 return SQLITE_OK;
23180 }
23181 SQLITE_API int sqlite3_os_end(void){
23182 freeUconvObjects();
23183 return SQLITE_OK;
@@ -23752,12 +24481,14 @@
23752 { "pwrite64", (sqlite3_syscall_ptr)0, 0 },
23753 #endif
23754 #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
23755 aSyscall[13].pCurrent)
23756
 
23757 { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
23758 #define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
 
23759
23760 #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
23761 { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 },
23762 #else
23763 { "fallocate", (sqlite3_syscall_ptr)0, 0 },
@@ -54608,10 +55339,14 @@
54608 Pager * const pDestPager = sqlite3BtreePager(p->pDest);
54609 const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
54610 int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
54611 const int nCopy = MIN(nSrcPgsz, nDestPgsz);
54612 const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
 
 
 
 
54613
54614 int rc = SQLITE_OK;
54615 i64 iOff;
54616
54617 assert( p->bDestLocked );
@@ -54626,15 +55361,26 @@
54626 rc = SQLITE_READONLY;
54627 }
54628
54629 #ifdef SQLITE_HAS_CODEC
54630 /* Backup is not possible if the page size of the destination is changing
54631 ** a a codec is in use.
54632 */
54633 if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){
54634 rc = SQLITE_READONLY;
54635 }
 
 
 
 
 
 
 
 
 
 
 
54636 #endif
54637
54638 /* This loop runs once for each destination page spanned by the source
54639 ** page. For each iteration, variable iOff is set to the byte offset
54640 ** of the destination page.
@@ -54996,11 +55742,15 @@
54996 if( !isFatalError(p->rc) && iPage<p->iNext ){
54997 /* The backup process p has already copied page iPage. But now it
54998 ** has been modified by a transaction on the source pager. Copy
54999 ** the new data into the backup.
55000 */
55001 int rc = backupOnePage(p, iPage, aData);
 
 
 
 
55002 assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
55003 if( rc!=SQLITE_OK ){
55004 p->rc = rc;
55005 }
55006 }
@@ -74977,10 +75727,14 @@
74977 }
74978 if( i==0 ) pTable->nRowEst = v;
74979 if( pIndex==0 ) break;
74980 pIndex->aiRowEst[i] = v;
74981 if( *z==' ' ) z++;
 
 
 
 
74982 }
74983 return 0;
74984 }
74985
74986 /*
@@ -75322,11 +76076,13 @@
75322 break;
75323
75324 case SQLITE_NULL:
75325 /* No key specified. Use the key from the main database */
75326 sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
75327 rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
 
 
75328 break;
75329 }
75330 }
75331 #endif
75332
@@ -76753,10 +77509,13 @@
76753 }
76754 pTable = sqlite3FindTable(db, zName, zDb);
76755 if( pTable ){
76756 if( !noErr ){
76757 sqlite3ErrorMsg(pParse, "table %T already exists", pName);
 
 
 
76758 }
76759 goto begin_table_error;
76760 }
76761 if( sqlite3FindIndex(db, zName, zDb)!=0 ){
76762 sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);
@@ -77940,10 +78699,11 @@
77940 pTab = sqlite3LocateTable(pParse, isView,
77941 pName->a[0].zName, pName->a[0].zDatabase);
77942 if( noErr ) db->suppressErr--;
77943
77944 if( pTab==0 ){
 
77945 goto exit_drop_table;
77946 }
77947 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
77948 assert( iDb>=0 && iDb<db->nDb );
77949
@@ -78458,10 +79218,13 @@
78458 }
78459 }
78460 if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){
78461 if( !ifNotExist ){
78462 sqlite3ErrorMsg(pParse, "index %s already exists", zName);
 
 
 
78463 }
78464 goto exit_create_index;
78465 }
78466 }else{
78467 int n;
@@ -78851,10 +79614,12 @@
78851 }
78852 pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
78853 if( pIndex==0 ){
78854 if( !ifExists ){
78855 sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);
 
 
78856 }
78857 pParse->checkSchema = 1;
78858 goto exit_drop_index;
78859 }
78860 if( pIndex->autoIndex ){
@@ -79439,10 +80204,25 @@
79439 sqlite3OpenTempDatabase(pToplevel);
79440 }
79441 }
79442 }
79443 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79444
79445 /*
79446 ** Generate VDBE code that prepares for doing an operation that
79447 ** might change the database.
79448 **
@@ -84872,13 +85652,12 @@
84872 ** index and making sure that duplicate entries do not already exist.
84873 ** Add the new records to the indices as we go.
84874 */
84875 for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
84876 int regIdx;
84877 #ifndef SQLITE_OMIT_UNIQUE_ENFORCEMENT
84878 int regR;
84879 #endif
84880 if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */
84881
84882 /* Create a key for accessing the index entry */
84883 regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
84884 for(i=0; i<pIdx->nColumn; i++){
@@ -84892,15 +85671,10 @@
84892 sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
84893 sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
84894 sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
84895 sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);
84896
84897 #ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT
84898 sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
84899 continue; /* Treat pIdx as if it is not a UNIQUE index */
84900 #else
84901
84902 /* Find out what action to take in case there is an indexing conflict */
84903 onError = pIdx->onError;
84904 if( onError==OE_None ){
84905 sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
84906 continue; /* pIdx is not a UNIQUE index */
@@ -84970,11 +85744,10 @@
84970 break;
84971 }
84972 }
84973 sqlite3VdbeJumpHere(v, j3);
84974 sqlite3ReleaseTempReg(pParse, regR);
84975 #endif
84976 }
84977
84978 if( pbMayReplace ){
84979 *pbMayReplace = seenReplace;
84980 }
@@ -88180,11 +88953,11 @@
88180 if( zExtra ){
88181 *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg,
88182 "%s - %s", *pData->pzErrMsg, zExtra);
88183 }
88184 }
88185 pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT;
88186 }
88187
88188 /*
88189 ** This is the callback routine for the code that initializes the
88190 ** database. See sqlite3Init() below for additional information.
@@ -93841,10 +94614,13 @@
93841 assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
93842 if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),
93843 zName, sqlite3Strlen30(zName)) ){
93844 if( !noErr ){
93845 sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
 
 
 
93846 }
93847 goto trigger_cleanup;
93848 }
93849
93850 /* Do not create a trigger on a system table */
@@ -94169,10 +94945,12 @@
94169 if( pTrigger ) break;
94170 }
94171 if( !pTrigger ){
94172 if( !noErr ){
94173 sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
 
 
94174 }
94175 pParse->checkSchema = 1;
94176 goto drop_trigger_cleanup;
94177 }
94178 sqlite3DropTriggerPtr(pParse, pTrigger);
@@ -98075,11 +98853,14 @@
98075 ** Note that the virtual term must be tagged with TERM_VNULL. This
98076 ** TERM_VNULL tag will suppress the not-null check at the beginning
98077 ** of the loop. Without the TERM_VNULL flag, the not-null check at
98078 ** the start of the loop will prevent any results from being returned.
98079 */
98080 if( pExpr->op==TK_NOTNULL && pExpr->pLeft->iColumn>=0 ){
 
 
 
98081 Expr *pNewExpr;
98082 Expr *pLeft = pExpr->pLeft;
98083 int idxNew;
98084 WhereTerm *pNewTerm;
98085
@@ -99265,11 +100046,11 @@
99265 ** This routine can fail if it is unable to load a collating sequence
99266 ** required for string comparison, or if unable to allocate memory
99267 ** for a UTF conversion required for comparison. The error is stored
99268 ** in the pParse structure.
99269 */
99270 int whereEqualScanEst(
99271 Parse *pParse, /* Parsing & code generating context */
99272 Index *p, /* The index whose left-most column is pTerm */
99273 Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */
99274 double *pnRow /* Write the revised row estimate here */
99275 ){
@@ -99322,11 +100103,11 @@
99322 ** This routine can fail if it is unable to load a collating sequence
99323 ** required for string comparison, or if unable to allocate memory
99324 ** for a UTF conversion required for comparison. The error is stored
99325 ** in the pParse structure.
99326 */
99327 int whereInScanEst(
99328 Parse *pParse, /* Parsing & code generating context */
99329 Index *p, /* The index whose left-most column is pTerm */
99330 ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
99331 double *pnRow /* Write the revised row estimate here */
99332 ){
@@ -99593,11 +100374,11 @@
99593 #endif
99594 used |= pTerm->prereqRight;
99595 }
99596
99597 /* Determine the value of estBound. */
99598 if( nEq<pProbe->nColumn ){
99599 int j = pProbe->aiColumn[nEq];
99600 if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
99601 WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx);
99602 WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx);
99603 whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &estBound);
@@ -99625,10 +100406,11 @@
99625 ** naturally scan rows in the required order, set the appropriate flags
99626 ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index
99627 ** will scan rows in a different order, set the bSort variable. */
99628 if( pOrderBy ){
99629 if( (wsFlags & WHERE_COLUMN_IN)==0
 
99630 && isSortingIndex(pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy,
99631 nEq, wsFlags, &rev)
99632 ){
99633 wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY;
99634 wsFlags |= (rev ? WHERE_REVERSE : 0);
99635
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -650,11 +650,11 @@
650 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
651 ** [sqlite_version()] and [sqlite_source_id()].
652 */
653 #define SQLITE_VERSION "3.7.6"
654 #define SQLITE_VERSION_NUMBER 3007006
655 #define SQLITE_SOURCE_ID "2011-04-12 01:58:40 f9d43fa363d54beab6f45db005abac0a7c0c47a7"
656
657 /*
658 ** CAPI3REF: Run-Time Library Version Numbers
659 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
660 **
@@ -9808,10 +9808,11 @@
9808 unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
9809 Table *pTable; /* The SQL table being indexed */
9810 int tnum; /* Page containing root of this index in database file */
9811 u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
9812 u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */
9813 u8 bUnordered; /* Use this index for == or IN queries only */
9814 char *zColAff; /* String defining the affinity of each column */
9815 Index *pNext; /* The next index associated with the same table */
9816 Schema *pSchema; /* Schema containing this index */
9817 u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */
9818 char **azColl; /* Array of collation sequence names for index */
@@ -11099,10 +11100,11 @@
11100 SQLITE_PRIVATE void sqlite3PrngSaveState(void);
11101 SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
11102 SQLITE_PRIVATE void sqlite3PrngResetState(void);
11103 SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*);
11104 SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int);
11105 SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
11106 SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int);
11107 SQLITE_PRIVATE void sqlite3CommitTransaction(Parse*);
11108 SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse*);
11109 SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
11110 SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
@@ -12078,13 +12080,10 @@
12080 "OMIT_TRIGGER",
12081 #endif
12082 #ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
12083 "OMIT_TRUNCATE_OPTIMIZATION",
12084 #endif
 
 
 
12085 #ifdef SQLITE_OMIT_UTF16
12086 "OMIT_UTF16",
12087 #endif
12088 #ifdef SQLITE_OMIT_VACUUM
12089 "OMIT_VACUUM",
@@ -16972,11 +16971,11 @@
16971 #ifdef SQLITE_DEBUG
16972 if( p->trace ) os2MutexTrace(p, "leave");
16973 #endif
16974 }
16975
16976 SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
16977 static const sqlite3_mutex_methods sMutex = {
16978 os2MutexInit,
16979 os2MutexEnd,
16980 os2MutexAlloc,
16981 os2MutexFree,
@@ -20224,12 +20223,12 @@
20223 /*
20224 ** Routine needed to support the testcase() macro.
20225 */
20226 #ifdef SQLITE_COVERAGE_TEST
20227 SQLITE_PRIVATE void sqlite3Coverage(int x){
20228 static unsigned dummy = 0;
20229 dummy += (unsigned)x;
20230 }
20231 #endif
20232
20233 #ifndef SQLITE_OMIT_FLOATING_POINT
20234 /*
@@ -22045,48 +22044,66 @@
22044 #endif /* !defined(_OS_COMMON_H_) */
22045
22046 /************** End of os_common.h *******************************************/
22047 /************** Continuing where we left off in os_os2.c *********************/
22048
22049 /* Forward references */
22050 typedef struct os2File os2File; /* The file structure */
22051 typedef struct os2ShmNode os2ShmNode; /* A shared descritive memory node */
22052 typedef struct os2ShmLink os2ShmLink; /* A connection to shared-memory */
22053
22054 /*
22055 ** The os2File structure is subclass of sqlite3_file specific for the OS/2
22056 ** protability layer.
22057 */
 
22058 struct os2File {
22059 const sqlite3_io_methods *pMethod; /* Always the first entry */
22060 HFILE h; /* Handle for accessing the file */
22061 int flags; /* Flags provided to os2Open() */
22062 int locktype; /* Type of lock currently held on this file */
22063 int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */
22064 char *zFullPathCp; /* Full path name of this file */
22065 os2ShmLink *pShmLink; /* Instance of shared memory on this file */
22066 };
22067
22068 #define LOCK_TIMEOUT 10L /* the default locking timeout */
22069
22070 /*
22071 ** Missing from some versions of the OS/2 toolkit -
22072 ** used to allocate from high memory if possible
22073 */
22074 #ifndef OBJ_ANY
22075 # define OBJ_ANY 0x00000400
22076 #endif
22077
22078 /*****************************************************************************
22079 ** The next group of routines implement the I/O methods specified
22080 ** by the sqlite3_io_methods object.
22081 ******************************************************************************/
22082
22083 /*
22084 ** Close a file.
22085 */
22086 static int os2Close( sqlite3_file *id ){
22087 APIRET rc;
22088 os2File *pFile = (os2File*)id;
22089
22090 assert( id!=0 );
22091 OSTRACE(( "CLOSE %d (%s)\n", pFile->h, pFile->zFullPathCp ));
22092
22093 rc = DosClose( pFile->h );
22094
22095 if( pFile->flags & SQLITE_OPEN_DELETEONCLOSE )
22096 DosForceDelete( (PSZ)pFile->zFullPathCp );
22097
22098 free( pFile->zFullPathCp );
22099 pFile->zFullPathCp = NULL;
22100 pFile->locktype = NO_LOCK;
22101 pFile->h = (HFILE)-1;
22102 pFile->flags = 0;
22103
22104 OpenCounter( -1 );
22105 return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
22106 }
22107
22108 /*
22109 ** Read data from a file into a buffer. Return SQLITE_OK if all
@@ -22155,14 +22172,25 @@
22172
22173 /*
22174 ** Truncate an open file to a specified size
22175 */
22176 static int os2Truncate( sqlite3_file *id, i64 nByte ){
22177 APIRET rc;
22178 os2File *pFile = (os2File*)id;
22179 assert( id!=0 );
22180 OSTRACE(( "TRUNCATE %d %lld\n", pFile->h, nByte ));
22181 SimulateIOError( return SQLITE_IOERR_TRUNCATE );
22182
22183 /* If the user has configured a chunk-size for this file, truncate the
22184 ** file so that it consists of an integer number of chunks (i.e. the
22185 ** actual file size after the operation may be larger than the requested
22186 ** size).
22187 */
22188 if( pFile->szChunk ){
22189 nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
22190 }
22191
22192 rc = DosSetFileSize( pFile->h, nByte );
22193 return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR_TRUNCATE;
22194 }
22195
22196 #ifdef SQLITE_TEST
@@ -22522,10 +22550,24 @@
22550 *(int*)pArg = ((os2File*)id)->locktype;
22551 OSTRACE(( "FCNTL_LOCKSTATE %d lock=%d\n",
22552 ((os2File*)id)->h, ((os2File*)id)->locktype ));
22553 return SQLITE_OK;
22554 }
22555 case SQLITE_FCNTL_CHUNK_SIZE: {
22556 ((os2File*)id)->szChunk = *(int*)pArg;
22557 return SQLITE_OK;
22558 }
22559 case SQLITE_FCNTL_SIZE_HINT: {
22560 sqlite3_int64 sz = *(sqlite3_int64*)pArg;
22561 SimulateIOErrorBenign(1);
22562 os2Truncate(id, sz);
22563 SimulateIOErrorBenign(0);
22564 return SQLITE_OK;
22565 }
22566 case SQLITE_FCNTL_SYNC_OMITTED: {
22567 return SQLITE_OK;
22568 }
22569 }
22570 return SQLITE_NOTFOUND;
22571 }
22572
22573 /*
@@ -22537,18 +22579,20 @@
22579 ** if two files are created in the same file-system directory (i.e.
22580 ** a database and its journal file) that the sector size will be the
22581 ** same for both.
22582 */
22583 static int os2SectorSize(sqlite3_file *id){
22584 UNUSED_PARAMETER(id);
22585 return SQLITE_DEFAULT_SECTOR_SIZE;
22586 }
22587
22588 /*
22589 ** Return a vector of device characteristics.
22590 */
22591 static int os2DeviceCharacteristics(sqlite3_file *id){
22592 UNUSED_PARAMETER(id);
22593 return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN;
22594 }
22595
22596
22597 /*
22598 ** Character set conversion objects used by conversion routines.
@@ -22630,17 +22674,668 @@
22674 /* determine string for the conversion of UTF-8 which is CP1208 */
22675 UniStrFromUcs( ucUtf8, out, tempPath, CCHMAXPATH );
22676
22677 return out;
22678 }
22679
22680
22681 #ifndef SQLITE_OMIT_WAL
22682
22683 /*
22684 ** Use main database file for interprocess locking. If un-defined
22685 ** a separate file is created for this purpose. The file will be
22686 ** used only to set file locks. There will be no data written to it.
22687 */
22688 #define SQLITE_OS2_NO_WAL_LOCK_FILE
22689
22690 #if 0
22691 static void _ERR_TRACE( const char *fmt, ... ) {
22692 va_list ap;
22693 va_start(ap, fmt);
22694 vfprintf(stderr, fmt, ap);
22695 fflush(stderr);
22696 }
22697 #define ERR_TRACE(rc, msg) \
22698 if( (rc) != SQLITE_OK ) _ERR_TRACE msg;
22699 #else
22700 #define ERR_TRACE(rc, msg)
22701 #endif
22702
22703 /*
22704 ** Helper functions to obtain and relinquish the global mutex. The
22705 ** global mutex is used to protect os2ShmNodeList.
22706 **
22707 ** Function os2ShmMutexHeld() is used to assert() that the global mutex
22708 ** is held when required. This function is only used as part of assert()
22709 ** statements. e.g.
22710 **
22711 ** os2ShmEnterMutex()
22712 ** assert( os2ShmMutexHeld() );
22713 ** os2ShmLeaveMutex()
22714 */
22715 static void os2ShmEnterMutex(void){
22716 sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
22717 }
22718 static void os2ShmLeaveMutex(void){
22719 sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
22720 }
22721 #ifdef SQLITE_DEBUG
22722 static int os2ShmMutexHeld(void) {
22723 return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
22724 }
22725 int GetCurrentProcessId(void) {
22726 PPIB pib;
22727 DosGetInfoBlocks(NULL, &pib);
22728 return (int)pib->pib_ulpid;
22729 }
22730 #endif
22731
22732 /*
22733 ** Object used to represent a the shared memory area for a single log file.
22734 ** When multiple threads all reference the same log-summary, each thread has
22735 ** its own os2File object, but they all point to a single instance of this
22736 ** object. In other words, each log-summary is opened only once per process.
22737 **
22738 ** os2ShmMutexHeld() must be true when creating or destroying
22739 ** this object or while reading or writing the following fields:
22740 **
22741 ** nRef
22742 ** pNext
22743 **
22744 ** The following fields are read-only after the object is created:
22745 **
22746 ** szRegion
22747 ** hLockFile
22748 ** shmBaseName
22749 **
22750 ** Either os2ShmNode.mutex must be held or os2ShmNode.nRef==0 and
22751 ** os2ShmMutexHeld() is true when reading or writing any other field
22752 ** in this structure.
22753 **
22754 */
22755 struct os2ShmNode {
22756 sqlite3_mutex *mutex; /* Mutex to access this object */
22757 os2ShmNode *pNext; /* Next in list of all os2ShmNode objects */
22758
22759 int szRegion; /* Size of shared-memory regions */
22760
22761 int nRegion; /* Size of array apRegion */
22762 void **apRegion; /* Array of pointers to shared-memory regions */
22763
22764 int nRef; /* Number of os2ShmLink objects pointing to this */
22765 os2ShmLink *pFirst; /* First os2ShmLink object pointing to this */
22766
22767 HFILE hLockFile; /* File used for inter-process memory locking */
22768 char shmBaseName[1]; /* Name of the memory object !!! must last !!! */
22769 };
22770
22771
22772 /*
22773 ** Structure used internally by this VFS to record the state of an
22774 ** open shared memory connection.
22775 **
22776 ** The following fields are initialized when this object is created and
22777 ** are read-only thereafter:
22778 **
22779 ** os2Shm.pShmNode
22780 ** os2Shm.id
22781 **
22782 ** All other fields are read/write. The os2Shm.pShmNode->mutex must be held
22783 ** while accessing any read/write fields.
22784 */
22785 struct os2ShmLink {
22786 os2ShmNode *pShmNode; /* The underlying os2ShmNode object */
22787 os2ShmLink *pNext; /* Next os2Shm with the same os2ShmNode */
22788 u32 sharedMask; /* Mask of shared locks held */
22789 u32 exclMask; /* Mask of exclusive locks held */
22790 #ifdef SQLITE_DEBUG
22791 u8 id; /* Id of this connection with its os2ShmNode */
22792 #endif
22793 };
22794
22795
22796 /*
22797 ** A global list of all os2ShmNode objects.
22798 **
22799 ** The os2ShmMutexHeld() must be true while reading or writing this list.
22800 */
22801 static os2ShmNode *os2ShmNodeList = NULL;
22802
22803 /*
22804 ** Constants used for locking
22805 */
22806 #ifdef SQLITE_OS2_NO_WAL_LOCK_FILE
22807 #define OS2_SHM_BASE (PENDING_BYTE + 0x10000) /* first lock byte */
22808 #else
22809 #define OS2_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */
22810 #endif
22811
22812 #define OS2_SHM_DMS (OS2_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */
22813
22814 /*
22815 ** Apply advisory locks for all n bytes beginning at ofst.
22816 */
22817 #define _SHM_UNLCK 1 /* no lock */
22818 #define _SHM_RDLCK 2 /* shared lock, no wait */
22819 #define _SHM_WRLCK 3 /* exlusive lock, no wait */
22820 #define _SHM_WRLCK_WAIT 4 /* exclusive lock, wait */
22821 static int os2ShmSystemLock(
22822 os2ShmNode *pNode, /* Apply locks to this open shared-memory segment */
22823 int lockType, /* _SHM_UNLCK, _SHM_RDLCK, _SHM_WRLCK or _SHM_WRLCK_WAIT */
22824 int ofst, /* Offset to first byte to be locked/unlocked */
22825 int nByte /* Number of bytes to lock or unlock */
22826 ){
22827 APIRET rc;
22828 FILELOCK area;
22829 ULONG mode, timeout;
22830
22831 /* Access to the os2ShmNode object is serialized by the caller */
22832 assert( sqlite3_mutex_held(pNode->mutex) || pNode->nRef==0 );
22833
22834 mode = 1; /* shared lock */
22835 timeout = 0; /* no wait */
22836 area.lOffset = ofst;
22837 area.lRange = nByte;
22838
22839 switch( lockType ) {
22840 case _SHM_WRLCK_WAIT:
22841 timeout = (ULONG)-1; /* wait forever */
22842 case _SHM_WRLCK:
22843 mode = 0; /* exclusive lock */
22844 case _SHM_RDLCK:
22845 rc = DosSetFileLocks(pNode->hLockFile,
22846 NULL, &area, timeout, mode);
22847 break;
22848 /* case _SHM_UNLCK: */
22849 default:
22850 rc = DosSetFileLocks(pNode->hLockFile,
22851 &area, NULL, 0, 0);
22852 break;
22853 }
22854
22855 OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n",
22856 pNode->hLockFile,
22857 rc==SQLITE_OK ? "ok" : "failed",
22858 lockType==_SHM_UNLCK ? "Unlock" : "Lock",
22859 rc));
22860
22861 ERR_TRACE(rc, ("os2ShmSystemLock: %d %s\n", rc, pNode->shmBaseName))
22862
22863 return ( rc == 0 ) ? SQLITE_OK : SQLITE_BUSY;
22864 }
22865
22866 /*
22867 ** Find an os2ShmNode in global list or allocate a new one, if not found.
22868 **
22869 ** This is not a VFS shared-memory method; it is a utility function called
22870 ** by VFS shared-memory methods.
22871 */
22872 static int os2OpenSharedMemory( os2File *fd, int szRegion ) {
22873 os2ShmLink *pLink;
22874 os2ShmNode *pNode;
22875 int cbShmName, rc = SQLITE_OK;
22876 char shmName[CCHMAXPATH + 30];
22877 #ifndef SQLITE_OS2_NO_WAL_LOCK_FILE
22878 ULONG action;
22879 #endif
22880
22881 /* We need some additional space at the end to append the region number */
22882 cbShmName = sprintf(shmName, "\\SHAREMEM\\%s", fd->zFullPathCp );
22883 if( cbShmName >= CCHMAXPATH-8 )
22884 return SQLITE_IOERR_SHMOPEN;
22885
22886 /* Replace colon in file name to form a valid shared memory name */
22887 shmName[10+1] = '!';
22888
22889 /* Allocate link object (we free it later in case of failure) */
22890 pLink = sqlite3_malloc( sizeof(*pLink) );
22891 if( !pLink )
22892 return SQLITE_NOMEM;
22893
22894 /* Access node list */
22895 os2ShmEnterMutex();
22896
22897 /* Find node by it's shared memory base name */
22898 for( pNode = os2ShmNodeList;
22899 pNode && stricmp(shmName, pNode->shmBaseName) != 0;
22900 pNode = pNode->pNext ) ;
22901
22902 /* Not found: allocate a new node */
22903 if( !pNode ) {
22904 pNode = sqlite3_malloc( sizeof(*pNode) + cbShmName );
22905 if( pNode ) {
22906 memset(pNode, 0, sizeof(*pNode) );
22907 pNode->szRegion = szRegion;
22908 pNode->hLockFile = (HFILE)-1;
22909 strcpy(pNode->shmBaseName, shmName);
22910
22911 #ifdef SQLITE_OS2_NO_WAL_LOCK_FILE
22912 if( DosDupHandle(fd->h, &pNode->hLockFile) != 0 ) {
22913 #else
22914 sprintf(shmName, "%s-lck", fd->zFullPathCp);
22915 if( DosOpen((PSZ)shmName, &pNode->hLockFile, &action, 0, FILE_NORMAL,
22916 OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW,
22917 OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE |
22918 OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR,
22919 NULL) != 0 ) {
22920 #endif
22921 sqlite3_free(pNode);
22922 rc = SQLITE_IOERR;
22923 } else {
22924 pNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
22925 if( !pNode->mutex ) {
22926 sqlite3_free(pNode);
22927 rc = SQLITE_NOMEM;
22928 }
22929 }
22930 } else {
22931 rc = SQLITE_NOMEM;
22932 }
22933
22934 if( rc == SQLITE_OK ) {
22935 pNode->pNext = os2ShmNodeList;
22936 os2ShmNodeList = pNode;
22937 } else {
22938 pNode = NULL;
22939 }
22940 } else if( pNode->szRegion != szRegion ) {
22941 rc = SQLITE_IOERR_SHMSIZE;
22942 pNode = NULL;
22943 }
22944
22945 if( pNode ) {
22946 sqlite3_mutex_enter(pNode->mutex);
22947
22948 memset(pLink, 0, sizeof(*pLink));
22949
22950 pLink->pShmNode = pNode;
22951 pLink->pNext = pNode->pFirst;
22952 pNode->pFirst = pLink;
22953 pNode->nRef++;
22954
22955 fd->pShmLink = pLink;
22956
22957 sqlite3_mutex_leave(pNode->mutex);
22958
22959 } else {
22960 /* Error occured. Free our link object. */
22961 sqlite3_free(pLink);
22962 }
22963
22964 os2ShmLeaveMutex();
22965
22966 ERR_TRACE(rc, ("os2OpenSharedMemory: %d %s\n", rc, fd->zFullPathCp))
22967
22968 return rc;
22969 }
22970
22971 /*
22972 ** Purge the os2ShmNodeList list of all entries with nRef==0.
22973 **
22974 ** This is not a VFS shared-memory method; it is a utility function called
22975 ** by VFS shared-memory methods.
22976 */
22977 static void os2PurgeShmNodes( int deleteFlag ) {
22978 os2ShmNode *pNode;
22979 os2ShmNode **ppNode;
22980
22981 os2ShmEnterMutex();
22982
22983 ppNode = &os2ShmNodeList;
22984
22985 while( *ppNode ) {
22986 pNode = *ppNode;
22987
22988 if( pNode->nRef == 0 ) {
22989 *ppNode = pNode->pNext;
22990
22991 if( pNode->apRegion ) {
22992 /* Prevent other processes from resizing the shared memory */
22993 os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1);
22994
22995 while( pNode->nRegion-- ) {
22996 #ifdef SQLITE_DEBUG
22997 int rc =
22998 #endif
22999 DosFreeMem(pNode->apRegion[pNode->nRegion]);
23000
23001 OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n",
23002 (int)GetCurrentProcessId(), pNode->nRegion,
23003 rc == 0 ? "ok" : "failed"));
23004 }
23005
23006 /* Allow other processes to resize the shared memory */
23007 os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1);
23008
23009 sqlite3_free(pNode->apRegion);
23010 }
23011
23012 DosClose(pNode->hLockFile);
23013
23014 #ifndef SQLITE_OS2_NO_WAL_LOCK_FILE
23015 if( deleteFlag ) {
23016 char fileName[CCHMAXPATH];
23017 /* Skip "\\SHAREMEM\\" */
23018 sprintf(fileName, "%s-lck", pNode->shmBaseName + 10);
23019 /* restore colon */
23020 fileName[1] = ':';
23021
23022 DosForceDelete(fileName);
23023 }
23024 #endif
23025
23026 sqlite3_mutex_free(pNode->mutex);
23027
23028 sqlite3_free(pNode);
23029
23030 } else {
23031 ppNode = &pNode->pNext;
23032 }
23033 }
23034
23035 os2ShmLeaveMutex();
23036 }
23037
23038 /*
23039 ** This function is called to obtain a pointer to region iRegion of the
23040 ** shared-memory associated with the database file id. Shared-memory regions
23041 ** are numbered starting from zero. Each shared-memory region is szRegion
23042 ** bytes in size.
23043 **
23044 ** If an error occurs, an error code is returned and *pp is set to NULL.
23045 **
23046 ** Otherwise, if the bExtend parameter is 0 and the requested shared-memory
23047 ** region has not been allocated (by any client, including one running in a
23048 ** separate process), then *pp is set to NULL and SQLITE_OK returned. If
23049 ** bExtend is non-zero and the requested shared-memory region has not yet
23050 ** been allocated, it is allocated by this function.
23051 **
23052 ** If the shared-memory region has already been allocated or is allocated by
23053 ** this call as described above, then it is mapped into this processes
23054 ** address space (if it is not already), *pp is set to point to the mapped
23055 ** memory and SQLITE_OK returned.
23056 */
23057 static int os2ShmMap(
23058 sqlite3_file *id, /* Handle open on database file */
23059 int iRegion, /* Region to retrieve */
23060 int szRegion, /* Size of regions */
23061 int bExtend, /* True to extend block if necessary */
23062 void volatile **pp /* OUT: Mapped memory */
23063 ){
23064 PVOID pvTemp;
23065 void **apRegion;
23066 os2ShmNode *pNode;
23067 int n, rc = SQLITE_OK;
23068 char shmName[CCHMAXPATH];
23069 os2File *pFile = (os2File*)id;
23070
23071 *pp = NULL;
23072
23073 if( !pFile->pShmLink )
23074 rc = os2OpenSharedMemory( pFile, szRegion );
23075
23076 if( rc == SQLITE_OK ) {
23077 pNode = pFile->pShmLink->pShmNode ;
23078
23079 sqlite3_mutex_enter(pNode->mutex);
23080
23081 assert( szRegion==pNode->szRegion );
23082
23083 /* Unmapped region ? */
23084 if( iRegion >= pNode->nRegion ) {
23085 /* Prevent other processes from resizing the shared memory */
23086 os2ShmSystemLock(pNode, _SHM_WRLCK_WAIT, OS2_SHM_DMS, 1);
23087
23088 apRegion = sqlite3_realloc(
23089 pNode->apRegion, (iRegion + 1) * sizeof(apRegion[0]));
23090
23091 if( apRegion ) {
23092 pNode->apRegion = apRegion;
23093
23094 while( pNode->nRegion <= iRegion ) {
23095 sprintf(shmName, "%s-%u",
23096 pNode->shmBaseName, pNode->nRegion);
23097
23098 if( DosGetNamedSharedMem(&pvTemp, (PSZ)shmName,
23099 PAG_READ | PAG_WRITE) != NO_ERROR ) {
23100 if( !bExtend )
23101 break;
23102
23103 if( DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion,
23104 PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_ANY) != NO_ERROR &&
23105 DosAllocSharedMem(&pvTemp, (PSZ)shmName, szRegion,
23106 PAG_READ | PAG_WRITE | PAG_COMMIT) != NO_ERROR ) {
23107 rc = SQLITE_NOMEM;
23108 break;
23109 }
23110 }
23111
23112 apRegion[pNode->nRegion++] = pvTemp;
23113 }
23114
23115 /* zero out remaining entries */
23116 for( n = pNode->nRegion; n <= iRegion; n++ )
23117 pNode->apRegion[n] = NULL;
23118
23119 /* Return this region (maybe zero) */
23120 *pp = pNode->apRegion[iRegion];
23121 } else {
23122 rc = SQLITE_NOMEM;
23123 }
23124
23125 /* Allow other processes to resize the shared memory */
23126 os2ShmSystemLock(pNode, _SHM_UNLCK, OS2_SHM_DMS, 1);
23127
23128 } else {
23129 /* Region has been mapped previously */
23130 *pp = pNode->apRegion[iRegion];
23131 }
23132
23133 sqlite3_mutex_leave(pNode->mutex);
23134 }
23135
23136 ERR_TRACE(rc, ("os2ShmMap: %s iRgn = %d, szRgn = %d, bExt = %d : %d\n",
23137 pFile->zFullPathCp, iRegion, szRegion, bExtend, rc))
23138
23139 return rc;
23140 }
23141
23142 /*
23143 ** Close a connection to shared-memory. Delete the underlying
23144 ** storage if deleteFlag is true.
23145 **
23146 ** If there is no shared memory associated with the connection then this
23147 ** routine is a harmless no-op.
23148 */
23149 static int os2ShmUnmap(
23150 sqlite3_file *id, /* The underlying database file */
23151 int deleteFlag /* Delete shared-memory if true */
23152 ){
23153 os2File *pFile = (os2File*)id;
23154 os2ShmLink *pLink = pFile->pShmLink;
23155
23156 if( pLink ) {
23157 int nRef = -1;
23158 os2ShmLink **ppLink;
23159 os2ShmNode *pNode = pLink->pShmNode;
23160
23161 sqlite3_mutex_enter(pNode->mutex);
23162
23163 for( ppLink = &pNode->pFirst;
23164 *ppLink && *ppLink != pLink;
23165 ppLink = &(*ppLink)->pNext ) ;
23166
23167 assert(*ppLink);
23168
23169 if( *ppLink ) {
23170 *ppLink = pLink->pNext;
23171 nRef = --pNode->nRef;
23172 } else {
23173 ERR_TRACE(1, ("os2ShmUnmap: link not found ! %s\n",
23174 pNode->shmBaseName))
23175 }
23176
23177 pFile->pShmLink = NULL;
23178 sqlite3_free(pLink);
23179
23180 sqlite3_mutex_leave(pNode->mutex);
23181
23182 if( nRef == 0 )
23183 os2PurgeShmNodes( deleteFlag );
23184 }
23185
23186 return SQLITE_OK;
23187 }
23188
23189 /*
23190 ** Change the lock state for a shared-memory segment.
23191 **
23192 ** Note that the relationship between SHAREd and EXCLUSIVE locks is a little
23193 ** different here than in posix. In xShmLock(), one can go from unlocked
23194 ** to shared and back or from unlocked to exclusive and back. But one may
23195 ** not go from shared to exclusive or from exclusive to shared.
23196 */
23197 static int os2ShmLock(
23198 sqlite3_file *id, /* Database file holding the shared memory */
23199 int ofst, /* First lock to acquire or release */
23200 int n, /* Number of locks to acquire or release */
23201 int flags /* What to do with the lock */
23202 ){
23203 u32 mask; /* Mask of locks to take or release */
23204 int rc = SQLITE_OK; /* Result code */
23205 os2File *pFile = (os2File*)id;
23206 os2ShmLink *p = pFile->pShmLink; /* The shared memory being locked */
23207 os2ShmLink *pX; /* For looping over all siblings */
23208 os2ShmNode *pShmNode = p->pShmNode; /* Our node */
23209
23210 assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
23211 assert( n>=1 );
23212 assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
23213 || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
23214 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
23215 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
23216 assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
23217
23218 mask = (u32)((1U<<(ofst+n)) - (1U<<ofst));
23219 assert( n>1 || mask==(1<<ofst) );
23220
23221
23222 sqlite3_mutex_enter(pShmNode->mutex);
23223
23224 if( flags & SQLITE_SHM_UNLOCK ){
23225 u32 allMask = 0; /* Mask of locks held by siblings */
23226
23227 /* See if any siblings hold this same lock */
23228 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
23229 if( pX==p ) continue;
23230 assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
23231 allMask |= pX->sharedMask;
23232 }
23233
23234 /* Unlock the system-level locks */
23235 if( (mask & allMask)==0 ){
23236 rc = os2ShmSystemLock(pShmNode, _SHM_UNLCK, ofst+OS2_SHM_BASE, n);
23237 }else{
23238 rc = SQLITE_OK;
23239 }
23240
23241 /* Undo the local locks */
23242 if( rc==SQLITE_OK ){
23243 p->exclMask &= ~mask;
23244 p->sharedMask &= ~mask;
23245 }
23246 }else if( flags & SQLITE_SHM_SHARED ){
23247 u32 allShared = 0; /* Union of locks held by connections other than "p" */
23248
23249 /* Find out which shared locks are already held by sibling connections.
23250 ** If any sibling already holds an exclusive lock, go ahead and return
23251 ** SQLITE_BUSY.
23252 */
23253 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
23254 if( (pX->exclMask & mask)!=0 ){
23255 rc = SQLITE_BUSY;
23256 break;
23257 }
23258 allShared |= pX->sharedMask;
23259 }
23260
23261 /* Get shared locks at the system level, if necessary */
23262 if( rc==SQLITE_OK ){
23263 if( (allShared & mask)==0 ){
23264 rc = os2ShmSystemLock(pShmNode, _SHM_RDLCK, ofst+OS2_SHM_BASE, n);
23265 }else{
23266 rc = SQLITE_OK;
23267 }
23268 }
23269
23270 /* Get the local shared locks */
23271 if( rc==SQLITE_OK ){
23272 p->sharedMask |= mask;
23273 }
23274 }else{
23275 /* Make sure no sibling connections hold locks that will block this
23276 ** lock. If any do, return SQLITE_BUSY right away.
23277 */
23278 for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
23279 if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
23280 rc = SQLITE_BUSY;
23281 break;
23282 }
23283 }
23284
23285 /* Get the exclusive locks at the system level. Then if successful
23286 ** also mark the local connection as being locked.
23287 */
23288 if( rc==SQLITE_OK ){
23289 rc = os2ShmSystemLock(pShmNode, _SHM_WRLCK, ofst+OS2_SHM_BASE, n);
23290 if( rc==SQLITE_OK ){
23291 assert( (p->sharedMask & mask)==0 );
23292 p->exclMask |= mask;
23293 }
23294 }
23295 }
23296
23297 sqlite3_mutex_leave(pShmNode->mutex);
23298
23299 OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n",
23300 p->id, (int)GetCurrentProcessId(), p->sharedMask, p->exclMask,
23301 rc ? "failed" : "ok"));
23302
23303 ERR_TRACE(rc, ("os2ShmLock: ofst = %d, n = %d, flags = 0x%x -> %d \n",
23304 ofst, n, flags, rc))
23305
23306 return rc;
23307 }
23308
23309 /*
23310 ** Implement a memory barrier or memory fence on shared memory.
23311 **
23312 ** All loads and stores begun before the barrier must complete before
23313 ** any load or store begun after the barrier.
23314 */
23315 static void os2ShmBarrier(
23316 sqlite3_file *id /* Database file holding the shared memory */
23317 ){
23318 UNUSED_PARAMETER(id);
23319 os2ShmEnterMutex();
23320 os2ShmLeaveMutex();
23321 }
23322
23323 #else
23324 # define os2ShmMap 0
23325 # define os2ShmLock 0
23326 # define os2ShmBarrier 0
23327 # define os2ShmUnmap 0
23328 #endif /* #ifndef SQLITE_OMIT_WAL */
23329
23330
23331 /*
23332 ** This vector defines all the methods that can operate on an
23333 ** sqlite3_file for os2.
23334 */
23335 static const sqlite3_io_methods os2IoMethod = {
23336 2, /* iVersion */
23337 os2Close, /* xClose */
23338 os2Read, /* xRead */
23339 os2Write, /* xWrite */
23340 os2Truncate, /* xTruncate */
23341 os2Sync, /* xSync */
@@ -22649,15 +23344,16 @@
23344 os2Unlock, /* xUnlock */
23345 os2CheckReservedLock, /* xCheckReservedLock */
23346 os2FileControl, /* xFileControl */
23347 os2SectorSize, /* xSectorSize */
23348 os2DeviceCharacteristics, /* xDeviceCharacteristics */
23349 os2ShmMap, /* xShmMap */
23350 os2ShmLock, /* xShmLock */
23351 os2ShmBarrier, /* xShmBarrier */
23352 os2ShmUnmap /* xShmUnmap */
23353 };
23354
23355
23356 /***************************************************************************
23357 ** Here ends the I/O methods that form the sqlite3_io_methods object.
23358 **
23359 ** The next block of code implements the VFS methods.
@@ -22666,54 +23362,61 @@
23362 /*
23363 ** Create a temporary file name in zBuf. zBuf must be big enough to
23364 ** hold at pVfs->mxPathname characters.
23365 */
23366 static int getTempname(int nBuf, char *zBuf ){
23367 static const char zChars[] =
23368 "abcdefghijklmnopqrstuvwxyz"
23369 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
23370 "0123456789";
23371 int i, j;
23372 PSZ zTempPathCp;
23373 char zTempPath[CCHMAXPATH];
23374 ULONG ulDriveNum, ulDriveMap;
23375
23376 /* It's odd to simulate an io-error here, but really this is just
23377 ** using the io-error infrastructure to test that SQLite handles this
23378 ** function failing.
23379 */
23380 SimulateIOError( return SQLITE_IOERR );
23381
23382 if( sqlite3_temp_directory ) {
23383 sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", sqlite3_temp_directory);
23384 } else if( DosScanEnv( (PSZ)"TEMP", &zTempPathCp ) == NO_ERROR ||
23385 DosScanEnv( (PSZ)"TMP", &zTempPathCp ) == NO_ERROR ||
23386 DosScanEnv( (PSZ)"TMPDIR", &zTempPathCp ) == NO_ERROR ) {
23387 char *zTempPathUTF = convertCpPathToUtf8( (char *)zTempPathCp );
23388 sqlite3_snprintf(CCHMAXPATH-30, zTempPath, "%s", zTempPathUTF);
23389 free( zTempPathUTF );
23390 } else if( DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap ) == NO_ERROR ) {
23391 zTempPath[0] = (char)('A' + ulDriveNum - 1);
23392 zTempPath[1] = ':';
23393 zTempPath[2] = '\0';
23394 } else {
23395 zTempPath[0] = '\0';
23396 }
23397
23398 /* Strip off a trailing slashes or backslashes, otherwise we would get *
23399 * multiple (back)slashes which causes DosOpen() to fail. *
23400 * Trailing spaces are not allowed, either. */
23401 j = sqlite3Strlen30(zTempPath);
23402 while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/' ||
23403 zTempPath[j-1] == ' ' ) ){
23404 j--;
23405 }
23406 zTempPath[j] = '\0';
23407
23408 /* We use 20 bytes to randomize the name */
23409 sqlite3_snprintf(nBuf-22, zBuf,
23410 "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
23411 j = sqlite3Strlen30(zBuf);
 
 
 
 
 
23412 sqlite3_randomness( 20, &zBuf[j] );
23413 for( i = 0; i < 20; i++, j++ ){
23414 zBuf[j] = zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
23415 }
23416 zBuf[j] = 0;
23417
23418 OSTRACE(( "TEMP FILENAME: %s\n", zBuf ));
23419 return SQLITE_OK;
23420 }
23421
23422
@@ -22729,12 +23432,12 @@
23432 char *zFull /* Output buffer */
23433 ){
23434 char *zRelativeCp = convertUtf8PathToCp( zRelative );
23435 char zFullCp[CCHMAXPATH] = "\0";
23436 char *zFullUTF;
23437 APIRET rc = DosQueryPathInfo( (PSZ)zRelativeCp, FIL_QUERYFULLNAME,
23438 zFullCp, CCHMAXPATH );
23439 free( zRelativeCp );
23440 zFullUTF = convertCpPathToUtf8( zFullCp );
23441 sqlite3_snprintf( nFull, zFull, zFullUTF );
23442 free( zFullUTF );
23443 return rc == NO_ERROR ? SQLITE_OK : SQLITE_IOERR;
@@ -22760,14 +23463,14 @@
23463 const char *zUtf8Name = zName;
23464 char *zNameCp;
23465 char zTmpname[CCHMAXPATH];
23466
23467 int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE);
 
23468 int isCreate = (flags & SQLITE_OPEN_CREATE);
23469 int isReadWrite = (flags & SQLITE_OPEN_READWRITE);
23470 #ifndef NDEBUG
23471 int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE);
23472 int isReadonly = (flags & SQLITE_OPEN_READONLY);
23473 int eType = (flags & 0xFFFFFF00);
23474 int isOpenJournal = (isCreate && (
23475 eType==SQLITE_OPEN_MASTER_JOURNAL
23476 || eType==SQLITE_OPEN_MAIN_JOURNAL
@@ -22803,11 +23506,11 @@
23506 || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL
23507 || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
23508 );
23509
23510 memset( pFile, 0, sizeof(*pFile) );
23511 pFile->h = (HFILE)-1;
23512
23513 /* If the second argument to this function is NULL, generate a
23514 ** temporary file name to use
23515 */
23516 if( !zUtf8Name ){
@@ -22825,15 +23528,15 @@
23528 ulOpenMode |= OPEN_ACCESS_READONLY;
23529 }
23530
23531 /* Open in random access mode for possibly better speed. Allow full
23532 ** sharing because file locks will provide exclusive access when needed.
23533 ** The handle should not be inherited by child processes and we don't
23534 ** want popups from the critical error handler.
23535 */
23536 ulOpenMode |= OPEN_FLAGS_RANDOM | OPEN_SHARE_DENYNONE |
23537 OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR;
 
 
23538
23539 /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is
23540 ** created. SQLite doesn't use it to indicate "exclusive access"
23541 ** as it is usually understood.
23542 */
@@ -22847,17 +23550,10 @@
23550 }else{
23551 /* Opens a file, only if it exists. */
23552 ulOpenFlags |= OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
23553 }
23554
 
 
 
 
 
 
 
23555 zNameCp = convertUtf8PathToCp( zUtf8Name );
23556 rc = DosOpen( (PSZ)zNameCp,
23557 &h,
23558 &ulAction,
23559 0L,
@@ -22868,13 +23564,10 @@
23564 free( zNameCp );
23565
23566 if( rc != NO_ERROR ){
23567 OSTRACE(( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulFlags=%#lx, ulMode=%#lx\n",
23568 rc, zUtf8Name, ulAction, ulOpenFlags, ulOpenMode ));
 
 
 
23569
23570 if( isReadWrite ){
23571 return os2Open( pVfs, zName, id,
23572 ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
23573 pOutFlags );
@@ -22885,11 +23578,16 @@
23578
23579 if( pOutFlags ){
23580 *pOutFlags = isReadWrite ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY;
23581 }
23582
23583 os2FullPathname( pVfs, zUtf8Name, sizeof( zTmpname ), zTmpname );
23584 pFile->zFullPathCp = convertUtf8PathToCp( zTmpname );
23585 pFile->pMethod = &os2IoMethod;
23586 pFile->flags = flags;
23587 pFile->h = h;
23588
23589 OpenCounter(+1);
23590 OSTRACE(( "OPEN %d pOutFlags=%d\n", pFile->h, pOutFlags ));
23591 return SQLITE_OK;
23592 }
23593
@@ -22920,34 +23618,46 @@
23618 sqlite3_vfs *pVfs, /* Not used on os2 */
23619 const char *zFilename, /* Name of file to check */
23620 int flags, /* Type of test to make on this file */
23621 int *pOut /* Write results here */
23622 ){
23623 APIRET rc;
23624 FILESTATUS3 fsts3ConfigInfo;
23625 char *zFilenameCp;
 
23626
23627 UNUSED_PARAMETER(pVfs);
23628 SimulateIOError( return SQLITE_IOERR_ACCESS; );
23629
23630 zFilenameCp = convertUtf8PathToCp( zFilename );
23631 rc = DosQueryPathInfo( (PSZ)zFilenameCp, FIL_STANDARD,
23632 &fsts3ConfigInfo, sizeof(FILESTATUS3) );
23633 free( zFilenameCp );
23634 OSTRACE(( "ACCESS fsts3ConfigInfo.attrFile=%d flags=%d rc=%d\n",
23635 fsts3ConfigInfo.attrFile, flags, rc ));
23636
23637 switch( flags ){
 
23638 case SQLITE_ACCESS_EXISTS:
23639 /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
23640 ** as if it does not exist.
23641 */
23642 if( fsts3ConfigInfo.cbFile == 0 )
23643 rc = ERROR_FILE_NOT_FOUND;
23644 break;
23645 case SQLITE_ACCESS_READ:
23646 break;
23647 case SQLITE_ACCESS_READWRITE:
23648 if( fsts3ConfigInfo.attrFile & FILE_READONLY )
23649 rc = ERROR_ACCESS_DENIED;
23650 break;
23651 default:
23652 rc = ERROR_FILE_NOT_FOUND;
23653 assert( !"Invalid flags argument" );
23654 }
23655
23656 *pOut = (rc == NO_ERROR);
23657 OSTRACE(( "ACCESS %s flags %d: rc=%d\n", zFilename, flags, *pOut ));
23658
23659 return SQLITE_OK;
23660 }
23661
23662
23663 #ifndef SQLITE_OMIT_LOAD_EXTENSION
@@ -22958,15 +23668,14 @@
23668 /*
23669 ** Interfaces for opening a shared library, finding entry points
23670 ** within the shared library, and closing the shared library.
23671 */
23672 static void *os2DlOpen(sqlite3_vfs *pVfs, const char *zFilename){
 
23673 HMODULE hmod;
23674 APIRET rc;
23675 char *zFilenameCp = convertUtf8PathToCp(zFilename);
23676 rc = DosLoadModule(NULL, 0, (PSZ)zFilenameCp, &hmod);
23677 free(zFilenameCp);
23678 return rc != NO_ERROR ? 0 : (void*)hmod;
23679 }
23680 /*
23681 ** A no-op since the error code is returned on the DosLoadModule call.
@@ -22976,18 +23685,18 @@
23685 /* no-op */
23686 }
23687 static void (*os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
23688 PFN pfn;
23689 APIRET rc;
23690 rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)zSymbol, &pfn);
23691 if( rc != NO_ERROR ){
23692 /* if the symbol itself was not found, search again for the same
23693 * symbol with an extra underscore, that might be needed depending
23694 * on the calling convention */
23695 char _zSymbol[256] = "_";
23696 strncat(_zSymbol, zSymbol, 254);
23697 rc = DosQueryProcAddr((HMODULE)pHandle, 0L, (PSZ)_zSymbol, &pfn);
23698 }
23699 return rc != NO_ERROR ? 0 : (void(*)(void))pfn;
23700 }
23701 static void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){
23702 DosFreeModule((HMODULE)pHandle);
@@ -23007,58 +23716,43 @@
23716 int n = 0;
23717 #if defined(SQLITE_TEST)
23718 n = nBuf;
23719 memset(zBuf, 0, nBuf);
23720 #else
23721 int i;
23722 PPIB ppib;
23723 PTIB ptib;
23724 DATETIME dt;
23725 static unsigned c = 0;
23726 /* Ordered by variation probability */
23727 static ULONG svIdx[6] = { QSV_MS_COUNT, QSV_TIME_LOW,
23728 QSV_MAXPRMEM, QSV_MAXSHMEM,
23729 QSV_TOTAVAILMEM, QSV_TOTRESMEM };
23730
23731 /* 8 bytes; timezone and weekday don't increase the randomness much */
23732 if( (int)sizeof(dt)-3 <= nBuf - n ){
23733 c += 0x0100;
23734 DosGetDateTime(&dt);
23735 dt.year = (USHORT)((dt.year - 1900) | c);
23736 memcpy(&zBuf[n], &dt, sizeof(dt)-3);
23737 n += sizeof(dt)-3;
23738 }
23739
23740 /* 4 bytes; PIDs and TIDs are 16 bit internally, so combine them */
23741 if( (int)sizeof(ULONG) <= nBuf - n ){
23742 DosGetInfoBlocks(&ptib, &ppib);
23743 *(PULONG)&zBuf[n] = MAKELONG(ppib->pib_ulpid,
23744 ptib->tib_ptib2->tib2_ultid);
23745 n += sizeof(ULONG);
23746 }
23747
23748 /* Up to 6 * 4 bytes; variables depend on the system state */
23749 for( i = 0; i < 6 && (int)sizeof(ULONG) <= nBuf - n; i++ ){
23750 DosQuerySysInfo(svIdx[i], svIdx[i],
23751 (PULONG)&zBuf[n], sizeof(ULONG));
23752 n += sizeof(ULONG);
23753 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23754 #endif
23755
23756 return n;
23757 }
23758
@@ -23082,68 +23776,102 @@
23776 #ifdef SQLITE_TEST
23777 SQLITE_API int sqlite3_current_time = 0;
23778 #endif
23779
23780 /*
23781 ** Find the current time (in Universal Coordinated Time). Write into *piNow
23782 ** the current time and date as a Julian Day number times 86_400_000. In
23783 ** other words, write into *piNow the number of milliseconds since the Julian
23784 ** epoch of noon in Greenwich on November 24, 4714 B.C according to the
23785 ** proleptic Gregorian calendar.
23786 **
23787 ** On success, return 0. Return 1 if the time and date cannot be found.
23788 */
23789 static int os2CurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
23790 #ifdef SQLITE_TEST
23791 static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
23792 #endif
23793 int year, month, datepart, timepart;
23794
23795 DATETIME dt;
23796 DosGetDateTime( &dt );
23797
23798 year = dt.year;
23799 month = dt.month;
 
 
 
 
23800
23801 /* Calculations from http://www.astro.keele.ac.uk/~rno/Astronomy/hjd.html
23802 ** http://www.astro.keele.ac.uk/~rno/Astronomy/hjd-0.1.c
23803 ** Calculate the Julian days
23804 */
23805 datepart = (int)dt.day - 32076 +
23806 1461*(year + 4800 + (month - 14)/12)/4 +
23807 367*(month - 2 - (month - 14)/12*12)/12 -
23808 3*((year + 4900 + (month - 14)/12)/100)/4;
23809
23810 /* Time in milliseconds, hours to noon added */
23811 timepart = 12*3600*1000 + dt.hundredths*10 + dt.seconds*1000 +
23812 ((int)dt.minutes + dt.timezone)*60*1000 + dt.hours*3600*1000;
23813
23814 *piNow = (sqlite3_int64)datepart*86400*1000 + timepart;
23815
23816 #ifdef SQLITE_TEST
23817 if( sqlite3_current_time ){
23818 *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
23819 }
23820 #endif
23821
23822 UNUSED_PARAMETER(pVfs);
23823 return 0;
23824 }
23825
23826 /*
23827 ** Find the current time (in Universal Coordinated Time). Write the
23828 ** current time and date as a Julian Day number into *prNow and
23829 ** return 0. Return 1 if the time and date cannot be found.
23830 */
23831 static int os2CurrentTime( sqlite3_vfs *pVfs, double *prNow ){
23832 int rc;
23833 sqlite3_int64 i;
23834 rc = os2CurrentTimeInt64(pVfs, &i);
23835 if( !rc ){
23836 *prNow = i/86400000.0;
23837 }
23838 return rc;
23839 }
23840
23841 /*
23842 ** The idea is that this function works like a combination of
23843 ** GetLastError() and FormatMessage() on windows (or errno and
23844 ** strerror_r() on unix). After an error is returned by an OS
23845 ** function, SQLite calls this function with zBuf pointing to
23846 ** a buffer of nBuf bytes. The OS layer should populate the
23847 ** buffer with a nul-terminated UTF-8 encoded error message
23848 ** describing the last IO error to have occurred within the calling
23849 ** thread.
23850 **
23851 ** If the error message is too large for the supplied buffer,
23852 ** it should be truncated. The return value of xGetLastError
23853 ** is zero if the error message fits in the buffer, or non-zero
23854 ** otherwise (if the message was truncated). If non-zero is returned,
23855 ** then it is not necessary to include the nul-terminator character
23856 ** in the output buffer.
23857 **
23858 ** Not supplying an error message will have no adverse effect
23859 ** on SQLite. It is fine to have an implementation that never
23860 ** returns an error message:
23861 **
23862 ** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
23863 ** assert(zBuf[0]=='\0');
23864 ** return 0;
23865 ** }
23866 **
23867 ** However if an error message is supplied, it will be incorporated
23868 ** by sqlite into the error message available to the user using
23869 ** sqlite3_errmsg(), possibly making IO errors easier to debug.
23870 */
23871 static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
23872 assert(zBuf[0]=='\0');
23873 return 0;
23874 }
23875
23876 /*
23877 ** Initialize and deinitialize the operating system interface.
@@ -23167,17 +23895,18 @@
23895 os2DlClose, /* xDlClose */
23896 os2Randomness, /* xRandomness */
23897 os2Sleep, /* xSleep */
23898 os2CurrentTime, /* xCurrentTime */
23899 os2GetLastError, /* xGetLastError */
23900 os2CurrentTimeInt64, /* xCurrentTimeInt64 */
23901 0, /* xSetSystemCall */
23902 0, /* xGetSystemCall */
23903 0 /* xNextSystemCall */
23904 };
23905 sqlite3_vfs_register(&os2Vfs, 1);
23906 initUconvObjects();
23907 /* sqlite3OSTrace = 1; */
23908 return SQLITE_OK;
23909 }
23910 SQLITE_API int sqlite3_os_end(void){
23911 freeUconvObjects();
23912 return SQLITE_OK;
@@ -23752,12 +24481,14 @@
24481 { "pwrite64", (sqlite3_syscall_ptr)0, 0 },
24482 #endif
24483 #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off_t))\
24484 aSyscall[13].pCurrent)
24485
24486 #if SQLITE_ENABLE_LOCKING_STYLE
24487 { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 },
24488 #define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent)
24489 #endif
24490
24491 #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
24492 { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 },
24493 #else
24494 { "fallocate", (sqlite3_syscall_ptr)0, 0 },
@@ -54608,10 +55339,14 @@
55339 Pager * const pDestPager = sqlite3BtreePager(p->pDest);
55340 const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
55341 int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
55342 const int nCopy = MIN(nSrcPgsz, nDestPgsz);
55343 const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
55344 #ifdef SQLITE_HAS_CODEC
55345 int nSrcReserve = sqlite3BtreeGetReserve(p->pSrc);
55346 int nDestReserve = sqlite3BtreeGetReserve(p->pDest);
55347 #endif
55348
55349 int rc = SQLITE_OK;
55350 i64 iOff;
55351
55352 assert( p->bDestLocked );
@@ -54626,15 +55361,26 @@
55361 rc = SQLITE_READONLY;
55362 }
55363
55364 #ifdef SQLITE_HAS_CODEC
55365 /* Backup is not possible if the page size of the destination is changing
55366 ** and a codec is in use.
55367 */
55368 if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){
55369 rc = SQLITE_READONLY;
55370 }
55371
55372 /* Backup is not possible if the number of bytes of reserve space differ
55373 ** between source and destination. If there is a difference, try to
55374 ** fix the destination to agree with the source. If that is not possible,
55375 ** then the backup cannot proceed.
55376 */
55377 if( nSrcReserve!=nDestReserve ){
55378 u32 newPgsz = nSrcPgsz;
55379 rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
55380 if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY;
55381 }
55382 #endif
55383
55384 /* This loop runs once for each destination page spanned by the source
55385 ** page. For each iteration, variable iOff is set to the byte offset
55386 ** of the destination page.
@@ -54996,11 +55742,15 @@
55742 if( !isFatalError(p->rc) && iPage<p->iNext ){
55743 /* The backup process p has already copied page iPage. But now it
55744 ** has been modified by a transaction on the source pager. Copy
55745 ** the new data into the backup.
55746 */
55747 int rc;
55748 assert( p->pDestDb );
55749 sqlite3_mutex_enter(p->pDestDb->mutex);
55750 rc = backupOnePage(p, iPage, aData);
55751 sqlite3_mutex_leave(p->pDestDb->mutex);
55752 assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
55753 if( rc!=SQLITE_OK ){
55754 p->rc = rc;
55755 }
55756 }
@@ -74977,10 +75727,14 @@
75727 }
75728 if( i==0 ) pTable->nRowEst = v;
75729 if( pIndex==0 ) break;
75730 pIndex->aiRowEst[i] = v;
75731 if( *z==' ' ) z++;
75732 if( memcmp(z, "unordered", 10)==0 ){
75733 pIndex->bUnordered = 1;
75734 break;
75735 }
75736 }
75737 return 0;
75738 }
75739
75740 /*
@@ -75322,11 +76076,13 @@
76076 break;
76077
76078 case SQLITE_NULL:
76079 /* No key specified. Use the key from the main database */
76080 sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
76081 if( nKey>0 || sqlite3BtreeGetReserve(db->aDb[0].pBt)>0 ){
76082 rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
76083 }
76084 break;
76085 }
76086 }
76087 #endif
76088
@@ -76753,10 +77509,13 @@
77509 }
77510 pTable = sqlite3FindTable(db, zName, zDb);
77511 if( pTable ){
77512 if( !noErr ){
77513 sqlite3ErrorMsg(pParse, "table %T already exists", pName);
77514 }else{
77515 assert( !db->init.busy );
77516 sqlite3CodeVerifySchema(pParse, iDb);
77517 }
77518 goto begin_table_error;
77519 }
77520 if( sqlite3FindIndex(db, zName, zDb)!=0 ){
77521 sqlite3ErrorMsg(pParse, "there is already an index named %s", zName);
@@ -77940,10 +78699,11 @@
78699 pTab = sqlite3LocateTable(pParse, isView,
78700 pName->a[0].zName, pName->a[0].zDatabase);
78701 if( noErr ) db->suppressErr--;
78702
78703 if( pTab==0 ){
78704 if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
78705 goto exit_drop_table;
78706 }
78707 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
78708 assert( iDb>=0 && iDb<db->nDb );
78709
@@ -78458,10 +79218,13 @@
79218 }
79219 }
79220 if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){
79221 if( !ifNotExist ){
79222 sqlite3ErrorMsg(pParse, "index %s already exists", zName);
79223 }else{
79224 assert( !db->init.busy );
79225 sqlite3CodeVerifySchema(pParse, iDb);
79226 }
79227 goto exit_create_index;
79228 }
79229 }else{
79230 int n;
@@ -78851,10 +79614,12 @@
79614 }
79615 pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
79616 if( pIndex==0 ){
79617 if( !ifExists ){
79618 sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0);
79619 }else{
79620 sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
79621 }
79622 pParse->checkSchema = 1;
79623 goto exit_drop_index;
79624 }
79625 if( pIndex->autoIndex ){
@@ -79439,10 +80204,25 @@
80204 sqlite3OpenTempDatabase(pToplevel);
80205 }
80206 }
80207 }
80208 }
80209
80210 /*
80211 ** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each
80212 ** attached database. Otherwise, invoke it for the database named zDb only.
80213 */
80214 SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){
80215 sqlite3 *db = pParse->db;
80216 int i;
80217 for(i=0; i<db->nDb; i++){
80218 Db *pDb = &db->aDb[i];
80219 if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zName)) ){
80220 sqlite3CodeVerifySchema(pParse, i);
80221 }
80222 }
80223 }
80224
80225 /*
80226 ** Generate VDBE code that prepares for doing an operation that
80227 ** might change the database.
80228 **
@@ -84872,13 +85652,12 @@
85652 ** index and making sure that duplicate entries do not already exist.
85653 ** Add the new records to the indices as we go.
85654 */
85655 for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
85656 int regIdx;
 
85657 int regR;
85658
85659 if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */
85660
85661 /* Create a key for accessing the index entry */
85662 regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
85663 for(i=0; i<pIdx->nColumn; i++){
@@ -84892,15 +85671,10 @@
85671 sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
85672 sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
85673 sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
85674 sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);
85675
 
 
 
 
 
85676 /* Find out what action to take in case there is an indexing conflict */
85677 onError = pIdx->onError;
85678 if( onError==OE_None ){
85679 sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
85680 continue; /* pIdx is not a UNIQUE index */
@@ -84970,11 +85744,10 @@
85744 break;
85745 }
85746 }
85747 sqlite3VdbeJumpHere(v, j3);
85748 sqlite3ReleaseTempReg(pParse, regR);
 
85749 }
85750
85751 if( pbMayReplace ){
85752 *pbMayReplace = seenReplace;
85753 }
@@ -88180,11 +88953,11 @@
88953 if( zExtra ){
88954 *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg,
88955 "%s - %s", *pData->pzErrMsg, zExtra);
88956 }
88957 }
88958 pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT;
88959 }
88960
88961 /*
88962 ** This is the callback routine for the code that initializes the
88963 ** database. See sqlite3Init() below for additional information.
@@ -93841,10 +94614,13 @@
94614 assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
94615 if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),
94616 zName, sqlite3Strlen30(zName)) ){
94617 if( !noErr ){
94618 sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
94619 }else{
94620 assert( !db->init.busy );
94621 sqlite3CodeVerifySchema(pParse, iDb);
94622 }
94623 goto trigger_cleanup;
94624 }
94625
94626 /* Do not create a trigger on a system table */
@@ -94169,10 +94945,12 @@
94945 if( pTrigger ) break;
94946 }
94947 if( !pTrigger ){
94948 if( !noErr ){
94949 sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
94950 }else{
94951 sqlite3CodeVerifyNamedSchema(pParse, zDb);
94952 }
94953 pParse->checkSchema = 1;
94954 goto drop_trigger_cleanup;
94955 }
94956 sqlite3DropTriggerPtr(pParse, pTrigger);
@@ -98075,11 +98853,14 @@
98853 ** Note that the virtual term must be tagged with TERM_VNULL. This
98854 ** TERM_VNULL tag will suppress the not-null check at the beginning
98855 ** of the loop. Without the TERM_VNULL flag, the not-null check at
98856 ** the start of the loop will prevent any results from being returned.
98857 */
98858 if( pExpr->op==TK_NOTNULL
98859 && pExpr->pLeft->op==TK_COLUMN
98860 && pExpr->pLeft->iColumn>=0
98861 ){
98862 Expr *pNewExpr;
98863 Expr *pLeft = pExpr->pLeft;
98864 int idxNew;
98865 WhereTerm *pNewTerm;
98866
@@ -99265,11 +100046,11 @@
100046 ** This routine can fail if it is unable to load a collating sequence
100047 ** required for string comparison, or if unable to allocate memory
100048 ** for a UTF conversion required for comparison. The error is stored
100049 ** in the pParse structure.
100050 */
100051 static int whereEqualScanEst(
100052 Parse *pParse, /* Parsing & code generating context */
100053 Index *p, /* The index whose left-most column is pTerm */
100054 Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */
100055 double *pnRow /* Write the revised row estimate here */
100056 ){
@@ -99322,11 +100103,11 @@
100103 ** This routine can fail if it is unable to load a collating sequence
100104 ** required for string comparison, or if unable to allocate memory
100105 ** for a UTF conversion required for comparison. The error is stored
100106 ** in the pParse structure.
100107 */
100108 static int whereInScanEst(
100109 Parse *pParse, /* Parsing & code generating context */
100110 Index *p, /* The index whose left-most column is pTerm */
100111 ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
100112 double *pnRow /* Write the revised row estimate here */
100113 ){
@@ -99593,11 +100374,11 @@
100374 #endif
100375 used |= pTerm->prereqRight;
100376 }
100377
100378 /* Determine the value of estBound. */
100379 if( nEq<pProbe->nColumn && pProbe->bUnordered==0 ){
100380 int j = pProbe->aiColumn[nEq];
100381 if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
100382 WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx);
100383 WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx);
100384 whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &estBound);
@@ -99625,10 +100406,11 @@
100406 ** naturally scan rows in the required order, set the appropriate flags
100407 ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index
100408 ** will scan rows in a different order, set the bSort variable. */
100409 if( pOrderBy ){
100410 if( (wsFlags & WHERE_COLUMN_IN)==0
100411 && pProbe->bUnordered==0
100412 && isSortingIndex(pParse, pWC->pMaskSet, pProbe, iCur, pOrderBy,
100413 nEq, wsFlags, &rev)
100414 ){
100415 wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY;
100416 wsFlags |= (rev ? WHERE_REVERSE : 0);
100417
+1 -1
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107107
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108108
** [sqlite_version()] and [sqlite_source_id()].
109109
*/
110110
#define SQLITE_VERSION "3.7.6"
111111
#define SQLITE_VERSION_NUMBER 3007006
112
-#define SQLITE_SOURCE_ID "2011-04-07 15:24:08 bf78acb9dfacde0f08a5b3ceac13480f12a06168"
112
+#define SQLITE_SOURCE_ID "2011-04-12 01:58:40 f9d43fa363d54beab6f45db005abac0a7c0c47a7"
113113
114114
/*
115115
** CAPI3REF: Run-Time Library Version Numbers
116116
** KEYWORDS: sqlite3_version, sqlite3_sourceid
117117
**
118118
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.6"
111 #define SQLITE_VERSION_NUMBER 3007006
112 #define SQLITE_SOURCE_ID "2011-04-07 15:24:08 bf78acb9dfacde0f08a5b3ceac13480f12a06168"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
118
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.6"
111 #define SQLITE_VERSION_NUMBER 3007006
112 #define SQLITE_SOURCE_ID "2011-04-12 01:58:40 f9d43fa363d54beab6f45db005abac0a7c0c47a7"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
118

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button