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: |
275ba356f351abcf9a079ac16b765c94 |
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
Changes to src/parse.y.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** 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. ** | | | 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 | ************************************************************************* ** 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. ** | | | 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 | 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 | 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; } | > | < | 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 |