You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2197 lines
63 KiB

21 years ago
21 years ago
Fix for bug#20670 "UPDATE using key and invoking trigger that modifies this key does not stop" (version for 5.0 only). UPDATE statement which WHERE clause used key and which invoked trigger that modified field in this key worked indefinetely. This problem occured because in cases when UPDATE statement was executed in update-on-the-fly mode (in which row is updated right during evaluation of select for WHERE clause) the new version of the row became visible to select representing WHERE clause and was updated again and again. We already solve this problem for UPDATE statements which does not invoke triggers by detecting the fact that we are going to update field in key used for scanning and performing update in two steps, during the first step we gather information about the rows to be updated and then doing actual updates. We also do this for MULTI-UPDATE and in its case we even detect situation when such fields are updated in triggers (actually we simply assume that we always update fields used in key if we have before update trigger). The fix simply extends this check which is done in check_if_key_used()/ QUICK_SELECT_I::check_if_keys_used() routine/method in such way that it also detects cases when field used in key is updated in trigger. As nice side-effect we have more precise and thus more optimal perfomance-wise check for the MULTI-UPDATE. Also check_if_key_used()/QUICK_SELECT_I::check_if_keys_used() were renamed to is_key_used()/QUICK_SELECT_I::is_keys_used() in order to better reflect that boolean predicate. Note that this check is implemented in much more elegant way in 5.1
19 years ago
Fix for bug#20670 "UPDATE using key and invoking trigger that modifies this key does not stop" (version for 5.0 only). UPDATE statement which WHERE clause used key and which invoked trigger that modified field in this key worked indefinetely. This problem occured because in cases when UPDATE statement was executed in update-on-the-fly mode (in which row is updated right during evaluation of select for WHERE clause) the new version of the row became visible to select representing WHERE clause and was updated again and again. We already solve this problem for UPDATE statements which does not invoke triggers by detecting the fact that we are going to update field in key used for scanning and performing update in two steps, during the first step we gather information about the rows to be updated and then doing actual updates. We also do this for MULTI-UPDATE and in its case we even detect situation when such fields are updated in triggers (actually we simply assume that we always update fields used in key if we have before update trigger). The fix simply extends this check which is done in check_if_key_used()/ QUICK_SELECT_I::check_if_keys_used() routine/method in such way that it also detects cases when field used in key is updated in trigger. As nice side-effect we have more precise and thus more optimal perfomance-wise check for the MULTI-UPDATE. Also check_if_key_used()/QUICK_SELECT_I::check_if_keys_used() were renamed to is_key_used()/QUICK_SELECT_I::is_keys_used() in order to better reflect that boolean predicate. Note that this check is implemented in much more elegant way in 5.1
19 years ago
19 years ago
Fix for: Bug #20662 "Infinite loop in CREATE TABLE IF NOT EXISTS ... SELECT with locked tables" Bug #20903 "Crash when using CREATE TABLE .. SELECT and triggers" Bug #24738 "CREATE TABLE ... SELECT is not isolated properly" Bug #24508 "Inconsistent results of CREATE TABLE ... SELECT when temporary table exists" Deadlock occured when one tried to execute CREATE TABLE IF NOT EXISTS ... SELECT statement under LOCK TABLES which held read lock on target table. Attempt to execute the same statement for already existing target table with triggers caused server crashes. Also concurrent execution of CREATE TABLE ... SELECT statement and other statements involving target table suffered from various races (some of which might've led to deadlocks). Finally, attempt to execute CREATE TABLE ... SELECT in case when a temporary table with same name was already present led to the insertion of data into this temporary table and creation of empty non-temporary table. All above problems stemmed from the old implementation of CREATE TABLE ... SELECT in which we created, opened and locked target table without any special protection in a separate step and not with the rest of tables used by this statement. This underminded deadlock-avoidance approach used in server and created window for races. It also excluded target table from prelocking causing problems with trigger execution. The patch solves these problems by implementing new approach to handling of CREATE TABLE ... SELECT for base tables. We try to open and lock table to be created at the same time as the rest of tables used by this statement. If such table does not exist at this moment we create and place in the table cache special placeholder for it which prevents its creation or any other usage by other threads. We still use old approach for creation of temporary tables. Also note that we decided to postpone introduction of some tests for concurrent behaviour of CREATE TABLE ... SELECT till 5.1. The main reason for this is absence in 5.0 ability to set @@debug variable at runtime, which can be circumvented only by using several test files with individual .opt files. Since the latter is likely to slowdown test-suite unnecessary we chose not to push this tests into 5.0, but run them manually for this version and later push their optimized version into 5.1
19 years ago
  1. # This test uses chmod, can't be run with root permissions
  2. -- source include/not_as_root.inc
  3. #
  4. # Basic triggers test
  5. #
  6. --disable_warnings
  7. drop table if exists t1, t2, t3, t4;
  8. drop view if exists v1;
  9. drop database if exists mysqltest;
  10. drop function if exists f1;
  11. drop function if exists f2;
  12. drop procedure if exists p1;
  13. --enable_warnings
  14. # Create additional connections used through test
  15. connect (addconroot1, localhost, root,,);
  16. connect (addconroot2, localhost, root,,);
  17. # Connection without current database set
  18. connect (addconwithoutdb, localhost, root,,*NO-ONE*);
  19. connection default;
  20. create table t1 (i int);
  21. # let us test some very simple trigger
  22. create trigger trg before insert on t1 for each row set @a:=1;
  23. set @a:=0;
  24. select @a;
  25. insert into t1 values (1);
  26. select @a;
  27. drop trigger trg;
  28. # let us test simple trigger reading some values
  29. create trigger trg before insert on t1 for each row set @a:=new.i;
  30. insert into t1 values (123);
  31. select @a;
  32. drop trigger trg;
  33. drop table t1;
  34. # Let us test before insert trigger
  35. # Such triggers can be used for setting complex default values
  36. create table t1 (i int not null, j int);
  37. delimiter |;
  38. create trigger trg before insert on t1 for each row
  39. begin
  40. if isnull(new.j) then
  41. set new.j:= new.i * 10;
  42. end if;
  43. end|
  44. insert into t1 (i) values (1)|
  45. insert into t1 (i,j) values (2, 3)|
  46. select * from t1|
  47. drop trigger trg|
  48. drop table t1|
  49. delimiter ;|
  50. # After insert trigger
  51. # Useful for aggregating data
  52. create table t1 (i int not null primary key);
  53. create trigger trg after insert on t1 for each row
  54. set @a:= if(@a,concat(@a, ":", new.i), new.i);
  55. set @a:="";
  56. insert into t1 values (2),(3),(4),(5);
  57. select @a;
  58. drop trigger trg;
  59. drop table t1;
  60. # PS doesn't work with multi-row statements
  61. --disable_ps_protocol
  62. # Before update trigger
  63. # (In future we will achieve this via proper error handling in triggers)
  64. create table t1 (aid int not null primary key, balance int not null default 0);
  65. insert into t1 values (1, 1000), (2,3000);
  66. delimiter |;
  67. create trigger trg before update on t1 for each row
  68. begin
  69. declare loc_err varchar(255);
  70. if abs(new.balance - old.balance) > 1000 then
  71. set new.balance:= old.balance;
  72. set loc_err := concat("Too big change for aid = ", new.aid);
  73. set @update_failed:= if(@update_failed, concat(@a, ":", loc_err), loc_err);
  74. end if;
  75. end|
  76. set @update_failed:=""|
  77. update t1 set balance=1500|
  78. select @update_failed;
  79. select * from t1|
  80. drop trigger trg|
  81. drop table t1|
  82. delimiter ;|
  83. --enable_ps_protocol
  84. # After update trigger
  85. create table t1 (i int);
  86. insert into t1 values (1),(2),(3),(4);
  87. create trigger trg after update on t1 for each row
  88. set @total_change:=@total_change + new.i - old.i;
  89. set @total_change:=0;
  90. update t1 set i=3;
  91. select @total_change;
  92. drop trigger trg;
  93. drop table t1;
  94. # Before delete trigger
  95. # This can be used for aggregation too :)
  96. create table t1 (i int);
  97. insert into t1 values (1),(2),(3),(4);
  98. create trigger trg before delete on t1 for each row
  99. set @del_sum:= @del_sum + old.i;
  100. set @del_sum:= 0;
  101. delete from t1 where i <= 3;
  102. select @del_sum;
  103. drop trigger trg;
  104. drop table t1;
  105. # After delete trigger.
  106. # Just run out of imagination.
  107. create table t1 (i int);
  108. insert into t1 values (1),(2),(3),(4);
  109. create trigger trg after delete on t1 for each row set @del:= 1;
  110. set @del:= 0;
  111. delete from t1 where i <> 0;
  112. select @del;
  113. drop trigger trg;
  114. drop table t1;
  115. # Several triggers on one table
  116. create table t1 (i int, j int);
  117. delimiter |;
  118. create trigger trg1 before insert on t1 for each row
  119. begin
  120. if new.j > 10 then
  121. set new.j := 10;
  122. end if;
  123. end|
  124. create trigger trg2 before update on t1 for each row
  125. begin
  126. if old.i % 2 = 0 then
  127. set new.j := -1;
  128. end if;
  129. end|
  130. create trigger trg3 after update on t1 for each row
  131. begin
  132. if new.j = -1 then
  133. set @fired:= "Yes";
  134. end if;
  135. end|
  136. delimiter ;|
  137. set @fired:="";
  138. insert into t1 values (1,2),(2,3),(3,14);
  139. select @fired;
  140. select * from t1;
  141. update t1 set j= 20;
  142. select @fired;
  143. select * from t1;
  144. drop trigger trg1;
  145. drop trigger trg2;
  146. drop trigger trg3;
  147. drop table t1;
  148. # Let us test how triggers work for special forms of INSERT such as
  149. # REPLACE and INSERT ... ON DUPLICATE KEY UPDATE
  150. create table t1 (id int not null primary key, data int);
  151. create trigger t1_bi before insert on t1 for each row
  152. set @log:= concat(@log, "(BEFORE_INSERT: new=(id=", new.id, ", data=", new.data,"))");
  153. create trigger t1_ai after insert on t1 for each row
  154. set @log:= concat(@log, "(AFTER_INSERT: new=(id=", new.id, ", data=", new.data,"))");
  155. create trigger t1_bu before update on t1 for each row
  156. set @log:= concat(@log, "(BEFORE_UPDATE: old=(id=", old.id, ", data=", old.data,
  157. ") new=(id=", new.id, ", data=", new.data,"))");
  158. create trigger t1_au after update on t1 for each row
  159. set @log:= concat(@log, "(AFTER_UPDATE: old=(id=", old.id, ", data=", old.data,
  160. ") new=(id=", new.id, ", data=", new.data,"))");
  161. create trigger t1_bd before delete on t1 for each row
  162. set @log:= concat(@log, "(BEFORE_DELETE: old=(id=", old.id, ", data=", old.data,"))");
  163. create trigger t1_ad after delete on t1 for each row
  164. set @log:= concat(@log, "(AFTER_DELETE: old=(id=", old.id, ", data=", old.data,"))");
  165. # Simple INSERT - both triggers should be called
  166. set @log:= "";
  167. insert into t1 values (1, 1);
  168. select @log;
  169. # INSERT IGNORE for already existing key - only before trigger should fire
  170. set @log:= "";
  171. insert ignore t1 values (1, 2);
  172. select @log;
  173. # INSERT ... ON DUPLICATE KEY UPDATE ...
  174. set @log:= "";
  175. insert into t1 (id, data) values (1, 3), (2, 2) on duplicate key update data= data + 1;
  176. select @log;
  177. # REPLACE (also test for bug#13479 "REPLACE activates UPDATE trigger,
  178. # not the DELETE and INSERT triggers")
  179. # We define REPLACE as INSERT which DELETEs old rows which conflict with
  180. # row being inserted. So for the first record in statement below we will
  181. # call before insert trigger, then delete will be executed (and both delete
  182. # triggers should fire). Finally after insert trigger will be called.
  183. # For the second record we will just call both on insert triggers.
  184. set @log:= "";
  185. replace t1 values (1, 4), (3, 3);
  186. select @log;
  187. # Now we will drop ON DELETE triggers to test REPLACE which is internally
  188. # executed via update
  189. drop trigger t1_bd;
  190. drop trigger t1_ad;
  191. set @log:= "";
  192. replace t1 values (1, 5);
  193. select @log;
  194. # This also drops associated triggers
  195. drop table t1;
  196. #
  197. # Let us test triggers which access other tables.
  198. #
  199. # Trivial trigger which inserts data into another table
  200. create table t1 (id int primary key, data varchar(10), fk int);
  201. create table t2 (event varchar(100));
  202. create table t3 (id int primary key);
  203. create trigger t1_ai after insert on t1 for each row
  204. insert into t2 values (concat("INSERT INTO t1 id=", new.id, " data='", new.data, "'"));
  205. insert into t1 (id, data) values (1, "one"), (2, "two");
  206. select * from t1;
  207. select * from t2;
  208. drop trigger t1_ai;
  209. # Trigger which uses couple of tables (and partially emulates FK constraint)
  210. delimiter |;
  211. create trigger t1_bi before insert on t1 for each row
  212. begin
  213. if exists (select id from t3 where id=new.fk) then
  214. insert into t2 values (concat("INSERT INTO t1 id=", new.id, " data='", new.data, "' fk=", new.fk));
  215. else
  216. insert into t2 values (concat("INSERT INTO t1 FAILED id=", new.id, " data='", new.data, "' fk=", new.fk));
  217. set new.id= NULL;
  218. end if;
  219. end|
  220. delimiter ;|
  221. insert into t3 values (1);
  222. --error ER_BAD_NULL_ERROR
  223. insert into t1 values (4, "four", 1), (5, "five", 2);
  224. select * from t1;
  225. select * from t2;
  226. drop table t1, t2, t3;
  227. # Trigger which invokes function
  228. create table t1 (id int primary key, data varchar(10));
  229. create table t2 (seq int);
  230. insert into t2 values (10);
  231. create function f1 () returns int return (select max(seq) from t2);
  232. delimiter |;
  233. create trigger t1_bi before insert on t1 for each row
  234. begin
  235. if new.id > f1() then
  236. set new.id:= f1();
  237. end if;
  238. end|
  239. delimiter ;|
  240. insert into t1 values (1, "first");
  241. insert into t1 values (f1(), "max");
  242. select * from t1;
  243. drop table t1, t2;
  244. drop function f1;
  245. # Trigger which forces invocation of another trigger
  246. # (emulation of FK on delete cascade policy)
  247. create table t1 (id int primary key, fk_t2 int);
  248. create table t2 (id int primary key, fk_t3 int);
  249. create table t3 (id int primary key);
  250. insert into t1 values (1,1), (2,1), (3,2);
  251. insert into t2 values (1,1), (2,2);
  252. insert into t3 values (1), (2);
  253. create trigger t3_ad after delete on t3 for each row
  254. delete from t2 where fk_t3=old.id;
  255. create trigger t2_ad after delete on t2 for each row
  256. delete from t1 where fk_t2=old.id;
  257. delete from t3 where id = 1;
  258. select * from t1 left join (t2 left join t3 on t2.fk_t3 = t3.id) on t1.fk_t2 = t2.id;
  259. drop table t1, t2, t3;
  260. # Trigger which assigns value selected from table to field of row
  261. # being inserted/updated.
  262. create table t1 (id int primary key, copy int);
  263. create table t2 (id int primary key, data int);
  264. insert into t2 values (1,1), (2,2);
  265. create trigger t1_bi before insert on t1 for each row
  266. set new.copy= (select data from t2 where id = new.id);
  267. create trigger t1_bu before update on t1 for each row
  268. set new.copy= (select data from t2 where id = new.id);
  269. insert into t1 values (1,3), (2,4), (3,3);
  270. update t1 set copy= 1 where id = 2;
  271. select * from t1;
  272. drop table t1, t2;
  273. #
  274. # Test of wrong column specifiers in triggers
  275. #
  276. create table t1 (i int);
  277. create table t3 (i int);
  278. --error ER_TRG_NO_SUCH_ROW_IN_TRG
  279. create trigger trg before insert on t1 for each row set @a:= old.i;
  280. --error ER_TRG_NO_SUCH_ROW_IN_TRG
  281. create trigger trg before delete on t1 for each row set @a:= new.i;
  282. --error ER_TRG_CANT_CHANGE_ROW
  283. create trigger trg before update on t1 for each row set old.i:=1;
  284. --error ER_TRG_NO_SUCH_ROW_IN_TRG
  285. create trigger trg before delete on t1 for each row set new.i:=1;
  286. --error ER_TRG_CANT_CHANGE_ROW
  287. create trigger trg after update on t1 for each row set new.i:=1;
  288. --error ER_BAD_FIELD_ERROR
  289. create trigger trg before update on t1 for each row set new.j:=1;
  290. --error ER_BAD_FIELD_ERROR
  291. create trigger trg before update on t1 for each row set @a:=old.j;
  292. #
  293. # Let us test various trigger creation errors
  294. # Also quickly test table namespace (bug#5892/6182)
  295. #
  296. --error ER_NO_SUCH_TABLE
  297. create trigger trg before insert on t2 for each row set @a:=1;
  298. create trigger trg before insert on t1 for each row set @a:=1;
  299. --error ER_TRG_ALREADY_EXISTS
  300. create trigger trg after insert on t1 for each row set @a:=1;
  301. --error ER_NOT_SUPPORTED_YET
  302. create trigger trg2 before insert on t1 for each row set @a:=1;
  303. --error ER_TRG_ALREADY_EXISTS
  304. create trigger trg before insert on t3 for each row set @a:=1;
  305. create trigger trg2 before insert on t3 for each row set @a:=1;
  306. drop trigger trg2;
  307. drop trigger trg;
  308. --error ER_TRG_DOES_NOT_EXIST
  309. drop trigger trg;
  310. create view v1 as select * from t1;
  311. --error ER_WRONG_OBJECT
  312. create trigger trg before insert on v1 for each row set @a:=1;
  313. drop view v1;
  314. drop table t1;
  315. drop table t3;
  316. create temporary table t1 (i int);
  317. --error ER_TRG_ON_VIEW_OR_TEMP_TABLE
  318. create trigger trg before insert on t1 for each row set @a:=1;
  319. drop table t1;
  320. #
  321. # Tests for various trigger-related bugs
  322. #
  323. # Test for bug #5887 "Triggers with string literals cause errors".
  324. # New .FRM parser was not handling escaped strings properly.
  325. create table t1 (x1col char);
  326. create trigger tx1 before insert on t1 for each row set new.x1col = 'x';
  327. insert into t1 values ('y');
  328. drop trigger tx1;
  329. drop table t1;
  330. #
  331. # Test for bug #5890 "Triggers fail for DELETE without WHERE".
  332. # If we are going to delete all rows in table but DELETE triggers exist
  333. # we should perform row-by-row deletion instead of using optimized
  334. # delete_all_rows() method.
  335. #
  336. create table t1 (i int) engine=myisam;
  337. insert into t1 values (1), (2);
  338. create trigger trg1 before delete on t1 for each row set @del_before:= @del_before + old.i;
  339. create trigger trg2 after delete on t1 for each row set @del_after:= @del_after + old.i;
  340. set @del_before:=0, @del_after:= 0;
  341. delete from t1;
  342. select @del_before, @del_after;
  343. drop trigger trg1;
  344. drop trigger trg2;
  345. drop table t1;
  346. # Test for bug #5859 "DROP TABLE does not drop triggers". Trigger should not
  347. # magically reappear when we recreate dropped table.
  348. create table t1 (a int);
  349. create trigger trg1 before insert on t1 for each row set new.a= 10;
  350. drop table t1;
  351. create table t1 (a int);
  352. insert into t1 values ();
  353. select * from t1;
  354. drop table t1;
  355. # Test for bug #6559 "DROP DATABASE forgets to drop triggers".
  356. create database mysqltest;
  357. use mysqltest;
  358. create table t1 (i int);
  359. create trigger trg1 before insert on t1 for each row set @a:= 1;
  360. # This should succeed
  361. drop database mysqltest;
  362. use test;
  363. # Test for bug #8791
  364. # "Triggers: Allowed to create triggers on a subject table in a different DB".
  365. create database mysqltest;
  366. create table mysqltest.t1 (i int);
  367. --error ER_TRG_IN_WRONG_SCHEMA
  368. create trigger trg1 before insert on mysqltest.t1 for each row set @a:= 1;
  369. use mysqltest;
  370. --error ER_NO_SUCH_TABLE
  371. create trigger test.trg1 before insert on t1 for each row set @a:= 1;
  372. drop database mysqltest;
  373. use test;
  374. # Test for bug #5860 "Multi-table UPDATE does not activate update triggers"
  375. # We will also test how delete triggers wor for multi-table DELETE.
  376. create table t1 (i int, j int default 10, k int not null, key (k));
  377. create table t2 (i int);
  378. insert into t1 (i, k) values (1, 1);
  379. insert into t2 values (1);
  380. create trigger trg1 before update on t1 for each row set @a:= @a + new.j - old.j;
  381. create trigger trg2 after update on t1 for each row set @b:= "Fired";
  382. set @a:= 0, @b:= "";
  383. # Check that trigger works in case of update on the fly
  384. update t1, t2 set j = j + 10 where t1.i = t2.i;
  385. select @a, @b;
  386. insert into t1 values (2, 13, 2);
  387. insert into t2 values (2);
  388. set @a:= 0, @b:= "";
  389. # And now let us check that triggers work in case of multi-update which
  390. # is done through temporary tables...
  391. update t1, t2 set j = j + 15 where t1.i = t2.i and t1.k >= 2;
  392. select @a, @b;
  393. # Let us test delete triggers for multi-delete now.
  394. # We create triggers for both tables because we want test how they
  395. # work in both on-the-fly and via-temp-tables cases.
  396. create trigger trg3 before delete on t1 for each row set @c:= @c + old.j;
  397. create trigger trg4 before delete on t2 for each row set @d:= @d + old.i;
  398. create trigger trg5 after delete on t1 for each row set @e:= "After delete t1 fired";
  399. create trigger trg6 after delete on t2 for each row set @f:= "After delete t2 fired";
  400. set @c:= 0, @d:= 0, @e:= "", @f:= "";
  401. delete t1, t2 from t1, t2 where t1.i = t2.i;
  402. select @c, @d, @e, @f;
  403. # This also will drop triggers
  404. drop table t1, t2;
  405. # Test for bug #6812 "Triggers are not activated for INSERT ... SELECT".
  406. # (We also check the fact that trigger modifies some field does not affect
  407. # value of next record inserted).
  408. delimiter |;
  409. create table t1 (i int, j int default 10)|
  410. create table t2 (i int)|
  411. insert into t2 values (1), (2)|
  412. create trigger trg1 before insert on t1 for each row
  413. begin
  414. if new.i = 1 then
  415. set new.j := 1;
  416. end if;
  417. end|
  418. create trigger trg2 after insert on t1 for each row set @a:= 1|
  419. set @a:= 0|
  420. insert into t1 (i) select * from t2|
  421. select * from t1|
  422. select @a|
  423. # This also will drop triggers
  424. drop table t1, t2|
  425. delimiter ;|
  426. # Test for bug #8755 "Trigger is not activated by LOAD DATA"
  427. create table t1 (i int, j int, k int);
  428. create trigger trg1 before insert on t1 for each row set new.k = new.i;
  429. create trigger trg2 after insert on t1 for each row set @b:= "Fired";
  430. set @b:="";
  431. # Test triggers with file with separators
  432. load data infile '../std_data_ln/rpl_loaddata.dat' into table t1 (@a, i);
  433. select *, @b from t1;
  434. set @b:="";
  435. # Test triggers with fixed size row file
  436. load data infile '../std_data_ln/loaddata5.dat' into table t1 fields terminated by '' enclosed by '' (i, j);
  437. select *, @b from t1;
  438. # This also will drop triggers
  439. drop table t1;
  440. # Test for bug #5894 "Triggers with altered tables cause corrupt databases"
  441. # Also tests basic error handling for various kinds of triggers.
  442. create table t1 (i int, at int, k int, key(k)) engine=myisam;
  443. create table t2 (i int);
  444. insert into t1 values (1, 1, 1);
  445. # We need at least 3 elements in t2 to test multi-update properly
  446. insert into t2 values (1), (2), (3);
  447. # Create and then break "after" triggers
  448. create trigger ai after insert on t1 for each row set @a:= new.at;
  449. create trigger au after update on t1 for each row set @a:= new.at;
  450. create trigger ad after delete on t1 for each row set @a:= old.at;
  451. alter table t1 drop column at;
  452. # We still should be able select data from tables.
  453. select * from t1;
  454. # The following statements changing t1 should fail, but still cause
  455. # their main effect. This is because operation on the table row is
  456. # executed before "after" trigger and its effect cannot be rolled back
  457. # when whole statement fails, because t1 is MyISAM table.
  458. --error ER_BAD_FIELD_ERROR
  459. insert into t1 values (2, 1);
  460. select * from t1;
  461. --error ER_BAD_FIELD_ERROR
  462. update t1 set k = 2 where i = 2;
  463. select * from t1;
  464. --error ER_BAD_FIELD_ERROR
  465. delete from t1 where i = 2;
  466. select * from t1;
  467. # Should fail and insert only 1 row
  468. --error ER_BAD_FIELD_ERROR
  469. load data infile '../std_data_ln/loaddata5.dat' into table t1 fields terminated by '' enclosed by '' (i, k);
  470. select * from t1;
  471. --error ER_BAD_FIELD_ERROR
  472. insert into t1 select 3, 3;
  473. select * from t1;
  474. # Multi-update working on the fly, again it will update only
  475. # one row even if more matches
  476. --error ER_BAD_FIELD_ERROR
  477. update t1, t2 set k = k + 10 where t1.i = t2.i;
  478. select * from t1;
  479. # The same for multi-update via temp table
  480. --error ER_BAD_FIELD_ERROR
  481. update t1, t2 set k = k + 10 where t1.i = t2.i and k < 3;
  482. select * from t1;
  483. # Multi-delete on the fly
  484. --error ER_BAD_FIELD_ERROR
  485. delete t1, t2 from t1 straight_join t2 where t1.i = t2.i;
  486. select * from t1;
  487. # And via temporary storage
  488. --error ER_BAD_FIELD_ERROR
  489. delete t2, t1 from t2 straight_join t1 where t1.i = t2.i;
  490. select * from t1;
  491. # Prepare table for testing of REPLACE and INSERT ... ON DUPLICATE KEY UPDATE
  492. alter table t1 add primary key (i);
  493. --error ER_BAD_FIELD_ERROR
  494. insert into t1 values (3, 4) on duplicate key update k= k + 10;
  495. select * from t1;
  496. # The following statement will delete old row and won't
  497. # insert new one since after delete trigger will fail.
  498. --error ER_BAD_FIELD_ERROR
  499. replace into t1 values (3, 3);
  500. select * from t1;
  501. # Also drops all triggers
  502. drop table t1, t2;
  503. create table t1 (i int, bt int, k int, key(k)) engine=myisam;
  504. create table t2 (i int);
  505. insert into t1 values (1, 1, 1), (2, 2, 2);
  506. insert into t2 values (1), (2), (3);
  507. # Create and then break "before" triggers
  508. create trigger bi before insert on t1 for each row set @a:= new.bt;
  509. create trigger bu before update on t1 for each row set @a:= new.bt;
  510. create trigger bd before delete on t1 for each row set @a:= old.bt;
  511. alter table t1 drop column bt;
  512. # The following statements changing t1 should fail and should not
  513. # cause any effect on table, since "before" trigger is executed
  514. # before operation on the table row.
  515. --error ER_BAD_FIELD_ERROR
  516. insert into t1 values (3, 3);
  517. select * from t1;
  518. --error ER_BAD_FIELD_ERROR
  519. update t1 set i = 2;
  520. select * from t1;
  521. --error ER_BAD_FIELD_ERROR
  522. delete from t1;
  523. select * from t1;
  524. --error ER_BAD_FIELD_ERROR
  525. load data infile '../std_data_ln/loaddata5.dat' into table t1 fields terminated by '' enclosed by '' (i, k);
  526. select * from t1;
  527. --error ER_BAD_FIELD_ERROR
  528. insert into t1 select 3, 3;
  529. select * from t1;
  530. # Both types of multi-update (on the fly and via temp table)
  531. --error ER_BAD_FIELD_ERROR
  532. update t1, t2 set k = k + 10 where t1.i = t2.i;
  533. select * from t1;
  534. --error ER_BAD_FIELD_ERROR
  535. update t1, t2 set k = k + 10 where t1.i = t2.i and k < 2;
  536. select * from t1;
  537. # Both types of multi-delete
  538. --error ER_BAD_FIELD_ERROR
  539. delete t1, t2 from t1 straight_join t2 where t1.i = t2.i;
  540. select * from t1;
  541. --error ER_BAD_FIELD_ERROR
  542. delete t2, t1 from t2 straight_join t1 where t1.i = t2.i;
  543. select * from t1;
  544. # Let us test REPLACE/INSERT ... ON DUPLICATE KEY UPDATE.
  545. # To test properly code-paths different from those that are used
  546. # in ordinary INSERT we need to drop "before insert" trigger.
  547. alter table t1 add primary key (i);
  548. drop trigger bi;
  549. --error ER_BAD_FIELD_ERROR
  550. insert into t1 values (2, 4) on duplicate key update k= k + 10;
  551. select * from t1;
  552. --error ER_BAD_FIELD_ERROR
  553. replace into t1 values (2, 4);
  554. select * from t1;
  555. # Also drops all triggers
  556. drop table t1, t2;
  557. # Test for bug #5893 "Triggers with dropped functions cause crashes"
  558. # Appropriate error should be reported instead of crash.
  559. # Also test for bug #11889 "Server crashes when dropping trigger
  560. # using stored routine".
  561. --disable_warnings
  562. drop function if exists bug5893;
  563. --enable_warnings
  564. create table t1 (col1 int, col2 int);
  565. insert into t1 values (1, 2);
  566. create function bug5893 () returns int return 5;
  567. create trigger t1_bu before update on t1 for each row set new.col1= bug5893();
  568. drop function bug5893;
  569. --error ER_SP_DOES_NOT_EXIST
  570. update t1 set col2 = 4;
  571. # This should not crash server too.
  572. drop trigger t1_bu;
  573. drop table t1;
  574. #
  575. # storing and restoring parsing modes for triggers (BUG#5891)
  576. #
  577. set sql_mode='ansi';
  578. create table t1 ("t1 column" int);
  579. create trigger t1_bi before insert on t1 for each row set new."t1 column" = 5;
  580. set sql_mode="";
  581. insert into t1 values (0);
  582. # create trigger with different sql_mode
  583. create trigger t1_af after insert on t1 for each row set @a=10;
  584. insert into t1 values (0);
  585. select * from t1;
  586. select @a;
  587. --replace_column 6 #
  588. show triggers;
  589. drop table t1;
  590. # check that rigger preserve sql_mode during execution
  591. set sql_mode="traditional";
  592. create table t1 (a date);
  593. -- error 1292
  594. insert into t1 values ('2004-01-00');
  595. set sql_mode="";
  596. create trigger t1_bi before insert on t1 for each row set new.a = '2004-01-00';
  597. set sql_mode="traditional";
  598. insert into t1 values ('2004-01-01');
  599. select * from t1;
  600. set sql_mode=default;
  601. show create table t1;
  602. --replace_column 6 #
  603. show triggers;
  604. drop table t1;
  605. # Test for bug #12280 "Triggers: crash if flush tables"
  606. # FLUSH TABLES and FLUSH PRIVILEGES should be disallowed inside
  607. # of functions and triggers.
  608. create table t1 (id int);
  609. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  610. create trigger t1_ai after insert on t1 for each row reset query cache;
  611. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  612. create trigger t1_ai after insert on t1 for each row reset master;
  613. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  614. create trigger t1_ai after insert on t1 for each row reset slave;
  615. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  616. create trigger t1_ai after insert on t1 for each row flush hosts;
  617. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  618. create trigger t1_ai after insert on t1 for each row flush tables with read lock;
  619. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  620. create trigger t1_ai after insert on t1 for each row flush logs;
  621. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  622. create trigger t1_ai after insert on t1 for each row flush status;
  623. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  624. create trigger t1_ai after insert on t1 for each row flush slave;
  625. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  626. create trigger t1_ai after insert on t1 for each row flush master;
  627. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  628. create trigger t1_ai after insert on t1 for each row flush des_key_file;
  629. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  630. create trigger t1_ai after insert on t1 for each row flush user_resources;
  631. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  632. create trigger t1_ai after insert on t1 for each row flush tables;
  633. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  634. create trigger t1_ai after insert on t1 for each row flush privileges;
  635. --disable_warnings
  636. drop procedure if exists p1;
  637. --enable_warnings
  638. create trigger t1_ai after insert on t1 for each row call p1();
  639. create procedure p1() flush tables;
  640. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  641. insert into t1 values (0);
  642. drop procedure p1;
  643. create procedure p1() reset query cache;
  644. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  645. insert into t1 values (0);
  646. drop procedure p1;
  647. create procedure p1() reset master;
  648. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  649. insert into t1 values (0);
  650. drop procedure p1;
  651. create procedure p1() reset slave;
  652. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  653. insert into t1 values (0);
  654. drop procedure p1;
  655. create procedure p1() flush hosts;
  656. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  657. insert into t1 values (0);
  658. drop procedure p1;
  659. create procedure p1() flush privileges;
  660. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  661. insert into t1 values (0);
  662. drop procedure p1;
  663. create procedure p1() flush tables with read lock;
  664. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  665. insert into t1 values (0);
  666. drop procedure p1;
  667. create procedure p1() flush tables;
  668. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  669. insert into t1 values (0);
  670. drop procedure p1;
  671. create procedure p1() flush logs;
  672. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  673. insert into t1 values (0);
  674. drop procedure p1;
  675. create procedure p1() flush status;
  676. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  677. insert into t1 values (0);
  678. drop procedure p1;
  679. create procedure p1() flush slave;
  680. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  681. insert into t1 values (0);
  682. drop procedure p1;
  683. create procedure p1() flush master;
  684. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  685. insert into t1 values (0);
  686. drop procedure p1;
  687. create procedure p1() flush des_key_file;
  688. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  689. insert into t1 values (0);
  690. drop procedure p1;
  691. create procedure p1() flush user_resources;
  692. --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
  693. insert into t1 values (0);
  694. drop procedure p1;
  695. drop table t1;
  696. # Test for bug #11973 "SELECT .. INTO var_name; in trigger cause
  697. # crash on update"
  698. create table t1 (id int, data int, username varchar(16));
  699. insert into t1 (id, data) values (1, 0);
  700. delimiter |;
  701. create trigger t1_whoupdated before update on t1 for each row
  702. begin
  703. declare user varchar(32);
  704. declare i int;
  705. select user() into user;
  706. set NEW.username = user;
  707. select count(*) from ((select 1) union (select 2)) as d1 into i;
  708. end|
  709. delimiter ;|
  710. update t1 set data = 1;
  711. connection addconroot1;
  712. update t1 set data = 2;
  713. connection default;
  714. drop table t1;
  715. #
  716. # #11587 Trigger causes lost connection error
  717. #
  718. create table t1 (c1 int, c2 datetime);
  719. delimiter |;
  720. --error ER_SP_NO_RETSET
  721. create trigger tr1 before insert on t1 for each row
  722. begin
  723. set new.c2= '2004-04-01';
  724. select 'hello';
  725. end|
  726. delimiter ;|
  727. insert into t1 (c1) values (1),(2),(3);
  728. select * from t1;
  729. --disable_warnings
  730. drop procedure if exists bug11587;
  731. --enable_warnings
  732. delimiter |;
  733. create procedure bug11587(x char(16))
  734. begin
  735. select "hello";
  736. select "hello again";
  737. end|
  738. create trigger tr1 before insert on t1 for each row
  739. begin
  740. call bug11587();
  741. set new.c2= '2004-04-02';
  742. end|
  743. delimiter ;|
  744. --error ER_SP_NO_RETSET
  745. insert into t1 (c1) values (4),(5),(6);
  746. select * from t1;
  747. drop procedure bug11587;
  748. drop table t1;
  749. # Test for bug #11896 "Partial locking in case of recursive trigger
  750. # definitions". Recursion in triggers should not be allowed.
  751. # We also should not allow to change tables which are used in
  752. # statements invoking this trigger.
  753. create table t1 (f1 integer);
  754. create table t2 (f2 integer);
  755. create trigger t1_ai after insert on t1
  756. for each row insert into t2 values (new.f1+1);
  757. create trigger t2_ai after insert on t2
  758. for each row insert into t1 values (new.f2+1);
  759. # Allow SP resursion to be show that it has not influence here
  760. set @SAVE_SP_RECURSION_LEVELS=@@max_sp_recursion_depth;
  761. set @@max_sp_recursion_depth=100;
  762. --error ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG
  763. insert into t1 values (1);
  764. set @@max_sp_recursion_depth=@SAVE_SP_RECURSION_LEVELS;
  765. select * from t1;
  766. select * from t2;
  767. drop trigger t1_ai;
  768. drop trigger t2_ai;
  769. create trigger t1_bu before update on t1
  770. for each row insert into t1 values (2);
  771. --error ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG
  772. update t1 set f1= 10;
  773. select * from t1;
  774. drop trigger t1_bu;
  775. create trigger t1_bu before update on t1
  776. for each row delete from t1 where f1=new.f1;
  777. --error ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG
  778. update t1 set f1= 10;
  779. select * from t1;
  780. drop trigger t1_bu;
  781. # This should work tough
  782. create trigger t1_bi before insert on t1
  783. for each row set new.f1=(select sum(f1) from t1);
  784. insert into t1 values (3);
  785. select * from t1;
  786. drop trigger t1_bi;
  787. drop tables t1, t2;
  788. # Tests for bug #12704 "Server crashes during trigger execution".
  789. # If we run DML statements and CREATE TRIGGER statements concurrently
  790. # it may happen that trigger will be created while DML statement is
  791. # waiting for table lock. In this case we have to reopen tables and
  792. # recalculate prelocking set.
  793. # Unfortunately these tests rely on the order in which tables are locked
  794. # by statement so they are non determenistic and are disabled.
  795. --disable_parsing
  796. create table t1 (id int);
  797. create table t2 (id int);
  798. create table t3 (id int);
  799. create function f1() returns int return (select max(id)+2 from t2);
  800. create view v1 as select f1() as f;
  801. # Let us check that we notice trigger at all
  802. connection addconroot1;
  803. lock tables t2 write;
  804. connection default;
  805. send insert into t1 values ((select max(id) from t2)), (2);
  806. --sleep 1
  807. connection addconroot2;
  808. create trigger t1_trg before insert on t1 for each row set NEW.id:= 1;
  809. connection addconroot1;
  810. unlock tables;
  811. connection default;
  812. reap;
  813. select * from t1;
  814. # Check that we properly calculate new prelocking set
  815. insert into t2 values (3);
  816. connection addconroot1;
  817. lock tables t2 write;
  818. connection default;
  819. send insert into t1 values ((select max(id) from t2)), (4);
  820. --sleep 1
  821. connection addconroot2;
  822. drop trigger t1_trg;
  823. create trigger t1_trg before insert on t1 for each row
  824. insert into t3 values (new.id);
  825. connection addconroot1;
  826. unlock tables;
  827. connection default;
  828. reap;
  829. select * from t1;
  830. select * from t3;
  831. # We should be able to do this even if fancy views are involved
  832. connection addconroot1;
  833. lock tables t2 write;
  834. connection default;
  835. send insert into t1 values ((select max(f) from v1)), (6);
  836. --sleep 1
  837. connection addconroot2;
  838. drop trigger t1_trg;
  839. create trigger t1_trg before insert on t1 for each row
  840. insert into t3 values (new.id + 100);
  841. connection addconroot1;
  842. unlock tables;
  843. connection default;
  844. reap;
  845. select * from t1;
  846. select * from t3;
  847. # This also should work for multi-update
  848. # Let us drop trigger to demonstrate that prelocking set is really
  849. # rebuilt
  850. drop trigger t1_trg;
  851. connection addconroot1;
  852. lock tables t2 write;
  853. connection default;
  854. send update t1, t2 set t1.id=10 where t1.id=t2.id;
  855. --sleep 1
  856. connection addconroot2;
  857. create trigger t1_trg before update on t1 for each row
  858. insert into t3 values (new.id);
  859. connection addconroot1;
  860. unlock tables;
  861. connection default;
  862. reap;
  863. select * from t1;
  864. select * from t3;
  865. # And even for multi-update converted from ordinary update thanks to view
  866. drop view v1;
  867. drop trigger t1_trg;
  868. create view v1 as select t1.id as id1 from t1, t2 where t1.id= t2.id;
  869. insert into t2 values (10);
  870. connection addconroot1;
  871. lock tables t2 write;
  872. connection default;
  873. send update v1 set id1= 11;
  874. --sleep 1
  875. connection addconroot2;
  876. create trigger t1_trg before update on t1 for each row
  877. insert into t3 values (new.id + 100);
  878. connection addconroot1;
  879. unlock tables;
  880. connection default;
  881. reap;
  882. select * from t1;
  883. select * from t3;
  884. drop function f1;
  885. drop view v1;
  886. drop table t1, t2, t3;
  887. --enable_parsing
  888. #
  889. # Test for bug #13399 "Crash when executing PS/SP which should activate
  890. # trigger which is now dropped". See also test for similar bug for stored
  891. # routines in sp-error.test (#12329).
  892. create table t1 (id int);
  893. create table t2 (id int);
  894. create trigger t1_bi before insert on t1 for each row insert into t2 values (new.id);
  895. prepare stmt1 from "insert into t1 values (10)";
  896. create procedure p1() insert into t1 values (10);
  897. call p1();
  898. # Actually it is enough to do FLUSH TABLES instead of DROP TRIGGER
  899. drop trigger t1_bi;
  900. # Server should not crash on these two statements
  901. execute stmt1;
  902. call p1();
  903. deallocate prepare stmt1;
  904. drop procedure p1;
  905. # Let us test more complex situation when we alter trigger in such way that
  906. # it uses different set of tables (or simply add new trigger).
  907. create table t3 (id int);
  908. create trigger t1_bi after insert on t1 for each row insert into t2 values (new.id);
  909. prepare stmt1 from "insert into t1 values (10)";
  910. create procedure p1() insert into t1 values (10);
  911. call p1();
  912. # Altering trigger forcing it use different set of tables
  913. drop trigger t1_bi;
  914. create trigger t1_bi after insert on t1 for each row insert into t3 values (new.id);
  915. # Until we implement proper mechanism for invalidation of PS/SP when table
  916. # or SP's are changed these two statements will fail with 'Table ... was
  917. # not locked' error (this mechanism should be based on the new TDC).
  918. --error ER_NO_SUCH_TABLE
  919. execute stmt1;
  920. --error ER_NO_SUCH_TABLE
  921. call p1();
  922. deallocate prepare stmt1;
  923. drop procedure p1;
  924. drop table t1, t2, t3;
  925. #
  926. # BUG#13549 "Server crash with nested stored procedures".
  927. # Server should not crash when during execution of stored procedure
  928. # we have to parse trigger/function definition and this new trigger/
  929. # function has more local variables declared than invoking stored
  930. # procedure and last of these variables is used in argument of NOT
  931. # operator.
  932. #
  933. create table t1 (a int);
  934. DELIMITER //;
  935. CREATE PROCEDURE `p1`()
  936. begin
  937. insert into t1 values (1);
  938. end//
  939. create trigger trg before insert on t1 for each row
  940. begin
  941. declare done int default 0;
  942. set done= not done;
  943. end//
  944. DELIMITER ;//
  945. CALL p1();
  946. drop procedure p1;
  947. drop table t1;
  948. #
  949. # Test for bug #14863 "Triggers: crash if create and there is no current
  950. # database". We should not crash and give proper error when database for
  951. # trigger or its table is not specified and there is no current database.
  952. #
  953. connection addconwithoutdb;
  954. --error ER_NO_DB_ERROR
  955. create trigger t1_bi before insert on test.t1 for each row set @a:=0;
  956. --error ER_NO_SUCH_TABLE
  957. create trigger test.t1_bi before insert on t1 for each row set @a:=0;
  958. --error ER_NO_DB_ERROR
  959. drop trigger t1_bi;
  960. connection default;
  961. #
  962. # Tests for bug #13525 "Rename table does not keep info of triggers"
  963. # and bug #17866 "Problem with renaming table with triggers with fully
  964. # qualified subject table".
  965. #
  966. create table t1 (id int);
  967. create trigger t1_bi before insert on t1 for each row set @a:=new.id;
  968. create trigger t1_ai after insert on test.t1 for each row set @b:=new.id;
  969. insert into t1 values (101);
  970. select @a, @b;
  971. select trigger_schema, trigger_name, event_object_schema,
  972. event_object_table, action_statement from information_schema.triggers
  973. where event_object_schema = 'test';
  974. rename table t1 to t2;
  975. # Trigger should work after rename
  976. insert into t2 values (102);
  977. select @a, @b;
  978. select trigger_schema, trigger_name, event_object_schema,
  979. event_object_table, action_statement from information_schema.triggers
  980. where event_object_schema = 'test';
  981. # Let us check that the same works for simple ALTER TABLE ... RENAME
  982. alter table t2 rename to t3;
  983. insert into t3 values (103);
  984. select @a, @b;
  985. select trigger_schema, trigger_name, event_object_schema,
  986. event_object_table, action_statement from information_schema.triggers
  987. where event_object_schema = 'test';
  988. # And for more complex ALTER TABLE
  989. alter table t3 rename to t4, add column val int default 0;
  990. insert into t4 values (104, 1);
  991. select @a, @b;
  992. select trigger_schema, trigger_name, event_object_schema,
  993. event_object_table, action_statement from information_schema.triggers
  994. where event_object_schema = 'test';
  995. # .TRN file should be updated with new table name
  996. drop trigger t1_bi;
  997. drop trigger t1_ai;
  998. drop table t4;
  999. # Rename between different databases if triggers exist should fail
  1000. create database mysqltest;
  1001. use mysqltest;
  1002. create table t1 (id int);
  1003. create trigger t1_bi before insert on t1 for each row set @a:=new.id;
  1004. insert into t1 values (101);
  1005. select @a;
  1006. select trigger_schema, trigger_name, event_object_schema,
  1007. event_object_table, action_statement from information_schema.triggers
  1008. where event_object_schema = 'test' or event_object_schema = 'mysqltest';
  1009. --error ER_TRG_IN_WRONG_SCHEMA
  1010. rename table t1 to test.t2;
  1011. insert into t1 values (102);
  1012. select @a;
  1013. select trigger_schema, trigger_name, event_object_schema,
  1014. event_object_table, action_statement from information_schema.triggers
  1015. where event_object_schema = 'test' or event_object_schema = 'mysqltest';
  1016. # There should be no fantom .TRN files
  1017. --error ER_TRG_DOES_NOT_EXIST
  1018. drop trigger test.t1_bi;
  1019. # Let us also check handling of this restriction in ALTER TABLE ... RENAME
  1020. --error ER_TRG_IN_WRONG_SCHEMA
  1021. alter table t1 rename to test.t1;
  1022. insert into t1 values (103);
  1023. select @a;
  1024. select trigger_schema, trigger_name, event_object_schema,
  1025. event_object_table, action_statement from information_schema.triggers
  1026. where event_object_schema = 'test' or event_object_schema = 'mysqltest';
  1027. # Again there should be no fantom .TRN files
  1028. --error ER_TRG_DOES_NOT_EXIST
  1029. drop trigger test.t1_bi;
  1030. --error ER_TRG_IN_WRONG_SCHEMA
  1031. alter table t1 rename to test.t1, add column val int default 0;
  1032. insert into t1 values (104);
  1033. select @a;
  1034. select trigger_schema, trigger_name, event_object_schema,
  1035. event_object_table, action_statement from information_schema.triggers
  1036. where event_object_schema = 'test' or event_object_schema = 'mysqltest';
  1037. # Table definition should not change
  1038. show create table t1;
  1039. # And once again check for fantom .TRN files
  1040. --error ER_TRG_DOES_NOT_EXIST
  1041. drop trigger test.t1_bi;
  1042. drop trigger t1_bi;
  1043. drop table t1;
  1044. drop database mysqltest;
  1045. use test;
  1046. # And now let us check that the properly handle rename if there is some
  1047. # error during it (that we rollback such renames completely).
  1048. create table t1 (id int);
  1049. create trigger t1_bi before insert on t1 for each row set @a:=new.id;
  1050. create trigger t1_ai after insert on t1 for each row set @b:=new.id;
  1051. insert into t1 values (101);
  1052. select @a, @b;
  1053. select trigger_schema, trigger_name, event_object_schema,
  1054. event_object_table, action_statement from information_schema.triggers
  1055. where event_object_schema = 'test';
  1056. # Trick which makes update of second .TRN file impossible
  1057. write_file $MYSQLTEST_VARDIR/master-data/test/t1_ai.TRN~;
  1058. dummy
  1059. EOF
  1060. chmod 0000 $MYSQLTEST_VARDIR/master-data/test/t1_ai.TRN~;
  1061. --replace_result $MYSQLTEST_VARDIR . master-data/ ''
  1062. --error 1
  1063. rename table t1 to t2;
  1064. # 't1' should be still there and triggers should work correctly
  1065. insert into t1 values (102);
  1066. select @a, @b;
  1067. select trigger_schema, trigger_name, event_object_schema,
  1068. event_object_table, action_statement from information_schema.triggers
  1069. where event_object_schema = 'test';
  1070. chmod 0600 $MYSQLTEST_VARDIR/master-data/test/t1_ai.TRN~;
  1071. remove_file $MYSQLTEST_VARDIR/master-data/test/t1_ai.TRN~;
  1072. # Let us check that updates to .TRN files were rolled back too
  1073. drop trigger t1_bi;
  1074. drop trigger t1_ai;
  1075. drop table t1;
  1076. # Test for bug #16829 "Firing trigger with RETURN crashes the server"
  1077. # RETURN is not supposed to be used anywhere except functions, so error
  1078. # should be returned when one attempts to create trigger with RETURN.
  1079. create table t1 (i int);
  1080. --error ER_SP_BADRETURN
  1081. create trigger t1_bi before insert on t1 for each row return 0;
  1082. insert into t1 values (1);
  1083. drop table t1;
  1084. # Test for bug #17764 "Trigger crashes MyISAM table"
  1085. #
  1086. # Table was reported as crashed when it was subject table of trigger invoked
  1087. # by insert statement which was executed with enabled bulk insert mode (which
  1088. # is actually set of optimizations enabled by handler::start_bulk_insert())
  1089. # and this trigger also explicitly referenced it.
  1090. # The same problem arose when table to which bulk insert was done was also
  1091. # referenced in function called by insert statement.
  1092. create table t1 (a varchar(64), b int);
  1093. create table t2 like t1;
  1094. create trigger t1_ai after insert on t1 for each row
  1095. set @a:= (select max(a) from t1);
  1096. insert into t1 (a) values
  1097. ("Twas"),("brillig"),("and"),("the"),("slithy"),("toves"),
  1098. ("Did"),("gyre"),("and"),("gimble"),("in"),("the"),("wabe");
  1099. create trigger t2_ai after insert on t2 for each row
  1100. set @a:= (select max(a) from t2);
  1101. insert into t2 select * from t1;
  1102. load data infile '../std_data_ln/words.dat' into table t1 (a);
  1103. drop trigger t1_ai;
  1104. drop trigger t2_ai;
  1105. # Test that the problem for functions is fixed as well
  1106. create function f1() returns int return (select max(b) from t1);
  1107. insert into t1 values
  1108. ("All",f1()),("mimsy",f1()),("were",f1()),("the",f1()),("borogoves",f1()),
  1109. ("And",f1()),("the",f1()),("mome", f1()),("raths",f1()),("outgrabe",f1());
  1110. create function f2() returns int return (select max(b) from t2);
  1111. insert into t2 select a, f2() from t1;
  1112. load data infile '../std_data_ln/words.dat' into table t1 (a) set b:= f1();
  1113. drop table t1, t2;
  1114. drop function f1;
  1115. drop function f2;
  1116. #
  1117. # Test for bug #16021 "Wrong index given to function in trigger" which
  1118. # was caused by the same bulk insert optimization as bug #17764 but had
  1119. # slightly different symptoms (instead of reporting table as crashed
  1120. # storage engine reported error number 124)
  1121. #
  1122. create table t1(i int not null, j int not null, n numeric(15,2), primary key(i,j));
  1123. create table t2(i int not null, n numeric(15,2), primary key(i));
  1124. delimiter |;
  1125. create trigger t1_ai after insert on t1 for each row
  1126. begin
  1127. declare sn numeric(15,2);
  1128. select sum(n) into sn from t1 where i=new.i;
  1129. replace into t2 values(new.i, sn);
  1130. end|
  1131. delimiter ;|
  1132. insert into t1 values
  1133. (1,1,10.00),(1,2,10.00),(1,3,10.00),(1,4,10.00),(1,5,10.00),
  1134. (1,6,10.00),(1,7,10.00),(1,8,10.00),(1,9,10.00),(1,10,10.00),
  1135. (1,11,10.00),(1,12,10.00),(1,13,10.00),(1,14,10.00),(1,15,10.00);
  1136. select * from t1;
  1137. select * from t2;
  1138. drop tables t1, t2;
  1139. #
  1140. # Test for Bug #16461 connection_id() does not work properly inside trigger
  1141. #
  1142. --disable_warnings
  1143. DROP TABLE IF EXISTS t1;
  1144. --enable_warnings
  1145. CREATE TABLE t1 (
  1146. conn_id INT,
  1147. trigger_conn_id INT
  1148. );
  1149. CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
  1150. SET NEW.trigger_conn_id = CONNECTION_ID();
  1151. INSERT INTO t1 (conn_id, trigger_conn_id) VALUES (CONNECTION_ID(), -1);
  1152. connect (con1,localhost,root,,);
  1153. INSERT INTO t1 (conn_id, trigger_conn_id) VALUES (CONNECTION_ID(), -1);
  1154. connection default;
  1155. disconnect con1;
  1156. SELECT * FROM t1 WHERE conn_id != trigger_conn_id;
  1157. DROP TRIGGER t1_bi;
  1158. DROP TABLE t1;
  1159. #
  1160. # Bug#6951: Triggers/Traditional: SET @ result wrong
  1161. #
  1162. --disable_warnings
  1163. DROP TABLE IF EXISTS t1;
  1164. --enable_warnings
  1165. CREATE TABLE t1 (i1 INT);
  1166. SET @save_sql_mode=@@sql_mode;
  1167. SET SQL_MODE='';
  1168. CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
  1169. SET @x = 5/0;
  1170. SET SQL_MODE='traditional';
  1171. CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
  1172. SET @x = 5/0;
  1173. SET @x=1;
  1174. INSERT INTO t1 VALUES (@x);
  1175. SELECT @x;
  1176. SET @x=2;
  1177. UPDATE t1 SET i1 = @x;
  1178. SELECT @x;
  1179. SET SQL_MODE='';
  1180. SET @x=3;
  1181. INSERT INTO t1 VALUES (@x);
  1182. SELECT @x;
  1183. SET @x=4;
  1184. UPDATE t1 SET i1 = @x;
  1185. SELECT @x;
  1186. SET @@sql_mode=@save_sql_mode;
  1187. DROP TRIGGER t1_ai;
  1188. DROP TRIGGER t1_au;
  1189. DROP TABLE t1;
  1190. #
  1191. # Test for bug #14635 Accept NEW.x as INOUT parameters to stored
  1192. # procedures from within triggers
  1193. #
  1194. --disable_warnings
  1195. DROP TABLE IF EXISTS t1;
  1196. DROP PROCEDURE IF EXISTS p1;
  1197. DROP PROCEDURE IF EXISTS p2;
  1198. --enable_warnings
  1199. CREATE TABLE t1 (i1 INT);
  1200. # Check that NEW.x pseudo variable is accepted as INOUT and OUT
  1201. # parameter to stored routine.
  1202. INSERT INTO t1 VALUES (3);
  1203. CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET i1 = 5;
  1204. CREATE PROCEDURE p2(INOUT i1 INT) DETERMINISTIC NO SQL SET i1 = i1 * 7;
  1205. delimiter //;
  1206. CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
  1207. BEGIN
  1208. CALL p1(NEW.i1);
  1209. CALL p2(NEW.i1);
  1210. END//
  1211. delimiter ;//
  1212. UPDATE t1 SET i1 = 11 WHERE i1 = 3;
  1213. DROP TRIGGER t1_bu;
  1214. DROP PROCEDURE p2;
  1215. DROP PROCEDURE p1;
  1216. # Check that OLD.x pseudo variable is not accepted as INOUT and OUT
  1217. # parameter to stored routine.
  1218. INSERT INTO t1 VALUES (13);
  1219. CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET @a = 17;
  1220. CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
  1221. CALL p1(OLD.i1);
  1222. --error ER_SP_NOT_VAR_ARG
  1223. UPDATE t1 SET i1 = 19 WHERE i1 = 13;
  1224. DROP TRIGGER t1_bu;
  1225. DROP PROCEDURE p1;
  1226. INSERT INTO t1 VALUES (23);
  1227. CREATE PROCEDURE p1(INOUT i1 INT) DETERMINISTIC NO SQL SET @a = i1 * 29;
  1228. CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
  1229. CALL p1(OLD.i1);
  1230. --error ER_SP_NOT_VAR_ARG
  1231. UPDATE t1 SET i1 = 31 WHERE i1 = 23;
  1232. DROP TRIGGER t1_bu;
  1233. DROP PROCEDURE p1;
  1234. # Check that NEW.x pseudo variable is read-only in the AFTER TRIGGER.
  1235. INSERT INTO t1 VALUES (37);
  1236. CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET @a = 41;
  1237. CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
  1238. CALL p1(NEW.i1);
  1239. --error ER_SP_NOT_VAR_ARG
  1240. UPDATE t1 SET i1 = 43 WHERE i1 = 37;
  1241. DROP TRIGGER t1_au;
  1242. DROP PROCEDURE p1;
  1243. INSERT INTO t1 VALUES (47);
  1244. CREATE PROCEDURE p1(INOUT i1 INT) DETERMINISTIC NO SQL SET @a = i1 * 49;
  1245. CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
  1246. CALL p1(NEW.i1);
  1247. --error ER_SP_NOT_VAR_ARG
  1248. UPDATE t1 SET i1 = 51 WHERE i1 = 47;
  1249. DROP TRIGGER t1_au;
  1250. DROP PROCEDURE p1;
  1251. # Post requisite.
  1252. SELECT * FROM t1;
  1253. DROP TABLE t1;
  1254. #
  1255. # Bug #18005: Creating a trigger on mysql.event leads to server crash on
  1256. # scheduler startup
  1257. #
  1258. # Bug #18361: Triggers on mysql.user table cause server crash
  1259. #
  1260. # We don't allow triggers on the mysql schema
  1261. delimiter |;
  1262. --error ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA
  1263. create trigger wont_work after update on mysql.user for each row
  1264. begin
  1265. set @a:= 1;
  1266. end|
  1267. # Try when we're already using the mysql schema
  1268. use mysql|
  1269. --error ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA
  1270. create trigger wont_work after update on event for each row
  1271. begin
  1272. set @a:= 1;
  1273. end|
  1274. use test|
  1275. delimiter ;|
  1276. #
  1277. # Test for BUG#16899: Possible buffer overflow in handling of DEFINER-clause.
  1278. #
  1279. # Prepare.
  1280. --disable_warnings
  1281. DROP TABLE IF EXISTS t1;
  1282. DROP TABLE IF EXISTS t2;
  1283. --enable_warnings
  1284. CREATE TABLE t1(c INT);
  1285. CREATE TABLE t2(c INT);
  1286. --error ER_WRONG_STRING_LENGTH
  1287. CREATE DEFINER=1234567890abcdefGHIKL@localhost
  1288. TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1;
  1289. --error ER_WRONG_STRING_LENGTH
  1290. CREATE DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY
  1291. TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW SET @a = 2;
  1292. # Cleanup.
  1293. DROP TABLE t1;
  1294. DROP TABLE t2;
  1295. #
  1296. # Bug#20028 Function with select return no data
  1297. #
  1298. --disable_warnings
  1299. drop table if exists t1;
  1300. drop table if exists t2;
  1301. drop table if exists t3;
  1302. drop table if exists t4;
  1303. --enable_warnings
  1304. SET @save_sql_mode=@@sql_mode;
  1305. delimiter |;
  1306. SET sql_mode='TRADITIONAL'|
  1307. create table t1 (id int(10) not null primary key, v int(10) )|
  1308. create table t2 (id int(10) not null primary key, v int(10) )|
  1309. create table t3 (id int(10) not null primary key, v int(10) )|
  1310. create table t4 (c int)|
  1311. create trigger t4_bi before insert on t4 for each row set @t4_bi_called:=1|
  1312. create trigger t4_bu before update on t4 for each row set @t4_bu_called:=1|
  1313. insert into t1 values(10, 10)|
  1314. set @a:=1/0|
  1315. select 1/0 from t1|
  1316. create trigger t1_bi before insert on t1 for each row set @a:=1/0|
  1317. insert into t1 values(20, 20)|
  1318. drop trigger t1_bi|
  1319. create trigger t1_bi before insert on t1 for each row
  1320. begin
  1321. insert into t2 values (new.id, new.v);
  1322. update t2 set v=v+1 where id= new.id;
  1323. replace t3 values (new.id, 0);
  1324. update t2, t3 set t2.v=new.v, t3.v=new.v where t2.id=t3.id;
  1325. create temporary table t5 select * from t1;
  1326. delete from t5;
  1327. insert into t5 select * from t1;
  1328. insert into t4 values (0);
  1329. set @check= (select count(*) from t5);
  1330. update t4 set c= @check;
  1331. drop temporary table t5;
  1332. set @a:=1/0;
  1333. end|
  1334. set @check=0, @t4_bi_called=0, @t4_bu_called=0|
  1335. insert into t1 values(30, 30)|
  1336. select @check, @t4_bi_called, @t4_bu_called|
  1337. delimiter ;|
  1338. SET @@sql_mode=@save_sql_mode;
  1339. drop table t1;
  1340. drop table t2;
  1341. drop table t3;
  1342. drop table t4;
  1343. #
  1344. # Bug#20670 "UPDATE using key and invoking trigger that modifies
  1345. # this key does not stop"
  1346. #
  1347. --disable_warnings
  1348. drop table if exists t1;
  1349. --enable_warnings
  1350. create table t1 (i int, j int key);
  1351. insert into t1 values (1,1), (2,2), (3,3);
  1352. create trigger t1_bu before update on t1 for each row
  1353. set new.j = new.j + 10;
  1354. # This should not work indefinitely and should cause
  1355. # expected result
  1356. update t1 set i= i+ 10 where j > 2;
  1357. select * from t1;
  1358. drop table t1;
  1359. #
  1360. # Bug#23556 TRUNCATE TABLE still maps to DELETE
  1361. #
  1362. CREATE TABLE t1 (a INT PRIMARY KEY);
  1363. CREATE TABLE t2 (a INT PRIMARY KEY);
  1364. INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8);
  1365. CREATE TRIGGER trg_t1 BEFORE DELETE on t1 FOR EACH ROW
  1366. INSERT INTO t2 VALUES (OLD.a);
  1367. FLUSH STATUS;
  1368. TRUNCATE t1;
  1369. SHOW STATUS LIKE 'handler_delete';
  1370. SELECT COUNT(*) FROM t2;
  1371. INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8);
  1372. DELETE FROM t2;
  1373. FLUSH STATUS;
  1374. DELETE FROM t1;
  1375. SHOW STATUS LIKE 'handler_delete';
  1376. SELECT COUNT(*) FROM t2;
  1377. DROP TRIGGER trg_t1;
  1378. DROP TABLE t1,t2;
  1379. #
  1380. # Bug #23651 "Server crashes when trigger which uses stored function
  1381. # invoked from different connections".
  1382. #
  1383. --disable_warnings
  1384. drop table if exists t1;
  1385. drop function if exists f1;
  1386. --enable_warnings
  1387. create table t1 (i int);
  1388. create function f1() returns int return 10;
  1389. create trigger t1_bi before insert on t1 for each row set @a:= f1() + 10;
  1390. insert into t1 values ();
  1391. select @a;
  1392. connection addconroot1;
  1393. insert into t1 values ();
  1394. select @a;
  1395. connection default;
  1396. drop table t1;
  1397. drop function f1;
  1398. #
  1399. # Bug#23703: DROP TRIGGER needs an IF EXISTS
  1400. #
  1401. --disable_warnings
  1402. drop table if exists t1;
  1403. --enable_warnings
  1404. create table t1(a int, b varchar(50));
  1405. -- error ER_TRG_DOES_NOT_EXIST
  1406. drop trigger not_a_trigger;
  1407. drop trigger if exists not_a_trigger;
  1408. create trigger t1_bi before insert on t1
  1409. for each row set NEW.b := "In trigger t1_bi";
  1410. insert into t1 values (1, "a");
  1411. drop trigger if exists t1_bi;
  1412. insert into t1 values (2, "b");
  1413. drop trigger if exists t1_bi;
  1414. insert into t1 values (3, "c");
  1415. select * from t1;
  1416. drop table t1;
  1417. #
  1418. # Bug#25398: crash when a trigger contains a SELECT with
  1419. # trigger fields in the select list under DISTINCT
  1420. #
  1421. CREATE TABLE t1 (
  1422. id int NOT NULL DEFAULT '0',
  1423. a varchar(10) NOT NULL,
  1424. b varchar(10),
  1425. c varchar(10),
  1426. d timestamp NOT NULL,
  1427. PRIMARY KEY (id, a)
  1428. );
  1429. CREATE TABLE t2 (
  1430. fubar_id int unsigned NOT NULL DEFAULT '0',
  1431. last_change_time datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  1432. PRIMARY KEY (fubar_id)
  1433. );
  1434. DELIMITER |;
  1435. CREATE TRIGGER fubar_change
  1436. AFTER UPDATE ON t1
  1437. FOR EACH ROW
  1438. BEGIN
  1439. INSERT INTO t2 (fubar_id, last_change_time)
  1440. SELECT DISTINCT NEW.id AS fubar_id, NOW() AS last_change_time
  1441. FROM t1 WHERE (id = NEW.id) AND (OLD.c != NEW.c)
  1442. ON DUPLICATE KEY UPDATE
  1443. last_change_time =
  1444. IF((fubar_id = NEW.id)AND(OLD.c != NEW.c),NOW(),last_change_time);
  1445. END
  1446. |
  1447. DELIMITER ;|
  1448. INSERT INTO t1 (id,a, b,c,d) VALUES
  1449. (1,'a','b','c',now()),(2,'a','b','c',now());
  1450. UPDATE t1 SET c='Bang!' WHERE id=1;
  1451. SELECT fubar_id FROM t2;
  1452. DROP TABLE t1,t2;
  1453. #
  1454. # Bug#21285 (Incorrect message error deleting records in a table with a
  1455. # trigger for inserting)
  1456. #
  1457. --disable_warnings
  1458. DROP TABLE IF EXISTS bug21825_A;
  1459. DROP TABLE IF EXISTS bug21825_B;
  1460. --enable_warnings
  1461. CREATE TABLE bug21825_A (id int(10));
  1462. CREATE TABLE bug21825_B (id int(10));
  1463. delimiter //;
  1464. CREATE TRIGGER trgA AFTER INSERT ON bug21825_A
  1465. FOR EACH ROW
  1466. BEGIN
  1467. INSERT INTO bug21825_B (id) values (1);
  1468. END//
  1469. delimiter ;//
  1470. INSERT INTO bug21825_A (id) VALUES (10);
  1471. INSERT INTO bug21825_A (id) VALUES (20);
  1472. DROP TABLE bug21825_B;
  1473. # Must pass, the missing table in the insert trigger should not matter.
  1474. DELETE FROM bug21825_A WHERE id = 20;
  1475. DROP TABLE bug21825_A;
  1476. #
  1477. # Bug#22580 (DROP TABLE in nested stored procedure causes strange dependancy
  1478. # error)
  1479. #
  1480. --disable_warnings
  1481. DROP TABLE IF EXISTS bug22580_t1;
  1482. DROP PROCEDURE IF EXISTS bug22580_proc_1;
  1483. DROP PROCEDURE IF EXISTS bug22580_proc_2;
  1484. --enable_warnings
  1485. CREATE TABLE bug22580_t1 (a INT, b INT);
  1486. DELIMITER ||;
  1487. CREATE PROCEDURE bug22580_proc_2()
  1488. BEGIN
  1489. DROP TABLE IF EXISTS bug22580_tmp;
  1490. CREATE TEMPORARY TABLE bug22580_tmp (a INT);
  1491. DROP TABLE bug22580_tmp;
  1492. END||
  1493. CREATE PROCEDURE bug22580_proc_1()
  1494. BEGIN
  1495. CALL bug22580_proc_2();
  1496. END||
  1497. CREATE TRIGGER t1bu BEFORE UPDATE ON bug22580_t1
  1498. FOR EACH ROW
  1499. BEGIN
  1500. CALL bug22580_proc_1();
  1501. END||
  1502. DELIMITER ;||
  1503. # Must pass, the actions of the update trigger should not matter
  1504. INSERT INTO bug22580_t1 VALUES (1,1);
  1505. DROP TABLE bug22580_t1;
  1506. DROP PROCEDURE bug22580_proc_1;
  1507. DROP PROCEDURE bug22580_proc_2;
  1508. #
  1509. # Bug#27006: AFTER UPDATE triggers not fired with INSERT ... ON DUPLICATE
  1510. #
  1511. --disable_warnings
  1512. DROP TRIGGER IF EXISTS trg27006_a_update;
  1513. DROP TRIGGER IF EXISTS trg27006_a_insert;
  1514. --enable_warnings
  1515. CREATE TABLE t1 (
  1516. `id` int(10) unsigned NOT NULL auto_increment,
  1517. `val` varchar(10) NOT NULL,
  1518. PRIMARY KEY (`id`)
  1519. );
  1520. CREATE TABLE t2 like t1;
  1521. DELIMITER |;
  1522. CREATE TRIGGER trg27006_a_insert AFTER INSERT ON t1 FOR EACH ROW
  1523. BEGIN
  1524. insert into t2 values (NULL,new.val);
  1525. END |
  1526. CREATE TRIGGER trg27006_a_update AFTER UPDATE ON t1 FOR EACH ROW
  1527. BEGIN
  1528. insert into t2 values (NULL,new.val);
  1529. END |
  1530. DELIMITER ;|
  1531. INSERT INTO t1(val) VALUES ('test1'),('test2');
  1532. SELECT * FROM t1;
  1533. SELECT * FROM t2;
  1534. INSERT INTO t1 VALUES (2,'test2') ON DUPLICATE KEY UPDATE val=VALUES(val);
  1535. INSERT INTO t1 VALUES (2,'test3') ON DUPLICATE KEY UPDATE val=VALUES(val);
  1536. INSERT INTO t1 VALUES (3,'test4') ON DUPLICATE KEY UPDATE val=VALUES(val);
  1537. SELECT * FROM t1;
  1538. SELECT * FROM t2;
  1539. DROP TRIGGER trg27006_a_insert;
  1540. DROP TRIGGER trg27006_a_update;
  1541. drop table t1,t2;
  1542. #
  1543. # Bug #20903 "Crash when using CREATE TABLE .. SELECT and triggers"
  1544. #
  1545. --disable_warnings
  1546. drop table if exists t1, t2, t3;
  1547. --enable_warnings
  1548. create table t1 (i int);
  1549. create trigger t1_bi before insert on t1 for each row set new.i = 7;
  1550. create trigger t1_ai after insert on t1 for each row set @a := 7;
  1551. create table t2 (j int);
  1552. insert into t2 values (1), (2);
  1553. set @a:="";
  1554. create table if not exists t1 select * from t2;
  1555. select * from t1;
  1556. select @a;
  1557. # Let us check that trigger that involves table also works ok.
  1558. drop trigger t1_bi;
  1559. drop trigger t1_ai;
  1560. create table t3 (isave int);
  1561. create trigger t1_bi before insert on t1 for each row insert into t3 values (new.i);
  1562. create table if not exists t1 select * from t2;
  1563. select * from t1;
  1564. select * from t3;
  1565. drop table t1, t2, t3;
  1566. disconnect addconroot1;
  1567. disconnect addconroot2;
  1568. disconnect addconwithoutdb;
  1569. #
  1570. # Bug #26162: Trigger DML ignores low_priority_updates setting
  1571. #
  1572. CREATE TABLE t1 (id INTEGER);
  1573. CREATE TABLE t2 (id INTEGER);
  1574. INSERT INTO t2 VALUES (1),(2);
  1575. # trigger that produces the high priority insert, but should be low, adding
  1576. # LOW_PRIORITY fixes this
  1577. CREATE TRIGGER t1_test AFTER INSERT ON t1 FOR EACH ROW
  1578. INSERT INTO t2 VALUES (new.id);
  1579. CONNECT (rl_holder, localhost, root,,);
  1580. CONNECT (rl_acquirer, localhost, root,,);
  1581. CONNECT (wl_acquirer, localhost, root,,);
  1582. CONNECT (rl_contender, localhost, root,,);
  1583. CONNECTION rl_holder;
  1584. SELECT GET_LOCK('B26162',120);
  1585. CONNECTION rl_acquirer;
  1586. --send
  1587. SELECT 'rl_acquirer', GET_LOCK('B26162',120), id FROM t2 WHERE id = 1;
  1588. CONNECTION wl_acquirer;
  1589. SET SESSION LOW_PRIORITY_UPDATES=1;
  1590. SET GLOBAL LOW_PRIORITY_UPDATES=1;
  1591. #need to wait for rl_acquirer to lock on the B26162 lock
  1592. sleep 2;
  1593. --send
  1594. INSERT INTO t1 VALUES (5);
  1595. CONNECTION rl_contender;
  1596. # must not "see" the row inserted by the INSERT (as it must run before the
  1597. # INSERT)
  1598. --send
  1599. SELECT 'rl_contender', id FROM t2 WHERE id > 1;
  1600. CONNECTION rl_holder;
  1601. #need to wait for wl_acquirer and rl_contender to lock on t2
  1602. sleep 2;
  1603. SELECT RELEASE_LOCK('B26162');
  1604. CONNECTION rl_acquirer;
  1605. --reap
  1606. SELECT RELEASE_LOCK('B26162');
  1607. CONNECTION wl_acquirer;
  1608. --reap
  1609. CONNECTION rl_contender;
  1610. --reap
  1611. CONNECTION default;
  1612. DISCONNECT rl_acquirer;
  1613. DISCONNECT wl_acquirer;
  1614. DISCONNECT rl_contender;
  1615. DISCONNECT rl_holder;
  1616. DROP TRIGGER t1_test;
  1617. DROP TABLE t1,t2;
  1618. SET SESSION LOW_PRIORITY_UPDATES=DEFAULT;
  1619. SET GLOBAL LOW_PRIORITY_UPDATES=DEFAULT;
  1620. --echo
  1621. --echo Bug#28502 Triggers that update another innodb table will block
  1622. --echo on X lock unnecessarily
  1623. --echo
  1624. --echo Ensure we do not open and lock tables for triggers we do not fire.
  1625. --echo
  1626. --disable_warnings
  1627. drop table if exists t1, t2;
  1628. drop trigger if exists trg_bug28502_au;
  1629. --enable_warnings
  1630. create table t1 (id int, count int);
  1631. create table t2 (id int);
  1632. delimiter |;
  1633. create trigger trg_bug28502_au before update on t2
  1634. for each row
  1635. begin
  1636. if (new.id is not null) then
  1637. update t1 set count= count + 1 where id = old.id;
  1638. end if;
  1639. end|
  1640. delimiter ;|
  1641. insert into t1 (id, count) values (1, 0);
  1642. lock table t1 write;
  1643. --connect (connection_insert, localhost, root, , test, , )
  1644. connection connection_insert;
  1645. # Is expected to pass.
  1646. insert into t2 set id=1;
  1647. connection default;
  1648. unlock tables;
  1649. update t2 set id=1 where id=1;
  1650. select * from t1;
  1651. select * from t2;
  1652. # Will drop the trigger
  1653. drop table t1, t2;
  1654. disconnect connection_insert;
  1655. --echo
  1656. --echo Additionally, provide test coverage for triggers and
  1657. --echo all MySQL data changing commands.
  1658. --echo
  1659. --disable_warnings
  1660. drop table if exists t1, t2, t1_op_log;
  1661. drop view if exists v1;
  1662. drop trigger if exists trg_bug28502_bi;
  1663. drop trigger if exists trg_bug28502_ai;
  1664. drop trigger if exists trg_bug28502_bu;
  1665. drop trigger if exists trg_bug28502_au;
  1666. drop trigger if exists trg_bug28502_bd;
  1667. drop trigger if exists trg_bug28502_ad;
  1668. --enable_warnings
  1669. create table t1 (id int primary key auto_increment, operation varchar(255));
  1670. create table t2 (id int primary key);
  1671. create table t1_op_log(operation varchar(255));
  1672. create view v1 as select * from t1;
  1673. create trigger trg_bug28502_bi before insert on t1
  1674. for each row
  1675. insert into t1_op_log (operation)
  1676. values (concat("Before INSERT, new=", new.operation));
  1677. create trigger trg_bug28502_ai after insert on t1
  1678. for each row
  1679. insert into t1_op_log (operation)
  1680. values (concat("After INSERT, new=", new.operation));
  1681. create trigger trg_bug28502_bu before update on t1
  1682. for each row
  1683. insert into t1_op_log (operation)
  1684. values (concat("Before UPDATE, new=", new.operation,
  1685. ", old=", old.operation));
  1686. create trigger trg_bug28502_au after update on t1
  1687. for each row
  1688. insert into t1_op_log (operation)
  1689. values (concat("After UPDATE, new=", new.operation,
  1690. ", old=", old.operation));
  1691. create trigger trg_bug28502_bd before delete on t1
  1692. for each row
  1693. insert into t1_op_log (operation)
  1694. values (concat("Before DELETE, old=", old.operation));
  1695. create trigger trg_bug28502_ad after delete on t1
  1696. for each row
  1697. insert into t1_op_log (operation)
  1698. values (concat("After DELETE, old=", old.operation));
  1699. insert into t1 (operation) values ("INSERT");
  1700. set @id=last_insert_id();
  1701. select * from t1;
  1702. select * from t1_op_log;
  1703. truncate t1_op_log;
  1704. update t1 set operation="UPDATE" where id=@id;
  1705. select * from t1;
  1706. select * from t1_op_log;
  1707. truncate t1_op_log;
  1708. delete from t1 where id=@id;
  1709. select * from t1;
  1710. select * from t1_op_log;
  1711. truncate t1;
  1712. truncate t1_op_log;
  1713. insert into t1 (id, operation) values
  1714. (NULL, "INSERT ON DUPLICATE KEY UPDATE, inserting a new key")
  1715. on duplicate key update id=NULL, operation="Should never happen";
  1716. set @id=last_insert_id();
  1717. select * from t1;
  1718. select * from t1_op_log;
  1719. truncate t1_op_log;
  1720. insert into t1 (id, operation) values
  1721. (@id, "INSERT ON DUPLICATE KEY UPDATE, the key value is the same")
  1722. on duplicate key update id=NULL,
  1723. operation="INSERT ON DUPLICATE KEY UPDATE, updating the duplicate";
  1724. select * from t1;
  1725. select * from t1_op_log;
  1726. truncate t1;
  1727. truncate t1_op_log;
  1728. replace into t1 values (NULL, "REPLACE, inserting a new key");
  1729. set @id=last_insert_id();
  1730. select * from t1;
  1731. select * from t1_op_log;
  1732. truncate t1_op_log;
  1733. replace into t1 values (@id, "REPLACE, deleting the duplicate");
  1734. select * from t1;
  1735. select * from t1_op_log;
  1736. truncate t1;
  1737. truncate t1_op_log;
  1738. create table if not exists t1
  1739. select NULL, "CREATE TABLE ... SELECT, inserting a new key";
  1740. set @id=last_insert_id();
  1741. select * from t1;
  1742. select * from t1_op_log;
  1743. truncate t1_op_log;
  1744. create table if not exists t1 replace
  1745. select @id, "CREATE TABLE ... REPLACE SELECT, deleting a duplicate key";
  1746. select * from t1;
  1747. select * from t1_op_log;
  1748. truncate t1;
  1749. truncate t1_op_log;
  1750. insert into t1 (id, operation)
  1751. select NULL, "INSERT ... SELECT, inserting a new key";
  1752. set @id=last_insert_id();
  1753. select * from t1;
  1754. select * from t1_op_log;
  1755. truncate t1_op_log;
  1756. insert into t1 (id, operation)
  1757. select @id,
  1758. "INSERT ... SELECT ... ON DUPLICATE KEY UPDATE, updating a duplicate"
  1759. on duplicate key update id=NULL,
  1760. operation="INSERT ... SELECT ... ON DUPLICATE KEY UPDATE, updating a duplicate";
  1761. select * from t1;
  1762. select * from t1_op_log;
  1763. truncate t1;
  1764. truncate t1_op_log;
  1765. replace into t1 (id, operation)
  1766. select NULL, "REPLACE ... SELECT, inserting a new key";
  1767. set @id=last_insert_id();
  1768. select * from t1;
  1769. select * from t1_op_log;
  1770. truncate t1_op_log;
  1771. replace into t1 (id, operation)
  1772. select @id, "REPLACE ... SELECT, deleting a duplicate";
  1773. select * from t1;
  1774. select * from t1_op_log;
  1775. truncate t1;
  1776. truncate t1_op_log;
  1777. insert into t1 (id, operation) values (1, "INSERT for multi-DELETE");
  1778. insert into t2 (id) values (1);
  1779. delete t1.*, t2.* from t1, t2 where t1.id=1;
  1780. select * from t1;
  1781. select * from t2;
  1782. select * from t1_op_log;
  1783. truncate t1;
  1784. truncate t2;
  1785. truncate t1_op_log;
  1786. insert into t1 (id, operation) values (1, "INSERT for multi-UPDATE");
  1787. insert into t2 (id) values (1);
  1788. update t1, t2 set t1.id=2, operation="multi-UPDATE" where t1.id=1;
  1789. update t1, t2
  1790. set t2.id=3, operation="multi-UPDATE, SET for t2, but the trigger is fired" where t1.id=2;
  1791. select * from t1;
  1792. select * from t2;
  1793. select * from t1_op_log;
  1794. truncate table t1;
  1795. truncate table t2;
  1796. truncate table t1_op_log;
  1797. --echo
  1798. --echo Now do the same but use a view instead of the base table.
  1799. --echo
  1800. insert into v1 (operation) values ("INSERT");
  1801. set @id=last_insert_id();
  1802. select * from t1;
  1803. select * from t1_op_log;
  1804. truncate t1_op_log;
  1805. update v1 set operation="UPDATE" where id=@id;
  1806. select * from t1;
  1807. select * from t1_op_log;
  1808. truncate t1_op_log;
  1809. delete from v1 where id=@id;
  1810. select * from t1;
  1811. select * from t1_op_log;
  1812. truncate t1;
  1813. truncate t1_op_log;
  1814. insert into v1 (id, operation) values
  1815. (NULL, "INSERT ON DUPLICATE KEY UPDATE, inserting a new key")
  1816. on duplicate key update id=NULL, operation="Should never happen";
  1817. set @id=last_insert_id();
  1818. select * from t1;
  1819. select * from t1_op_log;
  1820. truncate t1_op_log;
  1821. insert into v1 (id, operation) values
  1822. (@id, "INSERT ON DUPLICATE KEY UPDATE, the key value is the same")
  1823. on duplicate key update id=NULL,
  1824. operation="INSERT ON DUPLICATE KEY UPDATE, updating the duplicate";
  1825. select * from t1;
  1826. select * from t1_op_log;
  1827. truncate t1;
  1828. truncate t1_op_log;
  1829. replace into v1 values (NULL, "REPLACE, inserting a new key");
  1830. set @id=last_insert_id();
  1831. select * from t1;
  1832. select * from t1_op_log;
  1833. truncate t1_op_log;
  1834. replace into v1 values (@id, "REPLACE, deleting the duplicate");
  1835. select * from t1;
  1836. select * from t1_op_log;
  1837. truncate t1;
  1838. truncate t1_op_log;
  1839. create table if not exists v1
  1840. select NULL, "CREATE TABLE ... SELECT, inserting a new key";
  1841. set @id=last_insert_id();
  1842. select * from t1;
  1843. select * from t1_op_log;
  1844. truncate t1_op_log;
  1845. create table if not exists v1 replace
  1846. select @id, "CREATE TABLE ... REPLACE SELECT, deleting a duplicate key";
  1847. select * from t1;
  1848. select * from t1_op_log;
  1849. truncate t1;
  1850. truncate t1_op_log;
  1851. insert into v1 (id, operation)
  1852. select NULL, "INSERT ... SELECT, inserting a new key";
  1853. set @id=last_insert_id();
  1854. select * from t1;
  1855. select * from t1_op_log;
  1856. truncate t1_op_log;
  1857. insert into v1 (id, operation)
  1858. select @id,
  1859. "INSERT ... SELECT ... ON DUPLICATE KEY UPDATE, updating a duplicate"
  1860. on duplicate key update id=NULL,
  1861. operation="INSERT ... SELECT ... ON DUPLICATE KEY UPDATE, updating a duplicate";
  1862. select * from t1;
  1863. select * from t1_op_log;
  1864. truncate t1;
  1865. truncate t1_op_log;
  1866. replace into v1 (id, operation)
  1867. select NULL, "REPLACE ... SELECT, inserting a new key";
  1868. set @id=last_insert_id();
  1869. select * from t1;
  1870. select * from t1_op_log;
  1871. truncate t1_op_log;
  1872. replace into v1 (id, operation)
  1873. select @id, "REPLACE ... SELECT, deleting a duplicate";
  1874. select * from t1;
  1875. select * from t1_op_log;
  1876. truncate t1;
  1877. truncate t1_op_log;
  1878. insert into v1 (id, operation) values (1, "INSERT for multi-DELETE");
  1879. insert into t2 (id) values (1);
  1880. delete v1.*, t2.* from v1, t2 where v1.id=1;
  1881. select * from t1;
  1882. select * from t2;
  1883. select * from t1_op_log;
  1884. truncate t1;
  1885. truncate t2;
  1886. truncate t1_op_log;
  1887. insert into v1 (id, operation) values (1, "INSERT for multi-UPDATE");
  1888. insert into t2 (id) values (1);
  1889. update v1, t2 set v1.id=2, operation="multi-UPDATE" where v1.id=1;
  1890. update v1, t2
  1891. set t2.id=3, operation="multi-UPDATE, SET for t2, but the trigger is fired" where v1.id=2;
  1892. select * from t1;
  1893. select * from t2;
  1894. select * from t1_op_log;
  1895. drop view v1;
  1896. drop table t1, t2, t1_op_log;
  1897. #
  1898. # TODO: test LOAD DATA INFILE
  1899. --echo End of 5.0 tests