From 93e474e0d06c3163dbcf4d7df9e7718a521155cb Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Thu, 16 May 2024 09:57:12 +0200 Subject: [PATCH 01/36] Prepare statement processing for the introduction of graphs --- .../statementProcessing/DocumentExecutor.java | 71 +++---------------- .../statementProcessing/Executor.java | 27 ++++++- .../RelationalExecutor.java | 63 +--------------- .../StatementProcessor.java | 44 +++++------- 4 files changed, 56 insertions(+), 149 deletions(-) diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java index 8f962b6075..f87abdc46c 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java @@ -25,7 +25,6 @@ import org.polypheny.db.prisminterface.PIServiceException; import org.polypheny.db.prisminterface.statements.PIStatement; import org.polypheny.db.prisminterface.utils.PrismUtils; -import org.polypheny.db.transaction.Statement; import org.polypheny.db.type.entity.PolyValue; import org.polypheny.prism.Frame; import org.polypheny.prism.StatementResult; @@ -43,24 +42,9 @@ DataModel getDataModel() { @Override StatementResult executeAndGetResult( PIStatement piStatement ) { - if ( hasInvalidNamespaceType( piStatement ) ) { - throw new PIServiceException( "The results of type " - + piStatement.getLanguage().dataModel() - + "returned by this statement can't be retrieved by a document retriever.", - "I9000", - 9000 - ); - } - PolyImplementation implementation = piStatement.getImplementation(); - if ( implementation == null ) { - throw new PIServiceException( "Can't retrieve results form an unexecuted statement.", - "I9002", - 9002 - ); - } - PIClient client = piStatement.getClient(); + throwOnIllegalState( piStatement ); StatementResult.Builder resultBuilder = StatementResult.newBuilder(); - if ( implementation.isDDL() ) { + if ( piStatement.getImplementation().isDDL() ) { resultBuilder.setScalar( 1 ); return resultBuilder.build(); } @@ -73,21 +57,8 @@ StatementResult executeAndGetResult( PIStatement piStatement ) { @Override StatementResult executeAndGetResult( PIStatement piStatement, int fetchSize ) { - if ( hasInvalidNamespaceType( piStatement ) ) { - throw new PIServiceException( "The results of type " - + piStatement.getLanguage().dataModel() - + "returned by this statement can't be retrieved by a document retriever.", - "I9000", - 9000 - ); - } + throwOnIllegalState( piStatement ); PolyImplementation implementation = piStatement.getImplementation(); - if ( implementation == null ) { - throw new PIServiceException( "Can't retrieve results form an unexecuted statement.", - "I9002", - 9002 - ); - } PIClient client = piStatement.getClient(); StatementResult.Builder resultBuilder = StatementResult.newBuilder(); if ( implementation.isDDL() ) { @@ -107,40 +78,18 @@ StatementResult executeAndGetResult( PIStatement piStatement, int fetchSize ) { @Override Frame fetch( PIStatement piStatement, int fetchSize ) { - if ( hasInvalidNamespaceType( piStatement ) ) { - throw new PIServiceException( "The results of type " - + piStatement.getLanguage().dataModel() - + "returned by this statement can't be retrieved by a document retriever.", - "I9000", - 9000 - ); - } + throwOnIllegalState( piStatement ); StopWatch executionStopWatch = piStatement.getExecutionStopWatch(); - Statement statement = piStatement.getStatement(); - if ( statement == null ) { - throw new PIServiceException( "Statement is not linked to a polypheny statement", - "I9001", - 9001 - ); - } PolyImplementation implementation = piStatement.getImplementation(); - if ( implementation == null ) { - throw new PIServiceException( "Can't fetch from an unexecuted statement.", - "I9002", - 9002 - ); - } ResultIterator iterator = piStatement.getIterator(); - if ( iterator == null ) { - throw new PIServiceException( "Can't fetch from an unexecuted statement.", - "I9002", - 9002 - ); - } startOrResumeStopwatch( executionStopWatch ); List data = iterator.getNextBatch( fetchSize ).stream().map( p -> p.get( 0 ) ).toList(); - executionStopWatch.stop(); - return PrismUtils.buildDocumentFrame( !iterator.hasMoreRows(), data ); + boolean isLast = !iterator.hasMoreRows(); + if ( isLast ) { + executionStopWatch.stop(); + implementation.getExecutionTimeMonitor().setExecutionTime( executionStopWatch.getNanoTime() ); + } + return PrismUtils.buildDocumentFrame( isLast, data ); } } diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/Executor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/Executor.java index 2030a84be3..0f691df7e8 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/Executor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/Executor.java @@ -17,7 +17,9 @@ package org.polypheny.db.prisminterface.statementProcessing; import org.apache.commons.lang3.time.StopWatch; +import org.polypheny.db.PolyImplementation; import org.polypheny.db.catalog.logistic.DataModel; +import org.polypheny.db.prisminterface.PIServiceException; import org.polypheny.db.prisminterface.statements.PIStatement; import org.polypheny.prism.Frame; import org.polypheny.prism.StatementResult; @@ -36,8 +38,29 @@ protected void startOrResumeStopwatch( StopWatch stopWatch ) { } - protected boolean hasInvalidNamespaceType( PIStatement piStatement ) { - return piStatement.getLanguage().dataModel() != getDataModel(); + protected void throwOnIllegalState( PIStatement piStatement ) { + DataModel statementDataModel = piStatement.getLanguage().dataModel(); + + if ( statementDataModel != getDataModel() ) { + String message = String.format( + "The results of type %s returned by this statement can't be retrieved by a %s retriever.", + statementDataModel.name().toLowerCase(), + getDataModel().name().toLowerCase() + ); + throw new PIServiceException( message, "I9000", 9000 ); + } + + if ( piStatement.getStatement() == null ) { + throw new PIServiceException( "Statement is not linked to a polypheny statement", + "I9001", + 9001 + ); + } + + PolyImplementation implementation = piStatement.getImplementation(); + if ( implementation == null ) { + throw new PIServiceException( "Can't retrieve results form an unexecuted statement.", "I9002", 9002 ); + } } diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/RelationalExecutor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/RelationalExecutor.java index f73afa9446..f05ef70c6f 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/RelationalExecutor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/RelationalExecutor.java @@ -47,28 +47,9 @@ DataModel getDataModel() { @Override StatementResult executeAndGetResult( PIStatement piStatement ) { - if ( hasInvalidNamespaceType( piStatement ) ) { - throw new PIServiceException( "The results of type " - + piStatement.getLanguage().dataModel() - + "returned by this statement can't be retrieved by a relational retriever.", - "I9000", - 9000 - ); - } + throwOnIllegalState( piStatement ); Statement statement = piStatement.getStatement(); - if ( statement == null ) { - throw new PIServiceException( "Statement is not linked to a polypheny statement", - "I9001", - 9001 - ); - } PolyImplementation implementation = piStatement.getImplementation(); - if ( implementation == null ) { - throw new PIServiceException( "Can't retrieve results from an unexecuted statement.", - "I9002", - 9002 - ); - } PIClient client = piStatement.getClient(); StatementResult.Builder resultBuilder = StatementResult.newBuilder(); if ( implementation.isDDL() || Kind.DML.contains( implementation.getKind() ) ) { @@ -86,28 +67,9 @@ StatementResult executeAndGetResult( PIStatement piStatement ) { public StatementResult executeAndGetResult( PIStatement piStatement, int fetchSize ) { - if ( hasInvalidNamespaceType( piStatement ) ) { - throw new PIServiceException( "The results of type " - + piStatement.getLanguage().dataModel() - + "returned by this statement can't be retrieved by a relational retriever.", - "I9000", - 9000 - ); - } + throwOnIllegalState( piStatement ); Statement statement = piStatement.getStatement(); - if ( statement == null ) { - throw new PIServiceException( "Statement is not linked to a polypheny statement", - "I9001", - 9001 - ); - } PolyImplementation implementation = piStatement.getImplementation(); - if ( implementation == null ) { - throw new PIServiceException( "Can't retrieve results from an unprepared statement.", - "I9002", - 9002 - ); - } PIClient client = piStatement.getClient(); StatementResult.Builder resultBuilder = StatementResult.newBuilder(); if ( Kind.DDL.contains( implementation.getKind() ) ) { @@ -134,29 +96,10 @@ public StatementResult executeAndGetResult( PIStatement piStatement, int fetchSi @Override public Frame fetch( PIStatement piStatement, int fetchSize ) { - if ( hasInvalidNamespaceType( piStatement ) ) { - throw new PIServiceException( "The results of type " - + piStatement.getLanguage().dataModel() - + "returned by this statement can't be retrieved by a relational retriever.", - "I9000", - 9000 - ); - } + throwOnIllegalState( piStatement ); StopWatch executionStopWatch = piStatement.getExecutionStopWatch(); PolyImplementation implementation = piStatement.getImplementation(); - if ( implementation == null ) { - throw new PIServiceException( "Can't fetch from an unprepared statement.", - "I9002", - 9002 - ); - } ResultIterator iterator = piStatement.getIterator(); - if ( iterator == null ) { - throw new PIServiceException( "Can't fetch from an unexecuted statement.", - "I9002", - 9002 - ); - } startOrResumeStopwatch( executionStopWatch ); List> rows = iterator.getNextBatch( fetchSize ); executionStopWatch.suspend(); diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java index 9af54b719a..e088a8feb7 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java @@ -44,10 +44,11 @@ public class StatementProcessor { private static final String ORIGIN = "prism-interface"; - private static final Map RESULT_RETRIEVERS = + private static final Map EXECUTORS = ImmutableMap.builder() .put( DataModel.RELATIONAL, new RelationalExecutor() ) .put( DataModel.DOCUMENT, new DocumentExecutor() ) + .put( DataModel.GRAPH, new GraphExecutor() ) .build(); @@ -90,27 +91,12 @@ public static void implement( PIStatement piStatement ) { public static StatementResult executeAndGetResult( PIStatement piStatement ) { - Executor executor = RESULT_RETRIEVERS.get( piStatement.getLanguage().dataModel() ); - if ( executor == null ) { - throw new PIServiceException( "No result retriever registered for namespace type " - + piStatement.getLanguage().dataModel(), - "I9004", - 9004 - ); - } - return executor.executeAndGetResult( piStatement ); + return getExecutorOrThrow( piStatement ).executeAndGetResult( piStatement ); } public static StatementResult executeAndGetResult( PIStatement piStatement, int fetchSize ) { - Executor executor = RESULT_RETRIEVERS.get( piStatement.getLanguage().dataModel() ); - if ( executor == null ) { - throw new PIServiceException( "No result retriever registered for namespace type " - + piStatement.getLanguage().dataModel(), - "I9004", - 9004 - ); - } + Executor executor = getExecutorOrThrow( piStatement ); try { return executor.executeAndGetResult( piStatement, fetchSize ); } catch ( Exception e ) { @@ -120,14 +106,7 @@ public static StatementResult executeAndGetResult( PIStatement piStatement, int public static Frame fetch( PIStatement piStatement, int fetchSize ) { - Executor executor = RESULT_RETRIEVERS.get( piStatement.getLanguage().dataModel() ); - if ( executor == null ) { - throw new PIServiceException( "No result retriever registered for namespace type " - + piStatement.getLanguage().dataModel(), - "I9004", - 9004 - ); - } + Executor executor = getExecutorOrThrow( piStatement ); return executor.fetch( piStatement, fetchSize ); } @@ -147,4 +126,17 @@ public static void prepare( PIPreparedStatement piStatement ) { piStatement.setParameterPolyTypes( parameterRowType.getFields().stream().map( AlgDataTypeField::getType ).toList() ); } + + private static Executor getExecutorOrThrow( PIStatement piStatement ) { + Executor executor = EXECUTORS.get( piStatement.getLanguage().dataModel() ); + if ( executor == null ) { + throw new PIServiceException( "No executor registered for namespace type " + + piStatement.getLanguage().dataModel(), + "I9004", + 9004 + ); + } + return executor; + } + } From bb40400ffa3e3e0368fb21289241d39702cc34e4 Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Thu, 16 May 2024 09:59:27 +0200 Subject: [PATCH 02/36] Improve code readability --- .../statementProcessing/DocumentExecutor.java | 6 ++---- .../statementProcessing/RelationalExecutor.java | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java index f87abdc46c..8edc0009e0 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java @@ -59,7 +59,6 @@ StatementResult executeAndGetResult( PIStatement piStatement ) { StatementResult executeAndGetResult( PIStatement piStatement, int fetchSize ) { throwOnIllegalState( piStatement ); PolyImplementation implementation = piStatement.getImplementation(); - PIClient client = piStatement.getClient(); StatementResult.Builder resultBuilder = StatementResult.newBuilder(); if ( implementation.isDDL() ) { resultBuilder.setScalar( 1 ); @@ -70,7 +69,7 @@ StatementResult executeAndGetResult( PIStatement piStatement, int fetchSize ) { resultBuilder.setFrame( frame ); if ( frame.getIsLast() ) { //TODO TH: special handling for result set updates. Do we need to wait with committing until all changes have been done? - client.commitCurrentTransactionIfAuto(); + piStatement.getClient().commitCurrentTransactionIfAuto(); } return resultBuilder.build(); } @@ -80,14 +79,13 @@ StatementResult executeAndGetResult( PIStatement piStatement, int fetchSize ) { Frame fetch( PIStatement piStatement, int fetchSize ) { throwOnIllegalState( piStatement ); StopWatch executionStopWatch = piStatement.getExecutionStopWatch(); - PolyImplementation implementation = piStatement.getImplementation(); ResultIterator iterator = piStatement.getIterator(); startOrResumeStopwatch( executionStopWatch ); List data = iterator.getNextBatch( fetchSize ).stream().map( p -> p.get( 0 ) ).toList(); boolean isLast = !iterator.hasMoreRows(); if ( isLast ) { executionStopWatch.stop(); - implementation.getExecutionTimeMonitor().setExecutionTime( executionStopWatch.getNanoTime() ); + piStatement.getImplementation().getExecutionTimeMonitor().setExecutionTime( executionStopWatch.getNanoTime() ); } return PrismUtils.buildDocumentFrame( isLast, data ); } diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/RelationalExecutor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/RelationalExecutor.java index f05ef70c6f..e427ec1ebb 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/RelationalExecutor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/RelationalExecutor.java @@ -50,13 +50,12 @@ StatementResult executeAndGetResult( PIStatement piStatement ) { throwOnIllegalState( piStatement ); Statement statement = piStatement.getStatement(); PolyImplementation implementation = piStatement.getImplementation(); - PIClient client = piStatement.getClient(); StatementResult.Builder resultBuilder = StatementResult.newBuilder(); if ( implementation.isDDL() || Kind.DML.contains( implementation.getKind() ) ) { try ( ResultIterator iterator = implementation.execute( statement, -1 ) ) { resultBuilder.setScalar( PolyImplementation.getRowsChanged( statement, iterator.getIterator(), MonitoringType.from( implementation.getKind() ) ) ); } - client.commitCurrentTransactionIfAuto(); + piStatement.getClient().commitCurrentTransactionIfAuto(); return resultBuilder.build(); } throw new PIServiceException( "Can't execute a non DDL or non DML statement using this method..", From cc9e6b686391e3bb4f7d87885124a71af1129b0f Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Thu, 16 May 2024 10:39:59 +0200 Subject: [PATCH 03/36] Add basic graph execution --- .../statementProcessing/DocumentExecutor.java | 1 - .../statementProcessing/Executor.java | 2 +- .../statementProcessing/GraphExecutor.java | 92 +++++++++++++++++++ .../db/prisminterface/utils/PrismUtils.java | 2 +- 4 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/GraphExecutor.java diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java index 8edc0009e0..fd20e3e9e8 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java @@ -21,7 +21,6 @@ import org.polypheny.db.PolyImplementation; import org.polypheny.db.ResultIterator; import org.polypheny.db.catalog.logistic.DataModel; -import org.polypheny.db.prisminterface.PIClient; import org.polypheny.db.prisminterface.PIServiceException; import org.polypheny.db.prisminterface.statements.PIStatement; import org.polypheny.db.prisminterface.utils.PrismUtils; diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/Executor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/Executor.java index 0f691df7e8..71d021308f 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/Executor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/Executor.java @@ -38,7 +38,7 @@ protected void startOrResumeStopwatch( StopWatch stopWatch ) { } - protected void throwOnIllegalState( PIStatement piStatement ) { + protected void throwOnIllegalState( PIStatement piStatement ) throws PIServiceException { DataModel statementDataModel = piStatement.getLanguage().dataModel(); if ( statementDataModel != getDataModel() ) { diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/GraphExecutor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/GraphExecutor.java new file mode 100644 index 0000000000..875597d171 --- /dev/null +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/GraphExecutor.java @@ -0,0 +1,92 @@ +/* + * Copyright 2019-2024 The Polypheny Project + * + * 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 org.polypheny.db.prisminterface.statementProcessing; + +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.lang3.time.StopWatch; +import org.polypheny.db.PolyImplementation; +import org.polypheny.db.ResultIterator; +import org.polypheny.db.catalog.logistic.DataModel; +import org.polypheny.db.prisminterface.PIServiceException; +import org.polypheny.db.prisminterface.statements.PIStatement; +import org.polypheny.db.prisminterface.utils.PrismUtils; +import org.polypheny.db.type.entity.PolyValue; +import org.polypheny.prism.Frame; +import org.polypheny.prism.StatementResult; + +public class GraphExecutor extends Executor { + + private static final DataModel namespaceType = DataModel.GRAPH; + + + @Override + DataModel getDataModel() { + return namespaceType; + } + + + @Override + StatementResult executeAndGetResult( PIStatement piStatement ) { + throwOnIllegalState( piStatement ); + StatementResult.Builder resultBuilder = StatementResult.newBuilder(); + if ( piStatement.getImplementation().isDDL() ) { + resultBuilder.setScalar( 1 ); + return resultBuilder.build(); + } + throw new PIServiceException( "Can't execute a non DDL or non DML statement using this method..", + "I9003", + 9002 + ); + } + + + @Override + StatementResult executeAndGetResult( PIStatement piStatement, int fetchSize ) throws Exception { + throwOnIllegalState( piStatement ); + PolyImplementation implementation = piStatement.getImplementation(); + StatementResult.Builder resultBuilder = StatementResult.newBuilder(); + if ( implementation.isDDL() ) { + resultBuilder.setScalar( 1 ); + return resultBuilder.build(); + } + piStatement.setIterator( implementation.execute( piStatement.getStatement(), fetchSize ) ); + Frame frame = fetch( piStatement, fetchSize ); + resultBuilder.setFrame( frame ); + if ( frame.getIsLast() ) { + piStatement.getClient().commitCurrentTransactionIfAuto(); + } + return resultBuilder.build(); + } + + + @Override + Frame fetch( PIStatement piStatement, int fetchSize ) { + throwOnIllegalState( piStatement ); + StopWatch executionStopWatch = piStatement.getExecutionStopWatch(); + ResultIterator iterator = piStatement.getIterator(); + startOrResumeStopwatch( executionStopWatch ); + List> data = new ArrayList<>( iterator.getNextBatch( fetchSize ) ); + boolean isLast = !iterator.hasMoreRows(); + if ( isLast ) { + executionStopWatch.stop(); + piStatement.getImplementation().getExecutionTimeMonitor().setExecutionTime( executionStopWatch.getNanoTime() ); + } + return PrismUtils.buildGraphFrame( isLast, data ); + } + +} diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java index 0b27f6f57c..c17e271231 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java @@ -112,7 +112,7 @@ public static Frame buildDocumentFrame( boolean isLast, List data ) { } - public static Frame buildGraphFrame() { + public static Frame buildGraphFrame(boolean isLast, List> data) { throw new GenericRuntimeException( "Feature not implemented" ); } From d92e9bc30fe4a95c2b73d6c999516ba80399c4b3 Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Thu, 16 May 2024 16:26:34 +0200 Subject: [PATCH 04/36] Add relational graph results --- .../PIClientInfoProperties.java | 1 + .../metaRetrieval/GraphMetaRetriever.java | 71 +++++++++++++++++++ .../RelationalMetaRetriever.java | 60 ++++++++-------- .../statementProcessing/GraphExecutor.java | 7 ++ .../RelationalExecutor.java | 2 +- .../StatementProcessor.java | 2 +- .../db/prisminterface/utils/PrismUtils.java | 6 ++ 7 files changed, 117 insertions(+), 32 deletions(-) create mode 100644 plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/GraphMetaRetriever.java rename plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/{relational => metaRetrieval}/RelationalMetaRetriever.java (92%) diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIClientInfoProperties.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIClientInfoProperties.java index caccd5b21a..d6593e9f93 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIClientInfoProperties.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIClientInfoProperties.java @@ -62,3 +62,4 @@ record ClientInfoPropertiesDefault( String key, String default_value, int maxLen } } + diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/GraphMetaRetriever.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/GraphMetaRetriever.java new file mode 100644 index 0000000000..f52dd9aff8 --- /dev/null +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/GraphMetaRetriever.java @@ -0,0 +1,71 @@ +/* + * Copyright 2019-2024 The Polypheny Project + * + * 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 org.polypheny.db.prisminterface.metaRetrieval; + +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; +import org.polypheny.db.PolyImplementation; +import org.polypheny.db.algebra.type.AlgDataType; +import org.polypheny.db.algebra.type.AlgDataTypeField; +import org.polypheny.db.prisminterface.utils.PrismUtils; +import org.polypheny.db.processing.QueryProcessorHelpers; +import org.polypheny.db.type.PolyType; +import org.polypheny.prism.ColumnMeta; +import org.polypheny.prism.TypeMeta; + +public class GraphMetaRetriever { + + public static boolean retrievedResultIsRelational( PolyImplementation polyImplementation ) { + PolyType polyType = polyImplementation.tupleType.getFields().get( 0 ).getType().getPolyType(); + switch ( polyType ) { + case NODE, EDGE, PATH -> { + return false; + } + default -> { + return true; + } + } + } + + + public static List retrieveColumnMetas( PolyImplementation polyImplementation ) { + List columns = polyImplementation.tupleType.getFields(); + AtomicInteger columnIndexGenerator = new AtomicInteger(); + return columns.stream().map( c -> retieveColumnMeta( c, columnIndexGenerator ) ).collect( Collectors.toList() ); + + } + + + private static ColumnMeta retieveColumnMeta( AlgDataTypeField field, AtomicInteger columnIndexGenerator ) { + AlgDataType type = field.getType(); + TypeMeta typeMeta = TypeMeta.newBuilder() + .setProtoValueType( PrismUtils.getProtoFromPolyType( type.getPolyType() ) ) + .build(); + return ColumnMeta.newBuilder() + .setColumnIndex( columnIndexGenerator.getAndIncrement() ) + .setColumnLabel( field.getName() ) + .setColumnName( field.getName() ) + .setTypeMeta( typeMeta ) + .setIsNullable( type.isNullable() ) + .setLength( type.getPrecision() ) + .setPrecision( QueryProcessorHelpers.getPrecision( type ) ) // <- same as type.getPrecision() but returns 0 if not applicable + .setScale( type.getScale() ) + .build(); + } + +} diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/relational/RelationalMetaRetriever.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/RelationalMetaRetriever.java similarity index 92% rename from plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/relational/RelationalMetaRetriever.java rename to plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/RelationalMetaRetriever.java index f1ebf9c7bf..e8fb65ffaf 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/relational/RelationalMetaRetriever.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/RelationalMetaRetriever.java @@ -14,12 +14,13 @@ * limitations under the License. */ -package org.polypheny.db.prisminterface.relational; +package org.polypheny.db.prisminterface.metaRetrieval; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; import org.apache.calcite.linq4j.Ord; import org.polypheny.db.PolyImplementation; import org.polypheny.db.adapter.java.JavaTypeFactory; @@ -27,6 +28,7 @@ import org.polypheny.db.algebra.type.AlgDataType; import org.polypheny.db.algebra.type.AlgDataTypeField; import org.polypheny.db.plan.AlgOptUtil; +import org.polypheny.db.prisminterface.utils.PrismUtils; import org.polypheny.db.processing.QueryProcessorHelpers; import org.polypheny.db.type.PolyType; import org.polypheny.prism.ArrayMeta; @@ -44,25 +46,6 @@ public class RelationalMetaRetriever { private static final int ORIGIN_SCHEMA_INDEX = 1; - public static List retrieveParameterMetas( AlgDataType parameterRowType ) { - return parameterRowType.getFields().stream() - .map( p -> retrieveParameterMeta( p, null ) ) - .toList(); - } - - - private static ParameterMeta retrieveParameterMeta( AlgDataTypeField algDataTypeField, String parameterName ) { - AlgDataType algDataType = algDataTypeField.getType(); - ParameterMeta.Builder metaBuilder = ParameterMeta.newBuilder(); - metaBuilder.setName( algDataTypeField.getName() ); - metaBuilder.setTypeName( algDataType.getPolyType().getTypeName() ); - metaBuilder.setPrecision( QueryProcessorHelpers.getPrecision( algDataType ) ); - metaBuilder.setScale( QueryProcessorHelpers.getScale( algDataType ) ); - Optional.ofNullable( parameterName ).ifPresent( p -> metaBuilder.setParameterName( parameterName ) ); - return metaBuilder.build(); - } - - public static List retrieveColumnMetas( PolyImplementation polyImplementation ) { AlgDataType algDataType = retrieveAlgDataType( polyImplementation ); AlgDataType whatever = QueryProcessorHelpers.makeStruct( polyImplementation.getStatement().getTransaction().getTypeFactory(), algDataType ); @@ -78,8 +61,22 @@ public static List retrieveColumnMetas( PolyImplementation polyImple } - private static ProtoPolyType getFromPolyType( PolyType polyType ) { - return ProtoPolyType.valueOf( polyType.getName() ); + public static List retrieveParameterMetas( AlgDataType parameterRowType ) { + return parameterRowType.getFields().stream() + .map( p -> retrieveParameterMeta( p, null ) ) + .collect( Collectors.toList() ); + } + + + private static ParameterMeta retrieveParameterMeta( AlgDataTypeField algDataTypeField, String parameterName ) { + AlgDataType algDataType = algDataTypeField.getType(); + ParameterMeta.Builder metaBuilder = ParameterMeta.newBuilder(); + metaBuilder.setName( algDataTypeField.getName() ); + metaBuilder.setTypeName( algDataType.getPolyType().getTypeName() ); + metaBuilder.setPrecision( QueryProcessorHelpers.getPrecision( algDataType ) ); + metaBuilder.setScale( QueryProcessorHelpers.getScale( algDataType ) ); + Optional.ofNullable( parameterName ).ifPresent( p -> metaBuilder.setParameterName( parameterName ) ); + return metaBuilder.build(); } @@ -149,14 +146,14 @@ private static TypeMeta retrieveTypeMeta( AlgDataType algDataType ) { .getFields() .stream() .map( f -> retrieveFieldMeta( f.getIndex(), f.getName(), f.getType() ) ) - .toList(); + .collect( Collectors.toList() ); return TypeMeta.newBuilder() .setStructMeta( StructMeta.newBuilder().addAllFieldMetas( fieldMetas ).build() ) //.setProtoValueType( ProtoValueType.PROTO_VALUE_TYPE_STRUCTURED ) //TODO TH: handle structured type meta in a useful way .build(); } - ProtoPolyType type = getFromPolyType( polyType ); + ProtoPolyType type = PrismUtils.getProtoFromPolyType( polyType ); return TypeMeta.newBuilder() .setProtoValueType( type ) .build(); @@ -165,15 +162,18 @@ private static TypeMeta retrieveTypeMeta( AlgDataType algDataType ) { private static AlgDataType retrieveAlgDataType( PolyImplementation polyImplementation ) { - return switch ( polyImplementation.getKind() ) { - case INSERT, DELETE, UPDATE, EXPLAIN -> { + switch ( polyImplementation.getKind() ) { + case INSERT: + case DELETE: + case UPDATE: + case EXPLAIN: // FIXME: getValidatedNodeType is wrong for DML Kind kind = polyImplementation.getKind(); JavaTypeFactory typeFactory = polyImplementation.getStatement().getTransaction().getTypeFactory(); - yield AlgOptUtil.createDmlRowType( kind, typeFactory ); - } - default -> polyImplementation.tupleType; - }; + return AlgOptUtil.createDmlRowType( kind, typeFactory ); + default: + return polyImplementation.tupleType; + } } } diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/GraphExecutor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/GraphExecutor.java index 875597d171..8eb4fc5503 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/GraphExecutor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/GraphExecutor.java @@ -23,9 +23,12 @@ import org.polypheny.db.ResultIterator; import org.polypheny.db.catalog.logistic.DataModel; import org.polypheny.db.prisminterface.PIServiceException; +import org.polypheny.db.prisminterface.metaRetrieval.GraphMetaRetriever; +import org.polypheny.db.prisminterface.metaRetrieval.RelationalMetaRetriever; import org.polypheny.db.prisminterface.statements.PIStatement; import org.polypheny.db.prisminterface.utils.PrismUtils; import org.polypheny.db.type.entity.PolyValue; +import org.polypheny.prism.ColumnMeta; import org.polypheny.prism.Frame; import org.polypheny.prism.StatementResult; @@ -86,6 +89,10 @@ Frame fetch( PIStatement piStatement, int fetchSize ) { executionStopWatch.stop(); piStatement.getImplementation().getExecutionTimeMonitor().setExecutionTime( executionStopWatch.getNanoTime() ); } + if (GraphMetaRetriever.retrievedResultIsRelational(piStatement.getImplementation())) { + List columnMetas = GraphMetaRetriever.retrieveColumnMetas( piStatement.getImplementation() ); + return PrismUtils.buildRelationalFrame( isLast, data, columnMetas ); + } return PrismUtils.buildGraphFrame( isLast, data ); } diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/RelationalExecutor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/RelationalExecutor.java index e427ec1ebb..229d4a11aa 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/RelationalExecutor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/RelationalExecutor.java @@ -25,7 +25,7 @@ import org.polypheny.db.monitoring.events.MonitoringType; import org.polypheny.db.prisminterface.PIClient; import org.polypheny.db.prisminterface.PIServiceException; -import org.polypheny.db.prisminterface.relational.RelationalMetaRetriever; +import org.polypheny.db.prisminterface.metaRetrieval.RelationalMetaRetriever; import org.polypheny.db.prisminterface.statements.PIStatement; import org.polypheny.db.prisminterface.utils.PrismUtils; import org.polypheny.db.transaction.Statement; diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java index e088a8feb7..d2be8cc876 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java @@ -27,7 +27,7 @@ import org.polypheny.db.languages.QueryLanguage; import org.polypheny.db.nodes.Node; import org.polypheny.db.prisminterface.PIServiceException; -import org.polypheny.db.prisminterface.relational.RelationalMetaRetriever; +import org.polypheny.db.prisminterface.metaRetrieval.RelationalMetaRetriever; import org.polypheny.db.prisminterface.statements.PIPreparedStatement; import org.polypheny.db.prisminterface.statements.PIStatement; import org.polypheny.db.processing.ImplementationContext; diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java index c17e271231..cde81f0bd1 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java @@ -20,12 +20,14 @@ import org.polypheny.db.catalog.exceptions.GenericRuntimeException; import org.polypheny.db.prisminterface.statements.PIPreparedStatement; import org.polypheny.db.prisminterface.statements.PIStatement; +import org.polypheny.db.type.PolyType; import org.polypheny.db.type.entity.PolyValue; import org.polypheny.prism.ColumnMeta; import org.polypheny.prism.DocumentFrame; import org.polypheny.prism.Frame; import org.polypheny.prism.PreparedStatementSignature; import org.polypheny.prism.ProtoDocument; +import org.polypheny.prism.ProtoPolyType; import org.polypheny.prism.RelationalFrame; import org.polypheny.prism.Row; import org.polypheny.prism.StatementBatchResponse; @@ -116,4 +118,8 @@ public static Frame buildGraphFrame(boolean isLast, List> data) throw new GenericRuntimeException( "Feature not implemented" ); } + public static ProtoPolyType getProtoFromPolyType( PolyType polyType ) { + return ProtoPolyType.valueOf( polyType.getName() ); + } + } From 585dbd6832cb62854711e57c659e446d2629aece Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Thu, 16 May 2024 21:28:03 +0200 Subject: [PATCH 05/36] Add graph results --- plugins/prism-interface/build.gradle | 3 +- .../utils/PolyValueSerializer.java | 77 +++++++++++++++---- .../db/prisminterface/utils/PrismUtils.java | 40 +++++++++- 3 files changed, 100 insertions(+), 20 deletions(-) diff --git a/plugins/prism-interface/build.gradle b/plugins/prism-interface/build.gradle index 244efa1278..7d42efed1c 100644 --- a/plugins/prism-interface/build.gradle +++ b/plugins/prism-interface/build.gradle @@ -16,6 +16,7 @@ configurations { repositories { mavenCentral() + mavenLocal() } dependencies { @@ -25,7 +26,7 @@ dependencies { compileOnly project(path: ':plugins:mql-language') // Prism API files (protobuf files), needs to be implementation due to the prism-api-version.properties - implementation group: 'org.polypheny', name: 'prism', version: prism_api_version + implementation group: 'org.polypheny', name: 'prism', version: 5.1 // Protobuf implementation group: 'com.google.protobuf', name: 'protobuf-java', version: protobuf_version diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java index f827b9d512..a349232a1c 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java @@ -28,13 +28,16 @@ import org.polypheny.db.type.entity.PolyValue; import org.polypheny.db.type.entity.category.PolyBlob; import org.polypheny.db.type.entity.document.PolyDocument; +import org.polypheny.db.type.entity.graph.PolyEdge; +import org.polypheny.db.type.entity.graph.PolyEdge.EdgeDirection; +import org.polypheny.db.type.entity.graph.PolyNode; +import org.polypheny.db.type.entity.graph.PolyPath; import org.polypheny.db.type.entity.numerical.PolyBigDecimal; import org.polypheny.db.type.entity.numerical.PolyDouble; import org.polypheny.db.type.entity.numerical.PolyFloat; import org.polypheny.db.type.entity.numerical.PolyInteger; import org.polypheny.db.type.entity.numerical.PolyLong; import org.polypheny.db.type.entity.relational.PolyMap; -import org.polypheny.db.type.entity.spatial.PolyGeometry; import org.polypheny.db.type.entity.temporal.PolyDate; import org.polypheny.db.type.entity.temporal.PolyTime; import org.polypheny.db.type.entity.temporal.PolyTimestamp; @@ -44,13 +47,17 @@ import org.polypheny.prism.ProtoDate; import org.polypheny.prism.ProtoDocument; import org.polypheny.prism.ProtoDouble; +import org.polypheny.prism.ProtoEdge; +import org.polypheny.prism.ProtoEdge.Direction; import org.polypheny.prism.ProtoEntry; import org.polypheny.prism.ProtoFloat; import org.polypheny.prism.ProtoInteger; import org.polypheny.prism.ProtoInterval; import org.polypheny.prism.ProtoList; import org.polypheny.prism.ProtoLong; +import org.polypheny.prism.ProtoNode; import org.polypheny.prism.ProtoNull; +import org.polypheny.prism.ProtoPath; import org.polypheny.prism.ProtoString; import org.polypheny.prism.ProtoTime; import org.polypheny.prism.ProtoTimestamp; @@ -97,7 +104,6 @@ public static ProtoValue serialize( PolyValue polyValue ) { case NULL -> serializeAsProtoNull(); case ARRAY -> serializeAsProtoList( polyValue.asList() ); case DOCUMENT -> serializeAsProtoDocument( polyValue.asDocument() ); - case GEOMETRY -> serializeGeometry( polyValue.asGeometry() ); case IMAGE, VIDEO, AUDIO, FILE -> serializeAsProtoFile( polyValue.asBlob() ); // used case MAP, GRAPH, NODE, EDGE, PATH, DISTINCT, STRUCTURED, ROW, OTHER, CURSOR, COLUMN_LIST, DYNAMIC_STAR, SYMBOL, JSON, MULTISET, USER_DEFINED_TYPE, ANY -> throw new NotImplementedException( "Serialization of " + polyValue.getType() + " to proto not implemented" ); default -> throw new NotImplementedException(); @@ -105,19 +111,6 @@ public static ProtoValue serialize( PolyValue polyValue ) { } - private static ProtoValue serializeGeometry( PolyGeometry geometry ) { - ProtoString asString = ProtoString.newBuilder().setString( geometry.toString() ).build(); // todo add own value, taken from @danylokravchenko - return ProtoValue.newBuilder().setString( asString ).build(); - } - - - public static ProtoDocument buildProtoDocument( PolyDocument polyDocument ) { - return ProtoDocument.newBuilder() - .addAllEntries( serializeToProtoEntryList( polyDocument.asMap() ) ) - .build(); - } - - private static ProtoValue serializeAsProtoDocument( PolyDocument polyDocument ) { return ProtoValue.newBuilder() .setDocument( buildProtoDocument( polyDocument ) ) @@ -287,7 +280,7 @@ public static ProtoValue serializeAsProtoTimestamp( PolyTimestamp polyTimestamp } - private static ProtoValue serializeAsProtoNull() { + public static ProtoValue serializeAsProtoNull() { return ProtoValue.newBuilder() .setNull( ProtoNull.newBuilder().build() ) .build(); @@ -307,4 +300,56 @@ public static ProtoValue serializeAsProtoBigDecimal( PolyBigDecimal polyBigDecim .build(); } + + public static ProtoDocument buildProtoDocument( PolyDocument polyDocument ) { + return ProtoDocument.newBuilder() + .addAllEntries( serializeToProtoEntryList( polyDocument.asMap() ) ) + .build(); + } + + + public static ProtoNode buildProtoNode( PolyNode polyNode ) { + return ProtoNode.newBuilder() + .setId( polyNode.getId().getValue() ) + .setName( polyNode.getVariableName().getValue() ) + .addAllLabels( polyNode.getLabels().stream().map( l -> ((PolyString) l).getValue() ).collect( Collectors.toList() ) ) + .addAllProperties( serializeToProtoEntryList( polyNode.properties.asMap() ) ) + .build(); + } + + + public static ProtoEdge buildProtoEdge( PolyEdge polyEdge ) { + return ProtoEdge.newBuilder() + .setId( polyEdge.getId().getValue() ) + .setName( polyEdge.getVariableName().getValue() ) + .addAllLabels( polyEdge.getLabels().stream().map( l -> ((PolyString) l).getValue() ).collect( Collectors.toList() ) ) + .addAllProperties( serializeToProtoEntryList( polyEdge.properties.asMap() ) ) + .setSource( polyEdge.getSource().getValue() ) + .setTarget( polyEdge.getTarget().getValue() ) + .setDirection( buildProtoEdgeDirection( polyEdge.getDirection() ) ) + .build(); + } + + + private static Direction buildProtoEdgeDirection( EdgeDirection direction ) { + switch ( direction ) { + case LEFT_TO_RIGHT -> { + return Direction.LEFT_TO_RIGHT; + } + case RIGHT_TO_LEFT -> { + return Direction.RIGHT_TO_LEFT; + } + case NONE -> { + return Direction.NONE; + } + } + return Direction.UNSPECIFIED; + } + + + public static ProtoPath buildProtoPath( PolyPath polyPath ) { + throw new NotImplementedException(); + } + + } diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java index cde81f0bd1..0fc8e6ed97 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java @@ -17,16 +17,22 @@ package org.polypheny.db.prisminterface.utils; import java.util.List; -import org.polypheny.db.catalog.exceptions.GenericRuntimeException; import org.polypheny.db.prisminterface.statements.PIPreparedStatement; import org.polypheny.db.prisminterface.statements.PIStatement; import org.polypheny.db.type.PolyType; import org.polypheny.db.type.entity.PolyValue; +import org.polypheny.db.type.entity.graph.PolyEdge; +import org.polypheny.db.type.entity.graph.PolyNode; +import org.polypheny.db.type.entity.graph.PolyPath; import org.polypheny.prism.ColumnMeta; import org.polypheny.prism.DocumentFrame; import org.polypheny.prism.Frame; +import org.polypheny.prism.GraphFrame; import org.polypheny.prism.PreparedStatementSignature; import org.polypheny.prism.ProtoDocument; +import org.polypheny.prism.ProtoEdge; +import org.polypheny.prism.ProtoNode; +import org.polypheny.prism.ProtoPath; import org.polypheny.prism.ProtoPolyType; import org.polypheny.prism.RelationalFrame; import org.polypheny.prism.Row; @@ -87,6 +93,21 @@ public static List serializeToRows( List> rows ) { } + private static List serializeToNodes( List> data ) { + return data.stream().map( e -> PolyValueSerializer.buildProtoNode( (PolyNode) (e.get( 0 )) ) ).collect( Collectors.toList() ); + } + + + private static List serializeToEdges( List> data ) { + return data.stream().map( e -> PolyValueSerializer.buildProtoEdge( (PolyEdge) (e.get( 0 )) ) ).collect( Collectors.toList() ); + } + + + private static List serilaizeToPaths( List> data ) { + return data.stream().map( e -> PolyValueSerializer.buildProtoPath( (PolyPath) (e.get( 0 )) ) ).collect( Collectors.toList() ); + } + + public static Frame buildRelationalFrame( boolean isLast, List> rows, List metas ) { RelationalFrame relationalFrame = RelationalFrame.newBuilder() .addAllColumnMeta( metas ) @@ -114,10 +135,23 @@ public static Frame buildDocumentFrame( boolean isLast, List data ) { } - public static Frame buildGraphFrame(boolean isLast, List> data) { - throw new GenericRuntimeException( "Feature not implemented" ); + public static Frame buildGraphFrame( boolean isLast, List> data ) { + GraphFrame.Builder graphFrameBuilder = GraphFrame.newBuilder(); + PolyType elementType = data.get( 0 ).get( 0 ).getType(); + switch ( elementType ) { + case NODE -> graphFrameBuilder.addAllNodes( serializeToNodes( data ) ); + case EDGE -> graphFrameBuilder.addAllEdges( serializeToEdges( data ) ); + case PATH -> graphFrameBuilder.addAllPaths( serilaizeToPaths( data ) ); + default -> throw new RuntimeException( "Should never be thrown!" ); + } + + return Frame.newBuilder() + .setIsLast( isLast ) + .setGraphFrame( graphFrameBuilder.build() ) + .build(); } + public static ProtoPolyType getProtoFromPolyType( PolyType polyType ) { return ProtoPolyType.valueOf( polyType.getName() ); } From eb63649927170e5de83825b2f0a09f334b63f2d7 Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Fri, 17 May 2024 12:33:51 +0200 Subject: [PATCH 06/36] Add graph serialization tests --- .../db/prisminterface/utils/PrismUtils.java | 16 +- .../db/prisminterface/PrismUtilsTest.java | 151 ++++++++++++++++++ 2 files changed, 160 insertions(+), 7 deletions(-) create mode 100644 plugins/prism-interface/src/test/java/org/polypheny/db/prisminterface/PrismUtilsTest.java diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java index 0fc8e6ed97..239e8665f7 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java @@ -81,7 +81,7 @@ public static PreparedStatementSignature createPreparedStatementSignature( PIPre } - public static Row serializeToRow( List row ) { + private static Row serializeToRow( List row ) { return Row.newBuilder() .addAllValues( PolyValueSerializer.serializeList( row ) ) .build(); @@ -137,12 +137,14 @@ public static Frame buildDocumentFrame( boolean isLast, List data ) { public static Frame buildGraphFrame( boolean isLast, List> data ) { GraphFrame.Builder graphFrameBuilder = GraphFrame.newBuilder(); - PolyType elementType = data.get( 0 ).get( 0 ).getType(); - switch ( elementType ) { - case NODE -> graphFrameBuilder.addAllNodes( serializeToNodes( data ) ); - case EDGE -> graphFrameBuilder.addAllEdges( serializeToEdges( data ) ); - case PATH -> graphFrameBuilder.addAllPaths( serilaizeToPaths( data ) ); - default -> throw new RuntimeException( "Should never be thrown!" ); + if ( !data.isEmpty() ) { + PolyType elementType = data.get( 0 ).get( 0 ).getType(); + switch ( elementType ) { + case NODE -> graphFrameBuilder.addAllNodes( serializeToNodes( data ) ); + case EDGE -> graphFrameBuilder.addAllEdges( serializeToEdges( data ) ); + case PATH -> graphFrameBuilder.addAllPaths( serilaizeToPaths( data ) ); + default -> throw new RuntimeException( "Should never be thrown!" ); + } } return Frame.newBuilder() diff --git a/plugins/prism-interface/src/test/java/org/polypheny/db/prisminterface/PrismUtilsTest.java b/plugins/prism-interface/src/test/java/org/polypheny/db/prisminterface/PrismUtilsTest.java new file mode 100644 index 0000000000..8cf3d12f02 --- /dev/null +++ b/plugins/prism-interface/src/test/java/org/polypheny/db/prisminterface/PrismUtilsTest.java @@ -0,0 +1,151 @@ +/* + * Copyright 2019-2024 The Polypheny Project + * + * 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 org.polypheny.db.prisminterface; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.HashMap; +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.polypheny.db.TestHelper; +import org.polypheny.db.prisminterface.utils.PrismUtils; +import org.polypheny.db.type.entity.PolyBoolean; +import org.polypheny.db.type.entity.PolyString; +import org.polypheny.db.type.entity.PolyValue; +import org.polypheny.db.type.entity.graph.PolyDictionary; +import org.polypheny.db.type.entity.graph.PolyEdge; +import org.polypheny.db.type.entity.graph.PolyEdge.EdgeDirection; +import org.polypheny.db.type.entity.graph.PolyNode; +import org.polypheny.db.type.entity.numerical.PolyInteger; +import org.polypheny.prism.Frame; +import org.polypheny.prism.ProtoValue; +import org.polypheny.prism.ProtoValue.ValueCase; +import org.polypheny.prism.Row; + +public class PrismUtilsTest { + + @BeforeAll + public static void init() { + // needed to launch polypheny + TestHelper.getInstance(); + } + + + @Test + public void serializeToRowsSimpleTest() { + List row1 = List.of( new PolyString( "test" ), new PolyInteger( 42 ), new PolyBoolean( false ) ); + List row2 = List.of( new PolyString( "example" ), new PolyInteger( 24 ), new PolyBoolean( true ) ); + + List> inputRows = List.of( row1, row2 ); + List prismRows = PrismUtils.serializeToRows( inputRows ); + + Row prismRow1 = prismRows.get( 0 ); + List outputRow1 = prismRow1.getValuesList(); + assertEquals( ValueCase.STRING, outputRow1.get( 0 ).getValueCase() ); + assertEquals( ValueCase.INTEGER, outputRow1.get( 1 ).getValueCase() ); + assertEquals( ValueCase.BOOLEAN, outputRow1.get( 2 ).getValueCase() ); + assertEquals( "test", outputRow1.get( 0 ).getString().getString() ); + assertEquals( 42, outputRow1.get( 1 ).getInteger().getInteger() ); + assertFalse( outputRow1.get( 2 ).getBoolean().getBoolean() ); + + Row prismRow2 = prismRows.get( 1 ); + List outputRow2 = prismRow2.getValuesList(); + assertEquals( ValueCase.STRING, outputRow2.get( 0 ).getValueCase() ); + assertEquals( ValueCase.INTEGER, outputRow2.get( 1 ).getValueCase() ); + assertEquals( ValueCase.BOOLEAN, outputRow2.get( 2 ).getValueCase() ); + assertEquals( "example", outputRow2.get( 0 ).getString().getString() ); + assertEquals( 24, outputRow2.get( 1 ).getInteger().getInteger() ); + assertTrue( outputRow2.get( 2 ).getBoolean().getBoolean() ); + } + + + @Test + public void serializeToRowsEmptyRowTest() { + List> inputRows = List.of(); + List prismRows = PrismUtils.serializeToRows( inputRows ); + assertTrue( prismRows.isEmpty() ); + } + + + @Test + public void buildGraphFrameWithNodesTest() { + HashMap map1 = new HashMap<>(); + map1.put( new PolyString( "key1" ), new PolyString( "value1" ) ); + PolyDictionary properties1 = PolyDictionary.ofDict( map1 ); + + HashMap map2 = new HashMap<>(); + map2.put( new PolyString( "key2" ), new PolyString( "value2" ) ); + PolyDictionary properties2 = PolyDictionary.ofDict( map2 ); + + PolyNode node1 = new PolyNode( properties1, List.of( new PolyString( "label1" ) ), new PolyString( "node1" ) ); + PolyNode node2 = new PolyNode( properties2, List.of( new PolyString( "label2" ) ), new PolyString( "node2" ) ); + + List> data = List.of( + List.of( node1 ), + List.of( node2 ) + ); + + Frame result = PrismUtils.buildGraphFrame( true, data ); + + assertTrue( result.getIsLast() ); + assertEquals( 2, result.getGraphFrame().getNodesCount() ); + assertEquals( "node1", result.getGraphFrame().getNodes( 0 ).getName() ); + assertEquals( "node2", result.getGraphFrame().getNodes( 1 ).getName() ); + } + + + @Test + public void buildGraphFrameWithEmptyNodesTest() { + List> data = List.of(); + + Frame result = PrismUtils.buildGraphFrame( true, data ); + + assertTrue( result.getIsLast() ); + assertEquals( 0, result.getGraphFrame().getNodesCount() ); + } + + + @Test + public void buildGraphFrameWithEdgesTest() { + HashMap map1 = new HashMap<>(); + map1.put( new PolyString( "key1" ), new PolyString( "value1" ) ); + PolyDictionary properties1 = PolyDictionary.ofDict( map1 ); + + HashMap map2 = new HashMap<>(); + map2.put( new PolyString( "key2" ), new PolyString( "value2" ) ); + PolyDictionary properties2 = PolyDictionary.ofDict( map2 ); + + PolyEdge node1 = new PolyEdge( properties1, List.of( new PolyString( "label1" ) ), new PolyString( "node4" ), new PolyString( "node5" ), EdgeDirection.NONE, new PolyString( "edge1" ) ); + PolyEdge node2 = new PolyEdge( properties2, List.of( new PolyString( "label2" ) ), new PolyString( "node4" ), new PolyString( "node5" ), EdgeDirection.NONE, new PolyString( "edge2" ) ); + + List> data = List.of( + List.of( node1 ), + List.of( node2 ) + ); + + Frame result = PrismUtils.buildGraphFrame( false, data ); + + assertFalse( result.getIsLast() ); + assertEquals( 2, result.getGraphFrame().getEdgesCount() ); + assertEquals( "edge1", result.getGraphFrame().getEdges( 0 ).getName() ); + assertEquals( "edge2", result.getGraphFrame().getEdges( 1 ).getName() ); + } + +} From e536fed681784f486df6be0fcca38f89ead35d17 Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Fri, 17 May 2024 13:01:17 +0200 Subject: [PATCH 07/36] Use mavenLocal for driver --- dbms/build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dbms/build.gradle b/dbms/build.gradle index b5b067847d..4e7f67806d 100644 --- a/dbms/build.gradle +++ b/dbms/build.gradle @@ -6,6 +6,7 @@ buildscript { url "https://plugins.gradle.org/m2/" } google() + mavenLocal() } dependencies { classpath group: "app.cash.licensee", name: "licensee-gradle-plugin", version: licensee_version @@ -54,7 +55,7 @@ dependencies { // Workaround so org.polypheny.db.docker gets the right protobuf during testing testImplementation group: "com.google.protobuf", name: "protobuf-java", version: protobuf_version // BSD 3-clause - + testImplementation(group: "org.polypheny", name: "polypheny-jdbc-driver", version: polypheny_jdbc_driver_version) { exclude(group: "com.fasterxml.jackson.core") exclude(group: "com.fasterxml.jackson.databind") From c44d2348f91656a1ef7cbc161b69f6d2faf21508 Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Fri, 17 May 2024 13:01:45 +0200 Subject: [PATCH 08/36] Add testcase for relational multimodel operations --- .../polypheny/db/prisminterface/SqlTest.java | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 dbms/src/test/java/org/polypheny/db/prisminterface/SqlTest.java diff --git a/dbms/src/test/java/org/polypheny/db/prisminterface/SqlTest.java b/dbms/src/test/java/org/polypheny/db/prisminterface/SqlTest.java new file mode 100644 index 0000000000..de270ff530 --- /dev/null +++ b/dbms/src/test/java/org/polypheny/db/prisminterface/SqlTest.java @@ -0,0 +1,82 @@ +/* + * Copyright 2019-2024 The Polypheny Project + * + * 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 org.polypheny.db.prisminterface; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Iterator; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.polypheny.db.TestHelper.JdbcConnection; +import org.polypheny.jdbc.PolyConnection; +import org.polypheny.jdbc.multimodel.PolyRow; +import org.polypheny.jdbc.multimodel.PolyStatement; +import org.polypheny.jdbc.multimodel.RelationalResult; +import org.polypheny.jdbc.multimodel.Result; + +public class SqlTest { + + @BeforeAll + public static void setup() throws SQLException { + try ( Connection connection = new JdbcConnection( true ).getConnection() ) { + if ( !connection.isWrapperFor( PolyConnection.class ) ) { + fail( "Driver must support unwrapping to PolyConnection" ); + } + PolyStatement polyStatement = connection.unwrap( PolyConnection.class ).createPolyStatement(); + polyStatement.execute( "public", "sql", "DROP NAMESPACE IF EXISTS sqltest" ); + polyStatement.execute( "public", "sql", "CREATE RELATIONAL NAMESPACE sqltest" ); + polyStatement.execute( "sqltest", "sql", "CREATE TABLE sqltest.test_table (id INT PRIMARY KEY, name VARCHAR(50))" ); + polyStatement.execute( "sqltest", "sql", "INSERT INTO sqltest.test_table (id, name) VALUES (1, 'Alice')" ); + polyStatement.execute( "sqltest", "sql", "INSERT INTO sqltest.test_table (id, name) VALUES (2, 'Bob')" ); + } + } + + + @Test + public void sqlSelectTestTest() throws SQLException { + try ( Connection connection = new JdbcConnection( true ).getConnection() ) { + if ( !connection.isWrapperFor( PolyConnection.class ) ) { + fail( "Driver must support unwrapping to PolyConnection" ); + } + PolyStatement polyStatement = connection.unwrap( PolyConnection.class ).createPolyStatement(); + Result result = polyStatement.execute( "sqltest", "sql", "SELECT * FROM test_table" ); + Iterator rows = result.unwrap( RelationalResult.class ).iterator(); + assertTrue( rows.hasNext() ); + PolyRow row = rows.next(); + + assertEquals( 1, row.get( "id" ).asInt() ); + assertEquals( "Alice", row.get( "name" ).asString() ); + + assertEquals( 1, row.get( 0 ).asInt() ); + assertEquals( "Alice", row.get( 1 ).asString() ); + + assertTrue( rows.hasNext() ); + row = rows.next(); + + assertEquals( 2, row.get( "id" ).asInt() ); + assertEquals( "Bob", row.get( "name" ).asString() ); + + assertEquals( 2, row.get( 0 ).asInt() ); + assertEquals( "Bob", row.get( 1 ).asString() ); + } + } + +} From 28989ed4f787286daf82aea0914a158280cb2be0 Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Fri, 17 May 2024 13:23:57 +0200 Subject: [PATCH 09/36] Add testcase for multi-model relational metadata --- .../polypheny/db/prisminterface/SqlTest.java | 41 +++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/dbms/src/test/java/org/polypheny/db/prisminterface/SqlTest.java b/dbms/src/test/java/org/polypheny/db/prisminterface/SqlTest.java index de270ff530..7b31439e25 100644 --- a/dbms/src/test/java/org/polypheny/db/prisminterface/SqlTest.java +++ b/dbms/src/test/java/org/polypheny/db/prisminterface/SqlTest.java @@ -17,6 +17,7 @@ package org.polypheny.db.prisminterface; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -29,8 +30,9 @@ import org.polypheny.jdbc.PolyConnection; import org.polypheny.jdbc.multimodel.PolyRow; import org.polypheny.jdbc.multimodel.PolyStatement; +import org.polypheny.jdbc.multimodel.RelationalColumnMetadata; +import org.polypheny.jdbc.multimodel.RelationalMetadata; import org.polypheny.jdbc.multimodel.RelationalResult; -import org.polypheny.jdbc.multimodel.Result; public class SqlTest { @@ -51,13 +53,13 @@ public static void setup() throws SQLException { @Test - public void sqlSelectTestTest() throws SQLException { + public void sqlSelectTest() throws SQLException { try ( Connection connection = new JdbcConnection( true ).getConnection() ) { if ( !connection.isWrapperFor( PolyConnection.class ) ) { fail( "Driver must support unwrapping to PolyConnection" ); } PolyStatement polyStatement = connection.unwrap( PolyConnection.class ).createPolyStatement(); - Result result = polyStatement.execute( "sqltest", "sql", "SELECT * FROM test_table" ); + RelationalResult result = polyStatement.execute( "sqltest", "sql", "SELECT * FROM test_table" ).unwrap( RelationalResult.class ); Iterator rows = result.unwrap( RelationalResult.class ).iterator(); assertTrue( rows.hasNext() ); PolyRow row = rows.next(); @@ -79,4 +81,37 @@ public void sqlSelectTestTest() throws SQLException { } } + + @Test + public void sqlSelectMetadataTest() throws SQLException { + try ( Connection connection = new JdbcConnection( true ).getConnection() ) { + if ( !connection.isWrapperFor( PolyConnection.class ) ) { + fail( "Driver must support unwrapping to PolyConnection" ); + } + PolyStatement polyStatement = connection.unwrap( PolyConnection.class ).createPolyStatement(); + RelationalMetadata relationalMetadata = polyStatement.execute( "sqltest", "sql", "SELECT * FROM test_table" ).unwrap( RelationalResult.class ).getMetadata(); + assertEquals( 2, relationalMetadata.getColumnCount() ); + + RelationalColumnMetadata relationalColumnMetadata1 = relationalMetadata.getColumnMeta( 0 ); + assertEquals( 0, relationalColumnMetadata1.getColumnIndex() ); + assertFalse( relationalColumnMetadata1.isNullable() ); // false as this is the primary key + assertEquals( 10, relationalColumnMetadata1.getLength() ); + assertEquals( "id", relationalColumnMetadata1.getColumnLabel() ); + assertEquals( "id", relationalColumnMetadata1.getColumnName() ); + assertEquals( 10, relationalColumnMetadata1.getPrecision() ); + assertEquals( "INTEGER", relationalColumnMetadata1.getProtocolTypeName() ); + assertEquals( 0, relationalColumnMetadata1.getScale() ); + + RelationalColumnMetadata relationalColumnMetadata2 = relationalMetadata.getColumnMeta( 1 ); + assertEquals( 1, relationalColumnMetadata2.getColumnIndex() ); + assertTrue( relationalColumnMetadata2.isNullable() ); + assertEquals( 50, relationalColumnMetadata2.getLength() ); + assertEquals( "name", relationalColumnMetadata2.getColumnLabel() ); + assertEquals( "name", relationalColumnMetadata2.getColumnName() ); + assertEquals( 50, relationalColumnMetadata2.getPrecision() ); + assertEquals( "VARCHAR", relationalColumnMetadata2.getProtocolTypeName() ); + assertEquals( -2147483648, relationalColumnMetadata2.getScale() ); + } + } + } From e89ad2aaeaaac27450b14e3074d33176b2224db5 Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Fri, 17 May 2024 13:53:20 +0200 Subject: [PATCH 10/36] Add test for multimodel mql --- .../polypheny/db/prisminterface/MqlTest.java | 63 ++++++++++++------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/dbms/src/test/java/org/polypheny/db/prisminterface/MqlTest.java b/dbms/src/test/java/org/polypheny/db/prisminterface/MqlTest.java index 65e87560cc..4acebea4c9 100644 --- a/dbms/src/test/java/org/polypheny/db/prisminterface/MqlTest.java +++ b/dbms/src/test/java/org/polypheny/db/prisminterface/MqlTest.java @@ -18,52 +18,69 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import java.sql.Connection; import java.sql.SQLException; -import java.sql.Statement; +import java.util.Iterator; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.polypheny.db.TestHelper.JdbcConnection; import org.polypheny.jdbc.PolyConnection; -import org.polypheny.jdbc.PrismInterfaceServiceException; +import org.polypheny.jdbc.multimodel.DocumentResult; import org.polypheny.jdbc.multimodel.PolyStatement; -import org.polypheny.jdbc.multimodel.Result; -import org.polypheny.jdbc.multimodel.Result.ResultType; +import org.polypheny.jdbc.types.PolyDocument; public class MqlTest { - private static final String MQL_LANGUAGE_NAME = "mongo"; - private static final String TEST_QUERY = "db.students.find();"; - - - @Test - public void connectionUnwrapTest() throws SQLException { + @BeforeAll + public static void setup() throws SQLException { try ( Connection connection = new JdbcConnection( true ).getConnection() ) { if ( !connection.isWrapperFor( PolyConnection.class ) ) { - fail( "Driver must support unwrapping to PolyphenyConnection" ); + fail( "Driver must support unwrapping to PolyConnection" ); } + PolyStatement polyStatement = connection.unwrap( PolyConnection.class ).createPolyStatement(); + + assertThrows( PrismInterfaceServiceException.class, () -> { + // fails due to autogenerated query (would create students collection) + Result result = polyStatement.execute( "mqltest", MQL_LANGUAGE_NAME, TEST_QUERY ); + assertEquals( ResultType.DOCUMENT, result.getResultType() ); + } ); + + polyStatement.execute( "public", "sql", "DROP NAMESPACE IF EXISTS mongotest" ); + polyStatement.execute( "public", "sql", "CREATE DOCUMENT NAMESPACE mongotest" ); + polyStatement.execute( "mongotest", "mongo", "db.createCollection(test_collection)" ); + polyStatement.execute( "mongotest", "mongo", "db.test_collection.insert({ \"_id\": 1, \"name\": \"Alice\" })" ); + polyStatement.execute( "mongotest", "mongo", "db.test_collection.insert({ \"_id\": 2, \"name\": \"Bob\" })" ); } } @Test - public void simpleMqlTest() throws SQLException { + public void mongoSelectTest() throws SQLException { try ( Connection connection = new JdbcConnection( true ).getConnection() ) { - try ( Statement statement = connection.createStatement() ) { - statement.execute( "DROP NAMESPACE IF EXISTS mqltest" ); - statement.execute( "CREATE DOCUMENT NAMESPACE mqltest" ); - } if ( !connection.isWrapperFor( PolyConnection.class ) ) { - fail( "Driver must support unwrapping to PolyphenyConnection" ); + fail( "Driver must support unwrapping to PolyConnection" ); } PolyStatement polyStatement = connection.unwrap( PolyConnection.class ).createPolyStatement(); - assertThrows( PrismInterfaceServiceException.class, () -> { - // fails due to autogenerated query (would create students collection) - Result result = polyStatement.execute( "mqltest", MQL_LANGUAGE_NAME, TEST_QUERY ); - assertEquals( ResultType.DOCUMENT, result.getResultType() ); - } ); + DocumentResult result = polyStatement.execute( "mongotest", "mongo", "db.test_collection.find({})" ).unwrap( DocumentResult.class ); + Iterator documents = result.iterator(); + + assertTrue( documents.hasNext() ); + PolyDocument document = documents.next(); + + assertEquals( 1, document.get( "_id" ).asInt() ); + assertEquals( "Alice", document.get( "name" ).asString() ); + + assertTrue( documents.hasNext() ); + document = documents.next(); + + assertEquals( 2, document.get( "_id" ).asInt() ); + assertEquals( "Bob", document.get( "name" ).asString() ); + + assertFalse( documents.hasNext() ); } } From 893307352ee2b9d80322826c9475dfe9982d2809 Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Fri, 17 May 2024 13:53:31 +0200 Subject: [PATCH 11/36] Fix ddl result bug --- .../statementProcessing/DocumentExecutor.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java index fd20e3e9e8..09f612b7c9 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java @@ -20,10 +20,14 @@ import org.apache.commons.lang3.time.StopWatch; import org.polypheny.db.PolyImplementation; import org.polypheny.db.ResultIterator; +import org.polypheny.db.algebra.constant.Kind; import org.polypheny.db.catalog.logistic.DataModel; +import org.polypheny.db.monitoring.events.MonitoringType; +import org.polypheny.db.prisminterface.PIClient; import org.polypheny.db.prisminterface.PIServiceException; import org.polypheny.db.prisminterface.statements.PIStatement; import org.polypheny.db.prisminterface.utils.PrismUtils; +import org.polypheny.db.transaction.Statement; import org.polypheny.db.type.entity.PolyValue; import org.polypheny.prism.Frame; import org.polypheny.prism.StatementResult; @@ -57,18 +61,26 @@ StatementResult executeAndGetResult( PIStatement piStatement ) { @Override StatementResult executeAndGetResult( PIStatement piStatement, int fetchSize ) { throwOnIllegalState( piStatement ); + Statement statement = piStatement.getStatement(); PolyImplementation implementation = piStatement.getImplementation(); + PIClient client = piStatement.getClient(); StatementResult.Builder resultBuilder = StatementResult.newBuilder(); - if ( implementation.isDDL() ) { + if ( Kind.DDL.contains( implementation.getKind() ) ) { resultBuilder.setScalar( 1 ); return resultBuilder.build(); } + if ( Kind.DML.contains( implementation.getKind() ) ) { + try (ResultIterator iterator = implementation.execute( statement, -1 )) { + resultBuilder.setScalar( PolyImplementation.getRowsChanged( statement, iterator.getIterator(), MonitoringType.from(implementation.getKind()) ) ); + } + client.commitCurrentTransactionIfAuto(); + return resultBuilder.build(); + } piStatement.setIterator( implementation.execute( piStatement.getStatement(), fetchSize ) ); Frame frame = fetch( piStatement, fetchSize ); resultBuilder.setFrame( frame ); if ( frame.getIsLast() ) { - //TODO TH: special handling for result set updates. Do we need to wait with committing until all changes have been done? - piStatement.getClient().commitCurrentTransactionIfAuto(); + client.commitCurrentTransactionIfAuto(); } return resultBuilder.build(); } From aad24efe366711965932f46bd54e005d346768f4 Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Fri, 17 May 2024 14:21:10 +0200 Subject: [PATCH 12/36] Rephrase error message From 5cc1df79ca39b46606f15f7026624480bc3ba18e Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Fri, 17 May 2024 16:26:42 +0200 Subject: [PATCH 13/36] Add cypher tests --- .../db/prisminterface/CypherTest.java | 152 ++++++++++++++++++ .../statementProcessing/GraphExecutor.java | 19 ++- .../StatementProcessor.java | 2 +- 3 files changed, 169 insertions(+), 4 deletions(-) create mode 100644 dbms/src/test/java/org/polypheny/db/prisminterface/CypherTest.java diff --git a/dbms/src/test/java/org/polypheny/db/prisminterface/CypherTest.java b/dbms/src/test/java/org/polypheny/db/prisminterface/CypherTest.java new file mode 100644 index 0000000000..6f8e73ef32 --- /dev/null +++ b/dbms/src/test/java/org/polypheny/db/prisminterface/CypherTest.java @@ -0,0 +1,152 @@ +/* + * Copyright 2019-2024 The Polypheny Project + * + * 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 org.polypheny.db.prisminterface; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Iterator; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.polypheny.db.TestHelper.JdbcConnection; +import org.polypheny.jdbc.PolyConnection; +import org.polypheny.jdbc.multimodel.GraphResult; +import org.polypheny.jdbc.multimodel.PolyRow; +import org.polypheny.jdbc.multimodel.PolyStatement; +import org.polypheny.jdbc.multimodel.RelationalResult; +import org.polypheny.jdbc.types.PolyGraphElement; +import org.polypheny.jdbc.types.PolyPath; + +public class CypherTest { + + @BeforeAll + public static void setup() throws SQLException { + try ( Connection connection = new JdbcConnection( true ).getConnection() ) { + if ( !connection.isWrapperFor( PolyConnection.class ) ) { + fail( "Driver must support unwrapping to PolyConnection" ); + } + PolyStatement polyStatement = connection.unwrap( PolyConnection.class ).createPolyStatement(); + polyStatement.execute( "public", "sql", "DROP NAMESPACE IF EXISTS cyphertest" ); + polyStatement.execute( "public", "sql", "CREATE GRAPH NAMESPACE cyphertest" ); + polyStatement.execute( "cyphertest", "cypher", "CREATE (:Person {id: 1, name: 'Alice'})" ); + polyStatement.execute( "cyphertest", "cypher", "CREATE (:Person {id: 2, name: 'Bob'})" ); + polyStatement.execute( "cyphertest", "cypher", "CREATE (:Person {id: 3, name: 'Charlie'})" ); + polyStatement.execute( "cyphertest", "cypher", "MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'}) CREATE (a)-[:KNOWS]->(b)" ); + polyStatement.execute( "cyphertest", "cypher", "MATCH (b:Person {name: 'Bob'}), (c:Person {name: 'Charlie'}) CREATE (b)-[:KNOWS]->(c)" ); + } + } + + + @Test + public void cypherSelectNodesTest() throws SQLException { + try ( Connection connection = new JdbcConnection( true ).getConnection() ) { + if ( !connection.isWrapperFor( PolyConnection.class ) ) { + fail( "Driver must support unwrapping to PolyConnection" ); + } + PolyStatement polyStatement = connection.unwrap( PolyConnection.class ).createPolyStatement(); + GraphResult result = polyStatement.execute( "cyphertest", "cypher", "MATCH (n:Person) RETURN n" ).unwrap( GraphResult.class ); + Iterator elements = result.iterator(); + + assertTrue( elements.hasNext() ); + PolyGraphElement element = elements.next(); + assertEquals( "Alice", element.get( "name" ).asString() ); + assertEquals( 1, element.getLabels().size() ); + assertEquals( "Person", element.getLabels().get( 0 ) ); + + assertTrue( elements.hasNext() ); + element = elements.next(); + assertEquals( "Bob", element.get( "name" ).asString() ); + assertEquals( 1, element.getLabels().size() ); + assertEquals( "Person", element.getLabels().get( 0 ) ); + + assertTrue( elements.hasNext() ); + element = elements.next(); + assertEquals( "Charlie", element.get( "name" ).asString() ); + assertEquals( 1, element.getLabels().size() ); + assertEquals( "Person", element.getLabels().get( 0 ) ); + + assertFalse( elements.hasNext() ); + } + } + + + @Test + public void cypherSelectEdgesTest() throws SQLException { + try ( Connection connection = new JdbcConnection( true ).getConnection() ) { + if ( !connection.isWrapperFor( PolyConnection.class ) ) { + fail( "Driver must support unwrapping to PolyConnection" ); + } + PolyStatement polyStatement = connection.unwrap( PolyConnection.class ).createPolyStatement(); + GraphResult result = polyStatement.execute( "cyphertest", "cypher", "MATCH ()-[r:KNOWS]->() RETURN r" ).unwrap( GraphResult.class ); + Iterator elements = result.iterator(); + + assertTrue( elements.hasNext() ); + PolyGraphElement element = elements.next(); + assertEquals( "KNOWS", element.getLabels().get( 0 ) ); + + assertTrue( elements.hasNext() ); + element = elements.next(); + assertEquals( "KNOWS", element.getLabels().get( 0 ) ); + + assertFalse( elements.hasNext() ); + } + } + + + @Test + public void cypherSelectPathsTest() throws SQLException { + try ( Connection connection = new JdbcConnection( true ).getConnection() ) { + if ( !connection.isWrapperFor( PolyConnection.class ) ) { + fail( "Driver must support unwrapping to PolyConnection" ); + } + PolyStatement polyStatement = connection.unwrap( PolyConnection.class ).createPolyStatement(); + GraphResult result = polyStatement.execute( "cyphertest", "cypher", "MATCH p=(:Person {name: 'Alice'})-[:KNOWS*]->(:Person {name: 'Charlie'}) RETURN p" ).unwrap( GraphResult.class ); + Iterator elements = result.iterator(); + + assertTrue( elements.hasNext() ); + PolyGraphElement element = elements.next(); + PolyPath path = element.unwrap( PolyPath.class ); + assertFalse( elements.hasNext() ); + } + } + + + @Test + public void cypherRelationalTest() throws SQLException { + try ( Connection connection = new JdbcConnection( true ).getConnection() ) { + if ( !connection.isWrapperFor( PolyConnection.class ) ) { + fail( "Driver must support unwrapping to PolyConnection" ); + } + PolyStatement polyStatement = connection.unwrap( PolyConnection.class ).createPolyStatement(); + RelationalResult result = polyStatement.execute( "cyphertest", "cypher", "MATCH (n:Person {name: 'Alice'}) RETURN n.name, n.id" ).unwrap( RelationalResult.class ); + Iterator rows = result.iterator(); + + assertTrue( rows.hasNext() ); + PolyRow row = rows.next(); + assertEquals( "Alice", row.get( "n.name" ).asString() ); + assertEquals( 1, row.get( "n.id" ).asInt() ); + + assertFalse( rows.hasNext() ); + } + } + + +} diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/GraphExecutor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/GraphExecutor.java index 8eb4fc5503..2c84a14349 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/GraphExecutor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/GraphExecutor.java @@ -21,12 +21,16 @@ import org.apache.commons.lang3.time.StopWatch; import org.polypheny.db.PolyImplementation; import org.polypheny.db.ResultIterator; +import org.polypheny.db.algebra.constant.Kind; import org.polypheny.db.catalog.logistic.DataModel; +import org.polypheny.db.monitoring.events.MonitoringType; +import org.polypheny.db.prisminterface.PIClient; import org.polypheny.db.prisminterface.PIServiceException; import org.polypheny.db.prisminterface.metaRetrieval.GraphMetaRetriever; import org.polypheny.db.prisminterface.metaRetrieval.RelationalMetaRetriever; import org.polypheny.db.prisminterface.statements.PIStatement; import org.polypheny.db.prisminterface.utils.PrismUtils; +import org.polypheny.db.transaction.Statement; import org.polypheny.db.type.entity.PolyValue; import org.polypheny.prism.ColumnMeta; import org.polypheny.prism.Frame; @@ -59,19 +63,28 @@ StatementResult executeAndGetResult( PIStatement piStatement ) { @Override - StatementResult executeAndGetResult( PIStatement piStatement, int fetchSize ) throws Exception { + StatementResult executeAndGetResult( PIStatement piStatement, int fetchSize ) { throwOnIllegalState( piStatement ); + Statement statement = piStatement.getStatement(); PolyImplementation implementation = piStatement.getImplementation(); + PIClient client = piStatement.getClient(); StatementResult.Builder resultBuilder = StatementResult.newBuilder(); - if ( implementation.isDDL() ) { + if ( Kind.DDL.contains( implementation.getKind() ) ) { resultBuilder.setScalar( 1 ); return resultBuilder.build(); } + if ( Kind.DML.contains( implementation.getKind() ) ) { + try (ResultIterator iterator = implementation.execute( statement, -1 )) { + resultBuilder.setScalar( PolyImplementation.getRowsChanged( statement, iterator.getIterator(), MonitoringType.from(implementation.getKind()) ) ); + } + client.commitCurrentTransactionIfAuto(); + return resultBuilder.build(); + } piStatement.setIterator( implementation.execute( piStatement.getStatement(), fetchSize ) ); Frame frame = fetch( piStatement, fetchSize ); resultBuilder.setFrame( frame ); if ( frame.getIsLast() ) { - piStatement.getClient().commitCurrentTransactionIfAuto(); + client.commitCurrentTransactionIfAuto(); } return resultBuilder.build(); } diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java index d2be8cc876..1e9104acf2 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java @@ -64,7 +64,7 @@ public static void implement( PIStatement piStatement ) { .query( piStatement.getQuery() ) .language( piStatement.getLanguage() ) .namespaceId( piStatement.getNamespace().id ) - .transactionManager( piStatement.getTransaction().getTransactionManager() ) + .transactions( List.of(piStatement.getTransaction()) ) .origin( ORIGIN ) .build(); List implementations = LanguageManager.getINSTANCE().anyPrepareQuery( context, statement ); From a6606729fd4819ebcc62b477e59b6d06039786b7 Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Thu, 4 Jul 2024 15:24:41 +0200 Subject: [PATCH 14/36] Remove broken assertion --- .../org/polypheny/db/algebra/type/AlgDataTypeFieldImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/src/main/java/org/polypheny/db/algebra/type/AlgDataTypeFieldImpl.java b/core/src/main/java/org/polypheny/db/algebra/type/AlgDataTypeFieldImpl.java index c71d5d8df9..7bb6796371 100644 --- a/core/src/main/java/org/polypheny/db/algebra/type/AlgDataTypeFieldImpl.java +++ b/core/src/main/java/org/polypheny/db/algebra/type/AlgDataTypeFieldImpl.java @@ -67,8 +67,6 @@ public AlgDataTypeFieldImpl( Long id, String name, int index, AlgDataType type ) public AlgDataTypeFieldImpl( Long id, String name, String physicalName, int index, AlgDataType type ) { super( name, id, type ); - assert name != null; - assert type != null; this.id = id; this.name = name; this.index = index; From c1642f8d54330158e8fbac930b2d4ec8350abd8c Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Thu, 4 Jul 2024 15:29:02 +0200 Subject: [PATCH 15/36] Adjust test --- .../test/java/org/polypheny/db/prisminterface/CypherTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/test/java/org/polypheny/db/prisminterface/CypherTest.java b/dbms/src/test/java/org/polypheny/db/prisminterface/CypherTest.java index 6f8e73ef32..e8d3511aed 100644 --- a/dbms/src/test/java/org/polypheny/db/prisminterface/CypherTest.java +++ b/dbms/src/test/java/org/polypheny/db/prisminterface/CypherTest.java @@ -62,7 +62,7 @@ public void cypherSelectNodesTest() throws SQLException { fail( "Driver must support unwrapping to PolyConnection" ); } PolyStatement polyStatement = connection.unwrap( PolyConnection.class ).createPolyStatement(); - GraphResult result = polyStatement.execute( "cyphertest", "cypher", "MATCH (n:Person) RETURN n" ).unwrap( GraphResult.class ); + GraphResult result = polyStatement.execute( "cyphertest", "cypher", "MATCH (n:Person) RETURN n ORDER BY n.id" ).unwrap( GraphResult.class ); Iterator elements = result.iterator(); assertTrue( elements.hasNext() ); @@ -142,7 +142,7 @@ public void cypherRelationalTest() throws SQLException { assertTrue( rows.hasNext() ); PolyRow row = rows.next(); assertEquals( "Alice", row.get( "n.name" ).asString() ); - assertEquals( 1, row.get( "n.id" ).asInt() ); + assertEquals( "1", row.get( "n.id" ).asString() ); assertFalse( rows.hasNext() ); } From eb4b060fa46adc86c1d1eb1068aaa99380cde2ce Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Fri, 5 Jul 2024 10:09:27 +0200 Subject: [PATCH 16/36] Fix node serialization --- .../utils/PolyValueSerializer.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java index a349232a1c..a61e653312 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java @@ -309,25 +309,29 @@ public static ProtoDocument buildProtoDocument( PolyDocument polyDocument ) { public static ProtoNode buildProtoNode( PolyNode polyNode ) { - return ProtoNode.newBuilder() + ProtoNode.Builder node = ProtoNode.newBuilder() .setId( polyNode.getId().getValue() ) - .setName( polyNode.getVariableName().getValue() ) - .addAllLabels( polyNode.getLabels().stream().map( l -> ((PolyString) l).getValue() ).collect( Collectors.toList() ) ) - .addAllProperties( serializeToProtoEntryList( polyNode.properties.asMap() ) ) - .build(); + .addAllLabels( polyNode.getLabels().stream().map( l -> l.getValue() ).collect( Collectors.toList() ) ) + .addAllProperties( serializeToProtoEntryList( polyNode.properties.asMap() ) ); + if ( !(polyNode.variableName == null) ) { + node.setName( polyNode.variableName.getValue() ); + } + return node.build(); } public static ProtoEdge buildProtoEdge( PolyEdge polyEdge ) { - return ProtoEdge.newBuilder() + ProtoEdge.Builder edge = ProtoEdge.newBuilder() .setId( polyEdge.getId().getValue() ) - .setName( polyEdge.getVariableName().getValue() ) - .addAllLabels( polyEdge.getLabels().stream().map( l -> ((PolyString) l).getValue() ).collect( Collectors.toList() ) ) + .addAllLabels( polyEdge.getLabels().stream().map( l -> l.getValue() ).collect( Collectors.toList() ) ) .addAllProperties( serializeToProtoEntryList( polyEdge.properties.asMap() ) ) .setSource( polyEdge.getSource().getValue() ) .setTarget( polyEdge.getTarget().getValue() ) - .setDirection( buildProtoEdgeDirection( polyEdge.getDirection() ) ) - .build(); + .setDirection( buildProtoEdgeDirection( polyEdge.getDirection() ) ); + if ( !(polyEdge.variableName == null) ) { + edge.setName( polyEdge.getVariableName().getValue() ); + } + return edge.build(); } From aa036e5e1deb1c424e9571055ed588b8b57d6600 Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Thu, 18 Jul 2024 10:09:06 +0200 Subject: [PATCH 17/36] Add not implemented exception and todo for paths --- .../db/prisminterface/utils/PolyValueSerializer.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java index a61e653312..559b6348c6 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java @@ -352,7 +352,13 @@ private static Direction buildProtoEdgeDirection( EdgeDirection direction ) { public static ProtoPath buildProtoPath( PolyPath polyPath ) { - throw new NotImplementedException(); + /* + TODO: implement paths for graph results + 1) implement the proto value ProtoPath + 2) implement serialization here + 3) add fields to dummy class in drivers + */ + throw new NotImplementedException("Paths can not yet be serialized."); } From 5091b41deb6edf71bbe1b877c0333bd6d652f316 Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Thu, 18 Jul 2024 10:15:17 +0200 Subject: [PATCH 18/36] Update api version --- plugins/prism-interface/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/prism-interface/build.gradle b/plugins/prism-interface/build.gradle index 7d42efed1c..23eb1deb99 100644 --- a/plugins/prism-interface/build.gradle +++ b/plugins/prism-interface/build.gradle @@ -26,7 +26,7 @@ dependencies { compileOnly project(path: ':plugins:mql-language') // Prism API files (protobuf files), needs to be implementation due to the prism-api-version.properties - implementation group: 'org.polypheny', name: 'prism', version: 5.1 + implementation group: 'org.polypheny', name: 'prism', version: 1.4 // Protobuf implementation group: 'com.google.protobuf', name: 'protobuf-java', version: protobuf_version From 0a86c9d6fcca9647bbc115276af0aac63f135350 Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Fri, 19 Jul 2024 08:47:48 +0200 Subject: [PATCH 19/36] Put classes into corresponding packages --- .../polypheny/db/prisminterface/PIClient.java | 3 +- .../db/prisminterface/PIService.java | 2 + .../{ => metaRetrieval}/DbMetaRetriever.java | 58 +++++++++++-------- .../PIClientInfoProperties.java | 6 +- .../NamedValueProcessor.java | 2 +- .../statements/PIPreparedNamedStatement.java | 2 +- .../NamedValueProcessorTest.java | 1 + 7 files changed, 44 insertions(+), 30 deletions(-) rename plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/{ => metaRetrieval}/DbMetaRetriever.java (87%) rename plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/{ => metaRetrieval}/PIClientInfoProperties.java (93%) rename plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/{ => statementProcessing}/NamedValueProcessor.java (97%) diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIClient.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIClient.java index 4e3aba4118..f1c726d4fb 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIClient.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIClient.java @@ -21,6 +21,7 @@ import lombok.extern.slf4j.Slf4j; import org.polypheny.db.catalog.entity.LogicalUser; import org.polypheny.db.catalog.entity.logical.LogicalNamespace; +import org.polypheny.db.prisminterface.metaRetrieval.PIClientInfoProperties; import org.polypheny.db.prisminterface.statements.StatementManager; import org.polypheny.db.transaction.Transaction; import org.polypheny.db.transaction.TransactionException; @@ -39,7 +40,7 @@ public class PIClient { @Getter private final StatementManager statementManager; @Getter - private final PIClientInfoProperties PIClientInfoProperties; + private final org.polypheny.db.prisminterface.metaRetrieval.PIClientInfoProperties PIClientInfoProperties; @Getter @Setter private boolean isAutoCommit; diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIService.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIService.java index b591342e5a..0df6e87f5c 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIService.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIService.java @@ -30,6 +30,8 @@ import org.polypheny.db.catalog.exceptions.GenericRuntimeException; import org.polypheny.db.iface.AuthenticationException; import org.polypheny.db.languages.QueryLanguage; +import org.polypheny.db.prisminterface.metaRetrieval.DbMetaRetriever; +import org.polypheny.db.prisminterface.metaRetrieval.PIClientInfoProperties; import org.polypheny.db.prisminterface.statementProcessing.StatementProcessor; import org.polypheny.db.prisminterface.statements.PIPreparedIndexedStatement; import org.polypheny.db.prisminterface.statements.PIPreparedNamedStatement; diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/DbMetaRetriever.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/DbMetaRetriever.java similarity index 87% rename from plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/DbMetaRetriever.java rename to plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/DbMetaRetriever.java index 3f7207f6ee..dff6a45587 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/DbMetaRetriever.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/DbMetaRetriever.java @@ -14,12 +14,13 @@ * limitations under the License. */ -package org.polypheny.db.prisminterface; +package org.polypheny.db.prisminterface.metaRetrieval; import java.sql.DatabaseMetaData; import java.util.Arrays; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; import org.polypheny.db.PolyphenyDb; import org.polypheny.db.algebra.constant.FunctionCategory; import org.polypheny.db.algebra.type.AlgDataTypeSystem; @@ -38,6 +39,8 @@ import org.polypheny.db.catalog.logistic.Pattern; import org.polypheny.db.languages.OperatorRegistry; import org.polypheny.db.languages.QueryLanguage; +import org.polypheny.db.prisminterface.metaRetrieval.PIClientInfoProperties; +import org.polypheny.db.prisminterface.PIServiceException; import org.polypheny.db.type.PolyType; import org.polypheny.prism.ClientInfoPropertyMeta; import org.polypheny.prism.ClientInfoPropertyMetaResponse; @@ -73,12 +76,12 @@ static NamespacesResponse searchNamespaces( String namespacePattern, String name private static List getLogicalNamespaces( String namespacePattern, String namespaceType ) { Pattern catalogNamespacePattern = getPatternOrNull( namespacePattern ); - List logicalNamespaces = Catalog.snapshot().getNamespaces( catalogNamespacePattern ); + List logicalNamespaces = Catalog.getInstance().getSnapshot().getNamespaces( catalogNamespacePattern ); if ( namespaceType == null ) { return logicalNamespaces; } DataModel catalogNamespaceType = DataModel.valueOf( namespaceType ); - return logicalNamespaces.stream().filter( n -> n.getDataModel() == catalogNamespaceType ).toList(); + return logicalNamespaces.stream().filter( n -> n.getDataModel() == catalogNamespaceType ).collect( Collectors.toList() ); } @@ -96,27 +99,34 @@ private static Pattern getPatternOrNull( String pattern ) { public static Namespace getNamespace( String namespaceName ) { - return getNamespaceMeta( Catalog.snapshot().getNamespace( namespaceName ).orElseThrow() ); + return getNamespaceMeta( Catalog.getInstance().getSnapshot().getNamespace( namespaceName ).orElseThrow() ); } // Entity search by namespace static EntitiesResponse searchEntities( String namespaceName, String entityPattern ) { EntitiesResponse.Builder responseBuilder = EntitiesResponse.newBuilder(); - LogicalNamespace namespace = Catalog.snapshot().getNamespace( namespaceName ).orElseThrow(); - return switch ( namespace.getDataModel() ) { - case RELATIONAL -> responseBuilder.addAllEntities( getRelationalEntities( namespace.getId(), entityPattern ) ).build(); - case GRAPH -> responseBuilder.addAllEntities( getGraphEntities( namespace.getId(), entityPattern ) ).build(); - case DOCUMENT -> responseBuilder.addAllEntities( getDocumentEntities( namespace.getId(), entityPattern ) ).build(); - }; + LogicalNamespace namespace = Catalog.getInstance().getSnapshot().getNamespace( namespaceName ).orElseThrow(); + switch ( namespace.getDataModel() ) { + case RELATIONAL: + responseBuilder.addAllEntities( getRelationalEntities( namespace.getId(), entityPattern ) ); + break; + case GRAPH: + responseBuilder.addAllEntities( getGraphEntities( namespace.getId(), entityPattern ) ); + break; + case DOCUMENT: + responseBuilder.addAllEntities( getDocumentEntities( namespace.getId(), entityPattern ) ); + break; + } + return responseBuilder.build(); } // Relational entities private static List getRelationalEntities( long namespaceId, String entityPattern ) { Pattern catalogEntityPattern = getPatternOrNull( entityPattern ); - final List tables = Catalog.snapshot().rel().getTables( namespaceId, catalogEntityPattern ); - return tables.stream().map( logicalTable -> buildEntityFromTable( getTableMeta( logicalTable ) ) ).toList(); + final List tables = Catalog.getInstance().getSnapshot().rel().getTables( namespaceId, catalogEntityPattern ); + return tables.stream().map( logicalTable -> buildEntityFromTable( getTableMeta( logicalTable ) ) ).collect( Collectors.toList() ); } @@ -144,7 +154,7 @@ private static Table getTableMeta( LogicalTable logicalTable ) { private static List getColumns( LogicalTable logicalTable ) { - return logicalTable.getColumns().stream().map( DbMetaRetriever::getColumnMeta ).toList(); + return logicalTable.getColumns().stream().map( DbMetaRetriever::getColumnMeta ).collect( Collectors.toList() ); } @@ -152,12 +162,12 @@ private static boolean hasPrimaryKey( LogicalTable logicalTable ) { if ( logicalTable.primaryKey == null ) { return false; } - return Catalog.snapshot().rel().getPrimaryKey( logicalTable.primaryKey ).isPresent(); + return Catalog.getInstance().getSnapshot().rel().getPrimaryKey( logicalTable.primaryKey ).isPresent(); } private static PrimaryKey getPrimaryKeyMeta( LogicalTable logicalTable ) { - LogicalPrimaryKey logicalPrimaryKey = Catalog.snapshot().rel().getPrimaryKey( logicalTable.primaryKey ).orElseThrow(); + LogicalPrimaryKey logicalPrimaryKey = Catalog.getInstance().getSnapshot().rel().getPrimaryKey( logicalTable.primaryKey ).orElseThrow(); return PrimaryKey.newBuilder() .setDatabaseName( logicalPrimaryKey.getSchemaName() ) .setNamespaceName( logicalPrimaryKey.getSchemaName() ) @@ -191,8 +201,8 @@ private static Column getColumnMeta( LogicalColumn logicalColumn ) { private static List getForeignKeys( LogicalTable logicalTable ) { - return Catalog.snapshot().rel().getForeignKeys( logicalTable.getId() ) - .stream().map( DbMetaRetriever::getForeignKeyMeta ).toList(); + return Catalog.getInstance().getSnapshot().rel().getForeignKeys( logicalTable.getId() ) + .stream().map( DbMetaRetriever::getForeignKeyMeta ).collect( Collectors.toList() ); } @@ -210,19 +220,19 @@ private static ForeignKey getForeignKeyMeta( LogicalForeignKey logicalForeignKey private static List getReferencedColumns( LogicalForeignKey logicalForeignKey ) { - return logicalForeignKey.referencedKeyFieldIds.stream().map( id -> Catalog.snapshot().rel().getColumn( id ).orElseThrow() ).map( DbMetaRetriever::getColumnMeta ).toList(); + return logicalForeignKey.referencedKeyFieldIds.stream().map( id -> Catalog.snapshot().rel().getColumn( id ).orElseThrow() ).map( DbMetaRetriever::getColumnMeta ).collect( Collectors.toList() ); } private static List getExportedKeys( LogicalTable logicalTable ) { - return Catalog.snapshot().rel().getExportedKeys( logicalTable.getId() ) - .stream().map( DbMetaRetriever::getForeignKeyMeta ).toList(); + return Catalog.getInstance().getSnapshot().rel().getExportedKeys( logicalTable.getId() ) + .stream().map( DbMetaRetriever::getForeignKeyMeta ).collect( Collectors.toList() ); } private static List getIndexes( LogicalTable logicalTable, boolean unique ) { - return Catalog.snapshot().rel().getIndexes( logicalTable.getId(), unique ) - .stream().map( DbMetaRetriever::getIndexMeta ).toList(); + return Catalog.getInstance().getSnapshot().rel().getIndexes( logicalTable.getId(), unique ) + .stream().map( DbMetaRetriever::getIndexMeta ).collect( Collectors.toList() ); } @@ -301,7 +311,7 @@ static ProceduresResponse getProcedures( String languageName, String procedureNa static ClientInfoPropertyMetaResponse getClientInfoProperties() { List propertyInfoMetas = PIClientInfoProperties.DEFAULTS.stream() - .map( DbMetaRetriever::getClientInfoPropertyMeta ).toList(); + .map( DbMetaRetriever::getClientInfoPropertyMeta ).collect( Collectors.toList() ); return ClientInfoPropertyMetaResponse.newBuilder() .addAllClientInfoPropertyMetas( propertyInfoMetas ) .build(); @@ -324,7 +334,7 @@ static FunctionsResponse getFunctions( QueryLanguage language, FunctionCategory .map( org.polypheny.db.nodes.Function.class::cast ) .filter( f -> f.getFunctionCategory() == functionCategory || functionCategory == null ) .map( DbMetaRetriever::getFunctionMeta ) - .toList(); + .collect( Collectors.toList() ); return FunctionsResponse.newBuilder().addAllFunctions( functions ).build(); } diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIClientInfoProperties.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/PIClientInfoProperties.java similarity index 93% rename from plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIClientInfoProperties.java rename to plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/PIClientInfoProperties.java index d6593e9f93..a2a4206434 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIClientInfoProperties.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/PIClientInfoProperties.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.polypheny.db.prisminterface; +package org.polypheny.db.prisminterface.metaRetrieval; import java.util.Arrays; import java.util.List; import java.util.Properties; -class PIClientInfoProperties extends Properties { +public class PIClientInfoProperties extends Properties { private static final int MAX_STRING_LENGTH = 2147483647; static final List DEFAULTS = Arrays.asList( @@ -51,7 +51,7 @@ class PIClientInfoProperties extends Properties { ); - PIClientInfoProperties() { + public PIClientInfoProperties() { super(); DEFAULTS.forEach( p -> setProperty( p.key, p.default_value ) ); } diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/NamedValueProcessor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/NamedValueProcessor.java similarity index 97% rename from plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/NamedValueProcessor.java rename to plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/NamedValueProcessor.java index 8efe9f5c15..8b2371651f 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/NamedValueProcessor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/NamedValueProcessor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.polypheny.db.prisminterface; +package org.polypheny.db.prisminterface.statementProcessing; import java.util.ArrayList; import java.util.List; diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statements/PIPreparedNamedStatement.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statements/PIPreparedNamedStatement.java index 9dadddf7c0..63d9192395 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statements/PIPreparedNamedStatement.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statements/PIPreparedNamedStatement.java @@ -23,7 +23,7 @@ import org.polypheny.db.PolyImplementation; import org.polypheny.db.catalog.entity.logical.LogicalNamespace; import org.polypheny.db.languages.QueryLanguage; -import org.polypheny.db.prisminterface.NamedValueProcessor; +import org.polypheny.db.prisminterface.statementProcessing.NamedValueProcessor; import org.polypheny.db.prisminterface.PIClient; import org.polypheny.db.prisminterface.statementProcessing.StatementProcessor; import org.polypheny.db.transaction.Statement; diff --git a/plugins/prism-interface/src/test/java/org/polypheny/db/prisminterface/NamedValueProcessorTest.java b/plugins/prism-interface/src/test/java/org/polypheny/db/prisminterface/NamedValueProcessorTest.java index 57a49f0ff9..00f7592287 100644 --- a/plugins/prism-interface/src/test/java/org/polypheny/db/prisminterface/NamedValueProcessorTest.java +++ b/plugins/prism-interface/src/test/java/org/polypheny/db/prisminterface/NamedValueProcessorTest.java @@ -26,6 +26,7 @@ import org.junit.jupiter.api.Test; import org.polypheny.db.TestHelper; import org.polypheny.db.catalog.exceptions.GenericRuntimeException; +import org.polypheny.db.prisminterface.statementProcessing.NamedValueProcessor; import org.polypheny.db.type.entity.PolyString; import org.polypheny.db.type.entity.PolyValue; From 3bedb6852aa0c14868ff965ddaaaa046078a7593 Mon Sep 17 00:00:00 2001 From: Tobias Hafner Date: Fri, 19 Jul 2024 08:48:53 +0200 Subject: [PATCH 20/36] Fix method access --- .../metaRetrieval/DbMetaRetriever.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/DbMetaRetriever.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/DbMetaRetriever.java index dff6a45587..31e9b28a38 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/DbMetaRetriever.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/DbMetaRetriever.java @@ -63,10 +63,10 @@ import org.polypheny.prism.Type; import org.polypheny.prism.TypesResponse; -class DbMetaRetriever { +public class DbMetaRetriever { // Namespace search by name and type - static NamespacesResponse searchNamespaces( String namespacePattern, String namespaceType ) { + public static NamespacesResponse searchNamespaces( String namespacePattern, String namespaceType ) { List namespaces = getLogicalNamespaces( namespacePattern, namespaceType ); NamespacesResponse.Builder responseBuilder = NamespacesResponse.newBuilder(); namespaces.forEach( namespace -> responseBuilder.addNamespaces( getNamespaceMeta( namespace ) ) ); @@ -104,7 +104,7 @@ public static Namespace getNamespace( String namespaceName ) { // Entity search by namespace - static EntitiesResponse searchEntities( String namespaceName, String entityPattern ) { + public static EntitiesResponse searchEntities( String namespaceName, String entityPattern ) { EntitiesResponse.Builder responseBuilder = EntitiesResponse.newBuilder(); LogicalNamespace namespace = Catalog.getInstance().getSnapshot().getNamespace( namespaceName ).orElseThrow(); switch ( namespace.getDataModel() ) { @@ -259,14 +259,14 @@ static List getGraphEntities( long namespaceId, String entityPattern ) { } - static synchronized DefaultNamespaceResponse getDefaultNamespace() { + public static synchronized DefaultNamespaceResponse getDefaultNamespace() { return DefaultNamespaceResponse.newBuilder() .setDefaultNamespace( Catalog.DEFAULT_NAMESPACE_NAME ) .build(); } - static synchronized TableTypesResponse getTableTypes() { + public static synchronized TableTypesResponse getTableTypes() { List tableTypes = Arrays.stream( EntityType.values() ).map( EntityType::name ).toList(); TableTypesResponse.Builder responseBuilder = TableTypesResponse.newBuilder(); tableTypes.forEach( tableType -> responseBuilder.addTableTypes( getTableTypeMeta( tableType ) ) ); @@ -279,7 +279,7 @@ private static TableType getTableTypeMeta( String tableType ) { } - static synchronized TypesResponse getTypes() { + public static synchronized TypesResponse getTypes() { TypesResponse.Builder responseBuilder = TypesResponse.newBuilder(); Arrays.stream( PolyType.values() ).forEach( polyType -> responseBuilder.addTypes( getTypeMeta( polyType ) ) ); return responseBuilder.build(); @@ -303,7 +303,7 @@ private static Type getTypeMeta( PolyType polyType ) { } - static ProceduresResponse getProcedures( String languageName, String procedureNamePattern ) { + public static ProceduresResponse getProcedures( String languageName, String procedureNamePattern ) { // TODO: get data after functionality is implemented return ProceduresResponse.newBuilder().build(); } @@ -328,7 +328,7 @@ private static ClientInfoPropertyMeta getClientInfoPropertyMeta( PIClientInfoPro } - static FunctionsResponse getFunctions( QueryLanguage language, FunctionCategory functionCategory ) { + public static FunctionsResponse getFunctions( QueryLanguage language, FunctionCategory functionCategory ) { List functions = OperatorRegistry.getMatchingOperators( language ).values().stream() .filter( o -> o instanceof org.polypheny.db.nodes.Function ) .map( org.polypheny.db.nodes.Function.class::cast ) @@ -349,7 +349,7 @@ private static Function getFunctionMeta( org.polypheny.db.nodes.Function functio } - static DbmsVersionResponse getDbmsVersion() { + public static DbmsVersionResponse getDbmsVersion() { try { String versionName = PolyphenyDb.class.getPackage().getImplementationVersion(); if ( versionName == null ) { From 208d7c3e00121e1c3b20b8e3f56dd48d9da3feee Mon Sep 17 00:00:00 2001 From: Martin Vahlensieck Date: Fri, 4 Oct 2024 16:09:07 +0200 Subject: [PATCH 21/36] Update to new Prism API files --- plugins/prism-interface/build.gradle | 2 +- .../StatementProcessor.java | 2 +- .../utils/PolyValueSerializer.java | 52 ++++++++----------- .../db/prisminterface/utils/PrismUtils.java | 29 ++--------- .../utils/PrismValueDeserializer.java | 9 ++-- 5 files changed, 32 insertions(+), 62 deletions(-) diff --git a/plugins/prism-interface/build.gradle b/plugins/prism-interface/build.gradle index 23eb1deb99..32dd6c4449 100644 --- a/plugins/prism-interface/build.gradle +++ b/plugins/prism-interface/build.gradle @@ -26,7 +26,7 @@ dependencies { compileOnly project(path: ':plugins:mql-language') // Prism API files (protobuf files), needs to be implementation due to the prism-api-version.properties - implementation group: 'org.polypheny', name: 'prism', version: 1.4 + implementation group: 'org.polypheny', name: 'prism', version: 1.10 // Protobuf implementation group: 'com.google.protobuf', name: 'protobuf-java', version: protobuf_version diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java index 1e9104acf2..6ac437ae38 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java @@ -64,7 +64,7 @@ public static void implement( PIStatement piStatement ) { .query( piStatement.getQuery() ) .language( piStatement.getLanguage() ) .namespaceId( piStatement.getNamespace().id ) - .transactions( List.of(piStatement.getTransaction()) ) + .transactions( List.of( piStatement.getTransaction() ) ) .origin( ORIGIN ) .build(); List implementations = LanguageManager.getINSTANCE().anyPrepareQuery( context, statement ); diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java index 559b6348c6..389d8a9194 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java @@ -17,6 +17,7 @@ package org.polypheny.db.prisminterface.utils; import com.google.protobuf.ByteString; +import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang3.NotImplementedException; @@ -31,7 +32,6 @@ import org.polypheny.db.type.entity.graph.PolyEdge; import org.polypheny.db.type.entity.graph.PolyEdge.EdgeDirection; import org.polypheny.db.type.entity.graph.PolyNode; -import org.polypheny.db.type.entity.graph.PolyPath; import org.polypheny.db.type.entity.numerical.PolyBigDecimal; import org.polypheny.db.type.entity.numerical.PolyDouble; import org.polypheny.db.type.entity.numerical.PolyFloat; @@ -41,6 +41,7 @@ import org.polypheny.db.type.entity.temporal.PolyDate; import org.polypheny.db.type.entity.temporal.PolyTime; import org.polypheny.db.type.entity.temporal.PolyTimestamp; +import org.polypheny.prism.GraphElement; import org.polypheny.prism.ProtoBigDecimal; import org.polypheny.prism.ProtoBinary; import org.polypheny.prism.ProtoBoolean; @@ -49,7 +50,6 @@ import org.polypheny.prism.ProtoDouble; import org.polypheny.prism.ProtoEdge; import org.polypheny.prism.ProtoEdge.Direction; -import org.polypheny.prism.ProtoEntry; import org.polypheny.prism.ProtoFloat; import org.polypheny.prism.ProtoInteger; import org.polypheny.prism.ProtoInterval; @@ -57,7 +57,6 @@ import org.polypheny.prism.ProtoLong; import org.polypheny.prism.ProtoNode; import org.polypheny.prism.ProtoNull; -import org.polypheny.prism.ProtoPath; import org.polypheny.prism.ProtoString; import org.polypheny.prism.ProtoTime; import org.polypheny.prism.ProtoTimestamp; @@ -71,16 +70,12 @@ public static List serializeList( List valuesList ) { } - public static List serializeToProtoEntryList( PolyMap polyMap ) { - return polyMap.entrySet().stream().map( PolyValueSerializer::serializeToProtoEntry ).toList(); - } + public static Map serializeToProtoMap( PolyMap polyMap ) { + Map map = new HashMap<>(); + polyMap.forEach( ( k, v ) -> map.put( k.asString().value, PolyValueSerializer.serialize( v ) ) ); - public static ProtoEntry serializeToProtoEntry( Map.Entry polyMapEntry ) { - return ProtoEntry.newBuilder() - .setKey( serialize( polyMapEntry.getKey() ) ) - .setValue( serialize( polyMapEntry.getValue() ) ) - .build(); + return map; } @@ -303,16 +298,25 @@ public static ProtoValue serializeAsProtoBigDecimal( PolyBigDecimal polyBigDecim public static ProtoDocument buildProtoDocument( PolyDocument polyDocument ) { return ProtoDocument.newBuilder() - .addAllEntries( serializeToProtoEntryList( polyDocument.asMap() ) ) + .putAllEntries( serializeToProtoMap( polyDocument.asMap() ) ) .build(); } + public static GraphElement buildProtoGraphElement( PolyValue value ) { + return switch ( value.getType() ) { + case NODE -> GraphElement.newBuilder().setNode( buildProtoNode( value.asNode() ) ).build(); + case EDGE -> GraphElement.newBuilder().setEdge( buildProtoEdge( value.asEdge() ) ).build(); + default -> throw new RuntimeException("Invalid graph element " + value.getType() ); + }; + } + + public static ProtoNode buildProtoNode( PolyNode polyNode ) { ProtoNode.Builder node = ProtoNode.newBuilder() .setId( polyNode.getId().getValue() ) - .addAllLabels( polyNode.getLabels().stream().map( l -> l.getValue() ).collect( Collectors.toList() ) ) - .addAllProperties( serializeToProtoEntryList( polyNode.properties.asMap() ) ); + .addAllLabels( polyNode.getLabels().stream().map( PolyString::getValue ).toList() ) + .putAllProperties( serializeToProtoMap( polyNode.properties.asMap() ) ); if ( !(polyNode.variableName == null) ) { node.setName( polyNode.variableName.getValue() ); } @@ -323,10 +327,10 @@ public static ProtoNode buildProtoNode( PolyNode polyNode ) { public static ProtoEdge buildProtoEdge( PolyEdge polyEdge ) { ProtoEdge.Builder edge = ProtoEdge.newBuilder() .setId( polyEdge.getId().getValue() ) - .addAllLabels( polyEdge.getLabels().stream().map( l -> l.getValue() ).collect( Collectors.toList() ) ) - .addAllProperties( serializeToProtoEntryList( polyEdge.properties.asMap() ) ) - .setSource( polyEdge.getSource().getValue() ) - .setTarget( polyEdge.getTarget().getValue() ) + .addAllLabels( polyEdge.getLabels().stream().map( PolyString::getValue ).toList() ) + .putAllProperties( serializeToProtoMap( polyEdge.properties.asMap() ) ) + .setLeft( polyEdge.getSource().getValue() ) + .setRight( polyEdge.getTarget().getValue() ) .setDirection( buildProtoEdgeDirection( polyEdge.getDirection() ) ); if ( !(polyEdge.variableName == null) ) { edge.setName( polyEdge.getVariableName().getValue() ); @@ -350,16 +354,4 @@ private static Direction buildProtoEdgeDirection( EdgeDirection direction ) { return Direction.UNSPECIFIED; } - - public static ProtoPath buildProtoPath( PolyPath polyPath ) { - /* - TODO: implement paths for graph results - 1) implement the proto value ProtoPath - 2) implement serialization here - 3) add fields to dummy class in drivers - */ - throw new NotImplementedException("Paths can not yet be serialized."); - } - - } diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java index 239e8665f7..ee0de6e602 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismUtils.java @@ -21,18 +21,13 @@ import org.polypheny.db.prisminterface.statements.PIStatement; import org.polypheny.db.type.PolyType; import org.polypheny.db.type.entity.PolyValue; -import org.polypheny.db.type.entity.graph.PolyEdge; -import org.polypheny.db.type.entity.graph.PolyNode; -import org.polypheny.db.type.entity.graph.PolyPath; import org.polypheny.prism.ColumnMeta; import org.polypheny.prism.DocumentFrame; import org.polypheny.prism.Frame; +import org.polypheny.prism.GraphElement; import org.polypheny.prism.GraphFrame; import org.polypheny.prism.PreparedStatementSignature; import org.polypheny.prism.ProtoDocument; -import org.polypheny.prism.ProtoEdge; -import org.polypheny.prism.ProtoNode; -import org.polypheny.prism.ProtoPath; import org.polypheny.prism.ProtoPolyType; import org.polypheny.prism.RelationalFrame; import org.polypheny.prism.Row; @@ -93,18 +88,8 @@ public static List serializeToRows( List> rows ) { } - private static List serializeToNodes( List> data ) { - return data.stream().map( e -> PolyValueSerializer.buildProtoNode( (PolyNode) (e.get( 0 )) ) ).collect( Collectors.toList() ); - } - - - private static List serializeToEdges( List> data ) { - return data.stream().map( e -> PolyValueSerializer.buildProtoEdge( (PolyEdge) (e.get( 0 )) ) ).collect( Collectors.toList() ); - } - - - private static List serilaizeToPaths( List> data ) { - return data.stream().map( e -> PolyValueSerializer.buildProtoPath( (PolyPath) (e.get( 0 )) ) ).collect( Collectors.toList() ); + private static List serializeToGraphElement( List> data ) { + return data.stream().map( e -> PolyValueSerializer.buildProtoGraphElement( e.get( 0 ) ) ).toList(); } @@ -138,13 +123,7 @@ public static Frame buildDocumentFrame( boolean isLast, List data ) { public static Frame buildGraphFrame( boolean isLast, List> data ) { GraphFrame.Builder graphFrameBuilder = GraphFrame.newBuilder(); if ( !data.isEmpty() ) { - PolyType elementType = data.get( 0 ).get( 0 ).getType(); - switch ( elementType ) { - case NODE -> graphFrameBuilder.addAllNodes( serializeToNodes( data ) ); - case EDGE -> graphFrameBuilder.addAllEdges( serializeToEdges( data ) ); - case PATH -> graphFrameBuilder.addAllPaths( serilaizeToPaths( data ) ); - default -> throw new RuntimeException( "Should never be thrown!" ); - } + graphFrameBuilder.addAllElement( serializeToGraphElement( data ) ); } return Frame.newBuilder() diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismValueDeserializer.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismValueDeserializer.java index 5226f99a6a..9101120602 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismValueDeserializer.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismValueDeserializer.java @@ -104,11 +104,10 @@ public static PolyValue deserializeProtoValue( ProtoValue protoValue ) { private static PolyValue deserializeToPolyDocument( ProtoValue protoValue ) { PolyDocument document = new PolyDocument(); - protoValue.getDocument().getEntriesList().stream() - .filter( e -> e.getKey().getValueCase() == ValueCase.STRING ) - .forEach( e -> document.put( - new PolyString( e.getKey().getString().getString() ), - deserializeProtoValue( e.getValue() ) + protoValue.getDocument().getEntriesMap() + .forEach( (k, v) -> document.put( + new PolyString( k ), + deserializeProtoValue( v ) ) ); return document; } From 7ce351736c577d831e42a989b41f7ec2c71fe4e5 Mon Sep 17 00:00:00 2001 From: Martin Vahlensieck Date: Fri, 4 Oct 2024 16:29:55 +0200 Subject: [PATCH 22/36] Use switch expression --- .../utils/PolyValueSerializer.java | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java index 389d8a9194..d2b8dbdfdf 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java @@ -307,7 +307,7 @@ public static GraphElement buildProtoGraphElement( PolyValue value ) { return switch ( value.getType() ) { case NODE -> GraphElement.newBuilder().setNode( buildProtoNode( value.asNode() ) ).build(); case EDGE -> GraphElement.newBuilder().setEdge( buildProtoEdge( value.asEdge() ) ).build(); - default -> throw new RuntimeException("Invalid graph element " + value.getType() ); + default -> throw new RuntimeException( "Invalid graph element " + value.getType() ); }; } @@ -340,18 +340,11 @@ public static ProtoEdge buildProtoEdge( PolyEdge polyEdge ) { private static Direction buildProtoEdgeDirection( EdgeDirection direction ) { - switch ( direction ) { - case LEFT_TO_RIGHT -> { - return Direction.LEFT_TO_RIGHT; - } - case RIGHT_TO_LEFT -> { - return Direction.RIGHT_TO_LEFT; - } - case NONE -> { - return Direction.NONE; - } - } - return Direction.UNSPECIFIED; + return switch ( direction ) { + case LEFT_TO_RIGHT -> Direction.LEFT_TO_RIGHT; + case RIGHT_TO_LEFT -> Direction.RIGHT_TO_LEFT; + case NONE -> Direction.NONE; + }; } } From c1635e6516bf549c10d499f7055046132fe831de Mon Sep 17 00:00:00 2001 From: Martin Vahlensieck Date: Fri, 4 Oct 2024 16:49:15 +0200 Subject: [PATCH 23/36] Rename source/target to left/right --- .../algebra/logical/lpg/LogicalLpgValues.java | 4 +- .../db/functions/CrossModelFunctions.java | 4 +- .../db/type/entity/graph/PolyEdge.java | 38 +++++++++---------- .../db/type/entity/graph/PolyGraph.java | 26 ++++++------- .../neo4j/rules/graph/NeoLpgModify.java | 2 +- .../db/adapter/neo4j/util/NeoStatements.java | 4 +- .../utils/PolyValueSerializer.java | 4 +- 7 files changed, 41 insertions(+), 41 deletions(-) diff --git a/core/src/main/java/org/polypheny/db/algebra/logical/lpg/LogicalLpgValues.java b/core/src/main/java/org/polypheny/db/algebra/logical/lpg/LogicalLpgValues.java index 481cee9b96..cd35b8d181 100644 --- a/core/src/main/java/org/polypheny/db/algebra/logical/lpg/LogicalLpgValues.java +++ b/core/src/main/java/org/polypheny/db/algebra/logical/lpg/LogicalLpgValues.java @@ -191,8 +191,8 @@ private ImmutableList> getEdgeValues( ImmutableList>> enumerables, int i, AlgDataType idType, AlgDataType labelType, PolyEdge edge ) { context.addParameterValues( 0, idType, Collections.nCopies( edge.labels.size(), edge.id ) ); context.addParameterValues( 1, labelType, List.of( edge.labels.get( 0 ) ) ); - context.addParameterValues( 2, idType, List.of( edge.source ) ); - context.addParameterValues( 3, idType, List.of( edge.target ) ); + context.addParameterValues( 2, idType, List.of( edge.left ) ); + context.addParameterValues( 3, idType, List.of( edge.right ) ); // execute all inserts drainInserts( enumerables.get( i ), edge.labels.size() ); diff --git a/core/src/main/java/org/polypheny/db/type/entity/graph/PolyEdge.java b/core/src/main/java/org/polypheny/db/type/entity/graph/PolyEdge.java index b38579fad0..78eb860fb1 100644 --- a/core/src/main/java/org/polypheny/db/type/entity/graph/PolyEdge.java +++ b/core/src/main/java/org/polypheny/db/type/entity/graph/PolyEdge.java @@ -51,9 +51,9 @@ public class PolyEdge extends GraphPropertyHolder { @JsonProperty - public PolyString source; + public PolyString left; @JsonProperty - public PolyString target; + public PolyString right; @JsonProperty public EdgeDirection direction; @@ -67,11 +67,11 @@ public class PolyEdge extends GraphPropertyHolder { public PolyEdge( @NonNull PolyDictionary properties, List labels, - PolyString source, - PolyString target, + PolyString left, + PolyString right, EdgeDirection direction, PolyString variableName ) { - this( PolyString.of( UUID.randomUUID().toString() ), properties, labels, source, target, direction, variableName ); + this( PolyString.of( UUID.randomUUID().toString() ), properties, labels, left, right, direction, variableName ); } @@ -79,13 +79,13 @@ public PolyEdge( @JsonProperty("id") PolyString id, @JsonProperty("properties") @NonNull PolyDictionary properties, @JsonProperty("labels") List labels, - @JsonProperty("source") PolyString source, - @JsonProperty("target") PolyString target, + @JsonProperty("source") PolyString left, + @JsonProperty("target") PolyString right, @JsonProperty("direction") EdgeDirection direction, @JsonProperty("variableName") PolyString variableName ) { super( id, PolyType.EDGE, properties, labels, variableName ); - this.source = source; - this.target = target; + this.left = left; + this.right = right; this.direction = direction; } @@ -99,7 +99,7 @@ public int getVariants() { public PolyEdge from( PolyString left, PolyString right ) { - return new PolyEdge( id, properties, labels, left == null ? this.source : left, right == null ? this.target : right, direction, null ); + return new PolyEdge( id, properties, labels, left == null ? this.left : left, right == null ? this.right : right, direction, null ); } @@ -120,7 +120,7 @@ public PolyEdge copyNamed( PolyString newName ) { // no copy needed return this; } - return new PolyEdge( id, properties, labels, source, target, direction, newName ); + return new PolyEdge( id, properties, labels, left, right, direction, newName ); } @@ -182,8 +182,8 @@ public Expression asExpression() { id.asExpression(), properties.asExpression(), labels.asExpression(), - source.asExpression(), - target.asExpression(), + left.asExpression(), + right.asExpression(), Expressions.constant( direction ), getVariableName() == null ? Expressions.constant( null ) : getVariableName().asExpression() ), PolyEdge.class ); @@ -200,8 +200,8 @@ public String toJson() { return "{\"id\":" + id.toQuotedJson() + ", \"properties\":" + properties.toJson() + ", \"labels\":" + labels.toJson() + - ", \"source\":" + source.toQuotedJson() + - ", \"target\":" + target.toQuotedJson() + + ", \"source\":" + left.toQuotedJson() + + ", \"target\":" + right.toQuotedJson() + ", \"direction\":\"" + direction.name() + "\"" + "}"; } @@ -238,8 +238,8 @@ public String toString() { "id=" + id + ", properties=" + properties + ", labels=" + labels + - ", leftId=" + source + - ", rightId=" + target + + ", leftId=" + left + + ", rightId=" + right + ", direction=" + direction + '}'; } @@ -259,8 +259,8 @@ public void encode( BinaryOutput out, PolyEdge item ) { out.writeUTF8Nullable( item.variableName.value ); } out.writeUTF8( item.direction.name() ); - out.writeUTF8( item.source.value ); - out.writeUTF8( item.target.value ); + out.writeUTF8( item.left.value ); + out.writeUTF8( item.right.value ); out.writeUTF8( item.properties.serialize() ); } diff --git a/core/src/main/java/org/polypheny/db/type/entity/graph/PolyGraph.java b/core/src/main/java/org/polypheny/db/type/entity/graph/PolyGraph.java index 643674a40c..0f1731c870 100644 --- a/core/src/main/java/org/polypheny/db/type/entity/graph/PolyGraph.java +++ b/core/src/main/java/org/polypheny/db/type/entity/graph/PolyGraph.java @@ -208,24 +208,24 @@ private List buildMatchingTree( List segments ) { // for one only edges, which have matching nodes are considered, // additionally only not used edges can be use, relationship isomorphism prohibits this BiPredicate filter = - segment.direction == EdgeDirection.LEFT_TO_RIGHT ? (( e, p ) -> !p.usedEdgesIds.contains( e.id ) && e.source.equals( p.targetId )) : - segment.direction == EdgeDirection.RIGHT_TO_LEFT ? (( e, p ) -> !p.usedEdgesIds.contains( e.id ) && e.target.equals( p.targetId )) : - (( e, p ) -> !p.usedEdgesIds.contains( e.id ) && (e.target.equals( p.targetId ) || e.source.equals( p.targetId ))); + segment.direction == EdgeDirection.LEFT_TO_RIGHT ? (( e, p ) -> !p.usedEdgesIds.contains( e.id ) && e.left.equals( p.targetId )) : + segment.direction == EdgeDirection.RIGHT_TO_LEFT ? (( e, p ) -> !p.usedEdgesIds.contains( e.id ) && e.right.equals( p.targetId )) : + (( e, p ) -> !p.usedEdgesIds.contains( e.id ) && (e.right.equals( p.targetId ) || e.left.equals( p.targetId ))); for ( TreePart part : last ) { // only loop matching connections for ( PolyEdge edge : edges.values().stream().filter( e -> filter.test( e, part ) ).toList() ) { - PolyNode left = nodes.get( edge.source ); - PolyNode right = nodes.get( edge.target ); + PolyNode left = nodes.get( edge.left ); + PolyNode right = nodes.get( edge.right ); // then check if it matches pattern of segment either ()->() or ()-() depending if direction is specified if ( segment.direction == EdgeDirection.LEFT_TO_RIGHT || segment.direction == EdgeDirection.NONE ) { - if ( segment.matches( left, edge, right ) && !part.usedEdgesIds.contains( edge.id ) && part.targetId.equals( edge.source ) ) { - matches.add( new TreePart( part, edge.id, edge.target, segment.edge.getVariableName(), segment.target.getVariableName() ) ); + if ( segment.matches( left, edge, right ) && !part.usedEdgesIds.contains( edge.id ) && part.targetId.equals( edge.left ) ) { + matches.add( new TreePart( part, edge.id, edge.right, segment.edge.getVariableName(), segment.target.getVariableName() ) ); } } if ( segment.direction == EdgeDirection.RIGHT_TO_LEFT || segment.direction == EdgeDirection.NONE ) { - if ( segment.matches( right, edge, left ) && !part.usedEdgesIds.contains( edge.id ) && part.targetId.equals( edge.target ) ) { - matches.add( new TreePart( part, edge.id, edge.source, segment.edge.getVariableName(), segment.target.getVariableName() ) ); + if ( segment.matches( right, edge, left ) && !part.usedEdgesIds.contains( edge.id ) && part.targetId.equals( edge.right ) ) { + matches.add( new TreePart( part, edge.id, edge.left, segment.edge.getVariableName(), segment.target.getVariableName() ) ); } } @@ -248,18 +248,18 @@ private List buildMatchingTree( List segments ) { private void attachEmptyStubs( PolySegment segment, List root ) { Set> usedIds = new HashSet<>(); for ( PolyEdge edge : edges.values() ) { - PolyNode left = nodes.get( edge.source ); - PolyNode right = nodes.get( edge.target ); + PolyNode left = nodes.get( edge.left ); + PolyNode right = nodes.get( edge.right ); // We attach stubs, which allows ()->() and ()-() if ( segment.direction == EdgeDirection.LEFT_TO_RIGHT || segment.direction == EdgeDirection.NONE ) { if ( segment.matches( left, edge, right ) ) { - usedIds.add( Pair.of( edge.source, segment.source.getVariableName() ) ); + usedIds.add( Pair.of( edge.left, segment.source.getVariableName() ) ); } } // We attach stubs, which allows ()<-() and ()-() AKA inverted if ( segment.direction == EdgeDirection.RIGHT_TO_LEFT || segment.direction == EdgeDirection.NONE ) { if ( segment.matches( right, edge, left ) ) { - usedIds.add( Pair.of( edge.target, segment.source.getVariableName() ) ); + usedIds.add( Pair.of( edge.right, segment.source.getVariableName() ) ); } } } diff --git a/plugins/neo4j-adapter/src/main/java/org/polypheny/db/adapter/neo4j/rules/graph/NeoLpgModify.java b/plugins/neo4j-adapter/src/main/java/org/polypheny/db/adapter/neo4j/rules/graph/NeoLpgModify.java index 4a7fadf863..ca687403e9 100644 --- a/plugins/neo4j-adapter/src/main/java/org/polypheny/db/adapter/neo4j/rules/graph/NeoLpgModify.java +++ b/plugins/neo4j-adapter/src/main/java/org/polypheny/db/adapter/neo4j/rules/graph/NeoLpgModify.java @@ -166,7 +166,7 @@ private List getCreatePath( ImmutableList nodes, Immutab statements.add( node_( node, PolyString.of( implementor.getGraph().mappingLabel ), true ) ); } for ( PolyEdge edge : edges ) { - statements.add( path_( node_( uuidNameMapping.get( edge.source ) ), edge_( edge, true ), node_( uuidNameMapping.get( edge.target ) ) ) ); + statements.add( path_( node_( uuidNameMapping.get( edge.left ) ), edge_( edge, true ), node_( uuidNameMapping.get( edge.right ) ) ) ); } return statements; diff --git a/plugins/neo4j-adapter/src/main/java/org/polypheny/db/adapter/neo4j/util/NeoStatements.java b/plugins/neo4j-adapter/src/main/java/org/polypheny/db/adapter/neo4j/util/NeoStatements.java index 3a08939b23..26898f9e80 100644 --- a/plugins/neo4j-adapter/src/main/java/org/polypheny/db/adapter/neo4j/util/NeoStatements.java +++ b/plugins/neo4j-adapter/src/main/java/org/polypheny/db/adapter/neo4j/util/NeoStatements.java @@ -324,8 +324,8 @@ static EdgeStatement edge_( PolyEdge edge, boolean addId ) { List props = new ArrayList<>( properties_( edge.properties ) ); if ( addId ) { props.add( property_( PolyString.of( "_id" ), string_( edge.id ) ) ); - props.add( property_( PolyString.of( "__sourceId__" ), string_( edge.source ) ) ); - props.add( property_( PolyString.of( "__targetId__" ), string_( edge.target ) ) ); + props.add( property_( PolyString.of( "__sourceId__" ), string_( edge.left ) ) ); + props.add( property_( PolyString.of( "__targetId__" ), string_( edge.right ) ) ); } PolyString defIdentifier = edge.getVariableName(); diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java index d2b8dbdfdf..031db9d68d 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java @@ -329,8 +329,8 @@ public static ProtoEdge buildProtoEdge( PolyEdge polyEdge ) { .setId( polyEdge.getId().getValue() ) .addAllLabels( polyEdge.getLabels().stream().map( PolyString::getValue ).toList() ) .putAllProperties( serializeToProtoMap( polyEdge.properties.asMap() ) ) - .setLeft( polyEdge.getSource().getValue() ) - .setRight( polyEdge.getTarget().getValue() ) + .setLeft( polyEdge.getLeft().getValue() ) + .setRight( polyEdge.getRight().getValue() ) .setDirection( buildProtoEdgeDirection( polyEdge.getDirection() ) ); if ( !(polyEdge.variableName == null) ) { edge.setName( polyEdge.getVariableName().getValue() ); From 7b00a3896143407be23e522f2a588cc732bc5534 Mon Sep 17 00:00:00 2001 From: Martin Vahlensieck Date: Wed, 9 Oct 2024 18:32:36 +0200 Subject: [PATCH 24/36] Fix fallout from rebase --- dbms/build.gradle | 3 +- gradle.properties | 2 +- plugins/prism-interface/build.gradle | 2 +- .../polypheny/db/prisminterface/PIClient.java | 2 +- .../metaRetrieval/DbMetaRetriever.java | 47 ++++++++----------- .../RelationalMetaRetriever.java | 19 ++++---- 6 files changed, 32 insertions(+), 43 deletions(-) diff --git a/dbms/build.gradle b/dbms/build.gradle index 4e7f67806d..b5b067847d 100644 --- a/dbms/build.gradle +++ b/dbms/build.gradle @@ -6,7 +6,6 @@ buildscript { url "https://plugins.gradle.org/m2/" } google() - mavenLocal() } dependencies { classpath group: "app.cash.licensee", name: "licensee-gradle-plugin", version: licensee_version @@ -55,7 +54,7 @@ dependencies { // Workaround so org.polypheny.db.docker gets the right protobuf during testing testImplementation group: "com.google.protobuf", name: "protobuf-java", version: protobuf_version // BSD 3-clause - + testImplementation(group: "org.polypheny", name: "polypheny-jdbc-driver", version: polypheny_jdbc_driver_version) { exclude(group: "com.fasterxml.jackson.core") exclude(group: "com.fasterxml.jackson.databind") diff --git a/gradle.properties b/gradle.properties index 625af03536..6fdc60a448 100644 --- a/gradle.properties +++ b/gradle.properties @@ -86,7 +86,7 @@ postgresql_version = 42.2.19 postgis_version = 2024.1.0 proj4j_version = 1.3.0 pf4j_version = 3.12.0 -prism_api_version = 1.9 +prism_api_version = 1.10 protobuf_version = 3.23.4 protobuf_plugin_version = 0.9.4 reflections_version = 0.10.2 diff --git a/plugins/prism-interface/build.gradle b/plugins/prism-interface/build.gradle index 32dd6c4449..537f91f7ff 100644 --- a/plugins/prism-interface/build.gradle +++ b/plugins/prism-interface/build.gradle @@ -26,7 +26,7 @@ dependencies { compileOnly project(path: ':plugins:mql-language') // Prism API files (protobuf files), needs to be implementation due to the prism-api-version.properties - implementation group: 'org.polypheny', name: 'prism', version: 1.10 + implementation group: 'org.polypheny', name: 'prism', version: prism_api_version // Protobuf implementation group: 'com.google.protobuf', name: 'protobuf-java', version: protobuf_version diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIClient.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIClient.java index f1c726d4fb..bd9f14d10f 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIClient.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIClient.java @@ -40,7 +40,7 @@ public class PIClient { @Getter private final StatementManager statementManager; @Getter - private final org.polypheny.db.prisminterface.metaRetrieval.PIClientInfoProperties PIClientInfoProperties; + private final PIClientInfoProperties PIClientInfoProperties; @Getter @Setter private boolean isAutoCommit; diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/DbMetaRetriever.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/DbMetaRetriever.java index 31e9b28a38..45d62a33ed 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/DbMetaRetriever.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/DbMetaRetriever.java @@ -76,12 +76,12 @@ public static NamespacesResponse searchNamespaces( String namespacePattern, Stri private static List getLogicalNamespaces( String namespacePattern, String namespaceType ) { Pattern catalogNamespacePattern = getPatternOrNull( namespacePattern ); - List logicalNamespaces = Catalog.getInstance().getSnapshot().getNamespaces( catalogNamespacePattern ); + List logicalNamespaces = Catalog.snapshot().getNamespaces( catalogNamespacePattern ); if ( namespaceType == null ) { return logicalNamespaces; } DataModel catalogNamespaceType = DataModel.valueOf( namespaceType ); - return logicalNamespaces.stream().filter( n -> n.getDataModel() == catalogNamespaceType ).collect( Collectors.toList() ); + return logicalNamespaces.stream().filter( n -> n.getDataModel() == catalogNamespaceType ).toList(); } @@ -99,7 +99,7 @@ private static Pattern getPatternOrNull( String pattern ) { public static Namespace getNamespace( String namespaceName ) { - return getNamespaceMeta( Catalog.getInstance().getSnapshot().getNamespace( namespaceName ).orElseThrow() ); + return getNamespaceMeta( Catalog.snapshot().getNamespace( namespaceName ).orElseThrow() ); } @@ -107,26 +107,19 @@ public static Namespace getNamespace( String namespaceName ) { public static EntitiesResponse searchEntities( String namespaceName, String entityPattern ) { EntitiesResponse.Builder responseBuilder = EntitiesResponse.newBuilder(); LogicalNamespace namespace = Catalog.getInstance().getSnapshot().getNamespace( namespaceName ).orElseThrow(); - switch ( namespace.getDataModel() ) { - case RELATIONAL: - responseBuilder.addAllEntities( getRelationalEntities( namespace.getId(), entityPattern ) ); - break; - case GRAPH: - responseBuilder.addAllEntities( getGraphEntities( namespace.getId(), entityPattern ) ); - break; - case DOCUMENT: - responseBuilder.addAllEntities( getDocumentEntities( namespace.getId(), entityPattern ) ); - break; - } - return responseBuilder.build(); + return switch ( namespace.getDataModel() ) { + case RELATIONAL -> responseBuilder.addAllEntities( getRelationalEntities( namespace.getId(), entityPattern ) ).build(); + case GRAPH -> responseBuilder.addAllEntities( getGraphEntities( namespace.getId(), entityPattern ) ).build(); + case DOCUMENT -> responseBuilder.addAllEntities( getDocumentEntities( namespace.getId(), entityPattern ) ).build(); + }; } // Relational entities private static List getRelationalEntities( long namespaceId, String entityPattern ) { Pattern catalogEntityPattern = getPatternOrNull( entityPattern ); - final List tables = Catalog.getInstance().getSnapshot().rel().getTables( namespaceId, catalogEntityPattern ); - return tables.stream().map( logicalTable -> buildEntityFromTable( getTableMeta( logicalTable ) ) ).collect( Collectors.toList() ); + final List tables = Catalog.snapshot().rel().getTables( namespaceId, catalogEntityPattern ); + return tables.stream().map( logicalTable -> buildEntityFromTable( getTableMeta( logicalTable ) ) ).toList(); } @@ -154,7 +147,7 @@ private static Table getTableMeta( LogicalTable logicalTable ) { private static List getColumns( LogicalTable logicalTable ) { - return logicalTable.getColumns().stream().map( DbMetaRetriever::getColumnMeta ).collect( Collectors.toList() ); + return logicalTable.getColumns().stream().map( DbMetaRetriever::getColumnMeta ).toList(); } @@ -162,12 +155,12 @@ private static boolean hasPrimaryKey( LogicalTable logicalTable ) { if ( logicalTable.primaryKey == null ) { return false; } - return Catalog.getInstance().getSnapshot().rel().getPrimaryKey( logicalTable.primaryKey ).isPresent(); + return Catalog.snapshot().rel().getPrimaryKey( logicalTable.primaryKey ).isPresent(); } private static PrimaryKey getPrimaryKeyMeta( LogicalTable logicalTable ) { - LogicalPrimaryKey logicalPrimaryKey = Catalog.getInstance().getSnapshot().rel().getPrimaryKey( logicalTable.primaryKey ).orElseThrow(); + LogicalPrimaryKey logicalPrimaryKey = Catalog.snapshot().rel().getPrimaryKey( logicalTable.primaryKey ).orElseThrow(); return PrimaryKey.newBuilder() .setDatabaseName( logicalPrimaryKey.getSchemaName() ) .setNamespaceName( logicalPrimaryKey.getSchemaName() ) @@ -201,8 +194,8 @@ private static Column getColumnMeta( LogicalColumn logicalColumn ) { private static List getForeignKeys( LogicalTable logicalTable ) { - return Catalog.getInstance().getSnapshot().rel().getForeignKeys( logicalTable.getId() ) - .stream().map( DbMetaRetriever::getForeignKeyMeta ).collect( Collectors.toList() ); + return Catalog.snapshot().rel().getForeignKeys( logicalTable.getId() ) + .stream().map( DbMetaRetriever::getForeignKeyMeta ).toList(); } @@ -220,19 +213,19 @@ private static ForeignKey getForeignKeyMeta( LogicalForeignKey logicalForeignKey private static List getReferencedColumns( LogicalForeignKey logicalForeignKey ) { - return logicalForeignKey.referencedKeyFieldIds.stream().map( id -> Catalog.snapshot().rel().getColumn( id ).orElseThrow() ).map( DbMetaRetriever::getColumnMeta ).collect( Collectors.toList() ); + return logicalForeignKey.referencedKeyFieldIds.stream().map( id -> Catalog.snapshot().rel().getColumn( id ).orElseThrow() ).map( DbMetaRetriever::getColumnMeta ).toList(); } private static List getExportedKeys( LogicalTable logicalTable ) { return Catalog.getInstance().getSnapshot().rel().getExportedKeys( logicalTable.getId() ) - .stream().map( DbMetaRetriever::getForeignKeyMeta ).collect( Collectors.toList() ); + .stream().map( DbMetaRetriever::getForeignKeyMeta ).toList(); } private static List getIndexes( LogicalTable logicalTable, boolean unique ) { return Catalog.getInstance().getSnapshot().rel().getIndexes( logicalTable.getId(), unique ) - .stream().map( DbMetaRetriever::getIndexMeta ).collect( Collectors.toList() ); + .stream().map( DbMetaRetriever::getIndexMeta ).toList(); } @@ -311,7 +304,7 @@ public static ProceduresResponse getProcedures( String languageName, String proc static ClientInfoPropertyMetaResponse getClientInfoProperties() { List propertyInfoMetas = PIClientInfoProperties.DEFAULTS.stream() - .map( DbMetaRetriever::getClientInfoPropertyMeta ).collect( Collectors.toList() ); + .map( DbMetaRetriever::getClientInfoPropertyMeta ).toList(); return ClientInfoPropertyMetaResponse.newBuilder() .addAllClientInfoPropertyMetas( propertyInfoMetas ) .build(); @@ -334,7 +327,7 @@ public static FunctionsResponse getFunctions( QueryLanguage language, FunctionCa .map( org.polypheny.db.nodes.Function.class::cast ) .filter( f -> f.getFunctionCategory() == functionCategory || functionCategory == null ) .map( DbMetaRetriever::getFunctionMeta ) - .collect( Collectors.toList() ); + .toList(); return FunctionsResponse.newBuilder().addAllFunctions( functions ).build(); } diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/RelationalMetaRetriever.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/RelationalMetaRetriever.java index e8fb65ffaf..248d6d850f 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/RelationalMetaRetriever.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/RelationalMetaRetriever.java @@ -64,7 +64,7 @@ public static List retrieveColumnMetas( PolyImplementation polyImple public static List retrieveParameterMetas( AlgDataType parameterRowType ) { return parameterRowType.getFields().stream() .map( p -> retrieveParameterMeta( p, null ) ) - .collect( Collectors.toList() ); + .toList(); } @@ -146,7 +146,7 @@ private static TypeMeta retrieveTypeMeta( AlgDataType algDataType ) { .getFields() .stream() .map( f -> retrieveFieldMeta( f.getIndex(), f.getName(), f.getType() ) ) - .collect( Collectors.toList() ); + .toList(); return TypeMeta.newBuilder() .setStructMeta( StructMeta.newBuilder().addAllFieldMetas( fieldMetas ).build() ) //.setProtoValueType( ProtoValueType.PROTO_VALUE_TYPE_STRUCTURED ) @@ -162,18 +162,15 @@ private static TypeMeta retrieveTypeMeta( AlgDataType algDataType ) { private static AlgDataType retrieveAlgDataType( PolyImplementation polyImplementation ) { - switch ( polyImplementation.getKind() ) { - case INSERT: - case DELETE: - case UPDATE: - case EXPLAIN: + return switch ( polyImplementation.getKind() ) { + case INSERT, DELETE, UPDATE, EXPLAIN -> { // FIXME: getValidatedNodeType is wrong for DML Kind kind = polyImplementation.getKind(); JavaTypeFactory typeFactory = polyImplementation.getStatement().getTransaction().getTypeFactory(); - return AlgOptUtil.createDmlRowType( kind, typeFactory ); - default: - return polyImplementation.tupleType; - } + yield AlgOptUtil.createDmlRowType( kind, typeFactory ); + } + default -> polyImplementation.tupleType; + }; } } From 038d96d51ce481c7bd476f99b7f154159f0b96bb Mon Sep 17 00:00:00 2001 From: Martin Vahlensieck Date: Wed, 9 Oct 2024 18:34:54 +0200 Subject: [PATCH 25/36] Fix instances missed in previous --- .../db/prisminterface/metaRetrieval/DbMetaRetriever.java | 8 +++----- .../metaRetrieval/RelationalMetaRetriever.java | 3 +-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/DbMetaRetriever.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/DbMetaRetriever.java index 45d62a33ed..b1e1ae7a66 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/DbMetaRetriever.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/DbMetaRetriever.java @@ -20,7 +20,6 @@ import java.util.Arrays; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; import org.polypheny.db.PolyphenyDb; import org.polypheny.db.algebra.constant.FunctionCategory; import org.polypheny.db.algebra.type.AlgDataTypeSystem; @@ -39,7 +38,6 @@ import org.polypheny.db.catalog.logistic.Pattern; import org.polypheny.db.languages.OperatorRegistry; import org.polypheny.db.languages.QueryLanguage; -import org.polypheny.db.prisminterface.metaRetrieval.PIClientInfoProperties; import org.polypheny.db.prisminterface.PIServiceException; import org.polypheny.db.type.PolyType; import org.polypheny.prism.ClientInfoPropertyMeta; @@ -106,7 +104,7 @@ public static Namespace getNamespace( String namespaceName ) { // Entity search by namespace public static EntitiesResponse searchEntities( String namespaceName, String entityPattern ) { EntitiesResponse.Builder responseBuilder = EntitiesResponse.newBuilder(); - LogicalNamespace namespace = Catalog.getInstance().getSnapshot().getNamespace( namespaceName ).orElseThrow(); + LogicalNamespace namespace = Catalog.snapshot().getNamespace( namespaceName ).orElseThrow(); return switch ( namespace.getDataModel() ) { case RELATIONAL -> responseBuilder.addAllEntities( getRelationalEntities( namespace.getId(), entityPattern ) ).build(); case GRAPH -> responseBuilder.addAllEntities( getGraphEntities( namespace.getId(), entityPattern ) ).build(); @@ -218,13 +216,13 @@ private static List getReferencedColumns( LogicalForeignKey logicalForei private static List getExportedKeys( LogicalTable logicalTable ) { - return Catalog.getInstance().getSnapshot().rel().getExportedKeys( logicalTable.getId() ) + return Catalog.snapshot().rel().getExportedKeys( logicalTable.getId() ) .stream().map( DbMetaRetriever::getForeignKeyMeta ).toList(); } private static List getIndexes( LogicalTable logicalTable, boolean unique ) { - return Catalog.getInstance().getSnapshot().rel().getIndexes( logicalTable.getId(), unique ) + return Catalog.snapshot().rel().getIndexes( logicalTable.getId(), unique ) .stream().map( DbMetaRetriever::getIndexMeta ).toList(); } diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/RelationalMetaRetriever.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/RelationalMetaRetriever.java index 248d6d850f..9a2cca94b6 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/RelationalMetaRetriever.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/RelationalMetaRetriever.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.stream.Collectors; import org.apache.calcite.linq4j.Ord; import org.polypheny.db.PolyImplementation; import org.polypheny.db.adapter.java.JavaTypeFactory; @@ -167,7 +166,7 @@ private static AlgDataType retrieveAlgDataType( PolyImplementation polyImplement // FIXME: getValidatedNodeType is wrong for DML Kind kind = polyImplementation.getKind(); JavaTypeFactory typeFactory = polyImplementation.getStatement().getTransaction().getTypeFactory(); - yield AlgOptUtil.createDmlRowType( kind, typeFactory ); + yield AlgOptUtil.createDmlRowType( kind, typeFactory ); } default -> polyImplementation.tupleType; }; From 5a65a2028faf132ca09f48a773a0ab486f0ea188 Mon Sep 17 00:00:00 2001 From: Martin Vahlensieck Date: Wed, 9 Oct 2024 18:34:54 +0200 Subject: [PATCH 26/36] Improve switch expression --- .../metaRetrieval/GraphMetaRetriever.java | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/GraphMetaRetriever.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/GraphMetaRetriever.java index f52dd9aff8..613d91ae45 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/GraphMetaRetriever.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/GraphMetaRetriever.java @@ -32,14 +32,10 @@ public class GraphMetaRetriever { public static boolean retrievedResultIsRelational( PolyImplementation polyImplementation ) { PolyType polyType = polyImplementation.tupleType.getFields().get( 0 ).getType().getPolyType(); - switch ( polyType ) { - case NODE, EDGE, PATH -> { - return false; - } - default -> { - return true; - } - } + return switch ( polyType ) { + case NODE, EDGE, PATH -> false; + default -> true; + }; } @@ -47,7 +43,6 @@ public static List retrieveColumnMetas( PolyImplementation polyImple List columns = polyImplementation.tupleType.getFields(); AtomicInteger columnIndexGenerator = new AtomicInteger(); return columns.stream().map( c -> retieveColumnMeta( c, columnIndexGenerator ) ).collect( Collectors.toList() ); - } From badae3339fdc3b1d1318774abfd82c65fc793c52 Mon Sep 17 00:00:00 2001 From: Martin Vahlensieck Date: Wed, 9 Oct 2024 18:44:29 +0200 Subject: [PATCH 27/36] Use .toList() instead of Collectors.toList() --- .../db/prisminterface/metaRetrieval/GraphMetaRetriever.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/GraphMetaRetriever.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/GraphMetaRetriever.java index 613d91ae45..5efaeb05f1 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/GraphMetaRetriever.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/metaRetrieval/GraphMetaRetriever.java @@ -18,7 +18,6 @@ import java.util.List; import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; import org.polypheny.db.PolyImplementation; import org.polypheny.db.algebra.type.AlgDataType; import org.polypheny.db.algebra.type.AlgDataTypeField; @@ -42,7 +41,7 @@ public static boolean retrievedResultIsRelational( PolyImplementation polyImplem public static List retrieveColumnMetas( PolyImplementation polyImplementation ) { List columns = polyImplementation.tupleType.getFields(); AtomicInteger columnIndexGenerator = new AtomicInteger(); - return columns.stream().map( c -> retieveColumnMeta( c, columnIndexGenerator ) ).collect( Collectors.toList() ); + return columns.stream().map( c -> retieveColumnMeta( c, columnIndexGenerator ) ).toList(); } From c748e29e9e97930fc357a37dad9eee7e3d348184 Mon Sep 17 00:00:00 2001 From: Martin Vahlensieck Date: Wed, 9 Oct 2024 18:49:38 +0200 Subject: [PATCH 28/36] Remove unused state and errorCode from PIServiceExceptions --- .../db/prisminterface/PIServiceException.java | 54 +------------------ .../statementProcessing/DocumentExecutor.java | 9 ++-- .../statementProcessing/Executor.java | 9 ++-- .../statementProcessing/GraphExecutor.java | 12 ++--- .../RelationalExecutor.java | 5 +- .../StatementProcessor.java | 9 +--- 6 files changed, 14 insertions(+), 84 deletions(-) diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIServiceException.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIServiceException.java index 91d5744760..eb45a06fac 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIServiceException.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/PIServiceException.java @@ -17,41 +17,18 @@ package org.polypheny.db.prisminterface; import java.sql.SQLException; -import java.util.Optional; -import lombok.Getter; import org.polypheny.db.catalog.exceptions.GenericRuntimeException; -import org.polypheny.prism.ErrorDetails; public class PIServiceException extends GenericRuntimeException { - @Getter - private String state; - @Getter - private int errorCode; - - public PIServiceException( String reason, String state, int errorCode ) { - super( reason ); - this.state = state; - this.errorCode = errorCode; - } - - - public PIServiceException( String reason, String state ) { + public PIServiceException( String reason ) { super( reason ); - this.state = state; } public PIServiceException( SQLException sqlException ) { super( sqlException.getMessage(), sqlException ); - this.state = sqlException.getSQLState(); - this.errorCode = sqlException.getErrorCode(); - } - - - public PIServiceException( String reason ) { - super( reason ); } @@ -64,33 +41,4 @@ public PIServiceException( String reason, Throwable cause ) { super( reason, cause ); } - - public PIServiceException( String reason, String state, Throwable cause ) { - super( reason, cause ); - this.state = state; - } - - - public PIServiceException( String reason, String state, int errorCode, Throwable cause ) { - super( reason, cause ); - this.state = state; - this.errorCode = errorCode; - } - - - public PIServiceException( ErrorDetails errorDetails ) { - super( errorDetails.hasMessage() ? errorDetails.getMessage() : null ); - this.state = errorDetails.hasState() ? errorDetails.getState() : null; - this.errorCode = errorDetails.hasErrorCode() ? errorDetails.getErrorCode() : 0; - } - - - public ErrorDetails getPrismErrorDetails() { - ErrorDetails.Builder errorDetailsBuilder = ErrorDetails.newBuilder(); - errorDetailsBuilder.setErrorCode( getErrorCode() ); - Optional.ofNullable( getState() ).ifPresent( errorDetailsBuilder::setState ); - Optional.ofNullable( getMessage() ).ifPresent( errorDetailsBuilder::setMessage ); - return errorDetailsBuilder.build(); - } - } diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java index 09f612b7c9..fc57daac72 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/DocumentExecutor.java @@ -51,10 +51,7 @@ StatementResult executeAndGetResult( PIStatement piStatement ) { resultBuilder.setScalar( 1 ); return resultBuilder.build(); } - throw new PIServiceException( "Can't execute a non DDL or non DML statement using this method..", - "I9003", - 9002 - ); + throw new PIServiceException( "Can't execute a non DDL or non DML statement using this method." ); } @@ -70,8 +67,8 @@ StatementResult executeAndGetResult( PIStatement piStatement, int fetchSize ) { return resultBuilder.build(); } if ( Kind.DML.contains( implementation.getKind() ) ) { - try (ResultIterator iterator = implementation.execute( statement, -1 )) { - resultBuilder.setScalar( PolyImplementation.getRowsChanged( statement, iterator.getIterator(), MonitoringType.from(implementation.getKind()) ) ); + try ( ResultIterator iterator = implementation.execute( statement, -1 ) ) { + resultBuilder.setScalar( PolyImplementation.getRowsChanged( statement, iterator.getIterator(), MonitoringType.from( implementation.getKind() ) ) ); } client.commitCurrentTransactionIfAuto(); return resultBuilder.build(); diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/Executor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/Executor.java index 71d021308f..865f45d242 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/Executor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/Executor.java @@ -47,19 +47,16 @@ protected void throwOnIllegalState( PIStatement piStatement ) throws PIServiceEx statementDataModel.name().toLowerCase(), getDataModel().name().toLowerCase() ); - throw new PIServiceException( message, "I9000", 9000 ); + throw new PIServiceException( message ); } if ( piStatement.getStatement() == null ) { - throw new PIServiceException( "Statement is not linked to a polypheny statement", - "I9001", - 9001 - ); + throw new PIServiceException( "Statement is not linked to a polypheny statement" ); } PolyImplementation implementation = piStatement.getImplementation(); if ( implementation == null ) { - throw new PIServiceException( "Can't retrieve results form an unexecuted statement.", "I9002", 9002 ); + throw new PIServiceException( "Can't retrieve results form an unexecuted statement." ); } } diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/GraphExecutor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/GraphExecutor.java index 2c84a14349..4ba984e875 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/GraphExecutor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/GraphExecutor.java @@ -27,7 +27,6 @@ import org.polypheny.db.prisminterface.PIClient; import org.polypheny.db.prisminterface.PIServiceException; import org.polypheny.db.prisminterface.metaRetrieval.GraphMetaRetriever; -import org.polypheny.db.prisminterface.metaRetrieval.RelationalMetaRetriever; import org.polypheny.db.prisminterface.statements.PIStatement; import org.polypheny.db.prisminterface.utils.PrismUtils; import org.polypheny.db.transaction.Statement; @@ -55,10 +54,7 @@ StatementResult executeAndGetResult( PIStatement piStatement ) { resultBuilder.setScalar( 1 ); return resultBuilder.build(); } - throw new PIServiceException( "Can't execute a non DDL or non DML statement using this method..", - "I9003", - 9002 - ); + throw new PIServiceException( "Can't execute a non DDL or non DML statement using this method." ); } @@ -74,8 +70,8 @@ StatementResult executeAndGetResult( PIStatement piStatement, int fetchSize ) { return resultBuilder.build(); } if ( Kind.DML.contains( implementation.getKind() ) ) { - try (ResultIterator iterator = implementation.execute( statement, -1 )) { - resultBuilder.setScalar( PolyImplementation.getRowsChanged( statement, iterator.getIterator(), MonitoringType.from(implementation.getKind()) ) ); + try ( ResultIterator iterator = implementation.execute( statement, -1 ) ) { + resultBuilder.setScalar( PolyImplementation.getRowsChanged( statement, iterator.getIterator(), MonitoringType.from( implementation.getKind() ) ) ); } client.commitCurrentTransactionIfAuto(); return resultBuilder.build(); @@ -102,7 +98,7 @@ Frame fetch( PIStatement piStatement, int fetchSize ) { executionStopWatch.stop(); piStatement.getImplementation().getExecutionTimeMonitor().setExecutionTime( executionStopWatch.getNanoTime() ); } - if (GraphMetaRetriever.retrievedResultIsRelational(piStatement.getImplementation())) { + if ( GraphMetaRetriever.retrievedResultIsRelational( piStatement.getImplementation() ) ) { List columnMetas = GraphMetaRetriever.retrieveColumnMetas( piStatement.getImplementation() ); return PrismUtils.buildRelationalFrame( isLast, data, columnMetas ); } diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/RelationalExecutor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/RelationalExecutor.java index 229d4a11aa..a0155f2727 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/RelationalExecutor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/RelationalExecutor.java @@ -58,10 +58,7 @@ StatementResult executeAndGetResult( PIStatement piStatement ) { piStatement.getClient().commitCurrentTransactionIfAuto(); return resultBuilder.build(); } - throw new PIServiceException( "Can't execute a non DDL or non DML statement using this method..", - "I9003", - 9002 - ); + throw new PIServiceException( "Can't execute a non DDL or non DML statement using this method." ); } diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java index 6ac437ae38..afc9221280 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java @@ -55,10 +55,7 @@ public class StatementProcessor { public static void implement( PIStatement piStatement ) { Statement statement = piStatement.getStatement(); if ( statement == null ) { - throw new PIServiceException( "Statement is not linked to a PolyphenyStatement", - "I9003", - 9003 - ); + throw new PIServiceException( "Statement is not linked to a PolyphenyStatement" ); } QueryContext context = QueryContext.builder() .query( piStatement.getQuery() ) @@ -131,9 +128,7 @@ private static Executor getExecutorOrThrow( PIStatement piStatement ) { Executor executor = EXECUTORS.get( piStatement.getLanguage().dataModel() ); if ( executor == null ) { throw new PIServiceException( "No executor registered for namespace type " - + piStatement.getLanguage().dataModel(), - "I9004", - 9004 + + piStatement.getLanguage().dataModel() ); } return executor; From 45ba7a95cd89daf901c2b4c3e4133335891485fa Mon Sep 17 00:00:00 2001 From: Martin Vahlensieck Date: Wed, 9 Oct 2024 18:52:52 +0200 Subject: [PATCH 29/36] Make getExecutor switch over the data models --- .../StatementProcessor.java | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java index afc9221280..e76ee954b3 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statementProcessing/StatementProcessor.java @@ -16,13 +16,10 @@ package org.polypheny.db.prisminterface.statementProcessing; -import com.google.common.collect.ImmutableMap; import java.util.List; -import java.util.Map; import org.polypheny.db.algebra.type.AlgDataType; import org.polypheny.db.algebra.type.AlgDataTypeField; import org.polypheny.db.catalog.exceptions.GenericRuntimeException; -import org.polypheny.db.catalog.logistic.DataModel; import org.polypheny.db.languages.LanguageManager; import org.polypheny.db.languages.QueryLanguage; import org.polypheny.db.nodes.Node; @@ -44,12 +41,9 @@ public class StatementProcessor { private static final String ORIGIN = "prism-interface"; - private static final Map EXECUTORS = - ImmutableMap.builder() - .put( DataModel.RELATIONAL, new RelationalExecutor() ) - .put( DataModel.DOCUMENT, new DocumentExecutor() ) - .put( DataModel.GRAPH, new GraphExecutor() ) - .build(); + private static final RelationalExecutor relationalExecutor = new RelationalExecutor(); + private static final GraphExecutor graphExecutor = new GraphExecutor(); + private static final DocumentExecutor documentExecutor = new DocumentExecutor(); public static void implement( PIStatement piStatement ) { @@ -88,12 +82,12 @@ public static void implement( PIStatement piStatement ) { public static StatementResult executeAndGetResult( PIStatement piStatement ) { - return getExecutorOrThrow( piStatement ).executeAndGetResult( piStatement ); + return getExecutor( piStatement ).executeAndGetResult( piStatement ); } public static StatementResult executeAndGetResult( PIStatement piStatement, int fetchSize ) { - Executor executor = getExecutorOrThrow( piStatement ); + Executor executor = getExecutor( piStatement ); try { return executor.executeAndGetResult( piStatement, fetchSize ); } catch ( Exception e ) { @@ -103,7 +97,7 @@ public static StatementResult executeAndGetResult( PIStatement piStatement, int public static Frame fetch( PIStatement piStatement, int fetchSize ) { - Executor executor = getExecutorOrThrow( piStatement ); + Executor executor = getExecutor( piStatement ); return executor.fetch( piStatement, fetchSize ); } @@ -124,14 +118,12 @@ public static void prepare( PIPreparedStatement piStatement ) { } - private static Executor getExecutorOrThrow( PIStatement piStatement ) { - Executor executor = EXECUTORS.get( piStatement.getLanguage().dataModel() ); - if ( executor == null ) { - throw new PIServiceException( "No executor registered for namespace type " - + piStatement.getLanguage().dataModel() - ); - } - return executor; + private static Executor getExecutor( PIStatement piStatement ) { + return switch ( piStatement.getLanguage().dataModel() ) { + case RELATIONAL -> relationalExecutor; + case GRAPH -> graphExecutor; + case DOCUMENT -> documentExecutor; + }; } } From e4ca96eef3afdbe7bbd7f01f9bb8f2f527b96367 Mon Sep 17 00:00:00 2001 From: Martin Vahlensieck Date: Fri, 4 Oct 2024 16:48:17 +0200 Subject: [PATCH 30/36] Fix tests --- .../db/prisminterface/CypherTest.java | 24 ++++++++++++++++--- .../polypheny/db/prisminterface/MqlTest.java | 6 ----- gradle.properties | 2 +- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/dbms/src/test/java/org/polypheny/db/prisminterface/CypherTest.java b/dbms/src/test/java/org/polypheny/db/prisminterface/CypherTest.java index e8d3511aed..b05ae36c68 100644 --- a/dbms/src/test/java/org/polypheny/db/prisminterface/CypherTest.java +++ b/dbms/src/test/java/org/polypheny/db/prisminterface/CypherTest.java @@ -24,6 +24,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.Iterator; +import java.util.List; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.polypheny.db.TestHelper.JdbcConnection; @@ -32,8 +33,9 @@ import org.polypheny.jdbc.multimodel.PolyRow; import org.polypheny.jdbc.multimodel.PolyStatement; import org.polypheny.jdbc.multimodel.RelationalResult; +import org.polypheny.jdbc.types.PolyEdge; import org.polypheny.jdbc.types.PolyGraphElement; -import org.polypheny.jdbc.types.PolyPath; +import org.polypheny.jdbc.types.PolyNode; public class CypherTest { @@ -122,8 +124,24 @@ public void cypherSelectPathsTest() throws SQLException { Iterator elements = result.iterator(); assertTrue( elements.hasNext() ); - PolyGraphElement element = elements.next(); - PolyPath path = element.unwrap( PolyPath.class ); + PolyNode alice = elements.next().unwrap( PolyNode.class ); + assertEquals( alice.getLabels(), List.of( "Person" ) ); + assertEquals( alice.get("name").asString(), "Alice"); + + PolyEdge knows = elements.next().unwrap( PolyEdge.class ); + assertEquals( knows.getLabels(), List.of( "KNOWS" ) ); + + PolyNode bob = elements.next().unwrap( PolyNode.class ); + assertEquals( bob.getLabels(), List.of( "Person" ) ); + assertEquals( bob.get("name").asString(), "Bob"); + + knows = elements.next().unwrap( PolyEdge.class ); + assertEquals( knows.getLabels(), List.of( "KNOWS" ) ); + + PolyNode charlie = elements.next().unwrap( PolyNode.class ); + assertEquals( charlie.getLabels(), List.of( "Person" ) ); + assertEquals( charlie.get("name").asString(), "Charlie"); + assertFalse( elements.hasNext() ); } } diff --git a/dbms/src/test/java/org/polypheny/db/prisminterface/MqlTest.java b/dbms/src/test/java/org/polypheny/db/prisminterface/MqlTest.java index 4acebea4c9..0265c3c3ef 100644 --- a/dbms/src/test/java/org/polypheny/db/prisminterface/MqlTest.java +++ b/dbms/src/test/java/org/polypheny/db/prisminterface/MqlTest.java @@ -43,12 +43,6 @@ public static void setup() throws SQLException { } PolyStatement polyStatement = connection.unwrap( PolyConnection.class ).createPolyStatement(); - assertThrows( PrismInterfaceServiceException.class, () -> { - // fails due to autogenerated query (would create students collection) - Result result = polyStatement.execute( "mqltest", MQL_LANGUAGE_NAME, TEST_QUERY ); - assertEquals( ResultType.DOCUMENT, result.getResultType() ); - } ); - polyStatement.execute( "public", "sql", "DROP NAMESPACE IF EXISTS mongotest" ); polyStatement.execute( "public", "sql", "CREATE DOCUMENT NAMESPACE mongotest" ); polyStatement.execute( "mongotest", "mongo", "db.createCollection(test_collection)" ); diff --git a/gradle.properties b/gradle.properties index 6fdc60a448..470f57a594 100644 --- a/gradle.properties +++ b/gradle.properties @@ -80,7 +80,7 @@ opencsv_version = 5.9 oshi_core_version = 6.6.2 oauth_client_version = 1.34.1 poi_version = 5.2.3 -polypheny_jdbc_driver_version = 2.2 +polypheny_jdbc_driver_version = 2.4-SNAPSHOT polypheny_ui_version = 2.0-SNAPSHOT postgresql_version = 42.2.19 postgis_version = 2024.1.0 From 74d36ef92bdccc7193967b9f208d97a22d16c3c3 Mon Sep 17 00:00:00 2001 From: Martin Vahlensieck Date: Wed, 9 Oct 2024 19:01:30 +0200 Subject: [PATCH 31/36] Make conditionals easier to read --- .../db/prisminterface/utils/PolyValueSerializer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java index 031db9d68d..b27228354a 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java @@ -317,7 +317,7 @@ public static ProtoNode buildProtoNode( PolyNode polyNode ) { .setId( polyNode.getId().getValue() ) .addAllLabels( polyNode.getLabels().stream().map( PolyString::getValue ).toList() ) .putAllProperties( serializeToProtoMap( polyNode.properties.asMap() ) ); - if ( !(polyNode.variableName == null) ) { + if ( polyNode.variableName != null ) { node.setName( polyNode.variableName.getValue() ); } return node.build(); @@ -332,7 +332,7 @@ public static ProtoEdge buildProtoEdge( PolyEdge polyEdge ) { .setLeft( polyEdge.getLeft().getValue() ) .setRight( polyEdge.getRight().getValue() ) .setDirection( buildProtoEdgeDirection( polyEdge.getDirection() ) ); - if ( !(polyEdge.variableName == null) ) { + if ( polyEdge.variableName != null ) { edge.setName( polyEdge.getVariableName().getValue() ); } return edge.build(); From 23b8eecc630a6520279ec9e5bdbac6a6c63b6c22 Mon Sep 17 00:00:00 2001 From: Martin Vahlensieck Date: Wed, 9 Oct 2024 19:03:07 +0200 Subject: [PATCH 32/36] Format code & optimize imports --- .../db/prisminterface/statements/PIPreparedNamedStatement.java | 2 +- .../db/prisminterface/utils/PrismValueDeserializer.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statements/PIPreparedNamedStatement.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statements/PIPreparedNamedStatement.java index 63d9192395..7ca0559d1b 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statements/PIPreparedNamedStatement.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/statements/PIPreparedNamedStatement.java @@ -23,8 +23,8 @@ import org.polypheny.db.PolyImplementation; import org.polypheny.db.catalog.entity.logical.LogicalNamespace; import org.polypheny.db.languages.QueryLanguage; -import org.polypheny.db.prisminterface.statementProcessing.NamedValueProcessor; import org.polypheny.db.prisminterface.PIClient; +import org.polypheny.db.prisminterface.statementProcessing.NamedValueProcessor; import org.polypheny.db.prisminterface.statementProcessing.StatementProcessor; import org.polypheny.db.transaction.Statement; import org.polypheny.db.transaction.Transaction; diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismValueDeserializer.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismValueDeserializer.java index 9101120602..76e6d01806 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismValueDeserializer.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PrismValueDeserializer.java @@ -42,7 +42,6 @@ import org.polypheny.prism.IndexedParameters; import org.polypheny.prism.ProtoBigDecimal; import org.polypheny.prism.ProtoValue; -import org.polypheny.prism.ProtoValue.ValueCase; public class PrismValueDeserializer { @@ -105,7 +104,7 @@ public static PolyValue deserializeProtoValue( ProtoValue protoValue ) { private static PolyValue deserializeToPolyDocument( ProtoValue protoValue ) { PolyDocument document = new PolyDocument(); protoValue.getDocument().getEntriesMap() - .forEach( (k, v) -> document.put( + .forEach( ( k, v ) -> document.put( new PolyString( k ), deserializeProtoValue( v ) ) ); From 24efde1ce5e060e7610c02a6d9d4ae3951a3acba Mon Sep 17 00:00:00 2001 From: Martin Vahlensieck Date: Wed, 9 Oct 2024 19:03:07 +0200 Subject: [PATCH 33/36] Use Map.of instead of new HashMap --- .../db/prisminterface/PrismUtilsTest.java | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/plugins/prism-interface/src/test/java/org/polypheny/db/prisminterface/PrismUtilsTest.java b/plugins/prism-interface/src/test/java/org/polypheny/db/prisminterface/PrismUtilsTest.java index 8cf3d12f02..ac4c305a10 100644 --- a/plugins/prism-interface/src/test/java/org/polypheny/db/prisminterface/PrismUtilsTest.java +++ b/plugins/prism-interface/src/test/java/org/polypheny/db/prisminterface/PrismUtilsTest.java @@ -20,8 +20,8 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import java.util.HashMap; import java.util.List; +import java.util.Map; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.polypheny.db.TestHelper; @@ -86,13 +86,8 @@ public void serializeToRowsEmptyRowTest() { @Test public void buildGraphFrameWithNodesTest() { - HashMap map1 = new HashMap<>(); - map1.put( new PolyString( "key1" ), new PolyString( "value1" ) ); - PolyDictionary properties1 = PolyDictionary.ofDict( map1 ); - - HashMap map2 = new HashMap<>(); - map2.put( new PolyString( "key2" ), new PolyString( "value2" ) ); - PolyDictionary properties2 = PolyDictionary.ofDict( map2 ); + PolyDictionary properties1 = PolyDictionary.ofDict( Map.of( new PolyString( "key1" ), new PolyString( "value1" ) ) ); + PolyDictionary properties2 = PolyDictionary.ofDict( Map.of( new PolyString( "key2" ), new PolyString( "value2" ) ) ); PolyNode node1 = new PolyNode( properties1, List.of( new PolyString( "label1" ) ), new PolyString( "node1" ) ); PolyNode node2 = new PolyNode( properties2, List.of( new PolyString( "label2" ) ), new PolyString( "node2" ) ); @@ -124,13 +119,8 @@ public void buildGraphFrameWithEmptyNodesTest() { @Test public void buildGraphFrameWithEdgesTest() { - HashMap map1 = new HashMap<>(); - map1.put( new PolyString( "key1" ), new PolyString( "value1" ) ); - PolyDictionary properties1 = PolyDictionary.ofDict( map1 ); - - HashMap map2 = new HashMap<>(); - map2.put( new PolyString( "key2" ), new PolyString( "value2" ) ); - PolyDictionary properties2 = PolyDictionary.ofDict( map2 ); + PolyDictionary properties1 = PolyDictionary.ofDict( Map.of( new PolyString( "key1" ), new PolyString( "value1" ) ) ); + PolyDictionary properties2 = PolyDictionary.ofDict( Map.of( new PolyString( "key2" ), new PolyString( "value2" ) ) ); PolyEdge node1 = new PolyEdge( properties1, List.of( new PolyString( "label1" ) ), new PolyString( "node4" ), new PolyString( "node5" ), EdgeDirection.NONE, new PolyString( "edge1" ) ); PolyEdge node2 = new PolyEdge( properties2, List.of( new PolyString( "label2" ) ), new PolyString( "node4" ), new PolyString( "node5" ), EdgeDirection.NONE, new PolyString( "edge2" ) ); From 5e2d29e699ce0f4575370ef5c066ec6b8ca7ca9f Mon Sep 17 00:00:00 2001 From: Martin Vahlensieck Date: Thu, 10 Oct 2024 09:48:23 +0200 Subject: [PATCH 34/36] Fix PrismUtilsTest --- .../db/prisminterface/PrismUtilsTest.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/prism-interface/src/test/java/org/polypheny/db/prisminterface/PrismUtilsTest.java b/plugins/prism-interface/src/test/java/org/polypheny/db/prisminterface/PrismUtilsTest.java index ac4c305a10..9b1d4eaf95 100644 --- a/plugins/prism-interface/src/test/java/org/polypheny/db/prisminterface/PrismUtilsTest.java +++ b/plugins/prism-interface/src/test/java/org/polypheny/db/prisminterface/PrismUtilsTest.java @@ -100,9 +100,9 @@ public void buildGraphFrameWithNodesTest() { Frame result = PrismUtils.buildGraphFrame( true, data ); assertTrue( result.getIsLast() ); - assertEquals( 2, result.getGraphFrame().getNodesCount() ); - assertEquals( "node1", result.getGraphFrame().getNodes( 0 ).getName() ); - assertEquals( "node2", result.getGraphFrame().getNodes( 1 ).getName() ); + assertEquals( 2, result.getGraphFrame().getElementCount() ); + assertEquals( "node1", result.getGraphFrame().getElement( 0 ).getNode().getName() ); + assertEquals( "node2", result.getGraphFrame().getElement( 1 ).getNode().getName() ); } @@ -113,7 +113,7 @@ public void buildGraphFrameWithEmptyNodesTest() { Frame result = PrismUtils.buildGraphFrame( true, data ); assertTrue( result.getIsLast() ); - assertEquals( 0, result.getGraphFrame().getNodesCount() ); + assertEquals( 0, result.getGraphFrame().getElementCount() ); } @@ -133,9 +133,9 @@ public void buildGraphFrameWithEdgesTest() { Frame result = PrismUtils.buildGraphFrame( false, data ); assertFalse( result.getIsLast() ); - assertEquals( 2, result.getGraphFrame().getEdgesCount() ); - assertEquals( "edge1", result.getGraphFrame().getEdges( 0 ).getName() ); - assertEquals( "edge2", result.getGraphFrame().getEdges( 1 ).getName() ); + assertEquals( 2, result.getGraphFrame().getElementCount() ); + assertEquals( "edge1", result.getGraphFrame().getElement( 0 ).getEdge().getName() ); + assertEquals( "edge2", result.getGraphFrame().getElement( 1 ).getEdge().getName() ); } } From 83e9e1100f4f9db7b46a11dac1639d600c3942b9 Mon Sep 17 00:00:00 2001 From: Martin Vahlensieck Date: Thu, 10 Oct 2024 09:57:33 +0200 Subject: [PATCH 35/36] Add back GEOMETRY --- .../db/prisminterface/utils/PolyValueSerializer.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java index b27228354a..c0c78120b7 100644 --- a/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java +++ b/plugins/prism-interface/src/main/java/org/polypheny/db/prisminterface/utils/PolyValueSerializer.java @@ -38,6 +38,7 @@ import org.polypheny.db.type.entity.numerical.PolyInteger; import org.polypheny.db.type.entity.numerical.PolyLong; import org.polypheny.db.type.entity.relational.PolyMap; +import org.polypheny.db.type.entity.spatial.PolyGeometry; import org.polypheny.db.type.entity.temporal.PolyDate; import org.polypheny.db.type.entity.temporal.PolyTime; import org.polypheny.db.type.entity.temporal.PolyTimestamp; @@ -99,6 +100,7 @@ public static ProtoValue serialize( PolyValue polyValue ) { case NULL -> serializeAsProtoNull(); case ARRAY -> serializeAsProtoList( polyValue.asList() ); case DOCUMENT -> serializeAsProtoDocument( polyValue.asDocument() ); + case GEOMETRY -> serializeGeometry( polyValue.asGeometry() ); case IMAGE, VIDEO, AUDIO, FILE -> serializeAsProtoFile( polyValue.asBlob() ); // used case MAP, GRAPH, NODE, EDGE, PATH, DISTINCT, STRUCTURED, ROW, OTHER, CURSOR, COLUMN_LIST, DYNAMIC_STAR, SYMBOL, JSON, MULTISET, USER_DEFINED_TYPE, ANY -> throw new NotImplementedException( "Serialization of " + polyValue.getType() + " to proto not implemented" ); default -> throw new NotImplementedException(); @@ -106,6 +108,12 @@ public static ProtoValue serialize( PolyValue polyValue ) { } + private static ProtoValue serializeGeometry( PolyGeometry geometry ) { + ProtoString asString = ProtoString.newBuilder().setString( geometry.toString() ).build(); // todo add own value, taken from @danylokravchenko + return ProtoValue.newBuilder().setString( asString ).build(); + } + + private static ProtoValue serializeAsProtoDocument( PolyDocument polyDocument ) { return ProtoValue.newBuilder() .setDocument( buildProtoDocument( polyDocument ) ) From 634792b770d6bb16f053c2029eac293f8c4aa6f4 Mon Sep 17 00:00:00 2001 From: Martin Vahlensieck Date: Thu, 10 Oct 2024 10:08:01 +0200 Subject: [PATCH 36/36] Clean up after CypherTests --- .../db/prisminterface/CypherTest.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/dbms/src/test/java/org/polypheny/db/prisminterface/CypherTest.java b/dbms/src/test/java/org/polypheny/db/prisminterface/CypherTest.java index b05ae36c68..a260bc3c46 100644 --- a/dbms/src/test/java/org/polypheny/db/prisminterface/CypherTest.java +++ b/dbms/src/test/java/org/polypheny/db/prisminterface/CypherTest.java @@ -25,6 +25,7 @@ import java.sql.SQLException; import java.util.Iterator; import java.util.List; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.polypheny.db.TestHelper.JdbcConnection; @@ -57,6 +58,18 @@ public static void setup() throws SQLException { } + @AfterAll + public static void teardown() throws SQLException { + try ( Connection connection = new JdbcConnection( true ).getConnection() ) { + if ( !connection.isWrapperFor( PolyConnection.class ) ) { + fail( "Driver must support unwrapping to PolyConnection" ); + } + PolyStatement polyStatement = connection.unwrap( PolyConnection.class ).createPolyStatement(); + polyStatement.execute( "public", "sql", "DROP NAMESPACE IF EXISTS cyphertest" ); + } + } + + @Test public void cypherSelectNodesTest() throws SQLException { try ( Connection connection = new JdbcConnection( true ).getConnection() ) { @@ -126,21 +139,21 @@ public void cypherSelectPathsTest() throws SQLException { assertTrue( elements.hasNext() ); PolyNode alice = elements.next().unwrap( PolyNode.class ); assertEquals( alice.getLabels(), List.of( "Person" ) ); - assertEquals( alice.get("name").asString(), "Alice"); + assertEquals( alice.get( "name" ).asString(), "Alice" ); PolyEdge knows = elements.next().unwrap( PolyEdge.class ); assertEquals( knows.getLabels(), List.of( "KNOWS" ) ); PolyNode bob = elements.next().unwrap( PolyNode.class ); assertEquals( bob.getLabels(), List.of( "Person" ) ); - assertEquals( bob.get("name").asString(), "Bob"); + assertEquals( bob.get( "name" ).asString(), "Bob" ); knows = elements.next().unwrap( PolyEdge.class ); assertEquals( knows.getLabels(), List.of( "KNOWS" ) ); PolyNode charlie = elements.next().unwrap( PolyNode.class ); assertEquals( charlie.getLabels(), List.of( "Person" ) ); - assertEquals( charlie.get("name").asString(), "Charlie"); + assertEquals( charlie.get( "name" ).asString(), "Charlie" ); assertFalse( elements.hasNext() ); } @@ -166,5 +179,4 @@ public void cypherRelationalTest() throws SQLException { } } - }