From 821fb23db58ca0351e4e57ab21a1d50b9761dc86 Mon Sep 17 00:00:00 2001 From: datomo Date: Thu, 2 May 2024 16:29:58 +0200 Subject: [PATCH] added estimation for ANY types in jdbc, to handle some ARRAY edge cases --- .../polypheny/db/type/entity/PolyValue.java | 27 +++++++++++++++++++ .../db/adapter/jdbc/ResultSetEnumerable.java | 21 +++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/core/src/main/java/org/polypheny/db/type/entity/PolyValue.java b/core/src/main/java/org/polypheny/db/type/entity/PolyValue.java index 4e25658c25..ae192084d6 100644 --- a/core/src/main/java/org/polypheny/db/type/entity/PolyValue.java +++ b/core/src/main/java/org/polypheny/db/type/entity/PolyValue.java @@ -230,11 +230,38 @@ public static Function1 getPolyToJava( AlgDataType type, bool } case FILE, IMAGE, AUDIO, VIDEO -> o -> o.asBlob().asByteArray(); case DOCUMENT -> o -> o.asDocument().toJson(); + case ANY -> o -> getPolyToJavaRuntime( o, arrayAsList ); default -> throw new NotImplementedException( "meta: " + type.getFullTypeString() ); }; } + private static Object getPolyToJavaRuntime( PolyValue value, boolean arrayAsList ) { + if ( value == null || value.isNull() ) { + return null; + } + + return switch ( value.type ) { + case VARCHAR, CHAR, TEXT -> value.asString().value; + case INTEGER, TINYINT, SMALLINT -> value.asNumber().IntValue(); + case FLOAT, REAL -> value.asNumber().FloatValue(); + case DOUBLE -> value.asNumber().DoubleValue(); + case BIGINT -> value.asNumber().LongValue(); + case DECIMAL -> value.asNumber().BigDecimalValue(); + case DATE -> value.asDate().getDaysSinceEpoch(); + case TIME -> value.asTime().getMillisOfDay(); + case TIMESTAMP -> value.asTimestamp().millisSinceEpoch; + case BOOLEAN -> value.asBoolean().value; + case ARRAY -> arrayAsList + ? (value.asList().value.stream().map( e -> getPolyToJavaRuntime( e, true ) ).toList()) + : value.asList().value.stream().map( e -> getPolyToJavaRuntime( e, false ) ).toList().toArray(); + case FILE, IMAGE, AUDIO, VIDEO -> value.asBlob().asByteArray(); + case DOCUMENT -> value.asDocument().toJson(); + default -> throw new NotImplementedException( "meta: " + value.type ); + }; + } + + private static AlgDataType getAndDecreaseArrayDimensionIfNecessary( ArrayType type ) { AlgDataType component = type.getComponentType(); while ( component.getPolyType() == PolyType.ARRAY ) { diff --git a/plugins/jdbc-adapter-framework/src/main/java/org/polypheny/db/adapter/jdbc/ResultSetEnumerable.java b/plugins/jdbc-adapter-framework/src/main/java/org/polypheny/db/adapter/jdbc/ResultSetEnumerable.java index 45995eb139..223d155721 100644 --- a/plugins/jdbc-adapter-framework/src/main/java/org/polypheny/db/adapter/jdbc/ResultSetEnumerable.java +++ b/plugins/jdbc-adapter-framework/src/main/java/org/polypheny/db/adapter/jdbc/ResultSetEnumerable.java @@ -340,12 +340,33 @@ private static Array getArray( PolyValue value, AlgDataType type, ConnectionHand while ( t.getComponentType().getPolyType() == PolyType.ARRAY ) { t = t.getComponentType(); } + componentType = SqlType.valueOf( t.getComponentType().getPolyType().getJdbcOrdinal() ); + if ( t.getComponentType().getPolyType() == PolyType.ANY ) { + componentType = estimateFittingType( value.asList().value ); + } Object[] array = (Object[]) PolyValue.wrapNullableIfNecessary( PolyValue.getPolyToJava( type, false ), type.isNullable() ).apply( value ); return connectionHandler.createArrayOf( connectionHandler.getDialect().getArrayComponentTypeString( componentType ), array ); } + public static SqlType estimateFittingType( List value ) { + if ( value.isEmpty() ) { + return SqlType.NULL; + } else if ( value.stream().allMatch( PolyValue::isBoolean ) ) { + return SqlType.BOOLEAN; + } else if ( value.stream().allMatch( PolyValue::isNumber ) ) { + return SqlType.NUMERIC; + } else if ( value.stream().allMatch( PolyValue::isBinary ) ) { + return SqlType.BINARY; + } else if ( value.stream().allMatch( PolyValue::isString ) ) { + return SqlType.VARCHAR; + } + + return SqlType.ANY; + } + + @Override public Enumerator enumerator() { if ( preparedStatementEnricher == null ) {