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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
c179d0c1
Commit
c179d0c1
authored
Apr 20, 2005
by
ingo@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql.com:/home/mydev/mysql-4.1
into mysql.com:/home/mydev/mysql-4.1-bug7806
parents
b26d29a0
8faed379
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
154 additions
and
14 deletions
+154
-14
mysql-test/r/type_timestamp.result
mysql-test/r/type_timestamp.result
+47
-0
mysql-test/t/type_timestamp.test
mysql-test/t/type_timestamp.test
+21
-0
sql/mysql_priv.h
sql/mysql_priv.h
+0
-2
sql/sql_insert.cc
sql/sql_insert.cc
+82
-12
sql/table.h
sql/table.h
+4
-0
No files found.
mysql-test/r/type_timestamp.result
View file @
c179d0c1
...
...
@@ -432,3 +432,50 @@ t1 CREATE TABLE "t1" (
)
set sql_mode='';
drop table t1;
create table t1 (a int auto_increment primary key, b int, c timestamp);
insert into t1 (a, b, c) values (1, 0, '2001-01-01 01:01:01'),
(2, 0, '2002-02-02 02:02:02'), (3, 0, '2003-03-03 03:03:03');
select * from t1;
a b c
1 0 2001-01-01 01:01:01
2 0 2002-02-02 02:02:02
3 0 2003-03-03 03:03:03
update t1 set b = 2, c = c where a = 2;
select * from t1;
a b c
1 0 2001-01-01 01:01:01
2 2 2002-02-02 02:02:02
3 0 2003-03-03 03:03:03
insert into t1 (a) values (4);
select * from t1;
a b c
1 0 2001-01-01 01:01:01
2 2 2002-02-02 02:02:02
3 0 2003-03-03 03:03:03
4 NULL 2001-09-09 04:46:59
update t1 set c = '2004-04-04 04:04:04' where a = 4;
select * from t1;
a b c
1 0 2001-01-01 01:01:01
2 2 2002-02-02 02:02:02
3 0 2003-03-03 03:03:03
4 NULL 2004-04-04 04:04:04
insert into t1 (a) values (3), (5) on duplicate key update b = 3, c = c;
select * from t1;
a b c
1 0 2001-01-01 01:01:01
2 2 2002-02-02 02:02:02
3 3 2003-03-03 03:03:03
4 NULL 2004-04-04 04:04:04
5 NULL 2001-09-09 04:46:59
insert into t1 (a, c) values (4, '2004-04-04 00:00:00'),
(6, '2006-06-06 06:06:06') on duplicate key update b = 4;
select * from t1;
a b c
1 0 2001-01-01 01:01:01
2 2 2002-02-02 02:02:02
3 3 2003-03-03 03:03:03
4 4 2001-09-09 04:46:59
5 NULL 2001-09-09 04:46:59
6 NULL 2006-06-06 06:06:06
drop table t1;
mysql-test/t/type_timestamp.test
View file @
c179d0c1
...
...
@@ -298,3 +298,24 @@ show create table t1;
# restore default mode
set
sql_mode
=
''
;
drop
table
t1
;
#
# Bug#7806 - insert on duplicate key and auto-update of timestamp
#
create
table
t1
(
a
int
auto_increment
primary
key
,
b
int
,
c
timestamp
);
insert
into
t1
(
a
,
b
,
c
)
values
(
1
,
0
,
'2001-01-01 01:01:01'
),
(
2
,
0
,
'2002-02-02 02:02:02'
),
(
3
,
0
,
'2003-03-03 03:03:03'
);
select
*
from
t1
;
update
t1
set
b
=
2
,
c
=
c
where
a
=
2
;
select
*
from
t1
;
insert
into
t1
(
a
)
values
(
4
);
select
*
from
t1
;
update
t1
set
c
=
'2004-04-04 04:04:04'
where
a
=
4
;
select
*
from
t1
;
insert
into
t1
(
a
)
values
(
3
),
(
5
)
on
duplicate
key
update
b
=
3
,
c
=
c
;
select
*
from
t1
;
insert
into
t1
(
a
,
c
)
values
(
4
,
'2004-04-04 00:00:00'
),
(
6
,
'2006-06-06 06:06:06'
)
on
duplicate
key
update
b
=
4
;
select
*
from
t1
;
drop
table
t1
;
sql/mysql_priv.h
View file @
c179d0c1
...
...
@@ -668,8 +668,6 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name);
void
mysql_stmt_free
(
THD
*
thd
,
char
*
packet
);
void
mysql_stmt_reset
(
THD
*
thd
,
char
*
packet
);
void
mysql_stmt_get_longdata
(
THD
*
thd
,
char
*
pos
,
ulong
packet_length
);
int
check_insert_fields
(
THD
*
thd
,
TABLE
*
table
,
List
<
Item
>
&
fields
,
List
<
Item
>
&
values
,
ulong
counter
);
/* sql_error.cc */
MYSQL_ERROR
*
push_warning
(
THD
*
thd
,
MYSQL_ERROR
::
enum_warning_level
level
,
uint
code
,
...
...
sql/sql_insert.cc
View file @
c179d0c1
...
...
@@ -42,15 +42,29 @@ static void unlink_blobs(register TABLE *table);
#define DELAYED_LOG_UPDATE 1
#define DELAYED_LOG_BIN 2
/*
Check if insert fields are correct.
Sets table->timestamp_field_type to TIMESTAMP_NO_AUTO_SET or leaves it
as is, depending on if timestamp should be updated or not.
SYNOPSIS
check_insert_fields()
thd The current thread.
table The table for insert.
fields The insert fields.
values The insert values.
NOTE
Clears TIMESTAMP_AUTO_SET_ON_INSERT from table->timestamp_field_type
or leaves it as is, depending on if timestamp should be updated or
not.
RETURN
0 OK
-1 Error
*/
int
check_insert_fields
(
THD
*
thd
,
TABLE
*
table
,
List
<
Item
>
&
fields
,
List
<
Item
>
&
values
,
ulong
counter
)
static
int
check_insert_fields
(
THD
*
thd
,
TABLE
*
table
,
List
<
Item
>
&
fields
,
List
<
Item
>
&
values
)
{
if
(
fields
.
elements
==
0
&&
values
.
elements
!=
0
)
{
...
...
@@ -58,7 +72,7 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
{
my_printf_error
(
ER_WRONG_VALUE_COUNT_ON_ROW
,
ER
(
ER_WRONG_VALUE_COUNT_ON_ROW
),
MYF
(
0
),
counter
);
MYF
(
0
),
1
);
return
-
1
;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
...
...
@@ -66,7 +80,7 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
check_grant_all_columns
(
thd
,
INSERT_ACL
,
table
))
return
-
1
;
#endif
table
->
timestamp_field_type
=
TIMESTAMP_NO_AUTO_SE
T
;
(
int
)
table
->
timestamp_field_type
&=
~
(
int
)
TIMESTAMP_AUTO_SET_ON_INSER
T
;
}
else
{
// Part field list
...
...
@@ -74,7 +88,7 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
{
my_printf_error
(
ER_WRONG_VALUE_COUNT_ON_ROW
,
ER
(
ER_WRONG_VALUE_COUNT_ON_ROW
),
MYF
(
0
),
counter
);
MYF
(
0
),
1
);
return
-
1
;
}
TABLE_LIST
table_list
;
...
...
@@ -96,7 +110,7 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
}
if
(
table
->
timestamp_field
&&
// Don't set timestamp if used
table
->
timestamp_field
->
query_id
==
thd
->
query_id
)
table
->
timestamp_field_type
=
TIMESTAMP_NO_AUTO_SE
T
;
(
int
)
table
->
timestamp_field_type
&=
~
(
int
)
TIMESTAMP_AUTO_SET_ON_INSER
T
;
}
// For the values we need select_priv
#ifndef NO_EMBEDDED_ACCESS_CHECKS
...
...
@@ -106,6 +120,62 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
}
/*
Check update fields for the timestamp field.
SYNOPSIS
check_update_fields()
thd The current thread.
insert_table_list The insert table list.
table The table for update.
update_fields The update fields.
NOTE
If the update fields include the timestamp field,
remove TIMESTAMP_AUTO_SET_ON_UPDATE from table->timestamp_field_type.
RETURN
0 OK
-1 Error
*/
static
int
check_update_fields
(
THD
*
thd
,
TABLE
*
table
,
TABLE_LIST
*
insert_table_list
,
List
<
Item
>
&
update_fields
)
{
ulong
timestamp_query_id
;
LINT_INIT
(
timestamp_query_id
);
/*
Change the query_id for the timestamp column so that we can
check if this is modified directly.
*/
if
(
table
->
timestamp_field
)
{
timestamp_query_id
=
table
->
timestamp_field
->
query_id
;
table
->
timestamp_field
->
query_id
=
thd
->
query_id
-
1
;
}
/*
Check the fields we are going to modify. This will set the query_id
of all used fields to the threads query_id.
*/
if
(
setup_fields
(
thd
,
0
,
insert_table_list
,
update_fields
,
1
,
0
,
0
))
return
-
1
;
if
(
table
->
timestamp_field
)
{
/* Don't set timestamp column if this is modified. */
if
(
table
->
timestamp_field
->
query_id
==
thd
->
query_id
)
(
int
)
table
->
timestamp_field_type
&=
~
(
int
)
TIMESTAMP_AUTO_SET_ON_UPDATE
;
else
table
->
timestamp_field
->
query_id
=
timestamp_query_id
;
}
return
0
;
}
int
mysql_insert
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Item
>
&
fields
,
List
<
List_item
>
&
values_list
,
...
...
@@ -450,11 +520,11 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
if
(
!
table
->
insert_values
)
DBUG_RETURN
(
-
1
);
}
if
((
values
&&
check_insert_fields
(
thd
,
table
,
fields
,
*
values
,
1
))
||
if
((
values
&&
check_insert_fields
(
thd
,
table
,
fields
,
*
values
))
||
setup_tables
(
insert_table_list
)
||
(
values
&&
setup_fields
(
thd
,
0
,
insert_table_list
,
*
values
,
0
,
0
,
0
))
||
(
duplic
==
DUP_UPDATE
&&
(
setup_fields
(
thd
,
0
,
insert_table_list
,
update_fields
,
1
,
0
,
0
)
||
(
check_update_fields
(
thd
,
table
,
insert_table_list
,
update_fields
)
||
setup_fields
(
thd
,
0
,
insert_table_list
,
update_values
,
1
,
0
,
0
))))
DBUG_RETURN
(
-
1
);
if
(
values
&&
find_real_table_in_list
(
table_list
->
next
,
table_list
->
db
,
...
...
@@ -1457,7 +1527,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
DBUG_ENTER
(
"select_insert::prepare"
);
unit
=
u
;
if
(
check_insert_fields
(
thd
,
table
,
*
fields
,
values
,
1
))
if
(
check_insert_fields
(
thd
,
table
,
*
fields
,
values
))
DBUG_RETURN
(
1
);
restore_record
(
table
,
default_values
);
// Get empty record
...
...
sql/table.h
View file @
c179d0c1
...
...
@@ -60,6 +60,10 @@ typedef struct st_filesort_info
/*
Values in this enum are used to indicate during which operations value
of TIMESTAMP field should be set to current timestamp.
WARNING: The values are used for bit operations. If you change the enum,
you must keep the bitwise relation of the values. For example:
(int) TIMESTAMP_AUTO_SET_ON_BOTH ==
(int) TIMESTAMP_AUTO_SET_ON_INSERT | (int) TIMESTAMP_AUTO_SET_ON_UPDATE.
*/
enum
timestamp_auto_set_type
{
...
...
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