SQLite

Check-in [b6ea2f21f6]
Login

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

Overview
Comment:Avoid making unnecessary changes to the signatures of the sqlite3_auto_extension() and sqlite3_cancel_auto_extension() interfaces.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b6ea2f21f602031ef4dbd47462ac11b0bb0d5de6
User & Date: drh 2016-08-01 14:35:48.519
Context
2016-08-01
15:00
Update releasetest.tcl to automatically do one round of tests with USE_STDCALL=1 when running on Windows with MSVC. (check-in: a6a112de48 user: drh tags: trunk)
14:35
Avoid making unnecessary changes to the signatures of the sqlite3_auto_extension() and sqlite3_cancel_auto_extension() interfaces. (check-in: b6ea2f21f6 user: drh tags: trunk)
2016-07-30
18:54
Fix harmless compiler warning seen with MSVC. (check-in: 390a38a142 user: mistachkin tags: trunk)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to src/loadext.c.
672
673
674
675
676
677
678
679

680
681
682
683
684
685
686
672
673
674
675
676
677
678

679
680
681
682
683
684
685
686







-
+









/*
** Register a statically linked extension that is automatically
** loaded by every new database connection.
*/
int sqlite3_auto_extension(
  int (*xInit)(sqlite3 *, char **, const sqlite3_api_routines *)
  void (*xInit)(void)
){
  int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_AUTOINIT
  rc = sqlite3_initialize();
  if( rc ){
    return rc;
  }else
719
720
721
722
723
724
725
726

727
728
729
730
731
732
733
719
720
721
722
723
724
725

726
727
728
729
730
731
732
733







-
+







** is currently on the list.  If xInit is not on the list, then this
** routine is a no-op.
**
** Return 1 if xInit was found on the list and removed.  Return 0 if xInit
** was not on the list.
*/
int sqlite3_cancel_auto_extension(
  int (*xInit)(sqlite3 *, char **, const sqlite3_api_routines *)
  void (*xInit)(void)
){
#if SQLITE_THREADSAFE
  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
  int i;
  int n = 0;
  wsdAutoextInit;
Changes to src/sqlite.h.in.
1041
1042
1043
1044
1045
1046
1047










1048
1049
1050
1051
1052
1053
1054
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064







+
+
+
+
+
+
+
+
+
+







** at the internal representation of an [sqlite3_mutex].  It only
** deals with pointers to the [sqlite3_mutex] object.
**
** Mutexes are created using [sqlite3_mutex_alloc()].
*/
typedef struct sqlite3_mutex sqlite3_mutex;

/*
** CAPI3REF: Loadable Extension Thunk
**
** A pointer to the opaque sqlite3_api_routines structure is passed as
** the third parameter to entry points of [loadable extensions].  This
** structure must be typedefed in order to work around compiler warnings
** on some platforms.
*/
typedef struct sqlite3_api_routines sqlite3_api_routines;

/*
** CAPI3REF: OS Interface Object
**
** An instance of the sqlite3_vfs object defines the interface between
** the SQLite core and the underlying operating system.  The "vfs"
** in the name of the object stands for "virtual file system".  See
** the [VFS | VFS documentation] for further information.
2238
2239
2240
2241
2242
2243
2244
2245

2246
2247
2248
2249
2250
2251
2252
2248
2249
2250
2251
2252
2253
2254

2255
2256
2257
2258
2259
2260
2261
2262







-
+







** database connection that invoked the busy handler.  In other words,
** the busy handler is not reentrant.  Any such actions
** result in undefined behavior.
** 
** A busy handler must not close the database connection
** or [prepared statement] that invoked the busy handler.
*/
int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);

/*
** CAPI3REF: Set A Busy Timeout
** METHOD: sqlite3
**
** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps
** for a specified amount of time when a table is locked.  ^The handler
5677
5678
5679
5680
5681
5682
5683
5684

5685
5686
5687
5688
5689
5690
5691
5687
5688
5689
5690
5691
5692
5693

5694
5695
5696
5697
5698
5699
5700
5701







-
+







** ^This interface causes the xEntryPoint() function to be invoked for
** each new [database connection] that is created.  The idea here is that
** xEntryPoint() is the entry point for a statically linked [SQLite extension]
** that is to be automatically loaded into all new database connections.
**
** ^(Even though the function prototype shows that xEntryPoint() takes
** no arguments and returns void, SQLite invokes xEntryPoint() with three
** arguments and expects and integer result as if the signature of the
** arguments and expects an integer result as if the signature of the
** entry point where as follows:
**
** <blockquote><pre>
** &nbsp;  int xEntryPoint(
** &nbsp;    sqlite3 *db,
** &nbsp;    const char **pzErrMsg,
** &nbsp;    const struct sqlite3_api_routines *pThunk
5703
5704
5705
5706
5707
5708
5709
5710
5711

5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725

5726
5727
5728
5729
5730
5731
5732
5733
5734
5713
5714
5715
5716
5717
5718
5719


5720


5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731

5732


5733
5734
5735
5736
5737
5738
5739







-
-
+
-
-











-
+
-
-







** ^Calling sqlite3_auto_extension(X) with an entry point X that is already
** on the list of automatic extensions is a harmless no-op. ^No entry point
** will be called more than once for each database connection that is opened.
**
** See also: [sqlite3_reset_auto_extension()]
** and [sqlite3_cancel_auto_extension()]
*/
typedef struct sqlite3_api_routines sqlite3_api_routines;
int sqlite3_auto_extension(
int sqlite3_auto_extension(void(*xEntryPoint)(void));
  int (*xEntryPoint)(sqlite3 *, char **, const sqlite3_api_routines *)
);

/*
** CAPI3REF: Cancel Automatic Extension Loading
**
** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the
** initialization routine X that was registered using a prior call to
** [sqlite3_auto_extension(X)].  ^The [sqlite3_cancel_auto_extension(X)]
** routine returns 1 if initialization routine X was successfully 
** unregistered and it returns 0 if X was not on the list of initialization
** routines.
*/
int sqlite3_cancel_auto_extension(
int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
  int (*xEntryPoint)(sqlite3 *, char **, const sqlite3_api_routines *)
);

/*
** CAPI3REF: Reset Automatic Extension Loading
**
** ^This interface disables all automatic extensions previously
** registered using [sqlite3_auto_extension()].
*/
Changes to src/sqlite3ext.h.
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
15
16
17
18
19
20
21


22
23
24
25
26
27
28







-
-







** as extensions by SQLite should #include this file instead of 
** sqlite3.h.
*/
#ifndef SQLITE3EXT_H
#define SQLITE3EXT_H
#include "sqlite3.h"

typedef struct sqlite3_api_routines sqlite3_api_routines;

/*
** The following structure holds pointers to all of the SQLite API
** routines.
**
** WARNING:  In order to maintain backwards compatibility, add new
** interfaces to the end of this structure only.  If you insert new
** interfaces in the middle of this structure, then older different
247
248
249
250
251
252
253
254

255
256
257
258
259

260
261
262
263
264
265
266
267
245
246
247
248
249
250
251

252
253
254
255
256

257

258
259
260
261
262
263
264







-
+




-
+
-







  int (*stricmp)(const char*,const char*);
  int (*uri_boolean)(const char*,const char*,int);
  sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
  const char *(*uri_parameter)(const char*,const char*);
  char *(*vsnprintf)(int,char*,const char*,va_list);
  int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
  /* Version 3.8.7 and later */
  int (*auto_extension)(int(*)(sqlite3*,char**,const sqlite3_api_routines*));
  int (*auto_extension)(void(*)(void));
  int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
                     void(*)(void*));
  int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
                      void(*)(void*),unsigned char);
  int (*cancel_auto_extension)(int(*)(sqlite3*,char**,
  int (*cancel_auto_extension)(void(*)(void));
                                       const sqlite3_api_routines*));
  int (*load_extension)(sqlite3*,const char*,const char*,char**);
  void *(*malloc64)(sqlite3_uint64);
  sqlite3_uint64 (*msize)(void*);
  void *(*realloc64)(void*,sqlite3_uint64);
  void (*reset_auto_extension)(void);
  void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
                        void(*)(void*));
Changes to src/test1.c.
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6738
6739
6740
6741
6742
6743
6744

6745
6746
6747
6748
6749
6750
6751







-







    }
    return TCL_ERROR;
  }
  sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, db, mask);
  return TCL_OK;
}

typedef struct sqlite3_api_routines sqlite3_api_routines;
/*
**     load_static_extension DB NAME ...
**
** Load one or more statically linked extensions.
*/
static int SQLITE_TCLAPI tclLoadStaticExtensionCmd(
  void * clientData,
Changes to src/test_autoext.c.
96
97
98
99
100
101
102
103

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167

168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

184
185
186
187
188
189
190
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182

183
184
185
186
187
188
189
190







-
+















-
+















-
+















-
+















-
+















-
+







*/
static int SQLITE_TCLAPI autoExtSqrObjCmd(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int rc = sqlite3_auto_extension(sqr_init);
  int rc = sqlite3_auto_extension((void(*)(void))sqr_init);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  return SQLITE_OK;
}

/*
** tclcmd:   sqlite3_cancel_auto_extension_sqr
**
** Unregister the "sqr" extension.
*/
static int SQLITE_TCLAPI cancelAutoExtSqrObjCmd(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int rc = sqlite3_cancel_auto_extension(sqr_init);
  int rc = sqlite3_cancel_auto_extension((void(*)(void))sqr_init);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  return SQLITE_OK;
}

/*
** tclcmd:   sqlite3_auto_extension_cube
**
** Register the "cube" extension to be loaded automatically.
*/
static int SQLITE_TCLAPI autoExtCubeObjCmd(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int rc = sqlite3_auto_extension(cube_init);
  int rc = sqlite3_auto_extension((void(*)(void))cube_init);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  return SQLITE_OK;
}

/*
** tclcmd:   sqlite3_cancel_auto_extension_cube
**
** Unregister the "cube" extension.
*/
static int SQLITE_TCLAPI cancelAutoExtCubeObjCmd(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int rc = sqlite3_cancel_auto_extension(cube_init);
  int rc = sqlite3_cancel_auto_extension((void(*)(void))cube_init);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  return SQLITE_OK;
}

/*
** tclcmd:   sqlite3_auto_extension_broken
**
** Register the broken extension to be loaded automatically.
*/
static int SQLITE_TCLAPI autoExtBrokenObjCmd(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int rc = sqlite3_auto_extension(broken_init);
  int rc = sqlite3_auto_extension((void(*)(void))broken_init);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  return SQLITE_OK;
}

/*
** tclcmd:   sqlite3_cancel_auto_extension_broken
**
** Unregister the broken extension.
*/
static int SQLITE_TCLAPI cancelAutoExtBrokenObjCmd(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int rc = sqlite3_cancel_auto_extension(broken_init);
  int rc = sqlite3_cancel_auto_extension((void(*)(void))broken_init);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  return SQLITE_OK;
}

#endif /* SQLITE_OMIT_LOAD_EXTENSION */


Changes to src/test_func.c.
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
21
22
23
24
25
26
27

28
29
30
31
32
33
34







-







#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "sqliteInt.h"
#include "vdbeInt.h"


/*
** Allocate nByte bytes of space using sqlite3_malloc(). If the
** allocation fails, call sqlite3_result_error_nomem() to notify
** the database handle that malloc() has failed.
*/
static void *testContextMalloc(sqlite3_context *context, int nByte){
  char *z = sqlite3_malloc(nByte);
700
701
702
703
704
705
706
707

708
709

710
711
712
713
714
715
716
699
700
701
702
703
704
705

706
707

708
709
710
711
712
713
714
715







-
+

-
+







static int SQLITE_TCLAPI autoinstall_test_funcs(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  extern int Md5_Register(sqlite3 *, char **, const sqlite3_api_routines *);
  int rc = sqlite3_auto_extension(registerTestFunctions);
  int rc = sqlite3_auto_extension((void(*)(void))registerTestFunctions);
  if( rc==SQLITE_OK ){
    rc = sqlite3_auto_extension(Md5_Register);
    rc = sqlite3_auto_extension((void(*)(void))Md5_Register);
  }
  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  return TCL_OK;
}

/*
** A bogus step function and finalizer function.
786
787
788
789
790
791
792

793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813


814
815
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811


812
813
814
815







+



















-
-
+
+


  return TCL_OK;

abuse_err:
  Tcl_AppendResult(interp, "sqlite3_create_function abused test failed", 
                   (char*)0);
  return TCL_ERROR;
}


/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest_func_Init(Tcl_Interp *interp){
  static struct {
     char *zName;
     Tcl_ObjCmdProc *xProc;
  } aObjCmd[] = {
     { "autoinstall_test_functions",    autoinstall_test_funcs },
     { "abuse_create_function",         abuse_create_function  },
  };
  int i;
  extern int Md5_Register(sqlite3 *, char **, const sqlite3_api_routines *);

  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
  }
  sqlite3_initialize();
  sqlite3_auto_extension(registerTestFunctions);
  sqlite3_auto_extension(Md5_Register);
  sqlite3_auto_extension((void(*)(void))registerTestFunctions);
  sqlite3_auto_extension((void(*)(void))Md5_Register);
  return TCL_OK;
}
Changes to src/test_multiplex.c.
1193
1194
1195
1196
1197
1198
1199
1200

1201
1202
1203
1204
1205
1206
1207
1193
1194
1195
1196
1197
1198
1199

1200
1201
1202
1203
1204
1205
1206
1207







-
+







  gMultiplex.sIoMethodsV2.iVersion = 2;
  gMultiplex.sIoMethodsV2.xShmMap = multiplexShmMap;
  gMultiplex.sIoMethodsV2.xShmLock = multiplexShmLock;
  gMultiplex.sIoMethodsV2.xShmBarrier = multiplexShmBarrier;
  gMultiplex.sIoMethodsV2.xShmUnmap = multiplexShmUnmap;
  sqlite3_vfs_register(&gMultiplex.sThisVfs, makeDefault);

  sqlite3_auto_extension(multiplexFuncInit);
  sqlite3_auto_extension((void(*)(void))multiplexFuncInit);

  return SQLITE_OK;
}

/*
** CAPI: Shutdown the multiplex system - sqlite3_multiplex_shutdown()
**
Changes to src/test_thread.c.
276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
276
277
278
279
280
281
282

283
284
285
286
287
288
289
290







-
+







  Tcl_Obj *CONST objv[]
){
  int sqlite3TestMakePointerStr(Tcl_Interp *interp, char *zPtr, void *p);

  const char *zFilename;
  sqlite3 *db;
  char zBuf[100];
  extern int Md5_Register(sqlite3 *, char **, const sqlite3_api_routines *);
  extern int Md5_Register(sqlite3*,char**,const sqlite3_api_routines*);

  UNUSED_PARAMETER(clientData);
  UNUSED_PARAMETER(objc);

  zFilename = Tcl_GetString(objv[2]);
  sqlite3_open(zFilename, &db);
#ifdef SQLITE_HAS_CODEC