Commit 31941439 authored by Olivier Bertrand's avatar Olivier Bertrand

- Modify discovery to test a new way of adding columns. Currently the

  old way is still used if NEW_WAY is not defined.

modified:
  storage/connect/ha_connect.cc
parent b7f435f2
......@@ -107,6 +107,9 @@
#include "field.h"
#include "sql_parse.h"
#include "sql_base.h"
#if defined(NEW_WAY)
#include "sql_table.h"
#endif // NEW_WAY
#undef OFFSET
#define NOPARSE
......@@ -3367,11 +3370,69 @@ static char *encode(PGLOBAL g, char *cnm)
@return
Return 0 if ok
*/
#if defined(NEW_WAY)
static bool add_fields(PGLOBAL g,
THD *thd,
Alter_info *alter_info,
char *name,
int typ, int len, int dec,
uint type_modifier,
char *rem,
// CHARSET_INFO *cs,
// void *vcolinfo,
// engine_option_value *create_options,
int flg,
bool dbf)
{
register Create_field *new_field;
char *length, *decimals;
enum_field_types type= PLGtoMYSQL(typ, dbf);
//Virtual_column_info *vcol_info= (Virtual_column_info *)vcolinfo;
engine_option_value *crop;
LEX_STRING *comment= thd->make_lex_string(rem, strlen(rem));
LEX_STRING *field_name= thd->make_lex_string(name, strlen(name));
DBUG_ENTER("ha_connect::add_fields");
length= (char*)PlugSubAlloc(g, NULL, 8);
sprintf(length, "%d", len);
if (dec) {
decimals= (char*)PlugSubAlloc(g, NULL, 8);
sprintf(decimals, "%d", dec);
} else
decimals= NULL;
if (flg) {
engine_option_value *start= NULL, *end= NULL;
LEX_STRING *flag= thd->make_lex_string("flag", 4);
crop= new(thd->mem_root) engine_option_value(*flag, (ulonglong)flg,
&start, &end, thd->mem_root);
} else
crop= NULL;
if (check_string_char_length(field_name, "", NAME_CHAR_LEN,
system_charset_info, 1)) {
my_error(ER_TOO_LONG_IDENT, MYF(0), field_name->str); /* purecov: inspected */
DBUG_RETURN(1); /* purecov: inspected */
} // endif field_name
if (!(new_field= new Create_field()) ||
new_field->init(thd, field_name->str, type, length, decimals,
type_modifier, NULL, NULL, comment, NULL,
NULL, NULL, 0, NULL, crop, true))
DBUG_RETURN(1);
static bool add_field(String *sql, const char *field_name, const char *type,
int len, int dec, uint tm, const char *rem, int flag)
alter_info->create_list.push_back(new_field);
DBUG_RETURN(0);
} // end of add_fields
#else // !NEW_WAY
static bool add_field(String *sql, const char *field_name, int typ, int len,
int dec, uint tm, const char *rem, int flag, bool dbf)
{
bool error= false;
const char *type= PLGtoMYSQLtype(typ, dbf);
type= PLGtoMYSQLtype(typ, true);
error|= sql->append('`');
error|= sql->append(field_name);
......@@ -3382,7 +3443,7 @@ static bool add_field(String *sql, const char *field_name, const char *type,
error|= sql->append('(');
error|= sql->append_ulonglong(len);
if (/*dec || */!strcmp(type, "DOUBLE")) {
if (!strcmp(type, "DOUBLE")) {
error|= sql->append(',');
error|= sql->append_ulonglong(dec);
} // endif dec
......@@ -3404,9 +3465,225 @@ static bool add_field(String *sql, const char *field_name, const char *type,
error|= sql->append_ulonglong(flag);
} // endif flag
sql->append(',');
error|= sql->append(',');
return error;
} // end of add_field
#endif // !NEW_WAY
/**
Initialise the table share with the new columns.
@return
Return 0 if ok
*/
#if defined(NEW_WAY)
//static bool sql_unusable_for_discovery(THD *thd, const char *sql);
static int init_table_share(THD *thd,
TABLE_SHARE *table_s,
HA_CREATE_INFO *create_info,
Alter_info *alter_info)
{
int rc= 0;
handler *file;
LEX_CUSTRING frm= {0,0};
DBUG_ENTER("init_table_share");
#if 0
ulonglong saved_mode= thd->variables.sql_mode;
CHARSET_INFO *old_cs= thd->variables.character_set_client;
Parser_state parser_state;
char *sql_copy;
LEX *old_lex;
Query_arena *arena, backup;
LEX tmp_lex;
/*
Ouch. Parser may *change* the string it's working on.
Currently (2013-02-26) it is used to permanently disable
conditional comments.
Anyway, let's copy the caller's string...
*/
if (!(sql_copy= thd->strmake(sql, sql_length)))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
if (parser_state.init(thd, sql_copy, sql_length))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
thd->variables.sql_mode= MODE_NO_ENGINE_SUBSTITUTION | MODE_NO_DIR_IN_CREATE;
thd->variables.character_set_client= system_charset_info;
old_lex= thd->lex;
thd->lex= &tmp_lex;
arena= thd->stmt_arena;
if (arena->is_conventional())
arena= 0;
else
thd->set_n_backup_active_arena(arena, &backup);
lex_start(thd);
if ((error= parse_sql(thd, & parser_state, NULL)))
goto ret;
if (table_s->sql_unusable_for_discovery(thd, NULL)) {
my_error(ER_SQL_DISCOVER_ERROR, MYF(0), plugin_name(db_plugin)->str,
db.str, table_name.str, sql_copy);
goto ret;
} // endif unusable
thd->lex->create_info.db_type= plugin_data(db_plugin, handlerton *);
if (tabledef_version.str)
thd->lex->create_info.tabledef_version= tabledef_version;
#endif // 0
tmp_disable_binlog(thd);
file= mysql_create_frm_image(thd, table_s->db.str, table_s->table_name.str,
create_info, alter_info,
// &thd->lex->create_info, &thd->lex->alter_info,
C_ORDINARY_CREATE, &frm);
if (file)
delete file;
else
rc= OPEN_FRM_CORRUPTED;
if (!rc && frm.str) {
table_s->option_list= 0; // cleanup existing options ...
table_s->option_struct= 0; // ... if it's an assisted discovery
rc= table_s->init_from_binary_frm_image(thd, true, frm.str, frm.length);
} // endif frm
//ret:
my_free(const_cast<uchar*>(frm.str));
reenable_binlog(thd);
#if 0
lex_end(thd->lex);
thd->lex= old_lex;
if (arena)
thd->restore_active_arena(arena, &backup);
thd->variables.sql_mode= saved_mode;
thd->variables.character_set_client= old_cs;
#endif // 0
if (thd->is_error() || rc) {
thd->clear_error();
my_error(ER_NO_SUCH_TABLE, MYF(0), table_s->db.str,
table_s->table_name.str);
DBUG_RETURN(HA_ERR_NOT_A_TABLE);
} else
DBUG_RETURN(0);
} // end of init_table_share
#else // !NEW_WAY
static int init_table_share(THD* thd,
TABLE_SHARE *table_s,
HA_CREATE_INFO *create_info,
String *sql)
{
bool oom= false;
PTOS topt= table_s->option_struct;
sql->length(sql->length()-1); // remove the trailing comma
sql->append(')');
for (ha_create_table_option *opt= connect_table_option_list;
opt->name; opt++) {
ulonglong vull;
const char *vstr;
switch (opt->type) {
case HA_OPTION_TYPE_ULL:
vull= *(ulonglong*)(((char*)topt) + opt->offset);
if (vull != opt->def_value) {
oom|= sql->append(' ');
oom|= sql->append(opt->name);
oom|= sql->append('=');
oom|= sql->append_ulonglong(vull);
} // endif vull
break;
case HA_OPTION_TYPE_STRING:
vstr= *(char**)(((char*)topt) + opt->offset);
if (vstr) {
oom|= sql->append(' ');
oom|= sql->append(opt->name);
oom|= sql->append("='");
oom|= sql->append_for_single_quote(vstr, strlen(vstr));
oom|= sql->append('\'');
} // endif vstr
break;
case HA_OPTION_TYPE_BOOL:
vull= *(bool*)(((char*)topt) + opt->offset);
if (vull != opt->def_value) {
oom|= sql->append(' ');
oom|= sql->append(opt->name);
oom|= sql->append('=');
oom|= sql->append(vull ? "ON" : "OFF");
} // endif vull
break;
default: // no enums here, good :)
break;
} // endswitch type
if (oom)
return HA_ERR_OUT_OF_MEM;
} // endfor opt
if (create_info->connect_string.length) {
oom|= sql->append(' ');
oom|= sql->append("CONNECTION='");
oom|= sql->append_for_single_quote(create_info->connect_string.str,
create_info->connect_string.length);
oom|= sql->append('\'');
if (oom)
return HA_ERR_OUT_OF_MEM;
} // endif string
if (create_info->default_table_charset) {
oom|= sql->append(' ');
oom|= sql->append("CHARSET=");
oom|= sql->append(create_info->default_table_charset->csname);
if (oom)
return HA_ERR_OUT_OF_MEM;
} // endif charset
if (xtrace)
htrc("s_init: %.*s\n", sql->length(), sql->ptr());
return table_s->init_from_sql_statement_string(thd, true,
sql->ptr(), sql->length());
} // end of init_table_share
#endif // !NEW_WAY
// Add an option to the create_info option list
static void add_option(THD* thd, HA_CREATE_INFO *create_info,
const char *opname, const char *opval)
{
#if defined(NEW_WAY)
LEX_STRING *opn= thd->make_lex_string(opname, strlen(opname));
LEX_STRING *val= thd->make_lex_string(opval, strlen(opval));
engine_option_value *pov, **start= &create_info->option_list, *end= NULL;
for (pov= *start; pov; pov= pov->next)
end= pov;
pov= new(thd->mem_root) engine_option_value(*opn, *val, false, start, &end);
#endif // NEW_WAY
} // end of add_option
/**
@brief
......@@ -3416,6 +3693,9 @@ static bool add_field(String *sql, const char *field_name, const char *type,
When assisted discovery is used the .frm file have not already been
created. You can overwrite some definitions at this point but the
main purpose of it is to define the columns for some table types.
@note
this function is no more called in case of CREATE .. SELECT
*/
static int connect_assisted_discovery(handlerton *hton, THD* thd,
TABLE_SHARE *table_s,
......@@ -3429,7 +3709,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
#if defined(WIN32)
char *nsp= NULL, *cls= NULL;
#endif // WIN32
int port= 0, hdr= 0, mxr= 0, b= 0;
int port= 0, hdr= 0, mxr= 0, rc= 0;
uint tm, fnc= FNC_NO, supfnc= (FNC_NO | FNC_COL);
bool bif, ok= false, dbf= false;
TABTYPE ttp= TAB_UNDEF;
......@@ -3437,15 +3717,19 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
PCOLRES crp;
PGLOBAL g= GetPlug(thd, NULL);
PTOS topt= table_s->option_struct;
#if defined(NEW_WAY)
//CHARSET_INFO *cs;
Alter_info alter_info;
#else // !NEW_WAY
char buf[1024];
String sql(buf, sizeof(buf), system_charset_info);
sql.copy(STRING_WITH_LEN("CREATE TABLE whatever ("), system_charset_info);
#endif // !NEW_WAY
if (!g)
return HA_ERR_INTERNAL_ERROR;
sql.copy(STRING_WITH_LEN("CREATE TABLE whatever ("), system_charset_info);
user= host= pwd= prt= tbl= src= col= ocl= pic= fcl= rnk= dsn= NULL;
// Get the useful create options
......@@ -3495,6 +3779,7 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
ttp= GetTypeID(topt->type);
sprintf(g->Message, "No table_type. Was set to %s", topt->type);
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, g->Message);
add_option(thd, create_info, "table_type", topt->type);
} else if (ttp == TAB_NIY) {
sprintf(g->Message, "Unsupported table type %s", topt->type);
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
......@@ -3527,6 +3812,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
} else if (ttp != TAB_ODBC || !(fnc & (FNC_TABLE | FNC_COL)))
tab= (char*)create_info->alias;
#if defined(NEW_WAY)
add_option(thd, create_info, "tabname", tab);
#endif // NEW_WAY
} // endif tab
switch (ttp) {
......@@ -3617,13 +3905,9 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
ok= false;
} // endif src
// Here we should test the flag column options when
// this function is called in case of CREATE .. SELECT
if (ok) {
char *cnm, *rem;
int i, len, dec, typ, flg;
const char *type;
PDBUSER dup= PlgGetUser(g);
PCATLG cat= (dup) ? dup->Catalog : NULL;
......@@ -3714,24 +3998,35 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
if (fnc != FNC_NO || src || ttp == TAB_PIVOT) {
// Catalog like table
for (crp= qrp->Colresp; !b && crp; crp= crp->Next) {
for (crp= qrp->Colresp; !rc && crp; crp= crp->Next) {
cnm= encode(g, crp->Name);
type= PLGtoMYSQLtype(crp->Type, dbf);
typ= crp->Type;
len= crp->Length;
dec= crp->Prec;
flg= crp->Flag;
#if defined(NEW_WAY)
// Now add the field
if (add_field(&sql, cnm, type, len, dec, NOT_NULL_FLAG, 0, flg))
b= HA_ERR_OUT_OF_MEM;
rc= add_fields(g, thd, &alter_info, cnm, typ, len, dec,
NOT_NULL_FLAG, "", flg, dbf);
#else // !NEW_WAY
// Now add the field
if (add_field(&sql, cnm, typ, len, dec, NOT_NULL_FLAG, 0, flg, dbf))
rc= HA_ERR_OUT_OF_MEM;
#endif // !NEW_WAY
} // endfor crp
} else // Not a catalog table
for (i= 0; !b && i < qrp->Nblin; i++) {
rem= NULL;
for (i= 0; !rc && i < qrp->Nblin; i++) {
typ= len= dec= 0;
tm= NOT_NULL_FLAG;
cnm= (char*)"noname";
#if defined(NEW_WAY)
rem= "";
// cs= NULL;
#else // !NEW_WAY
rem= NULL;
#endif // !NEW_WAY
for (crp= qrp->Colresp; crp; crp= crp->Next)
switch (crp->Fld) {
......@@ -3787,103 +4082,27 @@ static int connect_assisted_discovery(handlerton *hton, THD* thd,
#endif // ODBC_SUPPORT
// Make the arguments as required by add_fields
type= PLGtoMYSQLtype(typ, true);
if (typ == TYPE_DATE)
len= 0;
// Now add the field
if (add_field(&sql, cnm, type, len, dec, tm, rem, 0))
b= HA_ERR_OUT_OF_MEM;
#if defined(NEW_WAY)
rc= add_fields(g, thd, &alter_info, cnm, typ, len, dec,
tm, rem, 0, true);
#else // !NEW_WAY
if (add_field(&sql, cnm, typ, len, dec, tm, rem, 0, true))
rc= HA_ERR_OUT_OF_MEM;
#endif // !NEW_WAY
} // endfor i
sql.length(sql.length()-1); // remove the trailing comma
sql.append(')');
for (ha_create_table_option *opt= connect_table_option_list;
opt->name; opt++) {
ulonglong vull;
const char *vstr;
bool oom= false;
switch (opt->type) {
case HA_OPTION_TYPE_ULL:
vull= *(ulonglong*)(((char*)topt) + opt->offset);
if (vull != opt->def_value) {
oom|= sql.append(' ');
oom|= sql.append(opt->name);
oom|= sql.append('=');
oom|= sql.append_ulonglong(vull);
} // endif vull
break;
case HA_OPTION_TYPE_STRING:
vstr= *(char**)(((char*)topt) + opt->offset);
if (vstr) {
oom|= sql.append(' ');
oom|= sql.append(opt->name);
oom|= sql.append("='");
oom|= sql.append_for_single_quote(vstr, strlen(vstr));
oom|= sql.append('\'');
} // endif vstr
break;
case HA_OPTION_TYPE_BOOL:
vull= *(bool*)(((char*)topt) + opt->offset);
if (vull != opt->def_value) {
oom|= sql.append(' ');
oom|= sql.append(opt->name);
oom|= sql.append('=');
oom|= sql.append(vull ? "ON" : "OFF");
} // endif vull
break;
default: // no enums here, good :)
break;
} // endswitch type
if (oom)
b= HA_ERR_OUT_OF_MEM;
} // endfor opt
if (create_info->connect_string.length) {
bool oom= false;
oom|= sql.append(' ');
oom|= sql.append("CONNECTION='");
oom|= sql.append_for_single_quote(create_info->connect_string.str,
create_info->connect_string.length);
oom|= sql.append('\'');
if (oom)
b= HA_ERR_OUT_OF_MEM;
} // endif string
if (create_info->default_table_charset) {
bool oom= false;
oom|= sql.append(' ');
oom|= sql.append("CHARSET=");
oom|= sql.append(create_info->default_table_charset->csname);
#if defined(NEW_WAY)
rc= init_table_share(thd, table_s, create_info, &alter_info);
#else // !NEW_WAY
if (!rc)
rc= init_table_share(thd, table_s, create_info, &sql);
#endif // !NEW_WAY
if (oom)
b= HA_ERR_OUT_OF_MEM;
} // endif charset
if (xtrace)
printf("s_init: %.*s\n", sql.length(), sql.ptr());
if (!b)
b= table_s->init_from_sql_statement_string(thd, true,
sql.ptr(), sql.length());
return b;
return rc;
} // endif ok
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
......
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