Skip to content
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

feat(oceanbase-catalog): Add implementation for converter package #5182

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,20 @@
*/
package org.apache.gravitino.catalog.oceanbase.converter;

import static org.apache.gravitino.rel.Column.DEFAULT_VALUE_NOT_SET;
import static org.apache.gravitino.rel.Column.DEFAULT_VALUE_OF_CURRENT_TIMESTAMP;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Objects;
import org.apache.gravitino.catalog.jdbc.converter.JdbcColumnDefaultValueConverter;
import org.apache.gravitino.catalog.jdbc.converter.JdbcTypeConverter;
import org.apache.gravitino.exceptions.GravitinoRuntimeException;
import org.apache.gravitino.rel.expressions.Expression;
import org.apache.gravitino.rel.expressions.UnparsedExpression;
import org.apache.gravitino.rel.expressions.literals.Literals;
import org.apache.gravitino.rel.types.Decimal;
import org.apache.gravitino.rel.types.Types;

public class OceanBaseColumnDefaultValueConverter extends JdbcColumnDefaultValueConverter {

Expand All @@ -31,6 +41,73 @@ public Expression toGravitino(
String columnDefaultValue,
boolean isExpression,
boolean nullable) {
throw new GravitinoRuntimeException("Not implemented yet.");
if (Objects.isNull(columnDefaultValue)) {
return nullable ? Literals.NULL : DEFAULT_VALUE_NOT_SET;
}

if (columnDefaultValue.equalsIgnoreCase(NULL)) {
return Literals.NULL;
}

if (isExpression) {
if (columnDefaultValue.equals(CURRENT_TIMESTAMP)) {
return DEFAULT_VALUE_OF_CURRENT_TIMESTAMP;
}
// The parsing of OceanBase expressions is complex, so we are not currently undertaking the
// parsing.
return UnparsedExpression.of(columnDefaultValue);
}

switch (type.getTypeName().toLowerCase()) {
case OceanBaseTypeConverter.TINYINT:
return Literals.byteLiteral(Byte.valueOf(columnDefaultValue));
case OceanBaseTypeConverter.TINYINT_UNSIGNED:
return Literals.unsignedByteLiteral(Short.valueOf(columnDefaultValue));
case OceanBaseTypeConverter.SMALLINT:
return Literals.shortLiteral(Short.valueOf(columnDefaultValue));
case OceanBaseTypeConverter.SMALLINT_UNSIGNED:
return Literals.unsignedShortLiteral(Integer.valueOf(columnDefaultValue));
case OceanBaseTypeConverter.INT:
return Literals.integerLiteral(Integer.valueOf(columnDefaultValue));
case OceanBaseTypeConverter.INT_UNSIGNED:
return Literals.unsignedIntegerLiteral(Long.valueOf(columnDefaultValue));
case OceanBaseTypeConverter.BIGINT:
return Literals.longLiteral(Long.valueOf(columnDefaultValue));
case OceanBaseTypeConverter.BIGINT_UNSIGNED:
return Literals.unsignedLongLiteral(Decimal.of(columnDefaultValue));
case OceanBaseTypeConverter.FLOAT:
return Literals.floatLiteral(Float.valueOf(columnDefaultValue));
case OceanBaseTypeConverter.DOUBLE:
return Literals.doubleLiteral(Double.valueOf(columnDefaultValue));
case OceanBaseTypeConverter.NUMBER:
case OceanBaseTypeConverter.NUMERIC:
case OceanBaseTypeConverter.DECIMAL:
return Literals.decimalLiteral(
Decimal.of(
columnDefaultValue,
Integer.parseInt(type.getColumnSize()),
Integer.parseInt(type.getScale())));
case JdbcTypeConverter.DATE:
return Literals.dateLiteral(LocalDate.parse(columnDefaultValue, DATE_FORMATTER));
case JdbcTypeConverter.TIME:
return Literals.timeLiteral(LocalTime.parse(columnDefaultValue, DATE_TIME_FORMATTER));
case JdbcTypeConverter.TIMESTAMP:
case OceanBaseTypeConverter.DATETIME:
return CURRENT_TIMESTAMP.equals(columnDefaultValue)
? DEFAULT_VALUE_OF_CURRENT_TIMESTAMP
: Literals.timestampLiteral(
LocalDateTime.parse(columnDefaultValue, DATE_TIME_FORMATTER));
case JdbcTypeConverter.VARCHAR:
return Literals.of(
columnDefaultValue, Types.VarCharType.of(Integer.parseInt(type.getColumnSize())));
case OceanBaseTypeConverter.CHAR:
return Literals.of(
columnDefaultValue, Types.FixedCharType.of(Integer.parseInt(type.getColumnSize())));
case OceanBaseTypeConverter.JSON:
case JdbcTypeConverter.TEXT:
return Literals.stringLiteral(columnDefaultValue);
default:
return UnparsedExpression.of(columnDefaultValue);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,30 @@
import java.sql.SQLException;
import org.apache.gravitino.catalog.jdbc.converter.JdbcExceptionConverter;
import org.apache.gravitino.exceptions.GravitinoRuntimeException;
import org.apache.gravitino.exceptions.NoSuchSchemaException;
import org.apache.gravitino.exceptions.NoSuchTableException;
import org.apache.gravitino.exceptions.SchemaAlreadyExistsException;
import org.apache.gravitino.exceptions.TableAlreadyExistsException;

/** Exception converter to Apache Gravitino exception for OceanBase. */
public class OceanBaseExceptionConverter extends JdbcExceptionConverter {

@SuppressWarnings("FormatStringAnnotation")
@Override
public GravitinoRuntimeException toGravitinoException(SQLException se) {
return new GravitinoRuntimeException("Not implemented yet.");
switch (se.getErrorCode()) {
case 1007:
return new SchemaAlreadyExistsException(se, se.getMessage());
case 1050:
return new TableAlreadyExistsException(se, se.getMessage());
case 1008:
case 1049:
return new NoSuchSchemaException(se, se.getMessage());
case 1146:
case 1051:
return new NoSuchTableException(se, se.getMessage());
default:
return new GravitinoRuntimeException(se, se.getMessage());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,132 @@
package org.apache.gravitino.catalog.oceanbase.converter;

import org.apache.gravitino.catalog.jdbc.converter.JdbcTypeConverter;
import org.apache.gravitino.exceptions.GravitinoRuntimeException;
import org.apache.gravitino.rel.types.Type;
import org.apache.gravitino.rel.types.Types;

/** Type converter for OceanBase. */
public class OceanBaseTypeConverter extends JdbcTypeConverter {

// More data types will be added.
static final String TINYINT = "tinyint";
static final String TINYINT_UNSIGNED = "tinyint unsigned";
static final String SMALLINT = "smallint";
static final String SMALLINT_UNSIGNED = "smallint unsigned";
static final String INT = "int";
static final String INT_UNSIGNED = "int unsigned";
static final String BIGINT = "bigint";
static final String BIGINT_UNSIGNED = "bigint unsigned";
static final String FLOAT = "float";
static final String DOUBLE = "double";
static final String DECIMAL = "decimal";
static final String NUMBER = "number";
static final String NUMERIC = "numeric";
static final String CHAR = "char";
static final String BINARY = "binary";
static final String DATETIME = "datetime";
static final String JSON = "json";

@Override
public Type toGravitino(JdbcTypeBean typeBean) {
throw new GravitinoRuntimeException("Not implemented yet.");
switch (typeBean.getTypeName().toLowerCase()) {
case TINYINT:
return Types.ByteType.get();
case TINYINT_UNSIGNED:
return Types.ByteType.unsigned();
case SMALLINT:
return Types.ShortType.get();
case SMALLINT_UNSIGNED:
return Types.ShortType.unsigned();
case INT:
return Types.IntegerType.get();
case INT_UNSIGNED:
return Types.IntegerType.unsigned();
case BIGINT:
return Types.LongType.get();
case BIGINT_UNSIGNED:
return Types.LongType.unsigned();
case FLOAT:
return Types.FloatType.get();
case DOUBLE:
return Types.DoubleType.get();
case DATE:
return Types.DateType.get();
case TIME:
return Types.TimeType.get();
case TIMESTAMP:
return Types.TimestampType.withTimeZone();
case DATETIME:
return Types.TimestampType.withoutTimeZone();
case NUMBER:
case NUMERIC:
case DECIMAL:
return Types.DecimalType.of(
Integer.parseInt(typeBean.getColumnSize()), Integer.parseInt(typeBean.getScale()));
case VARCHAR:
return Types.VarCharType.of(Integer.parseInt(typeBean.getColumnSize()));
case CHAR:
return Types.FixedCharType.of(Integer.parseInt(typeBean.getColumnSize()));
case JSON:
case TEXT:
return Types.StringType.get();
case BINARY:
return Types.BinaryType.get();
default:
return Types.ExternalType.of(typeBean.getTypeName());
}
}

@Override
public String fromGravitino(Type type) {
throw new GravitinoRuntimeException("Not implemented yet.");
if (type instanceof Types.ByteType) {
if (((Types.ByteType) type).signed()) {
return TINYINT;
} else {
return TINYINT_UNSIGNED;
}
} else if (type instanceof Types.ShortType) {
if (((Types.ShortType) type).signed()) {
return SMALLINT;
} else {
return SMALLINT_UNSIGNED;
}
} else if (type instanceof Types.IntegerType) {
if (((Types.IntegerType) type).signed()) {
return INT;
} else {
return INT_UNSIGNED;
}
} else if (type instanceof Types.LongType) {
if (((Types.LongType) type).signed()) {
return BIGINT;
} else {
return BIGINT_UNSIGNED;
}
} else if (type instanceof Types.FloatType) {
return type.simpleString();
} else if (type instanceof Types.DoubleType) {
return type.simpleString();
} else if (type instanceof Types.BooleanType) {
return type.simpleString();
} else if (type instanceof Types.StringType) {
return TEXT;
} else if (type instanceof Types.DateType) {
return type.simpleString();
} else if (type instanceof Types.TimeType) {
return type.simpleString();
} else if (type instanceof Types.TimestampType) {
return ((Types.TimestampType) type).hasTimeZone() ? TIMESTAMP : DATETIME;
} else if (type instanceof Types.DecimalType) {
return type.simpleString();
} else if (type instanceof Types.VarCharType) {
return type.simpleString();
} else if (type instanceof Types.FixedCharType) {
return type.simpleString();
} else if (type instanceof Types.BinaryType) {
return type.simpleString();
} else if (type instanceof Types.ExternalType) {
return ((Types.ExternalType) type).catalogString();
}
throw new IllegalArgumentException(
String.format("Couldn't convert Gravitino type %s to OceanBase type", type.simpleString()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.gravitino.catalog.oceanbase.converter;

import static org.apache.gravitino.catalog.jdbc.converter.JdbcTypeConverter.DATE;
import static org.apache.gravitino.catalog.jdbc.converter.JdbcTypeConverter.TEXT;
import static org.apache.gravitino.catalog.jdbc.converter.JdbcTypeConverter.TIME;
import static org.apache.gravitino.catalog.jdbc.converter.JdbcTypeConverter.TIMESTAMP;
import static org.apache.gravitino.catalog.jdbc.converter.JdbcTypeConverter.VARCHAR;
import static org.apache.gravitino.catalog.oceanbase.converter.OceanBaseTypeConverter.BIGINT;
import static org.apache.gravitino.catalog.oceanbase.converter.OceanBaseTypeConverter.BINARY;
import static org.apache.gravitino.catalog.oceanbase.converter.OceanBaseTypeConverter.CHAR;
import static org.apache.gravitino.catalog.oceanbase.converter.OceanBaseTypeConverter.DATETIME;
import static org.apache.gravitino.catalog.oceanbase.converter.OceanBaseTypeConverter.DECIMAL;
import static org.apache.gravitino.catalog.oceanbase.converter.OceanBaseTypeConverter.DOUBLE;
import static org.apache.gravitino.catalog.oceanbase.converter.OceanBaseTypeConverter.FLOAT;
import static org.apache.gravitino.catalog.oceanbase.converter.OceanBaseTypeConverter.INT;
import static org.apache.gravitino.catalog.oceanbase.converter.OceanBaseTypeConverter.JSON;
import static org.apache.gravitino.catalog.oceanbase.converter.OceanBaseTypeConverter.TINYINT;

import org.apache.gravitino.catalog.jdbc.converter.JdbcTypeConverter;
import org.apache.gravitino.rel.types.Type;
import org.apache.gravitino.rel.types.Types;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

/**
* Test class for {@link org.apache.gravitino.catalog.oceanbase.converter.OceanBaseTypeConverter}
*/
public class TestOceanBaseTypeConverter {

private static final OceanBaseTypeConverter MYSQL_TYPE_CONVERTER = new OceanBaseTypeConverter();
private static final String USER_DEFINED_TYPE = "user-defined";

@Test
public void testToGravitinoType() {
checkJdbcTypeToGravitinoType(Types.ByteType.get(), TINYINT, null, null);
checkJdbcTypeToGravitinoType(Types.IntegerType.get(), INT, null, null);
checkJdbcTypeToGravitinoType(Types.LongType.get(), BIGINT, null, null);
checkJdbcTypeToGravitinoType(Types.FloatType.get(), FLOAT, null, null);
checkJdbcTypeToGravitinoType(Types.DoubleType.get(), DOUBLE, null, null);
checkJdbcTypeToGravitinoType(Types.DateType.get(), DATE, null, null);
checkJdbcTypeToGravitinoType(Types.TimeType.get(), TIME, null, null);
checkJdbcTypeToGravitinoType(Types.TimestampType.withoutTimeZone(), DATETIME, null, null);
checkJdbcTypeToGravitinoType(Types.TimestampType.withTimeZone(), TIMESTAMP, null, null);
checkJdbcTypeToGravitinoType(Types.DecimalType.of(10, 2), DECIMAL, "10", "2");
checkJdbcTypeToGravitinoType(Types.VarCharType.of(20), VARCHAR, "20", null);
checkJdbcTypeToGravitinoType(Types.FixedCharType.of(20), CHAR, "20", null);
checkJdbcTypeToGravitinoType(Types.StringType.get(), TEXT, null, null);
checkJdbcTypeToGravitinoType(Types.StringType.get(), JSON, null, null);
checkJdbcTypeToGravitinoType(Types.BinaryType.get(), BINARY, null, null);
checkJdbcTypeToGravitinoType(
Types.ExternalType.of(USER_DEFINED_TYPE), USER_DEFINED_TYPE, null, null);
}

@Test
public void testFromGravitinoType() {
checkGravitinoTypeToJdbcType(TINYINT, Types.ByteType.get());
checkGravitinoTypeToJdbcType(INT, Types.IntegerType.get());
checkGravitinoTypeToJdbcType(BIGINT, Types.LongType.get());
checkGravitinoTypeToJdbcType(FLOAT, Types.FloatType.get());
checkGravitinoTypeToJdbcType(DOUBLE, Types.DoubleType.get());
checkGravitinoTypeToJdbcType(DATE, Types.DateType.get());
checkGravitinoTypeToJdbcType(TIME, Types.TimeType.get());
checkGravitinoTypeToJdbcType(TIMESTAMP, Types.TimestampType.withTimeZone());
checkGravitinoTypeToJdbcType(DATETIME, Types.TimestampType.withoutTimeZone());
checkGravitinoTypeToJdbcType(DECIMAL + "(10,2)", Types.DecimalType.of(10, 2));
checkGravitinoTypeToJdbcType(VARCHAR + "(20)", Types.VarCharType.of(20));
checkGravitinoTypeToJdbcType(CHAR + "(20)", Types.FixedCharType.of(20));
checkGravitinoTypeToJdbcType(TEXT, Types.StringType.get());
checkGravitinoTypeToJdbcType(BINARY, Types.BinaryType.get());
checkGravitinoTypeToJdbcType(USER_DEFINED_TYPE, Types.ExternalType.of(USER_DEFINED_TYPE));
Assertions.assertThrows(
IllegalArgumentException.class,
() -> MYSQL_TYPE_CONVERTER.fromGravitino(Types.UnparsedType.of(USER_DEFINED_TYPE)));
}

protected void checkGravitinoTypeToJdbcType(String jdbcTypeName, Type gravitinoType) {
Assertions.assertEquals(jdbcTypeName, MYSQL_TYPE_CONVERTER.fromGravitino(gravitinoType));
}

protected void checkJdbcTypeToGravitinoType(
Type gravitinoType, String jdbcTypeName, String columnSize, String scale) {
JdbcTypeConverter.JdbcTypeBean typeBean = createTypeBean(jdbcTypeName, columnSize, scale);
Assertions.assertEquals(gravitinoType, MYSQL_TYPE_CONVERTER.toGravitino(typeBean));
}

protected static JdbcTypeConverter.JdbcTypeBean createTypeBean(
String typeName, String columnSize, String scale) {
return new JdbcTypeConverter.JdbcTypeBean(typeName) {
{
setColumnSize(columnSize);
setScale(scale);
}
};
}
}
Loading