-
Notifications
You must be signed in to change notification settings - Fork 319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#2357] improvement(trino): Fix varchar type mapping between Gravitino JDBC catalog and Trino #2358
Changes from 9 commits
56e8b0d
c309df4
bfe88d2
c3a73ef
6f46852
f230b05
a1d9090
11656ab
473fc9b
d67f04c
a8afbcd
6832e37
a824c1b
cef4422
9d1d79d
51832d8
ffab489
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
CREATE SCHEMA "test.gt_mysql".varchar_db1; | ||
|
||
USE "test.gt_mysql".varchar_db1; | ||
|
||
CREATE TABLE tb01 (id int, name char(20)); | ||
|
||
SHOW CREATE TABLE "test.gt_mysql".varchar_db1.tb01; | ||
|
||
CREATE TABLE tb02 (id int, name char(255)); | ||
|
||
SHOW CREATE TABLE "test.gt_mysql".varchar_db1.tb02; | ||
|
||
CREATE TABLE tb03 (id int, name char(256)); | ||
|
||
CREATE TABLE tb04 (id int, name varchar(250)); | ||
|
||
SHOW CREATE TABLE "test.gt_mysql".varchar_db1.tb04; | ||
|
||
CREATE TABLE tb05 (id int, name varchar(256)); | ||
|
||
SHOW CREATE TABLE "test.gt_mysql".varchar_db1.tb05; | ||
|
||
drop table "test.gt_mysql".varchar_db1.tb01; | ||
|
||
drop table "test.gt_mysql".varchar_db1.tb02; | ||
|
||
drop table "test.gt_mysql".varchar_db1.tb04; | ||
|
||
drop table "test.gt_mysql".varchar_db1.tb05; | ||
|
||
drop schema "test.gt_mysql".varchar_db1; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
CREATE SCHEMA | ||
|
||
USE | ||
|
||
CREATE TABLE | ||
|
||
"CREATE TABLE ""test.gt_mysql"".varchar_db1.tb01 ( | ||
id integer, | ||
name char(20) | ||
) | ||
COMMENT '' | ||
WITH ( | ||
engine = 'InnoDB' | ||
)" | ||
|
||
CREATE TABLE | ||
|
||
"CREATE TABLE ""test.gt_mysql"".varchar_db1.tb02 ( | ||
id integer, | ||
name char(255) | ||
) | ||
COMMENT '' | ||
WITH ( | ||
engine = 'InnoDB' | ||
)" | ||
|
||
<QUERY_FAILED> MySQL does not support the datatype CHAR with the length greater than 255 | ||
|
||
CREATE TABLE | ||
|
||
"CREATE TABLE ""test.gt_mysql"".varchar_db1.tb04 ( | ||
id integer, | ||
name varchar(250) | ||
) | ||
COMMENT '' | ||
WITH ( | ||
engine = 'InnoDB' | ||
)" | ||
|
||
CREATE TABLE | ||
|
||
"CREATE TABLE ""test.gt_mysql"".varchar_db1.tb05 ( | ||
id integer, | ||
name varchar(256) | ||
) | ||
COMMENT '' | ||
WITH ( | ||
engine = 'InnoDB' | ||
)" | ||
|
||
DROP TABLE | ||
|
||
DROP TABLE | ||
|
||
DROP TABLE | ||
|
||
DROP TABLE | ||
|
||
DROP SCHEMA |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
CREATE SCHEMA "test.gt_postgresql".varchar_db1; | ||
|
||
USE "test.gt_postgresql".varchar_db1; | ||
|
||
CREATE TABLE tb01 (id int, name char(20)); | ||
|
||
SHOW CREATE TABLE "test.gt_postgresql".varchar_db1.tb01; | ||
|
||
CREATE TABLE tb02 (id int, name char(65536)); | ||
|
||
SHOW CREATE TABLE "test.gt_postgresql".varchar_db1.tb02; | ||
|
||
CREATE TABLE tb03 (id int, name char(65537)); | ||
|
||
CREATE TABLE tb04 (id int, name varchar(250)); | ||
|
||
SHOW CREATE TABLE "test.gt_postgresql".varchar_db1.tb04; | ||
|
||
CREATE TABLE tb05 (id int, name varchar(10485760)); | ||
|
||
SHOW CREATE TABLE "test.gt_postgresql".varchar_db1.tb05; | ||
|
||
CREATE TABLE tb06 (id int, name varchar(10485761)); | ||
|
||
SHOW CREATE TABLE "test.gt_postgresql".varchar_db1.tb06; | ||
|
||
drop table "test.gt_postgresql".varchar_db1.tb01; | ||
|
||
drop table "test.gt_postgresql".varchar_db1.tb02; | ||
|
||
drop table "test.gt_postgresql".varchar_db1.tb04; | ||
|
||
drop table "test.gt_postgresql".varchar_db1.tb05; | ||
|
||
drop schema "test.gt_postgresql".varchar_db1; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
CREATE SCHEMA | ||
|
||
USE | ||
|
||
CREATE TABLE | ||
|
||
"CREATE TABLE ""test.gt_postgresql"".varchar_db1.tb01 ( | ||
id integer, | ||
name char(20) | ||
) | ||
COMMENT ''" | ||
|
||
"CREATE TABLE ""test.gt_postgresql"".varchar_db1.tb02 ( | ||
id integer, | ||
name char(65536) | ||
) | ||
COMMENT ''" | ||
|
||
<QUERY_FAILED> Unknown type 'char(65537)' for column 'name' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the error message should not be understandable by the user There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The error message is from Trino itself, not from the Gravitino connector. |
||
|
||
CREATE TABLE | ||
|
||
"CREATE TABLE ""test.gt_postgresql"".varchar_db1.tb04 ( | ||
id integer, | ||
name varchar(250) | ||
) | ||
COMMENT ''" | ||
|
||
CREATE TABLE | ||
|
||
"CREATE TABLE ""test.gt_postgresql"".varchar_db1.tb05 ( | ||
id integer, | ||
name varchar(10485760) | ||
) | ||
COMMENT ''" | ||
|
||
<QUERY_FAILED> Failed to create table. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we show more detailed messages for the error There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I need to handle this special case to provide more error information, so I have omitted it. |
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing line 25 command output, Does it still work with subsequent commands?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK |
||
DROP TABLE | ||
|
||
DROP TABLE | ||
|
||
DROP TABLE | ||
|
||
DROP TABLE | ||
|
||
DROP SCHEMA |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,27 +11,65 @@ | |
import com.datastrato.gravitino.trino.connector.GravitinoErrorCode; | ||
import com.datastrato.gravitino.trino.connector.util.GeneralDataTypeTransformer; | ||
import io.trino.spi.TrinoException; | ||
import io.trino.spi.type.CharType; | ||
|
||
/** Type transformer between MySQL and Trino */ | ||
public class MySQLDataTypeTransformer extends GeneralDataTypeTransformer { | ||
private static final int MYSQL_CHAR_LENGTH_LIMIT = 255; | ||
// 65535 / 4 = 16383, in fact, MySQL limit the row size to 65535, and the utf8mb4 character set | ||
// uses 4 bytes per character. In fact, if a row has several varchar columns, the length of each | ||
// column should be less than 16383. For more details, please refer to | ||
// https://dev.mysql.com/doc/refman/8.0/en/char.html | ||
private static final int MYSQL_VARCHAR_LENGTH_LIMIT = 16383; | ||
|
||
yuqi1129 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
@Override | ||
public io.trino.spi.type.Type getTrinoType(Type type) { | ||
if (type.name() == Name.STRING) { | ||
return io.trino.spi.type.VarcharType.createUnboundedVarcharType(); | ||
} | ||
|
||
return super.getTrinoType(type); | ||
} | ||
|
||
@Override | ||
public Type getGravitinoType(io.trino.spi.type.Type type) { | ||
Type gravitinoType = super.getGravitinoType(type); | ||
if (gravitinoType.name() == Name.VARCHAR) { | ||
if (((Types.VarCharType) gravitinoType).length() > MYSQL_CHAR_LENGTH_LIMIT) { | ||
Class<? extends io.trino.spi.type.Type> typeClass = type.getClass(); | ||
if (typeClass == io.trino.spi.type.CharType.class) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why don't we use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't have any preference about |
||
CharType charType = (CharType) type; | ||
if (charType.getLength() > MYSQL_CHAR_LENGTH_LIMIT) { | ||
throw new TrinoException( | ||
GravitinoErrorCode.GRAVITINO_ILLEGAL_ARGUMENT, | ||
"MySQL does not support the datatype CHAR with the length greater than " | ||
+ MYSQL_CHAR_LENGTH_LIMIT); | ||
} | ||
|
||
// We do not support the CHAR without a length. | ||
if (charType.getLength() == 0) { | ||
throw new TrinoException( | ||
GravitinoErrorCode.GRAVITINO_ILLEGAL_ARGUMENT, | ||
"MySQL does not support the datatype CHAR with the length 0"); | ||
} | ||
|
||
return Types.FixedCharType.of(charType.getLength()); | ||
} else if (typeClass == io.trino.spi.type.VarcharType.class) { | ||
io.trino.spi.type.VarcharType varcharType = (io.trino.spi.type.VarcharType) type; | ||
|
||
// If the length is not specified, it is a VARCHAR without length, we convert it to a string | ||
// type. | ||
if (varcharType.getLength().isEmpty()) { | ||
return Types.StringType.get(); | ||
} | ||
} | ||
|
||
if (gravitinoType.name() == Name.FIXEDCHAR) { | ||
if (((Types.FixedCharType) gravitinoType).length() > MYSQL_CHAR_LENGTH_LIMIT) { | ||
int length = varcharType.getLength().get(); | ||
if (length > MYSQL_VARCHAR_LENGTH_LIMIT) { | ||
throw new TrinoException( | ||
GravitinoErrorCode.GRAVITINO_ILLEGAL_ARGUMENT, | ||
"MySQL does not support the datatype CHAR with the length greater than 255"); | ||
"MySQL does not support the datatype VARCHAR with the length greater than " | ||
+ MYSQL_VARCHAR_LENGTH_LIMIT); | ||
} | ||
return Types.VarCharType.of(length); | ||
} | ||
return gravitinoType; | ||
|
||
return super.getGravitinoType(type); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing the test cases: