From 01e452898a8bf6d64e8019473ad8d45e6fec52f3 Mon Sep 17 00:00:00 2001 From: Parth Bhore <81606042+Paarth002@users.noreply.github.com> Date: Tue, 12 Nov 2024 21:34:42 +0530 Subject: [PATCH] Add query timeout to database connection (#3218) Co-authored-by: Sai Sriharsha Annepu <72639930+gs-ssh16@users.noreply.github.com> --- .../stores/relational/RelationalExecutor.java | 2 +- .../manager/ConnectionManagerSelector.java | 1 + .../relational/result/SQLExecutionResult.java | 2 +- .../stores/relational/result/SQLResult.java | 7 +- .../relational/result/SQLUpdateResult.java | 5 +- .../connection/TestQueryTimeOut.java | 137 ++++++++++++++++++ ...elationalDatabaseConnectionLexerGrammar.g4 | 1 + ...lationalDatabaseConnectionParserGrammar.g4 | 8 +- ...erRelationalDatabaseConnectionBuilder.java | 6 +- .../RelationalCompilerExtension.java | 2 +- ...onalDatabaseConnectionParseTreeWalker.java | 3 + .../RelationalGrammarComposerExtension.java | 1 + ...ationalConnectionCompilationRoundtrip.java | 4 + ...TestRelationalConnectionGrammarParser.java | 14 ++ ...tRelationalConnectionGrammarRoundtrip.java | 16 ++ .../connection/DatabaseConnection.java | 1 + .../execution_relational_testConnection.pure | 1 + .../v1_33_0/models/metamodel_connection.pure | 1 + .../transfers/connection_relational.pure | 7 +- .../execution_relational_testConnection.pure | 1 + .../vX_X_X/models/metamodel_connection.pure | 1 + .../transfers/connection_relational.pure | 7 +- .../relationalMappingExecution.pure | 9 +- .../service/ServiceTestGenerationHelper.java | 1 + pom.xml | 2 +- 25 files changed, 223 insertions(+), 17 deletions(-) create mode 100644 legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/test/java/org/finos/legend/engine/plan/execution/stores/relational/connection/TestQueryTimeOut.java diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/RelationalExecutor.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/RelationalExecutor.java index 478597f5a83..a53e2ba2555 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/RelationalExecutor.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/RelationalExecutor.java @@ -264,7 +264,7 @@ public SQLUpdateResult execute(RelationalSaveNode node, Identity identity, Execu this.prepareForSQLExecution(node.sqlQuery, node.sqlComment, connectionManagerConnection, databaseTimeZone, databaseType, tempTableList, identity, executionState, false); - return new SQLUpdateResult(executionState.activities, databaseType, connectionManagerConnection, identity, tempTableList, executionState.getRequestContext()); + return new SQLUpdateResult(executionState.activities, databaseType, connectionManagerConnection, node.connection, identity, tempTableList, executionState.getRequestContext()); } private void prepareForSQLExecution(String sqlQuery, String sqlComment, Connection connection, String databaseTimeZone, String databaseTypeName, List tempTableList, Identity identity, ExecutionState executionState, boolean shouldLogSQL) diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/connection/manager/ConnectionManagerSelector.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/connection/manager/ConnectionManagerSelector.java index 5633354375e..2060423929b 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/connection/manager/ConnectionManagerSelector.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/connection/manager/ConnectionManagerSelector.java @@ -140,6 +140,7 @@ public static org.finos.legend.engine.protocol.pure.v1.model.packageableElement. db.type = DatabaseType.H2; db.element = originalConnection.element; db.timeZone = originalConnection instanceof DatabaseConnection ? ((DatabaseConnection) originalConnection).timeZone : null; + db.queryTimeOutInSeconds = originalConnection instanceof DatabaseConnection ? ((DatabaseConnection) originalConnection).queryTimeOutInSeconds : null; db.quoteIdentifiers = originalConnection instanceof DatabaseConnection ? ((DatabaseConnection) originalConnection).quoteIdentifiers : null; return db; } diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/result/SQLExecutionResult.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/result/SQLExecutionResult.java index 8a1899fd164..6f8496c91ba 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/result/SQLExecutionResult.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/result/SQLExecutionResult.java @@ -68,7 +68,7 @@ public SQLExecutionResult(List activities, SQLExecutionNode S public SQLExecutionResult(List activities, SQLExecutionNode SQLExecutionNode, String databaseType, String databaseTimeZone, Connection connection, Identity identity, List temporaryTables, Span topSpan, RequestContext requestContext, boolean logSQLWithParamValues) { - super("success", connection, activities, databaseType, temporaryTables, requestContext); + super("success", connection, SQLExecutionNode.connection, activities, databaseType, temporaryTables, requestContext); this.SQLExecutionNode = SQLExecutionNode; this.databaseTimeZone = databaseTimeZone; this.calendar = new GregorianCalendar(TimeZone.getTimeZone(databaseTimeZone)); diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/result/SQLResult.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/result/SQLResult.java index 4b4ebf034d6..4c39e743f4b 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/result/SQLResult.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/result/SQLResult.java @@ -22,6 +22,7 @@ import org.finos.legend.engine.plan.execution.stores.StoreExecutable; import org.finos.legend.engine.plan.execution.stores.relational.connection.driver.DatabaseManager; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.connection.DatabaseType; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.connection.DatabaseConnection; import org.finos.legend.engine.shared.core.api.request.RequestContext; import org.finos.legend.engine.shared.core.identity.Identity; import org.finos.legend.engine.shared.core.identity.factory.*; @@ -45,7 +46,7 @@ public abstract class SQLResult extends Result implements StoreExecutable private final RequestContext requestContext; - public SQLResult(String status, Connection connection, List activities, String databaseType, List temporaryTables, RequestContext requestContext) + public SQLResult(String status, Connection connection, DatabaseConnection protocolConnection, List activities, String databaseType, List temporaryTables, RequestContext requestContext) { super(status, activities); @@ -61,6 +62,10 @@ public SQLResult(String status, Connection connection, List a { this.statement.setFetchSize(100); } + if (protocolConnection.queryTimeOutInSeconds != null) + { + this.statement.setQueryTimeout(protocolConnection.queryTimeOutInSeconds); + } } catch (Throwable e) { diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/result/SQLUpdateResult.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/result/SQLUpdateResult.java index 1f29cd2295f..94a99dfef1c 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/result/SQLUpdateResult.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/main/java/org/finos/legend/engine/plan/execution/stores/relational/result/SQLUpdateResult.java @@ -19,6 +19,7 @@ import org.finos.legend.engine.plan.execution.stores.relational.activity.RelationalExecutionActivity; import org.finos.legend.engine.shared.core.api.request.RequestContext; import org.finos.legend.engine.shared.core.identity.Identity; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.connection.DatabaseConnection; import org.finos.legend.engine.shared.core.operational.logs.LogInfo; import org.finos.legend.engine.shared.core.operational.logs.LoggingEventType; import org.slf4j.Logger; @@ -32,9 +33,9 @@ public class SQLUpdateResult extends SQLResult private final int updateCount; - public SQLUpdateResult(List activities, String databaseType, Connection connection, Identity identity, List temporaryTables, RequestContext requestContext) + public SQLUpdateResult(List activities, String databaseType, Connection connection, DatabaseConnection dbConnection, Identity identity, List temporaryTables, RequestContext requestContext) { - super("success", connection, activities, databaseType, temporaryTables, requestContext); + super("success", connection, dbConnection, activities, databaseType, temporaryTables, requestContext); try { long start = System.currentTimeMillis(); diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/test/java/org/finos/legend/engine/plan/execution/stores/relational/connection/TestQueryTimeOut.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/test/java/org/finos/legend/engine/plan/execution/stores/relational/connection/TestQueryTimeOut.java new file mode 100644 index 00000000000..f3e47479d77 --- /dev/null +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-execution/legend-engine-xt-relationalStore-executionPlan/src/test/java/org/finos/legend/engine/plan/execution/stores/relational/connection/TestQueryTimeOut.java @@ -0,0 +1,137 @@ +// Copyright 2022 Goldman Sachs +// +// 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.finos.legend.engine.plan.execution.stores.relational.connection; + +import org.eclipse.collections.api.factory.Maps; +import org.finos.legend.engine.protocol.pure.v1.model.executionPlan.SingleExecutionPlan; +import org.junit.Assert; +import org.junit.Test; + +import java.sql.SQLException; +import java.sql.Statement; +import java.time.LocalDate; +import java.time.LocalDateTime; + +public class TestQueryTimeOut extends AlloyTestServer +{ + + private static final String TEST_FUNCTION = "###Pure\n" + + "function test::fetch(): Any[1]\n" + + "{\n" + + " {names:String[*] | test::Person.all()\n" + + " ->project([x | $x.fullName, x | $x.firmName], ['fullName', 'firmName'])\n" + + " ->extend([col(row:TDSRow[1] | $row.getString('fullName'), 'string')])\n" + + " ->olapGroupBy(['fullName'], asc('firmName'), func(y | $y->meta::pure::functions::math::olap::rank()), 'RANK 1')\n" + + " ->olapGroupBy(['fullName'], desc('firmName'), func(y | $y->meta::pure::functions::math::olap::rowNumber()), 'ROW 1')\n" + + " ->olapGroupBy(['fullName'], asc('firmName'), func(y | $y->meta::pure::functions::math::olap::denseRank()), 'DENSE RANK 1')\n" + + " ->olapGroupBy(['fullName'], desc('firmName'), func(y | $y->meta::pure::functions::math::olap::rank()), 'RANK 2')\n" + + " ->olapGroupBy(['firmName'], asc('fullName'), func(y | $y->meta::pure::functions::math::olap::rank()), 'RANK 3')\n" + + " ->olapGroupBy(['firmName'], desc('fullName'), func(y | $y->meta::pure::functions::math::olap::rowNumber()), 'ROW 2')\n" + + " ->olapGroupBy(['firmName'], asc('fullName'), func(y | $y->meta::pure::functions::math::olap::denseRank()), 'DENSE RANK 2')\n" + + " ->olapGroupBy(['firmName'], desc('fullName'), func(y | $y->meta::pure::functions::math::olap::rank()), 'RANK 3')\n" + + " }\n" + + "}"; + + private static final String LOGICAL_MODEL = "###Pure\n" + + "Class test::Person\n" + + "{\n" + + " fullName: String[1];\n" + + " addressName: String[1];\n" + + " firmName: String[1];\n" + + "}\n\n\n"; + + private static final String STORE_MODEL = "###Relational\n" + + "Database test::DB\n" + + "(\n" + + " Table PERSON (\n" + + " fullName VARCHAR(100) PRIMARY KEY,\n" + + " firmName VARCHAR(100),\n" + + " addressName VARCHAR(100)\n" + + " )\n" + + ")\n\n\n"; + + private static final String MAPPING = "###Mapping\n" + + "Mapping test::Map\n" + + "(\n" + + " test::Person: Relational\n" + + " {\n" + + " ~primaryKey\n" + + " (\n" + + " [test::DB]PERSON.fullName\n" + + " )\n" + + " ~mainTable [test::DB]PERSON\n" + + " fullName: [test::DB]PERSON.fullName,\n" + + " firmName: [test::DB]PERSON.firmName,\n" + + " addressName: [test::DB]PERSON.addressName\n" + + " }\n" + + ")\n\n\n"; + + private static final String RUNTIME = "###Runtime\n" + + "Runtime test::Runtime\n" + + "{\n" + + " mappings:\n" + + " [\n" + + " test::Map\n" + + " ];\n" + + " connections:\n" + + " [\n" + + " test::DB:\n" + + " [\n" + + " c1: #{\n" + + " RelationalDatabaseConnection\n" + + " {\n" + + " type: H2;\n" + + " specification: LocalH2 {};\n" + + " auth: DefaultH2;\n" + + " queryTimeOutInSeconds: 1;\n" + + " }\n" + + " }#\n" + + " ]\n" + + " ];\n" + + "}\n"; + + public static final String TEST_EXECUTION_PLAN = LOGICAL_MODEL + STORE_MODEL + MAPPING + RUNTIME + TEST_FUNCTION; + + + @Override + protected void insertTestData(Statement statement) throws SQLException + { + statement.execute("Drop table if exists PERSON;"); + statement.execute("Create Table PERSON(fullName VARCHAR(100) NOT NULL,firmName VARCHAR(100) NULL,addressName VARCHAR(100) NULL,PRIMARY KEY(fullName));"); + + Integer personTableLength = 100000; + for (int i = 1; i <= personTableLength; i++) + { + statement.execute(String.format("insert into PERSON (fullName,firmName,addressName) values ('fullName%d','firmName%d','addressName%d');", personTableLength - i, i, personTableLength - i)); + } + } + + @Test + public void testQueryTimeOutInSeconds() + { + try + { + SingleExecutionPlan executionPlan = buildPlan(TEST_EXECUTION_PLAN); + Assert.assertNotNull(executionPlan); + Assert.assertNotNull(executePlan(executionPlan, Maps.mutable.empty())); + } + catch (Exception e) + { + Assert.assertEquals("org.h2.jdbc.JdbcSQLTimeoutException: Statement was canceled or the session timed out; SQL statement:", e.getMessage().substring(0, e.getMessage().indexOf('\n'))); + return; + } + Assert.fail("Cannot test QueryTimeOut as query runs for less than 1 second"); + } +} diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/antlr4/org/finos/legend/engine/language/pure/grammar/from/antlr4/connection/RelationalDatabaseConnectionLexerGrammar.g4 b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/antlr4/org/finos/legend/engine/language/pure/grammar/from/antlr4/connection/RelationalDatabaseConnectionLexerGrammar.g4 index 1993d4d0357..ab414bc3941 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/antlr4/org/finos/legend/engine/language/pure/grammar/from/antlr4/connection/RelationalDatabaseConnectionLexerGrammar.g4 +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/antlr4/org/finos/legend/engine/language/pure/grammar/from/antlr4/connection/RelationalDatabaseConnectionLexerGrammar.g4 @@ -11,6 +11,7 @@ MODE: 'mode'; RELATIONAL_DATASOURCE_SPEC: 'specification'; RELATIONAL_AUTH_STRATEGY: 'auth'; RELATIONAL_POST_PROCESSORS: 'postProcessors'; +QUERY_TIMEOUT: 'queryTimeOutInSeconds'; DB_TIMEZONE: 'timezone'; TIMEZONE: TimeZone; diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/antlr4/org/finos/legend/engine/language/pure/grammar/from/antlr4/connection/RelationalDatabaseConnectionParserGrammar.g4 b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/antlr4/org/finos/legend/engine/language/pure/grammar/from/antlr4/connection/RelationalDatabaseConnectionParserGrammar.g4 index 7d9a4b1c8c4..8f1a76287cf 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/antlr4/org/finos/legend/engine/language/pure/grammar/from/antlr4/connection/RelationalDatabaseConnectionParserGrammar.g4 +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/antlr4/org/finos/legend/engine/language/pure/grammar/from/antlr4/connection/RelationalDatabaseConnectionParserGrammar.g4 @@ -12,7 +12,7 @@ options identifier: VALID_STRING | STRING | STORE - | TYPE | RELATIONAL_DATASOURCE_SPEC | RELATIONAL_AUTH_STRATEGY + | TYPE | QUERY_TIMEOUT | RELATIONAL_DATASOURCE_SPEC | RELATIONAL_AUTH_STRATEGY | DB_TIMEZONE | QUOTE_IDENTIFIERS ; @@ -22,6 +22,7 @@ identifier: VALID_STRING | STRING definition: ( connectionStore | dbType + | queryTimeOutInSeconds | connectionMode | dbConnectionTimezone | dbQuoteIdentifiers @@ -39,6 +40,8 @@ dbQuoteIdentifiers: QUOTE_IDENTIFIERS COLON BOOLEAN SEMI_COL ; dbType: TYPE COLON identifier SEMI_COLON ; +queryTimeOutInSeconds: QUERY_TIMEOUT COLON INTEGER SEMI_COLON +; connectionMode: MODE COLON identifier SEMI_COLON ; @@ -67,4 +70,5 @@ specificationValueBody: BRACE_OPEN (specificationValue)* ; specificationValue: SPECIFICATION_BRACE_OPEN | SPECIFICATION_CONTENT | SPECIFICATION_BRACE_CLOSE -; \ No newline at end of file +; + diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/HelperRelationalDatabaseConnectionBuilder.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/HelperRelationalDatabaseConnectionBuilder.java index 4b06754cf94..346d5f55dbb 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/HelperRelationalDatabaseConnectionBuilder.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/HelperRelationalDatabaseConnectionBuilder.java @@ -42,10 +42,14 @@ public static void addTestDataSetUp(Root_meta_external_store_relational_runtime_ } } - public static void addDatabaseConnectionProperties(Root_meta_external_store_relational_runtime_DatabaseConnection pureConnection, String element, SourceInformation elementSourceInformation, String connectionType, String timeZone, Boolean quoteIdentifiers, CompileContext context) + public static void addDatabaseConnectionProperties(Root_meta_external_store_relational_runtime_DatabaseConnection pureConnection, String element, SourceInformation elementSourceInformation, String connectionType, String timeZone, Integer queryTimeOutInSeconds, Boolean quoteIdentifiers, CompileContext context) { Root_meta_external_store_relational_runtime_DatabaseConnection connection = pureConnection._type(context.pureModel.getEnumValue("meta::relational::runtime::DatabaseType", connectionType)); connection._timeZone(timeZone); + if (queryTimeOutInSeconds != null) + { + connection._queryTimeOutInSeconds(Long.valueOf(queryTimeOutInSeconds)); + } connection._quoteIdentifiers(quoteIdentifiers); if (element != null) { diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/RelationalCompilerExtension.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/RelationalCompilerExtension.java index 5738b689924..0e9fa59e97c 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/RelationalCompilerExtension.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/compiler/toPureGraph/RelationalCompilerExtension.java @@ -451,7 +451,7 @@ public List extensions = IRelationalCompilerExtension.getExtensions(context); diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/from/RelationalDatabaseConnectionParseTreeWalker.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/from/RelationalDatabaseConnectionParseTreeWalker.java index 848debb5114..252ec56c4d5 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/from/RelationalDatabaseConnectionParseTreeWalker.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/from/RelationalDatabaseConnectionParseTreeWalker.java @@ -61,6 +61,9 @@ public void visitRelationalDatabaseConnectionValue(RelationalDatabaseConnectionP { throw new EngineException("Unknown database type '" + PureGrammarParserUtility.fromIdentifier(dbTypeCtx.identifier()) + "'", this.walkerSourceInformation.getSourceInformation(dbTypeCtx), EngineErrorType.PARSER); } + //queryTimeoutInSeconds (optional) + RelationalDatabaseConnectionParserGrammar.QueryTimeOutInSecondsContext queryTimeOutInSecondsCtx = PureGrammarParserUtility.validateAndExtractOptionalField(ctx.queryTimeOutInSeconds(), "queryTimeOutInSeconds", connectionValue.sourceInformation); + connectionValue.queryTimeOutInSeconds = queryTimeOutInSecondsCtx != null ? Integer.parseInt(queryTimeOutInSecondsCtx.INTEGER().getText()) : null; // timezone (optional) RelationalDatabaseConnectionParserGrammar.DbConnectionTimezoneContext timezoneCtx = PureGrammarParserUtility.validateAndExtractOptionalField(ctx.dbConnectionTimezone(), "timezone", connectionValue.sourceInformation); connectionValue.timeZone = timezoneCtx != null ? timezoneCtx.TIMEZONE().getText() : null; diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/to/RelationalGrammarComposerExtension.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/to/RelationalGrammarComposerExtension.java index a07d5bd1ef1..408044f0f24 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/to/RelationalGrammarComposerExtension.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-grammar/src/main/java/org/finos/legend/engine/language/pure/grammar/to/RelationalGrammarComposerExtension.java @@ -246,6 +246,7 @@ public List postProcessorWithParameter = Collections.emptyList(); } diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/v1_33_0/invocations/execution_relational_testConnection.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/v1_33_0/invocations/execution_relational_testConnection.pure index baec4cb25e3..e05f26a0877 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/v1_33_0/invocations/execution_relational_testConnection.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/v1_33_0/invocations/execution_relational_testConnection.pure @@ -91,6 +91,7 @@ function meta::protocols::pure::v1_33_0::transformation::toPureGraph::connection ^meta::external::store::relational::runtime::RelationalDatabaseConnection( timeZone = $conn.timeZone, quoteIdentifiers = $conn.quoteIdentifiers, + queryTimeOutInSeconds = $conn.queryTimeOutInSeconds, type = $type, datasourceSpecification = $conn.datasourceSpecification->meta::protocols::pure::v1_33_0::transformation::toPureGraph::connection::transformDatasourceSpecification($extensions), authenticationStrategy = $conn.authenticationStrategy->meta::protocols::pure::v1_33_0::transformation::toPureGraph::connection::transformAuthenticationStrategy($extensions), diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/v1_33_0/models/metamodel_connection.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/v1_33_0/models/metamodel_connection.pure index bf6b043c3cb..c755e30d0ab 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/v1_33_0/models/metamodel_connection.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/v1_33_0/models/metamodel_connection.pure @@ -96,6 +96,7 @@ Class meta::protocols::pure::v1_33_0::metamodel::store::relational::connection:: type : String[1]; timeZone : String[0..1]; quoteIdentifiers : Boolean[0..1]; + queryTimeOutInSeconds: Integer[0..1]; postProcessorWithParameter: meta::protocols::pure::v1_33_0::metamodel::store::relational::PostProcessorWithParameter[*]; } diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/v1_33_0/transfers/connection_relational.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/v1_33_0/transfers/connection_relational.pure index a2117ead3eb..e141ae42b2e 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/v1_33_0/transfers/connection_relational.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/v1_33_0/transfers/connection_relational.pure @@ -43,6 +43,7 @@ function meta::protocols::pure::v1_33_0::transformation::fromPureGraph::connecti type = $type, timeZone = $test.timeZone, quoteIdentifiers = $test.quoteIdentifiers, + queryTimeOutInSeconds = $test.queryTimeOutInSeconds, element = $element, datasourceSpecification = ^meta::protocols::pure::v1_33_0::metamodel::store::relational::connection::alloy::specification::LocalH2DatasourceSpecification( _type = 'h2Local', @@ -56,12 +57,13 @@ function meta::protocols::pure::v1_33_0::transformation::fromPureGraph::connecti ), relational:meta::external::store::relational::runtime::RelationalDatabaseConnection[1] | let processors = transformPostProcessors($relational.postProcessors, $extensions); - relational($type, $element, $relational.timeZone, $relational.quoteIdentifiers, $processors, $relational.datasourceSpecification, $relational.authenticationStrategy, $extensions);, + relational($type, $element, $relational.timeZone, $relational.quoteIdentifiers, $relational.queryTimeOutInSeconds, $processors, $relational.datasourceSpecification, $relational.authenticationStrategy, $extensions);, dbCon:meta::external::store::relational::runtime::DatabaseConnection[1]| ^meta::protocols::pure::v1_33_0::metamodel::store::relational::connection::DatabaseConnection( _type = $_type, timeZone = $dbCon.timeZone, quoteIdentifiers = $dbCon.quoteIdentifiers, + queryTimeOutInSeconds = $dbCon.queryTimeOutInSeconds, element = $element, postProcessorWithParameter = $postProcessorsWithParams, type = $type) @@ -101,7 +103,7 @@ function meta::protocols::pure::v1_33_0::transformation::fromPureGraph::connecti ) } -function meta::protocols::pure::v1_33_0::transformation::fromPureGraph::connection::relational(type:String[1], element:String[1], timeZone:String[0..1], quoteIdentifiers:Boolean[0..1], +function meta::protocols::pure::v1_33_0::transformation::fromPureGraph::connection::relational(type:String[1], element:String[1], timeZone:String[0..1], quoteIdentifiers:Boolean[0..1], queryTimeOutInSeconds: Integer[0..1], processors:meta::protocols::pure::v1_33_0::metamodel::store::relational::postProcessor::PostProcessor[*], spec:meta::pure::alloy::connections::alloy::specification::DatasourceSpecification[1], auth:meta::pure::alloy::connections::alloy::authentication::AuthenticationStrategy[1], @@ -111,6 +113,7 @@ function meta::protocols::pure::v1_33_0::transformation::fromPureGraph::connecti _type = 'RelationalDatabaseConnection', timeZone = $timeZone, quoteIdentifiers = $quoteIdentifiers, + queryTimeOutInSeconds = $queryTimeOutInSeconds, element = $element, type = $type, datasourceSpecification = $spec->meta::protocols::pure::v1_33_0::transformation::fromPureGraph::connection::transformDatasourceSpecification($extensions), diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/vX_X_X/invocations/execution_relational_testConnection.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/vX_X_X/invocations/execution_relational_testConnection.pure index 009607d477c..687654f14ae 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/vX_X_X/invocations/execution_relational_testConnection.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/vX_X_X/invocations/execution_relational_testConnection.pure @@ -91,6 +91,7 @@ function meta::protocols::pure::vX_X_X::transformation::toPureGraph::connection: connection=^meta::external::store::relational::runtime::RelationalDatabaseConnection( timeZone = $conn.timeZone, quoteIdentifiers = $conn.quoteIdentifiers, + queryTimeOutInSeconds = $conn.queryTimeOutInSeconds, type = $type, datasourceSpecification = $conn.datasourceSpecification->meta::protocols::pure::vX_X_X::transformation::toPureGraph::connection::transformDatasourceSpecification($extensions), authenticationStrategy = $conn.authenticationStrategy->meta::protocols::pure::vX_X_X::transformation::toPureGraph::connection::transformAuthenticationStrategy($extensions), diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/vX_X_X/models/metamodel_connection.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/vX_X_X/models/metamodel_connection.pure index 2cf66190f14..3942512ef55 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/vX_X_X/models/metamodel_connection.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/vX_X_X/models/metamodel_connection.pure @@ -96,6 +96,7 @@ Class meta::protocols::pure::vX_X_X::metamodel::store::relational::connection::D type : String[1]; timeZone : String[0..1]; quoteIdentifiers : Boolean[0..1]; + queryTimeOutInSeconds: Integer[0..1]; postProcessorWithParameter: meta::protocols::pure::vX_X_X::metamodel::store::relational::PostProcessorWithParameter[*]; } diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/vX_X_X/transfers/connection_relational.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/vX_X_X/transfers/connection_relational.pure index 1b3282c848b..192ff5b3fdc 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/vX_X_X/transfers/connection_relational.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/protocols/pure/vX_X_X/transfers/connection_relational.pure @@ -43,6 +43,7 @@ function meta::protocols::pure::vX_X_X::transformation::fromPureGraph::connectio type = $type, timeZone = $test.timeZone, quoteIdentifiers = $test.quoteIdentifiers, + queryTimeOutInSeconds = $test.queryTimeOutInSeconds, element = $element, datasourceSpecification = ^meta::protocols::pure::vX_X_X::metamodel::store::relational::connection::alloy::specification::LocalH2DatasourceSpecification( _type = 'h2Local', @@ -56,12 +57,13 @@ function meta::protocols::pure::vX_X_X::transformation::fromPureGraph::connectio ), relational:meta::external::store::relational::runtime::RelationalDatabaseConnection[1] | let processors = transformPostProcessors($relational.postProcessors, $extensions); - relational($type, $element, $relational.timeZone, $relational.quoteIdentifiers, $processors, $relational.datasourceSpecification, $relational.authenticationStrategy, $extensions);, + relational($type, $element, $relational.timeZone, $relational.quoteIdentifiers, $relational.queryTimeOutInSeconds, $processors, $relational.datasourceSpecification, $relational.authenticationStrategy, $extensions);, dbCon:meta::external::store::relational::runtime::DatabaseConnection[1]| ^meta::protocols::pure::vX_X_X::metamodel::store::relational::connection::DatabaseConnection( _type = $_type, timeZone = $dbCon.timeZone, quoteIdentifiers = $dbCon.quoteIdentifiers, + queryTimeOutInSeconds = $dbCon.queryTimeOutInSeconds, element = $element, postProcessorWithParameter = $postProcessorsWithParams, type = $type) @@ -101,7 +103,7 @@ function meta::protocols::pure::vX_X_X::transformation::fromPureGraph::connectio ) } -function meta::protocols::pure::vX_X_X::transformation::fromPureGraph::connection::relational(type:String[1], element:String[1], timeZone:String[0..1], quoteIdentifiers:Boolean[0..1], +function meta::protocols::pure::vX_X_X::transformation::fromPureGraph::connection::relational(type:String[1], element:String[1], timeZone:String[0..1], quoteIdentifiers:Boolean[0..1], queryTimeOutInSeconds: Integer[0..1], processors:meta::protocols::pure::vX_X_X::metamodel::store::relational::postProcessor::PostProcessor[*], spec:meta::pure::alloy::connections::alloy::specification::DatasourceSpecification[1], auth:meta::pure::alloy::connections::alloy::authentication::AuthenticationStrategy[1], @@ -111,6 +113,7 @@ function meta::protocols::pure::vX_X_X::transformation::fromPureGraph::connectio _type = 'RelationalDatabaseConnection', timeZone = $timeZone, quoteIdentifiers = $quoteIdentifiers, + queryTimeOutInSeconds = $queryTimeOutInSeconds, element = $element, type = $type, datasourceSpecification = $spec->meta::protocols::pure::vX_X_X::transformation::fromPureGraph::connection::transformDatasourceSpecification($extensions), diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/relationalMappingExecution.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/relationalMappingExecution.pure index 6fbc568466d..793c42e028a 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/relationalMappingExecution.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/legend-engine-xt-relationalStore-core-pure/src/main/resources/core_relational/relational/relationalMappingExecution.pure @@ -367,9 +367,12 @@ function meta::relational::mapping::executeQuery(sql:String[1], query:SQLQuery[0 print(if(!$debug.debug, |'', | $debug.space+'>Execute SQL: '+$sql+'\n')); let queryTimeOutInSeconds = if($g_queryTimeOutInSeconds->isNotEmpty(), - | $g_queryTimeOutInSeconds->toOne(), - | 3600 //1 hour - ); + | $g_queryTimeOutInSeconds->toOne(), + | if($connection.queryTimeOutInSeconds->isNotEmpty(), + | $connection.queryTimeOutInSeconds->toOne(), + | 3600 + ); + ); let sqlComment = sqlCommentPureExecution(); let res = executeInDb($sqlComment + '\n' + $sql, $connection->cast(@DatabaseConnection), $queryTimeOutInSeconds, 1000); //let res = ^ResultSet(connectionAcquisitionTimeInNanoSecond=1,executionTimeInNanoSecond=2); diff --git a/legend-engine-xts-service/legend-engine-test-runner-service/src/main/java/org/finos/legend/engine/test/runner/service/ServiceTestGenerationHelper.java b/legend-engine-xts-service/legend-engine-test-runner-service/src/main/java/org/finos/legend/engine/test/runner/service/ServiceTestGenerationHelper.java index 81bbab9b22c..e54051edfef 100644 --- a/legend-engine-xts-service/legend-engine-test-runner-service/src/main/java/org/finos/legend/engine/test/runner/service/ServiceTestGenerationHelper.java +++ b/legend-engine-xts-service/legend-engine-test-runner-service/src/main/java/org/finos/legend/engine/test/runner/service/ServiceTestGenerationHelper.java @@ -449,6 +449,7 @@ private static Connection newRelationalConnection(Connection connection, String if (connection instanceof DatabaseConnection) { relationalDatabaseConnection.timeZone = ((DatabaseConnection) connection).timeZone; + relationalDatabaseConnection.queryTimeOutInSeconds = ((DatabaseConnection) connection).queryTimeOutInSeconds; } LocalH2DatasourceSpecification localH2DatasourceSpecification = new LocalH2DatasourceSpecification(); diff --git a/pom.xml b/pom.xml index 8a458183e36..3fd700bfeb7 100644 --- a/pom.xml +++ b/pom.xml @@ -107,7 +107,7 @@ - 5.21.2 + 5.22.0 0.25.7 12.59.0