From eb6c63684186cbc6b6e0be821de0ec5ea49f1acf Mon Sep 17 00:00:00 2001 From: Mohammed Ibrahim Date: Fri, 15 Sep 2023 10:51:39 -0400 Subject: [PATCH 01/10] Uplift Service Ownership --- .../pom.xml | 7 +++ .../ownership/OwnershipValidator.java | 32 +++++++++++ .../core_service/service/metamodel.pure | 18 +++++- .../from/antlr4/ServiceLexerGrammar.g4 | 6 +- .../from/antlr4/ServiceParserGrammar.g4 | 25 +++++++- .../toPureGraph/HelperServiceBuilder.java | 16 ++++++ .../ServiceCompilerExtensionImpl.java | 30 +++++++--- .../grammar/from/ServiceParseTreeWalker.java | 30 ++++++++++ .../to/ServiceGrammarComposerExtension.java | 24 ++++++++ .../pure/v1/ServiceProtocolExtension.java | 7 +++ .../service/DeploymentOwnership.java | 31 ++++++++++ .../packageableElement/service/Ownership.java | 28 +++++++++ .../packageableElement/service/Service.java | 4 +- .../service/UserListOwnership.java | 23 ++++++++ .../TestServiceCompilationFromGrammar.java | 57 +++++++++++++++++++ .../test/TestServiceGrammarRoundtrip.java | 29 ++++++++++ 16 files changed, 356 insertions(+), 11 deletions(-) create mode 100644 legend-engine-xts-service/legend-engine-language-pure-dsl-service-generation/src/main/java/org/finos/legend/engine/language/pure/dsl/service/generation/ownership/OwnershipValidator.java create mode 100644 legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/packageableElement/service/DeploymentOwnership.java create mode 100644 legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/packageableElement/service/Ownership.java create mode 100644 legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/packageableElement/service/UserListOwnership.java diff --git a/legend-engine-xts-service/legend-engine-language-pure-dsl-service-generation/pom.xml b/legend-engine-xts-service/legend-engine-language-pure-dsl-service-generation/pom.xml index 900bf6f0733..7562e60ffb5 100644 --- a/legend-engine-xts-service/legend-engine-language-pure-dsl-service-generation/pom.xml +++ b/legend-engine-xts-service/legend-engine-language-pure-dsl-service-generation/pom.xml @@ -97,6 +97,13 @@ + + + org.pac4j + pac4j-core + + + com.fasterxml.jackson.core diff --git a/legend-engine-xts-service/legend-engine-language-pure-dsl-service-generation/src/main/java/org/finos/legend/engine/language/pure/dsl/service/generation/ownership/OwnershipValidator.java b/legend-engine-xts-service/legend-engine-language-pure-dsl-service-generation/src/main/java/org/finos/legend/engine/language/pure/dsl/service/generation/ownership/OwnershipValidator.java new file mode 100644 index 00000000000..95e6fc2fc81 --- /dev/null +++ b/legend-engine-xts-service/legend-engine-language-pure-dsl-service-generation/src/main/java/org/finos/legend/engine/language/pure/dsl/service/generation/ownership/OwnershipValidator.java @@ -0,0 +1,32 @@ +// Copyright 2023 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.language.pure.dsl.service.generation.ownership; + +import org.eclipse.collections.api.list.MutableList; +import org.finos.legend.pure.generated.Root_meta_legend_service_metamodel_Ownership; +import org.pac4j.core.profile.CommonProfile; + +public interface OwnershipValidator +{ + boolean supports(Root_meta_legend_service_metamodel_Ownership ownership); + + boolean validate(MutableList profiles, Root_meta_legend_service_metamodel_Ownership ownership); + + boolean isOwner(MutableList profiles, Root_meta_legend_service_metamodel_Ownership ownership); + + String authorizationFailureMessage(MutableList profiles, Root_meta_legend_service_metamodel_Ownership ownership); + + void clearCache(); +} diff --git a/legend-engine-xts-service/legend-engine-language-pure-dsl-service-pure/src/main/resources/core_service/service/metamodel.pure b/legend-engine-xts-service/legend-engine-language-pure-dsl-service-pure/src/main/resources/core_service/service/metamodel.pure index 197be57c9f3..059f3edf721 100644 --- a/legend-engine-xts-service/legend-engine-language-pure-dsl-service-pure/src/main/resources/core_service/service/metamodel.pure +++ b/legend-engine-xts-service/legend-engine-language-pure-dsl-service-pure/src/main/resources/core_service/service/metamodel.pure @@ -34,7 +34,8 @@ Class meta::legend::service::metamodel::Service extends PackageableElement, meta ] { pattern : String[1]; - owners : String[*]; + <> owners : String[*]; + ownership: Ownership[0..1]; autoActivateUpdates : Boolean[1]; documentation : String[1]; execution : Execution[1]; @@ -44,6 +45,21 @@ Class meta::legend::service::metamodel::Service extends PackageableElement, meta <> test: Test[0..1]; } +Class <> meta::legend::service::metamodel::Ownership +{ + +} + +Class meta::legend::service::metamodel::DeploymentOwner extends Ownership +{ + identifier: String[1]; +} + +Class meta::legend::service::metamodel::UserListOwner extends Ownership +{ + users: String[*]; +} + Class meta::legend::service::metamodel::ServiceTag { name: String[1]; diff --git a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/antlr4/org/finos/legend/engine/language/pure/grammar/from/antlr4/ServiceLexerGrammar.g4 b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/antlr4/org/finos/legend/engine/language/pure/grammar/from/antlr4/ServiceLexerGrammar.g4 index 8cdb07b67a1..ff3b2329de4 100644 --- a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/antlr4/org/finos/legend/engine/language/pure/grammar/from/antlr4/ServiceLexerGrammar.g4 +++ b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/antlr4/org/finos/legend/engine/language/pure/grammar/from/antlr4/ServiceLexerGrammar.g4 @@ -18,7 +18,11 @@ SERVICE_PATTERN: 'pattern'; SERVICE_OWNERS: 'owners'; SERVICE_DOCUMENTATION: 'documentation'; SERVICE_AUTO_ACTIVATE_UPDATES: 'autoActivateUpdates'; - +SERVICE_OWNERSHIP: 'ownership'; +SERVICE_OWNERSHIP_DEPLOYMENT: 'DID'; +SERVICE_OWNERSHIP_DEPLOYMENT_ID: 'identifier'; +SERVICE_OWNERSHIP_USERLIST: 'UserList'; +SERVICE_OWNERSHIP_USERLIST_USERS: 'users'; SERVICE_EXECUTION: 'execution'; SERVICE_EXECUTION_EXECUTIONS: 'executions'; SERVICE_FUNCTION: 'query'; diff --git a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/antlr4/org/finos/legend/engine/language/pure/grammar/from/antlr4/ServiceParserGrammar.g4 b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/antlr4/org/finos/legend/engine/language/pure/grammar/from/antlr4/ServiceParserGrammar.g4 index 1e583cde411..7122a543620 100644 --- a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/antlr4/org/finos/legend/engine/language/pure/grammar/from/antlr4/ServiceParserGrammar.g4 +++ b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/antlr4/org/finos/legend/engine/language/pure/grammar/from/antlr4/ServiceParserGrammar.g4 @@ -15,7 +15,8 @@ identifier: VALID_STRING | STRING | STEREOTYPES | TAGS | SERVICE | IMPORT | SERVICE_SINGLE | SERVICE_MULTI - | SERVICE_PATTERN | SERVICE_OWNERS | SERVICE_DOCUMENTATION | SERVICE_AUTO_ACTIVATE_UPDATES + | SERVICE_PATTERN | SERVICE_OWNERS | SERVICE_DOCUMENTATION | SERVICE_AUTO_ACTIVATE_UPDATES | SERVICE_OWNERSHIP + | SERVICE_OWNERSHIP_DEPLOYMENT | SERVICE_OWNERSHIP_DEPLOYMENT_ID | SERVICE_OWNERSHIP_USERLIST | SERVICE_OWNERSHIP_USERLIST_USERS | SERVICE_EXECUTION | SERVICE_FUNCTION | SERVICE_EXECUTION_KEY | SERVICE_EXECUTION_EXECUTIONS | SERVICE_RUNTIME | SERVICE_MAPPING | SERVICE_TEST_SUITES | SERVICE_TEST_DATA | SERVICE_TEST_CONNECTION_DATA | SERVICE_TEST_TESTS | SERVICE_TEST_ASSERTS | SERVICE_TEST_PARAMETERS | SERVICE_TEST_SERIALIZATION_FORMAT | SERVICE_TEST | PARAM_GROUP | ASSERT_FOR_KEYS | SERVICE_POST_VALIDATION | SERVICE_POST_VALIDATION_DESCRIPTION @@ -39,6 +40,7 @@ service: SERVICE stereotypes? taggedValues? quali ( servicePattern | serviceOwners + | serviceOwnership | serviceDocumentation | serviceAutoActivateUpdates | serviceExec @@ -64,6 +66,27 @@ serviceOwners: SERVICE_OWNERS COLON BRACKET_CLOSE SEMI_COLON ; + +serviceOwnership: SERVICE_OWNERSHIP COLON + (deployment | userList) + SEMI_COLON +; + +deployment: SERVICE_OWNERSHIP_DEPLOYMENT + BRACE_OPEN + SERVICE_OWNERSHIP_DEPLOYMENT_ID COLON STRING + BRACE_CLOSE +; + +userList: SERVICE_OWNERSHIP_USERLIST + BRACE_OPEN + SERVICE_OWNERSHIP_USERLIST_USERS COLON + BRACKET_OPEN + (STRING (COMMA STRING)*)? + BRACKET_CLOSE + BRACE_CLOSE +; + serviceDocumentation: SERVICE_DOCUMENTATION COLON STRING SEMI_COLON ; serviceAutoActivateUpdates: SERVICE_AUTO_ACTIVATE_UPDATES COLON BOOLEAN SEMI_COLON diff --git a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/language/pure/dsl/service/compiler/toPureGraph/HelperServiceBuilder.java b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/language/pure/dsl/service/compiler/toPureGraph/HelperServiceBuilder.java index 32be3755ae1..3ab4fbf052c 100644 --- a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/language/pure/dsl/service/compiler/toPureGraph/HelperServiceBuilder.java +++ b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/language/pure/dsl/service/compiler/toPureGraph/HelperServiceBuilder.java @@ -44,6 +44,22 @@ public static List getServiceCompilerExtensions(Compil return ListIterate.selectInstancesOf(context.getCompilerExtensions().getExtensions(), ServiceCompilerExtension.class); } + public static Root_meta_legend_service_metamodel_Ownership processOwnershipModel(Ownership o) + { + if (o instanceof DeploymentOwnership) + { + return new Root_meta_legend_service_metamodel_DeploymentOwner_Impl("")._identifier(((DeploymentOwnership) o).identifier); + } + else if (o instanceof UserListOwnership) + { + return new Root_meta_legend_service_metamodel_UserListOwner_Impl("")._usersAddAll(Lists.mutable.withAll(((UserListOwnership) o).users)); + } + else + { + throw new EngineException("Ownership model not supported. Type: " + o.getClass().getSimpleName(), EngineErrorType.COMPILATION); + } + } + private static void inferEmbeddedRuntimeMapping(org.finos.legend.engine.protocol.pure.v1.model.packageableElement.runtime.Runtime runtime, String mappingPath) { // If the runtime is embedded and no mapping is specified, we will take the mapping of the execution as the mapping for the runtime diff --git a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/language/pure/dsl/service/compiler/toPureGraph/ServiceCompilerExtensionImpl.java b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/language/pure/dsl/service/compiler/toPureGraph/ServiceCompilerExtensionImpl.java index 32a0cad49af..b8489548c9b 100644 --- a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/language/pure/dsl/service/compiler/toPureGraph/ServiceCompilerExtensionImpl.java +++ b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/language/pure/dsl/service/compiler/toPureGraph/ServiceCompilerExtensionImpl.java @@ -57,6 +57,8 @@ import java.util.Map; import java.util.stream.Collectors; +import static org.finos.legend.engine.language.pure.dsl.service.compiler.toPureGraph.HelperServiceBuilder.processOwnershipModel; + public class ServiceCompilerExtensionImpl implements ServiceCompilerExtension { @Override @@ -72,13 +74,7 @@ public Iterable> getExtraProcessors() Processor.newProcessor( Service.class, Lists.fixedSize.with(PackageableConnection.class, PackageableRuntime.class, DataElement.class, ExecutionEnvironmentInstance.class), - (service, context) -> new Root_meta_legend_service_metamodel_Service_Impl(service.name, null, context.pureModel.getClass("meta::legend::service::metamodel::Service")) - ._name(service.name) - ._stereotypes(ListIterate.collect(service.stereotypes, s -> context.resolveStereotype(s.profile, s.value, s.profileSourceInformation, s.sourceInformation))) - ._taggedValues(ListIterate.collect(service.taggedValues, t -> new Root_meta_pure_metamodel_extension_TaggedValue_Impl("", null, context.pureModel.getClass("meta::pure::metamodel::extension::TaggedValue"))._tag(context.resolveTag(t.tag.profile, t.tag.value, t.tag.profileSourceInformation, t.tag.sourceInformation))._value(t.value))) - ._pattern(service.pattern) - ._owners(Lists.mutable.withAll(service.owners)) - ._documentation(service.documentation), + (service, context) -> processserviceFirstPass(service, context), (service, context) -> { Root_meta_legend_service_metamodel_Service pureService = (Root_meta_legend_service_metamodel_Service) context.pureModel.getOrCreatePackage(service._package)._children().detect(c -> service.name.equals(c._name())); @@ -203,6 +199,26 @@ public Iterable> getExtraProcessors() ); } + public Root_meta_legend_service_metamodel_Service processserviceFirstPass(Service service, CompileContext context) + { + if (!service.owners.isEmpty() && service.ownership != null) + { + throw new EngineException("Cannot use both ownership model and explicit owners list.", service.sourceInformation, EngineErrorType.COMPILATION); + } +// if (service.owners == null && service.ownership == null) +// { +// throw new EngineException("Must use either ownership model or explicit owners list.", service.sourceInformation, EngineErrorType.COMPILATION); +// } + return new Root_meta_legend_service_metamodel_Service_Impl(service.name, null, context.pureModel.getClass("meta::legend::service::metamodel::Service")) + ._name(service.name) + ._stereotypes(ListIterate.collect(service.stereotypes, s -> context.resolveStereotype(s.profile, s.value, s.profileSourceInformation, s.sourceInformation))) + ._taggedValues(ListIterate.collect(service.taggedValues, t -> new Root_meta_pure_metamodel_extension_TaggedValue_Impl("", null, context.pureModel.getClass("meta::pure::metamodel::extension::TaggedValue"))._tag(context.resolveTag(t.tag.profile, t.tag.value, t.tag.profileSourceInformation, t.tag.sourceInformation))._value(t.value))) + ._pattern(service.pattern) + ._owners(Lists.mutable.withAll(service.owners)) + ._ownership(service.ownership != null ? processOwnershipModel(service.ownership) : null) + ._documentation(service.documentation); + } + @Override public List> getExtraTestProcessors() { diff --git a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/language/pure/dsl/service/grammar/from/ServiceParseTreeWalker.java b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/language/pure/dsl/service/grammar/from/ServiceParseTreeWalker.java index f7af21599d7..1ba1de71999 100644 --- a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/language/pure/dsl/service/grammar/from/ServiceParseTreeWalker.java +++ b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/language/pure/dsl/service/grammar/from/ServiceParseTreeWalker.java @@ -37,10 +37,12 @@ import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.runtime.RuntimePointer; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.section.ImportAwareCodeSection; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.ConnectionTestData; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.DeploymentOwnership; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.Execution; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.KeyedExecutionParameter; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.KeyedSingleExecutionTest; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.MultiExecutionTest; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.Ownership; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.PostValidation; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.PostValidationAssertion; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.PureMultiExecution; @@ -55,6 +57,7 @@ import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.ExecutionEnvironmentInstance; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.SingleExecutionParameters; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.MultiExecutionParameters; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.UserListOwnership; import org.finos.legend.engine.protocol.pure.v1.model.test.assertion.TestAssertion; import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.ValueSpecification; import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.ClassInstance; @@ -118,6 +121,13 @@ public Service visitService(ServiceParserGrammar.ServiceContext ctx) // owners (optional) ServiceParserGrammar.ServiceOwnersContext ownersContext = PureGrammarParserUtility.validateAndExtractOptionalField(ctx.serviceOwners(), "owners", service.sourceInformation); service.owners = ownersContext != null && ownersContext.STRING() != null ? ListIterate.collect(ownersContext.STRING(), ownerCtx -> PureGrammarParserUtility.fromGrammarString(ownerCtx.getText(), true)) : new ArrayList<>(); + + //Ownership (optional) + ServiceParserGrammar.ServiceOwnershipContext ownershipContext = PureGrammarParserUtility.validateAndExtractOptionalField(ctx.serviceOwnership(), "ownership", service.sourceInformation); + if (ownershipContext != null) + { + service.ownership = processOwnership(ownershipContext); + } // execution ServiceParserGrammar.ServiceExecContext execContext = PureGrammarParserUtility.validateAndExtractRequiredField(ctx.serviceExec(), "execution", service.sourceInformation); service.execution = this.visitExecution(execContext); @@ -269,6 +279,26 @@ private List visitStereotypes(ServiceParserGrammar.StereotypesCon }); } + private Ownership processOwnership(ServiceParserGrammar.ServiceOwnershipContext ownershipContext) + { + if (ownershipContext.deployment() != null) + { + DeploymentOwnership d = new DeploymentOwnership(); + d.identifier = PureGrammarParserUtility.fromGrammarString(ownershipContext.deployment().STRING().getText(), true); + return d; + } + else if (ownershipContext.userList() != null) + { + UserListOwnership u = new UserListOwnership(); + u.users = ownershipContext.userList().STRING() != null ? ListIterate.collect(ownershipContext.userList().STRING(), ownerCtx -> PureGrammarParserUtility.fromGrammarString(ownerCtx.getText(), true)) : new ArrayList<>(); + return u; + } + else + { + throw new EngineException("Ownership type not valid ", this.walkerSourceInformation.getSourceInformation(ownershipContext), EngineErrorType.PARSER); + } + } + private Execution visitExecution(ServiceParserGrammar.ServiceExecContext ctx) { if (ctx.singleExec() != null) diff --git a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/language/pure/dsl/service/grammar/to/ServiceGrammarComposerExtension.java b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/language/pure/dsl/service/grammar/to/ServiceGrammarComposerExtension.java index c46613d50b0..52bb41cd045 100644 --- a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/language/pure/dsl/service/grammar/to/ServiceGrammarComposerExtension.java +++ b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/language/pure/dsl/service/grammar/to/ServiceGrammarComposerExtension.java @@ -25,10 +25,13 @@ import org.finos.legend.engine.language.pure.grammar.to.PureGrammarComposerUtility; import org.finos.legend.engine.language.pure.grammar.to.extension.PureGrammarComposerExtension; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.PackageableElement; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.DeploymentOwnership; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.Execution; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.Ownership; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.PureExecution; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.Service; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.ExecutionEnvironmentInstance; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.UserListOwnership; import java.util.List; @@ -97,6 +100,11 @@ private static String renderService(Service service, PureGrammarComposerContext { serviceBuilder.append(getTabString()).append("owners:\n").append(getTabString()).append("[\n").append(LazyIterate.collect(service.owners, o -> getTabString(2) + convertString(o, true)).makeString(",\n")).append("\n").append(getTabString()).append("];\n"); } + if (service.ownership != null) + { + serviceBuilder.append(getTabString()).append("ownership: ").append(renderOwnership(service.ownership)).append(";\n"); + + } serviceBuilder.append(getTabString()).append("documentation: ").append(convertString(service.documentation, true)).append(";\n"); serviceBuilder.append(getTabString()).append("autoActivateUpdates: ").append(service.autoActivateUpdates ? "true" : "false").append(";\n"); Execution execution = service.execution; @@ -131,6 +139,22 @@ private static String renderService(Service service, PureGrammarComposerContext return serviceBuilder.append("}").toString(); } + private static String renderOwnership(Ownership o) + { + if (o instanceof DeploymentOwnership) + { + return "DID { identifier: \'" + ((DeploymentOwnership)o).identifier + "\' }"; + } + if (o instanceof UserListOwnership) + { + return "UserList { users: " + Lists.mutable.withAll(((UserListOwnership)o).users).makeString("[\'", "\', \'", "\']") + " }"; + } + else + { + return "/* Can't transform ownership '" + o.getClass().getSimpleName() + "' in this service */"; + } + } + private String renderExecutionEnvironment(ExecutionEnvironmentInstance execEnv, PureGrammarComposerContext context) { StringBuilder execEnvBuilder = new StringBuilder().append("ExecutionEnvironment").append(" ").append(PureGrammarComposerUtility.convertPath(execEnv.getPath())); diff --git a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/ServiceProtocolExtension.java b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/ServiceProtocolExtension.java index d00260f7762..a1940c2cbcf 100644 --- a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/ServiceProtocolExtension.java +++ b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/ServiceProtocolExtension.java @@ -20,8 +20,10 @@ import org.finos.legend.engine.protocol.pure.v1.extension.ProtocolSubTypeInfo; import org.finos.legend.engine.protocol.pure.v1.extension.PureProtocolExtension; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.PackageableElement; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.DeploymentOwnership; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.Execution; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.MultiExecutionTest; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.Ownership; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.PureMultiExecution; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.PureSingleExecution; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.Service; @@ -33,6 +35,7 @@ import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.ExecutionParameters; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.SingleExecutionParameters; import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.MultiExecutionParameters; +import org.finos.legend.engine.protocol.pure.v1.model.packageableElement.service.UserListOwnership; import org.finos.legend.engine.protocol.pure.v1.model.test.Test; import org.finos.legend.engine.protocol.pure.v1.model.test.TestSuite; @@ -71,6 +74,10 @@ public List>>> getExtraProtocolSubTypeInfo .build(), ProtocolSubTypeInfo.newBuilder(Test.class) .withSubtype(ServiceTest.class, "serviceTest") + .build(), + ProtocolSubTypeInfo.newBuilder(Ownership.class) + .withSubtype(DeploymentOwnership.class, "deploymentOwnership") + .withSubtype(UserListOwnership.class, "userListOwnership") .build() )); } diff --git a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/packageableElement/service/DeploymentOwnership.java b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/packageableElement/service/DeploymentOwnership.java new file mode 100644 index 00000000000..05fccdf3be5 --- /dev/null +++ b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/packageableElement/service/DeploymentOwnership.java @@ -0,0 +1,31 @@ +// Copyright 2023 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.protocol.pure.v1.model.packageableElement.service; + +public class DeploymentOwnership extends Ownership +{ + public String identifier; + + public DeploymentOwnership() + { + + } + + public DeploymentOwnership(String id) + { + this.identifier = id; + } +} diff --git a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/packageableElement/service/Ownership.java b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/packageableElement/service/Ownership.java new file mode 100644 index 00000000000..49545d9acdc --- /dev/null +++ b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/packageableElement/service/Ownership.java @@ -0,0 +1,28 @@ +// Copyright 2023 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.protocol.pure.v1.model.packageableElement.service; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "_type", defaultImpl = DeploymentOwnership.class) +@JsonSubTypes({ + @JsonSubTypes.Type(value = DeploymentOwnership.class, name = "deploymentOwnership"), + @JsonSubTypes.Type(value = UserListOwnership.class, name = "userListOwnership"), +}) +public abstract class Ownership +{ +} diff --git a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/packageableElement/service/Service.java b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/packageableElement/service/Service.java index 8f954c9e906..ed6a7840cc3 100644 --- a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/packageableElement/service/Service.java +++ b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/packageableElement/service/Service.java @@ -30,7 +30,9 @@ public class Service extends PackageableElement public List taggedValues = Collections.emptyList(); public String pattern; - public List owners; + @Deprecated + public List owners = Collections.emptyList(); + public Ownership ownership; public String documentation; public boolean autoActivateUpdates = true; public Execution execution; diff --git a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/packageableElement/service/UserListOwnership.java b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/packageableElement/service/UserListOwnership.java new file mode 100644 index 00000000000..c9b67bb9fa0 --- /dev/null +++ b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/main/java/org/finos/legend/engine/protocol/pure/v1/model/packageableElement/service/UserListOwnership.java @@ -0,0 +1,23 @@ +// Copyright 2023 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.protocol.pure.v1.model.packageableElement.service; + +import java.util.Collections; +import java.util.List; + +public class UserListOwnership extends Ownership +{ + public List users = Collections.emptyList(); +} diff --git a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/test/java/org/finos/legend/engine/language/pure/compiler/test/TestServiceCompilationFromGrammar.java b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/test/java/org/finos/legend/engine/language/pure/compiler/test/TestServiceCompilationFromGrammar.java index b7e7d71b889..8888eacbd7d 100644 --- a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/test/java/org/finos/legend/engine/language/pure/compiler/test/TestServiceCompilationFromGrammar.java +++ b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/test/java/org/finos/legend/engine/language/pure/compiler/test/TestServiceCompilationFromGrammar.java @@ -116,6 +116,63 @@ public void testFaultyAnnotations() "}\n", "COMPILATION error at [4:11-19]: Can't find the profile 'NoProfile'"); } + @Test + public void testOwnershipGrammarCompilation() + { + String resource = "Class test::class\n" + + "{\n" + + " prop1 : Integer[0..1];\n" + + "}\n" + + "###Mapping\n" + + "Mapping test::mapping\n" + + "(\n" + + ")\n" + + "###Connection\n" + + "JsonModelConnection test::connection\n" + + "{\n" + + " class : test::class;" + + " url : 'asd';\n" + + "}\n" + + "###Runtime\n" + + "Runtime test::runtime\n" + + "{\n" + + " mappings: [test::mapping];\n" + + "}\n"; + + // test multiple ownership: DID + test(resource + "###Service\n" + + "Service test::Service\n" + + "{\n" + + " pattern: 'url/myUrl/';\n" + + " owners: ['ownerName'];\n" + + " ownership: DID { identifier: 'deploymentIdentifier' };\n" + + " documentation: 'test';\n" + + " autoActivateUpdates: true;\n" + + " execution: Single\n" + + " {\n" + + " query: src: test::class[1]|$src.prop1;\n" + + " mapping: test::mapping;\n" + + " runtime: test::runtime;\n" + + " }\n" + + "}\n", "COMPILATION error at [20:1-33:1]: Cannot use both ownership model and explicit owners list."); + // test multiple ownership: userList + test(resource + "###Service\n" + + "Service test::Service\n" + + "{\n" + + " pattern: 'url/myUrl/';\n" + + " owners: ['ownerName'];\n" + + " ownership: UserList { users: ['user1', 'user2'] };\n" + + " documentation: 'test';\n" + + " autoActivateUpdates: true;\n" + + " execution: Single\n" + + " {\n" + + " query: src: test::class[1]|$src.prop1;\n" + + " mapping: test::mapping;\n" + + " runtime: test::runtime;\n" + + " }\n" + + "}\n", "COMPILATION error at [20:1-33:1]: Cannot use both ownership model and explicit owners list."); + } + @Test public void testServiceWithSingleExecution() { diff --git a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/test/java/org/finos/legend/engine/language/pure/grammar/test/TestServiceGrammarRoundtrip.java b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/test/java/org/finos/legend/engine/language/pure/grammar/test/TestServiceGrammarRoundtrip.java index acabb3197e4..60aa2483c49 100644 --- a/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/test/java/org/finos/legend/engine/language/pure/grammar/test/TestServiceGrammarRoundtrip.java +++ b/legend-engine-xts-service/legend-engine-language-pure-dsl-service/src/test/java/org/finos/legend/engine/language/pure/grammar/test/TestServiceGrammarRoundtrip.java @@ -37,6 +37,35 @@ public void testService() " 'ownerName',\n" + " 'ownerName2'\n" + " ];\n" + + " ownership: DID { identifier: '12345' };\n" + + " documentation: 'this is just for context';\n" + + " autoActivateUpdates: true;\n" + + " execution: Single\n" + + " {\n" + + " query: src: meta::transform::tests::Address[1]|$src.a;\n" + + " mapping: meta::myMapping;\n" + + " runtime: meta::myRuntime;\n" + + " }\n" + + " test: Single\n" + + " {\n" + + " data: 'moreThanData';\n" + + " asserts:\n" + + " [\n" + + " { [], res: Result[1]|$res.values->cast(@TabularDataSet).rows->size() == 1 },\n" + + " { [], res: Result[1]|$res.values->cast(@TabularDataSet).rows->size() == 1 }\n" + + " ];\n" + + " }\n" + + "}\n" + + "\n" + + "Service <> {doc.doc = 'something'} meta::pure::myServiceSingle2\n" + + "{\n" + + " pattern: 'url/myUrl2/';\n" + + " owners:\n" + + " [\n" + + " 'ownerName',\n" + + " 'ownerName2'\n" + + " ];\n" + + " ownership: UserList { users: ['12345', '789'] };\n" + " documentation: 'this is just for context';\n" + " autoActivateUpdates: true;\n" + " execution: Single\n" + From e9a31d2eab012cc76fdad6f01905a7313dbda960 Mon Sep 17 00:00:00 2001 From: Yasirmod17 Date: Fri, 29 Sep 2023 19:12:39 -0400 Subject: [PATCH 02/10] Add SparkSQL modules --- .../pom.xml | 5 + .../legend-engine-server/pom.xml | 5 + .../engine/server/test/userTestConfig.json | 4 +- .../finos/legend/engine/ide/PureIDELight.java | 1 + .../pom.xml | 267 ++++++ ...ationalSparkSQLCodeRepositoryProvider.java | 29 + ...lesystem.repository.CodeRepositoryProvider | 1 + .../core_relational_sparksql.definition.json | 5 + .../tests/executionPlanTestSybaseIQ.pure | 217 +++++ .../sqlQueryToString/sparkSQLExtension.pure | 654 +++++++++++++++ .../tests/testSparkSQLToSQLString.pure | 773 ++++++++++++++++++ .../core/Test_Pure_Relational_SparkSQL.java | 41 + ...arkSQLCodeRepositoryProviderAvailable.java | 36 + .../pom.xml | 34 + .../pom.xml | 1 + pom.xml | 5 + 16 files changed, 2076 insertions(+), 2 deletions(-) create mode 100644 legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/pom.xml create mode 100644 legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/java/org/finos/legend/pure/code/core/CoreRelationalSparkSQLCodeRepositoryProvider.java create mode 100644 legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider create mode 100644 legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql.definition.json create mode 100644 legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/executionPlan/tests/executionPlanTestSybaseIQ.pure create mode 100644 legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/sqlQueryToString/sparkSQLExtension.pure create mode 100644 legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/sqlQueryToString/tests/testSparkSQLToSQLString.pure create mode 100644 legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/test/java/org/finos/legend/pure/code/core/Test_Pure_Relational_SparkSQL.java create mode 100644 legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/test/java/org/finos/legend/pure/code/core/test/TestSparkSQLCodeRepositoryProviderAvailable.java create mode 100644 legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/pom.xml diff --git a/legend-engine-config/legend-engine-extensions-collection-generation/pom.xml b/legend-engine-config/legend-engine-extensions-collection-generation/pom.xml index 599c4fc3498..00f4cd62de8 100644 --- a/legend-engine-config/legend-engine-extensions-collection-generation/pom.xml +++ b/legend-engine-config/legend-engine-extensions-collection-generation/pom.xml @@ -295,6 +295,11 @@ legend-engine-xt-relationalStore-sybaseiq-pure runtime + + org.finos.legend.engine + legend-engine-xt-relationalStore-sparksql-pure + runtime + org.finos.legend.engine legend-engine-xt-relationalStore-javaPlatformBinding-pure diff --git a/legend-engine-config/legend-engine-server/pom.xml b/legend-engine-config/legend-engine-server/pom.xml index 01007e166df..e8b0a546fd4 100644 --- a/legend-engine-config/legend-engine-server/pom.xml +++ b/legend-engine-config/legend-engine-server/pom.xml @@ -134,6 +134,11 @@ legend-engine-xt-relationalStore-sybaseiq-pure runtime + + org.finos.legend.engine + legend-engine-xt-relationalStore-sparksql-pure + runtime + org.finos.legend.engine legend-engine-language-pure-grammar-api diff --git a/legend-engine-config/legend-engine-server/src/test/resources/org/finos/legend/engine/server/test/userTestConfig.json b/legend-engine-config/legend-engine-server/src/test/resources/org/finos/legend/engine/server/test/userTestConfig.json index acd17396d0d..b063f6106a9 100644 --- a/legend-engine-config/legend-engine-server/src/test/resources/org/finos/legend/engine/server/test/userTestConfig.json +++ b/legend-engine-config/legend-engine-server/src/test/resources/org/finos/legend/engine/server/test/userTestConfig.json @@ -3,7 +3,7 @@ "mode": "TEST_IGNORE_FUNCTION_MATCH" }, "logging": { - "level": "error", + "level": "info", "appenders": [ { "type": "console", @@ -47,7 +47,7 @@ "connector": { "maxRequestHeaderSize": "32KiB", "type": "http", - "port": 6300 + "port": 9090 }, "requestLog": { "appenders": [ diff --git a/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light/src/main/java/org/finos/legend/engine/ide/PureIDELight.java b/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light/src/main/java/org/finos/legend/engine/ide/PureIDELight.java index 2eea4dbd2b9..af88beddcbf 100644 --- a/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light/src/main/java/org/finos/legend/engine/ide/PureIDELight.java +++ b/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light/src/main/java/org/finos/legend/engine/ide/PureIDELight.java @@ -61,6 +61,7 @@ protected MutableList buildRepositories(SourceLocationCon .with(this.buildCore("legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-presto/legend-engine-xt-relationalStore-presto-pure", "relational_presto")) .with(this.buildCore("legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sybase/legend-engine-xt-relationalStore-sybase-pure", "relational_sybase")) .with(this.buildCore("legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sybaseiq/legend-engine-xt-relationalStore-sybaseiq-pure", "relational_sybaseiq")) + .with(this.buildCore("legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sybaseiq/legend-engine-xt-relationalStore-sparksql-pure", "relational_sparksql")) .with(this.buildCore("legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-analytics/legend-engine-xt-relationalStore-store-entitlement-pure", "relational_store_entitlement")) .with(this.buildCore("legend-engine-xts-serviceStore/legend-engine-xt-serviceStore-pure", "servicestore")) .with(this.buildCore("legend-engine-xts-serviceStore/legend-engine-xt-serviceStore-javaPlatformBinding-pure", "servicestore-java-platform-binding")) diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/pom.xml b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/pom.xml new file mode 100644 index 00000000000..dfb1bdf5e16 --- /dev/null +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/pom.xml @@ -0,0 +1,267 @@ + + + + + + org.finos.legend.engine + legend-engine-xt-relationalStore-sparksql + 4.29.2-SNAPSHOT + + 4.0.0 + + legend-engine-xt-relationalStore-sparksql-pure + jar + Legend Engine - XT - Relational Store - sparksql - Pure + + + + + org.finos.legend.pure + legend-pure-maven-generation-par + + src/main/resources + ${legend.pure.version} + + core_relational_sparksql + + + ${project.basedir}/src/main/resources/core_relational_sparksql.definition.json + + + + + + generate-sources + + build-pure-jar + + + + + + org.finos.legend.pure + legend-pure-m2-functions-pure + ${legend.pure.version} + + + org.finos.legend.pure + legend-pure-m2-dsl-mapping-grammar + ${legend.pure.version} + + + org.finos.legend.pure + legend-pure-m2-dsl-path-grammar + ${legend.pure.version} + + + org.finos.legend.pure + legend-pure-m2-dsl-graph-grammar + ${legend.pure.version} + + + org.finos.legend.pure + legend-pure-m2-dsl-diagram-grammar + ${legend.pure.version} + + + org.finos.legend.pure + legend-pure-m2-store-relational-grammar + ${legend.pure.version} + + + org.finos.legend.engine + legend-engine-pure-code-compiled-core + ${project.version} + + + org.finos.legend.engine + legend-engine-xt-relationalStore-pure + ${project.version} + + + + + org.finos.legend.pure + legend-pure-maven-generation-java + + + compile + + build-pure-compiled-jar + + + true + true + modular + true + + core_relational_sparksql + + + + + + + org.finos.legend.pure + legend-pure-m2-dsl-mapping-grammar + ${legend.pure.version} + + + org.finos.legend.pure + legend-pure-m2-dsl-path-grammar + ${legend.pure.version} + + + org.finos.legend.pure + legend-pure-m2-dsl-graph-grammar + ${legend.pure.version} + + + org.finos.legend.pure + legend-pure-m2-dsl-diagram-grammar + ${legend.pure.version} + + + org.finos.legend.pure + legend-pure-m2-store-relational-grammar + ${legend.pure.version} + + + org.finos.legend.engine + legend-engine-pure-code-compiled-core + ${project.version} + + + org.finos.legend.engine + legend-engine-xt-relationalStore-pure + ${project.version} + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + dependency-analyze + + + + org.finos.legend.pure:legend-pure-m2-dsl-mapping-pure + org.finos.legend.pure:legend-pure-m2-dsl-path-pure + org.finos.legend.engine:legend-engine-pure-platform-store-relational-java + org.finos.legend.engine:legend-engine-pure-platform-dsl-mapping-java + + + + + + + + + + + org.finos.legend.pure + legend-pure-m4 + + + org.finos.legend.pure + legend-pure-m3-core + + + org.finos.legend.pure + legend-pure-m2-dsl-mapping-pure + + + org.finos.legend.pure + legend-pure-m2-dsl-path-pure + + + org.finos.legend.pure + legend-pure-m2-store-relational-pure + + + org.finos.legend.pure + legend-pure-runtime-java-engine-compiled + + + + org.finos.legend.engine + legend-engine-pure-code-compiled-core + + + org.finos.legend.engine + legend-engine-pure-code-compiled-functions + + + org.finos.legend.engine + legend-engine-pure-platform-dsl-mapping-java + + + org.finos.legend.engine + legend-engine-pure-platform-java + + + org.finos.legend.engine + legend-engine-pure-platform-functions-java + + + org.finos.legend.engine + legend-engine-xt-relationalStore-pure + + + org.finos.legend.engine + legend-engine-pure-platform-store-relational-java + + + + org.eclipse.collections + eclipse-collections + + + org.eclipse.collections + eclipse-collections-api + + + + + org.finos.legend.pure + legend-pure-m2-functions-json-pure + test + + + com.fasterxml.jackson.core + jackson-annotations + test + + + com.fasterxml.jackson.core + jackson-databind + test + + + com.fasterxml.jackson.core + jackson-core + test + + + junit + junit + + + + diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/java/org/finos/legend/pure/code/core/CoreRelationalSparkSQLCodeRepositoryProvider.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/java/org/finos/legend/pure/code/core/CoreRelationalSparkSQLCodeRepositoryProvider.java new file mode 100644 index 00000000000..a652f3bddc0 --- /dev/null +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/java/org/finos/legend/pure/code/core/CoreRelationalSparkSQLCodeRepositoryProvider.java @@ -0,0 +1,29 @@ +// Copyright 2023 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.pure.code.core; + +import org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepository; +import org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider; +import org.finos.legend.pure.m3.serialization.filesystem.repository.GenericCodeRepository; + +public class CoreRelationalSparkSQLCodeRepositoryProvider implements CodeRepositoryProvider +{ + @Override + public CodeRepository repository() + { + return GenericCodeRepository.build("core_relational_sparksql.definition.json"); + } +} + diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider new file mode 100644 index 00000000000..96a2fb109ac --- /dev/null +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/META-INF/services/org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider @@ -0,0 +1 @@ +org.finos.legend.pure.code.core.CoreRelationalSparkSQLCodeRepositoryProvider \ No newline at end of file diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql.definition.json b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql.definition.json new file mode 100644 index 00000000000..ed5893f3ad1 --- /dev/null +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql.definition.json @@ -0,0 +1,5 @@ +{ + "name" : "core_relational_sparksql", + "pattern" : "(meta::relational::functions::sqlQueryToString::sparkSQL|meta::relational::tests::sqlQueryToString::sparkSQL|meta::relational::tests::sqlToString::sparkSQL|meta::pure::executionPlan::tests::sparkSQL|meta::relational::tests::mapping::sqlFunction::sparkSQL|meta::relational::tests::postProcessor::sparkSQL|meta::relational::tests::query::function::sparkSQL|meta::relational::tests::functions::sqlstring::sparkSQL|meta::relational::tests::tds::sparkSQL|meta::relational::tests::projection::sparkSQL|meta::pure::alloy::connections|meta::protocols::pure)(::.*)?", + "dependencies" : ["platform", "platform_functions", "platform_store_relational", "platform_dsl_mapping", "core_functions", "core", "core_relational"] +} diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/executionPlan/tests/executionPlanTestSybaseIQ.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/executionPlan/tests/executionPlanTestSybaseIQ.pure new file mode 100644 index 00000000000..9e2fa014cf0 --- /dev/null +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/executionPlan/tests/executionPlanTestSybaseIQ.pure @@ -0,0 +1,217 @@ +//// Copyright 2023 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. +// +//import meta::pure::alloy::connections::alloy::authentication::*; +//import meta::pure::alloy::connections::alloy::specification::*; +//import meta::pure::alloy::connections::*; +//import meta::pure::mapping::modelToModel::test::createInstances::*; +//import meta::relational::postProcessor::*; +//import meta::pure::extension::*; +//import meta::relational::extension::*; +//import meta::pure::mapping::modelToModel::test::shared::*; +//import meta::pure::mapping::modelToModel::test::enumerationMapping::enumToEnum::mapping::*; +//import meta::pure::mapping::modelToModel::test::enumerationMapping::enumToEnum::model::*; +//import meta::pure::mapping::modelToModel::test::enumeration::*; +//import meta::pure::graphFetch::execution::*; +//import meta::pure::executionPlan::tests::datetime::*; +//import meta::relational::tests::tds::tabletds::*; +//import meta::pure::mapping::*; +//import meta::relational::mapping::*; +//import meta::relational::runtime::*; +//import meta::relational::tests::mapping::inheritance::relational::*; +//import meta::relational::metamodel::join::*; +//import meta::relational::tests::tds::tdsJoin::*; +//import meta::pure::executionPlan::toString::*; +//import meta::pure::executionPlan::tests::*; +//import meta::relational::tests::groupBy::datePeriods::mapping::*; +//import meta::relational::tests::groupBy::datePeriods::*; +//import meta::relational::tests::groupBy::datePeriods::domain::*; +//import meta::pure::executionPlan::*; +//import meta::relational::tests::*; +//import meta::relational::tests::model::simple::*; +//import meta::pure::runtime::*; +//import meta::pure::mapping::modelToModel::test::shared::src::*; +//import meta::pure::graphFetch::executionPlan::*; +//import meta::pure::graphFetch::routing::*; +//import meta::pure::functions::collection::*; +//import meta::pure::executionPlan::tests::sybaseIQ::*; +// +//function <> meta::pure::executionPlan::tests::sybaseIQ::testFilterEqualsWithOptionalParameter_SybaseIQ():Boolean[1] +//{ +// let expectedPlan ='Sequence\n'+ +// '(\n'+ +// ' type = TDS[(Time, Integer, INT, "")]\n'+ +// ' (\n'+ +// ' FunctionParametersValidationNode\n'+ +// ' (\n'+ +// ' functionParameters = [optionalID:String[0..1], optionalActive:Boolean[0..1]]\n'+ +// ' )\n'+ +// ' Relational\n'+ +// ' (\n'+ +// ' type = TDS[(Time, Integer, INT, "")]\n'+ +// ' resultColumns = [("Time", INT)]\n'+ +// ' sql = select "root"."time" as "Time" from interactionTable as "root" where ((${optionalVarPlaceHolderOperationSelector(optionalID![], \'"root".ID = ${varPlaceHolderToString(optionalID![] "\\\'" "\\\'" {"\\\'" : "\\\'\\\'"} "null")}\', \'"root".ID is null\')}) and (${optionalVarPlaceHolderOperationSelector(optionalActive![], \'case when "root"."active" = \\\'Y\\\' then \\\'true\\\' else \\\'false\\\' end = ${varPlaceHolderToString(optionalActive![] "\\\'" "\\\'" {} "null")}\', \'case when "root"."active" = \\\'Y\\\' then \\\'true\\\' else \\\'false\\\' end is null\')}))\n'+ +// ' connection = DatabaseConnection(type = "SybaseIQ")\n'+ +// ' )\n'+ +// ' )\n'+ +// ')\n'; +// assertPlanGenerationForOptionalParameter(DatabaseType.SybaseIQ, $expectedPlan); +//} +// +//function <> meta::pure::executionPlan::tests::sybaseIQ::testGreaterThanLessThanEqualsWithOptionalParameter_SybaseIQ():Boolean[1] +//{ +// let func = {optionalAgeLowerLimit: Integer[0..1], optionalAgeHigherLimit: Integer[0..1]|Person.all()->filter(p|$p.age>$optionalAgeLowerLimit && ($p.age<=$optionalAgeHigherLimit))->project(col(a|$a.firstName, 'firstName'))}; +// let expectedPlan ='Sequence\n'+ +// '(\n'+ +// ' type = TDS[(firstName, String, VARCHAR(200), "")]\n'+ +// ' (\n'+ +// ' FunctionParametersValidationNode\n'+ +// ' (\n'+ +// ' functionParameters = [optionalAgeLowerLimit:Integer[0..1], optionalAgeHigherLimit:Integer[0..1]]\n'+ +// ' )\n'+ +// ' Relational\n'+ +// ' (\n'+ +// ' type = TDS[(firstName, String, VARCHAR(200), "")]\n'+ +// ' resultColumns = [("firstName", VARCHAR(200))]\n'+ +// ' sql = select "root".FIRSTNAME as "firstName" from personTable as "root" where ((("root".AGE is not null and ${varPlaceHolderToString(optionalAgeLowerLimit![] "" "" {} "null")} is not null) and "root".AGE > ${varPlaceHolderToString(optionalAgeLowerLimit![] "" "" {} "null")}) and (("root".AGE is not null and ${varPlaceHolderToString(optionalAgeHigherLimit![] "" "" {} "null")} is not null) and "root".AGE <= ${varPlaceHolderToString(optionalAgeHigherLimit![] "" "" {} "null")}))\n'+ +// ' connection = DatabaseConnection(type = "SybaseIQ")\n'+ +// ' )\n'+ +// ' )\n'+ +// ')\n'; +// assertPlanGenerationForOptionalParameterWithGreaterThanLessThan($func, DatabaseType.SybaseIQ, $expectedPlan); +//} +// +// +//function <> meta::pure::executionPlan::tests::sybaseIQ::testLessThanGreaterThanEqualsWithOptionalParameter_SybaseIQ():Boolean[1] +//{ +// let func = {optionalAgeLowerLimit: Integer[0..1], optionalAgeHigherLimit: Integer[0..1]|Person.all()->filter(p|$p.age<$optionalAgeLowerLimit && ($p.age>=$optionalAgeHigherLimit))->project(col(a|$a.firstName, 'firstName'))}; +// let expectedPlan ='Sequence\n'+ +// '(\n'+ +// ' type = TDS[(firstName, String, VARCHAR(200), "")]\n'+ +// ' (\n'+ +// ' FunctionParametersValidationNode\n'+ +// ' (\n'+ +// ' functionParameters = [optionalAgeLowerLimit:Integer[0..1], optionalAgeHigherLimit:Integer[0..1]]\n'+ +// ' )\n'+ +// ' Relational\n'+ +// ' (\n'+ +// ' type = TDS[(firstName, String, VARCHAR(200), "")]\n'+ +// ' resultColumns = [("firstName", VARCHAR(200))]\n'+ +// ' sql = select "root".FIRSTNAME as "firstName" from personTable as "root" where ((("root".AGE is not null and ${varPlaceHolderToString(optionalAgeLowerLimit![] "" "" {} "null")} is not null) and "root".AGE < ${varPlaceHolderToString(optionalAgeLowerLimit![] "" "" {} "null")}) and (("root".AGE is not null and ${varPlaceHolderToString(optionalAgeHigherLimit![] "" "" {} "null")} is not null) and "root".AGE >= ${varPlaceHolderToString(optionalAgeHigherLimit![] "" "" {} "null")}))\n'+ +// ' connection = DatabaseConnection(type = "SybaseIQ")\n'+ +// ' )\n'+ +// ' )\n'+ +// ')\n'; +// assertPlanGenerationForOptionalParameterWithGreaterThanLessThan($func, DatabaseType.SybaseIQ, $expectedPlan); +//} +// +//function meta::pure::executionPlan::tests::sybaseIQ::twoDBRunTimeSybaseIQ():meta::pure::runtime::Runtime[1] +//{ +// ^meta::pure::runtime::Runtime +// ( +// connections = [^TestDatabaseConnection( +// element = dbInc, +// type=DatabaseType.SybaseIQ +// ),^TestDatabaseConnection( +// element = database2, +// type=DatabaseType.SybaseIQ +// )] +// ); +//} +// +//function <> meta::pure::executionPlan::tests::sybaseIQ::twoDBTestSpaceIdentifierSybaseIQ():Boolean[1] +//{ +// let result = executionPlan({| +// testJoinTDS_Person.all()->meta::pure::tds::project([col(p|$p.firstName, 'first name'), col(p|$p.employerID, 'eID')])->join(testJoinTDS_Firm.all()->project([col(p|$p.firmID, 'fID'), +// col(p|$p.legalName, 'legalName')]), JoinType.INNER, {a,b|$a.getInteger('eID') == $b.getInteger('fID');})->filter( f| $f.getString('first name')=='Adam' && $f.getString('legalName')=='Firm X') +// ;}, meta::relational::tests::tds::tdsJoin::testJoinTDSMappingTwoDatabase, twoDBRunTimeSybaseIQ(), meta::relational::extension::relationalExtensions()); +// +// assertEquals('Sequence\n'+ +// '(\n'+ +// ' type = TDS[(first name, String, VARCHAR(200), \"\"), (eID, Integer, INT, \"\"), (fID, Integer, INT, \"\"), (legalName, String, VARCHAR(200), \"\")]\n'+ +// ' (\n'+ +// ' Allocation\n'+ +// ' (\n'+ +// ' type = TDS[(first name, String, VARCHAR(200), \"\"), (eID, Integer, INT, \"\")]\n'+ +// ' name = tdsVar_0\n'+ +// ' value = \n'+ +// ' (\n'+ +// ' Relational\n'+ +// ' (\n'+ +// ' type = TDS[(first name, String, VARCHAR(200), \"\"), (eID, Integer, INT, \"\")]\n'+ +// ' resultColumns = [("first name", VARCHAR(200)), ("eID", INT)]\n'+ +// ' sql = select \"root\".FIRSTNAME as \"first name\", \"root\".FIRMID as \"eID\" from personTable as \"root\"\n'+ +// ' connection = TestDatabaseConnection(type = \"SybaseIQ\")\n'+ +// ' )\n'+ +// ' )\n'+ +// ' )\n'+ +// ' Relational\n'+ +// ' (\n'+ +// ' type = TDS[(first name, String, VARCHAR(200), \"\"), (eID, Integer, INT, \"\"), (fID, Integer, INT, \"\"), (legalName, String, VARCHAR(200), \"\")]\n'+ +// ' resultColumns = [("first name", INT), ("eID", INT), ("fID", INT), ("legalName", VARCHAR(200))]\n'+ +// ' sql = select "tdsvar_0_0"."first name" as "first name", "tdsvar_0_0".eID as "eID", "tdsvar_0_0"."fID" as "fID", "tdsvar_0_0"."legalName" as "legalName" from (select * from (${tdsVar_0}) as "tdsvar_0_1" inner join (select "root".ID as "fID", "root".LEGALNAME as "legalName" from firmTable as "root") as "firmtable_0" on ("tdsvar_0_1".eID = "firmtable_0"."fID")) as "tdsvar_0_0" where ("tdsvar_0_0"."first name" = \'Adam\' and "tdsvar_0_0"."legalName" = \'Firm X\')\n'+ +// ' connection = TestDatabaseConnection(type = \"SybaseIQ\")\n'+ +// ' )\n'+ +// ' )\n'+ +// ')\n' +// , $result->planToString(meta::relational::extension::relationalExtensions())); +//} +// +//function <> meta::pure::executionPlan::tests::sybaseIQ::twoDBTestSlashSybaseIQ():Boolean[1] +//{ +// let result = executionPlan({| +// testJoinTDS_Person.all()->meta::pure::tds::project([col(p|$p.firstName, 'first/name'), col(p|$p.employerID, 'eID')])->join(testJoinTDS_Firm.all()->project([col(p|$p.firmID, 'fID'), +// col(p|$p.legalName, 'legalName')]), JoinType.INNER, {a,b|$a.getInteger('eID') == $b.getInteger('fID');})->filter( f| $f.getString('first/name')=='Adam' && $f.getString('legalName')=='Firm X') +// ;}, meta::relational::tests::tds::tdsJoin::testJoinTDSMappingTwoDatabase, twoDBRunTimeSybaseIQ(), meta::relational::extension::relationalExtensions()); +// +// assertEquals('Sequence\n'+ +// '(\n'+ +// ' type = TDS[(first/name, String, VARCHAR(200), \"\"), (eID, Integer, INT, \"\"), (fID, Integer, INT, \"\"), (legalName, String, VARCHAR(200), \"\")]\n'+ +// ' (\n'+ +// ' Allocation\n'+ +// ' (\n'+ +// ' type = TDS[(first/name, String, VARCHAR(200), \"\"), (eID, Integer, INT, \"\")]\n'+ +// ' name = tdsVar_0\n'+ +// ' value = \n'+ +// ' (\n'+ +// ' Relational\n'+ +// ' (\n'+ +// ' type = TDS[(first/name, String, VARCHAR(200), \"\"), (eID, Integer, INT, \"\")]\n'+ +// ' resultColumns = [("first/name", VARCHAR(200)), ("eID", INT)]\n'+ +// ' sql = select \"root\".FIRSTNAME as \"first/name\", \"root\".FIRMID as \"eID\" from personTable as \"root\"\n'+ +// ' connection = TestDatabaseConnection(type = \"SybaseIQ\")\n'+ +// ' )\n'+ +// ' )\n'+ +// ' )\n'+ +// ' Relational\n'+ +// ' (\n'+ +// ' type = TDS[(first/name, String, VARCHAR(200), \"\"), (eID, Integer, INT, \"\"), (fID, Integer, INT, \"\"), (legalName, String, VARCHAR(200), \"\")]\n'+ +// ' resultColumns = [("first/name", INT), ("eID", INT), ("fID", INT), ("legalName", VARCHAR(200))]\n'+ +// ' sql = select "tdsvar_0_0"."first/name" as "first/name", "tdsvar_0_0".eID as "eID", "tdsvar_0_0"."fID" as "fID", "tdsvar_0_0"."legalName" as "legalName" from (select * from (${tdsVar_0}) as "tdsvar_0_1" inner join (select "root".ID as "fID", "root".LEGALNAME as "legalName" from firmTable as "root") as "firmtable_0" on ("tdsvar_0_1".eID = "firmtable_0"."fID")) as "tdsvar_0_0" where ("tdsvar_0_0"."first/name" = \'Adam\' and "tdsvar_0_0"."legalName" = \'Firm X\')\n'+ +// ' connection = TestDatabaseConnection(type = \"SybaseIQ\")\n'+ +// ' )\n'+ +// ' )\n'+ +// ')\n' +// , $result->planToString(meta::relational::extension::relationalExtensions())); +//} +// +//function <> meta::pure::executionPlan::tests::sybaseIQ::testExecutionPlanGenerationForMultipleInWithCollectionAndConstantInputs() : Boolean[1] +//{ +// let res = executionPlan( +// {name:String[*] |_Person.all()->filter(x | $x.fullName->in($name))->filter(x | $x.fullName->in(['A', 'B']))->project([x | $x.fullName], ['fullName']);}, +// meta::pure::mapping::modelToModel::test::shared::relationalMapping, ^Runtime(connections=^DatabaseConnection(element = relationalDB, type=DatabaseType.SybaseIQ)), meta::relational::extension::relationalExtensions() +// ); +// let expected = 'RelationalBlockExecutionNode(type=TDS[(fullName,String,VARCHAR(1000),"")](FunctionParametersValidationNode(functionParameters=[name:String[*]])Allocation(type=Stringname=inFilterClause_namevalue=(FreeMarkerConditionalExecutionNode(type=Stringcondition=${(instanceOf(name,"Stream")||((collectionSize(name![])?number)>250000))?c}trueBlock=(Sequence(type=String(CreateAndPopulateTempTable(type=VoidinputVarNames=[name]tempTableName=tempTableForIn_nametempTableColumns=[(ColumnForStoringInCollection,VARCHAR(200))]connection=DatabaseConnection(type="SybaseIQ"))Constant(type=Stringvalues=[select"temptableforin_name_0".ColumnForStoringInCollectionasColumnForStoringInCollectionfromtempTableForIn_nameas"temptableforin_name_0"]))))falseBlock=(Constant(type=Stringvalues=[${renderCollection(name![]",""\'""\'"{"\'":"\'\'"}"null")}])))))Relational(type=TDS[(fullName,String,VARCHAR(1000),"")]resultColumns=[("fullName",VARCHAR(1000))]sql=select"root".fullnameas"fullName"fromPersonas"root"where"root".fullnamein(${inFilterClause_name})and"root".fullnamein(\'A\',\'B\')connection=DatabaseConnection(type="SybaseIQ"))))'; +// assertEquals($expected, $res->planToStringWithoutFormatting(meta::relational::extension::relationalExtensions())); +//} diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/sqlQueryToString/sparkSQLExtension.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/sqlQueryToString/sparkSQLExtension.pure new file mode 100644 index 00000000000..a14c2f8aad0 --- /dev/null +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/sqlQueryToString/sparkSQLExtension.pure @@ -0,0 +1,654 @@ +import meta::relational::metamodel::*; +import meta::relational::functions::sqlQueryToString::sparkSQL::*; +import meta::relational::functions::sqlQueryToString::default::*; +import meta::relational::functions::sqlQueryToString::*; +import meta::relational::metamodel::operation::*; +import meta::relational::metamodel::relation::*; +import meta::relational::runtime::*; +import meta::pure::extension::*; +import meta::relational::extension::*; + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::dbExtensionLoaderForSparkSQL():DbExtensionLoader[1] +{ + ^DbExtensionLoader(dbType = DatabaseType.SparkSQL, loader = createDbExtensionForSparkSQL__DbExtension_1_); +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::createDbExtensionForSparkSQL():DbExtension[1] +{ + let reservedWords = sybaseReservedWords(); + let literalProcessors = getDefaultLiteralProcessors()->putAll(getLiteralProcessorsForSparkSQL()); + let literalProcessor = {type:Type[1]| $literalProcessors->get(if($type->instanceOf(Enumeration), | Enum, | $type))->toOne()}; + let dynaFuncDispatch = getDynaFunctionToSqlDefault($literalProcessor)->groupBy(d| $d.funcName)->putAll( + getDynaFunctionToSqlForSparkSQL()->groupBy(d| $d.funcName))->getDynaFunctionDispatcher(); + + ^DbExtension( + isBooleanLiteralSupported = false, + collectionThresholdLimit = 250000, + aliasLimit = 255, + isDbReservedIdentifier = {str:String[1]| $str->in($reservedWords)}, + literalProcessor = $literalProcessor, + windowColumnProcessor = processWindowColumn_WindowColumn_1__SqlGenerationContext_1__String_1_, + joinStringsProcessor = processJoinStringsOperationForSparkSQL_JoinStrings_1__SqlGenerationContext_1__String_1_, + selectSQLQueryProcessor = processSelectSQLQueryForSparkSQL_SelectSQLQuery_1__SqlGenerationContext_1__Boolean_1__String_1_, + columnNameToIdentifier = columnNameToIdentifierForSparkSQL_String_1__DbConfig_1__String_1_, + identifierProcessor = processIdentifierWithDoubleQuotes_String_1__DbConfig_1__String_1_, + dynaFuncDispatch = $dynaFuncDispatch, + ddlCommandsTranslator = getDDLCommandsTranslator(), + processTempTableName = processTempTableNameDefault_String_1__String_1_ + ); +} + +function meta::relational::functions::sqlQueryToString::sparkSQL::getDDLCommandsTranslator(): RelationalDDLCommandsTranslator[1] +{ + ^RelationalDDLCommandsTranslator( + createSchema = translateCreateSchemaStatementDefault_CreateSchemaSQL_1__DbConfig_1__String_1_, + dropSchema = translateDropSchemaStatementDefault_DropSchemaSQL_1__DbConfig_1__String_1_, + createTable = translateCreateTableStatementForSparkSQL_CreateTableSQL_1__DbConfig_1__String_1_, + dropTable = translateDropTableStatementDefault_DropTableSQL_1__DbConfig_1__String_1_, + loadTable = loadValuesToDbTableForSparkSQL_LoadTableSQL_1__DbConfig_1__String_MANY_ + ); +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::getLiteralProcessorsForSparkSQL():Map[1] +{ + newMap([ + pair(StrictDate, ^LiteralProcessor(format = 'convert(DATE, \'%s\', 121)', transform = {d:StrictDate[1], dbTimeZone:String[0..1] | $d->convertDateToSqlString($dbTimeZone)})), + pair(DateTime, ^LiteralProcessor(format = 'convert(DATETIME, \'%s\', 121)', transform = {d:DateTime[1], dbTimeZone:String[0..1] | $d->convertDateToSqlString($dbTimeZone)})), + pair(Date, ^LiteralProcessor(format = 'convert(DATETIME, \'%s\', 121)', transform = {d:Date[1], dbTimeZone:String[0..1] | $d->convertDateToSqlString($dbTimeZone)})) + ]) +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::getDynaFunctionToSqlForSparkSQL(): DynaFunctionToSql[*] +{ + let allStates = allGenerationStates(); + + [ + dynaFnToSql('contains', $allStates, ^ToSql(format=likePattern('%%%s%%'), transform={p:String[2]|$p->transformLikeParamsForSparkSQL()})), + dynaFnToSql('dateDiff', $allStates, ^ToSql(format='datediff(%s,%s,%s)', transform={p:String[*]|[$p->at(2)->replace('\'', '')->processDateDiffDurationUnitForSparkSQL(),$p->at(0),$p->at(1)]})), + dynaFnToSql('datePart', $allStates, ^ToSql(format='date(%s)')), + dynaFnToSql('endsWith', $allStates, ^ToSql(format=likePattern('%%%s'), transform={p:String[2]|$p->transformLikeParamsForSparkSQL()})), + dynaFnToSql('isAlphaNumeric', $allStates, ^ToSql(format=likePatternWithoutEscape('%%%s%%'), transform={p:String[1]|$p->transformAlphaNumericParamsForSparkSQL()})), + dynaFnToSql('startsWith', $allStates, ^ToSql(format=likePattern('%s%%'), transform={p:String[2]|$p->transformLikeParamsForSparkSQL()})) + ]->concatenate(getDynaFunctionToSqlCommonToBothSybases()); +} + +function meta::relational::functions::sqlQueryToString::sparkSQL::getDynaFunctionToSqlCommonToBothSybases(): DynaFunctionToSql[*] +{ + let allStates = allGenerationStates(); + let selectOutsideWhen = selectOutsideWhenGenerationState(); + let notSelectOutsideWhen = notSelectOutsideWhenGenerationStates(); + + [ + dynaFnToSql('adjust', $allStates, ^ToSql(format='dateadd(%s)', transform={p:String[3] | $p->at(2)->mapToDBUnitType() + ', ' + $p->at(1) + ', ' + $p->at(0)})), + dynaFnToSql('atan2', $allStates, ^ToSql(format='atan2(%s,%s)')), + dynaFnToSql('char', $allStates, ^ToSql(format='char(%s)')), + dynaFnToSql('concat', $allStates, ^ToSql(format='%s', transform={p:String[*]|$p->joinStrings(' + ')})), + dynaFnToSql('convertDate', $allStates, ^ToSql(format='%s', transform={p:String[*] | $p->convertToDateIQ()})), + dynaFnToSql('convertDateTime', $allStates, ^ToSql(format='%s' , transform={p:String[*] | $p->convertToDateTimeIQ()})), + dynaFnToSql('convertVarchar128', $allStates, ^ToSql(format='convert(VARCHAR(128), %s)')), + dynaFnToSql('dayOfMonth', $allStates, ^ToSql(format='datepart(DAY,%s)')), + dynaFnToSql('dayOfWeek', $allStates, ^ToSql(format='datename(WEEKDAY,%s)')), + dynaFnToSql('dayOfWeekNumber', $allStates, ^ToSql(format='%s',transform={p:String[1..2]| if($p->size()==1,| 'datepart(Weekday,'+ $p->at(0)+')',|$p->dayOfWeekNumberSparkSQL());})), + dynaFnToSql('dayOfYear', $allStates, ^ToSql(format='datepart(DAYOFYEAR,%s)')), + dynaFnToSql('firstDayOfMonth', $allStates, ^ToSql(format='dateadd(DAY, -(day(%s) - 1), %s)', transform={p:String[1] | $p->repeat(2)})), + dynaFnToSql('firstDayOfQuarter', $allStates, ^ToSql(format='dateadd(QUARTER, quarter(%s) - 1, dateadd(DAY, -(datepart(dayofyear, %s) - 1), %s))', transform={p:String[1] | $p->repeat(3)})), + dynaFnToSql('firstDayOfThisMonth', $allStates, ^ToSql(format='dateadd(DAY, -(day(today()) - 1), today())%s', transform={p:String[*] | ''})), + dynaFnToSql('firstDayOfThisQuarter', $allStates, ^ToSql(format='dateadd(QUARTER, quarter(today()) - 1, dateadd(DAY, -(datepart(dayofyear, today()) - 1), today()))%s', transform={p:String[*] | ''})), + dynaFnToSql('firstDayOfThisYear', $allStates, ^ToSql(format='dateadd(DAY, -(datepart(dayofyear, today()) - 1), today())%s', transform={p:String[*] | ''})), + dynaFnToSql('firstDayOfWeek', $allStates, ^ToSql(format='dateadd(DAY, -(mod(datepart(weekday, %s)+5, 7)), %s)', transform={p:String[1] | $p->repeat(2)})), + dynaFnToSql('firstDayOfYear', $allStates, ^ToSql(format='dateadd(DAY, -(datepart(dayofyear, %s) - 1), %s)', transform={p:String[1] | $p->repeat(2)})), + dynaFnToSql('firstHourOfDay', $allStates, ^ToSql(format='datetime(date(%s))')), + dynaFnToSql('firstMillisecondOfSecond', $allStates, ^ToSql(format='dateadd(microsecond, -(datepart(microsecond, %s)), %s)', transform={p:String[1] | $p->repeat(2)})), + dynaFnToSql('firstMinuteOfHour', $allStates, ^ToSql(format='dateadd(hour, datepart(hour, %s), date(%s))', transform={p:String[1] | $p->repeat(2)})), + dynaFnToSql('firstSecondOfMinute', $allStates, ^ToSql(format='dateadd(minute, datepart(minute, %s), dateadd(hour, datepart(hour, %s), date(%s)))', transform={p:String[1] | $p->repeat(3)})), + dynaFnToSql('hour', $allStates, ^ToSql(format='hour(%s)')), + dynaFnToSql('indexOf', $allStates, ^ToSql(format='LOCATE(%s)', transform={p:String[2] | $p->at(0) + ', ' + $p->at(1)})), + dynaFnToSql('isEmpty', $selectOutsideWhen, ^ToSql(format='case when (%s is null) then \'true\' else \'false\' end', parametersWithinWhenClause=true)), + dynaFnToSql('isEmpty', $notSelectOutsideWhen, ^ToSql(format='%s is null')), + dynaFnToSql('isNotEmpty', $selectOutsideWhen, ^ToSql(format='case when (%s is not null) then \'true\' else \'false\' end', parametersWithinWhenClause=true)), + dynaFnToSql('isNotEmpty', $notSelectOutsideWhen, ^ToSql(format='%s is not null')), + dynaFnToSql('isNotNull', $selectOutsideWhen, ^ToSql(format='case when (%s is not null) then \'true\' else \'false\' end', parametersWithinWhenClause=true)), + dynaFnToSql('isNotNull', $notSelectOutsideWhen, ^ToSql(format='%s is not null')), + dynaFnToSql('isNull', $selectOutsideWhen, ^ToSql(format='case when (%s is null) then \'true\' else \'false\' end', parametersWithinWhenClause=true)), + dynaFnToSql('isNull', $notSelectOutsideWhen, ^ToSql(format='%s is null')), + dynaFnToSql('isNumeric', $allStates, ^ToSql(format='isnumeric(%s)')), + dynaFnToSql('joinStrings', $allStates, ^ToSql(format='list(%s,%s)')), + dynaFnToSql('left', $allStates, ^ToSql(format='left(%s,%s)')), + dynaFnToSql('length', $allStates, ^ToSql(format='char_length(%s)')), + dynaFnToSql('matches', $allStates, ^ToSql(format=regexpPattern('%s'), transform={p:String[2]|$p->transformRegexpParams()})), + dynaFnToSql('md5', $allStates, ^ToSql(format='hash(%s, \'MD5\')')), + dynaFnToSql('minute', $allStates, ^ToSql(format='minute(%s)')), + dynaFnToSql('mod', $allStates, ^ToSql(format='mod(%s,%s)')), + dynaFnToSql('month', $allStates, ^ToSql(format='month(%s)')), + dynaFnToSql('monthNumber', $allStates, ^ToSql(format='month(%s)')), + dynaFnToSql('mostRecentDayOfWeek', $allStates, ^ToSql(format='dateadd(Day, case when %s - dow(%s) > 0 then %s - dow(%s) - 7 else %s - dow(%s) end, %s)', transform={p:String[1..2] | $p->formatMostRecentSybase('today()')}, parametersWithinWhenClause = [false, false])), + dynaFnToSql('now', $allStates, ^ToSql(format='now(%s)', transform={p:String[*] | ''})), + dynaFnToSql('parseDate', $allStates, ^ToSql(format='%s', transform={p:String[*] | if( $p->size()==1,|'cast('+$p->at(0)+' as timestamp)' ,|'convert( datetime,'+ $p->at(0)+','+$p->at(1)+')' )})), + dynaFnToSql('parseDecimal', $allStates, ^ToSql(format='cast(%s as decimal)')), + dynaFnToSql('parseFloat', $allStates, ^ToSql(format='cast(%s as float)')), + dynaFnToSql('parseInteger', $allStates, ^ToSql(format='cast(%s as integer)')), + dynaFnToSql('position', $allStates, ^ToSql(format='charindex(%s, %s)')), + dynaFnToSql('previousDayOfWeek', $allStates, ^ToSql(format='dateadd(DAY, case when %s - dow(%s) >= 0 then %s - dow(%s) - 7 else %s - dow(%s) end, %s)', transform={p:String[1..2] | $p->formatMostRecentSybase('today()')}, parametersWithinWhenClause = [false, false])), + dynaFnToSql('quarter', $allStates, ^ToSql(format='quarter(%s)')), + dynaFnToSql('quarterNumber', $allStates, ^ToSql(format='quarter(%s)')), + dynaFnToSql('rem', $allStates, ^ToSql(format='mod(%s,%s)')), + dynaFnToSql('right', $allStates, ^ToSql(format='right(%s,%s)')), + dynaFnToSql('round', $allStates, ^ToSql(format='round(%s, %s)', transform=transformRound_String_MANY__String_MANY_)), + dynaFnToSql('second', $allStates, ^ToSql(format='second(%s)')), + dynaFnToSql('sha1', $allStates, ^ToSql(format='hash(%s, \'SHA1\')')), + dynaFnToSql('sha256', $allStates, ^ToSql(format='hash(%s, \'SHA256\')')), + dynaFnToSql('substring', $allStates, ^ToSql(format='substring%s', transform={p:String[*]|$p->joinStrings('(', ', ', ')')})), + dynaFnToSql('stdDevPopulation', $allStates, ^ToSql(format='stddev_pop(%s)')), + dynaFnToSql('stdDevSample', $allStates, ^ToSql(format='stddev_samp(%s)')), + dynaFnToSql('today', $allStates, ^ToSql(format='today(%s)', transform={p:String[*] | ''})), + dynaFnToSql('toDecimal', $allStates, ^ToSql(format='cast(%s as decimal)')), + dynaFnToSql('toFloat', $allStates, ^ToSql(format='cast(%s as double)')), + dynaFnToSql('toString', $allStates, ^ToSql(format='cast(%s as varchar)')), + dynaFnToSql('toTimestamp', $allStates, ^ToSql(format='%s', transform={p:String[2] | $p->transformToTimestampSparkSQL()})), + dynaFnToSql('weekOfYear', $allStates, ^ToSql(format='datepart(WEEK,%s)')), + dynaFnToSql('year', $allStates, ^ToSql(format='year(%s)')) + ]; +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::convertToDateIQ(params:String[*]):String[1] +{ + $params->convertDateFunctionHasCorrectParams(); + let dateFormat = if( $params->size() == 1,| 120,| dateFormats()->get($params->at(1)->replace('\'', ''))->toOne();); + if ($dateFormat == 106, + |'convert ( date,(\'01 \' + ' + 'substring(' + $params->at(0) + ',1,3)' + ' + \' \' + ' + 'substring(' + $params->at(0) + ',4,4))' + ',' + $dateFormat->toString() + ')', + |'convert ( date,'+$params->at(0)+','+$dateFormat->toString() +')';); +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::transformLikeParamsForSparkSQL(params: String[2]):String[*] +{ + let likeExpression = $params->at(1)->removeQuotes()->escapeLikeExprForSparkSQL(); + $params->at(0) + ->concatenate($likeExpression) + ->concatenate(likeEscapeClauseForSparkSQL($likeExpression)); +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::likeEscapeClauseForSparkSQL(expr: String[1]):String[*] +{ + if($expr->contains('\\'), + |' escape \'\\\'', + |''); +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::escapeLikeExprForSparkSQL(query: String[1]):String[1] +{ + // Escaping references... + // Sybase IQ: http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc38151.1520/html/iqrefbb/CACGCGGC.htm + + $query + ->replace('_', '\\_') + ->replace('%', '\\%') + ->replace('[', '\\['); +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::convertToDateTimeIQ(params:String[*]):String[1] +{ + $params->convertDateTimeFunctionHasCorrectParams(); + let dateTimeFormat = if( $params->size() == 1,| 120 ,| dateTimeFormats()->get($params->at(1)->replace('\'', ''))->toOne();); + //http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc38151.1520/html/iqrefbb/Dateformat.htm + 'convert( timestamp,'+$params->at(0)+','+$dateTimeFormat->toString() +')'; +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::transformToTimestampSparkSQL(params:String[2]):String[1] +{ + // Temporarily revert functionality to handle scenarios that have date string of the format yyyyMMdd + 'cast('+$params->at(0)+' as timestamp)'; + + //Standardizing the format as per Postgres specification, will include mappings for the formats in future. + // assert($params->at(1)->replace('\'', '') == 'YYYY-MM-DD HH24:MI:SS', | $params->at(1) +' not supported '); + // let timestampFormat = 121; + // 'convert(datetime,'+$params->at(0)+','+$timestampFormat->toString() +')'; +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::formatMostRecentSybase(p:String[1..2], defaultDay:String[1]):String[*] +{ + let day = $p->last()->toOne()->mapToDBDayOfWeekNumber()->toString(); + let current = if ($p->size() == 2, | $p->first()->toOne(), | $defaultDay); + [$day, $current, $day, $current, $day, $current, $current]; +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::processDateDiffDurationUnitForSparkSQL(durationUnit:String[1]):String[1] +{ + let durationEnumNames = [DurationUnit.YEARS,DurationUnit.MONTHS,DurationUnit.WEEKS,DurationUnit.DAYS,DurationUnit.HOURS,DurationUnit.MINUTES,DurationUnit.SECONDS,DurationUnit.MILLISECONDS]->map(e|$e->toString()); + let durationDbNames = ['yy', 'mm', 'wk', 'dd', 'hh', 'mi', 'ss', 'ms']; + $durationEnumNames->zip($durationDbNames)->filter(h | $h.first == $durationUnit).second->toOne(); +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::transformAlphaNumericParamsForSparkSQL(params: String[1]):String[*] +{ + let param = '\'[^a-zA-Z0-9]\''; + let expression = $param->removeQuotes(); + $params->at(0)->concatenate($expression); +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::processJoinStringsOperationForSparkSQL(js:JoinStrings[1], sgc:SqlGenerationContext[1]): String[1] +{ + processJoinStringsOperation($js, $sgc, {col, sep| 'list(' + $col + ',' + $sep + ' )'}, {strs, sep| $strs->joinStrings(if('\'\'' == $sep, |'+', |'+' + $sep + '+'))}); +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::processSelectSQLQueryForSparkSQL(s:SelectSQLQuery[1], sgc:SqlGenerationContext[1], isSubSelect:Boolean[1]):String[1] +{ + $s->processSelectSQLQueryForSparkSQL($sgc.dbConfig, $sgc.format, $sgc.config, $isSubSelect, $sgc.extensions); +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::processSelectSQLQueryForSparkSQL(sq:SelectSQLQuery[1], dbConfig : DbConfig[1], format:Format[1], config:Config[1], isSubSelect : Boolean[1], extensions:Extension[*]):String[1] +{ + // Sybase IQ does not support limit / offset in a subselect, so we need to adjust it, e.g. + // select * from (select top 10 "root".id as "ID" from trades as "root" ) as x + // gives + // SQL Anywhere Error -1001030: Feature, TOP/FIRST/LIMIT in a view, is not supported. + // but instead needs to be + // select * from (select "limitoffset_via_window_subquery"."ID" as "ID" from (select "root".id as "ID", row_number() OVER (Order By "root".id) as "row_number" from trades as "root") + // as "limitoffset_via_window_subquery" where "limitoffset_via_window_subquery".row_number < 10) as x + // Also see https://www.jooq.org/doc/3.1/manual/sql-building/sql-statements/select-statement/limit-clause/#N467C4 + + let s = if($isSubSelect && ($sq.fromRow->isNotEmpty() || $sq.toRow->isNotEmpty()), |$sq->rewriteSliceAsWindowFunction(), |$sq); + let opStr = if($s.filteringOperation->isEmpty(), |'', |$s.filteringOperation->map(s|$s->wrapAsBooleanOperation($extensions)->processOperation($dbConfig, $format->indent(), ^$config(callingFromFilter = true), $extensions))->filter(s|$s != '')->joinStrings(' <||> ')); + let havingStr = if($s.havingOperation->isEmpty(), |'', |$s.havingOperation->map(s|$s->processOperation($dbConfig, $format->indent(), $config, $extensions))->filter(s|$s != '')->joinStrings(' <||> ')); + + $format.separator + 'select ' + if($s.distinct == true,|'distinct ',|'') + processTop($s, $format, $dbConfig, $extensions) + + processSelectColumns($s.columns, $dbConfig, $format->indent(), false, $extensions) + + if ($s.data == [],|'',| ' ' + $format.separator + 'from ' + $s.data->toOne()->processJoinTreeNode([], $dbConfig, $format->indent(), [], $extensions)) + + if (eq($opStr, ''), |'', | ' ' + $format.separator + 'where ' + $opStr) + + if ($s.groupBy->isEmpty(),|'',| ' ' + $format.separator + 'group by '+$s.groupBy->processGroupByColumns($dbConfig, $format->indent(), true, $extensions)->makeString(','))+ + if (eq($havingStr, ''), |'', | ' ' + $format.separator + 'having ' + $havingStr) + + if ($s.orderBy->isEmpty(),|'',| ' ' + $format.separator + 'order by '+ $s.orderBy->processOrderBy($dbConfig, $format->indent(), $config, $extensions)->makeString(','))+ + + processLimit($s, $dbConfig, $format, $extensions, [], processSliceOrDropForSparkSQL_SelectSQLQuery_1__Format_1__DbConfig_1__Extension_MANY__Any_1__String_1_); +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::processSliceOrDropForSparkSQL(s:SelectSQLQuery[1], format:Format[1], dbConfig : DbConfig[1], extensions:Extension[*], size:Any[1]):String[1] +{ + // queries where specifying query with "limit 100,1000" would return 1100 rows. + // However when a order by column is specified, the expected number of rows is returned (i.e. 900 rows). + // Given that a slice without an order is largely meaningless, we'll simply report an error (rather than trying to simulate something) + // + // http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc00801.1601/doc/html/san1281564978024.html + + assert($s.orderBy->isNotEmpty(), | 'SparkSQL requires an order by column for meaningful limit/offset'); + '%s limit %s,%s'->format([$format.separator, $s.fromRow->toOne()->getValueForTake($format, $dbConfig, $extensions), $size]); +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::columnNameToIdentifierForSparkSQL(columnName: String[1], dbConfig: DbConfig[1]): String[1] +{ + if($dbConfig.isDbReservedIdentifier($columnName->toLower()), |'"' + $columnName->toLower() + '"', |$columnName->quoteIdentifierDefault()); +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::dayOfWeekNumberSparkSQL(dayOfWeek: String[*]):String[1] +{ + let day = if(startsWith($dayOfWeek->at(1),'\''),|$dayOfWeek->at(1)->removeQuotes(),|$dayOfWeek->at(1)); + assert(or($day == 'Sunday',$day == 'Monday'),'DayOfWeekNumber Function requires either Sunday or Monday as First Day of Week'); + if($day =='Sunday',|'datepart(Weekday,'+$dayOfWeek->at(0)+')',|'mod (datepart(weekday,'+$dayOfWeek->at(0)+')+5,7)+1'); +} + +function meta::relational::functions::sqlQueryToString::sparkSQL::translateCreateTableStatementForSparkSQL(c:CreateTableSQL[1], dbConfig: DbConfig[1]): String[1] +{ + let columns = $c.table.columns->map(r|$r->match([c:Column[1]| '[' + $c.name->processColumnName($dbConfig) + '] ' + $c.type->getColumnTypeSqlTextDefault(), + r:RelationalOperationElement[1]| fail('Only \'Column\' types are supported when creating temporary tables, found: '+$r->type()->toOne()->elementToPath());'';])); + + if($c.isTempTable->isTrue(),| 'DECLARE LOCAL TEMPORARY TABLE ' + $c.table->tableToString($dbConfig) + '('+ $columns->joinStrings(',') + ') ON COMMIT PRESERVE ROWS' + ,| $c->meta::relational::functions::sqlQueryToString::default::translateCreateTableStatementDefault($dbConfig)); + +} + +function meta::relational::functions::sqlQueryToString::sparkSQL::loadValuesToDbTableForSparkSQL(l:LoadTableSQL[1], dbConfig: DbConfig[1]): String[*] +{ + let columns = $l.table.columns->map(r|$r->match([c:Column[1]| $c.name->toOne(), + r:RelationalOperationElement[1]| fail('Only \'Column\' types are supported when creating temporary tables, found: '+$r->type()->toOne()->elementToPath());'';])); + + if($l.absolutePathToFile->isNotEmpty(),| 'load table ' + $l.table->tableToString($dbConfig) +'( '+ $columns->map(c|'['+$c + '] null(blanks)')->joinStrings(',') + ' ) USING CLIENT FILE \'' + $l.absolutePathToFile->toOne()->processOperation($dbConfig.dbType, []) + '\' FORMAT BCP \nwith checkpoint on \nquotes on \nescapes off \ndelimited by \',\' \nROW DELIMITED BY \'\r\n\''; + + ,| $l->meta::relational::functions::sqlQueryToString::default::loadValuesToDbTableDefault($dbConfig)); +} + +function <> meta::relational::functions::sqlQueryToString::sparkSQL::sybaseReservedWords():String[*] +{ + //Based on + // http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc38151.1510/html/iqrefbb/Alhakeywords.htm + // and + // http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc38151.1601/doc/html/san1278452828146.html + + [ + 'active', + 'add', + 'algorithm', + 'all', + 'alter', + 'and', + 'any', + 'append', + 'array', + 'as', + 'asc', + 'attach', + 'auto', + 'backup', + 'begin', + 'between', + 'bigint', + 'binary', + 'bit', + 'bottom', + 'break', + 'by', + 'calibrate', + 'calibration', + 'call', + 'cancel', + 'capability', + 'cascade', + 'case', + 'cast', + 'certificate', + 'char', + 'char_convert', + 'character', + 'check', + 'checkpoint', + 'checksum', + 'clientport', + 'close', + 'columns', + 'comment', + 'commit', + 'committed', + 'comparisons', + 'compressed', + 'computes', + 'conflict', + 'connect', + 'constraint', + 'contains', + 'continue', + 'convert', + 'create', + 'cross', + 'cube', + 'current', + 'current_timestamp', + 'current_user', + 'cursor', + 'date', + 'datetimeoffset', + 'dbspace', + 'dbspacename', + 'deallocate', + 'debug', + 'dec', + 'decimal', + 'declare', + 'decoupled', + 'decrypted', + 'default', + 'delay', + 'delete', + 'deleting', + 'density', + 'desc', + 'detach', + 'deterministic', + 'disable', + 'distinct', + 'do', + 'double', + 'drop', + 'dynamic', + 'elements', + 'else', + 'elseif', + 'enable', + 'encapsulated', + 'encrypted', + 'end', + 'endif', + 'escape', + 'except', + 'exception', + 'exclude', + 'exec', + 'execute', + 'existing', + 'exists', + 'explicit', + 'express', + 'externlogin', + 'fastfirstrow', + 'fetch', + 'first', + 'float', + 'following', + 'for', + 'force', + 'foreign', + 'forward', + 'from', + 'full', + 'gb', + 'goto', + 'grant', + 'group', + 'grouping', + 'having', + 'hidden', + 'history', + 'holdlock', + 'identified', + 'if', + 'in', + 'inactive', + 'index', + 'index_lparen', + 'inner', + 'inout', + 'input', + 'insensitive', + 'insert', + 'inserting', + 'install', + 'instead', + 'int', + 'integer', + 'integrated', + 'intersect', + 'into', + 'iq', + 'is', + 'isolation', + 'jdk', + 'join', + 'json', + 'kb', + 'kerberos', + 'key', + 'lateral', + 'left', + 'like', + 'limit', + 'lock', + 'logging', + 'login', + 'long', + 'match', + 'mb', + 'membership', + 'merge', + 'message', + 'mode', + 'modify', + 'namespace', + 'natural', + 'nchar', + 'new', + 'no', + 'noholdlock', + 'nolock', + 'not', + 'notify', + 'null', + 'numeric', + 'nvarchar', + 'of', + 'off', + 'on', + 'open', + 'openstring', + 'openxml', + 'optimization', + 'option', + 'options', + 'or', + 'order', + 'others', + 'out', + 'outer', + 'over', + 'pages', + 'paglock', + 'partial', + 'partition', + 'passthrough', + 'password', + 'plan', + 'preceding', + 'precision', + 'prepare', + 'primary', + 'print', + 'privileges', + 'proc', + 'procedure', + 'proxy', + 'publication', + 'raiserror', + 'range', + 'raw', + 'readcommitted', + 'readonly', + 'readpast', + 'readtext', + 'readuncommitted', + 'readwrite', + 'real', + 'recursive', + 'reference', + 'references', + 'refresh', + 'release', + 'relocate', + 'remote', + 'remove', + 'rename', + 'reorganize', + 'repeatable', + 'repeatableread', + 'reserve', + 'resizing', + 'resource', + 'restore', + 'restrict', + 'return', + 'revoke', + 'right', + 'rollback', + 'rollup', + 'root', + 'row', + 'rowlock', + 'rows', + 'rowtype', + 'save', + 'savepoint', + 'schedule', + 'scroll', + 'secure', + 'select', + 'sensitive', + 'serializable', + 'service', + 'session', + 'set', + 'setuser', + 'share', + 'smallint', + 'soapaction', + 'some', + 'space', + 'spatial', + 'sqlcode', + 'sqlstate', + 'start', + 'stop', + 'subtrans', + 'subtransaction', + 'synchronize', + 'syntax_error', + 'table', + 'tablock', + 'tablockx', + 'tb', + 'temporary', + 'then', + 'ties', + 'time', + 'timestamp', + 'tinyint', + 'to', + 'top', + 'tran', + 'transaction', + 'transactional', + 'transfer', + 'treat', + 'tries', + 'trigger', + 'truncate', + 'tsequal', + 'unbounded', + 'uncommitted', + 'union', + 'unique', + 'uniqueidentifier', + 'unknown', + 'unnest', + 'unsigned', + 'update', + 'updating', + 'updlock', + 'url', + 'user', + 'using', + 'utc', + 'validate', + 'values', + 'varbinary', + 'varbit', + 'varchar', + 'variable', + 'varray', + 'varying', + 'view', + 'virtual', + 'wait', + 'waitfor', + 'web', + 'when', + 'where', + 'while', + 'window', + 'with', + 'with_cube', + 'with_lparen', + 'with_rollup', + 'withauto', + 'within', + 'word', + 'work', + 'writeserver', + 'writetext', + 'xlock', + 'xml' + ] +} diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/sqlQueryToString/tests/testSparkSQLToSQLString.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/sqlQueryToString/tests/testSparkSQLToSQLString.pure new file mode 100644 index 00000000000..df1159a3514 --- /dev/null +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/sqlQueryToString/tests/testSparkSQLToSQLString.pure @@ -0,0 +1,773 @@ +//// Copyright 2023 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. +// +//import meta::relational::tests::functions::sqlstring::*; +//import meta::pure::mapping::*; +//import meta::relational::functions::asserts::*; +//import meta::relational::mapping::*; +//import meta::relational::tests::*; +//import meta::relational::tests::model::simple::*; +//import meta::pure::profiles::*; +//import meta::relational::functions::sqlstring::*; +//import meta::relational::runtime::*; +// +//function meta::relational::tests::functions::sqlstring::sybaseIQ::testCasesForDocGeneration():TestCase[*] +//{ +// [ +// ^TestCase( +// id ='testToSqlGenerationForBooleanInProject_SybaseIQ_StartsWith', +// query = |Person.all()->project([ +// a | $a.firstName->startsWith('tri') +// ], +// ['a']), +// mapping = simpleRelationalMapping, +// dbType = DatabaseType.SybaseIQ, +// expectedSql = 'select case when ("root".FIRSTNAME like \'tri%\') then \'true\' else \'false\' end as "a" from personTable as "root"', +// generateUsageFor = [meta::pure::functions::string::startsWith_String_1__String_1__Boolean_1_] +// ), +// +// ^TestCase( +// id ='testToSQLStringJoinStrings_SybaseIQ', +// query = {|Firm.all()->groupBy([f|$f.legalName], +// agg(x|$x.employees.firstName,y|$y->joinStrings('*')), +// ['legalName', 'employeesFirstName'] +// )}, +// mapping = meta::relational::tests::simpleRelationalMapping, +// dbType = meta::relational::runtime::DatabaseType.SybaseIQ, +// expectedSql = 'select "root".LEGALNAME as "legalName", list("personTable_d#4_d_m1".FIRSTNAME,\'*\') as "employeesFirstName" from firmTable as "root" left outer join personTable as "personTable_d#4_d_m1" on ("root".ID = "personTable_d#4_d_m1".FIRMID) group by "legalName"', +// generateUsageFor = [meta::pure::functions::string::joinStrings_String_MANY__String_1__String_1_] +// ) +// ] +//} +// +//function meta::relational::tests::functions::sqlstring::sybaseIQ::runTestCaseById(testCaseId: String[1]): Boolean[1] +//{ +// let filtered = meta::relational::tests::functions::sqlstring::sybaseIQ::testCasesForDocGeneration()->filter(c|$c.id==$testCaseId); +// assert($filtered->size()==1, 'Number of test cases found is not 1.'); +// let testCase = $filtered->toOne(); +// +// let result = toSQLString($testCase.query, $testCase.mapping, $testCase.dbType, meta::relational::extension::relationalExtensions()); +// assertEquals($testCase.expectedSql, $result, '\nSQL not as expected for \'%s\'\n\nexpected: %s\nactual: %s', [$testCase.id, $testCase.expectedSql, $result]); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringWithConditionalProjectSybaseIQ():Boolean[1] +//{ +// let s = toSQLString(|Person.all()->project(p|$p.firstName == 'John', 'isJohn'), meta::relational::tests::simpleRelationalMapping, meta::relational::runtime::DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when ("root".FIRSTNAME = \'John\') then \'true\' else \'false\' end as "isJohn" from personTable as "root"', $s); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringJoinStrings():Boolean[1] +//{ +// meta::relational::tests::functions::sqlstring::sybaseIQ::runTestCaseById('testToSQLStringJoinStrings_SybaseIQ'); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringJoinStringsSimpleConcat():Boolean[1] +//{ +// let fn = {|Person.all()->project([p | $p.firstName + '_' + $p.lastName], ['firstName_lastName'])}; +// let sybaseSql = toSQLString($fn, meta::relational::tests::simpleRelationalMapping, meta::relational::runtime::DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".FIRSTNAME+\'_\'+"root".LASTNAME as "firstName_lastName" from personTable as "root"', $sybaseSql); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testProcessLiteralForIQ():Boolean[1] +//{ +// let result = toSQLString(|Person.all()->project([ +// a | 'String', +// b | %2016-03-01, +// c | %2016-03-01T12:18:18.976+0200, +// d | 1, +// e | 1.1 +// ], +// ['a','b','c','d', 'e'])->take(0), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// print($result); +// assertEquals('select top 0 \'String\' as "a", convert(DATE, \'2016-03-01\', 121) as "b", convert(DATETIME, \'2016-03-01 10:18:18.976\', 121) as "c", 1 as "d", 1.1 as "e" from personTable as "root"', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringWithLength():Boolean[1] +//{ +// [DatabaseType.SybaseIQ]->map(db| +// let s = toSQLString(|Person.all()->project(p|length($p.firstName), 'nameLength'), simpleRelationalMapping, $db, meta::relational::extension::relationalExtensions()); +// assertEquals('select char_length("root".FIRSTNAME) as "nameLength" from personTable as "root"', $s); +// ); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringWithPosition():Boolean[1] +//{ +// [DatabaseType.SybaseIQ]->map(db| +// let s = toSQLString( +// |meta::relational::tests::mapping::propertyfunc::model::domain::Person.all()->project(p|$p.firstName, 'firstName'), +// meta::relational::tests::mapping::propertyfunc::model::mapping::PropertyfuncMapping, $db, meta::relational::extension::relationalExtensions()); +// +// assertEquals('select substring("root".FULLNAME, 0, charindex(\',\', "root".FULLNAME)-1) as "firstName" from personTable as "root"', $s); +// ); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringWithStdDevSample():Boolean[1] +//{ +// [DatabaseType.SybaseIQ]->map(db| +// let s = toSQLString( +// |meta::relational::tests::mapping::sqlFunction::model::domain::SqlFunctionDemo.all()->project(p|$p.float1StdDevSample, 'stdDevSample'), +// meta::relational::tests::mapping::sqlFunction::model::mapping::testMapping, $db, meta::relational::extension::relationalExtensions()); +// +// assertEquals('select stddev_samp("root".int1) as "stdDevSample" from dataTable as "root"', $s); +// )->distinct() == [true]; +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringWithStdDevPopulation():Boolean[1] +//{ +// [DatabaseType.SybaseIQ]->map(db| +// let s = toSQLString( +// |meta::relational::tests::mapping::sqlFunction::model::domain::SqlFunctionDemo.all()->project(p|$p.float1StdDevPopulation, 'stdDevPopulation'), +// meta::relational::tests::mapping::sqlFunction::model::mapping::testMapping, $db, meta::relational::extension::relationalExtensions()); +// +// assertEquals('select stddev_pop("root".int1) as "stdDevPopulation" from dataTable as "root"', $s); +// )->distinct() == [true]; +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testGenerateDateDiffExpressionForSybaseIQForDifferenceInYears():Boolean[1] +//{ +// let result = toSQLString(|Trade.all()->project([ +// t | dateDiff($t.settlementDateTime, now(), DurationUnit.YEARS) +// ], +// ['DiffYears']), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select datediff(yy,"root".settlementDateTime,now()) as "DiffYears" from tradeTable as "root"', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testGenerateDateDiffExpressionForSybaseIQForDifferenceInMonths():Boolean[1] +//{ +// let result = toSQLString(|Trade.all()->project([ +// t | dateDiff($t.settlementDateTime, now(), DurationUnit.MONTHS) +// ], +// ['DiffMonths']), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select datediff(mm,"root".settlementDateTime,now()) as "DiffMonths" from tradeTable as "root"', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testGenerateDateDiffExpressionForSybaseIQForDifferenceInWeeks():Boolean[1] +//{ +// let result = toSQLString(|Trade.all()->project([ +// t | dateDiff($t.settlementDateTime, now(), DurationUnit.WEEKS) +// ], +// ['DiffWeeks']), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select datediff(wk,"root".settlementDateTime,now()) as "DiffWeeks" from tradeTable as "root"', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationFirstDayOfTimePeriod():Boolean[1] +//{ +// let result = toSQLString( +// |Trade.all() +// ->project([ +// col(t|$t.date->firstHourOfDay(), 'day'), +// col(t|$t.date->firstMinuteOfHour(), 'hour'), +// col(t|$t.date->firstSecondOfMinute(), 'minute'), +// col(t|$t.date->firstMillisecondOfSecond(), 'second') +// ]), +// simpleRelationalMapping, +// DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// +// assertEquals('select datetime(date("root".tradeDate)) as "day", dateadd(hour, datepart(hour, "root".tradeDate), date("root".tradeDate)) as "hour", dateadd(minute, datepart(minute, "root".tradeDate), dateadd(hour, datepart(hour, "root".tradeDate), date("root".tradeDate))) as "minute", dateadd(microsecond, -(datepart(microsecond, "root".tradeDate)), "root".tradeDate) as "second" from tradeTable as "root"', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testGenerateDateDiffExpressionForSybaseIQForDifferenceInDays():Boolean[1] +//{ +// let result = toSQLString(|Trade.all()->project([ +// t | dateDiff($t.settlementDateTime, now(), DurationUnit.DAYS) +// ], +// ['DiffDays']), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select datediff(dd,"root".settlementDateTime,now()) as "DiffDays" from tradeTable as "root"', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testGenerateDateDiffExpressionForSybaseIQForDifferenceInHours():Boolean[1] +//{ +// let result = toSQLString(|Trade.all()->project([ +// t | dateDiff($t.settlementDateTime, now(), DurationUnit.HOURS) +// ], +// ['DiffHours']), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select datediff(hh,"root".settlementDateTime,now()) as "DiffHours" from tradeTable as "root"', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testGenerateDateDiffExpressionForSybaseIQForDifferenceInMinutes():Boolean[1] +//{ +// let result = toSQLString(|Trade.all()->project([ +// t | dateDiff($t.settlementDateTime, now(), DurationUnit.MINUTES) +// ], +// ['DiffMinutes']), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select datediff(mi,"root".settlementDateTime,now()) as "DiffMinutes" from tradeTable as "root"', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testGenerateDateDiffExpressionForSybaseIQForDifferenceInSeconds():Boolean[1] +//{ +// let result = toSQLString(|Trade.all()->project([ +// t | dateDiff($t.settlementDateTime, now(), DurationUnit.SECONDS) +// ], +// ['DiffSeconds']), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select datediff(ss,"root".settlementDateTime,now()) as "DiffSeconds" from tradeTable as "root"', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testGenerateDateDiffExpressionForSybaseIQForDifferenceInMilliseconds():Boolean[1] +//{ +// let result = toSQLString(|Trade.all()->project([ +// t | dateDiff($t.settlementDateTime, now(), DurationUnit.MILLISECONDS) +// ], +// ['DiffMilliseconds']), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select datediff(ms,"root".settlementDateTime,now()) as "DiffMilliseconds" from tradeTable as "root"', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testDayOfYear():Boolean[1] +//{ +// let expected = [ +// pair(DatabaseType.SybaseIQ, 'select datepart(DAYOFYEAR,"root".tradeDate) as "doy" from tradeTable as "root"') +// ]; +// +// $expected->map(p| +// let driver = $p.first; +// let expectedSql = $p.second; +// +// let result = toSQLString( +// |Trade.all() +// ->project(col(t|$t.date->dayOfYear(), 'doy')), +// simpleRelationalMapping, +// $driver, meta::relational::extension::relationalExtensions()); +// +// assertEquals($expectedSql, $result, '\nSQL not as expected for %s\n\nexpected: %s\nactual: %s', [$driver, $expectedSql, $result]); +// )->distinct() == [true]; +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testTrim():Boolean[1] +//{ +// let common = 'select ltrim("root".FIRSTNAME) as "ltrim", trim("root".FIRSTNAME) as "trim", rtrim("root".FIRSTNAME) as "rtrim" from personTable as "root"'; +// +// let expected = [ +// pair(DatabaseType.SybaseIQ, $common) +// ]; +// +// $expected->map(p| +// let driver = $p.first; +// let expectedSql = $p.second; +// +// let result = toSQLString( +// |Person.all()->project([ +// a | $a.firstName->ltrim(), +// a | $a.firstName->trim(), +// a | $a.firstName->rtrim() +// ], +// ['ltrim', 'trim', 'rtrim']), +// simpleRelationalMapping, +// $driver, meta::relational::extension::relationalExtensions()); +// +// assertEquals($expectedSql, $result, '\nSQL not as expected for %s\n\nexpected: %s\nactual: %s', [$driver, $expectedSql, $result]); +// )->distinct() == [true]; +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testCbrt():Boolean[1] +//{ +// let common = 'select cbrt("root".quantity) as "cbrt" from tradeTable as "root"'; +// +// let expected = [ +// pair(DatabaseType.SybaseIQ, $common) +// ]; +// +// $expected->map(p| +// let driver = $p.first; +// let expectedSql = $p.second; +// +// let result = toSQLString( +// |Trade.all()->project([ +// a | $a.quantity->cbrt() +// ], +// ['cbrt']), +// simpleRelationalMapping, +// $driver, meta::relational::extension::relationalExtensions()); +// +// assertEquals($expectedSql, $result, '\nSQL not as expected for %s\n\nexpected: %s\nactual: %s', [$driver, $expectedSql, $result]); +// )->distinct() == [true]; +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInProject_SybaseIQ_StartsWith():Boolean[1] +//{ +// meta::relational::tests::functions::sqlstring::sybaseIQ::runTestCaseById('testToSqlGenerationForBooleanInProject_SybaseIQ_StartsWith'); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInFilter_SybaseIQ():Boolean[1] +//{ +// let result = toSQLString(|Interaction.all()->filter(a | $a.active)->project([i | $i.id],['id']), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" where case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\'', $result); +//} +// +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInFilterWithAnd_SybaseIQ():Boolean[1] +//{ +// let result = toSQLString(|Interaction.all()->filter(a | $a.id == 1 && $a.active)->project([i | $i.id],['id']), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" where ("root".ID = 1 and case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\')', $result); +//} +// +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInFilterWithAnd_WithDistinct_SybaseIQ():Boolean[1] +//{ +// let result = toSQLString(|Interaction.all()->filter(a | $a.id == 1 && $a.active)->project([i | $i.id],['id'])->distinct(), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select distinct "root".ID as "id" from interactionTable as "root" where ("root".ID = 1 and case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\')', $result); +//} +// +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInFilterWithAndIsNull_SybaseIQ():Boolean[1] +//{ +// let result = toSQLString(|Interaction.all()->filter(a | $a.id->isEmpty() && $a.active)->project([i | $i.id],['id']), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" where ("root".ID is null and case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\')', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInFilterWithAndNotEqual_SybaseIQ():Boolean[1] +//{ +// let result = toSQLString(|Interaction.all()->filter(a | $a.id != 1 && $a.active)->project([i | $i.id],['id']), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" where (("root".ID <> 1 OR "root".ID is null) and case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\')', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForConstanNumInFilterWithNotEqual_SybaseIQ():Boolean[1] +//{ +// let result = toSQLString(|Synonym.all()->filter(s | $s.type != 'ISIN')->project([s | $s.name],['name']), +// simpleRelationalMappingWithEnumConstant, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".NAME as "name" from productSchema.synonymTable as "root" where (\'CUSIP\' <> \'ISIN\')', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInProject_SybaseIQ_IsEmpty():Boolean[1] +//{ +// let result = toSQLString(|Person.all()->project([ +// a | $a.firstName->isEmpty() +// ], +// ['a']), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when ("root".FIRSTNAME is null) then \'true\' else \'false\' end as "a" from personTable as "root"', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInProject_SybaseIQ_And():Boolean[1] +//{ +// let result = toSQLString(|Person.all()->project([ +// a | $a.firstName == 'A' && $a.lastName == 'B' +// ], +// ['a']), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when (("root".FIRSTNAME = \'A\' and "root".LASTNAME = \'B\')) then \'true\' else \'false\' end as "a" from personTable as "root"', $result); +//} +// +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInProject_SybaseIQ_If():Boolean[1] +//{ +// let result = toSQLString(|Person.all()->project([ +// a | if ($a.firstName == 'A', | true, | false) +// ], +// ['a']), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when "root".FIRSTNAME = \'A\' then \'true\' else \'false\' end as "a" from personTable as "root"', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInFilter_SybaseIQ_If():Boolean[1] +//{ +// let result = toSQLString(|Person.all()->filter(a | if ($a.firstName == 'A', | true, | false)), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "pk_0", "root".FIRSTNAME as "firstName", "root".AGE as "age", "root".LASTNAME as "lastName" from personTable as "root" where case when "root".FIRSTNAME = \'A\' then \'true\' else \'false\' end = \'true\'', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInProject_SybaseIQ_NestedIf():Boolean[1] +//{ +// let result = toSQLString(|Person.all()->project([ +// a | if ( if ($a.firstName == 'B', | true, | false), | true, | false) +// ], +// ['a']), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when case when "root".FIRSTNAME = \'B\' then \'true\' else \'false\' end = \'true\' then \'true\' else \'false\' end as "a" from personTable as "root"', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInProject_SybaseIQ_Or():Boolean[1] +//{ +// let result = toSQLString(|Person.all()->project([ +// a | true || false +// ], +// ['a']), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when ((\'true\' = \'true\' or \'false\' = \'true\')) then \'true\' else \'false\' end as "a" from personTable as "root"', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testSqlGenerationForDatePartForSybaseIQ():Boolean[1] +//{ +// let result = toSQLString(|Location.all()->project([ +// a | $a.censusdate->toOne()->datePart() +// ], +// ['a']), +// simpleRelationalMappingInc, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select date("root"."date") as "a" from locationTable as "root"', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForProjectLambdaWithSquareBrackets_SybaseIQ():Boolean[1] +//{ +// let result = toSQLString( +// |Person.all()->project([a|$a.firstName->startsWith('Dummy [With Sq Brackets]')], ['a']), +// simpleRelationalMapping, +// DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// +// assertEquals('select case when ("root".FIRSTNAME like \'Dummy \\[With Sq Brackets]%\' escape \'\\\') then \'true\' else \'false\' end as "a" from personTable as "root"', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForFilterWithSquareBrackets_SybaseIQ():Boolean[1] +//{ +// let result = toSQLString( +// |Person.all() +// ->project([#/Person/firstName!name#]) +// ->filter(a|$a.getString('name')->startsWith('Dummy [With Sq Brackets]')), +// simpleRelationalMapping, +// DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// +// assertEquals('select "root".FIRSTNAME as "name" from personTable as "root" where "root".FIRSTNAME like \'Dummy \\[With Sq Brackets]%\' escape \'\\\'', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationFirstDayOfMonth():Boolean[1] +//{ +// let expected = [ +// pair(DatabaseType.SybaseIQ, 'select dateadd(DAY, -(day("root".tradeDate) - 1), "root".tradeDate) as "date" from tradeTable as "root"') +// ]; +// +// $expected->map(p| +// let driver = $p.first; +// let expectedSql = $p.second; +// +// let result = toSQLString( +// |Trade.all() +// ->project(col(t|$t.date->firstDayOfMonth(), 'date')), +// simpleRelationalMapping, +// $driver, meta::relational::extension::relationalExtensions()); +// +// assertEquals($expectedSql, $result, '\nSQL not as expected for %s\n\nexpected: %s\nactual: %s', [$driver, $expectedSql, $result]); +// )->distinct() == [true]; +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationFirstDayOfYear():Boolean[1] +//{ +// let expected = [ +// pair(DatabaseType.SybaseIQ, 'select dateadd(DAY, -(datepart(dayofyear, "root".tradeDate) - 1), "root".tradeDate) as "date" from tradeTable as "root"') +// ]; +// +// $expected->map(p| +// let driver = $p.first; +// let expectedSql = $p.second; +// +// let result = toSQLString( +// |Trade.all() +// ->project(col(t|$t.date->firstDayOfYear(), 'date')), +// simpleRelationalMapping, +// $driver, meta::relational::extension::relationalExtensions()); +// +// assertEquals($expectedSql, $result, '\nSQL not as expected for %s\n\nexpected: %s\nactual: %s', [$driver, $expectedSql, $result]); +// )->distinct() == [true]; +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationFirstDayOfThisYear():Boolean[1] +//{ +// let expected = [ +// pair(DatabaseType.SybaseIQ, 'select dateadd(DAY, -(datepart(dayofyear, today()) - 1), today()) as "date" from tradeTable as "root"') +// ]; +// +// $expected->map(p| +// let driver = $p.first; +// let expectedSql = $p.second; +// +// let result = toSQLString( +// |Trade.all() +// ->project(col(t|firstDayOfThisYear(), 'date')), +// simpleRelationalMapping, +// $driver, meta::relational::extension::relationalExtensions()); +// +// assertEquals($expectedSql, $result, '\nSQL not as expected for %s\n\nexpected: %s\nactual: %s', [$driver, $expectedSql, $result]); +// )->distinct() == [true]; +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationFirstDayOfQuarter_SybaseIQ():Boolean[1] +//{ +// testToSqlGenerationFirstDayOfQuarter(DatabaseType.SybaseIQ, 'select dateadd(QUARTER, quarter("root".tradeDate) - 1, dateadd(DAY, -(datepart(dayofyear, "root".tradeDate) - 1), "root".tradeDate)) as "date" from tradeTable as "root"'); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationFirstDayOfWeek():Boolean[1] +//{ +// let expected = [ +// pair(DatabaseType.SybaseIQ, 'select dateadd(DAY, -(mod(datepart(weekday, "root".tradeDate)+5, 7)), "root".tradeDate) as "date" from tradeTable as "root"') +// ]; +// +// $expected->map(p| +// let driver = $p.first; +// let expectedSql = $p.second; +// +// let result = toSQLString( +// |Trade.all() +// ->project(col(t|$t.date->firstDayOfWeek(), 'date')), +// simpleRelationalMapping, +// $driver, meta::relational::extension::relationalExtensions()); +// +// assertEquals($expectedSql, $result, '\nSQL not as expected for %s\n\nexpected: %s\nactual: %s', [$driver, $expectedSql, $result]); +// )->distinct() == [true]; +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testSqlGenerationForBooleanProject_IQ():Boolean[1] +//{ +// +// let result1a = toSQLString(|Interaction.all()->project(col(p|true, 'active')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select \'true\' as "active" from interactionTable as "root"', $result1a); +// +// let result1b = toSQLString(|Interaction.all()->project(col(p|!true, 'active')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when (not \'true\' = \'true\') then \'true\' else \'false\' end as "active" from interactionTable as "root"', $result1b); +// +// let result1c = toSQLString(|Interaction.all()->project(col(p|false, 'active')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select \'false\' as "active" from interactionTable as "root"', $result1c); +// +// let result1d = toSQLString(|Interaction.all()->project(col(p|!false, 'active')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when (not \'false\' = \'true\') then \'true\' else \'false\' end as "active" from interactionTable as "root"', $result1d); +// +// let result2 = toSQLString(|Interaction.all()->project(col(p|$p.active, 'active')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when "root"."active" = \'Y\' then \'true\' else \'false\' end as "active" from interactionTable as "root"', $result2); +// +// let result3 = toSQLString(|Interaction.all()->project(col(p|$p.active == true, 'active')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when (case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\') then \'true\' else \'false\' end as "active" from interactionTable as "root"', $result3); +// +// let result4 = toSQLString(|Interaction.all()->project(col(p|$p.active && true, 'active')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when ((case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\' and \'true\' = \'true\')) then \'true\' else \'false\' end as "active" from interactionTable as "root"', $result4); +// +// let result5 = toSQLString(|Interaction.all()->project(col(p|if($p.active, |1, |0), 'active')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\' then 1 else 0 end as "active" from interactionTable as "root"', $result5); +// +// let result6 = toSQLString(|Interaction.all()->project(col(p|$p.active->in(true), 'active')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when (case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\') then \'true\' else \'false\' end as "active" from interactionTable as "root"', $result6); +// +// let result7 = toSQLString(|Interaction.all()->project(col(p|$p.target.firstName->isEmpty(), 'active')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when ("personTable_d#5_d_m1".FIRSTNAME is null) then \'true\' else \'false\' end as "active" from interactionTable as "root" left outer join personTable as "personTable_d#5_d_m1" on ("root".targetId = "personTable_d#5_d_m1".ID)', $result7); +// +// let result10 = toSQLString(|Interaction.all()->project(col(p|!$p.target.firstName->isEmpty(), 'active')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when (not "personTable_d#6_d_m1".FIRSTNAME is null) then \'true\' else \'false\' end as "active" from interactionTable as "root" left outer join personTable as "personTable_d#6_d_m1" on ("root".targetId = "personTable_d#6_d_m1".ID)', $result10); +// +// let result13 = toSQLString(|Interaction.all()->project(col(p|($p.target.firstName->isEmpty() || $p.target.firstName->isEmpty()), 'active')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when (("personTable_d#2_dy0_d#4_d_m1".FIRSTNAME is null or "personTable_d#2_dy0_d#4_d_m1".FIRSTNAME is null)) then \'true\' else \'false\' end as "active" from interactionTable as "root" left outer join personTable as "personTable_d#2_dy0_d#4_d_m1" on ("root".targetId = "personTable_d#2_dy0_d#4_d_m1".ID)', $result13); +// +// let result14 = toSQLString(|Interaction.all()->project(col(p|($p.target.firstName->isEmpty() && $p.target.firstName->isEmpty()), 'active')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when (("personTable_d#2_dy0_d#4_d_m1".FIRSTNAME is null and "personTable_d#2_dy0_d#4_d_m1".FIRSTNAME is null)) then \'true\' else \'false\' end as "active" from interactionTable as "root" left outer join personTable as "personTable_d#2_dy0_d#4_d_m1" on ("root".targetId = "personTable_d#2_dy0_d#4_d_m1".ID)', $result14); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testSqlGenerationForBooleanProject_IQ2():Boolean[1] +//{ +// let result8 = toSQLString(|Interaction.all()->project(col(p|$p.target.firstName->isEmpty() == true, 'active')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when ("personTable_d#6_d_m1".FIRSTNAME is null) then \'true\' else \'false\' end as "active" from interactionTable as "root" left outer join personTable as "personTable_d#6_d_m1" on ("root".targetId = "personTable_d#6_d_m1".ID)', $result8); +// +// let result9 = toSQLString(|Interaction.all()->project(col(p|$p.target.firstName->isEmpty() == false, 'active')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when (not "personTable_d#6_d_m1".FIRSTNAME is null) then \'true\' else \'false\' end as "active" from interactionTable as "root" left outer join personTable as "personTable_d#6_d_m1" on ("root".targetId = "personTable_d#6_d_m1".ID)', $result9); +// +// let result11 = toSQLString(|Interaction.all()->project(col(p|$p.target.firstName->isEmpty()->in(false), 'active')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when (not "personTable_d#6_d_m1".FIRSTNAME is null) then \'true\' else \'false\' end as "active" from interactionTable as "root" left outer join personTable as "personTable_d#6_d_m1" on ("root".targetId = "personTable_d#6_d_m1".ID)', $result11); +// +// let result12 = toSQLString(|Interaction.all()->project(col(p|!($p.target.firstName->isEmpty()->in(false)), 'active')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select case when (("personTable_d#7_d_m1".FIRSTNAME is null)) then \'true\' else \'false\' end as "active" from interactionTable as "root" left outer join personTable as "personTable_d#7_d_m1" on ("root".targetId = "personTable_d#7_d_m1".ID)', $result12); +//} +// +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testSqlGenerationForBooleanFilter_IQ():Boolean[1] +//{ +// let result1a = toSQLString(|Interaction.all()->filter(p|true)->project(col(p|$p.id, 'id')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" where \'true\' = \'true\'', $result1a); +// +// let result1b = toSQLString(|Interaction.all()->filter(p|!true)->project(col(p|$p.id, 'id')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" where not \'true\' = \'true\'', $result1b); +// +// let result1c = toSQLString(|Interaction.all()->filter(p|false)->project(col(p|$p.id, 'id')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" where \'false\' = \'true\'', $result1c); +// +// let result1d = toSQLString(|Interaction.all()->filter(p|!false)->project(col(p|$p.id, 'id')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" where not \'false\' = \'true\'', $result1d); +// +// let result2 = toSQLString(|Interaction.all()->filter(p|$p.active)->project(col(p|$p.id, 'id')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" where case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\'', $result2); +// +// let result3 = toSQLString(|Interaction.all()->filter(p|$p.active == true)->project(col(p|$p.id, 'id')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" where case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\'', $result3); +// +// let result4 = toSQLString(|Interaction.all()->filter(p|$p.active && true)->project(col(p|$p.id, 'id')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" where (case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\' and \'true\' = \'true\')', $result4); +// +// let result5 = toSQLString(|Interaction.all()->filter(p|if($p.active, |1, |0) == 1)->project(col(p|$p.id, 'id')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" where case when case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\' then 1 else 0 end = 1', $result5); +// +// let result6 = toSQLString(|Interaction.all()->filter(p|$p.active->in(true))->project(col(p|$p.id, 'id')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" where case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\'', $result6); +// +// let result7 = toSQLString(|Interaction.all()->filter(p|$p.target.firstName->isEmpty())->project(col(p|$p.id, 'id')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#6_d#2_m1" on ("root".targetId = "personTable_d#6_d#2_m1".ID) where "personTable_d#6_d#2_m1".FIRSTNAME is null', $result7); +// +// let result10 = toSQLString(|Interaction.all()->filter(p|!$p.target.firstName->isEmpty())->project(col(p|$p.id, 'id')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#7_d#2_m1" on ("root".targetId = "personTable_d#7_d#2_m1".ID) where not "personTable_d#7_d#2_m1".FIRSTNAME is null', $result10); +// +// let result13 = toSQLString(|Interaction.all()->filter(p|$p.target.firstName->isEmpty() || $p.target.firstName->isEmpty())->project(col(p|$p.id, 'id')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#3_dy0_d#4_d#2_m1" on ("root".targetId = "personTable_d#3_dy0_d#4_d#2_m1".ID) where ("personTable_d#3_dy0_d#4_d#2_m1".FIRSTNAME is null or "personTable_d#3_dy0_d#4_d#2_m1".FIRSTNAME is null)', $result13); +// +// let result14 = toSQLString(|Interaction.all()->filter(p|$p.target.firstName->isEmpty() && $p.target.firstName->isEmpty())->project(col(p|$p.id, 'id')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#3_dy0_d#4_d#2_m1" on ("root".targetId = "personTable_d#3_dy0_d#4_d#2_m1".ID) where ("personTable_d#3_dy0_d#4_d#2_m1".FIRSTNAME is null and "personTable_d#3_dy0_d#4_d#2_m1".FIRSTNAME is null)', $result14); +//} +// +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testSqlGenerationForBooleanFilter_IQ2():Boolean[1] +//{ +// let result8 = toSQLString(|Interaction.all()->filter(p|$p.target.firstName->isEmpty() == true)->project(col(p|$p.id, 'id')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#7_d#2_m1" on ("root".targetId = "personTable_d#7_d#2_m1".ID) where "personTable_d#7_d#2_m1".FIRSTNAME is null', $result8); +// +// let result9 = toSQLString(|Interaction.all()->filter(p|$p.target.firstName->isEmpty() == false)->project(col(p|$p.id, 'id')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#7_d#2_m1" on ("root".targetId = "personTable_d#7_d#2_m1".ID) where not "personTable_d#7_d#2_m1".FIRSTNAME is null', $result9); +// +// let result11 = toSQLString(|Interaction.all()->filter(p|$p.target.firstName->isEmpty()->in(false))->project(col(p|$p.id, 'id')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#7_d#2_m1" on ("root".targetId = "personTable_d#7_d#2_m1".ID) where not "personTable_d#7_d#2_m1".FIRSTNAME is null', $result11); +// +// let result12 = toSQLString(|Interaction.all()->filter(p|!$p.target.firstName->isEmpty()->in(false))->project(col(p|$p.id, 'id')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#8_d#2_m1" on ("root".targetId = "personTable_d#8_d#2_m1".ID) where ("personTable_d#8_d#2_m1".FIRSTNAME is null)', $result12); +// +// let result15 = toSQLString(|Interaction.all()->filter(p|isTrue($p.target.firstName == 'Andrew')), +// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#7_d#2_m1" on ("root".targetId = "personTable_d#7_d#2_m1".ID) where ("personTable_d#7_d#2_m1".FIRSTNAME is null and "personTable_d#7_d#2_m1".FIRSTNAME is null)', $result15); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationMinuteSecond():Boolean[1] +//{ +// let expected = [ +// pair(DatabaseType.SybaseIQ, 'select minute("root".settlementDateTime) as "settlementDateTimeMinute", second("root".settlementDateTime) as "settlementDateTimeSecond" from tradeTable as "root"') +// ]; +// +// $expected->map(p| +// let driver = $p.first; +// let expectedSql = $p.second; +// +// let result = toSQLString( +// |Trade.all()->project([ +// t | $t.settlementDateTime->cast(@Date)->toOne()->minute(), +// t | $t.settlementDateTime->cast(@Date)->toOne()->second() +// ], +// ['settlementDateTimeMinute', 'settlementDateTimeSecond']), +// simpleRelationalMapping, +// $driver, meta::relational::extension::relationalExtensions()); +// +// assertEquals($expectedSql, $result, '\nSQL not as expected for %s\n\nexpected: %s\nactual: %s', [$driver, $expectedSql, $result]); +// )->distinct() == [true]; +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringWithReplace():Boolean[1] +//{ +// let sybaseSql = toSQLString(|Person.all()->project(p|$p.firstName->replace('A', 'a'), 'lowerA'), simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertEquals('select replace("root".FIRSTNAME, \'A\', \'a\') as "lowerA" from personTable as "root"', $sybaseSql); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testSybaseKeyWordInSubSelect():Boolean[1] +//{ +// let date=%2018-03-05; +// let result = meta::relational::functions::sqlstring::toSQLString(|Firm.all()->project([f|$f.legalName, f|$f.employees.locations->filter(o|$o.censusdate == $date).censusdate], ['firm','employee address census date']), simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertSameSQL('select "root".LEGALNAME as "firm", "locationTable_d#5_f_d_d_m2_r"."date" as "employee address census date" from firmTable as "root" left outer join personTable as "personTable_d#7_d_m2" on ("root".ID = "personTable_d#7_d_m2".FIRMID) left outer join (select "locationTable_d#5_f_d".PERSONID as PERSONID, "locationTable_d#5_f_d"."date" as "date" from locationTable as "locationTable_d#5_f_d" where "locationTable_d#5_f_d"."date" = convert(DATE, \'2018-03-05\', 121)) as "locationTable_d#5_f_d_d_m2_r" on ("personTable_d#7_d_m2".ID = "locationTable_d#5_f_d_d_m2_r".PERSONID)', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testSybaseDistinctTake():Boolean[1] +//{ +// let iq = meta::relational::functions::sqlstring::toSQLString(|Person.all()->project(f|$f.firstName, 'firstName')->distinct()->take(10), simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// let ase = meta::relational::functions::sqlstring::toSQLString(|Person.all()->project(f|$f.firstName, 'firstName')->distinct()->take(10), simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// +// let sql = 'select distinct top 10 "root".FIRSTNAME as "firstName" from personTable as "root"'; +// +// assertSameSQL($sql, $iq); +// assertSameSQL($sql, $ase); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testSqlGenerationDivide_AllDBs():Boolean[1] +//{ +// let query = {|Trade.all()->filter(t | $t.id == 2)->map(t | $t.quantity->divide(1000000))}; +// let expectedSQL = 'select ((1.0 * "root".quantity) / 1000000) from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" group by "root".trade_id) as "tradeEventViewMaxTradeEventDate_d#4_d#4_m5" on ("root".ID = "tradeEventViewMaxTradeEventDate_d#4_d#4_m5".trade_id) where "root".ID = 2'; +// +// let resultSybaseIQ = meta::relational::functions::sqlstring::toSQLString($query, simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertSameSQL($expectedSQL, $resultSybaseIQ); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testIsDistinctSQLGeneration():Boolean[1] +//{ +// let func = {|Firm.all()->groupBy( +// [t|$t.legalName], +// [agg(x|$x.employees.firstName,y|$y->isDistinct())], +// ['LegalName', 'IsDistinctFirstName'] +// )}; +// +// let iq = toSQLString($func, simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// assertSameSQL('select "root".LEGALNAME as "LegalName", case when (count(distinct("personTable_d#4_d_m1".FIRSTNAME)) = count("personTable_d#4_d_m1".FIRSTNAME)) then \'true\' else \'false\' end as "IsDistinctFirstName" from firmTable as "root" left outer join personTable as "personTable_d#4_d_m1" on ("root".ID = "personTable_d#4_d_m1".FIRMID) group by "LegalName"', $iq); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationDayOfMonth_SybaseIQ():Boolean[1] +//{ +// let result = toSQLString( +// |Trade.all() +// ->project(col(t|$t.date->dayOfMonth(), 'date')), +// simpleRelationalMapping, +// DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// +// assertEquals('select datepart(DAY,"root".tradeDate) as "date" from tradeTable as "root"', $result); +//} +// +//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringToNumericCasts():Boolean[1] +//{ +// let result = toSQLString( +// |Trade.all() +// ->project([ +// col(t|$t.quantity->toDecimal(), 'decimal'), +// col(t|$t.quantity->toFloat(), 'float') +// ]), simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); +// +// assertEquals('select cast("root".quantity as decimal) as "decimal", cast("root".quantity as double) as "float" from tradeTable as "root"', $result); +//} \ No newline at end of file diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/test/java/org/finos/legend/pure/code/core/Test_Pure_Relational_SparkSQL.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/test/java/org/finos/legend/pure/code/core/Test_Pure_Relational_SparkSQL.java new file mode 100644 index 00000000000..5563221ed8e --- /dev/null +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/test/java/org/finos/legend/pure/code/core/Test_Pure_Relational_SparkSQL.java @@ -0,0 +1,41 @@ +// Copyright 2023 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.pure.code.core; + +import junit.framework.TestSuite; +import org.finos.legend.pure.m3.execution.test.PureTestBuilder; +import org.finos.legend.pure.runtime.java.compiled.testHelper.PureTestBuilderCompiled; +import org.finos.legend.pure.m3.execution.test.TestCollection; +import org.finos.legend.pure.runtime.java.compiled.execution.CompiledExecutionSupport; + +public class Test_Pure_Relational_SparkSQL +{ + public static TestSuite suite() + { + CompiledExecutionSupport executionSupport = PureTestBuilderCompiled.getClassLoaderExecutionSupport(); + executionSupport.getConsole().disable(); + TestSuite suite = new TestSuite(); + +// suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::relational::tests::sqlToString::sybaseIQ", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); +// suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::relational::tests::tds::sybaseIQ", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); +// suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::pure::executionPlan::tests::sybaseIQ", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); +// suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::relational::tests::projection::sybaseIQ", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); +// suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::relational::tests::functions::sqlstring::sybaseIQ", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); +// suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::relational::tests::mapping::sqlFunction::sybaseIQ", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); +// suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::relational::tests::query::function::sybaseIQ", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); +// suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::relational::tests::postProcessor::sybaseIQ", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); + return suite; + } +} diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/test/java/org/finos/legend/pure/code/core/test/TestSparkSQLCodeRepositoryProviderAvailable.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/test/java/org/finos/legend/pure/code/core/test/TestSparkSQLCodeRepositoryProviderAvailable.java new file mode 100644 index 00000000000..a127f31c56e --- /dev/null +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/test/java/org/finos/legend/pure/code/core/test/TestSparkSQLCodeRepositoryProviderAvailable.java @@ -0,0 +1,36 @@ +// Copyright 2023 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.pure.code.core.test; + +import org.eclipse.collections.api.list.MutableList; +import org.eclipse.collections.impl.factory.Lists; +import org.finos.legend.pure.code.core.CoreRelationalSparkSQLCodeRepositoryProvider; +import org.finos.legend.pure.m3.serialization.filesystem.repository.CodeRepositoryProvider; +import org.junit.Assert; +import org.junit.Test; + +import java.util.ServiceLoader; + +public class TestSparkSQLCodeRepositoryProviderAvailable +{ + @Test + public void testCodeRepositoryProviderAvailable() + { + MutableList> codeRepositoryProviders = + Lists.mutable.withAll(ServiceLoader.load(CodeRepositoryProvider.class)) + .collect(Object::getClass); + Assert.assertTrue(codeRepositoryProviders.contains(CoreRelationalSparkSQLCodeRepositoryProvider.class)); + } +} diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/pom.xml b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/pom.xml new file mode 100644 index 00000000000..40505c3634c --- /dev/null +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/pom.xml @@ -0,0 +1,34 @@ + + + + + org.finos.legend.engine + legend-engine-xt-relationalStore-dbExtension + 4.29.2-SNAPSHOT + + 4.0.0 + + legend-engine-xt-relationalStore-sparksql + pom + Legend Engine - XT - Relational Store - DB Extension - sparksql + + + + legend-engine-xt-relationalStore-sparksql-pure + + + \ No newline at end of file diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/pom.xml b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/pom.xml index 3ca8dff84a7..6ecff5fbe1e 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/pom.xml +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/pom.xml @@ -41,6 +41,7 @@ legend-engine-xt-relationalStore-hive legend-engine-xt-relationalStore-presto legend-engine-xt-relationalStore-databricks + legend-engine-xt-relationalStore-sparksql legend-engine-xt-relationalStore-test-reports diff --git a/pom.xml b/pom.xml index fd191dac961..46eb16a34dd 100644 --- a/pom.xml +++ b/pom.xml @@ -967,6 +967,11 @@ legend-engine-xt-relationalStore-sybaseiq-pure ${project.version} + + org.finos.legend.engine + legend-engine-xt-relationalStore-sparksql-pure + ${project.version} + org.finos.legend.engine legend-engine-xt-relationalStore-hive-pure From 9421187cd966b2f127c6f36555bf338e91dc101c Mon Sep 17 00:00:00 2001 From: Yasirmod17 Date: Fri, 29 Sep 2023 21:30:59 -0400 Subject: [PATCH 03/10] Add SparkSQL modules in idelight --- .../org/finos/legend/engine/server/test/userTestConfig.json | 4 ++-- .../main/java/org/finos/legend/engine/ide/PureIDELight.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/legend-engine-config/legend-engine-server/src/test/resources/org/finos/legend/engine/server/test/userTestConfig.json b/legend-engine-config/legend-engine-server/src/test/resources/org/finos/legend/engine/server/test/userTestConfig.json index b063f6106a9..acd17396d0d 100644 --- a/legend-engine-config/legend-engine-server/src/test/resources/org/finos/legend/engine/server/test/userTestConfig.json +++ b/legend-engine-config/legend-engine-server/src/test/resources/org/finos/legend/engine/server/test/userTestConfig.json @@ -3,7 +3,7 @@ "mode": "TEST_IGNORE_FUNCTION_MATCH" }, "logging": { - "level": "info", + "level": "error", "appenders": [ { "type": "console", @@ -47,7 +47,7 @@ "connector": { "maxRequestHeaderSize": "32KiB", "type": "http", - "port": 9090 + "port": 6300 }, "requestLog": { "appenders": [ diff --git a/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light/src/main/java/org/finos/legend/engine/ide/PureIDELight.java b/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light/src/main/java/org/finos/legend/engine/ide/PureIDELight.java index af88beddcbf..ad32fdc40f1 100644 --- a/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light/src/main/java/org/finos/legend/engine/ide/PureIDELight.java +++ b/legend-engine-pure/legend-engine-pure-ide/legend-engine-pure-ide-light/src/main/java/org/finos/legend/engine/ide/PureIDELight.java @@ -61,7 +61,7 @@ protected MutableList buildRepositories(SourceLocationCon .with(this.buildCore("legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-presto/legend-engine-xt-relationalStore-presto-pure", "relational_presto")) .with(this.buildCore("legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sybase/legend-engine-xt-relationalStore-sybase-pure", "relational_sybase")) .with(this.buildCore("legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sybaseiq/legend-engine-xt-relationalStore-sybaseiq-pure", "relational_sybaseiq")) - .with(this.buildCore("legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sybaseiq/legend-engine-xt-relationalStore-sparksql-pure", "relational_sparksql")) + .with(this.buildCore("legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure", "relational_sparksql")) .with(this.buildCore("legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-analytics/legend-engine-xt-relationalStore-store-entitlement-pure", "relational_store_entitlement")) .with(this.buildCore("legend-engine-xts-serviceStore/legend-engine-xt-serviceStore-pure", "servicestore")) .with(this.buildCore("legend-engine-xts-serviceStore/legend-engine-xt-serviceStore-javaPlatformBinding-pure", "servicestore-java-platform-binding")) From 9b5f217ccd1eef987f47414ae45e5236da09f15e Mon Sep 17 00:00:00 2001 From: Yasirmod17 Date: Sun, 1 Oct 2023 11:42:59 -0400 Subject: [PATCH 04/10] Add sparkSQL generation tests --- .../tests/executionPlanTestSparkSQL.pure | 93 ++ .../tests/executionPlanTestSybaseIQ.pure | 217 ----- .../tests/testSparkSQLToSQLString.pure | 818 +----------------- 3 files changed, 138 insertions(+), 990 deletions(-) create mode 100644 legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/executionPlan/tests/executionPlanTestSparkSQL.pure delete mode 100644 legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/executionPlan/tests/executionPlanTestSybaseIQ.pure diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/executionPlan/tests/executionPlanTestSparkSQL.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/executionPlan/tests/executionPlanTestSparkSQL.pure new file mode 100644 index 00000000000..5a3121306e1 --- /dev/null +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/executionPlan/tests/executionPlanTestSparkSQL.pure @@ -0,0 +1,93 @@ +// Copyright 2023 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. + +import meta::pure::alloy::connections::alloy::authentication::*; +import meta::pure::alloy::connections::alloy::specification::*; +import meta::pure::alloy::connections::*; +import meta::pure::mapping::modelToModel::test::createInstances::*; +import meta::relational::postProcessor::*; +import meta::pure::extension::*; +import meta::relational::extension::*; +import meta::pure::mapping::modelToModel::test::shared::*; +import meta::pure::mapping::modelToModel::test::enumerationMapping::enumToEnum::mapping::*; +import meta::pure::mapping::modelToModel::test::enumerationMapping::enumToEnum::model::*; +import meta::pure::mapping::modelToModel::test::enumeration::*; +import meta::pure::graphFetch::execution::*; +import meta::pure::executionPlan::tests::datetime::*; +import meta::relational::tests::tds::tabletds::*; +import meta::pure::mapping::*; +import meta::relational::mapping::*; +import meta::relational::runtime::*; +import meta::relational::tests::mapping::inheritance::relational::*; +import meta::relational::metamodel::join::*; +import meta::relational::tests::tds::tdsJoin::*; +import meta::pure::executionPlan::toString::*; +import meta::pure::executionPlan::tests::*; +import meta::relational::tests::groupBy::datePeriods::mapping::*; +import meta::relational::tests::groupBy::datePeriods::*; +import meta::relational::tests::groupBy::datePeriods::domain::*; +import meta::pure::executionPlan::*; +import meta::relational::tests::*; +import meta::relational::tests::model::simple::*; +import meta::pure::runtime::*; +import meta::pure::mapping::modelToModel::test::shared::src::*; +import meta::pure::graphFetch::executionPlan::*; +import meta::pure::graphFetch::routing::*; +import meta::pure::functions::collection::*; +import meta::pure::executionPlan::tests::SparkSQL::*; + +function <> meta::pure::executionPlan::tests::sparkSQL::testFilterEqualsWithOptionalParameter_SparkSQL():Boolean[1] +{ + let expectedPlan ='Sequence\n'+ + '(\n'+ + ' type = TDS[(Time, Integer, INT, "")]\n'+ + ' (\n'+ + ' FunctionParametersValidationNode\n'+ + ' (\n'+ + ' functionParameters = [optionalID:String[0..1], optionalActive:Boolean[0..1]]\n'+ + ' )\n'+ + ' Relational\n'+ + ' (\n'+ + ' type = TDS[(Time, Integer, INT, "")]\n'+ + ' resultColumns = [("Time", INT)]\n'+ + ' sql = select "root"."time" as "Time" from interactionTable as "root" where ((${optionalVarPlaceHolderOperationSelector(optionalID![], \'"root".ID = ${varPlaceHolderToString(optionalID![] "\\\'" "\\\'" {"\\\'" : "\\\'\\\'"} "null")}\', \'"root".ID is null\')}) and (${optionalVarPlaceHolderOperationSelector(optionalActive![], \'case when "root"."active" = \\\'Y\\\' then \\\'true\\\' else \\\'false\\\' end = ${varPlaceHolderToString(optionalActive![] "\\\'" "\\\'" {} "null")}\', \'case when "root"."active" = \\\'Y\\\' then \\\'true\\\' else \\\'false\\\' end is null\')}))\n'+ + ' connection = DatabaseConnection(type = "SparkSQL")\n'+ + ' )\n'+ + ' )\n'+ + ')\n'; + assertPlanGenerationForOptionalParameter(DatabaseType.SparkSQL, $expectedPlan); +} + +function <> meta::pure::executionPlan::tests::sparkSQL::testGreaterThanLessThanEqualsWithOptionalParameter_SparkSQL():Boolean[1] +{ + let func = {optionalAgeLowerLimit: Integer[0..1], optionalAgeHigherLimit: Integer[0..1]|Person.all()->filter(p|$p.age>$optionalAgeLowerLimit && ($p.age<=$optionalAgeHigherLimit))->project(col(a|$a.firstName, 'firstName'))}; + let expectedPlan ='Sequence\n'+ + '(\n'+ + ' type = TDS[(firstName, String, VARCHAR(200), "")]\n'+ + ' (\n'+ + ' FunctionParametersValidationNode\n'+ + ' (\n'+ + ' functionParameters = [optionalAgeLowerLimit:Integer[0..1], optionalAgeHigherLimit:Integer[0..1]]\n'+ + ' )\n'+ + ' Relational\n'+ + ' (\n'+ + ' type = TDS[(firstName, String, VARCHAR(200), "")]\n'+ + ' resultColumns = [("firstName", VARCHAR(200))]\n'+ + ' sql = select "root".FIRSTNAME as "firstName" from personTable as "root" where ((("root".AGE is not null and ${varPlaceHolderToString(optionalAgeLowerLimit![] "" "" {} "null")} is not null) and "root".AGE > ${varPlaceHolderToString(optionalAgeLowerLimit![] "" "" {} "null")}) and (("root".AGE is not null and ${varPlaceHolderToString(optionalAgeHigherLimit![] "" "" {} "null")} is not null) and "root".AGE <= ${varPlaceHolderToString(optionalAgeHigherLimit![] "" "" {} "null")}))\n'+ + ' connection = DatabaseConnection(type = "SparkSQL")\n'+ + ' )\n'+ + ' )\n'+ + ')\n'; + assertPlanGenerationForOptionalParameterWithGreaterThanLessThan($func, DatabaseType.SparkSQL, $expectedPlan); +} \ No newline at end of file diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/executionPlan/tests/executionPlanTestSybaseIQ.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/executionPlan/tests/executionPlanTestSybaseIQ.pure deleted file mode 100644 index 9e2fa014cf0..00000000000 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/executionPlan/tests/executionPlanTestSybaseIQ.pure +++ /dev/null @@ -1,217 +0,0 @@ -//// Copyright 2023 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. -// -//import meta::pure::alloy::connections::alloy::authentication::*; -//import meta::pure::alloy::connections::alloy::specification::*; -//import meta::pure::alloy::connections::*; -//import meta::pure::mapping::modelToModel::test::createInstances::*; -//import meta::relational::postProcessor::*; -//import meta::pure::extension::*; -//import meta::relational::extension::*; -//import meta::pure::mapping::modelToModel::test::shared::*; -//import meta::pure::mapping::modelToModel::test::enumerationMapping::enumToEnum::mapping::*; -//import meta::pure::mapping::modelToModel::test::enumerationMapping::enumToEnum::model::*; -//import meta::pure::mapping::modelToModel::test::enumeration::*; -//import meta::pure::graphFetch::execution::*; -//import meta::pure::executionPlan::tests::datetime::*; -//import meta::relational::tests::tds::tabletds::*; -//import meta::pure::mapping::*; -//import meta::relational::mapping::*; -//import meta::relational::runtime::*; -//import meta::relational::tests::mapping::inheritance::relational::*; -//import meta::relational::metamodel::join::*; -//import meta::relational::tests::tds::tdsJoin::*; -//import meta::pure::executionPlan::toString::*; -//import meta::pure::executionPlan::tests::*; -//import meta::relational::tests::groupBy::datePeriods::mapping::*; -//import meta::relational::tests::groupBy::datePeriods::*; -//import meta::relational::tests::groupBy::datePeriods::domain::*; -//import meta::pure::executionPlan::*; -//import meta::relational::tests::*; -//import meta::relational::tests::model::simple::*; -//import meta::pure::runtime::*; -//import meta::pure::mapping::modelToModel::test::shared::src::*; -//import meta::pure::graphFetch::executionPlan::*; -//import meta::pure::graphFetch::routing::*; -//import meta::pure::functions::collection::*; -//import meta::pure::executionPlan::tests::sybaseIQ::*; -// -//function <> meta::pure::executionPlan::tests::sybaseIQ::testFilterEqualsWithOptionalParameter_SybaseIQ():Boolean[1] -//{ -// let expectedPlan ='Sequence\n'+ -// '(\n'+ -// ' type = TDS[(Time, Integer, INT, "")]\n'+ -// ' (\n'+ -// ' FunctionParametersValidationNode\n'+ -// ' (\n'+ -// ' functionParameters = [optionalID:String[0..1], optionalActive:Boolean[0..1]]\n'+ -// ' )\n'+ -// ' Relational\n'+ -// ' (\n'+ -// ' type = TDS[(Time, Integer, INT, "")]\n'+ -// ' resultColumns = [("Time", INT)]\n'+ -// ' sql = select "root"."time" as "Time" from interactionTable as "root" where ((${optionalVarPlaceHolderOperationSelector(optionalID![], \'"root".ID = ${varPlaceHolderToString(optionalID![] "\\\'" "\\\'" {"\\\'" : "\\\'\\\'"} "null")}\', \'"root".ID is null\')}) and (${optionalVarPlaceHolderOperationSelector(optionalActive![], \'case when "root"."active" = \\\'Y\\\' then \\\'true\\\' else \\\'false\\\' end = ${varPlaceHolderToString(optionalActive![] "\\\'" "\\\'" {} "null")}\', \'case when "root"."active" = \\\'Y\\\' then \\\'true\\\' else \\\'false\\\' end is null\')}))\n'+ -// ' connection = DatabaseConnection(type = "SybaseIQ")\n'+ -// ' )\n'+ -// ' )\n'+ -// ')\n'; -// assertPlanGenerationForOptionalParameter(DatabaseType.SybaseIQ, $expectedPlan); -//} -// -//function <> meta::pure::executionPlan::tests::sybaseIQ::testGreaterThanLessThanEqualsWithOptionalParameter_SybaseIQ():Boolean[1] -//{ -// let func = {optionalAgeLowerLimit: Integer[0..1], optionalAgeHigherLimit: Integer[0..1]|Person.all()->filter(p|$p.age>$optionalAgeLowerLimit && ($p.age<=$optionalAgeHigherLimit))->project(col(a|$a.firstName, 'firstName'))}; -// let expectedPlan ='Sequence\n'+ -// '(\n'+ -// ' type = TDS[(firstName, String, VARCHAR(200), "")]\n'+ -// ' (\n'+ -// ' FunctionParametersValidationNode\n'+ -// ' (\n'+ -// ' functionParameters = [optionalAgeLowerLimit:Integer[0..1], optionalAgeHigherLimit:Integer[0..1]]\n'+ -// ' )\n'+ -// ' Relational\n'+ -// ' (\n'+ -// ' type = TDS[(firstName, String, VARCHAR(200), "")]\n'+ -// ' resultColumns = [("firstName", VARCHAR(200))]\n'+ -// ' sql = select "root".FIRSTNAME as "firstName" from personTable as "root" where ((("root".AGE is not null and ${varPlaceHolderToString(optionalAgeLowerLimit![] "" "" {} "null")} is not null) and "root".AGE > ${varPlaceHolderToString(optionalAgeLowerLimit![] "" "" {} "null")}) and (("root".AGE is not null and ${varPlaceHolderToString(optionalAgeHigherLimit![] "" "" {} "null")} is not null) and "root".AGE <= ${varPlaceHolderToString(optionalAgeHigherLimit![] "" "" {} "null")}))\n'+ -// ' connection = DatabaseConnection(type = "SybaseIQ")\n'+ -// ' )\n'+ -// ' )\n'+ -// ')\n'; -// assertPlanGenerationForOptionalParameterWithGreaterThanLessThan($func, DatabaseType.SybaseIQ, $expectedPlan); -//} -// -// -//function <> meta::pure::executionPlan::tests::sybaseIQ::testLessThanGreaterThanEqualsWithOptionalParameter_SybaseIQ():Boolean[1] -//{ -// let func = {optionalAgeLowerLimit: Integer[0..1], optionalAgeHigherLimit: Integer[0..1]|Person.all()->filter(p|$p.age<$optionalAgeLowerLimit && ($p.age>=$optionalAgeHigherLimit))->project(col(a|$a.firstName, 'firstName'))}; -// let expectedPlan ='Sequence\n'+ -// '(\n'+ -// ' type = TDS[(firstName, String, VARCHAR(200), "")]\n'+ -// ' (\n'+ -// ' FunctionParametersValidationNode\n'+ -// ' (\n'+ -// ' functionParameters = [optionalAgeLowerLimit:Integer[0..1], optionalAgeHigherLimit:Integer[0..1]]\n'+ -// ' )\n'+ -// ' Relational\n'+ -// ' (\n'+ -// ' type = TDS[(firstName, String, VARCHAR(200), "")]\n'+ -// ' resultColumns = [("firstName", VARCHAR(200))]\n'+ -// ' sql = select "root".FIRSTNAME as "firstName" from personTable as "root" where ((("root".AGE is not null and ${varPlaceHolderToString(optionalAgeLowerLimit![] "" "" {} "null")} is not null) and "root".AGE < ${varPlaceHolderToString(optionalAgeLowerLimit![] "" "" {} "null")}) and (("root".AGE is not null and ${varPlaceHolderToString(optionalAgeHigherLimit![] "" "" {} "null")} is not null) and "root".AGE >= ${varPlaceHolderToString(optionalAgeHigherLimit![] "" "" {} "null")}))\n'+ -// ' connection = DatabaseConnection(type = "SybaseIQ")\n'+ -// ' )\n'+ -// ' )\n'+ -// ')\n'; -// assertPlanGenerationForOptionalParameterWithGreaterThanLessThan($func, DatabaseType.SybaseIQ, $expectedPlan); -//} -// -//function meta::pure::executionPlan::tests::sybaseIQ::twoDBRunTimeSybaseIQ():meta::pure::runtime::Runtime[1] -//{ -// ^meta::pure::runtime::Runtime -// ( -// connections = [^TestDatabaseConnection( -// element = dbInc, -// type=DatabaseType.SybaseIQ -// ),^TestDatabaseConnection( -// element = database2, -// type=DatabaseType.SybaseIQ -// )] -// ); -//} -// -//function <> meta::pure::executionPlan::tests::sybaseIQ::twoDBTestSpaceIdentifierSybaseIQ():Boolean[1] -//{ -// let result = executionPlan({| -// testJoinTDS_Person.all()->meta::pure::tds::project([col(p|$p.firstName, 'first name'), col(p|$p.employerID, 'eID')])->join(testJoinTDS_Firm.all()->project([col(p|$p.firmID, 'fID'), -// col(p|$p.legalName, 'legalName')]), JoinType.INNER, {a,b|$a.getInteger('eID') == $b.getInteger('fID');})->filter( f| $f.getString('first name')=='Adam' && $f.getString('legalName')=='Firm X') -// ;}, meta::relational::tests::tds::tdsJoin::testJoinTDSMappingTwoDatabase, twoDBRunTimeSybaseIQ(), meta::relational::extension::relationalExtensions()); -// -// assertEquals('Sequence\n'+ -// '(\n'+ -// ' type = TDS[(first name, String, VARCHAR(200), \"\"), (eID, Integer, INT, \"\"), (fID, Integer, INT, \"\"), (legalName, String, VARCHAR(200), \"\")]\n'+ -// ' (\n'+ -// ' Allocation\n'+ -// ' (\n'+ -// ' type = TDS[(first name, String, VARCHAR(200), \"\"), (eID, Integer, INT, \"\")]\n'+ -// ' name = tdsVar_0\n'+ -// ' value = \n'+ -// ' (\n'+ -// ' Relational\n'+ -// ' (\n'+ -// ' type = TDS[(first name, String, VARCHAR(200), \"\"), (eID, Integer, INT, \"\")]\n'+ -// ' resultColumns = [("first name", VARCHAR(200)), ("eID", INT)]\n'+ -// ' sql = select \"root\".FIRSTNAME as \"first name\", \"root\".FIRMID as \"eID\" from personTable as \"root\"\n'+ -// ' connection = TestDatabaseConnection(type = \"SybaseIQ\")\n'+ -// ' )\n'+ -// ' )\n'+ -// ' )\n'+ -// ' Relational\n'+ -// ' (\n'+ -// ' type = TDS[(first name, String, VARCHAR(200), \"\"), (eID, Integer, INT, \"\"), (fID, Integer, INT, \"\"), (legalName, String, VARCHAR(200), \"\")]\n'+ -// ' resultColumns = [("first name", INT), ("eID", INT), ("fID", INT), ("legalName", VARCHAR(200))]\n'+ -// ' sql = select "tdsvar_0_0"."first name" as "first name", "tdsvar_0_0".eID as "eID", "tdsvar_0_0"."fID" as "fID", "tdsvar_0_0"."legalName" as "legalName" from (select * from (${tdsVar_0}) as "tdsvar_0_1" inner join (select "root".ID as "fID", "root".LEGALNAME as "legalName" from firmTable as "root") as "firmtable_0" on ("tdsvar_0_1".eID = "firmtable_0"."fID")) as "tdsvar_0_0" where ("tdsvar_0_0"."first name" = \'Adam\' and "tdsvar_0_0"."legalName" = \'Firm X\')\n'+ -// ' connection = TestDatabaseConnection(type = \"SybaseIQ\")\n'+ -// ' )\n'+ -// ' )\n'+ -// ')\n' -// , $result->planToString(meta::relational::extension::relationalExtensions())); -//} -// -//function <> meta::pure::executionPlan::tests::sybaseIQ::twoDBTestSlashSybaseIQ():Boolean[1] -//{ -// let result = executionPlan({| -// testJoinTDS_Person.all()->meta::pure::tds::project([col(p|$p.firstName, 'first/name'), col(p|$p.employerID, 'eID')])->join(testJoinTDS_Firm.all()->project([col(p|$p.firmID, 'fID'), -// col(p|$p.legalName, 'legalName')]), JoinType.INNER, {a,b|$a.getInteger('eID') == $b.getInteger('fID');})->filter( f| $f.getString('first/name')=='Adam' && $f.getString('legalName')=='Firm X') -// ;}, meta::relational::tests::tds::tdsJoin::testJoinTDSMappingTwoDatabase, twoDBRunTimeSybaseIQ(), meta::relational::extension::relationalExtensions()); -// -// assertEquals('Sequence\n'+ -// '(\n'+ -// ' type = TDS[(first/name, String, VARCHAR(200), \"\"), (eID, Integer, INT, \"\"), (fID, Integer, INT, \"\"), (legalName, String, VARCHAR(200), \"\")]\n'+ -// ' (\n'+ -// ' Allocation\n'+ -// ' (\n'+ -// ' type = TDS[(first/name, String, VARCHAR(200), \"\"), (eID, Integer, INT, \"\")]\n'+ -// ' name = tdsVar_0\n'+ -// ' value = \n'+ -// ' (\n'+ -// ' Relational\n'+ -// ' (\n'+ -// ' type = TDS[(first/name, String, VARCHAR(200), \"\"), (eID, Integer, INT, \"\")]\n'+ -// ' resultColumns = [("first/name", VARCHAR(200)), ("eID", INT)]\n'+ -// ' sql = select \"root\".FIRSTNAME as \"first/name\", \"root\".FIRMID as \"eID\" from personTable as \"root\"\n'+ -// ' connection = TestDatabaseConnection(type = \"SybaseIQ\")\n'+ -// ' )\n'+ -// ' )\n'+ -// ' )\n'+ -// ' Relational\n'+ -// ' (\n'+ -// ' type = TDS[(first/name, String, VARCHAR(200), \"\"), (eID, Integer, INT, \"\"), (fID, Integer, INT, \"\"), (legalName, String, VARCHAR(200), \"\")]\n'+ -// ' resultColumns = [("first/name", INT), ("eID", INT), ("fID", INT), ("legalName", VARCHAR(200))]\n'+ -// ' sql = select "tdsvar_0_0"."first/name" as "first/name", "tdsvar_0_0".eID as "eID", "tdsvar_0_0"."fID" as "fID", "tdsvar_0_0"."legalName" as "legalName" from (select * from (${tdsVar_0}) as "tdsvar_0_1" inner join (select "root".ID as "fID", "root".LEGALNAME as "legalName" from firmTable as "root") as "firmtable_0" on ("tdsvar_0_1".eID = "firmtable_0"."fID")) as "tdsvar_0_0" where ("tdsvar_0_0"."first/name" = \'Adam\' and "tdsvar_0_0"."legalName" = \'Firm X\')\n'+ -// ' connection = TestDatabaseConnection(type = \"SybaseIQ\")\n'+ -// ' )\n'+ -// ' )\n'+ -// ')\n' -// , $result->planToString(meta::relational::extension::relationalExtensions())); -//} -// -//function <> meta::pure::executionPlan::tests::sybaseIQ::testExecutionPlanGenerationForMultipleInWithCollectionAndConstantInputs() : Boolean[1] -//{ -// let res = executionPlan( -// {name:String[*] |_Person.all()->filter(x | $x.fullName->in($name))->filter(x | $x.fullName->in(['A', 'B']))->project([x | $x.fullName], ['fullName']);}, -// meta::pure::mapping::modelToModel::test::shared::relationalMapping, ^Runtime(connections=^DatabaseConnection(element = relationalDB, type=DatabaseType.SybaseIQ)), meta::relational::extension::relationalExtensions() -// ); -// let expected = 'RelationalBlockExecutionNode(type=TDS[(fullName,String,VARCHAR(1000),"")](FunctionParametersValidationNode(functionParameters=[name:String[*]])Allocation(type=Stringname=inFilterClause_namevalue=(FreeMarkerConditionalExecutionNode(type=Stringcondition=${(instanceOf(name,"Stream")||((collectionSize(name![])?number)>250000))?c}trueBlock=(Sequence(type=String(CreateAndPopulateTempTable(type=VoidinputVarNames=[name]tempTableName=tempTableForIn_nametempTableColumns=[(ColumnForStoringInCollection,VARCHAR(200))]connection=DatabaseConnection(type="SybaseIQ"))Constant(type=Stringvalues=[select"temptableforin_name_0".ColumnForStoringInCollectionasColumnForStoringInCollectionfromtempTableForIn_nameas"temptableforin_name_0"]))))falseBlock=(Constant(type=Stringvalues=[${renderCollection(name![]",""\'""\'"{"\'":"\'\'"}"null")}])))))Relational(type=TDS[(fullName,String,VARCHAR(1000),"")]resultColumns=[("fullName",VARCHAR(1000))]sql=select"root".fullnameas"fullName"fromPersonas"root"where"root".fullnamein(${inFilterClause_name})and"root".fullnamein(\'A\',\'B\')connection=DatabaseConnection(type="SybaseIQ"))))'; -// assertEquals($expected, $res->planToStringWithoutFormatting(meta::relational::extension::relationalExtensions())); -//} diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/sqlQueryToString/tests/testSparkSQLToSQLString.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/sqlQueryToString/tests/testSparkSQLToSQLString.pure index df1159a3514..53baa3649a6 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/sqlQueryToString/tests/testSparkSQLToSQLString.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/main/resources/core_relational_sparksql/relational/sqlQueryToString/tests/testSparkSQLToSQLString.pure @@ -1,773 +1,45 @@ -//// Copyright 2023 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. -// -//import meta::relational::tests::functions::sqlstring::*; -//import meta::pure::mapping::*; -//import meta::relational::functions::asserts::*; -//import meta::relational::mapping::*; -//import meta::relational::tests::*; -//import meta::relational::tests::model::simple::*; -//import meta::pure::profiles::*; -//import meta::relational::functions::sqlstring::*; -//import meta::relational::runtime::*; -// -//function meta::relational::tests::functions::sqlstring::sybaseIQ::testCasesForDocGeneration():TestCase[*] -//{ -// [ -// ^TestCase( -// id ='testToSqlGenerationForBooleanInProject_SybaseIQ_StartsWith', -// query = |Person.all()->project([ -// a | $a.firstName->startsWith('tri') -// ], -// ['a']), -// mapping = simpleRelationalMapping, -// dbType = DatabaseType.SybaseIQ, -// expectedSql = 'select case when ("root".FIRSTNAME like \'tri%\') then \'true\' else \'false\' end as "a" from personTable as "root"', -// generateUsageFor = [meta::pure::functions::string::startsWith_String_1__String_1__Boolean_1_] -// ), -// -// ^TestCase( -// id ='testToSQLStringJoinStrings_SybaseIQ', -// query = {|Firm.all()->groupBy([f|$f.legalName], -// agg(x|$x.employees.firstName,y|$y->joinStrings('*')), -// ['legalName', 'employeesFirstName'] -// )}, -// mapping = meta::relational::tests::simpleRelationalMapping, -// dbType = meta::relational::runtime::DatabaseType.SybaseIQ, -// expectedSql = 'select "root".LEGALNAME as "legalName", list("personTable_d#4_d_m1".FIRSTNAME,\'*\') as "employeesFirstName" from firmTable as "root" left outer join personTable as "personTable_d#4_d_m1" on ("root".ID = "personTable_d#4_d_m1".FIRMID) group by "legalName"', -// generateUsageFor = [meta::pure::functions::string::joinStrings_String_MANY__String_1__String_1_] -// ) -// ] -//} -// -//function meta::relational::tests::functions::sqlstring::sybaseIQ::runTestCaseById(testCaseId: String[1]): Boolean[1] -//{ -// let filtered = meta::relational::tests::functions::sqlstring::sybaseIQ::testCasesForDocGeneration()->filter(c|$c.id==$testCaseId); -// assert($filtered->size()==1, 'Number of test cases found is not 1.'); -// let testCase = $filtered->toOne(); -// -// let result = toSQLString($testCase.query, $testCase.mapping, $testCase.dbType, meta::relational::extension::relationalExtensions()); -// assertEquals($testCase.expectedSql, $result, '\nSQL not as expected for \'%s\'\n\nexpected: %s\nactual: %s', [$testCase.id, $testCase.expectedSql, $result]); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringWithConditionalProjectSybaseIQ():Boolean[1] -//{ -// let s = toSQLString(|Person.all()->project(p|$p.firstName == 'John', 'isJohn'), meta::relational::tests::simpleRelationalMapping, meta::relational::runtime::DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when ("root".FIRSTNAME = \'John\') then \'true\' else \'false\' end as "isJohn" from personTable as "root"', $s); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringJoinStrings():Boolean[1] -//{ -// meta::relational::tests::functions::sqlstring::sybaseIQ::runTestCaseById('testToSQLStringJoinStrings_SybaseIQ'); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringJoinStringsSimpleConcat():Boolean[1] -//{ -// let fn = {|Person.all()->project([p | $p.firstName + '_' + $p.lastName], ['firstName_lastName'])}; -// let sybaseSql = toSQLString($fn, meta::relational::tests::simpleRelationalMapping, meta::relational::runtime::DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".FIRSTNAME+\'_\'+"root".LASTNAME as "firstName_lastName" from personTable as "root"', $sybaseSql); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testProcessLiteralForIQ():Boolean[1] -//{ -// let result = toSQLString(|Person.all()->project([ -// a | 'String', -// b | %2016-03-01, -// c | %2016-03-01T12:18:18.976+0200, -// d | 1, -// e | 1.1 -// ], -// ['a','b','c','d', 'e'])->take(0), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// print($result); -// assertEquals('select top 0 \'String\' as "a", convert(DATE, \'2016-03-01\', 121) as "b", convert(DATETIME, \'2016-03-01 10:18:18.976\', 121) as "c", 1 as "d", 1.1 as "e" from personTable as "root"', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringWithLength():Boolean[1] -//{ -// [DatabaseType.SybaseIQ]->map(db| -// let s = toSQLString(|Person.all()->project(p|length($p.firstName), 'nameLength'), simpleRelationalMapping, $db, meta::relational::extension::relationalExtensions()); -// assertEquals('select char_length("root".FIRSTNAME) as "nameLength" from personTable as "root"', $s); -// ); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringWithPosition():Boolean[1] -//{ -// [DatabaseType.SybaseIQ]->map(db| -// let s = toSQLString( -// |meta::relational::tests::mapping::propertyfunc::model::domain::Person.all()->project(p|$p.firstName, 'firstName'), -// meta::relational::tests::mapping::propertyfunc::model::mapping::PropertyfuncMapping, $db, meta::relational::extension::relationalExtensions()); -// -// assertEquals('select substring("root".FULLNAME, 0, charindex(\',\', "root".FULLNAME)-1) as "firstName" from personTable as "root"', $s); -// ); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringWithStdDevSample():Boolean[1] -//{ -// [DatabaseType.SybaseIQ]->map(db| -// let s = toSQLString( -// |meta::relational::tests::mapping::sqlFunction::model::domain::SqlFunctionDemo.all()->project(p|$p.float1StdDevSample, 'stdDevSample'), -// meta::relational::tests::mapping::sqlFunction::model::mapping::testMapping, $db, meta::relational::extension::relationalExtensions()); -// -// assertEquals('select stddev_samp("root".int1) as "stdDevSample" from dataTable as "root"', $s); -// )->distinct() == [true]; -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringWithStdDevPopulation():Boolean[1] -//{ -// [DatabaseType.SybaseIQ]->map(db| -// let s = toSQLString( -// |meta::relational::tests::mapping::sqlFunction::model::domain::SqlFunctionDemo.all()->project(p|$p.float1StdDevPopulation, 'stdDevPopulation'), -// meta::relational::tests::mapping::sqlFunction::model::mapping::testMapping, $db, meta::relational::extension::relationalExtensions()); -// -// assertEquals('select stddev_pop("root".int1) as "stdDevPopulation" from dataTable as "root"', $s); -// )->distinct() == [true]; -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testGenerateDateDiffExpressionForSybaseIQForDifferenceInYears():Boolean[1] -//{ -// let result = toSQLString(|Trade.all()->project([ -// t | dateDiff($t.settlementDateTime, now(), DurationUnit.YEARS) -// ], -// ['DiffYears']), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select datediff(yy,"root".settlementDateTime,now()) as "DiffYears" from tradeTable as "root"', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testGenerateDateDiffExpressionForSybaseIQForDifferenceInMonths():Boolean[1] -//{ -// let result = toSQLString(|Trade.all()->project([ -// t | dateDiff($t.settlementDateTime, now(), DurationUnit.MONTHS) -// ], -// ['DiffMonths']), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select datediff(mm,"root".settlementDateTime,now()) as "DiffMonths" from tradeTable as "root"', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testGenerateDateDiffExpressionForSybaseIQForDifferenceInWeeks():Boolean[1] -//{ -// let result = toSQLString(|Trade.all()->project([ -// t | dateDiff($t.settlementDateTime, now(), DurationUnit.WEEKS) -// ], -// ['DiffWeeks']), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select datediff(wk,"root".settlementDateTime,now()) as "DiffWeeks" from tradeTable as "root"', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationFirstDayOfTimePeriod():Boolean[1] -//{ -// let result = toSQLString( -// |Trade.all() -// ->project([ -// col(t|$t.date->firstHourOfDay(), 'day'), -// col(t|$t.date->firstMinuteOfHour(), 'hour'), -// col(t|$t.date->firstSecondOfMinute(), 'minute'), -// col(t|$t.date->firstMillisecondOfSecond(), 'second') -// ]), -// simpleRelationalMapping, -// DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// -// assertEquals('select datetime(date("root".tradeDate)) as "day", dateadd(hour, datepart(hour, "root".tradeDate), date("root".tradeDate)) as "hour", dateadd(minute, datepart(minute, "root".tradeDate), dateadd(hour, datepart(hour, "root".tradeDate), date("root".tradeDate))) as "minute", dateadd(microsecond, -(datepart(microsecond, "root".tradeDate)), "root".tradeDate) as "second" from tradeTable as "root"', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testGenerateDateDiffExpressionForSybaseIQForDifferenceInDays():Boolean[1] -//{ -// let result = toSQLString(|Trade.all()->project([ -// t | dateDiff($t.settlementDateTime, now(), DurationUnit.DAYS) -// ], -// ['DiffDays']), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select datediff(dd,"root".settlementDateTime,now()) as "DiffDays" from tradeTable as "root"', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testGenerateDateDiffExpressionForSybaseIQForDifferenceInHours():Boolean[1] -//{ -// let result = toSQLString(|Trade.all()->project([ -// t | dateDiff($t.settlementDateTime, now(), DurationUnit.HOURS) -// ], -// ['DiffHours']), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select datediff(hh,"root".settlementDateTime,now()) as "DiffHours" from tradeTable as "root"', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testGenerateDateDiffExpressionForSybaseIQForDifferenceInMinutes():Boolean[1] -//{ -// let result = toSQLString(|Trade.all()->project([ -// t | dateDiff($t.settlementDateTime, now(), DurationUnit.MINUTES) -// ], -// ['DiffMinutes']), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select datediff(mi,"root".settlementDateTime,now()) as "DiffMinutes" from tradeTable as "root"', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testGenerateDateDiffExpressionForSybaseIQForDifferenceInSeconds():Boolean[1] -//{ -// let result = toSQLString(|Trade.all()->project([ -// t | dateDiff($t.settlementDateTime, now(), DurationUnit.SECONDS) -// ], -// ['DiffSeconds']), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select datediff(ss,"root".settlementDateTime,now()) as "DiffSeconds" from tradeTable as "root"', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testGenerateDateDiffExpressionForSybaseIQForDifferenceInMilliseconds():Boolean[1] -//{ -// let result = toSQLString(|Trade.all()->project([ -// t | dateDiff($t.settlementDateTime, now(), DurationUnit.MILLISECONDS) -// ], -// ['DiffMilliseconds']), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select datediff(ms,"root".settlementDateTime,now()) as "DiffMilliseconds" from tradeTable as "root"', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testDayOfYear():Boolean[1] -//{ -// let expected = [ -// pair(DatabaseType.SybaseIQ, 'select datepart(DAYOFYEAR,"root".tradeDate) as "doy" from tradeTable as "root"') -// ]; -// -// $expected->map(p| -// let driver = $p.first; -// let expectedSql = $p.second; -// -// let result = toSQLString( -// |Trade.all() -// ->project(col(t|$t.date->dayOfYear(), 'doy')), -// simpleRelationalMapping, -// $driver, meta::relational::extension::relationalExtensions()); -// -// assertEquals($expectedSql, $result, '\nSQL not as expected for %s\n\nexpected: %s\nactual: %s', [$driver, $expectedSql, $result]); -// )->distinct() == [true]; -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testTrim():Boolean[1] -//{ -// let common = 'select ltrim("root".FIRSTNAME) as "ltrim", trim("root".FIRSTNAME) as "trim", rtrim("root".FIRSTNAME) as "rtrim" from personTable as "root"'; -// -// let expected = [ -// pair(DatabaseType.SybaseIQ, $common) -// ]; -// -// $expected->map(p| -// let driver = $p.first; -// let expectedSql = $p.second; -// -// let result = toSQLString( -// |Person.all()->project([ -// a | $a.firstName->ltrim(), -// a | $a.firstName->trim(), -// a | $a.firstName->rtrim() -// ], -// ['ltrim', 'trim', 'rtrim']), -// simpleRelationalMapping, -// $driver, meta::relational::extension::relationalExtensions()); -// -// assertEquals($expectedSql, $result, '\nSQL not as expected for %s\n\nexpected: %s\nactual: %s', [$driver, $expectedSql, $result]); -// )->distinct() == [true]; -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testCbrt():Boolean[1] -//{ -// let common = 'select cbrt("root".quantity) as "cbrt" from tradeTable as "root"'; -// -// let expected = [ -// pair(DatabaseType.SybaseIQ, $common) -// ]; -// -// $expected->map(p| -// let driver = $p.first; -// let expectedSql = $p.second; -// -// let result = toSQLString( -// |Trade.all()->project([ -// a | $a.quantity->cbrt() -// ], -// ['cbrt']), -// simpleRelationalMapping, -// $driver, meta::relational::extension::relationalExtensions()); -// -// assertEquals($expectedSql, $result, '\nSQL not as expected for %s\n\nexpected: %s\nactual: %s', [$driver, $expectedSql, $result]); -// )->distinct() == [true]; -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInProject_SybaseIQ_StartsWith():Boolean[1] -//{ -// meta::relational::tests::functions::sqlstring::sybaseIQ::runTestCaseById('testToSqlGenerationForBooleanInProject_SybaseIQ_StartsWith'); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInFilter_SybaseIQ():Boolean[1] -//{ -// let result = toSQLString(|Interaction.all()->filter(a | $a.active)->project([i | $i.id],['id']), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" where case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\'', $result); -//} -// -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInFilterWithAnd_SybaseIQ():Boolean[1] -//{ -// let result = toSQLString(|Interaction.all()->filter(a | $a.id == 1 && $a.active)->project([i | $i.id],['id']), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" where ("root".ID = 1 and case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\')', $result); -//} -// -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInFilterWithAnd_WithDistinct_SybaseIQ():Boolean[1] -//{ -// let result = toSQLString(|Interaction.all()->filter(a | $a.id == 1 && $a.active)->project([i | $i.id],['id'])->distinct(), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select distinct "root".ID as "id" from interactionTable as "root" where ("root".ID = 1 and case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\')', $result); -//} -// -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInFilterWithAndIsNull_SybaseIQ():Boolean[1] -//{ -// let result = toSQLString(|Interaction.all()->filter(a | $a.id->isEmpty() && $a.active)->project([i | $i.id],['id']), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" where ("root".ID is null and case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\')', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInFilterWithAndNotEqual_SybaseIQ():Boolean[1] -//{ -// let result = toSQLString(|Interaction.all()->filter(a | $a.id != 1 && $a.active)->project([i | $i.id],['id']), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" where (("root".ID <> 1 OR "root".ID is null) and case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\')', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForConstanNumInFilterWithNotEqual_SybaseIQ():Boolean[1] -//{ -// let result = toSQLString(|Synonym.all()->filter(s | $s.type != 'ISIN')->project([s | $s.name],['name']), -// simpleRelationalMappingWithEnumConstant, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".NAME as "name" from productSchema.synonymTable as "root" where (\'CUSIP\' <> \'ISIN\')', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInProject_SybaseIQ_IsEmpty():Boolean[1] -//{ -// let result = toSQLString(|Person.all()->project([ -// a | $a.firstName->isEmpty() -// ], -// ['a']), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when ("root".FIRSTNAME is null) then \'true\' else \'false\' end as "a" from personTable as "root"', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInProject_SybaseIQ_And():Boolean[1] -//{ -// let result = toSQLString(|Person.all()->project([ -// a | $a.firstName == 'A' && $a.lastName == 'B' -// ], -// ['a']), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when (("root".FIRSTNAME = \'A\' and "root".LASTNAME = \'B\')) then \'true\' else \'false\' end as "a" from personTable as "root"', $result); -//} -// -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInProject_SybaseIQ_If():Boolean[1] -//{ -// let result = toSQLString(|Person.all()->project([ -// a | if ($a.firstName == 'A', | true, | false) -// ], -// ['a']), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when "root".FIRSTNAME = \'A\' then \'true\' else \'false\' end as "a" from personTable as "root"', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInFilter_SybaseIQ_If():Boolean[1] -//{ -// let result = toSQLString(|Person.all()->filter(a | if ($a.firstName == 'A', | true, | false)), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "pk_0", "root".FIRSTNAME as "firstName", "root".AGE as "age", "root".LASTNAME as "lastName" from personTable as "root" where case when "root".FIRSTNAME = \'A\' then \'true\' else \'false\' end = \'true\'', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInProject_SybaseIQ_NestedIf():Boolean[1] -//{ -// let result = toSQLString(|Person.all()->project([ -// a | if ( if ($a.firstName == 'B', | true, | false), | true, | false) -// ], -// ['a']), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when case when "root".FIRSTNAME = \'B\' then \'true\' else \'false\' end = \'true\' then \'true\' else \'false\' end as "a" from personTable as "root"', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForBooleanInProject_SybaseIQ_Or():Boolean[1] -//{ -// let result = toSQLString(|Person.all()->project([ -// a | true || false -// ], -// ['a']), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when ((\'true\' = \'true\' or \'false\' = \'true\')) then \'true\' else \'false\' end as "a" from personTable as "root"', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testSqlGenerationForDatePartForSybaseIQ():Boolean[1] -//{ -// let result = toSQLString(|Location.all()->project([ -// a | $a.censusdate->toOne()->datePart() -// ], -// ['a']), -// simpleRelationalMappingInc, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select date("root"."date") as "a" from locationTable as "root"', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForProjectLambdaWithSquareBrackets_SybaseIQ():Boolean[1] -//{ -// let result = toSQLString( -// |Person.all()->project([a|$a.firstName->startsWith('Dummy [With Sq Brackets]')], ['a']), -// simpleRelationalMapping, -// DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// -// assertEquals('select case when ("root".FIRSTNAME like \'Dummy \\[With Sq Brackets]%\' escape \'\\\') then \'true\' else \'false\' end as "a" from personTable as "root"', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationForFilterWithSquareBrackets_SybaseIQ():Boolean[1] -//{ -// let result = toSQLString( -// |Person.all() -// ->project([#/Person/firstName!name#]) -// ->filter(a|$a.getString('name')->startsWith('Dummy [With Sq Brackets]')), -// simpleRelationalMapping, -// DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// -// assertEquals('select "root".FIRSTNAME as "name" from personTable as "root" where "root".FIRSTNAME like \'Dummy \\[With Sq Brackets]%\' escape \'\\\'', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationFirstDayOfMonth():Boolean[1] -//{ -// let expected = [ -// pair(DatabaseType.SybaseIQ, 'select dateadd(DAY, -(day("root".tradeDate) - 1), "root".tradeDate) as "date" from tradeTable as "root"') -// ]; -// -// $expected->map(p| -// let driver = $p.first; -// let expectedSql = $p.second; -// -// let result = toSQLString( -// |Trade.all() -// ->project(col(t|$t.date->firstDayOfMonth(), 'date')), -// simpleRelationalMapping, -// $driver, meta::relational::extension::relationalExtensions()); -// -// assertEquals($expectedSql, $result, '\nSQL not as expected for %s\n\nexpected: %s\nactual: %s', [$driver, $expectedSql, $result]); -// )->distinct() == [true]; -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationFirstDayOfYear():Boolean[1] -//{ -// let expected = [ -// pair(DatabaseType.SybaseIQ, 'select dateadd(DAY, -(datepart(dayofyear, "root".tradeDate) - 1), "root".tradeDate) as "date" from tradeTable as "root"') -// ]; -// -// $expected->map(p| -// let driver = $p.first; -// let expectedSql = $p.second; -// -// let result = toSQLString( -// |Trade.all() -// ->project(col(t|$t.date->firstDayOfYear(), 'date')), -// simpleRelationalMapping, -// $driver, meta::relational::extension::relationalExtensions()); -// -// assertEquals($expectedSql, $result, '\nSQL not as expected for %s\n\nexpected: %s\nactual: %s', [$driver, $expectedSql, $result]); -// )->distinct() == [true]; -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationFirstDayOfThisYear():Boolean[1] -//{ -// let expected = [ -// pair(DatabaseType.SybaseIQ, 'select dateadd(DAY, -(datepart(dayofyear, today()) - 1), today()) as "date" from tradeTable as "root"') -// ]; -// -// $expected->map(p| -// let driver = $p.first; -// let expectedSql = $p.second; -// -// let result = toSQLString( -// |Trade.all() -// ->project(col(t|firstDayOfThisYear(), 'date')), -// simpleRelationalMapping, -// $driver, meta::relational::extension::relationalExtensions()); -// -// assertEquals($expectedSql, $result, '\nSQL not as expected for %s\n\nexpected: %s\nactual: %s', [$driver, $expectedSql, $result]); -// )->distinct() == [true]; -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationFirstDayOfQuarter_SybaseIQ():Boolean[1] -//{ -// testToSqlGenerationFirstDayOfQuarter(DatabaseType.SybaseIQ, 'select dateadd(QUARTER, quarter("root".tradeDate) - 1, dateadd(DAY, -(datepart(dayofyear, "root".tradeDate) - 1), "root".tradeDate)) as "date" from tradeTable as "root"'); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationFirstDayOfWeek():Boolean[1] -//{ -// let expected = [ -// pair(DatabaseType.SybaseIQ, 'select dateadd(DAY, -(mod(datepart(weekday, "root".tradeDate)+5, 7)), "root".tradeDate) as "date" from tradeTable as "root"') -// ]; -// -// $expected->map(p| -// let driver = $p.first; -// let expectedSql = $p.second; -// -// let result = toSQLString( -// |Trade.all() -// ->project(col(t|$t.date->firstDayOfWeek(), 'date')), -// simpleRelationalMapping, -// $driver, meta::relational::extension::relationalExtensions()); -// -// assertEquals($expectedSql, $result, '\nSQL not as expected for %s\n\nexpected: %s\nactual: %s', [$driver, $expectedSql, $result]); -// )->distinct() == [true]; -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testSqlGenerationForBooleanProject_IQ():Boolean[1] -//{ -// -// let result1a = toSQLString(|Interaction.all()->project(col(p|true, 'active')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select \'true\' as "active" from interactionTable as "root"', $result1a); -// -// let result1b = toSQLString(|Interaction.all()->project(col(p|!true, 'active')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when (not \'true\' = \'true\') then \'true\' else \'false\' end as "active" from interactionTable as "root"', $result1b); -// -// let result1c = toSQLString(|Interaction.all()->project(col(p|false, 'active')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select \'false\' as "active" from interactionTable as "root"', $result1c); -// -// let result1d = toSQLString(|Interaction.all()->project(col(p|!false, 'active')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when (not \'false\' = \'true\') then \'true\' else \'false\' end as "active" from interactionTable as "root"', $result1d); -// -// let result2 = toSQLString(|Interaction.all()->project(col(p|$p.active, 'active')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when "root"."active" = \'Y\' then \'true\' else \'false\' end as "active" from interactionTable as "root"', $result2); -// -// let result3 = toSQLString(|Interaction.all()->project(col(p|$p.active == true, 'active')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when (case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\') then \'true\' else \'false\' end as "active" from interactionTable as "root"', $result3); -// -// let result4 = toSQLString(|Interaction.all()->project(col(p|$p.active && true, 'active')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when ((case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\' and \'true\' = \'true\')) then \'true\' else \'false\' end as "active" from interactionTable as "root"', $result4); -// -// let result5 = toSQLString(|Interaction.all()->project(col(p|if($p.active, |1, |0), 'active')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\' then 1 else 0 end as "active" from interactionTable as "root"', $result5); -// -// let result6 = toSQLString(|Interaction.all()->project(col(p|$p.active->in(true), 'active')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when (case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\') then \'true\' else \'false\' end as "active" from interactionTable as "root"', $result6); -// -// let result7 = toSQLString(|Interaction.all()->project(col(p|$p.target.firstName->isEmpty(), 'active')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when ("personTable_d#5_d_m1".FIRSTNAME is null) then \'true\' else \'false\' end as "active" from interactionTable as "root" left outer join personTable as "personTable_d#5_d_m1" on ("root".targetId = "personTable_d#5_d_m1".ID)', $result7); -// -// let result10 = toSQLString(|Interaction.all()->project(col(p|!$p.target.firstName->isEmpty(), 'active')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when (not "personTable_d#6_d_m1".FIRSTNAME is null) then \'true\' else \'false\' end as "active" from interactionTable as "root" left outer join personTable as "personTable_d#6_d_m1" on ("root".targetId = "personTable_d#6_d_m1".ID)', $result10); -// -// let result13 = toSQLString(|Interaction.all()->project(col(p|($p.target.firstName->isEmpty() || $p.target.firstName->isEmpty()), 'active')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when (("personTable_d#2_dy0_d#4_d_m1".FIRSTNAME is null or "personTable_d#2_dy0_d#4_d_m1".FIRSTNAME is null)) then \'true\' else \'false\' end as "active" from interactionTable as "root" left outer join personTable as "personTable_d#2_dy0_d#4_d_m1" on ("root".targetId = "personTable_d#2_dy0_d#4_d_m1".ID)', $result13); -// -// let result14 = toSQLString(|Interaction.all()->project(col(p|($p.target.firstName->isEmpty() && $p.target.firstName->isEmpty()), 'active')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when (("personTable_d#2_dy0_d#4_d_m1".FIRSTNAME is null and "personTable_d#2_dy0_d#4_d_m1".FIRSTNAME is null)) then \'true\' else \'false\' end as "active" from interactionTable as "root" left outer join personTable as "personTable_d#2_dy0_d#4_d_m1" on ("root".targetId = "personTable_d#2_dy0_d#4_d_m1".ID)', $result14); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testSqlGenerationForBooleanProject_IQ2():Boolean[1] -//{ -// let result8 = toSQLString(|Interaction.all()->project(col(p|$p.target.firstName->isEmpty() == true, 'active')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when ("personTable_d#6_d_m1".FIRSTNAME is null) then \'true\' else \'false\' end as "active" from interactionTable as "root" left outer join personTable as "personTable_d#6_d_m1" on ("root".targetId = "personTable_d#6_d_m1".ID)', $result8); -// -// let result9 = toSQLString(|Interaction.all()->project(col(p|$p.target.firstName->isEmpty() == false, 'active')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when (not "personTable_d#6_d_m1".FIRSTNAME is null) then \'true\' else \'false\' end as "active" from interactionTable as "root" left outer join personTable as "personTable_d#6_d_m1" on ("root".targetId = "personTable_d#6_d_m1".ID)', $result9); -// -// let result11 = toSQLString(|Interaction.all()->project(col(p|$p.target.firstName->isEmpty()->in(false), 'active')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when (not "personTable_d#6_d_m1".FIRSTNAME is null) then \'true\' else \'false\' end as "active" from interactionTable as "root" left outer join personTable as "personTable_d#6_d_m1" on ("root".targetId = "personTable_d#6_d_m1".ID)', $result11); -// -// let result12 = toSQLString(|Interaction.all()->project(col(p|!($p.target.firstName->isEmpty()->in(false)), 'active')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select case when (("personTable_d#7_d_m1".FIRSTNAME is null)) then \'true\' else \'false\' end as "active" from interactionTable as "root" left outer join personTable as "personTable_d#7_d_m1" on ("root".targetId = "personTable_d#7_d_m1".ID)', $result12); -//} -// -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testSqlGenerationForBooleanFilter_IQ():Boolean[1] -//{ -// let result1a = toSQLString(|Interaction.all()->filter(p|true)->project(col(p|$p.id, 'id')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" where \'true\' = \'true\'', $result1a); -// -// let result1b = toSQLString(|Interaction.all()->filter(p|!true)->project(col(p|$p.id, 'id')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" where not \'true\' = \'true\'', $result1b); -// -// let result1c = toSQLString(|Interaction.all()->filter(p|false)->project(col(p|$p.id, 'id')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" where \'false\' = \'true\'', $result1c); -// -// let result1d = toSQLString(|Interaction.all()->filter(p|!false)->project(col(p|$p.id, 'id')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" where not \'false\' = \'true\'', $result1d); -// -// let result2 = toSQLString(|Interaction.all()->filter(p|$p.active)->project(col(p|$p.id, 'id')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" where case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\'', $result2); -// -// let result3 = toSQLString(|Interaction.all()->filter(p|$p.active == true)->project(col(p|$p.id, 'id')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" where case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\'', $result3); -// -// let result4 = toSQLString(|Interaction.all()->filter(p|$p.active && true)->project(col(p|$p.id, 'id')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" where (case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\' and \'true\' = \'true\')', $result4); -// -// let result5 = toSQLString(|Interaction.all()->filter(p|if($p.active, |1, |0) == 1)->project(col(p|$p.id, 'id')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" where case when case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\' then 1 else 0 end = 1', $result5); -// -// let result6 = toSQLString(|Interaction.all()->filter(p|$p.active->in(true))->project(col(p|$p.id, 'id')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" where case when "root"."active" = \'Y\' then \'true\' else \'false\' end = \'true\'', $result6); -// -// let result7 = toSQLString(|Interaction.all()->filter(p|$p.target.firstName->isEmpty())->project(col(p|$p.id, 'id')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#6_d#2_m1" on ("root".targetId = "personTable_d#6_d#2_m1".ID) where "personTable_d#6_d#2_m1".FIRSTNAME is null', $result7); -// -// let result10 = toSQLString(|Interaction.all()->filter(p|!$p.target.firstName->isEmpty())->project(col(p|$p.id, 'id')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#7_d#2_m1" on ("root".targetId = "personTable_d#7_d#2_m1".ID) where not "personTable_d#7_d#2_m1".FIRSTNAME is null', $result10); -// -// let result13 = toSQLString(|Interaction.all()->filter(p|$p.target.firstName->isEmpty() || $p.target.firstName->isEmpty())->project(col(p|$p.id, 'id')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#3_dy0_d#4_d#2_m1" on ("root".targetId = "personTable_d#3_dy0_d#4_d#2_m1".ID) where ("personTable_d#3_dy0_d#4_d#2_m1".FIRSTNAME is null or "personTable_d#3_dy0_d#4_d#2_m1".FIRSTNAME is null)', $result13); -// -// let result14 = toSQLString(|Interaction.all()->filter(p|$p.target.firstName->isEmpty() && $p.target.firstName->isEmpty())->project(col(p|$p.id, 'id')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#3_dy0_d#4_d#2_m1" on ("root".targetId = "personTable_d#3_dy0_d#4_d#2_m1".ID) where ("personTable_d#3_dy0_d#4_d#2_m1".FIRSTNAME is null and "personTable_d#3_dy0_d#4_d#2_m1".FIRSTNAME is null)', $result14); -//} -// -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testSqlGenerationForBooleanFilter_IQ2():Boolean[1] -//{ -// let result8 = toSQLString(|Interaction.all()->filter(p|$p.target.firstName->isEmpty() == true)->project(col(p|$p.id, 'id')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#7_d#2_m1" on ("root".targetId = "personTable_d#7_d#2_m1".ID) where "personTable_d#7_d#2_m1".FIRSTNAME is null', $result8); -// -// let result9 = toSQLString(|Interaction.all()->filter(p|$p.target.firstName->isEmpty() == false)->project(col(p|$p.id, 'id')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#7_d#2_m1" on ("root".targetId = "personTable_d#7_d#2_m1".ID) where not "personTable_d#7_d#2_m1".FIRSTNAME is null', $result9); -// -// let result11 = toSQLString(|Interaction.all()->filter(p|$p.target.firstName->isEmpty()->in(false))->project(col(p|$p.id, 'id')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#7_d#2_m1" on ("root".targetId = "personTable_d#7_d#2_m1".ID) where not "personTable_d#7_d#2_m1".FIRSTNAME is null', $result11); -// -// let result12 = toSQLString(|Interaction.all()->filter(p|!$p.target.firstName->isEmpty()->in(false))->project(col(p|$p.id, 'id')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#8_d#2_m1" on ("root".targetId = "personTable_d#8_d#2_m1".ID) where ("personTable_d#8_d#2_m1".FIRSTNAME is null)', $result12); -// -// let result15 = toSQLString(|Interaction.all()->filter(p|isTrue($p.target.firstName == 'Andrew')), -// simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select "root".ID as "id" from interactionTable as "root" left outer join personTable as "personTable_d#7_d#2_m1" on ("root".targetId = "personTable_d#7_d#2_m1".ID) where ("personTable_d#7_d#2_m1".FIRSTNAME is null and "personTable_d#7_d#2_m1".FIRSTNAME is null)', $result15); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationMinuteSecond():Boolean[1] -//{ -// let expected = [ -// pair(DatabaseType.SybaseIQ, 'select minute("root".settlementDateTime) as "settlementDateTimeMinute", second("root".settlementDateTime) as "settlementDateTimeSecond" from tradeTable as "root"') -// ]; -// -// $expected->map(p| -// let driver = $p.first; -// let expectedSql = $p.second; -// -// let result = toSQLString( -// |Trade.all()->project([ -// t | $t.settlementDateTime->cast(@Date)->toOne()->minute(), -// t | $t.settlementDateTime->cast(@Date)->toOne()->second() -// ], -// ['settlementDateTimeMinute', 'settlementDateTimeSecond']), -// simpleRelationalMapping, -// $driver, meta::relational::extension::relationalExtensions()); -// -// assertEquals($expectedSql, $result, '\nSQL not as expected for %s\n\nexpected: %s\nactual: %s', [$driver, $expectedSql, $result]); -// )->distinct() == [true]; -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringWithReplace():Boolean[1] -//{ -// let sybaseSql = toSQLString(|Person.all()->project(p|$p.firstName->replace('A', 'a'), 'lowerA'), simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertEquals('select replace("root".FIRSTNAME, \'A\', \'a\') as "lowerA" from personTable as "root"', $sybaseSql); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testSybaseKeyWordInSubSelect():Boolean[1] -//{ -// let date=%2018-03-05; -// let result = meta::relational::functions::sqlstring::toSQLString(|Firm.all()->project([f|$f.legalName, f|$f.employees.locations->filter(o|$o.censusdate == $date).censusdate], ['firm','employee address census date']), simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertSameSQL('select "root".LEGALNAME as "firm", "locationTable_d#5_f_d_d_m2_r"."date" as "employee address census date" from firmTable as "root" left outer join personTable as "personTable_d#7_d_m2" on ("root".ID = "personTable_d#7_d_m2".FIRMID) left outer join (select "locationTable_d#5_f_d".PERSONID as PERSONID, "locationTable_d#5_f_d"."date" as "date" from locationTable as "locationTable_d#5_f_d" where "locationTable_d#5_f_d"."date" = convert(DATE, \'2018-03-05\', 121)) as "locationTable_d#5_f_d_d_m2_r" on ("personTable_d#7_d_m2".ID = "locationTable_d#5_f_d_d_m2_r".PERSONID)', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testSybaseDistinctTake():Boolean[1] -//{ -// let iq = meta::relational::functions::sqlstring::toSQLString(|Person.all()->project(f|$f.firstName, 'firstName')->distinct()->take(10), simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// let ase = meta::relational::functions::sqlstring::toSQLString(|Person.all()->project(f|$f.firstName, 'firstName')->distinct()->take(10), simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// -// let sql = 'select distinct top 10 "root".FIRSTNAME as "firstName" from personTable as "root"'; -// -// assertSameSQL($sql, $iq); -// assertSameSQL($sql, $ase); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testSqlGenerationDivide_AllDBs():Boolean[1] -//{ -// let query = {|Trade.all()->filter(t | $t.id == 2)->map(t | $t.quantity->divide(1000000))}; -// let expectedSQL = 'select ((1.0 * "root".quantity) / 1000000) from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" group by "root".trade_id) as "tradeEventViewMaxTradeEventDate_d#4_d#4_m5" on ("root".ID = "tradeEventViewMaxTradeEventDate_d#4_d#4_m5".trade_id) where "root".ID = 2'; -// -// let resultSybaseIQ = meta::relational::functions::sqlstring::toSQLString($query, simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertSameSQL($expectedSQL, $resultSybaseIQ); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testIsDistinctSQLGeneration():Boolean[1] -//{ -// let func = {|Firm.all()->groupBy( -// [t|$t.legalName], -// [agg(x|$x.employees.firstName,y|$y->isDistinct())], -// ['LegalName', 'IsDistinctFirstName'] -// )}; -// -// let iq = toSQLString($func, simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// assertSameSQL('select "root".LEGALNAME as "LegalName", case when (count(distinct("personTable_d#4_d_m1".FIRSTNAME)) = count("personTable_d#4_d_m1".FIRSTNAME)) then \'true\' else \'false\' end as "IsDistinctFirstName" from firmTable as "root" left outer join personTable as "personTable_d#4_d_m1" on ("root".ID = "personTable_d#4_d_m1".FIRMID) group by "LegalName"', $iq); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSqlGenerationDayOfMonth_SybaseIQ():Boolean[1] -//{ -// let result = toSQLString( -// |Trade.all() -// ->project(col(t|$t.date->dayOfMonth(), 'date')), -// simpleRelationalMapping, -// DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// -// assertEquals('select datepart(DAY,"root".tradeDate) as "date" from tradeTable as "root"', $result); -//} -// -//function <> meta::relational::tests::functions::sqlstring::sybaseIQ::testToSQLStringToNumericCasts():Boolean[1] -//{ -// let result = toSQLString( -// |Trade.all() -// ->project([ -// col(t|$t.quantity->toDecimal(), 'decimal'), -// col(t|$t.quantity->toFloat(), 'float') -// ]), simpleRelationalMapping, DatabaseType.SybaseIQ, meta::relational::extension::relationalExtensions()); -// -// assertEquals('select cast("root".quantity as decimal) as "decimal", cast("root".quantity as double) as "float" from tradeTable as "root"', $result); -//} \ No newline at end of file +// Copyright 2023 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. + +import meta::relational::tests::functions::sqlstring::*; +import meta::pure::mapping::*; +import meta::relational::functions::asserts::*; +import meta::relational::mapping::*; +import meta::relational::tests::*; +import meta::relational::tests::model::simple::*; +import meta::pure::profiles::*; +import meta::relational::functions::sqlstring::*; +import meta::relational::runtime::*; + +function <> meta::relational::tests::functions::sqlstring::sparkSQL::testProcessLiteralForSpark():Boolean[1] +{ + let result = toSQLString(|Person.all()->project([ + a | 'String', + b | %2016-03-01, + c | %2016-03-01T12:18:18.976+0200, + d | 1, + e | 1.1 + ], + ['a','b','c','d', 'e'])->take(0), + simpleRelationalMapping, DatabaseType.SparkSQL, meta::relational::extension::relationalExtensions()); + assertEquals('select top 0 \'String\' as "a", convert(DATE, \'2016-03-01\', 121) as "b", convert(DATETIME, \'2016-03-01 10:18:18.976\', 121) as "c", 1 as "d", 1.1 as "e" from personTable as "root"', $result); +} + +function <> meta::relational::tests::functions::sqlstring::sparkSQL::testToSQLStringWithLength():Boolean[1] +{ + [DatabaseType.SparkSQL]->map(db| + let s = toSQLString(|Person.all()->project(p|length($p.firstName), 'nameLength'), simpleRelationalMapping, $db, meta::relational::extension::relationalExtensions()); + assertEquals('select char_length("root".FIRSTNAME) as "nameLength" from personTable as "root"', $s); + ); +} From a2551f2f55f6170e6dce0f765bc110d059fae088 Mon Sep 17 00:00:00 2001 From: Yasirmod17 Date: Sun, 1 Oct 2023 11:53:04 -0400 Subject: [PATCH 05/10] Add sparkSQL testSuite --- .../pure/code/core/Test_Pure_Relational_SparkSQL.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/test/java/org/finos/legend/pure/code/core/Test_Pure_Relational_SparkSQL.java b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/test/java/org/finos/legend/pure/code/core/Test_Pure_Relational_SparkSQL.java index 5563221ed8e..c729562435f 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/test/java/org/finos/legend/pure/code/core/Test_Pure_Relational_SparkSQL.java +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/src/test/java/org/finos/legend/pure/code/core/Test_Pure_Relational_SparkSQL.java @@ -28,14 +28,8 @@ public static TestSuite suite() executionSupport.getConsole().disable(); TestSuite suite = new TestSuite(); -// suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::relational::tests::sqlToString::sybaseIQ", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); -// suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::relational::tests::tds::sybaseIQ", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); -// suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::pure::executionPlan::tests::sybaseIQ", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); -// suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::relational::tests::projection::sybaseIQ", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); -// suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::relational::tests::functions::sqlstring::sybaseIQ", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); -// suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::relational::tests::mapping::sqlFunction::sybaseIQ", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); -// suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::relational::tests::query::function::sybaseIQ", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); -// suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::relational::tests::postProcessor::sybaseIQ", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); + suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::pure::executionPlan::tests::sparkSQL", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); + suite.addTest(PureTestBuilderCompiled.buildSuite(TestCollection.collectTests("meta::relational::tests::functions::sqlstring::sparkSQL", executionSupport.getProcessorSupport(), fn -> PureTestBuilderCompiled.generatePureTestCollection(fn, executionSupport), ci -> PureTestBuilder.satisfiesConditions(ci, executionSupport.getProcessorSupport())), executionSupport)); return suite; } } From ee819f703c248910a4ff6cab465ac6acd9b5701e Mon Sep 17 00:00:00 2001 From: Yasirmod17 Date: Sun, 1 Oct 2023 13:58:20 -0400 Subject: [PATCH 06/10] add extension --- .../engine/extensions/collection/generation/TestExtensions.java | 1 + 1 file changed, 1 insertion(+) diff --git a/legend-engine-config/legend-engine-extensions-collection-generation/src/test/java/org/finos/legend/engine/extensions/collection/generation/TestExtensions.java b/legend-engine-config/legend-engine-extensions-collection-generation/src/test/java/org/finos/legend/engine/extensions/collection/generation/TestExtensions.java index 5ae46944c3d..da2039c880d 100644 --- a/legend-engine-config/legend-engine-extensions-collection-generation/src/test/java/org/finos/legend/engine/extensions/collection/generation/TestExtensions.java +++ b/legend-engine-config/legend-engine-extensions-collection-generation/src/test/java/org/finos/legend/engine/extensions/collection/generation/TestExtensions.java @@ -509,6 +509,7 @@ protected Iterable getExpectedCodeRepositories() .with("core_relational_presto") .with("core_relational_sybase") .with("core_relational_sybaseiq") + .with("core_relational_sparksql") .with("core_relational_store_entitlement") .with("core_servicestore") .with("core_authentication") From bfd35e7ac475aabcccfe9bc58754f6b756cdead3 Mon Sep 17 00:00:00 2001 From: Mohammed Ibrahim Date: Mon, 2 Oct 2023 09:30:00 -0400 Subject: [PATCH 07/10] Update pom version --- .../legend-engine-xt-relationalStore-sparksql/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/pom.xml b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/pom.xml index 40505c3634c..d38d4ff5c94 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/pom.xml +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/pom.xml @@ -18,7 +18,7 @@ org.finos.legend.engine legend-engine-xt-relationalStore-dbExtension - 4.29.2-SNAPSHOT + >4.30.1-SNAPSHOT 4.0.0 @@ -31,4 +31,4 @@ legend-engine-xt-relationalStore-sparksql-pure - \ No newline at end of file + From 4534741e12466bbb3d32c411ee85cad083785512 Mon Sep 17 00:00:00 2001 From: Mohammed Ibrahim Date: Mon, 2 Oct 2023 09:30:24 -0400 Subject: [PATCH 08/10] Update pom version --- .../legend-engine-xt-relationalStore-sparksql-pure/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/pom.xml b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/pom.xml index dfb1bdf5e16..da5244418e9 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/pom.xml +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/pom.xml @@ -19,7 +19,7 @@ org.finos.legend.engine legend-engine-xt-relationalStore-sparksql - 4.29.2-SNAPSHOT + >4.30.1-SNAPSHOT 4.0.0 From 4ee149438f1074b02e5f831a51d7cf8c172bbba8 Mon Sep 17 00:00:00 2001 From: Mohammed Ibrahim Date: Mon, 2 Oct 2023 09:34:36 -0400 Subject: [PATCH 09/10] Update pom.xml --- .../legend-engine-xt-relationalStore-sparksql/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/pom.xml b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/pom.xml index d38d4ff5c94..2f986e7fe3f 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/pom.xml +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/pom.xml @@ -18,7 +18,7 @@ org.finos.legend.engine legend-engine-xt-relationalStore-dbExtension - >4.30.1-SNAPSHOT + 4.30.1-SNAPSHOT 4.0.0 From 664c24b91735dc4d7739d51ccf11f6a1469a0844 Mon Sep 17 00:00:00 2001 From: Mohammed Ibrahim Date: Mon, 2 Oct 2023 09:35:03 -0400 Subject: [PATCH 10/10] Update pom.xml --- .../legend-engine-xt-relationalStore-sparksql-pure/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/pom.xml b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/pom.xml index da5244418e9..2ce8d244130 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/pom.xml +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-dbExtension/legend-engine-xt-relationalStore-sparksql/legend-engine-xt-relationalStore-sparksql-pure/pom.xml @@ -19,7 +19,7 @@ org.finos.legend.engine legend-engine-xt-relationalStore-sparksql - >4.30.1-SNAPSHOT + 4.30.1-SNAPSHOT 4.0.0