calcite自定义数据类型

calcite本身基于JDBC规范实现了基础的数据类型,但不是所有类型。
比如空间类型Geometry,只是简单的存在。
当我们想要自定义数据类型时,可以从以下方面修改源码。

下面的修改经过实践测试。

扩展了Geometry的具体数据类型,增加了 TRAJECTORYROAD_NETWORK两种自定义类型。

org/apache/calcite/sql/type/SqlTypeFamily.java


    GEOMETRY
    TRAJECTORY,
    ROAD_NETWORK,

getTypeNames

            case GEOMETRY:
                return ImmutableList.of(SqlTypeName.GEOMETRY, SqlTypeName.POINT,
                        SqlTypeName.MULTIPOINT, SqlTypeName.LINESTRING, SqlTypeName.MULTILINESTRING,
                        SqlTypeName.POLYGON, SqlTypeName.MULTIPOLYGON, SqlTypeName.GEOMETRYCOLLECTION);
            case TRAJECTORY:
                return ImmutableList.of(SqlTypeName.TRAJECTORY);
            case ROAD_NETWORK:
                return ImmutableList.of(SqlTypeName.ROADNETWORK);

getDefaultConcreteType

            case GEOMETRY:
                return factory.createSqlType(SqlTypeName.GEOMETRY);
            //            case GEOMETRYCOLLECTION:
            //                return factory.createSqlType(SqlTypeName.GEOMETRYCOLLECTION);
            case TRAJECTORY:
                return factory.createSqlType(SqlTypeName.TRAJECTORY);
            case ROAD_NETWORK:
                return factory.createSqlType(SqlTypeName.ROADNETWORK);

org/apache/calcite/sql/type/SqlTypeName.java

    POINT(PrecScale.NO_NO, false, Types.OTHER, SqlTypeFamily.GEOMETRY),
    MULTIPOINT(PrecScale.NO_NO, false, Types.OTHER, SqlTypeFamily.GEOMETRY),
    LINESTRING(PrecScale.NO_NO, false, Types.OTHER, SqlTypeFamily.GEOMETRY),
    MULTILINESTRING(PrecScale.NO_NO, false, Types.OTHER, SqlTypeFamily.GEOMETRY),
    POLYGON(PrecScale.NO_NO, false, Types.OTHER, SqlTypeFamily.GEOMETRY),
    MULTIPOLYGON(PrecScale.NO_NO, false, Types.OTHER, SqlTypeFamily.GEOMETRY),
    GEOMETRYCOLLECTION(PrecScale.NO_NO, false, Types.OTHER, SqlTypeFamily.GEOMETRY),
    GEOMETRY(PrecScale.NO_NO, false, ExtraSqlTypes.GEOMETRY, SqlTypeFamily.GEOMETRY),
    TRAJECTORY(PrecScale.NO_NO, false, Types.OTHER, SqlTypeFamily.TRAJECTORY),
    ROADNETWORK(PrecScale.NO_NO, false, Types.OTHER, SqlTypeFamily.ROAD_NETWORK),

org/apache/calcite/sql/type/SqlTypeUtil.java

canCastFrom

    public static boolean canCastFrom(
            RelDataType toType,
            RelDataType fromType,
            boolean coerce) {
        if (toType.equals(fromType)) {
            return true;
        }
        if (isAny(toType) || isAny(fromType)) {
            return true;
        }

        final SqlTypeName fromTypeName = fromType.getSqlTypeName();
        final SqlTypeName toTypeName = toType.getSqlTypeName();
        // start
        if (toTypeName.equals(fromTypeName)
                || (toType.getSqlTypeName() == SqlTypeName.GEOMETRY && fromTypeName.getFamily() == SqlTypeFamily.GEOMETRY)) {
            return true;
        }
        // end
		...

convertTypeToSpec

    public static SqlDataTypeSpec convertTypeToSpec(RelDataType type,
                                                    String charSetName, int maxPrecision) {
        SqlTypeName typeName = type.getSqlTypeName();

        // TODO jvs 28-Dec-2004:  support row types, user-defined types,
        // interval types, multiset types, etc
        assert typeName != null;

        final SqlTypeNameSpec typeNameSpec;
        // start 自定义类型
        if (isAtomic(type) || isNull(type) || typeName == SqlTypeName.GEOMETRY) {
        // end 自定义类型
		...

org/apache/calcite/adapter/enumerable/RexToLixTranslator.java

translateLiteral

            case POINT:
            case MULTIPOINT:
            case LINESTRING:
            case MULTILINESTRING:
            case POLYGON:
            case MULTIPOLYGON:
            case GEOMETRYCOLLECTION:
            case GEOMETRY:
                final Geometry geom = literal.getValueAs(Geometry.class);
                final String wkt = geom.toString();
                return Expressions.call(null, BuiltInMethod.ST_GEOM_FROM_TEXT.method,
                        Expressions.constant(wkt));

org/apache/calcite/avatica/ColumnMetaData.java

enum Rep

    POINT(Point.class,100001),
    MULTI_POINT(MultiPoint.class,100002),
    LINESTRING(LineString.class,100003),
    MULTI_LINESTRING(MultiLineString.class,100004),
    POLYGON(Polygon.class,100005),
    MULTI_POLYGON(MultiPolygon.class,100006),
    TRAJECTORY(Trajectory.class,100007),
    ROAD_NETWORK(RoadNetwork.class,100008),
    GEOMETRY(Geometry.class,100009)

AvaticaType

  public static class AvaticaType {
...
    public String columnClassName() {
      // edit start 因为java.sql.Types最好不要改,我们就直接修改这里吧
      final Class<?> originCls = SqlType.valueOf(id).boxedClass();
      final Class<?> deepCls = this.rep.clazz;
      return originCls == Object.class || Geometry.class.isAssignableFrom(deepCls) ? deepCls.getName() : originCls.getName();
      // return SqlType.valueOf(id).boxedClass().getName();
      // edit end
    }

org/apache/calcite/jdbc/JavaTypeFactoryImpl.java

public Type getJavaClass(RelDataType type)

	case POINT:
	case MULTIPOINT:
	case LINESTRING:
	case MULTILINESTRING:
	case POLYGON:
	case MULTIPOLYGON:
	case GEOMETRYCOLLECTION:
	case GEOMETRY:
		return Geometry.class;
	case TRAJECTORY:
		return Trajectory.class;
	case ROADNETWORK:
		return RoadNetwork.class;

org/apache/calcite/rex/RexBuilder.java

public RexNode makeLiteral(Object value, RelDataType type,
boolean allowCast, boolean trim)

	case POINT:
	case MULTIPOINT:
	case LINESTRING:
	case MULTILINESTRING:
	case POLYGON:
	case MULTIPOLYGON:
	case GEOMETRYCOLLECTION:
	case GEOMETRY:
		return new RexLiteral((Comparable) value, guessType(value),
				SqlTypeName.GEOMETRY);

org/apache/calcite/rex/RexLiteral.java

public static boolean valueMatchesType(
Comparable value,
SqlTypeName typeName,
boolean strict)

	case POINT:
	case MULTIPOINT:
	case LINESTRING:
	case MULTILINESTRING:
	case POLYGON:
	case MULTIPOLYGON:
	case GEOMETRYCOLLECTION:
	case GEOMETRY:
		return value instanceof Geometry;

private static void appendAsJava(Comparable value, StringBuilder sb,
SqlTypeName typeName, RelDataType type, boolean java,
RexDigestIncludeType includeType)

            case GEOMETRY:
                final String wkt = value.toString();
                sb.append(wkt);
                break;

org/apache/calcite/sql/type/JavaToSqlTypeConversionRules.java

private final Map<Class<?>, SqlTypeName> rules

	.put(Point.class, SqlTypeName.POINT)
	.put(MultiPoint.class, SqlTypeName.MULTIPOINT)
	.put(LineString.class, SqlTypeName.LINESTRING)
	.put(MultiLineString.class, SqlTypeName.MULTILINESTRING)
	.put(Polygon.class, SqlTypeName.POLYGON)
	.put(MultiPolygon.class, SqlTypeName.MULTIPOLYGON)
	.put(Geometry.class, SqlTypeName.GEOMETRY)
	.put(GeometryCollection.class, SqlTypeName.GEOMETRYCOLLECTION)
	.put(RoadNetwork.class, SqlTypeName.ROADNETWORK)
	.put(Trajectory.class, SqlTypeName.TRAJECTORY)

org/apache/calcite/sql/type/SqlTypeAssignmentRule.java

static {

	// GEOMETRY is assignable from ...
	rules.add(SqlTypeName.ROADNETWORK, EnumSet.of(SqlTypeName.ROADNETWORK));
	rules.add(SqlTypeName.TRAJECTORY, EnumSet.of(SqlTypeName.TRAJECTORY));
	rules.add(SqlTypeName.GEOMETRY, EnumSet.of(SqlTypeName.GEOMETRY));
	rules.add(SqlTypeName.POINT, EnumSet.of(SqlTypeName.GEOMETRY));
	rules.add(SqlTypeName.MULTIPOINT, EnumSet.of(SqlTypeName.GEOMETRY));
	rules.add(SqlTypeName.LINESTRING, EnumSet.of(SqlTypeName.GEOMETRY));
	rules.add(SqlTypeName.MULTILINESTRING, EnumSet.of(SqlTypeName.GEOMETRY));
	rules.add(SqlTypeName.POLYGON, EnumSet.of(SqlTypeName.GEOMETRY));
	rules.add(SqlTypeName.MULTIPOLYGON, EnumSet.of(SqlTypeName.GEOMETRY));
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值