summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/partition_symlink.result2
-rw-r--r--mysql-test/t/partition_symlink.test2
-rw-r--r--sql/partition_info.cc26
-rw-r--r--sql/partition_info.h13
-rw-r--r--sql/sql_parse.cc19
5 files changed, 59 insertions, 3 deletions
diff --git a/mysql-test/r/partition_symlink.result b/mysql-test/r/partition_symlink.result
index f26a1642a52..91cc78f1361 100644
--- a/mysql-test/r/partition_symlink.result
+++ b/mysql-test/r/partition_symlink.result
@@ -4,6 +4,8 @@ DROP DATABASE IF EXISTS mysqltest2;
# test.t1 have partitions in mysqltest2-directory!
# user root:
CREATE USER mysqltest_1@localhost;
+# Need FILE permission to use external datadir or indexdir.
+GRANT FILE ON *.* TO mysqltest_1@localhost;
CREATE DATABASE mysqltest2;
USE mysqltest2;
CREATE TABLE t1 (a INT) ENGINE = MyISAM;
diff --git a/mysql-test/t/partition_symlink.test b/mysql-test/t/partition_symlink.test
index 5fdde8e0abc..9e57d616213 100644
--- a/mysql-test/t/partition_symlink.test
+++ b/mysql-test/t/partition_symlink.test
@@ -32,6 +32,8 @@ DROP DATABASE IF EXISTS mysqltest2;
-- echo # test.t1 have partitions in mysqltest2-directory!
-- echo # user root:
CREATE USER mysqltest_1@localhost;
+-- echo # Need FILE permission to use external datadir or indexdir.
+ GRANT FILE ON *.* TO mysqltest_1@localhost;
CREATE DATABASE mysqltest2;
USE mysqltest2;
CREATE TABLE t1 (a INT) ENGINE = MyISAM;
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index a0d09557b81..cd17e3366cf 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -2550,6 +2550,30 @@ void partition_info::print_debug(const char *str, uint *value)
DBUG_PRINT("info", ("parser: %s", str));
DBUG_VOID_RETURN;
}
+
+bool has_external_data_or_index_dir(partition_info &pi)
+{
+ List_iterator<partition_element> part_it(pi.partitions);
+ for (partition_element *part= part_it++; part; part= part_it++)
+ {
+ if (part->data_file_name != NULL || part->index_file_name != NULL)
+ {
+ return true;
+ }
+ List_iterator<partition_element> subpart_it(part->subpartitions);
+ for (const partition_element *subpart= subpart_it++;
+ subpart;
+ subpart= subpart_it++)
+ {
+ if (subpart->data_file_name != NULL || subpart->index_file_name != NULL)
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
#else /* WITH_PARTITION_STORAGE_ENGINE */
/*
For builds without partitioning we need to define these functions
diff --git a/sql/partition_info.h b/sql/partition_info.h
index 7bfbf8a1b1a..7ff6abeebd2 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -1,7 +1,7 @@
#ifndef PARTITION_INFO_INCLUDED
#define PARTITION_INFO_INCLUDED
-/* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -349,4 +349,15 @@ void init_all_partitions_iterator(partition_info *part_info,
part_iter->get_next= get_next_partition_id_range;
}
+/**
+ Predicate which returns true if any partition or subpartition uses
+ an external data directory or external index directory.
+
+ @param pi partitioning information
+ @retval true if any partition or subpartition has an external
+ data directory or external index directory.
+ @retval false otherwise
+ */
+bool has_external_data_or_index_dir(partition_info &pi);
+
#endif /* PARTITION_INFO_INCLUDED */
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index ac3901997f3..18cb758c9b5 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -35,6 +35,9 @@
#include "sql_insert.h" // mysql_insert
#include "sql_update.h" // mysql_update, mysql_multi_update
#include "sql_partition.h" // struct partition_info
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+#include "partition_info.h" // has_external_data_or_index_dir
+#endif /* WITH_PARTITION_STORAGE_ENGINE */
#include "sql_db.h" // mysql_change_db, mysql_create_db,
// mysql_rm_db, mysql_upgrade_db,
// mysql_alter_db,
@@ -2413,7 +2416,6 @@ case SQLCOM_PREPARE:
copy.
*/
Alter_info alter_info(lex->alter_info, thd->mem_root);
-
if (thd->is_fatal_error)
{
/* If out of memory when creating a copy of alter_info. */
@@ -2421,6 +2423,15 @@ case SQLCOM_PREPARE:
goto end_with_restore_list;
}
+ if (((lex->create_info.used_fields & HA_CREATE_USED_DATADIR) != 0 ||
+ (lex->create_info.used_fields & HA_CREATE_USED_INDEXDIR) != 0) &&
+ check_access(thd, FILE_ACL, NULL, NULL, NULL, FALSE, FALSE))
+ {
+ res= 1;
+ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "FILE");
+ goto end_with_restore_list;
+ }
+
if ((res= create_table_precheck(thd, select_tables, create_table)))
goto end_with_restore_list;
@@ -2458,6 +2469,12 @@ case SQLCOM_PREPARE:
#ifdef WITH_PARTITION_STORAGE_ENGINE
{
partition_info *part_info= thd->lex->part_info;
+ if (part_info != NULL && has_external_data_or_index_dir(*part_info) &&
+ check_access(thd, FILE_ACL, NULL, NULL, NULL, FALSE, FALSE))
+ {
+ res= -1;
+ goto end_with_restore_list;
+ }
if (part_info && !(part_info= thd->lex->part_info->get_clone(true)))
{
res= -1;