Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
6dc933b7
Commit
6dc933b7
authored
Sep 09, 2004
by
dlenev@brandersnatch.localdomain
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WL#1218 "Triggers"
After review and after merge fixes.
parent
9b1bc6a4
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
65 additions
and
53 deletions
+65
-53
mysql-test/t/trigger.test
mysql-test/t/trigger.test
+10
-10
sql/sp_head.cc
sql/sp_head.cc
+3
-3
sql/sp_head.h
sql/sp_head.h
+5
-4
sql/sql_trigger.cc
sql/sql_trigger.cc
+17
-18
sql/sql_yacc.yy
sql/sql_yacc.yy
+30
-18
No files found.
mysql-test/t/trigger.test
View file @
6dc933b7
...
@@ -151,15 +151,15 @@ drop table t1;
...
@@ -151,15 +151,15 @@ drop table t1;
#
#
create
table
t1
(
i
int
);
create
table
t1
(
i
int
);
--
error
13
58
--
error
13
62
create
trigger
trg
before
insert
on
t1
for
each
row
set
@
a
:=
old
.
i
;
create
trigger
trg
before
insert
on
t1
for
each
row
set
@
a
:=
old
.
i
;
--
error
13
58
--
error
13
62
create
trigger
trg
before
delete
on
t1
for
each
row
set
@
a
:=
new
.
i
;
create
trigger
trg
before
delete
on
t1
for
each
row
set
@
a
:=
new
.
i
;
--
error
13
57
--
error
13
61
create
trigger
trg
before
update
on
t1
for
each
row
set
old
.
i
:=
1
;
create
trigger
trg
before
update
on
t1
for
each
row
set
old
.
i
:=
1
;
--
error
13
58
--
error
13
62
create
trigger
trg
before
delete
on
t1
for
each
row
set
new
.
i
:=
1
;
create
trigger
trg
before
delete
on
t1
for
each
row
set
new
.
i
:=
1
;
--
error
13
57
--
error
13
61
create
trigger
trg
after
update
on
t1
for
each
row
set
new
.
i
:=
1
;
create
trigger
trg
after
update
on
t1
for
each
row
set
new
.
i
:=
1
;
# TODO: We should also test wrong field names here, we don't do it now
# TODO: We should also test wrong field names here, we don't do it now
# because proper error handling is not in place yet.
# because proper error handling is not in place yet.
...
@@ -173,23 +173,23 @@ create trigger trg after update on t1 for each row set new.i:=1;
...
@@ -173,23 +173,23 @@ create trigger trg after update on t1 for each row set new.i:=1;
create
trigger
trg
before
insert
on
t2
for
each
row
set
@
a
:=
1
;
create
trigger
trg
before
insert
on
t2
for
each
row
set
@
a
:=
1
;
create
trigger
trg
before
insert
on
t1
for
each
row
set
@
a
:=
1
;
create
trigger
trg
before
insert
on
t1
for
each
row
set
@
a
:=
1
;
--
error
135
4
--
error
135
8
create
trigger
trg
after
insert
on
t1
for
each
row
set
@
a
:=
1
;
create
trigger
trg
after
insert
on
t1
for
each
row
set
@
a
:=
1
;
--
error
135
4
--
error
135
8
create
trigger
trg2
before
insert
on
t1
for
each
row
set
@
a
:=
1
;
create
trigger
trg2
before
insert
on
t1
for
each
row
set
@
a
:=
1
;
drop
trigger
t1
.
trg
;
drop
trigger
t1
.
trg
;
--
error
135
5
--
error
135
9
drop
trigger
t1
.
trg
;
drop
trigger
t1
.
trg
;
create
view
v1
as
select
*
from
t1
;
create
view
v1
as
select
*
from
t1
;
--
error
13
56
--
error
13
60
create
trigger
trg
before
insert
on
v1
for
each
row
set
@
a
:=
1
;
create
trigger
trg
before
insert
on
v1
for
each
row
set
@
a
:=
1
;
drop
view
v1
;
drop
view
v1
;
drop
table
t1
;
drop
table
t1
;
create
temporary
table
t1
(
i
int
);
create
temporary
table
t1
(
i
int
);
--
error
13
56
--
error
13
60
create
trigger
trg
before
insert
on
t1
for
each
row
set
@
a
:=
1
;
create
trigger
trg
before
insert
on
t1
for
each
row
set
@
a
:=
1
;
drop
table
t1
;
drop
table
t1
;
sql/sp_head.cc
View file @
6dc933b7
...
@@ -1230,7 +1230,7 @@ sp_instr_set::execute(THD *thd, uint *nextp)
...
@@ -1230,7 +1230,7 @@ sp_instr_set::execute(THD *thd, uint *nextp)
thd
->
spcont
->
set_item
(
m_offset
,
it
);
thd
->
spcont
->
set_item
(
m_offset
,
it
);
}
}
*
nextp
=
m_ip
+
1
;
*
nextp
=
m_ip
+
1
;
if
(
t
hd
->
lock
||
thd
->
open_tables
||
thd
->
derived_tables
)
if
(
t
ables
&&
(
thd
->
lock
||
thd
->
open_tables
||
thd
->
derived_tables
)
)
close_thread_tables
(
thd
);
close_thread_tables
(
thd
);
DBUG_RETURN
(
res
);
DBUG_RETURN
(
res
);
}
}
...
@@ -1387,7 +1387,7 @@ sp_instr_jump_if::execute(THD *thd, uint *nextp)
...
@@ -1387,7 +1387,7 @@ sp_instr_jump_if::execute(THD *thd, uint *nextp)
else
else
*
nextp
=
m_ip
+
1
;
*
nextp
=
m_ip
+
1
;
}
}
if
(
t
hd
->
lock
||
thd
->
open_tables
||
thd
->
derived_tables
)
if
(
t
ables
&&
(
thd
->
lock
||
thd
->
open_tables
||
thd
->
derived_tables
)
)
close_thread_tables
(
thd
);
close_thread_tables
(
thd
);
DBUG_RETURN
(
res
);
DBUG_RETURN
(
res
);
}
}
...
@@ -1444,7 +1444,7 @@ sp_instr_jump_if_not::execute(THD *thd, uint *nextp)
...
@@ -1444,7 +1444,7 @@ sp_instr_jump_if_not::execute(THD *thd, uint *nextp)
else
else
*
nextp
=
m_ip
+
1
;
*
nextp
=
m_ip
+
1
;
}
}
if
(
t
hd
->
lock
||
thd
->
open_tables
||
thd
->
derived_tables
)
if
(
t
ables
&&
(
thd
->
lock
||
thd
->
open_tables
||
thd
->
derived_tables
)
)
close_thread_tables
(
thd
);
close_thread_tables
(
thd
);
DBUG_RETURN
(
res
);
DBUG_RETURN
(
res
);
}
}
...
...
sql/sp_head.h
View file @
6dc933b7
...
@@ -392,8 +392,8 @@ class sp_instr_set_user_var : public sp_instr
...
@@ -392,8 +392,8 @@ class sp_instr_set_user_var : public sp_instr
public:
public:
sp_instr_set_user_var
(
uint
ip
,
LEX_STRING
var
,
Item
*
val
)
sp_instr_set_user_var
(
uint
ip
,
sp_pcontext
*
ctx
,
LEX_STRING
var
,
Item
*
val
)
:
sp_instr
(
ip
),
m_set_var_item
(
var
,
val
)
:
sp_instr
(
ip
,
ctx
),
m_set_var_item
(
var
,
val
)
{}
{}
virtual
~
sp_instr_set_user_var
()
virtual
~
sp_instr_set_user_var
()
...
@@ -419,8 +419,9 @@ class sp_instr_set_trigger_field : public sp_instr
...
@@ -419,8 +419,9 @@ class sp_instr_set_trigger_field : public sp_instr
public:
public:
sp_instr_set_trigger_field
(
uint
ip
,
LEX_STRING
field_name
,
Item
*
val
)
sp_instr_set_trigger_field
(
uint
ip
,
sp_pcontext
*
ctx
,
:
sp_instr
(
ip
),
LEX_STRING
field_name
,
Item
*
val
)
:
sp_instr
(
ip
,
ctx
),
trigger_field
(
Item_trigger_field
::
NEW_ROW
,
field_name
.
str
),
trigger_field
(
Item_trigger_field
::
NEW_ROW
,
field_name
.
str
),
value
(
val
)
value
(
val
)
{}
{}
...
...
sql/sql_trigger.cc
View file @
6dc933b7
...
@@ -319,18 +319,18 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
...
@@ -319,18 +319,18 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
if
(
!
strncmp
(
triggers_file_type
.
str
,
parser
->
type
()
->
str
,
if
(
!
strncmp
(
triggers_file_type
.
str
,
parser
->
type
()
->
str
,
parser
->
type
()
->
length
))
parser
->
type
()
->
length
))
{
{
int
i
;
Field
**
fld
,
**
old_fld
;
Table_triggers_list
*
triggers
_info
=
Table_triggers_list
*
triggers
=
new
(
&
table
->
mem_root
)
Table_triggers_list
();
new
(
&
table
->
mem_root
)
Table_triggers_list
();
if
(
!
triggers
_info
)
if
(
!
triggers
)
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
if
(
parser
->
parse
((
gptr
)
triggers
_info
,
&
table
->
mem_root
,
if
(
parser
->
parse
((
gptr
)
triggers
,
&
table
->
mem_root
,
triggers_file_parameters
,
1
))
triggers_file_parameters
,
1
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
table
->
triggers
=
triggers
_info
;
table
->
triggers
=
triggers
;
/*
/*
We have to prepare array of Field objects which will represent OLD.*
We have to prepare array of Field objects which will represent OLD.*
...
@@ -338,27 +338,26 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
...
@@ -338,27 +338,26 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
TODO: This could be avoided if there is no ON UPDATE trigger.
TODO: This could be avoided if there is no ON UPDATE trigger.
*/
*/
if
(
!
(
triggers
_info
->
old_field
=
if
(
!
(
triggers
->
old_field
=
(
Field
**
)
alloc_root
(
&
table
->
mem_root
,
(
table
->
fields
+
1
)
*
(
Field
**
)
alloc_root
(
&
table
->
mem_root
,
(
table
->
fields
+
1
)
*
sizeof
(
Field
*
))))
sizeof
(
Field
*
))))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
for
(
i
=
0
;
i
<
table
->
fields
;
i
++
)
for
(
fld
=
table
->
field
,
old_fld
=
triggers
->
old_field
;
*
fld
;
fld
++
,
old_fld
++
)
{
{
/*
/*
QQ: it is supposed that it is ok to use this function for field
QQ: it is supposed that it is ok to use this function for field
cloning...
cloning...
*/
*/
if
(
!
(
triggers_info
->
old_field
[
i
]
=
if
(
!
(
*
old_fld
=
(
*
fld
)
->
new_field
(
&
table
->
mem_root
,
table
)))
table
->
field
[
i
]
->
new_field
(
&
table
->
mem_root
,
table
)))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
triggers_info
->
old_field
[
i
]
->
move_field
((
my_ptrdiff_t
)
(
*
old_fld
)
->
move_field
((
my_ptrdiff_t
)(
table
->
record
[
1
]
-
(
table
->
record
[
1
]
-
table
->
record
[
0
]));
table
->
record
[
0
]));
}
}
triggers_info
->
old_field
[
i
]
=
0
;
*
old_fld
=
0
;
List_iterator_fast
<
LEX_STRING
>
it
(
triggers
_info
->
definitions_list
);
List_iterator_fast
<
LEX_STRING
>
it
(
triggers
->
definitions_list
);
LEX_STRING
*
trg_create_str
,
*
trg_name_str
;
LEX_STRING
*
trg_create_str
,
*
trg_name_str
;
char
*
trg_name_buff
;
char
*
trg_name_buff
;
LEX
*
old_lex
=
thd
->
lex
,
lex
;
LEX
*
old_lex
=
thd
->
lex
,
lex
;
...
@@ -367,8 +366,8 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
...
@@ -367,8 +366,8 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
while
((
trg_create_str
=
it
++
))
while
((
trg_create_str
=
it
++
))
{
{
lex_start
(
thd
,
(
uchar
*
)
trg_create_str
->
str
,
trg_create_str
->
length
);
mysql_init_query
(
thd
,
(
uchar
*
)
trg_create_str
->
str
,
mysql_init_query
(
thd
,
true
);
trg_create_str
->
length
,
true
);
lex
.
trg_table
=
table
;
lex
.
trg_table
=
table
;
if
(
yyparse
((
void
*
)
thd
)
||
thd
->
is_fatal_error
)
if
(
yyparse
((
void
*
)
thd
)
||
thd
->
is_fatal_error
)
{
{
...
@@ -385,7 +384,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
...
@@ -385,7 +384,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
goto
err_with_lex_cleanup
;
goto
err_with_lex_cleanup
;
}
}
triggers
_info
->
bodies
[
lex
.
trg_chistics
.
event
]
triggers
->
bodies
[
lex
.
trg_chistics
.
event
]
[
lex
.
trg_chistics
.
action_time
]
=
lex
.
sphead
;
[
lex
.
trg_chistics
.
action_time
]
=
lex
.
sphead
;
lex
.
sphead
=
0
;
lex
.
sphead
=
0
;
...
@@ -404,7 +403,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
...
@@ -404,7 +403,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
old_global_mem_root
=
my_pthread_getspecific_ptr
(
MEM_ROOT
*
,
THR_MALLOC
);
old_global_mem_root
=
my_pthread_getspecific_ptr
(
MEM_ROOT
*
,
THR_MALLOC
);
my_pthread_setspecific_ptr
(
THR_MALLOC
,
&
table
->
mem_root
);
my_pthread_setspecific_ptr
(
THR_MALLOC
,
&
table
->
mem_root
);
if
(
triggers
_info
->
names_list
.
push_back
(
trg_name_str
))
if
(
triggers
->
names_list
.
push_back
(
trg_name_str
))
goto
err_with_lex_cleanup
;
goto
err_with_lex_cleanup
;
my_pthread_setspecific_ptr
(
THR_MALLOC
,
old_global_mem_root
);
my_pthread_setspecific_ptr
(
THR_MALLOC
,
old_global_mem_root
);
...
...
sql/sql_yacc.yy
View file @
6dc933b7
...
@@ -1212,15 +1212,6 @@ create:
...
@@ -1212,15 +1212,6 @@ create:
LEX *lex= Lex;
LEX *lex= Lex;
sp_head *sp;
sp_head *sp;
lex->name_and_length= $3;
/* QQ: Could we loosen lock type in certain cases ? */
if (!lex->select_lex.add_table_to_list(YYTHD, $7,
(LEX_STRING*) 0,
TL_OPTION_UPDATING,
TL_WRITE))
YYABORT;
if (lex->sphead)
if (lex->sphead)
{
{
net_printf(YYTHD, ER_SP_NO_RECURSIVE_CREATE, "TRIGGER");
net_printf(YYTHD, ER_SP_NO_RECURSIVE_CREATE, "TRIGGER");
...
@@ -1256,6 +1247,23 @@ create:
...
@@ -1256,6 +1247,23 @@ create:
if (sp->m_old_cmq)
if (sp->m_old_cmq)
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
sp->restore_thd_mem_root(YYTHD);
sp->restore_thd_mem_root(YYTHD);
lex->name_and_length= $3;
/*
We have to do it after parsing trigger body, because some of
sp_proc_stmt alternatives are not saving/restoring LEX, so
lex->query_tables can be wiped out.
QQ: What are other consequences of this?
QQ: Could we loosen lock type in certain cases ?
*/
if (!lex->select_lex.add_table_to_list(YYTHD, $7,
(LEX_STRING*) 0,
TL_OPTION_UPDATING,
TL_WRITE))
YYABORT;
}
}
;
;
...
@@ -6922,10 +6930,18 @@ option_value:
...
@@ -6922,10 +6930,18 @@ option_value:
We have to use special instruction in functions and triggers
We have to use special instruction in functions and triggers
because sp_instr_stmt will close all tables and thus ruin
because sp_instr_stmt will close all tables and thus ruin
execution of statement invoking function or trigger.
execution of statement invoking function or trigger.
We also do not want to allow expression with subselects in
this case.
*/
*/
if (lex->query_tables)
{
send_error(YYTHD, ER_SP_SUBSELECT_NYI);
YYABORT;
}
sp_instr_set_user_var *i=
sp_instr_set_user_var *i=
new sp_instr_set_user_var(lex->sphead->instructions(),
new sp_instr_set_user_var(lex->sphead->instructions(),
$2, $4);
lex->spcont,
$2, $4);
lex->sphead->add_instr(i);
lex->sphead->add_instr(i);
}
}
else
else
...
@@ -6941,12 +6957,8 @@ option_value:
...
@@ -6941,12 +6957,8 @@ option_value:
/* We are in trigger and assigning value to field of new row */
/* We are in trigger and assigning value to field of new row */
Item *it;
Item *it;
sp_instr_set_trigger_field *i;
sp_instr_set_trigger_field *i;
if ($3 && $3->type() == Item::SUBSELECT_ITEM)
if (lex->query_tables)
{ /*
{
QQ For now, just disallow subselects as values
Unfortunately this doesn't helps in case when we have
subselect deeper in expression.
*/
send_error(YYTHD, ER_SP_SUBSELECT_NYI);
send_error(YYTHD, ER_SP_SUBSELECT_NYI);
YYABORT;
YYABORT;
}
}
...
@@ -6958,7 +6970,7 @@ option_value:
...
@@ -6958,7 +6970,7 @@ option_value:
it= new Item_null();
it= new Item_null();
}
}
i= new sp_instr_set_trigger_field(lex->sphead->instructions(),
i= new sp_instr_set_trigger_field(lex->sphead->instructions(),
$1.base_name, it);
lex->spcont,
$1.base_name, it);
if (lex->trg_table && i->setup_field(YYTHD, lex->trg_table,
if (lex->trg_table && i->setup_field(YYTHD, lex->trg_table,
lex->trg_chistics.event))
lex->trg_chistics.event))
{
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment