summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorstewart@mysql.com <>2006-02-02 00:52:32 +1100
committerstewart@mysql.com <>2006-02-02 00:52:32 +1100
commit72b9f287df769770230f21e967afcab52f4f3f59 (patch)
treebccdaeba2026c99a47e48fdcb3dfa73a4bb47371 /sql
parentd590dd568203c48607f5d809d6f82d2fa6546877 (diff)
parent084a0ed822c5904203c45b1f00d62f57e8081bcd (diff)
downloadmariadb-git-72b9f287df769770230f21e967afcab52f4f3f59.tar.gz
Merge mysql.com:/home/stewart/Documents/MySQL/5.1/wl1359
into mysql.com:/home/stewart/Documents/MySQL/5.1/tmp_merge
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_ndbcluster.cc59
-rw-r--r--sql/ha_ndbcluster.h22
-rw-r--r--sql/ha_ndbcluster_binlog.cc6
-rw-r--r--sql/handler.h4
-rw-r--r--sql/sql_acl.cc10
-rw-r--r--sql/sql_acl.h16
-rw-r--r--sql/sql_show.cc5
-rw-r--r--sql/sql_trigger.cc48
-rw-r--r--sql/sql_yacc.yy1
9 files changed, 113 insertions, 58 deletions
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 0d13121c8b3..235c0d3949c 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -1042,7 +1042,8 @@ int ha_ndbcluster::get_metadata(const char *path)
DBUG_RETURN(1);
}
- if (m_share->state != NSS_ALTERED && cmp_frm(tab, pack_data, pack_length))
+ if (get_ndb_share_state(m_share) != NSS_ALTERED
+ && cmp_frm(tab, pack_data, pack_length))
{
if (!invalidating_ndb_table)
{
@@ -4435,7 +4436,7 @@ int ha_ndbcluster::create_handler_files(const char *file)
NDBDICT *dict= ndb->getDictionary();
if (!(tab= dict->getTable(m_tabname)))
DBUG_RETURN(0); // Must be a create, ignore since frm is saved in create
- DBUG_ASSERT(m_share->state == NSS_ALTERED);
+ DBUG_ASSERT(get_ndb_share_state(m_share) == NSS_ALTERED);
name= table->s->normalized_path.str;
DBUG_PRINT("enter", ("m_tabname: %s, path: %s", m_tabname, name));
if (readfrm(name, &data, &length) ||
@@ -4454,7 +4455,7 @@ int ha_ndbcluster::create_handler_files(const char *file)
my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR));
my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR));
}
- m_share->state= NSS_INITIAL;
+ set_ndb_share_state(m_share, NSS_INITIAL);
free_share(&m_share); // Decrease ref_count
DBUG_RETURN(error);
@@ -4591,7 +4592,7 @@ int ha_ndbcluster::add_index(TABLE *table_arg,
if (!error)
{
ndbcluster_get_share(m_share); // Increase ref_count
- m_share->state= NSS_ALTERED;
+ set_ndb_share_state(m_share, NSS_ALTERED);
}
DBUG_RETURN(error);
}
@@ -4630,7 +4631,7 @@ int ha_ndbcluster::prepare_drop_index(TABLE *table_arg,
Ndb *ndb= thd_ndb->ndb;
renumber_indexes(ndb, table_arg);
ndbcluster_get_share(m_share); // Increase ref_count
- m_share->state= NSS_ALTERED;
+ set_ndb_share_state(m_share, NSS_ALTERED);
DBUG_RETURN(0);
}
@@ -5281,7 +5282,7 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name,
dict->invalidateTable(name);
strxnmov(key, FN_LEN-1, mysql_data_home, "/", db, "/", name, NullS);
NDB_SHARE *share= get_share(key, 0, false);
- if (share && share->state == NSS_ALTERED)
+ if (share && get_ndb_share_state(share) == NSS_ALTERED)
{
// Frm has been altered on disk, but not yet written to ndb
if (readfrm(key, &data, &len))
@@ -5533,7 +5534,7 @@ int ndbcluster_find_all_files(THD *thd)
else if (cmp_frm(ndbtab, pack_data, pack_length))
{
NDB_SHARE *share= get_share(key, 0, false);
- if (!share || share->state != NSS_ALTERED)
+ if (!share || get_ndb_share_state(share) != NSS_ALTERED)
{
discover= 1;
sql_print_information("NDB: mismatch in frm for %s.%s, discovering...",
@@ -8907,28 +8908,40 @@ ha_ndbcluster::generate_scan_filter(Ndb_cond_stack *ndb_cond_stack,
/*
get table space info for SHOW CREATE TABLE
*/
-char* ha_ndbcluster::get_tablespace_create_info()
+char* ha_ndbcluster::get_tablespace_name()
{
- const char tablespace_key[]= " TABLESPACE ";
- const char storage_key[]= " STORAGE DISK";
- char* str= 0;
-
Ndb *ndb= get_ndb();
NDBDICT *ndbdict= ndb->getDictionary();
+ NdbError ndberr;
+ Uint32 id;
ndb->setDatabaseName(m_dbname);
const NDBTAB *ndbtab= ndbdict->getTable(m_tabname);
if (ndbtab == 0)
+ {
+ ndberr= ndbdict->getNdbError();
+ goto err;
+ }
+ if (!ndbtab->getTablespace(&id))
+ {
return 0;
-
- // TODO retrieve table space name if there is one
+ }
+ {
+ NdbDictionary::Tablespace ts= ndbdict->getTablespace(id);
+ ndberr= ndbdict->getNdbError();
+ if(ndberr.classification != ndberror_cl_none)
+ goto err;
+ return (my_strdup(ts.getName(), MYF(0)));
+ }
+err:
+ if (ndberr.status == NdbError::TemporaryError)
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_GET_TEMPORARY_ERRMSG, ER(ER_GET_TEMPORARY_ERRMSG),
+ ndberr.code, ndberr.message, "NDB");
+ else
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_GET_ERRMSG, ER(ER_GET_ERRMSG),
+ ndberr.code, ndberr.message, "NDB");
return 0;
-
- const char *tablespace_name= "<name>";
-
- uint len= sizeof(tablespace_key) + strlen(tablespace_name) + sizeof(storage_key);
- str= my_malloc(len, MYF(0));
- strxnmov(str, len, tablespace_key, tablespace_name, storage_key, NullS);
- return(str);
}
/*
@@ -9526,7 +9539,7 @@ int ndbcluster_alter_tablespace(THD* thd, st_alter_tablespace *info)
DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED);
}
}
-
+#ifdef HAVE_NDB_BINLOG
if (is_tablespace)
ndbcluster_log_schema_op(thd, 0,
thd->query, thd->query_length,
@@ -9539,7 +9552,7 @@ int ndbcluster_alter_tablespace(THD* thd, st_alter_tablespace *info)
"", info->logfile_group_name,
0, 0,
SOT_LOGFILE_GROUP);
-
+#endif
DBUG_RETURN(FALSE);
ndberror:
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index 2a5e3eaee3a..f12b6198a68 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -118,6 +118,26 @@ typedef struct st_ndbcluster_share {
#endif
} NDB_SHARE;
+inline
+NDB_SHARE_STATE
+get_ndb_share_state(NDB_SHARE *share)
+{
+ NDB_SHARE_STATE state;
+ pthread_mutex_lock(&share->mutex);
+ state= share->state;
+ pthread_mutex_unlock(&share->mutex);
+ return state;
+}
+
+inline
+void
+set_ndb_share_state(NDB_SHARE *share, NDB_SHARE_STATE state)
+{
+ pthread_mutex_lock(&share->mutex);
+ share->state= state;
+ pthread_mutex_unlock(&share->mutex);
+}
+
#ifdef HAVE_NDB_BINLOG
/* NDB_SHARE.flags */
#define NSF_HIDDEN_PK 1 /* table has hidden primary key */
@@ -701,7 +721,7 @@ private:
uint set_up_partition_info(partition_info *part_info,
TABLE *table,
void *tab);
- char* get_tablespace_create_info();
+ char* get_tablespace_name();
int set_range_data(void *tab, partition_info* part_info);
int set_list_data(void *tab, partition_info* part_info);
int complemented_pk_read(const byte *old_data, byte *new_data,
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index 324c15e77a4..1ce28f51061 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -1715,6 +1715,12 @@ int ndbcluster_create_binlog_setup(Ndb *ndb, const char *key,
if (share)
{
+ if (share->op || share->op_old)
+ {
+ my_errno= HA_ERR_TABLE_EXIST;
+ pthread_mutex_unlock(&ndbcluster_mutex);
+ DBUG_RETURN(1);
+ }
handle_trailing_share(share);
}
diff --git a/sql/handler.h b/sql/handler.h
index 5eae5b0f862..80395d9fb50 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1716,8 +1716,8 @@ public:
{ return FALSE; }
virtual char* get_foreign_key_create_info()
{ return(NULL);} /* gets foreign key create string from InnoDB */
- virtual char* get_tablespace_create_info()
- { return(NULL);} /* gets tablespace create string from handler */
+ virtual char* get_tablespace_name()
+ { return(NULL);} /* gets tablespace name from handler */
/* used in ALTER TABLE; 1 if changing storage engine is allowed */
virtual bool can_switch_engines() { return 1; }
/* used in REPLACE; is > 0 if table is referred by a FOREIGN KEY */
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 8877d607e92..dc56880a1a0 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -361,6 +361,12 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
if (table->s->fields <= 37 && (user.access & CREATE_ACL))
user.access|= EVENT_ACL;
+ /*
+ if it is pre 5.1.6 privilege then map TRIGGER privilege on CREATE.
+ */
+ if (table->s->fields <= 38 && (user.access & SUPER_ACL))
+ user.access|= TRIGGER_ACL;
+
user.sort= get_sort(2,user.host.hostname,user.user);
user.hostname_length= (user.host.hostname ?
(uint) strlen(user.host.hostname) : 0);
@@ -4070,13 +4076,13 @@ static const char *command_array[]=
"ALTER", "SHOW DATABASES", "SUPER", "CREATE TEMPORARY TABLES",
"LOCK TABLES", "EXECUTE", "REPLICATION SLAVE", "REPLICATION CLIENT",
"CREATE VIEW", "SHOW VIEW", "CREATE ROUTINE", "ALTER ROUTINE",
- "CREATE USER", "EVENT"
+ "CREATE USER", "EVENT", "TRIGGER"
};
static uint command_lengths[]=
{
6, 6, 6, 6, 6, 4, 6, 8, 7, 4, 5, 10, 5, 5, 14, 5, 23, 11, 7, 17, 18, 11, 9,
- 14, 13, 11, 5
+ 14, 13, 11, 5, 7
};
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index f42406ca1d2..66799986413 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -43,6 +43,7 @@
#define ALTER_PROC_ACL (1L << 24)
#define CREATE_USER_ACL (1L << 25)
#define EVENT_ACL (1L << 26)
+#define TRIGGER_ACL (1L << 27)
/*
don't forget to update
1. static struct show_privileges_st sys_privileges[]
@@ -57,12 +58,12 @@
(UPDATE_ACL | SELECT_ACL | INSERT_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL | \
LOCK_TABLES_ACL | EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | \
- CREATE_PROC_ACL | ALTER_PROC_ACL | EVENT_ACL)
+ CREATE_PROC_ACL | ALTER_PROC_ACL | EVENT_ACL | TRIGGER_ACL)
#define TABLE_ACLS \
(SELECT_ACL | INSERT_ACL | UPDATE_ACL | DELETE_ACL | CREATE_ACL | DROP_ACL | \
GRANT_ACL | REFERENCES_ACL | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | \
- SHOW_VIEW_ACL)
+ SHOW_VIEW_ACL | TRIGGER_ACL)
#define COL_ACLS \
(SELECT_ACL | INSERT_ACL | UPDATE_ACL | REFERENCES_ACL)
@@ -79,7 +80,7 @@
REFERENCES_ACL | INDEX_ACL | ALTER_ACL | SHOW_DB_ACL | SUPER_ACL | \
CREATE_TMP_ACL | LOCK_TABLES_ACL | REPL_SLAVE_ACL | REPL_CLIENT_ACL | \
EXECUTE_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | CREATE_PROC_ACL | \
- ALTER_PROC_ACL | CREATE_USER_ACL | EVENT_ACL)
+ ALTER_PROC_ACL | CREATE_USER_ACL | EVENT_ACL | TRIGGER_ACL)
#define DEFAULT_CREATE_PROC_ACLS \
(ALTER_PROC_ACL | EXECUTE_ACL)
@@ -97,7 +98,7 @@
#define DB_CHUNK3 (CREATE_VIEW_ACL | SHOW_VIEW_ACL | \
CREATE_PROC_ACL | ALTER_PROC_ACL )
#define DB_CHUNK4 (EXECUTE_ACL)
-#define DB_CHUNK5 (EVENT_ACL)
+#define DB_CHUNK5 (EVENT_ACL | TRIGGER_ACL)
#define fix_rights_for_db(A) (((A) & DB_CHUNK0) | \
(((A) << 4) & DB_CHUNK1) | \
@@ -114,12 +115,15 @@
#define TBL_CHUNK0 DB_CHUNK0
#define TBL_CHUNK1 DB_CHUNK1
#define TBL_CHUNK2 (CREATE_VIEW_ACL | SHOW_VIEW_ACL)
+#define TBL_CHUNK3 TRIGGER_ACL
#define fix_rights_for_table(A) (((A) & TBL_CHUNK0) | \
(((A) << 4) & TBL_CHUNK1) | \
- (((A) << 11) & TBL_CHUNK2))
+ (((A) << 11) & TBL_CHUNK2) | \
+ (((A) << 15) & TBL_CHUNK3))
#define get_rights_for_table(A) (((A) & TBL_CHUNK0) | \
(((A) & TBL_CHUNK1) >> 4) | \
- (((A) & TBL_CHUNK2) >> 11))
+ (((A) & TBL_CHUNK2) >> 11) | \
+ (((A) & TBL_CHUNK3) >> 15))
#define fix_rights_for_column(A) (((A) & 7) | (((A) & ~7) << 8))
#define get_rights_for_column(A) (((A) & 7) | ((A) >> 8))
#define fix_rights_for_procedure(A) ((((A) << 18) & EXECUTE_ACL) | \
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index e616439033a..1e051ab34c4 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -264,6 +264,7 @@ static struct show_privileges_st sys_privileges[]=
{"Show view","Tables","To see views with SHOW CREATE VIEW"},
{"Shutdown","Server Admin", "To shut down the server"},
{"Super","Server Admin","To use KILL thread, SET GLOBAL, CHANGE MASTER, etc."},
+ {"Trigger","Tables", "To use triggers"},
{"Update", "Tables", "To update existing rows"},
{"Usage","Server Admin","No privileges - allow connect only"},
{NullS, NullS, NullS}
@@ -1137,9 +1138,11 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
to the CREATE TABLE statement
*/
- if ((for_str= file->get_tablespace_create_info()))
+ if ((for_str= file->get_tablespace_name()))
{
+ packet->append(" TABLESPACE ");
packet->append(for_str, strlen(for_str));
+ packet->append(" STORAGE DISK");
my_free(for_str, MYF(0));
}
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index b9da49632d2..ec41e02f439 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -177,12 +177,20 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
DBUG_ASSERT(tables->next_global == 0);
/*
- TODO: We should check if user has TRIGGER privilege for table here.
- Now we just require SUPER privilege for creating/dropping because
- we don't have proper privilege checking for triggers in place yet.
+ Check that the user has TRIGGER privilege on the subject table.
*/
- if (check_global_access(thd, SUPER_ACL))
- DBUG_RETURN(TRUE);
+ {
+ bool err_status;
+ TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last;
+ thd->lex->query_tables_own_last= 0;
+
+ err_status= check_table_access(thd, TRIGGER_ACL, tables, 0);
+
+ thd->lex->query_tables_own_last= save_query_tables_own_last;
+
+ if (err_status)
+ DBUG_RETURN(TRUE);
+ }
/*
There is no DETERMINISTIC clause for triggers, so can't check it.
@@ -1151,24 +1159,10 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event,
if (sp_change_security_context(thd, sp_trigger, &save_ctx))
return TRUE;
- /*
- NOTE: TRIGGER_ACL should be used below.
- */
-
- if (check_global_access(thd, SUPER_ACL))
- {
- sp_restore_security_context(thd, save_ctx);
- return TRUE;
- }
-
- /*
- If the trigger uses special variables (NEW/OLD), check that we have
- SELECT and UPDATE privileges on the subject table.
- */
-
- if (is_special_var_used(event, time_type))
{
TABLE_LIST table_list, **save_query_tables_own_last;
+ ulong wanted_access = TRIGGER_ACL;
+
bzero((char *) &table_list, sizeof (table_list));
table_list.db= (char *) table->s->db.str;
table_list.db_length= table->s->db.length;
@@ -1178,9 +1172,17 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event,
table_list.table= table;
save_query_tables_own_last= thd->lex->query_tables_own_last;
thd->lex->query_tables_own_last= 0;
+
+ /*
+ If the trigger uses special variables (NEW/OLD), check that we have
+ SELECT and UPDATE privileges on the subject table.
+ */
+
+ if (is_special_var_used(event, time_type))
+ wanted_access|= SELECT_ACL | UPDATE_ACL;
+
+ err_status= check_table_access(thd, wanted_access, &table_list, 0);
- err_status= check_table_access(thd, SELECT_ACL | UPDATE_ACL,
- &table_list, 0);
thd->lex->query_tables_own_last= save_query_tables_own_last;
if (err_status)
{
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index a86eccb493f..513dc0b7416 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -10237,6 +10237,7 @@ object_privilege:
| ALTER ROUTINE_SYM { Lex->grant |= ALTER_PROC_ACL; }
| CREATE USER { Lex->grant |= CREATE_USER_ACL; }
| EVENT_SYM { Lex->grant |= EVENT_ACL;}
+ | TRIGGER_SYM { Lex->grant |= TRIGGER_ACL; }
;