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"
#endif
#include "my_global.h"
#include "my_sys.h"
#define scanner x->scanner
using namespace std;
@ -57,6 +60,42 @@ using namespace ddlpackage;
int ddllex(YYSTYPE* ddllval, void* yyscanner);
void ddlerror(struct pass_to_bison* x, char const *s);
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
@ -204,6 +243,7 @@ ZEROFILL
%type <sqlStmt> rename_table_statement
%type <str> ident
%type <str> opt_quoted_literal
%type <str> opt_column_charset
%%
stmtblock: stmtmulti { x->fParseTree = $1; }
;
@ -283,15 +323,14 @@ opt_table_options:
;
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));
}
|
CREATE TABLE opt_if_not_exists table_name '(' table_element_list ')'
{
$$ = new CreateTableStatement(new TableDef($4, $6, NULL));
}
;
opt_if_not_exists:
@ -647,10 +686,20 @@ ata_add_column:
/* See the documentation for SchemaObject for an explanation of why we are using
* dynamic_cast here.
*/
ADD column_def {$$ = new AtaAddColumn(dynamic_cast<ColumnDef*>($2));}
| ADD COLUMN column_def {$$ = new AtaAddColumn(dynamic_cast<ColumnDef*>($3));}
| ADD '(' table_element_list ')' {$$ = new AtaAddColumns($3);}
| ADD COLUMN '(' table_element_list ')' {$$ = new AtaAddColumns($4);}
ADD column_def { fix_column_length($2, x->default_table_charset); $$ = new AtaAddColumn(dynamic_cast<ColumnDef*>($2));}
| ADD COLUMN column_def { fix_column_length($3, x->default_table_charset); $$ = new AtaAddColumn(dynamic_cast<ColumnDef*>($3));}
| ADD '(' table_element_list ')' {
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:
@ -737,9 +786,9 @@ optional_braces:
;
opt_column_charset:
/* empty */ {}
/* empty */ { $$ = NULL; }
|
IDB_CHAR SET opt_quoted_literal {}
IDB_CHAR SET opt_quoted_literal { $$ = $3; }
;
opt_column_collate:
@ -749,12 +798,18 @@ opt_column_collate:
;
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
| numeric_type
| datetime_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
{
$$ = new ColumnType(DDL_BLOB);
@ -955,6 +1010,7 @@ text_type:
{
$$ = new ColumnType(DDL_TEXT);
$$->fLength = atol($3);
$$->fExplicitLength = true;
}
| TEXT
{

View File

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

View File

@ -1004,7 +1004,7 @@ struct ColumnType
EXPORT virtual int serialize(messageqcpp::ByteStream& bs);
/** @brief For deserialization. */
ColumnType()
ColumnType() : fCharset(NULL), fExplicitLength(false)
{}
friend std::ostream& operator<<(std::ostream& os, const ColumnType& ac);
@ -1044,6 +1044,12 @@ struct ColumnType
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;
}
void SqlParser::setDefaultCharset(const CHARSET_INFO* default_charset)
{
x.default_table_charset = default_charset;
}
int SqlParser::Parse(const char* sqltext)
{
ddllex_init_extra(&scanData, &x.scanner);

View File

@ -27,6 +27,8 @@
*/
#include <stdexcept>
#include <my_global.h>
#include <my_sys.h>
#include "ddlpkg.h"
#if defined(_MSC_VER) && defined(xxxDDLPKGSQLPARSER_DLLEXPORT)
@ -86,8 +88,9 @@ struct pass_to_bison
ParseTree* fParseTree;
std::string fDBSchema;
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
@ -120,6 +123,13 @@ public:
*/
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:
ParseTree fParseTree;
std::string fDBSchema;