Commit a8df3d3c authored by Narayanan V's avatar Narayanan V

Bug#44610 RCDFMT clause requested when creating DB2 table

In order to better support the usage of
IBMDB2I tables from within RPG programs,
the storage engine should ensure that the
RCDFMT name is consistent and predictable
for DB2 tables.

This patch appends a "RCDFMT <name>"
clause to the CREATE TABLE statement
that is passed to DB2.  <name> is
generated from the original name of
the table itself. This ensures a
consistent and deterministic mapping
from the original table.

For the sake of simplicity only
the alpha-numeric characters are
preserved when generating the new
name, and these are upper-cased;
other characters are replaced with
an underscore (_). Following DB2
system identifier rules, the name
always begins with an alpha-character
and has a maximum of ten characters.
If no usable characters are found in
the table name, the name X is used.

mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_44610.result:
  Bug#44610 RCDFMT clause requested when creating DB2 table
  
  Result file for the test case.
mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_44610.test:
  Bug#44610 RCDFMT clause requested when creating DB2 table
  
  Test case that confirms that the names that are being generated are valid.
storage/ibmdb2i/ha_ibmdb2i.cc:
  Bug#44610 RCDFMT clause requested when creating DB2 table
  
  This patch appends a "RCDFMT <name>"
  clause to the CREATE TABLE statement
  that is passed to DB2.  <name> is
  generated from the original name of
  the table itself. This ensures a
  consistent and deterministic mapping
  from the original table.
storage/ibmdb2i/ha_ibmdb2i.h:
  Bug#44610 RCDFMT clause requested when creating DB2 table
  
  This patch appends a "RCDFMT <name>"
  clause to the CREATE TABLE statement
  that is passed to DB2.  <name> is
  generated from the original name of
  the table itself. This ensures a
  consistent and deterministic mapping
  from the original table.
parent 99224768
create table ABC (i int) engine=ibmdb2i;
drop table ABC;
create table `1234567890ABC` (i int) engine=ibmdb2i;
drop table `1234567890ABC`;
create table `!@#$%` (i int) engine=ibmdb2i;
drop table `!@#$%`;
create table `ABCD#########` (i int) engine=ibmdb2i;
drop table `ABCD#########`;
create table `_` (i int) engine=ibmdb2i;
drop table `_`;
create table `abc##def` (i int) engine=ibmdb2i;
drop table `abc##def`;
set names utf8;
create table İ (s1 int) engine=ibmdb2i;
drop table İ;
create table İİ (s1 int) engine=ibmdb2i;
drop table İİ;
set names latin1;
source suite/ibmdb2i/include/have_ibmdb2i.inc;
# Test RCDFMT generation for a variety of kinds of table names
create table ABC (i int) engine=ibmdb2i;
drop table ABC;
create table `1234567890ABC` (i int) engine=ibmdb2i;
drop table `1234567890ABC`;
create table `!@#$%` (i int) engine=ibmdb2i;
drop table `!@#$%`;
create table `ABCD#########` (i int) engine=ibmdb2i;
drop table `ABCD#########`;
create table `_` (i int) engine=ibmdb2i;
drop table `_`;
create table `abc##def` (i int) engine=ibmdb2i;
drop table `abc##def`;
set names utf8;
create table İ (s1 int) engine=ibmdb2i;
drop table İ;
create table İİ (s1 int) engine=ibmdb2i;
drop table İİ;
set names latin1;
......@@ -2273,7 +2273,12 @@ int ha_ibmdb2i::create(const char *name, TABLE *table_arg,
if (isTemporary)
query.append(STRING_WITH_LEN(" ON COMMIT PRESERVE ROWS "));
if (create_info->alias)
generateAndAppendRCDFMT(create_info->alias, query);
else if (((TABLE_LIST*)(thd->lex->select_lex.table_list.first))->table_name)
generateAndAppendRCDFMT((char*)((TABLE_LIST*)(thd->lex->select_lex.table_list.first))->table_name, query);
DBUG_PRINT("ha_ibmdb2i::create", ("Sent to DB2: %s",query.c_ptr()));
SqlStatementStream sqlStream(query.length());
sqlStream.addStatement(query,fileSortSequence,fileSortSequenceLibrary);
......
......@@ -746,5 +746,56 @@ private:
free_root(&conversionBufferMemroot, MYF(0));
}
}
/**
Generate a valid RCDFMT name based on the name of the table.
The RCDFMT name is devised by munging the name of the table,
uppercasing all ascii alpha-numeric characters and replacing all other
characters with underscores until up to ten characters have been generated.
@param tableName The name of the table, as given on the MySQL
CREATE TABLE statement
@param[out] query The string to receive the generated RCDFMT name
*/
static void generateAndAppendRCDFMT(const char* tableName, String& query)
{
char rcdfmt[11];
// The RCDFMT name must begin with an alpha character.
// We enforce this by skipping to the first alpha character in the table
// name. If no alpha character exists, we use 'X' for the RCDFMT name;
while (*tableName &&
(!my_isascii(*tableName) ||
!my_isalpha(system_charset_info, *tableName)))
{
tableName += my_mbcharlen(system_charset_info, *tableName);
}
if (unlikely(!(*tableName)))
{
rcdfmt[0]= 'X';
rcdfmt[1]= 0;
}
else
{
int r= 0;
while ((r < sizeof(rcdfmt)-1) && *tableName)
{
if (my_isascii(*tableName) &&
my_isalnum(system_charset_info, *tableName))
rcdfmt[r] = my_toupper(system_charset_info, *tableName);
else
rcdfmt[r] = '_';
++r;
tableName += my_mbcharlen(system_charset_info, *tableName);
}
rcdfmt[r]= 0;
}
query.append(STRING_WITH_LEN(" RCDFMT "));
query.append(rcdfmt);
}
};
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