Commit 897ea374 authored by Patrick Crews's avatar Patrick Crews

merge

parents 1f847d16 f7f0e8b4
...@@ -1691,3 +1691,15 @@ FROM t1; ...@@ -1691,3 +1691,15 @@ FROM t1;
ERROR 21000: Subquery returns more than 1 row ERROR 21000: Subquery returns more than 1 row
DROP TABLE t1; DROP TABLE t1;
SET @@sql_mode = @old_sql_mode; SET @@sql_mode = @old_sql_mode;
SET @old_sql_mode = @@sql_mode;
SET @@sql_mode='ONLY_FULL_GROUP_BY';
CREATE TABLE t1(i INT);
INSERT INTO t1 VALUES (1), (10);
SELECT COUNT(i) FROM t1;
COUNT(i)
2
SELECT COUNT(i) FROM t1 WHERE i > 1;
COUNT(i)
1
DROP TABLE t1;
SET @@sql_mode = @old_sql_mode;
...@@ -921,6 +921,32 @@ c4 ...@@ -921,6 +921,32 @@ c4
DROP DATABASE mysqltest1; DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2; DROP DATABASE mysqltest2;
DROP USER mysqltest_u1@localhost; DROP USER mysqltest_u1@localhost;
CREATE DATABASE db1;
USE db1;
CREATE TABLE t1(f1 INT, f2 INT);
CREATE VIEW v1 AS SELECT f1, f2 FROM t1;
GRANT SELECT (f1) ON t1 TO foo;
GRANT SELECT (f1) ON v1 TO foo;
USE db1;
SELECT f1 FROM t1;
f1
SELECT f2 FROM t1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'f2' in table 't1'
SELECT * FROM t1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 't1'
SELECT f1 FROM v1;
f1
SELECT f2 FROM v1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for column 'f2' in table 'v1'
SELECT * FROM v1;
ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 'v1'
USE test;
REVOKE SELECT (f1) ON db1.t1 FROM foo;
REVOKE SELECT (f1) ON db1.v1 FROM foo;
DROP USER foo;
DROP VIEW db1.v1;
DROP TABLE db1.t1;
DROP DATABASE db1;
End of 5.0 tests. End of 5.0 tests.
DROP VIEW IF EXISTS v1; DROP VIEW IF EXISTS v1;
DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t1;
......
...@@ -18,6 +18,8 @@ insert into t1 values (3,5,"C"); ...@@ -18,6 +18,8 @@ insert into t1 values (3,5,"C");
insert into t1 values (3,6,"D"); insert into t1 values (3,6,"D");
# Test of MySQL field extension with and without matching records. # Test of MySQL field extension with and without matching records.
#### Note: The two following statements may fail if the execution plan
#### or optimizer is changed. The result for column c is undefined.
select a,c,sum(a) from t1 group by a; select a,c,sum(a) from t1 group by a;
select a,c,sum(a) from t1 where a > 10 group by a; select a,c,sum(a) from t1 where a > 10 group by a;
select sum(a) from t1 where a > 10; select sum(a) from t1 where a > 10;
......
...@@ -1139,4 +1139,22 @@ DROP TABLE t1; ...@@ -1139,4 +1139,22 @@ DROP TABLE t1;
SET @@sql_mode = @old_sql_mode; SET @@sql_mode = @old_sql_mode;
#
# Bug#42567 Invalid GROUP BY error
#
# Setup of the subtest
SET @old_sql_mode = @@sql_mode;
SET @@sql_mode='ONLY_FULL_GROUP_BY';
CREATE TABLE t1(i INT);
INSERT INTO t1 VALUES (1), (10);
# The actual test
SELECT COUNT(i) FROM t1;
SELECT COUNT(i) FROM t1 WHERE i > 1;
# Cleanup of subtest
DROP TABLE t1;
SET @@sql_mode = @old_sql_mode;
...@@ -946,8 +946,13 @@ set global max_prepared_stmt_count=3; ...@@ -946,8 +946,13 @@ set global max_prepared_stmt_count=3;
select @@max_prepared_stmt_count; select @@max_prepared_stmt_count;
show status like 'prepared_stmt_count'; show status like 'prepared_stmt_count';
prepare stmt from "select 1"; prepare stmt from "select 1";
connect (con1,localhost,root,,); connect (con1,localhost,root,,);
# Switch to connection con1
connection con1; connection con1;
let $con1_id=`SELECT CONNECTION_ID()`;
prepare stmt from "select 2"; prepare stmt from "select 2";
prepare stmt1 from "select 3"; prepare stmt1 from "select 3";
--error ER_MAX_PREPARED_STMT_COUNT_REACHED --error ER_MAX_PREPARED_STMT_COUNT_REACHED
...@@ -957,18 +962,17 @@ connection default; ...@@ -957,18 +962,17 @@ connection default;
prepare stmt2 from "select 4"; prepare stmt2 from "select 4";
select @@max_prepared_stmt_count; select @@max_prepared_stmt_count;
show status like 'prepared_stmt_count'; show status like 'prepared_stmt_count';
# Disconnect connection con1 and switch to default connection
disconnect con1; disconnect con1;
connection default; connection default;
# Wait for the connection to die: deal with a possible race
# Wait for the connection con1 to die
let $wait_condition=SELECT COUNT(*)=0 FROM information_schema.processlist WHERE id=$con1_id;
--source include/wait_condition.inc
deallocate prepare stmt; deallocate prepare stmt;
let $query= select variable_value from information_schema.global_status
where variable_name = 'prepared_stmt_count';
let $count= `$query`;
if ($count)
{
--sleep 1
let $count= `$query`;
}
select @@max_prepared_stmt_count; select @@max_prepared_stmt_count;
show status like 'prepared_stmt_count'; show status like 'prepared_stmt_count';
# #
......
...@@ -1191,6 +1191,46 @@ DROP DATABASE mysqltest1; ...@@ -1191,6 +1191,46 @@ DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2; DROP DATABASE mysqltest2;
DROP USER mysqltest_u1@localhost; DROP USER mysqltest_u1@localhost;
#
# Bug #41354: Access control is bypassed when all columns of a view are
# selected by * wildcard
CREATE DATABASE db1;
USE db1;
CREATE TABLE t1(f1 INT, f2 INT);
CREATE VIEW v1 AS SELECT f1, f2 FROM t1;
GRANT SELECT (f1) ON t1 TO foo;
GRANT SELECT (f1) ON v1 TO foo;
connect (addconfoo, localhost, foo,,);
connection addconfoo;
USE db1;
SELECT f1 FROM t1;
--error ER_COLUMNACCESS_DENIED_ERROR
SELECT f2 FROM t1;
--error ER_TABLEACCESS_DENIED_ERROR
SELECT * FROM t1;
SELECT f1 FROM v1;
--error ER_COLUMNACCESS_DENIED_ERROR
SELECT f2 FROM v1;
--error ER_TABLEACCESS_DENIED_ERROR
SELECT * FROM v1;
connection default;
USE test;
disconnect addconfoo;
REVOKE SELECT (f1) ON db1.t1 FROM foo;
REVOKE SELECT (f1) ON db1.v1 FROM foo;
DROP USER foo;
DROP VIEW db1.v1;
DROP TABLE db1.t1;
DROP DATABASE db1;
--echo End of 5.0 tests. --echo End of 5.0 tests.
......
...@@ -573,7 +573,8 @@ bool Protocol::send_fields(List<Item> *list, uint flags) ...@@ -573,7 +573,8 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
else else
{ {
/* With conversion */ /* With conversion */
uint max_char_len; ulonglong max_length;
uint32 field_length;
int2store(pos, thd_charset->number); int2store(pos, thd_charset->number);
/* /*
For TEXT/BLOB columns, field_length describes the maximum data For TEXT/BLOB columns, field_length describes the maximum data
...@@ -584,12 +585,22 @@ bool Protocol::send_fields(List<Item> *list, uint flags) ...@@ -584,12 +585,22 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
char_count * mbmaxlen, where character count is taken from the char_count * mbmaxlen, where character count is taken from the
definition of the column. In other words, the maximum number definition of the column. In other words, the maximum number
of characters here is limited by the column definition. of characters here is limited by the column definition.
When one has a LONG TEXT column with a single-byte
character set, and the connection character set is multi-byte, the
client may get fields longer than UINT_MAX32, due to
<character set column> -> <character set connection> conversion.
In that case column max length does not fit into the 4 bytes
reserved for it in the protocol.
*/ */
max_char_len= (field.type >= (int) MYSQL_TYPE_TINY_BLOB && max_length= (field.type >= MYSQL_TYPE_TINY_BLOB &&
field.type <= (int) MYSQL_TYPE_BLOB) ? field.type <= MYSQL_TYPE_BLOB) ?
field.length / item->collation.collation->mbminlen : field.length / item->collation.collation->mbminlen :
field.length / item->collation.collation->mbmaxlen; field.length / item->collation.collation->mbmaxlen;
int4store(pos+2, max_char_len * thd_charset->mbmaxlen); max_length*= thd_charset->mbmaxlen;
field_length= (max_length > UINT_MAX32) ?
UINT_MAX32 : (uint32) max_length;
int4store(pos + 2, field_length);
} }
pos[6]= field.type; pos[6]= field.type;
int2store(pos+7,field.flags); int2store(pos+7,field.flags);
......
...@@ -723,6 +723,7 @@ static void do_verify_prepare_field(MYSQL_RES *result, ...@@ -723,6 +723,7 @@ static void do_verify_prepare_field(MYSQL_RES *result,
{ {
MYSQL_FIELD *field; MYSQL_FIELD *field;
CHARSET_INFO *cs; CHARSET_INFO *cs;
ulonglong expected_field_length;
if (!(field= mysql_fetch_field_direct(result, no))) if (!(field= mysql_fetch_field_direct(result, no)))
{ {
...@@ -731,6 +732,8 @@ static void do_verify_prepare_field(MYSQL_RES *result, ...@@ -731,6 +732,8 @@ static void do_verify_prepare_field(MYSQL_RES *result,
} }
cs= get_charset(field->charsetnr, 0); cs= get_charset(field->charsetnr, 0);
DIE_UNLESS(cs); DIE_UNLESS(cs);
if ((expected_field_length= length * cs->mbmaxlen) > UINT_MAX32)
expected_field_length= UINT_MAX32;
if (!opt_silent) if (!opt_silent)
{ {
fprintf(stdout, "\n field[%d]:", no); fprintf(stdout, "\n field[%d]:", no);
...@@ -745,8 +748,8 @@ static void do_verify_prepare_field(MYSQL_RES *result, ...@@ -745,8 +748,8 @@ static void do_verify_prepare_field(MYSQL_RES *result,
fprintf(stdout, "\n org_table:`%s`\t(expected: `%s`)", fprintf(stdout, "\n org_table:`%s`\t(expected: `%s`)",
field->org_table, org_table); field->org_table, org_table);
fprintf(stdout, "\n database :`%s`\t(expected: `%s`)", field->db, db); fprintf(stdout, "\n database :`%s`\t(expected: `%s`)", field->db, db);
fprintf(stdout, "\n length :`%lu`\t(expected: `%lu`)", fprintf(stdout, "\n length :`%lu`\t(expected: `%llu`)",
field->length, length * cs->mbmaxlen); field->length, expected_field_length);
fprintf(stdout, "\n maxlength:`%ld`", field->max_length); fprintf(stdout, "\n maxlength:`%ld`", field->max_length);
fprintf(stdout, "\n charsetnr:`%d`", field->charsetnr); fprintf(stdout, "\n charsetnr:`%d`", field->charsetnr);
fprintf(stdout, "\n default :`%s`\t(expected: `%s`)", fprintf(stdout, "\n default :`%s`\t(expected: `%s`)",
...@@ -782,11 +785,11 @@ static void do_verify_prepare_field(MYSQL_RES *result, ...@@ -782,11 +785,11 @@ static void do_verify_prepare_field(MYSQL_RES *result,
as utf8. Field length is calculated as number of characters * maximum as utf8. Field length is calculated as number of characters * maximum
number of bytes a character can occupy. number of bytes a character can occupy.
*/ */
if (length && field->length != length * cs->mbmaxlen) if (length && (field->length != expected_field_length))
{ {
fprintf(stderr, "Expected field length: %d, got length: %d\n", fprintf(stderr, "Expected field length: %llu, got length: %lu\n",
(int) (length * cs->mbmaxlen), (int) field->length); expected_field_length, field->length);
DIE_UNLESS(field->length == length * cs->mbmaxlen); DIE_UNLESS(field->length == expected_field_length);
} }
if (def) if (def)
DIE_UNLESS(strcmp(field->def, def) == 0); DIE_UNLESS(strcmp(field->def, def) == 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment