SQLite

Check-in [4cedc641ed]
Login

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

Overview
Comment:Disallow the ON CONFLICT clause on CHECK constraints. The syntax used to be allowed but never worked, so this should not present compatibility problems. Other internal grammar simplifications. (CVS 5546)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4cedc641ed39982ae8cbb9200aa1e2f37c878b73
User & Date: drh 2008-08-08 14:19:41.000
Context
2008-08-08
14:33
Round lookaside buffer sizes in the right direction. Ticket #3277. (CVS 5547) (check-in: c1a9bf3863 user: drh tags: trunk)
14:19
Disallow the ON CONFLICT clause on CHECK constraints. The syntax used to be allowed but never worked, so this should not present compatibility problems. Other internal grammar simplifications. (CVS 5546) (check-in: 4cedc641ed user: drh tags: trunk)
2008-08-07
13:05
Improved clarity of presentation in the tokenizer. (CVS 5545) (check-in: 732657c6a6 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to addopcodes.awk.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
  printf "#define TK_%-29s %4d\n", "TO_NUMERIC",      max+3
  printf "#define TK_%-29s %4d\n", "TO_INT",          max+4
  printf "#define TK_%-29s %4d\n", "TO_REAL",         max+5
  printf "#define TK_%-29s %4d\n", "END_OF_FILE",     max+6
  printf "#define TK_%-29s %4d\n", "ILLEGAL",         max+7
  printf "#define TK_%-29s %4d\n", "SPACE",           max+8
  printf "#define TK_%-29s %4d\n", "UNCLOSED_STRING", max+9
  printf "#define TK_%-29s %4d\n", "COMMENT",         max+10
  printf "#define TK_%-29s %4d\n", "FUNCTION",        max+11
  printf "#define TK_%-29s %4d\n", "COLUMN",          max+12
  printf "#define TK_%-29s %4d\n", "AGG_FUNCTION",    max+13
  printf "#define TK_%-29s %4d\n", "AGG_COLUMN",      max+14
  printf "#define TK_%-29s %4d\n", "CONST_FUNC",      max+15
}







<
|
|
|
|
|

19
20
21
22
23
24
25

26
27
28
29
30
31
  printf "#define TK_%-29s %4d\n", "TO_NUMERIC",      max+3
  printf "#define TK_%-29s %4d\n", "TO_INT",          max+4
  printf "#define TK_%-29s %4d\n", "TO_REAL",         max+5
  printf "#define TK_%-29s %4d\n", "END_OF_FILE",     max+6
  printf "#define TK_%-29s %4d\n", "ILLEGAL",         max+7
  printf "#define TK_%-29s %4d\n", "SPACE",           max+8
  printf "#define TK_%-29s %4d\n", "UNCLOSED_STRING", max+9

  printf "#define TK_%-29s %4d\n", "FUNCTION",        max+10
  printf "#define TK_%-29s %4d\n", "COLUMN",          max+11
  printf "#define TK_%-29s %4d\n", "AGG_FUNCTION",    max+12
  printf "#define TK_%-29s %4d\n", "AGG_COLUMN",      max+13
  printf "#define TK_%-29s %4d\n", "CONST_FUNC",      max+14
}
Changes to src/alter.c.
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 C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
**
** $Id: alter.c,v 1.47 2008/07/28 19:34:53 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The code in this file only exists if we are not omitting the
** ALTER TABLE logic from the build.







|







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 C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
**
** $Id: alter.c,v 1.48 2008/08/08 14:19:41 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The code in this file only exists if we are not omitting the
** ALTER TABLE logic from the build.
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

      /* Advance zCsr to the next token. Store that token type in 'token',
      ** and its length in 'len' (to be used next iteration of this loop).
      */
      do {
        zCsr += len;
        len = sqlite3GetToken(zCsr, &token);
      } while( token==TK_SPACE || token==TK_COMMENT );
      assert( len>0 );
    } while( token!=TK_LP && token!=TK_USING );

    zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", tname.z - zSql, zSql, 
       zTableName, tname.z+tname.n);
    sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
  }







|







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

      /* Advance zCsr to the next token. Store that token type in 'token',
      ** and its length in 'len' (to be used next iteration of this loop).
      */
      do {
        zCsr += len;
        len = sqlite3GetToken(zCsr, &token);
      } while( token==TK_SPACE );
      assert( len>0 );
    } while( token!=TK_LP && token!=TK_USING );

    zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", tname.z - zSql, zSql, 
       zTableName, tname.z+tname.n);
    sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
  }
Changes to src/parse.y.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.248 2008/07/31 01:40:42 shane Exp $
*/

// All token codes are small integers with #defines that begin with "TK_"
%token_prefix TK_

// The type of the data attached to each token is Token.  This is also the
// default type for non-terminals.







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.249 2008/08/08 14:19:41 drh Exp $
*/

// All token codes are small integers with #defines that begin with "TK_"
%token_prefix TK_

// The type of the data attached to each token is Token.  This is also the
// default type for non-terminals.
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

102
103
104
105
106
107
108

} // end %include

// Input is a single SQL command
input ::= cmdlist.
cmdlist ::= cmdlist ecmd.
cmdlist ::= ecmd.
cmdx ::= cmd.           { sqlite3FinishCoding(pParse); }
ecmd ::= SEMI.
ecmd ::= explain cmdx SEMI.
explain ::= .           { sqlite3BeginParse(pParse, 0); }
%ifndef SQLITE_OMIT_EXPLAIN
explain ::= EXPLAIN.              { sqlite3BeginParse(pParse, 1); }
explain ::= EXPLAIN QUERY PLAN.   { sqlite3BeginParse(pParse, 2); }
%endif  SQLITE_OMIT_EXPLAIN


///////////////////// Begin and end transactions. ////////////////////////////
//

cmd ::= BEGIN transtype(Y) trans_opt.  {sqlite3BeginTransaction(pParse, Y);}
trans_opt ::= .
trans_opt ::= TRANSACTION.







<







>







87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

} // end %include

// Input is a single SQL command
input ::= cmdlist.
cmdlist ::= cmdlist ecmd.
cmdlist ::= ecmd.

ecmd ::= SEMI.
ecmd ::= explain cmdx SEMI.
explain ::= .           { sqlite3BeginParse(pParse, 0); }
%ifndef SQLITE_OMIT_EXPLAIN
explain ::= EXPLAIN.              { sqlite3BeginParse(pParse, 1); }
explain ::= EXPLAIN QUERY PLAN.   { sqlite3BeginParse(pParse, 2); }
%endif  SQLITE_OMIT_EXPLAIN
cmdx ::= cmd.           { sqlite3FinishCoding(pParse); }

///////////////////// Begin and end transactions. ////////////////////////////
//

cmd ::= BEGIN transtype(Y) trans_opt.  {sqlite3BeginTransaction(pParse, Y);}
trans_opt ::= .
trans_opt ::= TRANSACTION.
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
conslist ::= conslist tcons.
conslist ::= tcons.
tcons ::= CONSTRAINT nm.
tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R).
                                         {sqlite3AddPrimaryKey(pParse,X,R,I,0);}
tcons ::= UNIQUE LP idxlist(X) RP onconf(R).
                                 {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0);}
tcons ::= CHECK LP expr(E) RP onconf. {sqlite3AddCheckConstraint(pParse,E);}
tcons ::= FOREIGN KEY LP idxlist(FA) RP
          REFERENCES nm(T) idxlist_opt(TA) refargs(R) defer_subclause_opt(D). {
    sqlite3CreateForeignKey(pParse, FA, &T, TA, R);
    sqlite3DeferForeignKey(pParse, D);
}
%type defer_subclause_opt {int}
defer_subclause_opt(A) ::= .                    {A = 0;}







|







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
conslist ::= conslist tcons.
conslist ::= tcons.
tcons ::= CONSTRAINT nm.
tcons ::= PRIMARY KEY LP idxlist(X) autoinc(I) RP onconf(R).
                                         {sqlite3AddPrimaryKey(pParse,X,R,I,0);}
tcons ::= UNIQUE LP idxlist(X) RP onconf(R).
                                 {sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0);}
tcons ::= CHECK LP expr(E) RP. {sqlite3AddCheckConstraint(pParse,E);}
tcons ::= FOREIGN KEY LP idxlist(FA) RP
          REFERENCES nm(T) idxlist_opt(TA) refargs(R) defer_subclause_opt(D). {
    sqlite3CreateForeignKey(pParse, FA, &T, TA, R);
    sqlite3DeferForeignKey(pParse, D);
}
%type defer_subclause_opt {int}
defer_subclause_opt(A) ::= .                    {A = 0;}
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
uniqueflag(A) ::= UNIQUE.  {A = OE_Abort;}
uniqueflag(A) ::= .        {A = OE_None;}

%type idxlist {ExprList*}
%destructor idxlist {sqlite3ExprListDelete(pParse->db, $$);}
%type idxlist_opt {ExprList*}
%destructor idxlist_opt {sqlite3ExprListDelete(pParse->db, $$);}
%type idxitem {Token}

idxlist_opt(A) ::= .                         {A = 0;}
idxlist_opt(A) ::= LP idxlist(X) RP.         {A = X;}
idxlist(A) ::= idxlist(X) COMMA idxitem(Y) collate(C) sortorder(Z).  {
  Expr *p = 0;
  if( C.n>0 ){
    p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
    sqlite3ExprSetColl(pParse, p, &C);
  }
  A = sqlite3ExprListAppend(pParse,X, p, &Y);
  sqlite3ExprListCheckLength(pParse, A, "index");
  if( A ) A->a[A->nExpr-1].sortOrder = Z;
}
idxlist(A) ::= idxitem(Y) collate(C) sortorder(Z). {
  Expr *p = 0;
  if( C.n>0 ){
    p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
    sqlite3ExprSetColl(pParse, p, &C);
  }
  A = sqlite3ExprListAppend(pParse,0, p, &Y);
  sqlite3ExprListCheckLength(pParse, A, "index");
  if( A ) A->a[A->nExpr-1].sortOrder = Z;
}
idxitem(A) ::= nm(X).              {A = X;}

%type collate {Token}
collate(C) ::= .                {C.z = 0; C.n = 0;}
collate(C) ::= COLLATE ids(X).   {C = X;}


///////////////////////////// The DROP INDEX command /////////////////////////







<



|









|









<







881
882
883
884
885
886
887

888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910

911
912
913
914
915
916
917
uniqueflag(A) ::= UNIQUE.  {A = OE_Abort;}
uniqueflag(A) ::= .        {A = OE_None;}

%type idxlist {ExprList*}
%destructor idxlist {sqlite3ExprListDelete(pParse->db, $$);}
%type idxlist_opt {ExprList*}
%destructor idxlist_opt {sqlite3ExprListDelete(pParse->db, $$);}


idxlist_opt(A) ::= .                         {A = 0;}
idxlist_opt(A) ::= LP idxlist(X) RP.         {A = X;}
idxlist(A) ::= idxlist(X) COMMA nm(Y) collate(C) sortorder(Z).  {
  Expr *p = 0;
  if( C.n>0 ){
    p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
    sqlite3ExprSetColl(pParse, p, &C);
  }
  A = sqlite3ExprListAppend(pParse,X, p, &Y);
  sqlite3ExprListCheckLength(pParse, A, "index");
  if( A ) A->a[A->nExpr-1].sortOrder = Z;
}
idxlist(A) ::= nm(Y) collate(C) sortorder(Z). {
  Expr *p = 0;
  if( C.n>0 ){
    p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
    sqlite3ExprSetColl(pParse, p, &C);
  }
  A = sqlite3ExprListAppend(pParse,0, p, &Y);
  sqlite3ExprListCheckLength(pParse, A, "index");
  if( A ) A->a[A->nExpr-1].sortOrder = Z;
}


%type collate {Token}
collate(C) ::= .                {C.z = 0; C.n = 0;}
collate(C) ::= COLLATE ids(X).   {C = X;}


///////////////////////////// The DROP INDEX command /////////////////////////
Changes to src/tokenize.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*************************************************************************
** 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.149 2008/08/07 13:05:36 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <stdlib.h>

/*
** The charMap() macro maps alphabetic characters into their







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*************************************************************************
** 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.150 2008/08/08 14:19:41 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <stdlib.h>

/*
** The charMap() macro maps alphabetic characters into their
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
      for(i=1; isspace(z[i]); i++){}
      *tokenType = TK_SPACE;
      return i;
    }
    case '-': {
      if( z[1]=='-' ){
        for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
        *tokenType = TK_COMMENT;
        return i;
      }
      *tokenType = TK_MINUS;
      return 1;
    }
    case '(': {
      *tokenType = TK_LP;







|







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
      for(i=1; isspace(z[i]); i++){}
      *tokenType = TK_SPACE;
      return i;
    }
    case '-': {
      if( z[1]=='-' ){
        for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
        *tokenType = TK_SPACE;
        return i;
      }
      *tokenType = TK_MINUS;
      return 1;
    }
    case '(': {
      *tokenType = TK_LP;
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
    case '/': {
      if( z[1]!='*' || z[2]==0 ){
        *tokenType = TK_SLASH;
        return 1;
      }
      for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
      if( c ) i++;
      *tokenType = TK_COMMENT;
      return i;
    }
    case '%': {
      *tokenType = TK_REM;
      return 1;
    }
    case '=': {







|







160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
    case '/': {
      if( z[1]!='*' || z[2]==0 ){
        *tokenType = TK_SLASH;
        return 1;
      }
      for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
      if( c ) i++;
      *tokenType = TK_SPACE;
      return i;
    }
    case '%': {
      *tokenType = TK_REM;
      return 1;
    }
    case '=': {
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
    pParse->sLastToken.n = sqlite3GetToken((unsigned char*)&zSql[i],&tokenType);
    i += pParse->sLastToken.n;
    if( i>mxSqlLen ){
      pParse->rc = SQLITE_TOOBIG;
      break;
    }
    switch( tokenType ){
      case TK_SPACE:
      case TK_COMMENT: {
        if( db->u1.isInterrupted ){
          pParse->rc = SQLITE_INTERRUPT;
          sqlite3SetString(pzErrMsg, db, "interrupt");
          goto abort_parse;
        }
        break;
      }







|
<







416
417
418
419
420
421
422
423

424
425
426
427
428
429
430
    pParse->sLastToken.n = sqlite3GetToken((unsigned char*)&zSql[i],&tokenType);
    i += pParse->sLastToken.n;
    if( i>mxSqlLen ){
      pParse->rc = SQLITE_TOOBIG;
      break;
    }
    switch( tokenType ){
      case TK_SPACE: {

        if( db->u1.isInterrupted ){
          pParse->rc = SQLITE_INTERRUPT;
          sqlite3SetString(pzErrMsg, db, "interrupt");
          goto abort_parse;
        }
        break;
      }