SQLite

Check-in [ef6936e50a]
Login

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

Overview
Comment:Initialize the global built-in function table at start-time instead of at compile-time. This is less prone to malfunction when compile-time parameters very. (CVS 5583)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ef6936e50adb9ebea39c890167403fff01bbb5ed
User & Date: drh 2008-08-21 18:49:28.000
Context
2008-08-21
19:28
Remove references to OP_MoveTo in comments of vdbe.c - that opcode no longer exists. Ticket #3327. (CVS 5584) (check-in: 30077ece45 user: drh tags: trunk)
18:49
Initialize the global built-in function table at start-time instead of at compile-time. This is less prone to malfunction when compile-time parameters very. (CVS 5583) (check-in: ef6936e50a user: drh tags: trunk)
15:54
Fix soft-heap-limit related test suite failures. (CVS 5582) (check-in: 2091d9a526 user: danielk1977 tags: trunk)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to Makefile.in.
153
154
155
156
157
158
159
160

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

160
161
162
163
164
165
166
167







-
+







# You should not have to change anything below this line
###############################################################################

# Object files for the SQLite library (non-amalgamation).
#
OBJS0 = alter.lo analyze.lo attach.lo auth.lo bitvec.lo btmutex.lo \
        btree.lo build.lo callback.lo complete.lo date.lo \
        delete.lo expr.lo fault.lo func2.lo global.lo \
        delete.lo expr.lo fault.lo func.lo global.lo \
        hash.lo journal.lo insert.lo loadext.lo \
        main.lo malloc.lo mem1.lo mem2.lo mem3.lo mem4.lo mem5.lo mem6.lo \
        mutex.lo mutex_os2.lo mutex_unix.lo mutex_w32.lo \
        opcodes.lo os.lo os_unix.lo os_win.lo os_os2.lo \
        pager.lo parse.lo pcache.lo pragma.lo prepare.lo printf.lo random.lo \
        resolve.lo select.lo status.lo \
        table.lo tokenize.lo trigger.lo update.lo \
194
195
196
197
198
199
200

201
202
203
204
205
206
207
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208







+







  $(TOP)/src/build.c \
  $(TOP)/src/callback.c \
  $(TOP)/src/complete.c \
  $(TOP)/src/date.c \
  $(TOP)/src/delete.c \
  $(TOP)/src/expr.c \
  $(TOP)/src/fault.c \
  $(TOP)/src/func.c \
  $(TOP)/src/global.c \
  $(TOP)/src/hash.c \
  $(TOP)/src/hash.h \
  $(TOP)/src/hwtime.h \
  $(TOP)/src/insert.c \
  $(TOP)/src/journal.c \
  $(TOP)/src/legacy.c \
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
262
263
264
265
266
267
268

269
270
271
272
273
274
275







-







  $(TOP)/src/vtab.c \
  $(TOP)/src/walker.c \
  $(TOP)/src/where.c

# Generated source code files
#
SRC += \
  func2.c \
  keywordhash.h \
  opcodes.c \
  opcodes.h \
  parse.c \
  parse.h \
  config.h \
  sqlite3.h
517
518
519
520
521
522
523
524
525


526
527
528
529
530
531
532
517
518
519
520
521
522
523


524
525
526
527
528
529
530
531
532







-
-
+
+








expr.lo:	$(TOP)/src/expr.c $(HDR)
	$(LTCOMPILE) -c $(TOP)/src/expr.c

fault.lo:	$(TOP)/src/fault.c $(HDR)
	$(LTCOMPILE) -c $(TOP)/src/fault.c

func2.lo:	func2.c $(HDR)
	$(LTCOMPILE) -c func2.c
func.lo:	$(TOP)/src/func.c $(HDR)
	$(LTCOMPILE) -c $(TOP)/src/func.c

global.lo:	$(TOP)/src/global.c $(HDR)
	$(LTCOMPILE) -c $(TOP)/src/global.c

hash.lo:	$(TOP)/src/hash.c $(HDR)
	$(LTCOMPILE) -c $(TOP)/src/hash.c

612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
612
613
614
615
616
617
618





619
620
621
622
623
624
625







-
-
-
-
-








parse.c:	$(TOP)/src/parse.y lemon$(BEXE) $(TOP)/addopcodes.awk
	cp $(TOP)/src/parse.y .
	./lemon$(BEXE) $(OPTS) $(OPT_FEATURE_FLAGS) parse.y
	mv parse.h parse.h.temp
	$(NAWK) -f $(TOP)/addopcodes.awk parse.h.temp >parse.h

func2.c: $(TOP)/src/func.c $(HDR)
	$(BCC) -o mkfunction$(BEXE) $(OPTS) $(OPT_FEATURE_FLAGS) $(TOP)/tool/mkfunction.c -I$(TOP)/src -I.
	cat $(TOP)/src/func.c > func2.c
	./mkfunction$(BEXE) >> func2.c

pragma.lo:	$(TOP)/src/pragma.c $(HDR)
	$(LTCOMPILE) -c $(TOP)/src/pragma.c

prepare.lo:	$(TOP)/src/prepare.c $(HDR)
	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/prepare.c

printf.lo:	$(TOP)/src/printf.c $(HDR)
Changes to main.mk.
47
48
49
50
51
52
53
54

55
56
57
58
59
60
61
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61







-
+







TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP) -I$(TOP)/ext/rtree

# Object files for the SQLite library.
#
LIBOBJ+= alter.o analyze.o attach.o auth.o \
         bitvec.o btmutex.o btree.o build.o \
         callback.o complete.o date.o delete.o \
         expr.o fault.o func2.o global.o hash.o \
         expr.o fault.o func.o global.o hash.o \
         icu.o insert.o journal.o legacy.o loadext.o \
         main.o malloc.o mem1.o mem2.o mem3.o mem4.o mem5.o mem6.o \
         mutex.o mutex_os2.o mutex_unix.o mutex_w32.o \
         opcodes.o os.o os_os2.o os_unix.o os_win.o \
         pager.o parse.o pcache.o pragma.o prepare.o printf.o \
         random.o resolve.o rtree.o select.o status.o \
         table.o tokenize.o trigger.o \
79
80
81
82
83
84
85

86
87
88
89
90
91
92
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93







+







  $(TOP)/src/build.c \
  $(TOP)/src/callback.c \
  $(TOP)/src/complete.c \
  $(TOP)/src/date.c \
  $(TOP)/src/delete.c \
  $(TOP)/src/expr.c \
  $(TOP)/src/fault.c \
  $(TOP)/src/func.c \
  $(TOP)/src/global.c \
  $(TOP)/src/hash.c \
  $(TOP)/src/hash.h \
  $(TOP)/src/hwtime.h \
  $(TOP)/src/insert.c \
  $(TOP)/src/journal.c \
  $(TOP)/src/legacy.c \
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
139
140
141
142
143
144
145

146
147
148
149
150
151
152







-







  $(TOP)/src/vdbe.c \
  $(TOP)/src/vdbe.h \
  $(TOP)/src/vdbeapi.c \
  $(TOP)/src/vdbeaux.c \
  $(TOP)/src/vdbeblob.c \
  $(TOP)/src/vdbefifo.c \
  $(TOP)/src/vdbemem.c \
  $(TOP)/src/pcache.c \
  $(TOP)/src/vdbeInt.h \
  $(TOP)/src/vtab.c \
  $(TOP)/src/walker.c \
  $(TOP)/src/where.c

# Source code for extensions
#
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
189
190
191
192
193
194
195

196
197
198
199
200
201
202







-







#
SRC += \
  keywordhash.h \
  opcodes.c \
  opcodes.h \
  parse.c \
  parse.h \
  func2.c \
  sqlite3.h


# Source code to the test files.
#
TESTSRC = \
  $(TOP)/src/test1.c \
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
226
227
228
229
230
231
232

233
234
235
236
237
238
239
240







-
+







  $(TOP)/src/test_thread.c \

#TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c
#TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c

TESTSRC2 = \
  $(TOP)/src/attach.c $(TOP)/src/btree.c $(TOP)/src/build.c $(TOP)/src/date.c  \
  $(TOP)/src/expr.c func2.c $(TOP)/src/insert.c $(TOP)/src/os.c      \
  $(TOP)/src/expr.c $(TOP)/src/func.c $(TOP)/src/insert.c $(TOP)/src/os.c      \
  $(TOP)/src/os_os2.c $(TOP)/src/os_unix.c $(TOP)/src/os_win.c                 \
  $(TOP)/src/pager.c $(TOP)/src/pragma.c $(TOP)/src/prepare.c                  \
  $(TOP)/src/printf.c $(TOP)/src/random.c $(TOP)/src/pcache.c                  \
  $(TOP)/src/select.c $(TOP)/src/tokenize.c                                    \
  $(TOP)/src/utf.c $(TOP)/src/util.c $(TOP)/src/vdbeapi.c $(TOP)/src/vdbeaux.c \
  $(TOP)/src/vdbe.c $(TOP)/src/vdbemem.c $(TOP)/src/where.c parse.c

345
346
347
348
349
350
351
352
353


354
355
356
357
358
359
360
361
362
363
364
344
345
346
347
348
349
350


351
352




353
354
355
356
357
358
359







-
-
+
+
-
-
-
-








# Rules to build opcodes.c and opcodes.h
#
opcodes.c:	opcodes.h $(TOP)/mkopcodec.awk
	sort -n -b -k 3 opcodes.h | $(NAWK) -f $(TOP)/mkopcodec.awk >opcodes.c

opcodes.h:	parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
	cat parse.h $(TOP)/src/vdbe.c |$(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h

	cat parse.h $(TOP)/src/vdbe.c | \
		$(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
func2.c: $(TOP)/src/func.c $(HDR)
	$(BCC) -o mkfunction $(OPTS) $(TOP)/tool/mkfunction.c -I$(TOP)/src -I.
	cat $(TOP)/src/func.c > func2.c
	./mkfunction >> func2.c

# Rules to build parse.c and parse.h - the outputs of lemon.
#
parse.h:	parse.c

parse.c:	$(TOP)/src/parse.y lemon $(TOP)/addopcodes.awk
	cp $(TOP)/src/parse.y .
493
494
495
496
497
498
499
500

488
489
490
491
492
493
494

495







-
+
clean:	
	rm -f *.o sqlite3 libsqlite3.a sqlite3.h opcodes.*
	rm -f lemon lempar.c parse.* sqlite*.tar.gz mkkeywordhash keywordhash.h
	rm -f $(PUBLISH)
	rm -f *.da *.bb *.bbg gmon.out
	rm -rf tsrc target_source
	rm -f testloadext.dll libtestloadext.so
	rm -f sqlite3.c fts?amal.c tclsqlite3.c func2.c
	rm -f sqlite3.c fts?amal.c tclsqlite3.c
Changes to src/callback.c.
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23







-
+







**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains functions used to access the internal hash tables
** of user defined functions and collation sequences.
**
** $Id: callback.c,v 1.27 2008/08/20 14:49:24 danielk1977 Exp $
** $Id: callback.c,v 1.28 2008/08/21 18:49:28 drh Exp $
*/

#include "sqliteInt.h"

/*
** Invoke the 'collation needed' callback to request a collation sequence
** in the database text encoding of name zName, length nName.
256
257
258
259
260
261
262











































263
264
265
266
267
268
269
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312







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







             (enc==SQLITE_UTF16BE && p->iPrefEnc==SQLITE_UTF16LE) ){
      match += 1;
    }
  }
  return match;
}

/*
** Search a FuncDefHash for a function with the given name.  Return
** a pointer to the matching FuncDef if found, or 0 if there is no match.
*/
static FuncDef *functionSearch(
  FuncDefHash *pHash,  /* Hash table to search */
  int h,               /* Hash of the name */
  const char *zFunc,   /* Name of function */
  int nFunc            /* Number of bytes in zFunc */
){
  FuncDef *p;
  for(p=pHash->a[h]; p; p=p->pHash){
    if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 && p->zName[nFunc]==0 ){
      return p;
    }
  }
  return 0;
}

/*
** Insert a new FuncDef into a FuncDefHash hash table.
*/
void sqlite3FuncDefInsert(
  FuncDefHash *pHash,  /* The hash table into which to insert */
  FuncDef *pDef        /* The function definition to insert */
){
  FuncDef *pOther;
  int nName = strlen(pDef->zName);
  u8 c1 = (u8)pDef->zName[0];
  int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash->a);
  pOther = functionSearch(pHash, h, pDef->zName, nName);
  if( pOther ){
    pDef->pNext = pOther->pNext;
    pOther->pNext = pDef;
  }else{
    pDef->pNext = 0;
    pDef->pHash = pHash->a[h];
    pHash->a[h] = pDef;
  }
}
  
  

/*
** Locate a user function given a name, a number of arguments and a flag
** indicating whether the function prefers UTF-16 over UTF-8.  Return a
** pointer to the FuncDef structure that defines that function, or return
** NULL if the function does not exist.
**
** If the createFlag argument is true, then a new (blank) FuncDef
285
286
287
288
289
290
291
292
293
294


295
296
297
298

299
300
301
302
303





304
305

306

307
308
309
310
311
312
313
314
315
316


317
318
319
320
321
322




323

324
325
326
327
328
329
330
331

332
333
334
335
336
337
338
339

340
341
342
343
344
345
346
347
348
349
350
328
329
330
331
332
333
334

335

336
337
338
339
340
341
342
343




344
345
346
347
348
349

350
351
352
353
354
355
356
357
358
359



360
361






362
363
364
365
366
367
368
369
370
371
372
373
374

375
376
377
378

379
380
381

382




383
384
385
386
387
388
389







-

-
+
+




+

-
-
-
-
+
+
+
+
+

-
+

+







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

+







-
+



-



-
+
-
-
-
-







  const char *zName, /* Name of the function.  Not null-terminated */
  int nName,         /* Number of characters in the name */
  int nArg,          /* Number of arguments.  -1 means any number */
  u8 enc,            /* Preferred text encoding */
  int createFlag     /* Create new entry if true and does not otherwise exist */
){
  FuncDef *p;         /* Iterator variable */
  FuncDef *pFirst;    /* First function with this name */
  FuncDef *pBest = 0; /* Best match found so far */
  int bestmatch = 0;  
  int bestScore = 0;  /* Score of best match */
  int h;              /* Hash value */


  assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
  if( nArg<-1 ) nArg = -1;
  h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a);

  pFirst = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, nName);
  for(p=pFirst; p; p=p->pNext){
    int match = matchQuality(p, nArg, enc);
    if( match>bestmatch ){

  p = functionSearch(&db->aFunc, h, zName, nName);
  while( p ){
    int score = matchQuality(p, nArg, enc);
    if( score>bestScore ){
      pBest = p;
      bestmatch = match;
      bestScore = score;
    }
    p = p->pNext;
  }

  /* If the createFlag parameter is false and no match was found amongst
  ** the custom functions stored in sqlite3.aFunc, try to find a built-in
  ** function to use.
  */ 
  if( !createFlag && !pBest ){
    FuncDef *aFunc;
    int nFunc;
    int i;
    p = functionSearch(&sqlite3FuncBuiltins, h, zName, nName);
    while( p ){
    nFunc = sqlite3GetBuiltinFunction(zName, nName, &aFunc);
    for(i=0; i<nFunc; i++){
      int match = matchQuality(&aFunc[i], nArg, enc);
      if( match>bestmatch ){
        pBest = &aFunc[i];
        bestmatch = match;
      int score = matchQuality(p, nArg, enc);
      if( score>bestScore ){
        pBest = p;
        bestScore = score;
      }
      p = p->pNext;
    }
  }

  /* If the createFlag parameter is true, and the seach did not reveal an
  ** exact match for the name, number of arguments and encoding, then add a
  ** new entry to the hash table and return it.
  */
  if( createFlag && bestmatch<6 && 
  if( createFlag && bestScore<6 && 
      (pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
    pBest->zName = (char *)&pBest[1];
    pBest->nArg = nArg;
    pBest->pNext = pFirst;
    pBest->iPrefEnc = enc;
    memcpy(pBest->zName, zName, nName);
    pBest->zName[nName] = 0;
    if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){
    sqlite3FuncDefInsert(&db->aFunc, pBest);
      db->mallocFailed = 1;
      sqlite3DbFree(db, pBest);
      return 0;
    }
  }

  if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){
    return pBest;
  }
  return 0;
}
Changes to src/func.c.
12
13
14
15
16
17
18
19

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

19
20
21
22
23
24
25
26







-
+







** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.197 2008/08/20 14:49:24 danielk1977 Exp $
** $Id: func.c,v 1.198 2008/08/21 18:49:28 drh Exp $
*/

#ifndef CREATE_BUILTIN_HASHTABLE

#include "sqliteInt.h"
#include <ctype.h>
#include <stdlib.h>
1418
1419
1420
1421
1422
1423
1424










1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434







+
+
+
+
+
+
+
+
+
+
  LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
#else
  LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
  LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
#endif
};

/*
** Build up the global built-in function table at initialization
** time.
*/
void sqlite3RegisterGlobalFunctions(void){
  int i;
  for(i=0; i<ArraySize(aBuiltinFunc); i++){
    sqlite3FuncDefInsert(&sqlite3FuncBuiltins, &aBuiltinFunc[i]);
  }
}
Changes to src/global.c.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains definitions of global variables and contants.
**
** $Id: global.c,v 1.4 2008/07/28 19:34:53 drh Exp $
** $Id: global.c,v 1.5 2008/08/21 18:49:28 drh Exp $
*/
#include "sqliteInt.h"


/* An array to map all upper-case characters into their corresponding
** lower-case character. 
**
71
72
73
74
75
76
77








71
72
73
74
75
76
77
78
79
80
81
82
83
84
85







+
+
+
+
+
+
+
+
   1,                /* bCoreMutex */
   1,                /* bFullMutex */
   0x7ffffffe,       /* mxStrlen */
   100,              /* szLookaside */
   500,              /* nLookaside */
   /* Other fields all default to zero */
};


/*
** Hash table for global functions - functions common to all
** database connections.  After initialization, this table is
** read-only.
*/
FuncDefHash sqlite3FuncBuiltins;
Changes to src/main.c.
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24







-
+







**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.491 2008/08/20 16:35:10 drh Exp $
** $Id: main.c,v 1.492 2008/08/21 18:49:28 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

#ifdef SQLITE_ENABLE_FTS3
# include "fts3.h"
#endif
143
144
145
146
147
148
149


150
151
152
153
154
155
156
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158







+
+







  ** sqlite3_initialize().  The recursive calls normally come through
  ** sqlite3_os_init() when it invokes sqlite3_vfs_register(), but other
  ** recursive calls might also be possible.
  */
  sqlite3_mutex_enter(sqlite3Config.pInitMutex);
  if( sqlite3Config.isInit==0 && inProgress==0 ){
    inProgress = 1;
    memset(&sqlite3FuncBuiltins, 0, sizeof(sqlite3FuncBuiltins));
    sqlite3RegisterGlobalFunctions();
    rc = sqlite3_os_init();
    if( rc==SQLITE_OK ){
      rc = sqlite3PcacheInitialize();
      sqlite3PCacheBufferSetup(sqlite3Config.pPage, sqlite3Config.szPage, 
          sqlite3Config.nPage);
    }
    inProgress = 0;
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576











577
578
579
580
581
582
583
564
565
566
567
568
569
570








571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588







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







        pDb->pSchema = 0;
      }
    }
  }
  sqlite3ResetInternalSchema(db, 0);
  assert( db->nDb<=2 );
  assert( db->aDb==db->aDbStatic );
  for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
    FuncDef *pFunc, *pNext;
    for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){
      pNext = pFunc->pNext;
      sqlite3DbFree(db, pFunc);
    }
  }

  for(j=0; j<ArraySize(db->aFunc.a); j++){
    FuncDef *pNext, *pHash, *p;
    for(p=db->aFunc.a[j]; p; p=pHash){
      pHash = p->pHash;
      while( p ){
        pNext = p->pNext;
        sqlite3DbFree(db, p);
        p = pNext;
      }
    }
  }
  for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
    CollSeq *pColl = (CollSeq *)sqliteHashData(i);
    /* Invoke any destructors registered for collation sequence user data. */
    for(j=0; j<3; j++){
      if( pColl[j].xDel ){
        pColl[j].xDel(pColl[j].pUser);
      }
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
597
598
599
600
601
602
603

604
605
606
607
608
609
610







-







      pMod->xDestroy(pMod->pAux);
    }
    sqlite3DbFree(db, pMod);
  }
  sqlite3HashClear(&db->aModule);
#endif

  sqlite3HashClear(&db->aFunc);
  sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */
  if( db->pErr ){
    sqlite3ValueFree(db->pErr);
  }
  sqlite3CloseExtensions(db);

  db->magic = SQLITE_MAGIC_ERROR;
1367
1368
1369
1370
1371
1372
1373



1374
1375
1376
1377
1378
1379
1380
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387







+
+
+







#endif
#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1
# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1
#endif
#if SQLITE_MAX_VARIABLE_NUMBER<1
# error SQLITE_MAX_VARIABLE_NUMBER must be at least 1
#endif
#if SQLITE_MAX_COLUMN>32767
# error SQLITE_MAX_COLUMN must not exceed 32767
#endif


/*
** Change the value of a limit.  Report the old value.
** If an invalid limit index is supplied, report -1.
** Make no changes but still report the old value if the
** new limit is negative.
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1469
1470
1471
1472
1473
1474
1475

1476
1477
1478
1479
1480
1481
1482







-







#if SQLITE_DEFAULT_FILE_FORMAT<4
                 | SQLITE_LegacyFileFmt
#endif
#ifdef SQLITE_ENABLE_LOAD_EXTENSION
                 | SQLITE_LoadExtension
#endif
      ;
  sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0);
  sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0);
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3HashInit(&db->aModule, SQLITE_HASH_STRING, 0);
#endif

  db->pVfs = sqlite3_vfs_find(zVfs);
  if( !db->pVfs ){
Changes to src/sqliteInt.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21













-
+







/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.757 2008/08/20 16:35:10 drh Exp $
** @(#) $Id: sqliteInt.h,v 1.758 2008/08/21 18:49:28 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** Include the configuration header output by 'configure' if we're using the
** autoconf-based build
362
363
364
365
366
367
368
369

370
371
372
373
374
375
376
362
363
364
365
366
367
368

369
370
371
372
373
374
375
376







-
+







#endif
typedef sqlite_int64 i64;          /* 8-byte signed integer */
typedef sqlite_uint64 u64;         /* 8-byte unsigned integer */
typedef UINT32_TYPE u32;           /* 4-byte unsigned integer */
typedef UINT16_TYPE u16;           /* 2-byte unsigned integer */
typedef INT16_TYPE i16;            /* 2-byte signed integer */
typedef UINT8_TYPE u8;             /* 1-byte unsigned integer */
typedef UINT8_TYPE i8;             /* 1-byte signed integer */
typedef INT8_TYPE i8;              /* 1-byte signed integer */

/*
** Macros to determine whether the machine is big or little endian,
** evaluated at runtime.
*/
#ifdef SQLITE_AMALGAMATION
const int sqlite3one;
451
452
453
454
455
456
457

458
459
460
461
462
463
464
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465







+







typedef struct Column Column;
typedef struct Db Db;
typedef struct Schema Schema;
typedef struct Expr Expr;
typedef struct ExprList ExprList;
typedef struct FKey FKey;
typedef struct FuncDef FuncDef;
typedef struct FuncDefHash FuncDefHash;
typedef struct IdList IdList;
typedef struct Index Index;
typedef struct KeyClass KeyClass;
typedef struct KeyInfo KeyInfo;
typedef struct Lookaside Lookaside;
typedef struct LookasideSlot LookasideSlot;
typedef struct Module Module;
588
589
590
591
592
593
594










595
596
597
598
599
600
601
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612







+
+
+
+
+
+
+
+
+
+







  void *pStart;           /* First byte of available memory space */
  void *pEnd;             /* First byte past end of available space */
};
struct LookasideSlot {
  LookasideSlot *pNext;    /* Next buffer in the list of free buffers */
};

/*
** A hash table for function definitions.
**
** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
** Collisions are on the FuncDef.pHash chain.
*/
struct FuncDefHash {
  FuncDef *a[23];       /* Hash table for functions */
};

/*
** Each database is an instance of the following structure.
**
** The sqlite.lastRowid records the last insert rowid generated by an
** insert statement.  Inserts on views do not affect its value.  Each
** trigger has its own context, so that lastRowid can be updated inside
** triggers as usual.  The previous value will be restored once the trigger
684
685
686
687
688
689
690
691

692
693
694
695
696
697
698
695
696
697
698
699
700
701

702
703
704
705
706
707
708
709







-
+







#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
  Hash aModule;                 /* populated by sqlite3_create_module() */
  Table *pVTab;                 /* vtab with active Connect/Create method */
  sqlite3_vtab **aVTrans;       /* Virtual tables with open transactions */
  int nVTrans;                  /* Allocated size of aVTrans */
#endif
  Hash aFunc;                   /* All functions that can be in SQL exprs */
  FuncDefHash aFunc;            /* Hash table of connection functions */
  Hash aCollSeq;                /* All collating sequences */
  BusyHandler busyHandler;      /* Busy callback */
  int busyTimeout;              /* Busy handler timeout, in msec */
  Db aDbStatic[2];              /* Static space for the 2 default backends */
#ifdef SQLITE_SSE
  sqlite3_stmt *pFetch;         /* Used by SSE to fetch stored statements */
#endif
749
750
751
752
753
754
755
756

757
758
759
760
761
762
763
764
765

766
767
768
769
770
771
772
773



774
775
776
777
778
779
780
760
761
762
763
764
765
766

767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782



783
784
785
786
787
788
789
790
791
792







-
+









+





-
-
-
+
+
+







/*
** Each SQL function is defined by an instance of the following
** structure.  A pointer to this structure is stored in the sqlite.aFunc
** hash table.  When multiple functions have the same name, the hash table
** points to a linked list of these structures.
*/
struct FuncDef {
  i16 nArg;            /* Number of arguments.  -1 means unlimited */
  i8 nArg;             /* Number of arguments.  -1 means unlimited */
  u8 iPrefEnc;         /* Preferred text encoding (SQLITE_UTF8, 16LE, 16BE) */
  u8 needCollSeq;      /* True if sqlite3GetFuncCollSeq() might be called */
  u8 flags;            /* Some combination of SQLITE_FUNC_* */
  void *pUserData;     /* User data parameter */
  FuncDef *pNext;      /* Next function with same name */
  void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */
  void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */
  void (*xFinalize)(sqlite3_context*);                /* Aggregate finializer */
  char *zName;         /* SQL name of the function. */
  FuncDef *pHash;      /* Next with a different name but the same hash */
};

/*
** Possible values for FuncDef.flags
*/
#define SQLITE_FUNC_LIKE   0x01  /* Candidate for the LIKE optimization */
#define SQLITE_FUNC_CASE   0x02  /* Case-sensitive LIKE-type function */
#define SQLITE_FUNC_EPHEM  0x04  /* Ephermeral.  Delete with VDBE */
#define SQLITE_FUNC_LIKE     0x01  /* Candidate for the LIKE optimization */
#define SQLITE_FUNC_CASE     0x02  /* Case-sensitive LIKE-type function */
#define SQLITE_FUNC_EPHEM    0x04  /* Ephermeral.  Delete with VDBE */

/*
** Each SQLite module (virtual table definition) is defined by an
** instance of the following structure, stored in the sqlite3.aModule
** hash table.
*/
struct Module {
2123
2124
2125
2126
2127
2128
2129

2130
2131
2132

2133
2134
2135
2136
2137
2138
2139
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153







+



+







void sqlite3BeginWriteOperation(Parse*, int, int);
Expr *sqlite3ExprDup(sqlite3*,Expr*);
void sqlite3TokenCopy(sqlite3*,Token*, Token*);
ExprList *sqlite3ExprListDup(sqlite3*,ExprList*);
SrcList *sqlite3SrcListDup(sqlite3*,SrcList*);
IdList *sqlite3IdListDup(sqlite3*,IdList*);
Select *sqlite3SelectDup(sqlite3*,Select*);
void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,int);
void sqlite3RegisterBuiltinFunctions(sqlite3*);
void sqlite3RegisterDateTimeFunctions(sqlite3*);
void sqlite3RegisterGlobalFunctions(void);
int sqlite3GetBuiltinFunction(const char *, int, FuncDef **);
#ifdef SQLITE_DEBUG
  int sqlite3SafetyOn(sqlite3*);
  int sqlite3SafetyOff(sqlite3*);
#else
# define sqlite3SafetyOn(A) 0
# define sqlite3SafetyOff(A) 0
2264
2265
2266
2267
2268
2269
2270

2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292







+







sqlite3_value *sqlite3ValueNew(sqlite3 *);
char *sqlite3Utf16to8(sqlite3 *, const void*, int);
int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
#ifndef SQLITE_AMALGAMATION
extern const unsigned char sqlite3UpperToLower[];
extern struct Sqlite3Config sqlite3Config;
extern FuncDefHash sqlite3FuncBuiltins;
#endif
void sqlite3RootPageMoved(Db*, int, int);
void sqlite3Reindex(Parse*, Token*, Token*);
void sqlite3AlterFunctions(sqlite3*);
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
Deleted tool/mkfunction.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186


























































































































































































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

/*
** This file contains a standalone program used to generate C code that
** implements a static hash table to store the definitions of built-in
** SQL functions in SQLite. 
*/

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

/*
** The SQLite source file "func.c" is included below.
**
** By defining the 4 macros and typedef below before including "func.c",
** most of the code is excluded. What is left is an array of constant
** strings, aBuiltinFunc[], containing the names of SQLite's built-in 
** SQL functions. i.e.:
**
**   const char aBuiltinFunc[] = { "like", "glob", "min", "max" ... };
**
** The data from aBuiltinFunc[] is used by this program to create the
** static hash table.
*/
#define CREATE_BUILTIN_HASHTABLE 1
#define FUNCTION(zName,w,x,y,z)    #zName
#define AGGREGATE(zName,v,w,x,y,z) #zName
#define LIKEFUNC(zName,x,y,z)      #zName
#define FuncDef const char *

#include "func.c"

/* The number of buckets in the static hash table. */
#define HASHSIZE 127

typedef unsigned char u8;

/* An array to map all upper-case characters into their corresponding
** lower-case character. 
*/
static const u8 sqlite3UpperToLower[] = {
      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
     18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
     36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
     54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 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, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
    108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
    126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
    144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
    162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
    180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
    198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
    216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
    234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
    252,253,254,255
};
#define UpperToLower sqlite3UpperToLower

int sqlite3StrICmp(const char *zLeft, const char *zRight){
  register unsigned char *a, *b;
  a = (unsigned char *)zLeft;
  b = (unsigned char *)zRight;
  while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
  return UpperToLower[*a] - UpperToLower[*b];
}

static int hashstring(const char *zName){
  int ii;
  unsigned int iKey = 0;
  for(ii=0; zName[ii]; ii++){
    iKey = (iKey<<3) + (u8)sqlite3UpperToLower[(u8)zName[ii]];
  }
  iKey = iKey%HASHSIZE;
  return iKey;
}

static void printarray(const char *zName, u8 *aArray, int nArray){
  int ii;
  printf("  static u8 %s[%d] = {", zName, nArray);
  for(ii=0; ii<nArray; ii++){
    if( (ii%16)==0 ){
      printf("\n    ");
    }
    printf("%2d, ", aArray[ii]);
  }
  printf("\n  };\n");
}


int main(int argc, char **argv){
  int nFunc;              /* Number of entries in the aBuiltinFunc array */

  u8 anFunc[256];
  u8 aHash[HASHSIZE];
  u8 aNext[256];
  int ii;
  int iHead;

  nFunc = (sizeof(aBuiltinFunc)/sizeof(const char *));
  assert(nFunc<256);

  memset(aHash, (unsigned char)nFunc, sizeof(aHash));
  memset(aNext, (unsigned char)nFunc, sizeof(aNext));
  memset(anFunc, 0, sizeof(anFunc));

  iHead = -1;
  for(ii=0; ii<nFunc; ii++){
    int iHash;

    if( iHead>=0 && 0==sqlite3StrICmp(aBuiltinFunc[ii], aBuiltinFunc[iHead]) ){
      anFunc[iHead]++;
      continue;
    }else{
      /* The routine generated by this program assumes that if there are
      ** two or more entries in the aBuiltinFunc[] array with the same
      ** name (i.e. two versions of the "max" function), then they must
      ** be stored in adjacent slots. The following block detects the
      ** problem if this is not the case.
      */
      int jj;
      for(jj=0; jj<ii; jj++){
        if( 0==sqlite3StrICmp(aBuiltinFunc[ii], aBuiltinFunc[jj]) ){
          fprintf(stderr, "Error in func.c\n");
          return -1;
        }
      }

      iHead = ii;
      anFunc[iHead] = 1;
    }

    iHash = hashstring(aBuiltinFunc[ii]);
    if( aHash[iHash]!=nFunc ){
      int iNext = aHash[iHash];
      while( aNext[iNext]!=nFunc ){
        iNext = aNext[iNext];
      }
      aNext[iNext] = ii;
    }else{
      aHash[iHash] = ii;
    }
  }

  printf(
  "/******* Automatically Generated code - do not edit **************/\n"
  "int sqlite3GetBuiltinFunction(\n"
  "  const char *zName,   \n"
  "  int nName, \n"
  "  FuncDef **paFunc\n"
  "){\n"
  );

  printarray("aHash", aHash, HASHSIZE);
  printarray("anFunc", anFunc, nFunc);
  printarray("aNext", aNext, nFunc);
  printf("  FuncDef *pNoFunc = &aBuiltinFunc[%d];\n", nFunc);

  printf(
  "  unsigned int iKey = 0;  /* Hash of case-insensitive string zName. */\n"
  "  int ii;\n"
  "  FuncDef *pFunc;\n"
  "\n"
  );
  printf(
  "  assert( (sizeof(aBuiltinFunc)/sizeof(aBuiltinFunc[0]))==%d );\n", nFunc
  );
  printf(
  "  /* Generate the hash of zName */\n"
  "  for(ii=0; ii<nName; ii++){\n"
  "    iKey = (iKey<<3) + (u8)sqlite3UpperToLower[(u8)zName[ii]];\n"
  "  }\n"
  "  iKey = iKey%%127;\n"
  "\n"
  "  pFunc = &aBuiltinFunc[iKey = aHash[iKey]];\n"
  "  while( pFunc!=pNoFunc && sqlite3StrNICmp(pFunc->zName, zName, nName) ){\n"
  "    pFunc = &aBuiltinFunc[iKey = aNext[iKey]];\n"
  "  }\n"
  "\n"
  "  *paFunc = pFunc;\n"
  "  return anFunc[iKey];\n"
  "}\n"
  );

  return 0;
}
Changes to tool/mksqlite3c.tcl.
252
253
254
255
256
257
258
259

260
261
262
263
264
265
266
252
253
254
255
256
257
258

259
260
261
262
263
264
265
266







-
+







   alter.c
   analyze.c
   attach.c
   auth.c
   build.c
   callback.c
   delete.c
   func2.c
   func.c
   insert.c
   legacy.c
   loadext.c
   pragma.c
   prepare.c
   select.c
   table.c