SQLite

Check-in [1bb8ee8d9f]
Login

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

Overview
Comment::-) (CVS 14)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1bb8ee8d9f1d3c409a11910e7552e4bb5e7f5f87
User & Date: drh 2000-05-30 13:44:19.000
Context
2000-05-30
16:27
:-) (CVS 15) (check-in: 8d66c7355d user: drh tags: trunk)
13:44
:-) (CVS 14) (check-in: 1bb8ee8d9f user: drh tags: trunk)
03:28
:-) (CVS 13) (check-in: 191a7f484e user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/build.c.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines that are called by the parser
** when syntax rules are reduced.
**
** $Id: build.c,v 1.5 2000/05/30 03:12:21 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called after a single SQL statement has been
** parsed and we want to execute the code to implement 
** the statement.  Prior action routines should have already







|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines that are called by the parser
** when syntax rules are reduced.
**
** $Id: build.c,v 1.6 2000/05/30 13:44:19 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called after a single SQL statement has been
** parsed and we want to execute the code to implement 
** the statement.  Prior action routines should have already
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
** Add a new column to the table currently being constructed.
*/
void sqliteAddColumn(Parse *pParse, Token *pName){
  Table *p;
  char **pz;
  if( (p = pParse->pNewTable)==0 ) return;
  if( (p->nCol & 0x7)==0 ){
    p->azCol = sqliteRealloc( p->azCol, (p->nCol+9)*sizeof(p->azCol[0]));
  }
  if( p->azCol==0 ){
    p->nCol = 0;
    return;
  }
  pz = &p->azCol[p->nCol++];
  *pz = 0;







|







239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
** Add a new column to the table currently being constructed.
*/
void sqliteAddColumn(Parse *pParse, Token *pName){
  Table *p;
  char **pz;
  if( (p = pParse->pNewTable)==0 ) return;
  if( (p->nCol & 0x7)==0 ){
    p->azCol = sqliteRealloc( p->azCol, (p->nCol+8)*sizeof(p->azCol[0]));
  }
  if( p->azCol==0 ){
    p->nCol = 0;
    return;
  }
  pz = &p->azCol[p->nCol++];
  *pz = 0;
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
    pList = sqliteIdListAppend(0, &nullId);
    if( pList==0 ) goto exit_create_index;
  }

  /* 
  ** Allocate the index structure. 
  */
  pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 
                        sizeof(int)*pList->nId );
  if( pIndex==0 ){
    sqliteSetString(&pParse->zErrMsg, "out of memory", 0);
    pParse->nErr++;
    goto exit_create_index;
  }
  pIndex->aiField = (int*)&pIndex[1];







|







469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
    pList = sqliteIdListAppend(0, &nullId);
    if( pList==0 ) goto exit_create_index;
  }

  /* 
  ** Allocate the index structure. 
  */
  pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 +
                        sizeof(int)*pList->nId );
  if( pIndex==0 ){
    sqliteSetString(&pParse->zErrMsg, "out of memory", 0);
    pParse->nErr++;
    goto exit_create_index;
  }
  pIndex->aiField = (int*)&pIndex[1];
Changes to src/sqliteInt.h.
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
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.1 2000/05/29 14:26:01 drh Exp $
*/
#include "sqlite.h"
#include "dbbe.h"
#include "vdbe.h"
#include "parse.h"
#include <gdbm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>








/*
** The number of entries in the in-memory hash table holding the
** schema.
*/
#define N_HASH        51








|










>
>
>
>
>
>
>







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
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.2 2000/05/30 13:44:20 drh Exp $
*/
#include "sqlite.h"
#include "dbbe.h"
#include "vdbe.h"
#include "parse.h"
#include <gdbm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

/* #define MEMORY_DEBUG 1 */
#ifdef MEMORY_DEBUG
# define sqliteMalloc(X)    sqliteMalloc_(X,__FILE__,__LINE__)
# define sqliteFree(X)      sqliteFree_(X,__FILE__,__LINE__)
# define sqliteRealloc(X,Y) sqliteRealloc_(X,Y,__FILE__,__LINE__)
#endif

/*
** The number of entries in the in-memory hash table holding the
** schema.
*/
#define N_HASH        51

196
197
198
199
200
201
202





203
204
205

206
207
208
209
210
211
212
** Internal function prototypes
*/
int sqliteStrICmp(const char *, const char *);
int sqliteStrNICmp(const char *, const char *, int);
int sqliteHashNoCase(const char *, int);
int sqliteCompare(const char *, const char *);
int sqliteSortCompare(const char *, const char *);





void *sqliteMalloc(int);
void sqliteFree(void*);
void *sqliteRealloc(void*,int);

int sqliteGetToken(const char*, int *);
void sqliteSetString(char **, const char *, ...);
void sqliteSetNString(char **, ...);
int sqliteRunParser(Parse*, char*, char **);
void sqliteExec(Parse*);
Expr *sqliteExpr(int, Expr*, Expr*, Token*);
Expr *sqliteExprFunction(ExprList*, Token*);







>
>
>
>
>
|
|
|
>







203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
** Internal function prototypes
*/
int sqliteStrICmp(const char *, const char *);
int sqliteStrNICmp(const char *, const char *, int);
int sqliteHashNoCase(const char *, int);
int sqliteCompare(const char *, const char *);
int sqliteSortCompare(const char *, const char *);
#ifdef MEMORY_DEBUG
  void *sqliteMalloc_(int,char*,int);
  void sqliteFree_(void*,char*,int);
  void *sqliteRealloc_(void*,int,char*,int);
#else
  void *sqliteMalloc(int);
  void sqliteFree(void*);
  void *sqliteRealloc(void*,int);
#endif
int sqliteGetToken(const char*, int *);
void sqliteSetString(char **, const char *, ...);
void sqliteSetNString(char **, ...);
int sqliteRunParser(Parse*, char*, char **);
void sqliteExec(Parse*);
Expr *sqliteExpr(int, Expr*, Expr*, Token*);
Expr *sqliteExprFunction(ExprList*, Token*);
Changes to src/tclsqlite.c.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.2 2000/05/29 20:41:51 drh Exp $
*/
#include "sqlite.h"
#include <tcl.h>
#include <stdlib.h>
#include <string.h>

/*







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.3 2000/05/30 13:44:20 drh Exp $
*/
#include "sqlite.h"
#include <tcl.h>
#include <stdlib.h>
#include <string.h>

/*
148
149
150
151
152
153
154

155
156
157
158
159
160
161
    if( argc!=5 && argc!=3 ){
      Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
         " eval SQL ?ARRAY-NAME CODE?", 0);
      return TCL_ERROR;
    }
    if( argc==5 ){
      cbData.interp = interp;

      cbData.zArray = argv[3];
      cbData.zCode = argv[4];
      zErrMsg = 0;
      rc = sqlite_exec(db, argv[2], DbEvalCallback, &cbData, &zErrMsg);
    }else{
      rc = sqlite_exec(db, argv[2], 0, 0, &zErrMsg);
    }







>







148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
    if( argc!=5 && argc!=3 ){
      Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
         " eval SQL ?ARRAY-NAME CODE?", 0);
      return TCL_ERROR;
    }
    if( argc==5 ){
      cbData.interp = interp;
      cbData.once = 1;
      cbData.zArray = argv[3];
      cbData.zCode = argv[4];
      zErrMsg = 0;
      rc = sqlite_exec(db, argv[2], DbEvalCallback, &cbData, &zErrMsg);
    }else{
      rc = sqlite_exec(db, argv[2], 0, 0, &zErrMsg);
    }
Changes to src/tokenize.c.
23
24
25
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.1 2000/05/29 14:26:02 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>


/*
** All the keywords of the SQL language are stored as in a hash
** table composed of instances of the following structure.
*/
typedef struct Keyword Keyword;
struct Keyword {







|



>







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.2 2000/05/30 13:44:20 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <stdlib.h>

/*
** All the keywords of the SQL language are stored as in a hash
** table composed of instances of the following structure.
*/
typedef struct Keyword Keyword;
struct Keyword {
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
  static FILE *trace = 0;
  extern void *sqliteParserAlloc(void*(*)(int));
  extern void sqliteParserFree(void*, void(*)(void*));
  extern int sqliteParser(void*, int, ...);
  extern void sqliteParserTrace(FILE*, char *);

  i = 0;
  pEngine = sqliteParserAlloc(sqliteMalloc);
  if( pEngine==0 ){
    sqliteSetString(pzErrMsg, "out of memory", 0);
    return 1;
  }
  sqliteParserTrace(trace, "parser: ");
  while( nErr==0 && i>=0 && zSql[i]!=0 ){
    int tokenType;







|







284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
  static FILE *trace = 0;
  extern void *sqliteParserAlloc(void*(*)(int));
  extern void sqliteParserFree(void*, void(*)(void*));
  extern int sqliteParser(void*, int, ...);
  extern void sqliteParserTrace(FILE*, char *);

  i = 0;
  pEngine = sqliteParserAlloc((void(*)())malloc);
  if( pEngine==0 ){
    sqliteSetString(pzErrMsg, "out of memory", 0);
    return 1;
  }
  sqliteParserTrace(trace, "parser: ");
  while( nErr==0 && i>=0 && zSql[i]!=0 ){
    int tokenType;
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
          pParse->sErrToken.z, pParse->sErrToken.n,
          "\": ", -1,
          pParse->zErrMsg, -1,
          0);
       nErr++;
    }
  }
  sqliteParserFree(pEngine, sqliteFree);
  if( pParse->zErrMsg ){
    if( pzErrMsg ){
      *pzErrMsg = pParse->zErrMsg;
    }else{
      sqliteFree(pParse->zErrMsg);
    }
    if( !nErr ) nErr++;







|







351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
          pParse->sErrToken.z, pParse->sErrToken.n,
          "\": ", -1,
          pParse->zErrMsg, -1,
          0);
       nErr++;
    }
  }
  sqliteParserFree(pEngine, free);
  if( pParse->zErrMsg ){
    if( pzErrMsg ){
      *pzErrMsg = pParse->zErrMsg;
    }else{
      sqliteFree(pParse->zErrMsg);
    }
    if( !nErr ) nErr++;
Changes to src/util.c.
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
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.4 2000/05/29 23:48:23 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>




























































































/*
** Allocate new memory and set it to zero.  Return NULL if
** no memory is available.
*/
void *sqliteMalloc(int n){
  void *p = malloc(n);
  /* printf("alloc 0x%x size: %d bytes\n", (int)p, n); */
  if( p==0 ) return 0;
  memset(p, 0, n);
  return p;
}

/*
** Free memory previously obtained from sqliteMalloc()
*/
void sqliteFree(void *p){
  if( p ){
    /* printf("free 0x%x\n", (int)p); */
    free(p);
  }
}

/*
** Resize a prior allocation.  If p==0, then this routine
** works just like sqliteMalloc().  If n==0, then this routine
** works just like sqliteFree().
*/
void *sqliteRealloc(void *p, int n){
  if( p==0 ){
    return sqliteMalloc(n);
  }
  if( n==0 ){
    sqliteFree(p);
    return 0;
  }
  /* printf("realloc 0x%x size: %d bytes\n", (int)p, n); */
  return realloc(p, n);
}


/*
** Create a string from the 2nd and subsequent arguments (up to the
** first NULL argument), store the string in memory obtained from
** sqliteMalloc() and make the pointer indicated by the 1st argument
** point to that string.
*/







|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






<










<

















<


>







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
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.5 2000/05/30 13:44:20 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

#ifdef MEMORY_DEBUG


/*
** Allocate new memory and set it to zero.  Return NULL if
** no memory is available.
*/
void *sqliteMalloc_(int n, char *zFile, int line){
  void *p;
  int *pi;
  int k;
  k = (n+sizeof(int)-1)/sizeof(int);
  pi = malloc( (3+k)*sizeof(int));
  if( pi==0 ) return 0;
  pi[0] = 0xdead1122;
  pi[1] = n;
  pi[k+2] = 0xdead3344;
  p = &pi[2];
  memset(p, 0, n);
  printf("malloc %d bytes at 0x%x from %s:%d\n", n, (int)p, zFile, line);
  return p;
}

/*
** Free memory previously obtained from sqliteMalloc()
*/
void sqliteFree_(void *p, char *zFile, int line){
  if( p ){
    int *pi, k, n;
    pi = p;
    pi -= 2;
    if( pi[0]!=0xdead1122 ){
      printf("Low-end memory corruption at 0x%x\n", (int)p);
      return;
    }
    n = pi[1];
    k = (n+sizeof(int)-1)/sizeof(int);
    if( pi[k+2]!=0xdead3344 ){
      printf("High-end memory corruption at 0x%x\n", (int)p);
      return;
    }
    memset(pi, 0, (k+3)*sizeof(int));
    printf("free %d bytes at 0x%x from %s:%d\n", n, (int)p, zFile, line);
    free(pi);
  }
}

/*
** Resize a prior allocation.  If p==0, then this routine
** works just like sqliteMalloc().  If n==0, then this routine
** works just like sqliteFree().
*/
void *sqliteRealloc_(void *oldP, int n, char *zFile, int line){
  int *oldPi, *pi, k, oldN, oldK;
  void *p;
  if( oldP==0 ){
    return sqliteMalloc_(n,zFile,line);
  }
  if( n==0 ){
    sqliteFree_(oldP,zFile,line);
    return 0;
  }
  oldPi = oldP;
  oldPi -= 2;
  if( oldPi[0]!=0xdead1122 ){
    printf("Low-end memory corruption in realloc at 0x%x\n", (int)p);
    return;
  }
  oldN = oldPi[1];
  oldK = (oldN+sizeof(int)-1)/sizeof(int);
  if( oldPi[oldK+2]!=0xdead3344 ){
    printf("High-end memory corruption in realloc at 0x%x\n", (int)p);
    return;
  }
  k = (n + sizeof(int) - 1)/sizeof(int);
  pi = malloc( (k+3)*sizeof(int) );
  pi[0] = 0xdead1122;
  pi[1] = n;
  pi[k+2] = 0xdead3344;
  p = &pi[2];
  memcpy(p, oldP, n>oldN ? oldN : n);
  if( n>oldN ){
    memset(&((char*)p)[oldN], 0, n-oldN);
  }
  memset(oldPi, 0, (oldK+3)*sizeof(int));
  free(oldPi);
  printf("realloc %d->%d bytes at 0x%x->0x%x at %s:%d\n", oldN, n,
    (int)oldP, (int)p, zFile, line);
  return p;
}
#else  /* !defined(MEMORY_DEBUG) */
/*
** Allocate new memory and set it to zero.  Return NULL if
** no memory is available.
*/
void *sqliteMalloc(int n){
  void *p = malloc(n);

  if( p==0 ) return 0;
  memset(p, 0, n);
  return p;
}

/*
** Free memory previously obtained from sqliteMalloc()
*/
void sqliteFree(void *p){
  if( p ){

    free(p);
  }
}

/*
** Resize a prior allocation.  If p==0, then this routine
** works just like sqliteMalloc().  If n==0, then this routine
** works just like sqliteFree().
*/
void *sqliteRealloc(void *p, int n){
  if( p==0 ){
    return sqliteMalloc(n);
  }
  if( n==0 ){
    sqliteFree(p);
    return 0;
  }

  return realloc(p, n);
}
#endif /* MEMORY_DEBUG */

/*
** Create a string from the 2nd and subsequent arguments (up to the
** first NULL argument), store the string in memory obtained from
** sqliteMalloc() and make the pointer indicated by the 1st argument
** point to that string.
*/
Changes to test/table.test.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the CREATE TABLE statement.
#
# $Id: table.test,v 1.2 2000/05/30 03:12:22 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create a basic table and verify it is added to sqlite_master
#
do_test table-1.1 {







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the CREATE TABLE statement.
#
# $Id: table.test,v 1.3 2000/05/30 13:44:20 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create a basic table and verify it is added to sqlite_master
#
do_test table-1.1 {
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
} {1 {table sqlite_master already exists}}
do_test table-2.1d {
  execsql {DROP TABLE test2; SELECT name FROM sqlite_master}
} {}

# Verify that we cannot make a table with the same name as an index
#
do_test table-2.2 {
  execsql {CREATE TABLE test2(one text); CREATE INDEX test3 ON test2(one)}
  set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
  lappend v $msg
} {1 {there is already an index named test3}}
do_test table-2.2b {
  db close
  sqlite db testdb







|







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
} {1 {table sqlite_master already exists}}
do_test table-2.1d {
  execsql {DROP TABLE test2; SELECT name FROM sqlite_master}
} {}

# Verify that we cannot make a table with the same name as an index
#
do_test table-2.2a {
  execsql {CREATE TABLE test2(one text); CREATE INDEX test3 ON test2(one)}
  set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
  lappend v $msg
} {1 {there is already an index named test3}}
do_test table-2.2b {
  db close
  sqlite db testdb
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

# Create a table with many field names
#
set big_table \
{CREATE TABLE big(
  f1 varchar(20),
  f2 char(10),
  f3 varchar(30),
  f4 text,
  f5 text,
  f6 text,
  f7 text,
  f8 text,
  f9 text,
  f10 text,







|







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

# Create a table with many field names
#
set big_table \
{CREATE TABLE big(
  f1 varchar(20),
  f2 char(10),
  f3 varchar(30) primary key,
  f4 text,
  f5 text,
  f6 text,
  f7 text,
  f8 text,
  f9 text,
  f10 text,