diff --git a/presto-postgresql/pom.xml b/presto-postgresql/pom.xml index 6aa4ee6fc508..e74137d3be00 100644 --- a/presto-postgresql/pom.xml +++ b/presto-postgresql/pom.xml @@ -67,6 +67,11 @@ joda-time + + javax.validation + validation-api + + io.prestosql diff --git a/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/PostgreSqlClient.java b/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/PostgreSqlClient.java index d6e7a16bab14..f80fe83e7772 100644 --- a/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/PostgreSqlClient.java +++ b/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/PostgreSqlClient.java @@ -17,6 +17,7 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import io.airlift.json.ObjectMapperProvider; import io.airlift.slice.DynamicSliceOutput; import io.airlift.slice.Slice; @@ -97,12 +98,24 @@ public class PostgreSqlClient private static final String DUPLICATE_TABLE_SQLSTATE = "42P07"; private final Type jsonType; + private final boolean supportArrays; @Inject - public PostgreSqlClient(BaseJdbcConfig config, TypeManager typeManager) + public PostgreSqlClient(BaseJdbcConfig config, PostgreSqlConfig postgreSqlConfig, TypeManager typeManager) { super(config, "\"", new DriverConnectionFactory(new Driver(), config)); this.jsonType = typeManager.getType(new TypeSignature(StandardTypes.JSON)); + + switch (postgreSqlConfig.getArrayMapping()) { + case DISABLED: + supportArrays = false; + break; + case AS_ARRAY: + supportArrays = true; + break; + default: + throw new IllegalArgumentException("Unsupported ArrayMapping: " + postgreSqlConfig.getArrayMapping()); + } } @Override @@ -197,6 +210,9 @@ public List getColumns(ConnectorSession session, JdbcTableHand private Map getArrayColumnDimensions(Connection connection, JdbcTableHandle tableHandle) throws SQLException { + if (!supportArrays) { + return ImmutableMap.of(); + } String sql = "" + "SELECT att.attname, att.attndims " + "FROM pg_attribute att " + @@ -237,7 +253,7 @@ public Optional toPrestoType(ConnectorSession session, JdbcTypeHa if (typeHandle.getJdbcType() == Types.TIMESTAMP) { return Optional.of(timestampColumnMapping(session)); } - if (typeHandle.getJdbcType() == Types.ARRAY) { + if (typeHandle.getJdbcType() == Types.ARRAY && supportArrays) { if (!typeHandle.getArrayDimensions().isPresent()) { return Optional.empty(); } @@ -278,7 +294,7 @@ public WriteMapping toWriteMapping(ConnectorSession session, Type type) if (type.getTypeSignature().getBase().equals(StandardTypes.JSON)) { return WriteMapping.sliceMapping("jsonb", typedVarcharWriteFunction("json")); } - if (type instanceof ArrayType) { + if (type instanceof ArrayType && supportArrays) { Type elementType = ((ArrayType) type).getElementType(); String elementDataType = toWriteMapping(session, elementType).getDataType(); return WriteMapping.blockMapping(elementDataType + "[]", arrayWriteFunction(session, elementType, getArrayElementPgTypeName(session, this, elementType))); diff --git a/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/PostgreSqlClientModule.java b/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/PostgreSqlClientModule.java index 6b91a2ba87d0..122f98f70203 100644 --- a/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/PostgreSqlClientModule.java +++ b/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/PostgreSqlClientModule.java @@ -29,5 +29,6 @@ public void configure(Binder binder) { binder.bind(JdbcClient.class).to(PostgreSqlClient.class).in(Scopes.SINGLETON); configBinder(binder).bindConfig(BaseJdbcConfig.class); + configBinder(binder).bindConfig(PostgreSqlConfig.class); } } diff --git a/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/PostgreSqlConfig.java b/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/PostgreSqlConfig.java new file mode 100644 index 000000000000..6d334bea5b9a --- /dev/null +++ b/presto-postgresql/src/main/java/io/prestosql/plugin/postgresql/PostgreSqlConfig.java @@ -0,0 +1,42 @@ +/* + * Licensed 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 io.prestosql.plugin.postgresql; + +import io.airlift.configuration.Config; + +import javax.validation.constraints.NotNull; + +public class PostgreSqlConfig +{ + private ArrayMapping arrayMapping = ArrayMapping.DISABLED; + + public enum ArrayMapping { + DISABLED, + @Deprecated // TODO https://github.com/prestosql/presto/issues/682 + AS_ARRAY, + } + + @NotNull + public ArrayMapping getArrayMapping() + { + return arrayMapping; + } + + @Config("postgresql.experimental.array-mapping") + public PostgreSqlConfig setArrayMapping(ArrayMapping arrayMapping) + { + this.arrayMapping = arrayMapping; + return this; + } +} diff --git a/presto-postgresql/src/test/java/io/prestosql/plugin/postgresql/TestPostgreSqlConfig.java b/presto-postgresql/src/test/java/io/prestosql/plugin/postgresql/TestPostgreSqlConfig.java new file mode 100644 index 000000000000..a8270451a6f4 --- /dev/null +++ b/presto-postgresql/src/test/java/io/prestosql/plugin/postgresql/TestPostgreSqlConfig.java @@ -0,0 +1,43 @@ +/* + * Licensed 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 io.prestosql.plugin.postgresql; + +import com.google.common.collect.ImmutableMap; +import io.airlift.configuration.testing.ConfigAssertions; +import org.testng.annotations.Test; + +import java.util.Map; + +public class TestPostgreSqlConfig +{ + @Test + public void testDefaults() + { + ConfigAssertions.assertRecordedDefaults(ConfigAssertions.recordDefaults(PostgreSqlConfig.class) + .setArrayMapping(PostgreSqlConfig.ArrayMapping.DISABLED)); + } + + @Test + public void testExplicitPropertyMappings() + { + Map properties = new ImmutableMap.Builder() + .put("postgresql.experimental.array-mapping", "AS_ARRAY") + .build(); + + PostgreSqlConfig expected = new PostgreSqlConfig() + .setArrayMapping(PostgreSqlConfig.ArrayMapping.AS_ARRAY); + + ConfigAssertions.assertFullMapping(properties, expected); + } +} diff --git a/presto-postgresql/src/test/java/io/prestosql/plugin/postgresql/TestPostgreSqlDistributedQueries.java b/presto-postgresql/src/test/java/io/prestosql/plugin/postgresql/TestPostgreSqlDistributedQueries.java index 62b6b40cfb46..d3a3b48cc464 100644 --- a/presto-postgresql/src/test/java/io/prestosql/plugin/postgresql/TestPostgreSqlDistributedQueries.java +++ b/presto-postgresql/src/test/java/io/prestosql/plugin/postgresql/TestPostgreSqlDistributedQueries.java @@ -55,6 +55,13 @@ protected boolean supportsViews() return false; } + @Override + protected boolean supportsArrays() + { + // Arrays are supported conditionally. Check the defaults. + return new PostgreSqlConfig().getArrayMapping() != PostgreSqlConfig.ArrayMapping.DISABLED; + } + @Override public void testCommentTable() { diff --git a/presto-postgresql/src/test/java/io/prestosql/plugin/postgresql/TestPostgreSqlTypeMapping.java b/presto-postgresql/src/test/java/io/prestosql/plugin/postgresql/TestPostgreSqlTypeMapping.java index d5f61b4928f1..7eb9dd169f6d 100644 --- a/presto-postgresql/src/test/java/io/prestosql/plugin/postgresql/TestPostgreSqlTypeMapping.java +++ b/presto-postgresql/src/test/java/io/prestosql/plugin/postgresql/TestPostgreSqlTypeMapping.java @@ -85,7 +85,7 @@ public TestPostgreSqlTypeMapping() private TestPostgreSqlTypeMapping(TestingPostgreSqlServer postgreSqlServer) { - super(() -> createPostgreSqlQueryRunner(postgreSqlServer, ImmutableMap.of(), ImmutableList.of())); + super(() -> createPostgreSqlQueryRunner(postgreSqlServer, ImmutableMap.of("postgresql.experimental.array-mapping", "AS_ARRAY"), ImmutableList.of())); this.postgreSqlServer = postgreSqlServer; }