Skip to content

Commit

Permalink
Added JSON validation for db_metadata option during CREATE and ALTER …
Browse files Browse the repository at this point in the history
…DATABASE parsing

Summary: Added logic to validate that the string given for DB_METADATA option in CREATE and ALTER DATABASE commands.

Reviewed By: abhinav04sharma

Differential Revision: D5530251

fbshipit-source-id: fef1d6d
  • Loading branch information
yashtc authored and facebook-github-bot committed Aug 3, 2017
1 parent 5a42ae6 commit a21e84f
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 24 deletions.
8 changes: 6 additions & 2 deletions mysql-test/r/db_metadata.result
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ default-character-set=utf8
default-collation=utf8_general_ci
db-read-only=1
db-metadata={"shard":"test9_shard"}
create database test10 db_metadata = "invalid_json";
ERROR HY000: Invalid JSON for DB_METADATA attribute: invalid_json.
alter database test3 character set ascii;
show create database test3;
Database Create Database
Expand Down Expand Up @@ -134,7 +136,7 @@ default-character-set=utf8
default-collation=utf8_general_ci
db-read-only=0
db-metadata={"shard":"Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Fin"}
alter database test5 db_metadata "{\"shard\":\"Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Fin\"}";;
alter database test5 db_metadata "{\"shard\":\"Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Fin\"}";
ERROR HY000: Metadata for the database is too long. Max length is 1024 bytes
alter database test6 character set ascii db_metadata = "{\"shard\":\"test6_shard_altered\"}";
show create database test6;
Expand Down Expand Up @@ -174,8 +176,10 @@ information_schema CREATE DATABASE `information_schema` /*!40100 DEFAULT CHARACT
show create database mysql;
Database Create Database
mysql CREATE DATABASE `mysql` /*!40100 DEFAULT CHARACTER SET latin1 */
alter database information_schema db_metadata "{\"shard\":\"is_shard\"}";;
alter database information_schema db_metadata "{\"shard\":\"is_shard\"}";
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
alter database test9 db_metadata = "invalid_json";
ERROR HY000: Invalid JSON for DB_METADATA attribute: invalid_json.
drop database if exists test2;
drop database if exists test3;
drop database if exists test4;
Expand Down
52 changes: 30 additions & 22 deletions mysql-test/t/db_metadata.test
Original file line number Diff line number Diff line change
Expand Up @@ -25,114 +25,122 @@ file_exists $MYSQLD_DATADIR/test/db.opt;
# create database without any options
create database test2;
show create database test2;
--exec cat $MYSQLD_DATADIR/test2/db.opt;
--exec cat $MYSQLD_DATADIR/test2/db.opt

# create database with character set
create database test3 character set utf8;
show create database test3;
--exec cat $MYSQLD_DATADIR/test3/db.opt;
--exec cat $MYSQLD_DATADIR/test3/db.opt

# create database with read only
create database test4 read_only = true;
show create database test4;
--exec cat $MYSQLD_DATADIR/test4/db.opt;
--exec cat $MYSQLD_DATADIR/test4/db.opt

# create database with db metadata
create database test5 db_metadata = "{\"shard\":\"test5_shard\"}";
show create database test5;
--exec cat $MYSQLD_DATADIR/test5/db.opt;
--exec cat $MYSQLD_DATADIR/test5/db.opt

# create database with character set and db metadata
create database test6 character set utf8 db_metadata = "{\"shard\":\"test6_shard\"}";
show create database test6;
--exec cat $MYSQLD_DATADIR/test6/db.opt;
--exec cat $MYSQLD_DATADIR/test6/db.opt

# create database with read only and db metadata
create database test7 read_only = true db_metadata = "{\"shard\":\"test7_shard\"}";
show create database test7;
--exec cat $MYSQLD_DATADIR/test7/db.opt;
--exec cat $MYSQLD_DATADIR/test7/db.opt

# create database with character set and read only
create database test8 character set utf8 read_only = true;
show create database test8;
--exec cat $MYSQLD_DATADIR/test8/db.opt;
--exec cat $MYSQLD_DATADIR/test8/db.opt

# create database with character set, read only and db metadata
create database test9 character set utf8 read_only = true db_metadata = "{\"shard\":\"test9_shard\"}";
show create database test9;
--exec cat $MYSQLD_DATADIR/test9/db.opt;
--exec cat $MYSQLD_DATADIR/test9/db.opt

# create database with invalid JSON string for db_metadata
--error ER_DB_METADATA_INVALID_JSON
create database test10 db_metadata = "invalid_json";

# alter database tests

# alter database character set
alter database test3 character set ascii;
show create database test3;
--exec cat $MYSQLD_DATADIR/test3/db.opt;
--exec cat $MYSQLD_DATADIR/test3/db.opt

# alter database read only
alter database test4 read_only = true;
show create database test4;
--exec cat $MYSQLD_DATADIR/test4/db.opt;
--exec cat $MYSQLD_DATADIR/test4/db.opt

# alter database db metadata
alter database test5 db_metadata = "{\"shard\":\"test5_shard_altered\"}";
show create database test5;
--exec cat $MYSQLD_DATADIR/test5/db.opt;
--exec cat $MYSQLD_DATADIR/test5/db.opt

# alter database character set but keep db metadata intact
alter database test5 character set ascii;
show create database test5;
--exec cat $MYSQLD_DATADIR/test5/db.opt;
--exec cat $MYSQLD_DATADIR/test5/db.opt

# alter database read only but keep db metadata intact
alter database test5 read_only = true;
show create database test5;
--exec cat $MYSQLD_DATADIR/test5/db.opt;
--exec cat $MYSQLD_DATADIR/test5/db.opt

# alter database character set and read only but keep db metadata intact
alter database test5 character set utf8 read_only = false;
show create database test5;
--exec cat $MYSQLD_DATADIR/test5/db.opt;
--exec cat $MYSQLD_DATADIR/test5/db.opt

# alter database reset db metadata
alter database test5 db_metadata "";
show create database test5;
--exec cat $MYSQLD_DATADIR/test5/db.opt;
--exec cat $MYSQLD_DATADIR/test5/db.opt

# alter database set db metadata to max length string
alter database test5 db_metadata "{\"shard\":\"Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Fin\"}";
show create database test5;
--exec cat $MYSQLD_DATADIR/test5/db.opt;
--exec cat $MYSQLD_DATADIR/test5/db.opt

# alter database exceed db metadata max length
--error ER_DB_METADATA_TOO_LONG
--eval alter database test5 db_metadata \"{\\\"shard\\\":\\\"Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Fin\\\"}\";
alter database test5 db_metadata "{\"shard\":\"Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Really long shard name. Fin\"}";

# alter database character set and db metadata
alter database test6 character set ascii db_metadata = "{\"shard\":\"test6_shard_altered\"}";
show create database test6;
--exec cat $MYSQLD_DATADIR/test6/db.opt;
--exec cat $MYSQLD_DATADIR/test6/db.opt

# alter database read only and db metadata
alter database test7 read_only = true db_metadata = "{\"shard\":\"test7_shard_altered\"}";
show create database test7;
--exec cat $MYSQLD_DATADIR/test7/db.opt;
--exec cat $MYSQLD_DATADIR/test7/db.opt

# alter database character set and read only
alter database test8 character set ascii read_only = true;
show create database test8;
--exec cat $MYSQLD_DATADIR/test8/db.opt;
--exec cat $MYSQLD_DATADIR/test8/db.opt

# alter database character set, read only and db metadata
alter database test9 character set ascii read_only = true db_metadata = "{\"shard\":\"test9_shard_altered\"}";
show create database test9;
--exec cat $MYSQLD_DATADIR/test9/db.opt;
--exec cat $MYSQLD_DATADIR/test9/db.opt

# ensure information_schema and mysql tables are intact
show create database information_schema;
show create database mysql;
--error ER_DBACCESS_DENIED_ERROR
--eval alter database information_schema db_metadata \"{\\"shard\\":\\"is_shard\\"}\";
alter database information_schema db_metadata "{\"shard\":\"is_shard\"}";

# alter database with invalid JSON string for db_metadata
--error ER_DB_METADATA_INVALID_JSON
alter database test9 db_metadata = "invalid_json";

# cleanup
--disable_warnings
Expand Down
3 changes: 3 additions & 0 deletions sql/share/errmsg-utf8.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7326,6 +7326,9 @@ ER_SLAVE_WORKER_STOPPED_PREVIOUS_THD_ERROR
ER_DB_METADATA_TOO_LONG
eng "Metadata for the database is too long. Max length is %d bytes"

ER_DB_METADATA_INVALID_JSON
eng "Invalid JSON for DB_METADATA attribute: %s."

ER_DB_METADATA_READ_ERROR
eng "Error reading db metadata option: '%-.64s'"

Expand Down
19 changes: 19 additions & 0 deletions sql/sql_yacc.yy
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ Note: YYTHD is passed as an argument to yyparse(), and subsequently to yylex().
#include "opt_explain_traditional.h"
#include "opt_explain_json.h"
#include "lex_token.h"
#include <sstream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

/* this is to get the bison compilation windows warnings out */
#ifdef _MSC_VER
Expand Down Expand Up @@ -6558,6 +6561,22 @@ db_metadata_str:
my_error(ER_DB_METADATA_TOO_LONG, MYF(0), DB_METADATA_MAX_LENGTH);
MYSQL_YYABORT;
}
/* Verify that a valid JSON is provided */
if ($3.length > 0)
{
boost::property_tree::ptree db_metadata_root;
std::istringstream is($3.str);
try
{
boost::property_tree::json_parser::read_json(is,
db_metadata_root);
}
catch (std::exception)
{
my_error(ER_DB_METADATA_INVALID_JSON, MYF(0), $3.str);
MYSQL_YYABORT;
}
}
Lex->create_info.db_metadata= String($3.str, $3.length,
&my_charset_bin);
}
Expand Down

0 comments on commit a21e84f

Please sign in to comment.