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 Show Whitespace Changes 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
  }
} {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);








>







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
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);

576
577
578
579
580
581
582

583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
	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








>

|












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

	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