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
56e4f4c4
Commit
56e4f4c4
authored
Dec 16, 2004
by
jan@hundin.mysql.fi
Browse files
Options
Browse Files
Download
Plain Diff
Merge jlindstrom@bk-internal.mysql.com:/home/bk/mysql-5.0
into hundin.mysql.fi:/home/jan/new/mysql-5.0
parents
2f38a79a
f6b1f5de
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
174 additions
and
32 deletions
+174
-32
include/my_global.h
include/my_global.h
+1
-0
libmysql/libmysql.c
libmysql/libmysql.c
+11
-11
mysql-test/r/information_schema.result
mysql-test/r/information_schema.result
+37
-0
mysql-test/r/init_connect.result
mysql-test/r/init_connect.result
+1
-1
mysql-test/r/view.result
mysql-test/r/view.result
+5
-5
mysql-test/t/information_schema.test
mysql-test/t/information_schema.test
+26
-0
mysql-test/t/init_connect.test
mysql-test/t/init_connect.test
+1
-1
mysql-test/t/view.test
mysql-test/t/view.test
+1
-1
sql/share/errmsg.txt
sql/share/errmsg.txt
+2
-3
sql/sp.cc
sql/sp.cc
+1
-0
sql/sql_derived.cc
sql/sql_derived.cc
+12
-0
sql/sql_select.cc
sql/sql_select.cc
+14
-1
sql/sql_show.cc
sql/sql_show.cc
+57
-6
sql/table.cc
sql/table.cc
+3
-2
tests/client_test.c
tests/client_test.c
+2
-1
No files found.
include/my_global.h
View file @
56e4f4c4
...
...
@@ -661,6 +661,7 @@ typedef SOCKET_SIZE_TYPE size_socket;
#define UINT_MAX16 0xFFFF
#define INT_MIN8 (~0x7F)
#define INT_MAX8 0x7F
#define UINT_MAX8 0xFF
/* From limits.h instead */
#ifndef DBL_MIN
...
...
libmysql/libmysql.c
View file @
56e4f4c4
...
...
@@ -3442,7 +3442,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
longlong
data
=
my_strntoll
(
&
my_charset_latin1
,
value
,
length
,
10
,
&
endptr
,
&
err
);
*
param
->
error
=
(
IS_TRUNCATED
(
data
,
param
->
is_unsigned
,
INT
8_MIN
,
INT8_MAX
,
UINT8_MAX
)
|
INT
_MIN8
,
INT_MAX8
,
UINT_MAX8
)
|
test
(
err
));
*
buffer
=
(
uchar
)
data
;
break
;
...
...
@@ -3452,7 +3452,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
longlong
data
=
my_strntoll
(
&
my_charset_latin1
,
value
,
length
,
10
,
&
endptr
,
&
err
);
*
param
->
error
=
(
IS_TRUNCATED
(
data
,
param
->
is_unsigned
,
INT
16_MIN
,
INT16_MAX
,
UINT16_MAX
)
|
INT
_MIN16
,
INT_MAX16
,
UINT_MAX16
)
|
test
(
err
));
shortstore
(
buffer
,
(
short
)
data
);
break
;
...
...
@@ -3462,7 +3462,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
longlong
data
=
my_strntoll
(
&
my_charset_latin1
,
value
,
length
,
10
,
&
endptr
,
&
err
);
*
param
->
error
=
(
IS_TRUNCATED
(
data
,
param
->
is_unsigned
,
INT
32_MIN
,
INT32_MAX
,
UINT32_MAX
)
|
INT
_MIN32
,
INT_MAX32
,
UINT_MAX32
)
|
test
(
err
));
longstore
(
buffer
,
(
int32
)
data
);
break
;
...
...
@@ -3564,17 +3564,17 @@ static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
break
;
case
MYSQL_TYPE_TINY
:
*
param
->
error
=
IS_TRUNCATED
(
value
,
param
->
is_unsigned
,
INT
8_MIN
,
INT8_MAX
,
UINT8_MAX
);
INT
_MIN8
,
INT_MAX8
,
UINT_MAX8
);
*
(
uchar
*
)
param
->
buffer
=
(
uchar
)
value
;
break
;
case
MYSQL_TYPE_SHORT
:
*
param
->
error
=
IS_TRUNCATED
(
value
,
param
->
is_unsigned
,
INT
16_MIN
,
INT16_MAX
,
UINT16_MAX
);
INT
_MIN16
,
INT_MAX16
,
UINT_MAX16
);
shortstore
(
buffer
,
(
short
)
value
);
break
;
case
MYSQL_TYPE_LONG
:
*
param
->
error
=
IS_TRUNCATED
(
value
,
param
->
is_unsigned
,
INT
32_MIN
,
INT32_MAX
,
UINT32_MAX
);
INT
_MIN32
,
INT_MAX32
,
UINT_MAX32
);
longstore
(
buffer
,
(
int32
)
value
);
break
;
case
MYSQL_TYPE_LONGLONG
:
...
...
@@ -3978,7 +3978,7 @@ static void fetch_result_tinyint(MYSQL_BIND *param, MYSQL_FIELD *field,
my_bool
field_is_unsigned
=
test
(
field
->
flags
&
UNSIGNED_FLAG
);
uchar
data
=
**
row
;
*
(
uchar
*
)
param
->
buffer
=
data
;
*
param
->
error
=
param
->
is_unsigned
!=
field_is_unsigned
&&
data
>
INT
8_MAX
;
*
param
->
error
=
param
->
is_unsigned
!=
field_is_unsigned
&&
data
>
INT
_MAX8
;
(
*
row
)
++
;
}
...
...
@@ -3988,7 +3988,7 @@ static void fetch_result_short(MYSQL_BIND *param, MYSQL_FIELD *field,
my_bool
field_is_unsigned
=
test
(
field
->
flags
&
UNSIGNED_FLAG
);
ushort
data
=
(
ushort
)
sint2korr
(
*
row
);
shortstore
(
param
->
buffer
,
data
);
*
param
->
error
=
param
->
is_unsigned
!=
field_is_unsigned
&&
data
>
INT
16_MAX
;
*
param
->
error
=
param
->
is_unsigned
!=
field_is_unsigned
&&
data
>
INT
_MAX16
;
*
row
+=
2
;
}
...
...
@@ -3999,7 +3999,7 @@ static void fetch_result_int32(MYSQL_BIND *param,
my_bool
field_is_unsigned
=
test
(
field
->
flags
&
UNSIGNED_FLAG
);
uint32
data
=
(
uint32
)
sint4korr
(
*
row
);
longstore
(
param
->
buffer
,
data
);
*
param
->
error
=
param
->
is_unsigned
!=
field_is_unsigned
&&
data
>
INT
32_MAX
;
*
param
->
error
=
param
->
is_unsigned
!=
field_is_unsigned
&&
data
>
INT
_MAX32
;
*
row
+=
4
;
}
...
...
@@ -4009,7 +4009,7 @@ static void fetch_result_int64(MYSQL_BIND *param,
{
my_bool
field_is_unsigned
=
test
(
field
->
flags
&
UNSIGNED_FLAG
);
ulonglong
data
=
(
ulonglong
)
sint8korr
(
*
row
);
*
param
->
error
=
param
->
is_unsigned
!=
field_is_unsigned
&&
data
>
INT64
_MAX
;
*
param
->
error
=
param
->
is_unsigned
!=
field_is_unsigned
&&
data
>
LONGLONG
_MAX
;
longlongstore
(
param
->
buffer
,
data
);
*
row
+=
8
;
}
...
...
@@ -4149,7 +4149,7 @@ static my_bool is_binary_compatible(enum enum_field_types type1,
MYSQL_TYPE_DECIMAL
,
0
},
*
range_list
[]
=
{
range1
,
range2
,
range3
,
range4
},
**
range_list_end
=
range_list
+
sizeof
(
range_list
)
/
sizeof
(
*
range_list
);
enum
enum_field_types
**
range
,
*
type
;
const
enum
enum_field_types
**
range
,
*
type
;
if
(
type1
==
type2
)
return
TRUE
;
...
...
mysql-test/r/information_schema.result
View file @
56e4f4c4
...
...
@@ -590,3 +590,40 @@ TABLES
TABLE_PRIVILEGES
TABLE_CONSTRAINTS
TABLE_NAMES
use test;
create function sub1(i int) returns int
return i+1;
create table t1(f1 int);
create view t2 (c) as select f1 from t1;
create view t3 (c) as select sub1(1);
create table t4(f1 int, KEY f1_key (f1));
drop table t1;
drop function sub1;
select table_name from information_schema.views
where table_schema='test';
table_name
Warnings:
Warning 1356 View 'test.t2' references invalid table(s) or column(s) or function(s)
Warning 1356 View 'test.t3' references invalid table(s) or column(s) or function(s)
select table_name from information_schema.views
where table_schema='test';
table_name
Warnings:
Warning 1356 View 'test.t2' references invalid table(s) or column(s) or function(s)
Warning 1356 View 'test.t3' references invalid table(s) or column(s) or function(s)
select column_name from information_schema.columns
where table_schema='test';
column_name
f1
Warnings:
Warning 1356 View 'test.t2' references invalid table(s) or column(s) or function(s)
Warning 1356 View 'test.t3' references invalid table(s) or column(s) or function(s)
select index_name from information_schema.statistics where table_schema='test';
index_name
f1_key
select constraint_name from information_schema.table_constraints
where table_schema='test';
constraint_name
drop view t2;
drop view t3;
drop table t4;
mysql-test/r/init_connect.result
View file @
56e4f4c4
...
...
@@ -12,7 +12,7 @@ set GLOBAL init_connect=DEFAULT;
select @a;
@a
NULL
set global init_connect="create table t1(a char(10));\
set global init_connect="
drop table if exists t1;
create table t1(a char(10));\
insert into t1 values ('\0');insert into t1 values('abc')";
select hex(a) from t1;
hex(a)
...
...
mysql-test/r/view.result
View file @
56e4f4c4
...
...
@@ -983,10 +983,10 @@ create view v1 as select * from t1;
drop table t1;
create table t1 (col1 char(5),newcol2 char(5));
insert into v1 values('a','aa');
ERROR HY000: View 'test.v1' references invalid table(s) or column(s)
ERROR HY000: View 'test.v1' references invalid table(s) or column(s)
or function(s)
drop table t1;
select * from v1;
ERROR HY000: View 'test.v1' references invalid table(s) or column(s)
ERROR HY000: View 'test.v1' references invalid table(s) or column(s)
or function(s)
drop view v1;
create view v1 (a,a) as select 'a','a';
ERROR 42S21: Duplicate column name 'a'
...
...
@@ -1217,11 +1217,11 @@ create table t1 (s1 int);
create view v1 as select x1() from t1;
drop function x1;
select * from v1;
ERROR
42000: FUNCTION test.x1 does not exist
ERROR
HY000: View 'test.v1' references invalid table(s) or column(s) or function(s)
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MyISAM 9 Fixed 0 0 0 21474836479 1024 0 NULL # # NULL latin1_swedish_ci NULL
v1 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL
FUNCTION test.x1 does not exist
v1 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL
View 'test.v1' references invalid table(s) or column(s) or function(s)
drop view v1;
drop table t1;
create view v1 as select 99999999999999999999999999999999999999999999999999999 as col1;
...
...
@@ -1655,7 +1655,7 @@ test.t1 check status OK
drop table t1;
check table v1;
Table Op Msg_type Msg_text
test.v1 check error View 'test.v1' references invalid table(s) or column(s)
test.v1 check error View 'test.v1' references invalid table(s) or column(s)
or function(s)
drop view v1;
create table t1 (a int);
create table t2 (a int);
...
...
mysql-test/t/information_schema.test
View file @
56e4f4c4
...
...
@@ -292,3 +292,29 @@ use test;
show
tables
;
use
information_schema
;
show
tables
like
"T%"
;
#
# Bug#7212: information_schema: "Can't find file" errors if storage engine gone
# Bug#7211: information_schema: crash if bad view
#
use
test
;
create
function
sub1
(
i
int
)
returns
int
return
i
+
1
;
create
table
t1
(
f1
int
);
create
view
t2
(
c
)
as
select
f1
from
t1
;
create
view
t3
(
c
)
as
select
sub1
(
1
);
create
table
t4
(
f1
int
,
KEY
f1_key
(
f1
));
drop
table
t1
;
drop
function
sub1
;
select
table_name
from
information_schema
.
views
where
table_schema
=
'test'
;
select
table_name
from
information_schema
.
views
where
table_schema
=
'test'
;
select
column_name
from
information_schema
.
columns
where
table_schema
=
'test'
;
select
index_name
from
information_schema
.
statistics
where
table_schema
=
'test'
;
select
constraint_name
from
information_schema
.
table_constraints
where
table_schema
=
'test'
;
drop
view
t2
;
drop
view
t3
;
drop
table
t4
;
mysql-test/t/init_connect.test
View file @
56e4f4c4
...
...
@@ -19,7 +19,7 @@ connect (con3,localhost,user_1,,);
connection
con3
;
select
@
a
;
connection
con0
;
set
global
init_connect
=
"create table t1(a char(10));\
set
global
init_connect
=
"
drop table if exists t1;
create table t1(a char(10));\
insert into t1 values ('
\0
');insert into t1 values('abc')"
;
connect
(
con4
,
localhost
,
user_1
,,);
connection
con4
;
...
...
mysql-test/t/view.test
View file @
56e4f4c4
...
...
@@ -1169,7 +1169,7 @@ create function x1 () returns int return 5;
create table t1 (s1 int);
create view v1 as select x1() from t1;
drop function x1;
-- error 13
05
-- error 13
56
select * from v1;
--replace_column 12 # 13 #
--replace_result "2147483647 " "21474836479 "
...
...
sql/share/errmsg.txt
View file @
56e4f4c4
...
...
@@ -5464,10 +5464,9 @@ ER_WARN_VIEW_WITHOUT_KEY
serbian "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
ukr "View, , ͦ æ(), Ҧ "
ER_VIEW_INVALID
eng "View '%-.64s.%-.64s' references invalid table(s) or column(s)"
rus "View '%-.64s.%-.64s' "
eng "View '%-.64s.%-.64s' references invalid table(s) or column(s)
or function(s)
"
rus "View '%-.64s.%-.64s'
"
serbian "Can't drop a %s from within another stored routine"
ukr "View '%-.64s.%-.64s' Ŧަ æ æ"
ER_SP_NO_DROP_SP
eng "Can't drop a %s from within another stored routine"
serbian "GOTO is not allowed in a stored procedure handler"
...
...
sql/sp.cc
View file @
56e4f4c4
...
...
@@ -981,6 +981,7 @@ sp_cache_functions(THD *thd, LEX *lex)
thd
->
lex
=
newlex
;
newlex
->
proc_table
=
oldlex
->
proc_table
;
// hint if mysql.oper is opened
newlex
->
current_select
=
NULL
;
name
.
m_name
.
str
=
strchr
(
name
.
m_qname
.
str
,
'.'
);
name
.
m_db
.
length
=
name
.
m_name
.
str
-
name
.
m_qname
.
str
;
name
.
m_db
.
str
=
strmake_root
(
thd
->
mem_root
,
...
...
sql/sql_derived.cc
View file @
56e4f4c4
...
...
@@ -140,6 +140,18 @@ int mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list)
derived_result
->
set_table
(
table
);
exit:
/* Hide "Unknown column" or "Unknown function" error */
if
(
orig_table_list
->
view
)
{
if
(
thd
->
net
.
last_errno
==
ER_BAD_FIELD_ERROR
||
thd
->
net
.
last_errno
==
ER_SP_DOES_NOT_EXIST
)
{
thd
->
clear_error
();
my_error
(
ER_VIEW_INVALID
,
MYF
(
0
),
orig_table_list
->
db
,
orig_table_list
->
real_name
);
}
}
/*
if it is preparation PS only or commands that need only VIEW structure
then we do not need real data and we can skip execution (and parameters
...
...
sql/sql_select.cc
View file @
56e4f4c4
...
...
@@ -11654,8 +11654,21 @@ calc_group_buffer(JOIN *join,ORDER *group)
key_length
+=
sizeof
(
double
);
else
if
((
*
group
->
item
)
->
result_type
()
==
INT_RESULT
)
key_length
+=
sizeof
(
longlong
);
else
if
((
*
group
->
item
)
->
result_type
()
==
STRING_RESULT
)
{
/*
Group strings are taken as varstrings and require an length field.
A field is not yet created by create_tmp_field()
and the sizes should match up.
*/
key_length
+=
(
*
group
->
item
)
->
max_length
+
HA_KEY_BLOB_LENGTH
;
}
else
key_length
+=
(
*
group
->
item
)
->
max_length
;
{
/* This case should never be choosen */
DBUG_ASSERT
(
0
);
current_thd
->
fatal_error
();
}
parts
++
;
if
((
*
group
->
item
)
->
maybe_null
)
null_parts
++
;
...
...
sql/sql_show.cc
View file @
56e4f4c4
...
...
@@ -2374,12 +2374,24 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables,
const
char
*
file_name
)
{
TIME
time
;
const
char
*
wild
=
thd
->
lex
->
wild
?
thd
->
lex
->
wild
->
ptr
()
:
NullS
;
LEX
*
lex
=
thd
->
lex
;
const
char
*
wild
=
lex
->
wild
?
lex
->
wild
->
ptr
()
:
NullS
;
CHARSET_INFO
*
cs
=
system_charset_info
;
DBUG_ENTER
(
"get_schema_column_record"
);
if
(
res
)
{
DBUG_RETURN
(
1
);
if
(
lex
->
orig_sql_command
!=
SQLCOM_SHOW_FIELDS
)
{
/*
I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
rather than in SHOW COLUMNS
*/
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
thd
->
net
.
last_errno
,
thd
->
net
.
last_error
);
thd
->
clear_error
();
res
=
0
;
}
DBUG_RETURN
(
res
);
}
TABLE
*
show_table
=
tables
->
table
;
...
...
@@ -2745,7 +2757,23 @@ static int get_schema_stat_record(THD *thd, struct st_table_list *tables,
{
CHARSET_INFO
*
cs
=
system_charset_info
;
DBUG_ENTER
(
"get_schema_stat_record"
);
if
(
!
res
&&
!
tables
->
view
)
if
(
res
)
{
if
(
thd
->
lex
->
orig_sql_command
!=
SQLCOM_SHOW_KEYS
)
{
/*
I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
rather than in SHOW KEYS
*/
if
(
!
tables
->
view
)
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
thd
->
net
.
last_errno
,
thd
->
net
.
last_error
);
thd
->
clear_error
();
res
=
0
;
}
DBUG_RETURN
(
res
);
}
else
if
(
!
tables
->
view
)
{
TABLE
*
show_table
=
tables
->
table
;
KEY
*
key_info
=
show_table
->
key_info
;
...
...
@@ -2843,7 +2871,14 @@ static int get_schema_views_record(THD *thd, struct st_table_list *tables,
table
->
file
->
write_row
(
table
->
record
[
0
]);
}
}
DBUG_RETURN
(
res
);
else
{
if
(
tables
->
view
)
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
thd
->
net
.
last_errno
,
thd
->
net
.
last_error
);
thd
->
clear_error
();
}
DBUG_RETURN
(
0
);
}
...
...
@@ -2868,7 +2903,15 @@ static int get_schema_constraints_record(THD *thd, struct st_table_list *tables,
const
char
*
file_name
)
{
DBUG_ENTER
(
"get_schema_constraints_record"
);
if
(
!
res
&&
!
tables
->
view
)
if
(
res
)
{
if
(
!
tables
->
view
)
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
thd
->
net
.
last_errno
,
thd
->
net
.
last_error
);
thd
->
clear_error
();
DBUG_RETURN
(
0
);
}
else
if
(
!
tables
->
view
)
{
List
<
FOREIGN_KEY_INFO
>
f_key_list
;
TABLE
*
show_table
=
tables
->
table
;
...
...
@@ -2925,7 +2968,15 @@ static int get_schema_key_column_usage_record(THD *thd,
{
DBUG_ENTER
(
"get_schema_key_column_usage_record"
);
CHARSET_INFO
*
cs
=
system_charset_info
;
if
(
!
res
&&
!
tables
->
view
)
if
(
res
)
{
if
(
!
tables
->
view
)
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
thd
->
net
.
last_errno
,
thd
->
net
.
last_error
);
thd
->
clear_error
();
DBUG_RETURN
(
0
);
}
else
if
(
!
tables
->
view
)
{
List
<
FOREIGN_KEY_INFO
>
f_key_list
;
TABLE
*
show_table
=
tables
->
table
;
...
...
sql/table.cc
View file @
56e4f4c4
...
...
@@ -1845,8 +1845,9 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds,
DBUG_RETURN
(
0
);
err:
/* Hide "Unknown column" error */
if
(
thd
->
net
.
last_errno
==
ER_BAD_FIELD_ERROR
)
/* Hide "Unknown column" or "Unknown function" error */
if
(
thd
->
net
.
last_errno
==
ER_BAD_FIELD_ERROR
||
thd
->
net
.
last_errno
==
ER_SP_DOES_NOT_EXIST
)
{
thd
->
clear_error
();
my_error
(
ER_VIEW_INVALID
,
MYF
(
0
),
view_db
.
str
,
view_name
.
str
);
...
...
tests/client_test.c
View file @
56e4f4c4
...
...
@@ -12065,6 +12065,7 @@ static void test_truncation()
MYSQL_STMT
*
stmt
;
const
char
*
stmt_text
;
int
rc
;
uint
bind_count
;
MYSQL_BIND
*
bind_array
,
*
bind
;
myheader
(
"test_truncation"
);
...
...
@@ -12112,7 +12113,7 @@ static void test_truncation()
check_execute
(
stmt
,
rc
);
rc
=
mysql_stmt_execute
(
stmt
);
check_execute
(
stmt
,
rc
);
uint
bind_count
=
(
uint
)
mysql_stmt_field_count
(
stmt
);
bind_count
=
(
uint
)
mysql_stmt_field_count
(
stmt
);
/*************** Fill in the bind structure and bind it **************/
bind_array
=
malloc
(
sizeof
(
MYSQL_BIND
)
*
bind_count
);
...
...
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