mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-03 14:33:32 +03:00 
			
		
		
		
	Log queries to maria_log if compiled with EXTRA_DEBUG
Added DBUG_ASSERT() to unlikely error senario Don't use errno == 0 in maria_create() / myisam_create() sql/sql_insert.cc: Added DBUG_ASSERT() for case that should never happen in real life Added my_error() to avoid assert if mysql_lock() or postlock() doesn't call my_error() storage/maria/ha_maria.cc: Log queries to maria_log if compiled with EXTRA_DEBUG storage/maria/ma_create.c: Don't use errno == 0 storage/maria/ma_loghandler.c: Added logging of debug info to maria_log storage/maria/ma_loghandler.h: Added logging of debug info to maria_log storage/maria/ma_recovery.c: Added printing of debug info from maria_log storage/maria/trnman.c: Added functions to read/store state in TRN storage/maria/trnman.h: Added functions to read/store state in TRN storage/maria/trnman_public.h: Added state in TRN to remmeber if we have already logged the query storage/myisam/mi_create.c: Don't use errno == 0
This commit is contained in:
		@@ -3493,6 +3493,9 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
 | 
			
		||||
                                    MYSQL_LOCK_IGNORE_FLUSH, ¬_used)) ||
 | 
			
		||||
        hooks->postlock(&table, 1))
 | 
			
		||||
  {
 | 
			
		||||
    DBUG_ASSERT(0);                             // This should never happen
 | 
			
		||||
    /* purecov: begin tested */
 | 
			
		||||
    my_error(ER_CANT_LOCK, MYF(0), my_errno);
 | 
			
		||||
    if (*lock)
 | 
			
		||||
    {
 | 
			
		||||
      mysql_unlock_tables(thd, *lock);
 | 
			
		||||
@@ -3502,6 +3505,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
 | 
			
		||||
    if (!create_info->table_existed)
 | 
			
		||||
      drop_open_table(thd, table, create_table->db, create_table->table_name);
 | 
			
		||||
    DBUG_RETURN(0);
 | 
			
		||||
    /* purecov: end */
 | 
			
		||||
  }
 | 
			
		||||
  DBUG_RETURN(table);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2261,6 +2261,9 @@ int ha_maria::extra_opt(enum ha_extra_function operation, ulong cache_size)
 | 
			
		||||
 | 
			
		||||
int ha_maria::delete_all_rows()
 | 
			
		||||
{
 | 
			
		||||
  THD *thd= current_thd;
 | 
			
		||||
  (void) translog_log_debug_info(file->trn, LOGREC_DEBUG_INFO_QUERY,
 | 
			
		||||
                                 (uchar*) thd->query, thd->query_length);
 | 
			
		||||
  if (file->s->now_transactional &&
 | 
			
		||||
      ((table->in_use->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) ||
 | 
			
		||||
       table->in_use->locked_tables))
 | 
			
		||||
@@ -2277,6 +2280,9 @@ int ha_maria::delete_all_rows()
 | 
			
		||||
 | 
			
		||||
int ha_maria::delete_table(const char *name)
 | 
			
		||||
{
 | 
			
		||||
  THD *thd= current_thd;
 | 
			
		||||
  (void) translog_log_debug_info(0, LOGREC_DEBUG_INFO_QUERY,
 | 
			
		||||
                                 (uchar*) thd->query, thd->query_length);
 | 
			
		||||
  return maria_delete_table(name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2350,6 +2356,16 @@ int ha_maria::external_lock(THD *thd, int lock_type)
 | 
			
		||||
        DBUG_PRINT("info", ("Disabling logging for table"));
 | 
			
		||||
        _ma_tmp_disable_logging_for_table(file, TRUE);
 | 
			
		||||
      }
 | 
			
		||||
#ifdef EXTRA_DEBUG
 | 
			
		||||
      if (lock_type == F_WRLCK &&
 | 
			
		||||
          ! (trnman_get_state(trn) & TRN_STATE_INFO_LOGGED))
 | 
			
		||||
      {
 | 
			
		||||
        trnman_set_state(trn, trnman_get_state(trn) | TRN_STATE_INFO_LOGGED |
 | 
			
		||||
                         TRN_STATE_TABLES_CAN_CHANGE);
 | 
			
		||||
        (void) translog_log_debug_info(trn, LOGREC_DEBUG_INFO_QUERY,
 | 
			
		||||
                                       (uchar*) thd->query, thd->query_length);
 | 
			
		||||
      }
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
@@ -2374,9 +2390,10 @@ int ha_maria::external_lock(THD *thd, int lock_type)
 | 
			
		||||
        external lock of the table
 | 
			
		||||
      */
 | 
			
		||||
      file->state= &file->s->state.state;
 | 
			
		||||
      if (trn && trnman_has_locked_tables(trn))
 | 
			
		||||
      if (trn)
 | 
			
		||||
      {
 | 
			
		||||
        if (!trnman_decrement_locked_tables(trn))
 | 
			
		||||
        if (trnman_has_locked_tables(trn) &&
 | 
			
		||||
            !trnman_decrement_locked_tables(trn))
 | 
			
		||||
        {
 | 
			
		||||
          /*
 | 
			
		||||
            OK should not have been sent to client yet (ACID).
 | 
			
		||||
@@ -2399,6 +2416,7 @@ int ha_maria::external_lock(THD *thd, int lock_type)
 | 
			
		||||
          }
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
        trnman_set_state(trn, trnman_get_state(trn) & ~ TRN_STATE_INFO_LOGGED);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } /* if transactional table */
 | 
			
		||||
@@ -2433,6 +2451,16 @@ int ha_maria::start_stmt(THD *thd, thr_lock_type lock_type)
 | 
			
		||||
      call to start_stmt().
 | 
			
		||||
    */
 | 
			
		||||
    trnman_new_statement(trn);
 | 
			
		||||
 | 
			
		||||
#ifdef EXTRA_DEBUG
 | 
			
		||||
    if (!(trnman_get_state(trn) & TRN_STATE_INFO_LOGGED) &&
 | 
			
		||||
        trnman_get_state(trn) & TRN_STATE_TABLES_CAN_CHANGE)
 | 
			
		||||
    {
 | 
			
		||||
      trnman_set_state(trn, trnman_get_state(trn) | TRN_STATE_INFO_LOGGED);
 | 
			
		||||
      (void) translog_log_debug_info(trn, LOGREC_DEBUG_INFO_QUERY,
 | 
			
		||||
                                     (uchar*) thd->query, thd->query_length);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -2645,6 +2673,7 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
 | 
			
		||||
  TABLE_SHARE *share= table_arg->s;
 | 
			
		||||
  uint options= share->db_options_in_use;
 | 
			
		||||
  enum data_file_type row_type;
 | 
			
		||||
  THD *thd= current_thd;
 | 
			
		||||
  DBUG_ENTER("ha_maria::create");
 | 
			
		||||
 | 
			
		||||
  for (i= 0; i < share->keys; i++)
 | 
			
		||||
@@ -2709,6 +2738,9 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
 | 
			
		||||
       ha_create_info->page_checksum ==  HA_CHOICE_YES)
 | 
			
		||||
    create_flags|= HA_CREATE_PAGE_CHECKSUM;
 | 
			
		||||
 | 
			
		||||
  (void) translog_log_debug_info(0, LOGREC_DEBUG_INFO_QUERY,
 | 
			
		||||
                                 (uchar*) thd->query, thd->query_length);
 | 
			
		||||
 | 
			
		||||
  /* TODO: Check that the following fn_format is really needed */
 | 
			
		||||
  error=
 | 
			
		||||
    maria_create(fn_format(buff, name, "", "",
 | 
			
		||||
@@ -2725,6 +2757,9 @@ int ha_maria::create(const char *name, register TABLE *table_arg,
 | 
			
		||||
 | 
			
		||||
int ha_maria::rename_table(const char *from, const char *to)
 | 
			
		||||
{
 | 
			
		||||
  THD *thd= current_thd;
 | 
			
		||||
  (void) translog_log_debug_info(0, LOGREC_DEBUG_INFO_QUERY,
 | 
			
		||||
                                 (uchar*) thd->query, thd->query_length);
 | 
			
		||||
  return maria_rename(from, to);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2869,6 +2904,8 @@ static int maria_commit(handlerton *hton __attribute__ ((unused)),
 | 
			
		||||
  TRN *trn= THD_TRN;
 | 
			
		||||
  DBUG_ENTER("maria_commit");
 | 
			
		||||
  trnman_reset_locked_tables(trn, 0);
 | 
			
		||||
  trnman_set_state(trn, trnman_get_state(trn) & ~TRN_STATE_INFO_LOGGED);
 | 
			
		||||
 | 
			
		||||
  /* statement or transaction ? */
 | 
			
		||||
  if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) && !all)
 | 
			
		||||
    DBUG_RETURN(0); // end of statement
 | 
			
		||||
 
 | 
			
		||||
@@ -652,7 +652,8 @@ int maria_create(const char *name, enum data_file_type datafile_type,
 | 
			
		||||
  /* There are only 16 bits for the total header length. */
 | 
			
		||||
  if (info_length > 65535)
 | 
			
		||||
  {
 | 
			
		||||
    my_printf_error(0, "Maria table '%s' has too many columns and/or "
 | 
			
		||||
    my_printf_error(HA_WRONG_CREATE_OPTION,
 | 
			
		||||
                    "Maria table '%s' has too many columns and/or "
 | 
			
		||||
                    "indexes and/or unique constraints.",
 | 
			
		||||
                    MYF(0), name + dirname_length(name));
 | 
			
		||||
    my_errno= HA_WRONG_CREATE_OPTION;
 | 
			
		||||
 
 | 
			
		||||
@@ -685,6 +685,10 @@ static LOG_DESC INIT_LOGREC_IMPORTED_TABLE=
 | 
			
		||||
{LOGRECTYPE_VARIABLE_LENGTH, 0, 0, NULL, NULL, NULL, 0,
 | 
			
		||||
 "imported_table", LOGREC_IS_GROUP_ITSELF, NULL, NULL};
 | 
			
		||||
 | 
			
		||||
static LOG_DESC INIT_LOGREC_DEBUG_INFO=
 | 
			
		||||
{LOGRECTYPE_VARIABLE_LENGTH, 0, 0, NULL, NULL, NULL, 0,
 | 
			
		||||
 "info", LOGREC_IS_GROUP_ITSELF, NULL, NULL};
 | 
			
		||||
 | 
			
		||||
const myf log_write_flags= MY_WME | MY_NABP | MY_WAIT_IF_FULL;
 | 
			
		||||
 | 
			
		||||
void translog_table_init()
 | 
			
		||||
@@ -774,6 +778,9 @@ void translog_table_init()
 | 
			
		||||
    INIT_LOGREC_REDO_BITMAP_NEW_PAGE;
 | 
			
		||||
  log_record_type_descriptor[LOGREC_IMPORTED_TABLE]=
 | 
			
		||||
    INIT_LOGREC_IMPORTED_TABLE;
 | 
			
		||||
  log_record_type_descriptor[LOGREC_DEBUG_INFO]=
 | 
			
		||||
    INIT_LOGREC_DEBUG_INFO;
 | 
			
		||||
 | 
			
		||||
  for (i= LOGREC_FIRST_FREE; i < LOGREC_NUMBER_OF_TYPES; i++)
 | 
			
		||||
    log_record_type_descriptor[i].rclass= LOGRECTYPE_NOT_ALLOWED;
 | 
			
		||||
#ifndef DBUG_OFF
 | 
			
		||||
@@ -8299,6 +8306,43 @@ void translog_set_file_size(uint32 size)
 | 
			
		||||
  DBUG_VOID_RETURN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   Write debug information to log if we EXTRA_DEBUG is enabled
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
my_bool translog_log_debug_info(TRN *trn, enum translog_debug_info_type type,
 | 
			
		||||
                                uchar *info, size_t length)
 | 
			
		||||
{
 | 
			
		||||
#ifdef EXTRA_DEBUG
 | 
			
		||||
  LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 2];
 | 
			
		||||
  uchar debug_type;
 | 
			
		||||
  LSN lsn;
 | 
			
		||||
 | 
			
		||||
  if (!trn)
 | 
			
		||||
  {
 | 
			
		||||
    /*
 | 
			
		||||
      We can't log the current transaction because we don't have
 | 
			
		||||
      an active transaction. Use a temporary transaction object instead
 | 
			
		||||
    */
 | 
			
		||||
    trn= &dummy_transaction_object;
 | 
			
		||||
  }
 | 
			
		||||
  debug_type= (uchar) type;
 | 
			
		||||
  log_array[TRANSLOG_INTERNAL_PARTS + 0].str= &debug_type;
 | 
			
		||||
  log_array[TRANSLOG_INTERNAL_PARTS + 0].length= 1;
 | 
			
		||||
  log_array[TRANSLOG_INTERNAL_PARTS + 1].str= info;
 | 
			
		||||
  log_array[TRANSLOG_INTERNAL_PARTS + 1].length= length;
 | 
			
		||||
  return translog_write_record(&lsn, LOGREC_DEBUG_INFO,
 | 
			
		||||
                               trn, NULL,
 | 
			
		||||
                               (translog_size_t) (1+ length),
 | 
			
		||||
                               sizeof(log_array)/sizeof(log_array[0]),
 | 
			
		||||
                               log_array, NULL, NULL);
 | 
			
		||||
#else
 | 
			
		||||
  return 0;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef MARIA_DUMP_LOG
 | 
			
		||||
#include <my_getopt.h>
 | 
			
		||||
extern void translog_example_table_init();
 | 
			
		||||
 
 | 
			
		||||
@@ -144,6 +144,7 @@ enum translog_record_type
 | 
			
		||||
  LOGREC_UNDO_BULK_INSERT,
 | 
			
		||||
  LOGREC_REDO_BITMAP_NEW_PAGE,
 | 
			
		||||
  LOGREC_IMPORTED_TABLE,
 | 
			
		||||
  LOGREC_DEBUG_INFO,
 | 
			
		||||
  LOGREC_FIRST_FREE,
 | 
			
		||||
  LOGREC_RESERVED_FUTURE_EXTENSION= 63
 | 
			
		||||
};
 | 
			
		||||
@@ -167,6 +168,12 @@ enum en_key_op
 | 
			
		||||
  KEY_OP_COMPACT_PAGE   /* Compact key page */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
enum translog_debug_info_type
 | 
			
		||||
{
 | 
			
		||||
  LOGREC_DEBUG_INFO_QUERY
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Size of log file; One log file is restricted to 4G */
 | 
			
		||||
typedef uint32 translog_size_t;
 | 
			
		||||
 | 
			
		||||
@@ -323,6 +330,9 @@ translog_assign_id_to_share_from_recovery(struct st_maria_share *share,
 | 
			
		||||
extern my_bool translog_walk_filenames(const char *directory,
 | 
			
		||||
                                       my_bool (*callback)(const char *,
 | 
			
		||||
                                                           const char *));
 | 
			
		||||
extern my_bool translog_log_debug_info(TRN *trn,
 | 
			
		||||
                                       enum translog_debug_info_type type,
 | 
			
		||||
                                       uchar *info, size_t length);
 | 
			
		||||
 | 
			
		||||
enum enum_translog_status
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -98,6 +98,7 @@ prototype_redo_exec_hook(UNDO_KEY_DELETE);
 | 
			
		||||
prototype_redo_exec_hook(UNDO_KEY_DELETE_WITH_ROOT);
 | 
			
		||||
prototype_redo_exec_hook(COMMIT);
 | 
			
		||||
prototype_redo_exec_hook(CLR_END);
 | 
			
		||||
prototype_redo_exec_hook(DEBUG_INFO);
 | 
			
		||||
prototype_undo_exec_hook(UNDO_ROW_INSERT);
 | 
			
		||||
prototype_undo_exec_hook(UNDO_ROW_DELETE);
 | 
			
		||||
prototype_undo_exec_hook(UNDO_ROW_UPDATE);
 | 
			
		||||
@@ -488,6 +489,11 @@ static void display_record_position(const LOG_DESC *log_desc,
 | 
			
		||||
         number ? "" : "   ", number, LSN_IN_PARTS(rec->lsn),
 | 
			
		||||
         rec->short_trid, log_desc->name, rec->type,
 | 
			
		||||
         (ulong)rec->record_length);
 | 
			
		||||
  if (rec->type == LOGREC_DEBUG_INFO)
 | 
			
		||||
  {
 | 
			
		||||
    /* Print some extra information */
 | 
			
		||||
    (*log_desc->record_execute_in_redo_phase)(rec);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -2003,6 +2009,37 @@ prototype_redo_exec_hook(CLR_END)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
   Hock to print debug information (like MySQL query)
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
prototype_redo_exec_hook(DEBUG_INFO)
 | 
			
		||||
{
 | 
			
		||||
  uchar *data;
 | 
			
		||||
  enum translog_debug_info_type debug_info;
 | 
			
		||||
 | 
			
		||||
  enlarge_buffer(rec);
 | 
			
		||||
  if (log_record_buffer.str == NULL ||
 | 
			
		||||
      translog_read_record(rec->lsn, 0, rec->record_length,
 | 
			
		||||
                           log_record_buffer.str, NULL) !=
 | 
			
		||||
      rec->record_length)
 | 
			
		||||
  {
 | 
			
		||||
    eprint(tracef, "Failed to read record debug record");
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
  debug_info= (enum translog_debug_info_type) log_record_buffer.str[0];
 | 
			
		||||
  data= log_record_buffer.str + 1;
 | 
			
		||||
  switch (debug_info) {
 | 
			
		||||
  case LOGREC_DEBUG_INFO_QUERY:
 | 
			
		||||
    tprint(tracef, "Query: %s\n", (char*) data);
 | 
			
		||||
    break;
 | 
			
		||||
  default:
 | 
			
		||||
    DBUG_ASSERT(0);
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  In some cases we have to skip execution of an UNDO record during the UNDO
 | 
			
		||||
  phase.
 | 
			
		||||
@@ -2361,6 +2398,7 @@ static int run_redo_phase(LSN lsn, enum maria_apply_log_way apply)
 | 
			
		||||
  install_redo_exec_hook(UNDO_BULK_INSERT);
 | 
			
		||||
  install_undo_exec_hook(UNDO_BULK_INSERT);
 | 
			
		||||
  install_redo_exec_hook(IMPORTED_TABLE);
 | 
			
		||||
  install_redo_exec_hook(DEBUG_INFO);
 | 
			
		||||
 | 
			
		||||
  current_group_end_lsn= LSN_IMPOSSIBLE;
 | 
			
		||||
#ifndef DBUG_OFF
 | 
			
		||||
@@ -3403,6 +3441,7 @@ static void print_redo_phase_progress(TRANSLOG_ADDRESS addr)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef MARIA_EXTERNAL_LOCKING
 | 
			
		||||
#error Marias Checkpoint and Recovery are really not ready for it
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -88,6 +88,19 @@ void trnman_reset_locked_tables(TRN *trn, uint locked_tables)
 | 
			
		||||
  trn->locked_tables= locked_tables;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef EXTRA_DEBUG
 | 
			
		||||
uint16 trnman_get_state(TRN *trn)
 | 
			
		||||
{
 | 
			
		||||
  return trn->state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void trnman_set_state(TRN *trn, uint16 state)
 | 
			
		||||
{
 | 
			
		||||
  trn->state= state;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void wt_thd_release_self(TRN *trn)
 | 
			
		||||
{
 | 
			
		||||
  if (trn->wt)
 | 
			
		||||
 
 | 
			
		||||
@@ -53,6 +53,7 @@ struct st_ma_transaction
 | 
			
		||||
  LSN_WITH_FLAGS       first_undo_lsn;
 | 
			
		||||
  uint                 locked_tables;
 | 
			
		||||
  uint16               short_id;
 | 
			
		||||
  uint16               state;                   /* Internal flags */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define TRANSACTION_LOGGED_LONG_ID ULL(0x8000000000000000)
 | 
			
		||||
 
 | 
			
		||||
@@ -70,5 +70,17 @@ my_bool trnman_exists_active_transactions(TrID min_id, TrID max_id,
 | 
			
		||||
void trnman_lock();
 | 
			
		||||
void trnman_unlock();
 | 
			
		||||
my_bool trman_is_inited();
 | 
			
		||||
#ifdef EXTRA_DEBUG
 | 
			
		||||
uint16 trnman_get_state(TRN *);
 | 
			
		||||
void trnman_set_state(TRN *, uint16 state_bit);
 | 
			
		||||
#else
 | 
			
		||||
#define trnman_get_state(A) 0
 | 
			
		||||
uint16 trnman_set_state(A, B) do { } while (0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Bits for 'state' */
 | 
			
		||||
#define TRN_STATE_INFO_LOGGED       1  /* Query is logged */
 | 
			
		||||
#define TRN_STATE_TABLES_CAN_CHANGE 2  /* Things can change during trans. */
 | 
			
		||||
 | 
			
		||||
C_MODE_END
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -496,7 +496,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
 | 
			
		||||
  /* There are only 16 bits for the total header length. */
 | 
			
		||||
  if (info_length > 65535)
 | 
			
		||||
  {
 | 
			
		||||
    my_printf_error(0, "MyISAM table '%s' has too many columns and/or "
 | 
			
		||||
    my_printf_error(HA_WRONG_CREATE_OPTION,
 | 
			
		||||
                    "MyISAM table '%s' has too many columns and/or "
 | 
			
		||||
                    "indexes and/or unique constraints.",
 | 
			
		||||
                    MYF(0), name + dirname_length(name));
 | 
			
		||||
    my_errno= HA_WRONG_CREATE_OPTION;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user