diff options
author | stewart@mysql.com <> | 2006-02-02 00:52:32 +1100 |
---|---|---|
committer | stewart@mysql.com <> | 2006-02-02 00:52:32 +1100 |
commit | 72b9f287df769770230f21e967afcab52f4f3f59 (patch) | |
tree | bccdaeba2026c99a47e48fdcb3dfa73a4bb47371 /sql | |
parent | d590dd568203c48607f5d809d6f82d2fa6546877 (diff) | |
parent | 084a0ed822c5904203c45b1f00d62f57e8081bcd (diff) | |
download | mariadb-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.cc | 59 | ||||
-rw-r--r-- | sql/ha_ndbcluster.h | 22 | ||||
-rw-r--r-- | sql/ha_ndbcluster_binlog.cc | 6 | ||||
-rw-r--r-- | sql/handler.h | 4 | ||||
-rw-r--r-- | sql/sql_acl.cc | 10 | ||||
-rw-r--r-- | sql/sql_acl.h | 16 | ||||
-rw-r--r-- | sql/sql_show.cc | 5 | ||||
-rw-r--r-- | sql/sql_trigger.cc | 48 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 1 |
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; } ; |