SQLite

Check-in [275ba356f3]
Login

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

Overview
Comment:Do not allow triggers on the SQLITE_MASTER table. (CVS 579)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 275ba356f351abcf9a079ac16b765c9443750f0e
User & Date: drh 2002-05-23 00:30:31.000
Context
2002-05-23
02:09
Fix some places where a malloc() failure would lead to a segfault. (CVS 580) (check-in: 01ad352c3c user: drh tags: trunk)
00:30
Do not allow triggers on the SQLITE_MASTER table. (CVS 579) (check-in: 275ba356f3 user: drh tags: trunk)
2002-05-22
21:27
Fix for ticket #46: Report an error if a CREATE TABLE contains two or more columns with the same name. (CVS 578) (check-in: ba1953abd0 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
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.66 2002/05/21 11:38:12 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  sqliteSetString(&pParse->zErrMsg,"syntax error",0);







|







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.67 2002/05/23 00:30:31 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%default_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  sqliteSetString(&pParse->zErrMsg,"syntax error",0);
120
121
122
123
124
125
126

127
128
129
130
131
132
133
id(A) ::= INSTEAD(X).    {A = X;}
id(A) ::= KEY(X).        {A = X;}
id(A) ::= OF(X).         {A = X;}
id(A) ::= OFFSET(X).     {A = X;}
id(A) ::= PRAGMA(X).     {A = X;}
id(A) ::= REPLACE(X).    {A = X;}
id(A) ::= ROW(X).        {A = X;}

id(A) ::= TEMP(X).       {A = X;}
id(A) ::= TRIGGER(X).    {A = X;}
id(A) ::= VACUUM(X).     {A = X;}
id(A) ::= VIEW(X).       {A = X;}

// And "ids" is an identifer-or-string.
//







>







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
id(A) ::= INSTEAD(X).    {A = X;}
id(A) ::= KEY(X).        {A = X;}
id(A) ::= OF(X).         {A = X;}
id(A) ::= OFFSET(X).     {A = X;}
id(A) ::= PRAGMA(X).     {A = X;}
id(A) ::= REPLACE(X).    {A = X;}
id(A) ::= ROW(X).        {A = X;}
id(A) ::= STATEMENT(X).  {A = X;}
id(A) ::= TEMP(X).       {A = X;}
id(A) ::= TRIGGER(X).    {A = X;}
id(A) ::= VACUUM(X).     {A = X;}
id(A) ::= VIEW(X).       {A = X;}

// And "ids" is an identifer-or-string.
//
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.41 2002/05/15 08:30:14 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*







|







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.42 2002/05/23 00:30:31 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
96
97
98
99
100
101
102

103
104
105
106
107
108
109
  { "PRAGMA",            0, TK_PRAGMA,           0 },
  { "PRIMARY",           0, TK_PRIMARY,          0 },
  { "REPLACE",           0, TK_REPLACE,          0 },
  { "ROLLBACK",          0, TK_ROLLBACK,         0 },
  { "ROW",               0, TK_ROW,              0 },
  { "SELECT",            0, TK_SELECT,           0 },
  { "SET",               0, TK_SET,              0 },

  { "TABLE",             0, TK_TABLE,            0 },
  { "TEMP",              0, TK_TEMP,             0 },
  { "TEMPORARY",         0, TK_TEMP,             0 },
  { "THEN",              0, TK_THEN,             0 },
  { "TRANSACTION",       0, TK_TRANSACTION,      0 },
  { "TRIGGER",           0, TK_TRIGGER,          0 },
  { "UNION",             0, TK_UNION,            0 },







>







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  { "PRAGMA",            0, TK_PRAGMA,           0 },
  { "PRIMARY",           0, TK_PRIMARY,          0 },
  { "REPLACE",           0, TK_REPLACE,          0 },
  { "ROLLBACK",          0, TK_ROLLBACK,         0 },
  { "ROW",               0, TK_ROW,              0 },
  { "SELECT",            0, TK_SELECT,           0 },
  { "SET",               0, TK_SET,              0 },
  { "STATEMENT",         0, TK_STATEMENT,        0 },
  { "TABLE",             0, TK_TABLE,            0 },
  { "TEMP",              0, TK_TEMP,             0 },
  { "TEMPORARY",         0, TK_TEMP,             0 },
  { "THEN",              0, TK_THEN,             0 },
  { "TRANSACTION",       0, TK_TRANSACTION,      0 },
  { "TRIGGER",           0, TK_TRIGGER,          0 },
  { "UNION",             0, TK_UNION,            0 },
Changes to src/trigger.c.
55
56
57
58
59
60
61






62
63
64
65
66
67
68
    tab = sqliteFindTable(pParse->db, tmp_str);
    sqliteFree(tmp_str);
    if( !tab ){
      sqliteSetNString(&pParse->zErrMsg, "no such table: ", -1,
          pTableName->z, pTableName->n, 0);
      pParse->nErr++;
      goto trigger_cleanup;






    }
  }

  /* Build the Trigger object */
  nt = (Trigger*)sqliteMalloc(sizeof(Trigger));
  nt->name = sqliteStrNDup(pName->z, pName->n);
  nt->table = sqliteStrNDup(pTableName->z, pTableName->n);







>
>
>
>
>
>







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
    tab = sqliteFindTable(pParse->db, tmp_str);
    sqliteFree(tmp_str);
    if( !tab ){
      sqliteSetNString(&pParse->zErrMsg, "no such table: ", -1,
          pTableName->z, pTableName->n, 0);
      pParse->nErr++;
      goto trigger_cleanup;
    }
    if( sqliteStrICmp(tab->zName, MASTER_NAME)==0 ){
      sqliteSetString(&pParse->zErrMsg, "cannot create trigger on system "
         "table: " MASTER_NAME, 0);
      pParse->nErr++;
      goto trigger_cleanup;
    }
  }

  /* Build the Trigger object */
  nt = (Trigger*)sqliteMalloc(sizeof(Trigger));
  nt->name = sqliteStrNDup(pName->z, pName->n);
  nt->table = sqliteStrNDup(pTableName->z, pTableName->n);
Changes to test/trigger1.test.
98
99
100
101
102
103
104








105
106
107
108
109
110
111
112
113
	CREATE TRIGGER temp_trig UPDATE ON temp_table BEGIN
	    SELECT * from sqlite_master;
	END;
	SELECT count(*) FROM sqlite_master WHERE name = 'temp_trig';
  } 
} {0}









catchsql {
  DROP TABLE temp_table;
}
catchsql {
  DROP TABLE t1;
}

finish_test








>
>
>
>
>
>
>
>








<
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

	CREATE TRIGGER temp_trig UPDATE ON temp_table BEGIN
	    SELECT * from sqlite_master;
	END;
	SELECT count(*) FROM sqlite_master WHERE name = 'temp_trig';
  } 
} {0}

do_test trig_cd-1.9 {
  catchsql {
    CREATE TRIGGER tr1 AFTER UPDATE ON sqlite_master BEGIN
       SELECT * FROM sqlite_master;
    END;
  }
} {1 {cannot create trigger on system table: sqlite_master}}

catchsql {
  DROP TABLE temp_table;
}
catchsql {
  DROP TABLE t1;
}

finish_test

Changes to test/trigger2.test.
537
538
539
540
541
542
543

544
545
546
547
548
549
550
551
  }
} {4 2 3 6 3 4}
execsql {
  DROP TABLE tbl;
}

# 7. Triggers on views

execsql {
  CREATE TABLE ab(a, b);
  CREATE TABLE cd(c, d);
  INSERT INTO ab VALUES (1, 2);
  INSERT INTO ab VALUES (0, 0);
  INSERT INTO cd VALUES (3, 4);

  CREATE TABLE tlog(ii INTEGER PRIMARY KEY, 







>
|







537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
  }
} {4 2 3 6 3 4}
execsql {
  DROP TABLE tbl;
}

# 7. Triggers on views
do_test trig-7.1 {
  execsql {
  CREATE TABLE ab(a, b);
  CREATE TABLE cd(c, d);
  INSERT INTO ab VALUES (1, 2);
  INSERT INTO ab VALUES (0, 0);
  INSERT INTO cd VALUES (3, 4);

  CREATE TABLE tlog(ii INTEGER PRIMARY KEY, 
575
576
577
578
579
580
581
582

583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
    INSERT INTO tlog VALUES(NULL, 
	0, 0, 0, 0, new.a, new.b, new.c, new.d);
  END;
   CREATE TRIGGER after_insert AFTER INSERT ON abcd BEGIN
    INSERT INTO tlog VALUES(NULL, 
	0, 0, 0, 0, new.a, new.b, new.c, new.d);
   END;
}


do_test trig-7 {
  execsql {
    UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
    DELETE FROM abcd WHERE a = 1;
    INSERT INTO abcd VALUES(10, 20, 30, 40);
    SELECT * FROM tlog;
  }
} [ list 1 1 2 3 4 100 25 3 4 \
         2 1 2 3 4 100 25 3 4 \
 3 1 2 3 4 0 0 0 0 4 1 2 3 4 0 0 0 0 \
 5 0 0 0 0 10 20 30 40 6 0 0 0 0 10 20 30 40 ]

finish_test








|
>

|












<
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598

    INSERT INTO tlog VALUES(NULL, 
	0, 0, 0, 0, new.a, new.b, new.c, new.d);
  END;
   CREATE TRIGGER after_insert AFTER INSERT ON abcd BEGIN
    INSERT INTO tlog VALUES(NULL, 
	0, 0, 0, 0, new.a, new.b, new.c, new.d);
   END;
  }
} {}

do_test trig-7.2 {
  execsql {
    UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
    DELETE FROM abcd WHERE a = 1;
    INSERT INTO abcd VALUES(10, 20, 30, 40);
    SELECT * FROM tlog;
  }
} [ list 1 1 2 3 4 100 25 3 4 \
         2 1 2 3 4 100 25 3 4 \
 3 1 2 3 4 0 0 0 0 4 1 2 3 4 0 0 0 0 \
 5 0 0 0 0 10 20 30 40 6 0 0 0 0 10 20 30 40 ]

finish_test