Commit f83588a0 authored by Olivier Bertrand's avatar Olivier Bertrand

Implementing pre_create option test and setting of default values.

Currently, only TABLE_TYPE is tested, and if wrong or unspecified,
is replaced by the default value DOS.

- Test on type was moved from create to pre_create
- pre_create is now called unconditionally and must return true
  on error and false otherwise.
- Warnings are produced if the table type was changed.
- The errors have specific error messages (instead of being warnings
  with an error message telling that a table must have columns)

Modified:
ha_connect.cc
ha_connect.h
handler.h
sql_table.cc
parent 3a91f1a9
...@@ -1932,8 +1932,8 @@ class handler :public Sql_alloc ...@@ -1932,8 +1932,8 @@ class handler :public Sql_alloc
/* ha_ methods: pubilc wrappers for private virtual API */ /* ha_ methods: pubilc wrappers for private virtual API */
/* Added by O. Bertrand */ /* Added by O. Bertrand */
virtual bool pre_create(THD *thd, void *crt_info, void *alt_info) virtual bool pre_create(THD *thd, HA_CREATE_INFO *crt_info, void *alt_info)
{return true;} {return false;}
int ha_open(TABLE *table, const char *name, int mode, uint test_if_locked); int ha_open(TABLE *table, const char *name, int mode, uint test_if_locked);
int ha_index_init(uint idx, bool sorted) int ha_index_init(uint idx, bool sorted)
......
...@@ -4134,7 +4134,6 @@ bool mysql_create_table_no_lock(THD *thd, ...@@ -4134,7 +4134,6 @@ bool mysql_create_table_no_lock(THD *thd,
db, table_name, internal_tmp_table)); db, table_name, internal_tmp_table));
/* Check for duplicate fields and check type of table to create */
if (check_engine(thd, db, table_name, create_info)) if (check_engine(thd, db, table_name, create_info))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
...@@ -4152,6 +4151,17 @@ bool mysql_create_table_no_lock(THD *thd, ...@@ -4152,6 +4151,17 @@ bool mysql_create_table_no_lock(THD *thd,
mem_alloc_error(sizeof(handler)); mem_alloc_error(sizeof(handler));
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
/* Let handlers test and update create table definition. */
if (file->pre_create(thd, create_info, alter_info))
DBUG_RETURN(TRUE); // Error message was created in pre_create
/* Check for duplicate fields and check type of table to create */
if (!alter_info->create_list.elements)
{
my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
MYF(0));
DBUG_RETURN(TRUE);
}
#ifdef WITH_PARTITION_STORAGE_ENGINE #ifdef WITH_PARTITION_STORAGE_ENGINE
partition_info *part_info= thd->work_part_info; partition_info *part_info= thd->work_part_info;
...@@ -4314,14 +4324,6 @@ bool mysql_create_table_no_lock(THD *thd, ...@@ -4314,14 +4324,6 @@ bool mysql_create_table_no_lock(THD *thd,
} }
#endif #endif
// Added by O. Bertrand
if (!alter_info->create_list.elements &&
file->pre_create(thd, create_info, alter_info))
{
my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
MYF(0));
DBUG_RETURN(TRUE);
}
if (mysql_prepare_create_table(thd, create_info, alter_info, if (mysql_prepare_create_table(thd, create_info, alter_info,
internal_tmp_table, internal_tmp_table,
&db_options, file, &db_options, file,
......
...@@ -3301,7 +3301,8 @@ bool ha_connect::add_fields(THD *thd, void *alt_info, ...@@ -3301,7 +3301,8 @@ bool ha_connect::add_fields(THD *thd, void *alt_info,
@note @note
Not really implemented yet. Not really implemented yet.
*/ */
bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info) bool ha_connect::pre_create(THD *thd, HA_CREATE_INFO *create_info,
void *alt_info)
{ {
char spc= ',', qch= 0; char spc= ',', qch= 0;
const char *typn= "?"; const char *typn= "?";
...@@ -3315,10 +3316,11 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info) ...@@ -3315,10 +3316,11 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
uint tm, fnc= FNC_NO, supfnc= (FNC_NO | FNC_COL); uint tm, fnc= FNC_NO, supfnc= (FNC_NO | FNC_COL);
bool b= false, ok= false, dbf= false; bool b= false, ok= false, dbf= false;
TABTYPE ttp= TAB_UNDEF; TABTYPE ttp= TAB_UNDEF;
LEX_STRING *comment, *name; LEX_STRING *comment, *name, *val;
HA_CREATE_INFO *create_info= (HA_CREATE_INFO *)crt_info; MEM_ROOT *mem= thd->mem_root;
CHARSET_INFO *cs; CHARSET_INFO *cs;
engine_option_value *pov; Alter_info *alter_info= (Alter_info*)alt_info;
engine_option_value *pov, *start= create_info->option_list, *end= NULL;
PQRYRES qrp; PQRYRES qrp;
PCOLRES crp; PCOLRES crp;
PGLOBAL g= GetPlug(thd); PGLOBAL g= GetPlug(thd);
...@@ -3331,7 +3333,7 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info) ...@@ -3331,7 +3333,7 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
db= thd->db; // Default value db= thd->db; // Default value
// Get the useful create options // Get the useful create options
for (pov= create_info->option_list; pov; pov= pov->next) for (pov= start; pov; pov= pov->next) {
if (!stricmp(pov->name.str, "table_type")) { if (!stricmp(pov->name.str, "table_type")) {
typn= pov->value.str; typn= pov->value.str;
ttp= GetTypeID(typn); ttp= GetTypeID(typn);
...@@ -3368,6 +3370,28 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info) ...@@ -3368,6 +3370,28 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
mxr= atoi(GetListOption("maxerr", pov->value.str, "0")); mxr= atoi(GetListOption("maxerr", pov->value.str, "0"));
} // endelse option_list } // endelse option_list
end= pov;
} // endfor pov
// Check table type
if (ttp == TAB_UNDEF || ttp == TAB_NIY) {
sprintf(g->Message, "Unknown Table_type '%s'", typn);
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, g->Message);
strcpy(g->Message, "Using Table_type DOS");
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, g->Message);
ttp= TAB_DOS;
typn= "DOS";
name= thd->make_lex_string(NULL, "table_type", 10, true);
val= thd->make_lex_string(NULL, typn, strlen(typn), true);
pov= new(mem) engine_option_value(*name, *val, false, &start, &end);
} // endif ttp
// Test whether columns must be specified
if (alter_info->create_list.elements)
return false;
dbf= ttp == TAB_DBF;
if (!tab && !(fnc & (FNC_TABLE | FNC_COL))) if (!tab && !(fnc & (FNC_TABLE | FNC_COL)))
tab= (char*)create_info->alias; tab= (char*)create_info->alias;
...@@ -3450,7 +3474,7 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info) ...@@ -3450,7 +3474,7 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
qrp= ODBCDrivers(g, true); qrp= ODBCDrivers(g, true);
break; break;
default: default:
sprintf(g->Message, "invalid catfunc %c", fncn); sprintf(g->Message, "invalid catfunc %s", fncn);
} // endswitch info } // endswitch info
break; break;
...@@ -3475,7 +3499,7 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info) ...@@ -3475,7 +3499,7 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
} // endswitch ttp } // endswitch ttp
if (!qrp) { if (!qrp) {
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, g->Message); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
return true; return true;
} // endif qrp } // endif qrp
...@@ -3550,7 +3574,7 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info) ...@@ -3550,7 +3574,7 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
// typ must be PLG type, not SQL type // typ must be PLG type, not SQL type
if (!(plgtyp= TranslateSQLType(typ, dec, len))) { if (!(plgtyp= TranslateSQLType(typ, dec, len))) {
sprintf(g->Message, "Unsupported SQL type %d", typ); sprintf(g->Message, "Unsupported SQL type %d", typ);
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, g->Message); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
return true; return true;
} else } else
typ= plgtyp; typ= plgtyp;
...@@ -3576,7 +3600,7 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info) ...@@ -3576,7 +3600,7 @@ bool ha_connect::pre_create(THD *thd, void *crt_info, void *alt_info)
return b; return b;
} // endif ok } // endif ok
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, g->Message); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
return true; return true;
} // end of pre_create } // end of pre_create
...@@ -3612,7 +3636,6 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -3612,7 +3636,6 @@ int ha_connect::create(const char *name, TABLE *table_arg,
bool dbf; bool dbf;
Field* *field; Field* *field;
Field *fp; Field *fp;
TABTYPE ttp;
TABLE *st= table; // Probably unuseful TABLE *st= table; // Probably unuseful
PIXDEF xdp, pxd= NULL, toidx= NULL; PIXDEF xdp, pxd= NULL, toidx= NULL;
PGLOBAL g= GetPlug(table_arg->in_use); PGLOBAL g= GetPlug(table_arg->in_use);
...@@ -3626,31 +3649,8 @@ int ha_connect::create(const char *name, TABLE *table_arg, ...@@ -3626,31 +3649,8 @@ int ha_connect::create(const char *name, TABLE *table_arg,
if (!g) { if (!g) {
rc= HA_ERR_INTERNAL_ERROR; rc= HA_ERR_INTERNAL_ERROR;
DBUG_RETURN(rc); DBUG_RETURN(rc);
} // endif g } else
dbf= (GetTypeID(options->type) == TAB_DBF);
// Check table type
ttp= GetTypeID(options->type);
if (ttp == TAB_UNDEF || ttp == TAB_NIY) {
#if 0 // Does not work. It's too late, FRM is constructed yet.
THD *thd= table_arg->in_use;
ttp= TAB_DOS;
options->type= strmake_root(thd->mem_root, "DOS", strlen("DOS"));
strcpy(g->Message, "Table_type defaulted to DOS");
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, g->Message);
#endif
if (options->type)
sprintf(g->Message, "Unsupported table type %s", options->type);
else
strcpy(g->Message, "Unspecified table type");
rc= HA_ERR_INTERNAL_ERROR;
my_printf_error(ER_UNKNOWN_ERROR, g->Message, MYF(0));
DBUG_RETURN(rc);
} // endif ttp
dbf= ttp == TAB_DBF;
// Check column types // Check column types
for (field= table_arg->field; *field; field++) { for (field= table_arg->field; *field; field++) {
......
...@@ -335,7 +335,7 @@ const char *GetValStr(OPVAL vop, bool neg); ...@@ -335,7 +335,7 @@ const char *GetValStr(OPVAL vop, bool neg);
ha_rows records_in_range(uint inx, key_range *min_key, ha_rows records_in_range(uint inx, key_range *min_key,
key_range *max_key); key_range *max_key);
int delete_table(const char *from); int delete_table(const char *from);
bool pre_create(THD *thd, void *crt_info, void *alt_info); bool pre_create(THD *thd, HA_CREATE_INFO *crt_info, void *alt_info);
int create(const char *name, TABLE *form, int create(const char *name, TABLE *form,
HA_CREATE_INFO *create_info); ///< required HA_CREATE_INFO *create_info); ///< required
bool check_if_incompatible_data(HA_CREATE_INFO *info, bool check_if_incompatible_data(HA_CREATE_INFO *info,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment