Skip to content

Commit

Permalink
Merge branch 'enumpushtosql' into enumPushUpdate
Browse files Browse the repository at this point in the history
# Conflicts:
#	legend-engine-pure/legend-engine-pure-code/legend-engine-pure-code-compiled-core/src/main/resources/core/pure/router/routing/router_routing.pure
#	legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/contract/storeContract.pure
#	legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/graphFetch/relationalGraphFetch.pure
#	legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/relationalMappingExecution.pure
  • Loading branch information
AFine-gs committed Jan 9, 2024
2 parents 2f58b07 + 46e9484 commit c1ac562
Show file tree
Hide file tree
Showing 12 changed files with 453 additions and 156 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// 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::executionPlan::*;
import meta::pure::runtime::*;
import meta::pure::router::routing::*;
import meta::pure::extension::*;
import meta::pure::executionPlan::featureFlag::*;


Enum meta::pure::executionPlan::features::Feature
{
PUSH_DOWN_ENUM_TRANSFORM
}

function meta::pure::executionPlan::featureFlag::withFeatureFlags<T>(object:T[*],e:Enum[*]):T[*]
{
$object;
}

Class meta::pure::executionPlan::featureFlag::FeatureFlagOption extends meta::pure::executionPlan::ExecutionOption
{
flags:Enum[*];
}


function meta::pure::executionPlan::featureFlag::contextHasFlag(context:ExecutionContext[1],flag:Enum[1]) : Boolean[1]
{
$context ->getContexts()->filter(c|$c->instanceOf(ExecutionOptionContext))->cast(@ExecutionOptionContext)->map(c| $c.executionOptions->filter(f| $f->instanceOf(FeatureFlagOption))->cast(@FeatureFlagOption).flags)->contains($flag);
}

function meta::pure::executionPlan::featureFlag::addFlagToContext(context:ExecutionContext[1],flag:Enum[*]) : ExecutionContext[1]
{
let flagOption =^FeatureFlagOption(flags = $flag);
if($context->instanceOf(ExecutionOptionContext),
|let optionContext = $context->cast(@ExecutionOptionContext);
^$optionContext(executionOptions += $flagOption);,
| let option = ^ExecutionOptionContext(executionOptions=$flagOption);
$context->meta::pure::executionPlan::mergeContext($option);
);
}


function meta::pure::executionPlan::featureFlag::wrapFnWithFeatureFlag<T>(function:Function<T>[1],flags:Enum[*]) : Function<T>[1]
{
$function;
}




function meta::pure::executionPlan::featureFlag::ExecutionPlanFeatureFlagExtension() : Extension[1]
{
let shared = ^Extension(
type = 'featureFlag',
availableFeatures = ^FeatureExtension
(
id = 'featureFlag',
routeFunctionExpressions = [
pair(
fe:FunctionExpression[1] | $fe.func == meta::pure::executionPlan::featureFlag::withFeatureFlags_T_MANY__Enum_MANY__T_MANY_,
{f:Function<Any>[1], fe:FunctionExpression[1], state:RoutingState[1], executionContext:ExecutionContext[1], vars:Map<VariableExpression, ValueSpecification>[1], inScopeVars:Map<String, List<Any>>[1], extensions:meta::pure::extension::Extension[*], debug:DebugContext[1] |

let flags = $fe.parametersValues->at(1)->match([ s: SimpleFunctionExpression[1] | $s->at(0)->cast(@SimpleFunctionExpression)->reactivate()->cast(@Enum);,
i :InstanceValue[*] | $i.values->map(v|$v->cast(@SimpleFunctionExpression)->reactivate()->cast(@Enum));,
a :Any[*] | fail('Found unsupported feature flag Specification, Parameters are not supported for feature flags'); @Enum;
]);


let updatedContext =meta::pure::executionPlan::featureFlag::addFlagToContext($executionContext,$flags);
routeFunctionExpressionFunctionDefinition($f, $fe, ^$state(executionContext=$updatedContext), $updatedContext, $vars, $inScopeVars, $extensions, $debug);
}
)]
)


)
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,50 @@ Class meta::pure::executionPlan::ExecutionOption
{
}

Class meta::pure::executionPlan::ExecutionOptionContext extends ExecutionContext
Class meta::pure::executionPlan::MultiExecutionContext extends ExecutionContext
{
childExecutionContext:ExecutionContext[*];
allContexts() {$this.childExecutionContext->map(e |if($e->instanceOf(MultiExecutionContext),
| $e->concatenate($e->cast(@MultiExecutionContext)->collectionMultiExecutionContexts([])),
|$e)
);
}:ExecutionContext[*];
}
function meta::pure::executionPlan::getContexts(context:ExecutionContext[1]):ExecutionContext[*]
{
if($context->instanceOf(MultiExecutionContext),
| $context->concatenate($context->cast(@MultiExecutionContext).allContexts()),
|$context);
}

function meta::pure::executionPlan::allContextsOfType<T>(context:ExecutionContext[1],contextFilter:Class<T>[1]):T[*]
{
$context->getContexts()->filter(c|$c->instanceOf($contextFilter))->cast(@T);
}


function meta::pure::executionPlan::mergeContext(rootContext:ExecutionContext[1],childContext:ExecutionContext[1]):MultiExecutionContext[1]
{
if($rootContext->instanceOf(MultiExecutionContext),
| let mult = $rootContext->cast(@MultiExecutionContext);
^$mult(childExecutionContext+=$childContext );,
|^MultiExecutionContext(childExecutionContext =$rootContext ->concatenate($childContext) );

);

}



function <<access.private>> meta::pure::executionPlan::collectionMultiExecutionContexts(context:MultiExecutionContext[1], visited : ExecutionContext[*]):ExecutionContext[*]
{
$context.childExecutionContext->map(e |if($e->instanceOf(MultiExecutionContext) && !$e->in($visited),
|$e->concatenate( $e->cast(@MultiExecutionContext)->collectionMultiExecutionContexts( $visited->concatenate($e) )),
|$e)
)
}

Class meta::pure::executionPlan::ExecutionOptionContext extends MultiExecutionContext
{
executionOptions : ExecutionOption[*];
}
Expand Down Expand Up @@ -163,6 +206,7 @@ function meta::pure::executionPlan::generatePlatformCode(plan:ExecutionPlan[1],
function meta::pure::executionPlan::generatePlatformCode(plan:ExecutionPlan[1], platformId:String[1], config:meta::pure::executionPlan::platformBinding::PlatformBindingConfig[1], extensions:meta::pure::extension::Extension[*], debug:DebugContext[1]):ExecutionPlan[1]
{
let platformBinding = $extensions->meta::pure::executionPlan::platformBinding::extractPlatformBindingById($platformId);

$platformBinding.bindPlanToPlatform->eval($plan, $config, $extensions, $debug);
}

Expand Down Expand Up @@ -225,14 +269,14 @@ function meta::pure::executionPlan::nodeFromConnection(c:Connection[1], tree:Roo

function meta::pure::executionPlan::isExecutionOptionPresent(execCtx: ExecutionOptionContext[1], execOption: Class<Any>[1]):Boolean[1]
{
let executionOptionsList = $execCtx.executionOptions->filter(f| $f->instanceOf($execOption));
let executionOptionsList = $execCtx->allContextsOfType(ExecutionOptionContext).executionOptions->filter(f| $f->instanceOf($execOption));
assert($executionOptionsList->size() <= 1, |'Execution Option :' + $execOption.name->toOne() + 'has more than one instance specified in the context');
$executionOptionsList->isNotEmpty();
}

function meta::pure::executionPlan::validateAndReturnExecutionOptionOfType(execCtx: ExecutionOptionContext[1], execOption: Class<Any>[1]):ExecutionOption[1]
{
let executionOptionsList = $execCtx.executionOptions->filter(f| $f->instanceOf($execOption));
let executionOptionsList = $execCtx->allContextsOfType(ExecutionOptionContext).executionOptions->filter(f| $f->instanceOf($execOption));
assert($executionOptionsList->size() == 1, |'Execution Option:' + $execOption.name->toOne() + 'not mentioned or mentioned more than once as part of the context');
$executionOptionsList->head()->toOne();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import meta::pure::router::platform::metamodel::*;
import meta::pure::executionPlan::*;
import meta::pure::graphFetch::execution::*;
import meta::pure::functions::tests::model::*;
import meta::pure::router::platform::metamodel::clustering::*;
import meta::pure::executionPlan::featureFlag::*;

Enum meta::pure::executionPlan::tests::ExampleFlag
{
myFlag

}
Enum meta::pure::executionPlan::tests::ExampleFlag2
{
AnotherFlag

}


Class meta::pure::executionPlan::tests::featureFlag::Person
{

}

function <<test.Test>> meta::pure::executionPlan::tests::featureFlag::testTwoFeatureFlags() : Boolean[1]
{
let gft = #{Person{firstName}}#;
let fn = {|meta::pure::executionPlan::tests::featureFlag::Person.all()->graphFetch($gft)->withFeatureFlags([meta::pure::executionPlan::tests::ExampleFlag.myFlag ,meta::pure::executionPlan::tests::ExampleFlag2.AnotherFlag ])};
let result = meta::pure::router::routeFunction($fn,meta::pure::executionPlan::featureFlag::ExecutionPlanFeatureFlagExtension());
let context =$result.expressionSequence->evaluateAndDeactivate()->cast(@PlatformClusteredValueSpecification).val->cast(@PlatformRoutedValueSpecification).executionContext->toOne();

assert( $context ->contextHasFlag(meta::pure::executionPlan::tests::ExampleFlag.myFlag));
assert( $context ->contextHasFlag(meta::pure::executionPlan::tests::ExampleFlag2.AnotherFlag));
}

function <<test.Test>> meta::pure::executionPlan::tests::featureFlag::testTwoFlagFunctions() : Boolean[1]
{
let gft = #{Person{firstName}}#;
let fn = {|meta::pure::executionPlan::tests::featureFlag::Person.all()->withFeatureFlags([meta::pure::executionPlan::tests::ExampleFlag.myFlag ])->graphFetch($gft)->serialize($gft)->withFeatureFlags([meta::pure::executionPlan::tests::ExampleFlag2.AnotherFlag ])};
let result = meta::pure::router::routeFunction($fn ,meta::pure::executionPlan::featureFlag::ExecutionPlanFeatureFlagExtension());
let context =$result.expressionSequence->evaluateAndDeactivate()->cast(@PlatformClusteredValueSpecification).val->cast(@PlatformRoutedValueSpecification).executionContext->toOne();
assert( $context ->contextHasFlag(meta::pure::executionPlan::tests::ExampleFlag.myFlag));
assert( $context ->contextHasFlag(meta::pure::executionPlan::tests::ExampleFlag2.AnotherFlag));

}

function <<test.Test>> meta::pure::executionPlan::tests::featureFlag::testContextHasFlag() : Boolean[1]
{
let context1= ^ExecutionOptionContext(executionOptions=^FeatureFlagOption(flags=meta::pure::executionPlan::tests::ExampleFlag.myFlag));
assert( $context1 ->contextHasFlag(meta::pure::executionPlan::tests::ExampleFlag.myFlag));

}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Class meta::pure::router::routing::RoutingState
routingStrategy : RoutingStrategy[1];
shouldBeRouted : Boolean[1];
value : Any[0..1];
executionContext: ExecutionContext[1] = ^ExecutionContext();
graphFetchFlow : Boolean[0..1];
}

Expand All @@ -65,7 +66,7 @@ function meta::pure::router::routing::enrichFunctionExpressions(expressions:Func

$processedFunctions->map(fxn | $fxn.value->match([
evs: ExtendedRoutedValueSpecification[1] | $evs,
vs: ValueSpecification[1] | $fxn.routingStrategy.wrapValueSpec($vs, 'strategy_wrapper', $executionContext, $extensions, $debug)
vs: ValueSpecification[1] | $fxn.routingStrategy.wrapValueSpec($vs, 'strategy_wrapper', $fxn.executionContext, $extensions, $debug)
]));
}

Expand Down Expand Up @@ -140,7 +141,7 @@ function <<access.private>> meta::pure::router::routing::routeValueSpecification
if($i.values->size() == 1 && $i.values->at(0)->instanceOf(RelationStoreAccessor),
| $state.routingStrategy.processRelationStoreAccessor($i.values->at(0)->cast(@RelationStoreAccessor<Any>), $i, $state, $executionContext, $debug);,
| $state
);
);
),
pair(
|$i->isOneClass() || ($i.values->isEmpty() && $i.multiplicity == PureOne && $i.genericType.rawType->isNotEmpty() && $i.genericType.rawType->toOne()->instanceOf(Class)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,12 +240,13 @@ function meta::relational::contract::planExecution(sq:meta::pure::mapping::Store
let dbConnectionStore = $oldRuntime.connectionStores->filter(c|$c.connection==$dbConn);
^$oldRuntime(connectionStores = $dbConnectionStore);
);

let queryExeCtx = if($exeCtx->instanceOf(RelationalExecutionContext),|$exeCtx,|[])->cast(@RelationalExecutionContext);
let originalQuery = $sq.fe->toSQLQuery($m, $sq.inScopeVars, $queryExeCtx, $debug, $extensions);
$originalQuery->postProcessSQLQuery($store, $ext, $m, $storeRuntime, $exeCtx, $extensions)
->generateExecutionNodeForPostProcessedResult($sq, $store, $ext, $m, $storeRuntime, $exeCtx, $debug, $extensions);
);
let originalQuery = $sq.fe->toSQLQuery($m->toOne(), $sq.inScopeVars,$debug,$queryExeCtx->relationalExecutionContextToState(defaultState($m->toOne(), $sq.inScopeVars, $exeCtx, $extensions)), $extensions);
$originalQuery->postProcessSQLQuery($store, $ext, $m->toOne(), $storeRuntime, $exeCtx, $extensions)
->generateExecutionNodeForPostProcessedResult($sq, $store, $ext, $m->toOne(), $storeRuntime, $exeCtx, $debug, $extensions);
);

);
}

function meta::relational::contract::postProcessorsMatch(postProcessors1: meta::pure::alloy::connections::PostProcessor[*], postProcessors2: meta::pure::alloy::connections::PostProcessor[*]): Boolean[1]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2482,8 +2482,8 @@ function <<test.Test>> meta::pure::executionPlan::tests::datetime::testPlanWithL
}


function <<test.Test>> meta::pure::executionPlan::tests::testRelationalProjectionWithExternalFormat():Boolean[1]
{
function <<test.Test>> meta::pure::executionPlan::tests::testRelationalProjectionWithExternalFormat():Boolean[1]
{

let extensions =meta::relational::extension::relationalExtensions() ->concatenate(meta::external::format::shared::transformation::tests::exampleExternalFormatExtension()->concatenate(meta::pure::extension::configuration::coreExtensions()));
let result = executionPlan({|Product.all()->project(p|$p.name, 'name')->meta::external::format::shared::functions::externalize('text/example')}, simpleRelationalMapping,meta::external::store::relational::tests::testRuntime(), $extensions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,8 @@ function meta::relational::extension::relationalExtension() : meta::pure::extens
)
},
testExtension_testedBy = {allReferenceUses:ReferenceUsage[*], extensions:Extension[*] | {soFarr:TestedByResult[1]| $allReferenceUses.owner->filter(o|$o->instanceOf(Database))->cast(@Database)->fold({db,tbr|$db->testedBy($tbr, $extensions)}, $soFarr)}},
validTestPackages = 'meta::relational::tests'
validTestPackages = 'meta::relational::tests',
availableFeatures = meta::pure::executionPlan::featureFlag::ExecutionPlanFeatureFlagExtension().availableFeatures
)
}

Expand Down
Loading

0 comments on commit c1ac562

Please sign in to comment.