1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-29 08:21:15 +03:00

MCOL-2000 Process charset definitions in the DDL

MCOL-2000 Process charset definitions in the ALTER TABLE .. ADD COLUMN

MCOL-2000 Yet another fixes for column charsets

* make respect for column (including table/db/server default) charsets
  for the TEXT(n) fields
* round TEXT(n) column length up to the next default length of TEXT-like
  subtypes, 255 (TINYTEXT), 65535 (TEXT) and so on up to 2100000000
  (LONGTEXT)
This commit is contained in:
Alexey Antipovsky
2020-11-24 15:56:14 +03:00
parent 6b13fbc210
commit d2e7c9d98d
6 changed files with 281 additions and 188 deletions

View File

@ -49,6 +49,9 @@
#include "ddl-gram.h" #include "ddl-gram.h"
#endif #endif
#include "my_global.h"
#include "my_sys.h"
#define scanner x->scanner #define scanner x->scanner
using namespace std; using namespace std;
@ -57,6 +60,42 @@ using namespace ddlpackage;
int ddllex(YYSTYPE* ddllval, void* yyscanner); int ddllex(YYSTYPE* ddllval, void* yyscanner);
void ddlerror(struct pass_to_bison* x, char const *s); void ddlerror(struct pass_to_bison* x, char const *s);
char* copy_string(const char *str); char* copy_string(const char *str);
void fix_column_length(SchemaObject* elem, const CHARSET_INFO* def_cs) {
auto* column = dynamic_cast<ColumnDef*>(elem);
if (column == NULL || column->fType == NULL)
{
return;
}
if (column->fType->fType == DDL_VARCHAR ||
column->fType->fType == DDL_CHAR ||
(column->fType->fType == DDL_TEXT && column->fType->fExplicitLength))
{
unsigned mul = def_cs ? def_cs->mbmaxlen : 1;
if (column->fType->fCharset) {
const CHARSET_INFO* cs = get_charset_by_csname(column->fType->fCharset, MY_CS_PRIMARY, MYF(0));
if (cs)
mul = cs->mbmaxlen;
}
column->fType->fLength *= mul;
}
if (column->fType->fType == DDL_TEXT && column->fType->fExplicitLength)
{
// Rounding the resulting length of TEXT(N) field to the next default length
if (column->fType->fLength <= 255)
column->fType->fLength = 255;
else if (column->fType->fLength <= 65535)
column->fType->fLength = 65535;
else if (column->fType->fLength <= 16777215)
column->fType->fLength = 16777215;
else if (column->fType->fLength <= 2100000000)
column->fType->fLength = 2100000000;
// otherwise leave the decision to a caller code
}
}
%} %}
%expect 17 %expect 17
@ -204,6 +243,7 @@ ZEROFILL
%type <sqlStmt> rename_table_statement %type <sqlStmt> rename_table_statement
%type <str> ident %type <str> ident
%type <str> opt_quoted_literal %type <str> opt_quoted_literal
%type <str> opt_column_charset
%% %%
stmtblock: stmtmulti { x->fParseTree = $1; } stmtblock: stmtmulti { x->fParseTree = $1; }
; ;
@ -283,15 +323,14 @@ opt_table_options:
; ;
create_table_statement: create_table_statement:
CREATE TABLE opt_if_not_exists table_name '(' table_element_list ')' table_options CREATE TABLE opt_if_not_exists table_name '(' table_element_list ')' opt_table_options
{ {
for (auto* elem : *$6)
{
fix_column_length(elem, x->default_table_charset);
}
$$ = new CreateTableStatement(new TableDef($4, $6, $8)); $$ = new CreateTableStatement(new TableDef($4, $6, $8));
} }
|
CREATE TABLE opt_if_not_exists table_name '(' table_element_list ')'
{
$$ = new CreateTableStatement(new TableDef($4, $6, NULL));
}
; ;
opt_if_not_exists: opt_if_not_exists:
@ -647,10 +686,20 @@ ata_add_column:
/* See the documentation for SchemaObject for an explanation of why we are using /* See the documentation for SchemaObject for an explanation of why we are using
* dynamic_cast here. * dynamic_cast here.
*/ */
ADD column_def {$$ = new AtaAddColumn(dynamic_cast<ColumnDef*>($2));} ADD column_def { fix_column_length($2, x->default_table_charset); $$ = new AtaAddColumn(dynamic_cast<ColumnDef*>($2));}
| ADD COLUMN column_def {$$ = new AtaAddColumn(dynamic_cast<ColumnDef*>($3));} | ADD COLUMN column_def { fix_column_length($3, x->default_table_charset); $$ = new AtaAddColumn(dynamic_cast<ColumnDef*>($3));}
| ADD '(' table_element_list ')' {$$ = new AtaAddColumns($3);} | ADD '(' table_element_list ')' {
| ADD COLUMN '(' table_element_list ')' {$$ = new AtaAddColumns($4);} for (auto* elem : *$3) {
fix_column_length(elem, x->default_table_charset);
}
$$ = new AtaAddColumns($3);
}
| ADD COLUMN '(' table_element_list ')' {
for (auto* elem : *$4) {
fix_column_length(elem, x->default_table_charset);
}
$$ = new AtaAddColumns($4);
}
; ;
column_name: column_name:
@ -737,9 +786,9 @@ optional_braces:
; ;
opt_column_charset: opt_column_charset:
/* empty */ {} /* empty */ { $$ = NULL; }
| |
IDB_CHAR SET opt_quoted_literal {} IDB_CHAR SET opt_quoted_literal { $$ = $3; }
; ;
opt_column_collate: opt_column_collate:
@ -749,12 +798,18 @@ opt_column_collate:
; ;
data_type: data_type:
character_string_type opt_column_charset opt_column_collate character_string_type opt_column_charset opt_column_collate {
$1->fCharset = $2;
$$ = $1;
}
| binary_string_type | binary_string_type
| numeric_type | numeric_type
| datetime_type | datetime_type
| blob_type | blob_type
| text_type opt_column_charset opt_column_collate | text_type opt_column_charset opt_column_collate {
$1->fCharset = $2;
$$ = $1;
}
| IDB_BLOB | IDB_BLOB
{ {
$$ = new ColumnType(DDL_BLOB); $$ = new ColumnType(DDL_BLOB);
@ -955,6 +1010,7 @@ text_type:
{ {
$$ = new ColumnType(DDL_TEXT); $$ = new ColumnType(DDL_TEXT);
$$->fLength = atol($3); $$->fLength = atol($3);
$$->fExplicitLength = true;
} }
| TEXT | TEXT
{ {

View File

@ -67,7 +67,9 @@ ColumnType::ColumnType(int prec, int scale) :
fLength(0), fLength(0),
fPrecision(prec), fPrecision(prec),
fScale(scale), fScale(scale),
fWithTimezone(false) fWithTimezone(false),
fCharset(NULL),
fExplicitLength(false)
{ {
fLength = utils::widthByPrecision(fPrecision); fLength = utils::widthByPrecision(fPrecision);
} }
@ -76,7 +78,9 @@ ColumnType::ColumnType(int type) :
fType(type), fType(type),
fLength(0), fLength(0),
fScale(0), fScale(0),
fWithTimezone(false) fWithTimezone(false),
fCharset(NULL),
fExplicitLength(false)
{ {
switch ( type ) switch ( type )
{ {

View File

@ -1004,7 +1004,7 @@ struct ColumnType
EXPORT virtual int serialize(messageqcpp::ByteStream& bs); EXPORT virtual int serialize(messageqcpp::ByteStream& bs);
/** @brief For deserialization. */ /** @brief For deserialization. */
ColumnType() ColumnType() : fCharset(NULL), fExplicitLength(false)
{} {}
friend std::ostream& operator<<(std::ostream& os, const ColumnType& ac); friend std::ostream& operator<<(std::ostream& os, const ColumnType& ac);
@ -1044,6 +1044,12 @@ struct ColumnType
uint64_t fNextvalue; uint64_t fNextvalue;
/** @brief Column charset (CHAR, VARCHAR and TEXT only) */
const char* fCharset;
/** @brief Is the TEXT column has explicit defined length, ie TEXT(1717) */
bool fExplicitLength;
}; };

View File

@ -63,6 +63,11 @@ void SqlParser::setDefaultSchema(std::string schema)
x.fDBSchema = schema; x.fDBSchema = schema;
} }
void SqlParser::setDefaultCharset(const CHARSET_INFO* default_charset)
{
x.default_table_charset = default_charset;
}
int SqlParser::Parse(const char* sqltext) int SqlParser::Parse(const char* sqltext)
{ {
ddllex_init_extra(&scanData, &x.scanner); ddllex_init_extra(&scanData, &x.scanner);

View File

@ -27,6 +27,8 @@
*/ */
#include <stdexcept> #include <stdexcept>
#include <my_global.h>
#include <my_sys.h>
#include "ddlpkg.h" #include "ddlpkg.h"
#if defined(_MSC_VER) && defined(xxxDDLPKGSQLPARSER_DLLEXPORT) #if defined(_MSC_VER) && defined(xxxDDLPKGSQLPARSER_DLLEXPORT)
@ -86,8 +88,9 @@ struct pass_to_bison
ParseTree* fParseTree; ParseTree* fParseTree;
std::string fDBSchema; std::string fDBSchema;
void* scanner; void* scanner;
const CHARSET_INFO* default_table_charset;
pass_to_bison(ParseTree* pt) : fParseTree(pt), scanner(NULL) {}; pass_to_bison(ParseTree* pt) : fParseTree(pt), scanner(NULL), default_table_charset(NULL) {};
}; };
class SqlParser class SqlParser
@ -120,6 +123,13 @@ public:
*/ */
EXPORT void setDefaultSchema(std::string schema); EXPORT void setDefaultSchema(std::string schema);
/** @brief Set the default table charset. Can be overriden by column
* or table options
*
* @param default_charset the default CHARSET_INFO pointer
*/
EXPORT void setDefaultCharset(const CHARSET_INFO* default_charset);
protected: protected:
ParseTree fParseTree; ParseTree fParseTree;
std::string fDBSchema; std::string fDBSchema;

View File

@ -113,21 +113,21 @@ static void decode_objectname(char *buf, const char *path, size_t buf_size)
static void decode_file_path(const char *path, char *decoded_dbname, static void decode_file_path(const char *path, char *decoded_dbname,
char *decoded_tbname) char *decoded_tbname)
{ {
// The format cont ains './' in the beginning of a path. // The format cont ains './' in the beginning of a path.
char *dbname_start = (char*) path + 2; char *dbname_start = (char*) path + 2;
char *dbname_end = dbname_start; char *dbname_end = dbname_start;
while (*dbname_end != '/') while (*dbname_end != '/')
dbname_end++; dbname_end++;
int cnt = dbname_end - dbname_start; int cnt = dbname_end - dbname_start;
char *dbname = (char *)my_alloca(cnt + 1); char *dbname = (char *)my_alloca(cnt + 1);
memcpy(dbname, dbname_start, cnt); memcpy(dbname, dbname_start, cnt);
dbname[cnt] = '\0'; dbname[cnt] = '\0';
decode_objectname(decoded_dbname, dbname, FN_REFLEN); decode_objectname(decoded_dbname, dbname, FN_REFLEN);
my_afree(dbname); my_afree(dbname);
char *tbname_start = dbname_end + 1; char *tbname_start = dbname_end + 1;
decode_objectname(decoded_tbname, tbname_start, FN_REFLEN); decode_objectname(decoded_tbname, tbname_start, FN_REFLEN);
} }
@ -158,7 +158,7 @@ int parseCompressionComment ( std::string comment )
{ {
//Find the pattern, now get the compression type //Find the pattern, now get the compression type
string compType (&(*(what[0].second))); string compType (&(*(what[0].second)));
//; is the seperator between compression and autoincrement comments. //; is the separator between compression and autoincrement comments.
unsigned i = compType.find_first_of(";"); unsigned i = compType.find_first_of(";");
if ( i <= compType.length() ) if ( i <= compType.length() )
@ -310,7 +310,7 @@ bool anyRowInTable(string& schema, string& tableName, int sessionID)
} }
aTableName.schema = schema; aTableName.schema = schema;
aTableName.table = tableName; aTableName.table = tableName;
CalpontSystemCatalog::RIDList ridList = csc->columnRIDs(aTableName, true); CalpontSystemCatalog::RIDList ridList = csc->columnRIDs(aTableName, true);
CalpontSystemCatalog::TableColName tableColName = csc->colName(ridList[0].objnum); CalpontSystemCatalog::TableColName tableColName = csc->colName(ridList[0].objnum);
@ -759,7 +759,8 @@ bool anyNullInTheColumn (THD* thd, string& schema, string& table, string& column
} }
int ProcessDDLStatement(string& ddlStatement, string& schema, const string& table, int sessionID, int ProcessDDLStatement(string& ddlStatement, string& schema, const string& table, int sessionID,
string& emsg, int compressionTypeIn = 2, bool isAnyAutoincreCol = false, int64_t nextvalue = 1, std::string autoiColName = "") string& emsg, int compressionTypeIn = 2, bool isAnyAutoincreCol = false, int64_t nextvalue = 1, std::string autoiColName = "",
const CHARSET_INFO* default_table_charset = NULL)
{ {
SqlParser parser; SqlParser parser;
THD* thd = current_thd; THD* thd = current_thd;
@ -768,6 +769,7 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
#endif #endif
parser.setDefaultSchema(schema); parser.setDefaultSchema(schema);
parser.setDefaultCharset(default_table_charset);
int rc = 0; int rc = 0;
IDBCompressInterface idbCompress; IDBCompressInterface idbCompress;
parser.Parse(ddlStatement.c_str()); parser.Parse(ddlStatement.c_str());
@ -1477,23 +1479,23 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
return rc; return rc;
} }
/* else if ( dynamic_cast<AtaSetColumnDefault*> (actionList[i]) ) /* else if ( dynamic_cast<AtaSetColumnDefault*> (actionList[i]) )
{ {
rc = 1; rc = 1;
thd->get_stmt_da()->set_overwrite_status(true); thd->get_stmt_da()->set_overwrite_status(true);
thd->raise_error_printf(ER_CHECK_NOT_IMPLEMENTED, (IDBErrorInfo::instance()->errorMsg(ERR_CONSTRAINTS)).c_str()); thd->raise_error_printf(ER_CHECK_NOT_IMPLEMENTED, (IDBErrorInfo::instance()->errorMsg(ERR_CONSTRAINTS)).c_str());
ci->alterTableState = cal_connection_info::NOT_ALTER; ci->alterTableState = cal_connection_info::NOT_ALTER;
ci->isAlter = false; ci->isAlter = false;
return rc; return rc;
} }
else if ( dynamic_cast<AtaDropColumnDefault*> (actionList[i]) ) else if ( dynamic_cast<AtaDropColumnDefault*> (actionList[i]) )
{ {
rc = 1; rc = 1;
thd->get_stmt_da()->set_overwrite_status(true); thd->get_stmt_da()->set_overwrite_status(true);
thd->raise_error_printf(ER_CHECK_NOT_IMPLEMENTED, (IDBErrorInfo::instance()->errorMsg(ERR_CONSTRAINTS)).c_str()); thd->raise_error_printf(ER_CHECK_NOT_IMPLEMENTED, (IDBErrorInfo::instance()->errorMsg(ERR_CONSTRAINTS)).c_str());
ci->alterTableState = cal_connection_info::NOT_ALTER; ci->alterTableState = cal_connection_info::NOT_ALTER;
ci->isAlter = false; ci->isAlter = false;
return rc; return rc;
} }
*/ */
else if ( ddlpackage::AtaAddColumns* addColumnsPtr = dynamic_cast<AtaAddColumns*>(actionList[i])) else if ( ddlpackage::AtaAddColumns* addColumnsPtr = dynamic_cast<AtaAddColumns*>(actionList[i]))
{ {
@ -1879,14 +1881,14 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
//@Bug 5444. rename column doen't need to check this. //@Bug 5444. rename column doen't need to check this.
/* if (tblInfo.tablewithautoincr == 1) /* if (tblInfo.tablewithautoincr == 1)
{ {
rc = 1; rc = 1;
thd->get_stmt_da()->set_overwrite_status(true); thd->get_stmt_da()->set_overwrite_status(true);
thd->raise_error_printf(ER_INTERNAL_ERROR, (IDBErrorInfo::instance()->errorMsg(ERR_INVALID_NUMBER_AUTOINCREMENT)).c_str()); thd->raise_error_printf(ER_INTERNAL_ERROR, (IDBErrorInfo::instance()->errorMsg(ERR_INVALID_NUMBER_AUTOINCREMENT)).c_str());
ci->alterTableState = cal_connection_info::NOT_ALTER; ci->alterTableState = cal_connection_info::NOT_ALTER;
ci->isAlter = false; ci->isAlter = false;
return rc; return rc;
} */ } */
if (!validateAutoincrementDatatype(renameColumnsPtr->fNewType->fType)) if (!validateAutoincrementDatatype(renameColumnsPtr->fNewType->fType))
{ {
@ -2113,68 +2115,68 @@ int ProcessDDLStatement(string& ddlStatement, string& schema, const string& tabl
static bool get_field_default_value(THD *thd, Field *field, String *def_value, static bool get_field_default_value(THD *thd, Field *field, String *def_value,
bool quoted) bool quoted)
{ {
bool has_default; bool has_default;
enum enum_field_types field_type= field->type(); enum enum_field_types field_type= field->type();
has_default= (field->default_value || has_default= (field->default_value ||
(!(field->flags & NO_DEFAULT_VALUE_FLAG) && (!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
field->unireg_check != Field::NEXT_NUMBER)); field->unireg_check != Field::NEXT_NUMBER));
def_value->length(0); def_value->length(0);
if (has_default) if (has_default)
{
StringBuffer<MAX_FIELD_WIDTH> str(field->charset());
if (field->default_value)
{ {
field->default_value->print(&str); StringBuffer<MAX_FIELD_WIDTH> str(field->charset());
if (field->default_value->expr->need_parentheses_in_default()) if (field->default_value)
{ {
def_value->set_charset(&my_charset_utf8mb4_general_ci); field->default_value->print(&str);
def_value->append('('); if (field->default_value->expr->need_parentheses_in_default())
def_value->append(str); {
def_value->append(')'); def_value->set_charset(&my_charset_utf8mb4_general_ci);
} def_value->append('(');
else def_value->append(str);
def_value->append(str); def_value->append(')');
} }
else if (!field->is_null()) else
{ // Not null by default def_value->append(str);
if (field_type == MYSQL_TYPE_BIT) }
{ else if (!field->is_null())
str.qs_append('b'); { // Not null by default
str.qs_append('\''); if (field_type == MYSQL_TYPE_BIT)
str.qs_append(field->val_int(), 2); {
str.qs_append('\''); str.qs_append('b');
quoted= 0; str.qs_append('\'');
} str.qs_append(field->val_int(), 2);
else str.qs_append('\'');
{ quoted= 0;
field->val_str(&str); }
if (!field->str_needs_quotes()) else
quoted= 0; {
} field->val_str(&str);
if (str.length()) if (!field->str_needs_quotes())
{ quoted= 0;
StringBuffer<MAX_FIELD_WIDTH> def_val; }
uint dummy_errors; if (str.length())
/* convert to system_charset_info == utf8 */ {
def_val.copy(str.ptr(), str.length(), field->charset(), StringBuffer<MAX_FIELD_WIDTH> def_val;
system_charset_info, &dummy_errors); uint dummy_errors;
if (quoted) /* convert to system_charset_info == utf8 */
append_unescaped(def_value, def_val.ptr(), def_val.length()); def_val.copy(str.ptr(), str.length(), field->charset(),
system_charset_info, &dummy_errors);
if (quoted)
append_unescaped(def_value, def_val.ptr(), def_val.length());
else
def_value->append(def_val);
}
else if (quoted)
def_value->set(STRING_WITH_LEN("''"), system_charset_info);
}
else if (field->maybe_null() && quoted)
def_value->set(STRING_WITH_LEN("NULL"), system_charset_info); // Null as default
else else
def_value->append(def_val); return 0;
}
else if (quoted)
def_value->set(STRING_WITH_LEN("''"), system_charset_info);
}
else if (field->maybe_null() && quoted)
def_value->set(STRING_WITH_LEN("NULL"), system_charset_info); // Null as default
else
return 0;
} }
return has_default; return has_default;
} }
/* /*
@ -2211,7 +2213,7 @@ int ha_mcs_impl_create_(const char* name, TABLE* table_arg, HA_CREATE_INFO* crea
string stmt(query); string stmt(query);
stmt += ";"; stmt += ";";
algorithm::to_upper(stmt); algorithm::to_upper(stmt);
string db, tbl; string db, tbl;
db = table_arg->s->db.str; db = table_arg->s->db.str;
tbl = table_arg->s->table_name.str; tbl = table_arg->s->table_name.str;
@ -2358,67 +2360,75 @@ int ha_mcs_impl_create_(const char* name, TABLE* table_arg, HA_CREATE_INFO* crea
return 1; return 1;
} }
// Check if this is one of // Check if this is one of
// * "CREATE TABLE ... LIKE " // * "CREATE TABLE ... LIKE "
// * "ALTER TABLE ... ENGINE=Columnstore" // * "ALTER TABLE ... ENGINE=Columnstore"
// * "CREATE TABLE ... AS ..." // * "CREATE TABLE ... AS ..."
// If so generate a full create table statement using the properties of // If so generate a full create table statement using the properties of
// the source table. Note that source table has to be a columnstore table and // the source table. Note that source table has to be a columnstore table and
// we only check for currently supported options. // we only check for currently supported options.
// //
if ((thd->lex->sql_command == SQLCOM_CREATE_TABLE && thd->lex->used_tables) || if ((thd->lex->sql_command == SQLCOM_CREATE_TABLE && thd->lex->used_tables) ||
(thd->lex->sql_command == SQLCOM_ALTER_TABLE && create_info->used_fields & HA_CREATE_USED_ENGINE) || (thd->lex->sql_command == SQLCOM_ALTER_TABLE && create_info->used_fields & HA_CREATE_USED_ENGINE) ||
(thd->lex->create_info.like())) (thd->lex->create_info.like()))
{ {
TABLE_SHARE *share = table_arg->s; TABLE_SHARE *share = table_arg->s;
my_bitmap_map *old_map; // To save the read_set my_bitmap_map *old_map; // To save the read_set
char datatype_buf[MAX_FIELD_WIDTH], def_value_buf[MAX_FIELD_WIDTH]; char datatype_buf[MAX_FIELD_WIDTH], def_value_buf[MAX_FIELD_WIDTH];
String datatype, def_value; String datatype, def_value;
ostringstream oss; ostringstream oss;
string tbl_name = string(share->db.str) + "." + string(share->table_name.str); string tbl_name = string(share->db.str) + "." + string(share->table_name.str);
// Save the current read_set map and mark it for read // Save the current read_set map and mark it for read
old_map= tmp_use_all_columns(table_arg, table_arg->read_set); old_map= tmp_use_all_columns(table_arg, table_arg->read_set);
oss << "CREATE TABLE " << tbl_name << " ("; oss << "CREATE TABLE " << tbl_name << " (";
restore_record(table_arg, s->default_values); restore_record(table_arg, s->default_values);
for (Field **field= table_arg->field; *field; field++) for (Field **field= table_arg->field; *field; field++)
{ {
uint flags = (*field)->flags; uint flags = (*field)->flags;
datatype.set(datatype_buf, sizeof(datatype_buf), system_charset_info); datatype.set(datatype_buf, sizeof(datatype_buf), system_charset_info);
(*field)->sql_type(datatype); (*field)->sql_type(datatype);
if (field != table_arg->field) if (field != table_arg->field)
oss << ", "; oss << ", ";
oss << (*field)->field_name.str << " " << datatype.ptr(); oss << (*field)->field_name.str << " " << datatype.ptr();
if (flags & NOT_NULL_FLAG) if (flags & NOT_NULL_FLAG)
oss << " NOT NULL"; oss << " NOT NULL";
def_value.set(def_value_buf, sizeof(def_value_buf), system_charset_info); def_value.set(def_value_buf, sizeof(def_value_buf), system_charset_info);
if (get_field_default_value(thd, *field, &def_value, true)) { if (get_field_default_value(thd, *field, &def_value, true))
oss << " DEFAULT " << def_value.c_ptr(); {
} oss << " DEFAULT " << def_value.c_ptr();
if ((*field)->comment.length) }
{
String comment;
append_unescaped(&comment, (*field)->comment.str, (*field)->comment.length);
oss << " COMMENT ";
oss << comment.c_ptr();
}
} const CHARSET_INFO* field_cs = (*field)->charset();
// End the list of columns if (field_cs && (!share->table_charset || field_cs->number != share->table_charset->number))
oss<< ") ENGINE=columnstore "; {
oss << " CHARACTER SET " << field_cs->csname;
}
// Process table level options if ((*field)->comment.length)
{
String comment;
append_unescaped(&comment, (*field)->comment.str, (*field)->comment.length);
oss << " COMMENT ";
oss << comment.c_ptr();
}
}
// End the list of columns
oss << ") ENGINE=columnstore ";
// Process table level options
/* TODO: uncomment when we support AUTO_INCREMENT /* TODO: uncomment when we support AUTO_INCREMENT
if (create_info->auto_increment_value > 1) if (create_info->auto_increment_value > 1)
{ {
oss << " AUTO_INCREMENT=" << create_info->auto_increment_value; oss << " AUTO_INCREMENT=" << create_info->auto_increment_value;
} }
*/ */
if (create_info->auto_increment_value > 1) if (create_info->auto_increment_value > 1)
@ -2427,40 +2437,42 @@ int ha_mcs_impl_create_(const char* name, TABLE* table_arg, HA_CREATE_INFO* crea
} }
if (share->table_charset) if (share->table_charset)
{ {
oss << " DEFAULT CHARSET=" << share->table_charset->csname; oss << " DEFAULT CHARSET=" << share->table_charset->csname;
} }
// Process table level options such as MIN_ROWS, MAX_ROWS, COMMENT // Process table level options such as MIN_ROWS, MAX_ROWS, COMMENT
if (share->min_rows) if (share->min_rows)
{ {
char buff[80]; char buff[80];
longlong10_to_str(share->min_rows, buff, 10); longlong10_to_str(share->min_rows, buff, 10);
oss << " MIN_ROWS=" << buff; oss << " MIN_ROWS=" << buff;
} }
if (share->max_rows) { if (share->max_rows)
char buff[80]; {
longlong10_to_str(share->max_rows, buff, 10); char buff[80];
oss << " MAX_ROWS=" << buff; longlong10_to_str(share->max_rows, buff, 10);
} oss << " MAX_ROWS=" << buff;
}
if (share->comment.length) { if (share->comment.length)
String comment; {
append_unescaped(&comment, share->comment.str, share->comment.length); String comment;
oss << " COMMENT "; append_unescaped(&comment, share->comment.str, share->comment.length);
oss << comment.c_ptr(); oss << " COMMENT ";
} oss << comment.c_ptr();
}
oss << ";"; oss << ";";
stmt = oss.str(); stmt = oss.str();
tmp_restore_column_map(table_arg->read_set, old_map); tmp_restore_column_map(table_arg->read_set, old_map);
} }
rc = ProcessDDLStatement(stmt, db, tbl, tid2sid(thd->thread_id), emsg, compressiontype, isAnyAutoincreCol, startValue, columnName); rc = ProcessDDLStatement(stmt, db, tbl, tid2sid(thd->thread_id), emsg, compressiontype, isAnyAutoincreCol, startValue, columnName, create_info->default_table_charset);
if (rc != 0) if (rc != 0)
{ {