From 2aaa5d45b98d053cdafba2327a6b40d6170a9067 Mon Sep 17 00:00:00 2001 From: Sai Sriharsha Annepu <72639930+gs-ssh16@users.noreply.github.com> Date: Tue, 11 Jun 2024 22:34:51 +0530 Subject: [PATCH] Filter push down improvements with groupBy subqueries (#2900) --- .../pushFiltersDownToJoin.pure | 159 +++++++++++-- .../tests/testPostProcessor.pure | 210 +++++++++++++++++- .../tests/mapping/dynaJoin/testDynaJoin.pure | 6 +- .../tests/query/testWithFunction.pure | 2 +- 4 files changed, 341 insertions(+), 36 deletions(-) diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/postprocessor/defaultPostProcessor/pushFiltersDownToJoin.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/postprocessor/defaultPostProcessor/pushFiltersDownToJoin.pure index 188110546ed..3969ca01b54 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/postprocessor/defaultPostProcessor/pushFiltersDownToJoin.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/postprocessor/defaultPostProcessor/pushFiltersDownToJoin.pure @@ -92,32 +92,70 @@ function <> meta::relational::postProcessor::filterPushDown::try function <> meta::relational::postProcessor::filterPushDown::tryAddingFiltersToSubQuery(subSelect: SelectSQLQuery[1], filteringPairs: List>[1], extensions:Extension[*]): SelectSQLQuery[1] { - let groupByExists = $subSelect.groupBy->isNotEmpty(); - let opToUpdate = $groupByExists->if(|$subSelect.havingOperation, |$subSelect.filteringOperation); - if ($opToUpdate->size() > 1, + if ($filteringPairs.values->isEmpty(), | $subSelect, - | let newFilters = $filteringPairs.values->map({fp | - let selectCol = $subSelect.columns->filter(x | $x->match([ - a:Alias[1] | ($a.name == $fp.first.column.name) && ($a.relationalElement->instanceOf(TableAliasColumn)), - a:Any[*] | false - ])); - if ($selectCol->size() == 1, - | let toReplaceWith = $selectCol->toOne()->cast(@Alias).relationalElement->cast(@TableAliasColumn); - let transformFunc = {rel: RelationalOperationElement[1] | if($rel == $fp.first, | $toReplaceWith, | $rel)}; - $fp.second->transformNonCached($transformFunc);, - | [] - ); - }); - let combinedNewFilter = $newFilters->reverse()->andFilters($extensions); - - if ($combinedNewFilter->isEmpty(), + | let elementsInSubSelect = $subSelect->extractRelationalElements(false); + let subSelectHasUnknownElementsOrWindowColumns = (!$elementsInSubSelect.noUnknownElement) || $elementsInSubSelect.elements->exists(x | $x->instanceOf(WindowColumn)); + let subSelectHasFromOrToRow = $subSelect.fromRow->isNotEmpty() || $subSelect.toRow->isNotEmpty(); + let cannotPushFiltersIntoSubQuery = $subSelectHasUnknownElementsOrWindowColumns || $subSelectHasFromOrToRow || ($subSelect.filteringOperation->size() > 1) || ($subSelect.havingOperation->size() > 1); + if ($cannotPushFiltersIntoSubQuery, | $subSelect, - | let updatedOp = if($opToUpdate->size() == 1, | [$combinedNewFilter->toOne(), $opToUpdate->toOne()]->andFilters($extensions), | $combinedNewFilter); - $groupByExists->if(|^$subSelect(havingOperation = $updatedOp), | ^$subSelect(filteringOperation = $updatedOp)); + | $filteringPairs.values->fold({fp, aggSelect | $aggSelect->tryAddingSingleFilterToSubQuery($fp, $extensions)}, $subSelect); + ); + ); +} + +function <> meta::relational::postProcessor::filterPushDown::tryAddingSingleFilterToSubQuery(subSelect: SelectSQLQuery[1], filteringPair: Pair[1], extensions:Extension[*]): SelectSQLQuery[1] +{ + let groupByExists = $subSelect.groupBy->isNotEmpty(); + + let selectCol = $subSelect.columns->filter(x | $x->match([ + a:Alias[1] | ($a.name == $filteringPair.first.column.name) && $a.relationalElement->resolveIfSingleTableAliasColumnGroup()->instanceOf(TableAliasColumn), + a:Any[*] | false + ])); + + let groupByNames = $subSelect.groupBy->map(column| $column->match([a:Alias[1]|$a.name, c:ColumnName[1]|$c.name, a:Any[*]|[]])); + let isGroupingColumn = $groupByNames->contains($filteringPair.first.column.name) || + ( + ($selectCol->size() == 1) && + $subSelect.groupBy->map(g | $g->resolveIfSingleTableAliasColumnGroup())->exists({x | + let selectTAC = $selectCol->toOne()->cast(@Alias).relationalElement->resolveIfSingleTableAliasColumnGroup()->cast(@TableAliasColumn); + $x->instanceOf(TableAliasColumn) && ($x->cast(@TableAliasColumn).alias.name == $selectTAC.alias.name) && ($x->cast(@TableAliasColumn).column.name == $selectTAC.column.name); + }) + ); + let opToUpdate = if ($groupByExists && (!$isGroupingColumn), + | $subSelect.havingOperation, + | $subSelect.filteringOperation + ); + + let newFilter = if ($selectCol->size() == 1, + | let toReplaceWith = $selectCol->toOne()->cast(@Alias).relationalElement->resolveIfSingleTableAliasColumnGroup(); + let transformFunc = {rel: RelationalOperationElement[1] | if($rel == $filteringPair.first, | $toReplaceWith, | $rel)}; + $filteringPair.second->transformNonCached($transformFunc);, + | [] + ); + + if ($newFilter->isEmpty(), + | $subSelect, + | let updatedOp = if($opToUpdate->size() == 1, | [$newFilter->toOne(), $opToUpdate->toOne()]->andFilters($extensions), | $newFilter); + if ($groupByExists && (!$isGroupingColumn), + | ^$subSelect(havingOperation = $updatedOp), + | ^$subSelect(filteringOperation = $updatedOp) ); ); } +function <> meta::relational::postProcessor::filterPushDown::resolveIfSingleTableAliasColumnGroup(relOp: RelationalOperationElement[1]): RelationalOperationElement[1] +{ + $relOp->match([ + d: DynaFunction[1] | if(($d.name == 'group') && ($d.parameters->size() == 1) && $d.parameters->at(0)->instanceOf(TableAliasColumn), + | $d.parameters->at(0), + | $relOp + ), + a: Any[*] | $relOp + ]) +} + function <> meta::relational::postProcessor::filterPushDown::addFilterToJoinoperation(filteringPairs : Pair[*], left: TableAliasColumn[1], right: TableAliasColumn[1], operation: RelationalOperationElement[1], joinTableAlias: TableAlias[1], extensions:Extension[*]):Pair>>[1] { let candidatePairs = $filteringPairs->filter(p | $p.first == $left && !($left.alias.name == $joinTableAlias.name && $left.alias.relationalElement->buildUniqueName(true, $extensions) == $joinTableAlias.relationalElement->buildUniqueName(true, $extensions))); @@ -178,4 +216,85 @@ function <> meta::relational::postProcessor::filterPushDown::get | [])));, column: TableAliasColumn[1] | pair($column, $column), rel: RelationalOperationElement[1] | [] ]) ); +} + +Class <> meta::relational::postProcessor::filterPushDown::RelationalElementCollection +{ + noUnknownElement: Boolean[1]; + elements: RelationalOperationElement[*]; +} + +function <> meta::relational::postProcessor::filterPushDown::collection(noUnknownElement: Boolean[1], elements: RelationalOperationElement[*]): RelationalElementCollection[1] +{ + ^RelationalElementCollection(noUnknownElement = $noUnknownElement, elements = $elements) +} + +function <> meta::relational::postProcessor::filterPushDown::extractRelationalElements(elements: RelationalOperationElement[*], recurseSubQueries: Boolean[1]): RelationalElementCollection[1] +{ + let results = $elements->map(el | $el->extractRelationalElements($recurseSubQueries)); + collection($results.noUnknownElement->and(), $results.elements); +} + +function <> meta::relational::postProcessor::filterPushDown::extractRelationalElements(el: RelationalOperationElement[1], recurseSubQueries: Boolean[1]): RelationalElementCollection[1] +{ + let results = $el->match([ + {s: SelectSQLQuery[1] | + let fromData = if($s.data->isNotEmpty(), | $s.data->toOne()->extractRelationalElements($recurseSubQueries), | []); + let fromOtherElements = $s.columns + ->concatenate($s.filteringOperation) + ->concatenate($s.groupBy) + ->concatenate($s.havingOperation) + ->concatenate($s.orderBy.column) + ->concatenate($s.fromRow) + ->concatenate($s.toRow) + ->concatenate($s->match([c:SelectSQLQueryWithCommonTableExpressions[1]|$c.commonTableExpressions, a:Any[*]|[]])) + ->extractRelationalElements($recurseSubQueries); + $fromData->concatenate($fromOtherElements); + }, + {v: ViewSelectSQLQuery[1] | collection(true, [])}, + {u: Union[1] | collection(true, [])}, + {a: TableAlias[1] | collection(true, [])}, // Not recursing on relational element, as it will happen from data + {a: Alias[1] | $a.relationalElement->extractRelationalElements($recurseSubQueries)}, + {t: Table[1] | collection(true, [])}, + {c: CommonTableExpression[1] | $c.sqlQuery->extractRelationalElements($recurseSubQueries)}, + {t: CommonTableExpressionReference[1] | collection(true, [])}, + {t: TableAliasColumn[1] | $t.column->extractRelationalElements($recurseSubQueries)}, // Not recursing on alias, as it will happen from data + {a: TableAliasColumnName[1] | collection(true, [])}, // Not recursing on alias, as it will happen from data + {u: UnaryOperation[1] | $u.nested->extractRelationalElements($recurseSubQueries)}, + {b: BinaryOperation[1] | $b.left->concatenate($b.right)->extractRelationalElements($recurseSubQueries)}, + {va: VariableArityOperation[1] |$va.args->extractRelationalElements($recurseSubQueries)}, + {d: DynaFunction[1] | $d.parameters->extractRelationalElements($recurseSubQueries)}, + {f: FreeMarkerOperationHolder[1] | $f.parameters->extractRelationalElements($recurseSubQueries)}, + {wc: Column[1] | collection(true, [])}, + {wc: ColumnName[1] | collection(true, [])}, + {wc: WindowColumn[1] | $wc.window->concatenate($wc.func)->extractRelationalElements($recurseSubQueries)}, + {wc: Literal[1] | collection(true, [])}, + {wc: LiteralList[1] | collection(true, [])}, + {wc: VarPlaceHolder[1] | collection(true, [])}, + {w: meta::relational::metamodel::Window[1] | $w.partition->concatenate($w.sortBy)->extractRelationalElements($recurseSubQueries)}, + {js: JoinStrings[1] | $js.strings->concatenate($js.prefix)->concatenate($js.separator)->concatenate($js.suffix)->extractRelationalElements($recurseSubQueries)}, + {s: SemiStructuredPropertyAccess[1] | $s.operand->concatenate($s.property)->concatenate($s.index)->extractRelationalElements($recurseSubQueries)}, + {s: SemiStructuredArrayElementAccess[1] | $s.operand->concatenate($s.index)->extractRelationalElements($recurseSubQueries)}, + {s: SemiStructuredArrayFlatten[1] | $s.navigation->extractRelationalElements($recurseSubQueries)}, + {s: SemiStructuredArrayFlattenOutput[1] | $s.tableAliasColumn->extractRelationalElements($recurseSubQueries)}, + {a: Any[*] | /*println('Encountered unknown element of type: ' + $el->type()->elementToPath());*/ collection(false, []);} + ]); + collection($results.noUnknownElement->and(), $el->concatenate($results.elements)); +} + +function <> meta::relational::postProcessor::filterPushDown::extractRelationalElements(rn: RelationalTreeNode[1], recurseSubQueries: Boolean[1]): RelationalElementCollection[1] +{ + let aliasResults = $rn.alias->extractRelationalElements($recurseSubQueries); + let relElementResults = $rn.alias.relationalElement->match([ + u: Union[1] | collection(true, $u)->concatenate(if($recurseSubQueries, | $u.queries->extractRelationalElements($recurseSubQueries), | [])), + v: ViewSelectSQLQuery[1] | collection(true, $v)->concatenate(if($recurseSubQueries, | $v.selectSQLQuery->extractRelationalElements($recurseSubQueries), | [])), + s: SelectSQLQuery[1] | collection(true, $s)->concatenate(if($recurseSubQueries, | $s->extractRelationalElements($recurseSubQueries), | [])), + t: Table[1] | collection(true, $t), + ss: SemiStructuredArrayFlatten[1] | $ss->extractRelationalElements($recurseSubQueries), + a: Any[*] | /*println('Encountered unknown element of type: ' + $a->type()->elementToPath());*/ collection(false, $rn.alias.relationalElement); + ]); + let joinResults = $rn->match([jtn: JoinTreeNode[1] | $jtn.join.operation->extractRelationalElements($recurseSubQueries), a: Any[*] | []]); + let childrenResults = $rn.childrenData->cast(@RelationalTreeNode)->map(c | $c->extractRelationalElements($recurseSubQueries)); + let results = $aliasResults->concatenate($relElementResults)->concatenate($joinResults)->concatenate($childrenResults); + collection($results.noUnknownElement->and(), $results.elements); } \ No newline at end of file diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/postprocessor/tests/testPostProcessor.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/postprocessor/tests/testPostProcessor.pure index f70d0206523..db078d749ff 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/postprocessor/tests/testPostProcessor.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/postprocessor/tests/testPostProcessor.pure @@ -146,43 +146,43 @@ function meta::relational::tests::postProcessor::nonExecutable::runtimeWithNonEx function <> meta::relational::tests::postProcessor::filterPushDown::testPushFiltersDownToJoinsPostProcessorSimpleObjectFilterEqual():Boolean[1] { let result = execute(|Trade.all()->filter(x | $x.id == 100)->project([x|$x.id, x|$x.quantity, x|$x.latestEventDate], ['TradeID', 'Quantity', 'LastEventDate']), simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions()); - assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" 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 having "root".trade_id = 100) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id = 100) where "root".ID = 100', $result); + assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" where "root".trade_id = 100 group by "root".trade_id) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id = 100) where "root".ID = 100', $result); } function <> meta::relational::tests::postProcessor::filterPushDown::testPushFiltersDownToJoinsPostProcessorSimpleTDSFilterEqual():Boolean[1] { let result = execute(|Trade.all()->project([x|$x.id, x|$x.quantity, x|$x.latestEventDate], ['TradeID', 'Quantity', 'LastEventDate'])->filter(x | $x.getInteger('TradeID') == 100), simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions()); - assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" 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 having "root".trade_id = 100) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id = 100) where "root".ID = 100', $result); + assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" where "root".trade_id = 100 group by "root".trade_id) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id = 100) where "root".ID = 100', $result); } function <> meta::relational::tests::postProcessor::filterPushDown::testPushFiltersDownToJoinsPostProcessorTDSFilterGreaterThan():Boolean[1] { let result = execute(|Trade.all()->project([x|$x.id, x|$x.quantity, x|$x.latestEventDate], ['TradeID', 'Quantity', 'LastEventDate'])->filter(x | $x.getInteger('TradeID') > 100), simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions()); - assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" 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 having "root".trade_id > 100) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id > 100) where "root".ID > 100', $result); + assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" where "root".trade_id > 100 group by "root".trade_id) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id > 100) where "root".ID > 100', $result); } function <> meta::relational::tests::postProcessor::filterPushDown::testPushFiltersDownToJoinsPostProcessorTDSFilterGreaterThanWithDyna():Boolean[1] { let result = execute(|Trade.all()->project([x|$x.id, x|$x.quantity, x|$x.latestEventDate], ['TradeID', 'Quantity', 'LastEventDate'])->filter(x | $x.getInteger('TradeID') > (100 + 2)), simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions()); - assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" 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 having "root".trade_id > (100 + 2)) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id > (100 + 2)) where "root".ID > (100 + 2)', $result); + assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" where "root".trade_id > (100 + 2) group by "root".trade_id) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id > (100 + 2)) where "root".ID > (100 + 2)', $result); } function <> meta::relational::tests::postProcessor::filterPushDown::testPushFiltersDownToJoinsPostProcessorTDSFilterUnaryOp():Boolean[1] { let result = execute(|Trade.all()->project([x|$x.id, x|$x.quantity, x|$x.latestEventDate], ['TradeID', 'Quantity', 'LastEventDate'])->filter(x | $x.getInteger('TradeID')->isNotEmpty()), simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions()); - assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" 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 having "root".trade_id is not null) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id is not null) where "root".ID is not null', $result); + assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" where "root".trade_id is not null group by "root".trade_id) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id is not null) where "root".ID is not null', $result); } function <> meta::relational::tests::postProcessor::filterPushDown::testPushFiltersDownToJoinsPostProcessorTDSFilterInOp():Boolean[1] { let result = execute(|Trade.all()->project([x|$x.id, x|$x.quantity, x|$x.latestEventDate], ['TradeID', 'Quantity', 'LastEventDate'])->filter(x | $x.getInteger('TradeID')->in([1,2,3,4,5])), simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions()); - assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" 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 having "root".trade_id in (1, 2, 3, 4, 5)) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id in (1, 2, 3, 4, 5)) where "root".ID in (1, 2, 3, 4, 5)', $result); + assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" where "root".trade_id in (1, 2, 3, 4, 5) group by "root".trade_id) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id in (1, 2, 3, 4, 5)) where "root".ID in (1, 2, 3, 4, 5)', $result); } function <> meta::relational::tests::postProcessor::filterPushDown::testPushFiltersDownToJoinsPostProcessorTDSFilterAndOp():Boolean[1] { let result = execute(|Trade.all()->project([x|$x.id, x|$x.quantity, x|$x.latestEventDate], ['TradeID', 'Quantity', 'LastEventDate'])->filter(x | ($x.getInteger('TradeID') > 0) && ($x.getInteger('TradeID') <= 5)), simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions()); - assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" 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 having "root".trade_id > 0 and "root".trade_id <= 5) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id > 0 and "tradeeventviewmaxtradeeventdate_0".trade_id <= 5) where ("root".ID > 0 and "root".ID <= 5)', $result); + assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" where "root".trade_id > 0 and "root".trade_id <= 5 group by "root".trade_id) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id > 0 and "tradeeventviewmaxtradeeventdate_0".trade_id <= 5) where ("root".ID > 0 and "root".ID <= 5)', $result); } function <> meta::relational::tests::postProcessor::filterPushDown::testPushFiltersDownToJoinsPostProcessorTDSFilterOrOp():Boolean[1] @@ -194,31 +194,217 @@ function <> meta::relational::tests::postProcessor::filterPushDown::t function <> meta::relational::tests::postProcessor::filterPushDown::testPushFiltersDownToJoinsPostProcessorTDSFilterCombinedOp():Boolean[1] { let result = execute(|Trade.all()->project([x|$x.id, x|$x.quantity, x|$x.latestEventDate], ['TradeID', 'Quantity', 'LastEventDate'])->filter(x | $x.getInteger('TradeID')->isNotEmpty() && $x.getInteger('TradeID')->in([1,2])), simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions()); - assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" 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 having "root".trade_id is not null and "root".trade_id in (1, 2)) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id is not null and "tradeeventviewmaxtradeeventdate_0".trade_id in (1, 2)) where ("root".ID is not null and "root".ID in (1, 2))', $result); + assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" where "root".trade_id is not null and "root".trade_id in (1, 2) group by "root".trade_id) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id is not null and "tradeeventviewmaxtradeeventdate_0".trade_id in (1, 2)) where ("root".ID is not null and "root".ID in (1, 2))', $result); } function <> meta::relational::tests::postProcessor::filterPushDown::testPushFiltersDownToJoinsPostProcessorTDSFilterCombinedWithOrOp():Boolean[1] { let result = execute(|Trade.all()->project([x|$x.id, x|$x.quantity, x|$x.latestEventDate], ['TradeID', 'Quantity', 'LastEventDate'])->filter(x | $x.getInteger('TradeID')->isNotEmpty() && !(($x.getInteger('TradeID') <= 0) || ($x.getInteger('TradeID') > 5))), simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions()); - assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" 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 having "root".trade_id is not null) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id is not null) where ("root".ID is not null and not ("root".ID <= 0 or "root".ID > 5))', $result); + assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" where "root".trade_id is not null group by "root".trade_id) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id is not null) where ("root".ID is not null and not ("root".ID <= 0 or "root".ID > 5))', $result); } function <> meta::relational::tests::postProcessor::filterPushDown::testPushFiltersDownToJoinsPostProcessorMultipleChildren():Boolean[1] { let result = execute(|Trade.all()->project([x|$x.id, x|$x.quantity, x|$x.latestEventDate, x|$x.initiator.firstName], ['TradeID', 'Quantity', 'LastEventDate', 'Initiator'])->filter(x | $x.getInteger('TradeID')->in([1,2,3,4,5])), simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions()); - assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate", "persontable_0".FIRSTNAME as "Initiator" 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 having "root".trade_id in (1, 2, 3, 4, 5)) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id in (1, 2, 3, 4, 5)) left outer join tradeEventTable as "tradeeventtable_1" on ("root".ID = "tradeeventtable_1".trade_id and "tradeeventtable_1".trade_id in (1, 2, 3, 4, 5) and "tradeeventtable_1".eventDate = "root".tradeDate) left outer join personTable as "persontable_0" on ("tradeeventtable_1".person_id = "persontable_0".ID) where "root".ID in (1, 2, 3, 4, 5)', $result); + assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate", "persontable_0".FIRSTNAME as "Initiator" from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" where "root".trade_id in (1, 2, 3, 4, 5) group by "root".trade_id) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id in (1, 2, 3, 4, 5)) left outer join tradeEventTable as "tradeeventtable_1" on ("root".ID = "tradeeventtable_1".trade_id and "tradeeventtable_1".trade_id in (1, 2, 3, 4, 5) and "tradeeventtable_1".eventDate = "root".tradeDate) left outer join personTable as "persontable_0" on ("tradeeventtable_1".person_id = "persontable_0".ID) where "root".ID in (1, 2, 3, 4, 5)', $result); +} + +function <> meta::relational::tests::postProcessor::filterPushDown::testPushFiltersDownIntoSubQuery():Boolean[1] +{ + let result = execute( + {|Trade.all() + ->project( + [ + x|$x.id, + x|$x.date, + x|$x.quantity, + x|$x.product.name, + x|$x.latestEventDate + ], + [ + 'TradeID', + 'TradeDate', + 'Quantity', + 'Product', + 'LastEventDate' + ] + ) + ->distinct() + ->restrict( + [ + 'TradeID', + 'TradeDate', + 'Quantity', + 'Product' + ] + ) + ->filter(x | $x.getInteger('TradeID') == 1) + }, + simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions() + ); + + assertSameSQL('select "tradetable_0"."TradeID" as "TradeID", "tradetable_0"."TradeDate" as "TradeDate", "tradetable_0"."Quantity" as "Quantity", "tradetable_0"."Product" as "Product" from (select distinct "root".ID as "TradeID", "root".tradeDate as "TradeDate", "root".quantity as "Quantity", "producttable_0".NAME as "Product", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate" from tradeTable as "root" left outer join productSchema.productTable as "producttable_0" on ("root".prodId = "producttable_0".ID) left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" where "root".trade_id = 1 group by "root".trade_id) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id = 1) where "root".ID = 1) as "tradetable_0" where "tradetable_0"."TradeID" = 1', $result); +} + +function <> meta::relational::tests::postProcessor::filterPushDown::testPushFiltersDownIntoSubQueryWithTDSJoin():Boolean[1] +{ + let result = execute( + {|Trade.all() + ->project( + [ + x|$x.id, + x|$x.date + ], + [ + 'TradeID', + 'TradeDate' + ] + ) + ->join( + Trade.all() + ->project( + [ + x|$x.id, + x|$x.product.name + ], + [ + 'TradeID', + 'ProductName' + ] + ), + JoinType.INNER, + ['TradeID'] + ) + ->filter(x | $x.getInteger('TradeID') == 1) + }, + simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions() + ); + + assertSameSQL('select "tradetable_0"."TradeID" as "TradeID", "tradetable_0"."TradeDate" as "TradeDate", "tradetable_0"."ProductName" as "ProductName" from (select "tradetable_1"."TradeID" as "TradeID", "tradetable_1"."TradeDate" as "TradeDate", "tradetable_3"."ProductName" as "ProductName" from (select "root".ID as "TradeID", "root".tradeDate as "TradeDate" from tradeTable as "root" where "root".ID = 1) as "tradetable_1" inner join (select "root".ID as "TradeID", "producttable_0".NAME as "ProductName" from tradeTable as "root" left outer join productSchema.productTable as "producttable_0" on ("root".prodId = "producttable_0".ID) where "root".ID = 1) as "tradetable_3" on ("tradetable_1"."TradeID" = "tradetable_3"."TradeID" and "tradetable_3"."TradeID" = 1) where "tradetable_1"."TradeID" = 1) as "tradetable_0" where "tradetable_0"."TradeID" = 1', $result); +} + +function <> meta::relational::tests::postProcessor::filterPushDown::testPushFiltersDownIntoSubQueryWithTDSJoinPartial():Boolean[1] +{ + let result = execute( + {|Trade.all() + ->project( + [ + x|$x.id, + x|$x.product.name + ], + [ + 'TradeID', + 'ProductName' + ] + ) + ->join( + Product.all() + ->project( + [ + x|$x.name, + x|$x.cusip + ], + [ + 'ProductName', + 'CUSIP' + ] + ), + JoinType.INNER, + ['ProductName'] + ) + ->filter(x | $x.getInteger('TradeID') == 1) + }, + simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions() + ); + + assertSameSQL('select "tradetable_0"."TradeID" as "TradeID", "tradetable_0"."ProductName" as "ProductName", "tradetable_0"."CUSIP" as "CUSIP" from (select "tradetable_1"."TradeID" as "TradeID", "tradetable_1"."ProductName" as "ProductName", "producttable_1"."CUSIP" as "CUSIP" from (select "root".ID as "TradeID", "producttable_0".NAME as "ProductName" from tradeTable as "root" left outer join productSchema.productTable as "producttable_0" on ("root".prodId = "producttable_0".ID) where "root".ID = 1) as "tradetable_1" inner join (select "root".NAME as "ProductName", "synonymtable_0".NAME as "CUSIP" from productSchema.productTable as "root" left outer join productSchema.synonymTable as "synonymtable_0" on ("synonymtable_0".PRODID = "root".ID and "synonymtable_0".TYPE = \'CUSIP\')) as "producttable_1" on ("tradetable_1"."ProductName" = "producttable_1"."ProductName") where "tradetable_1"."TradeID" = 1) as "tradetable_0" where "tradetable_0"."TradeID" = 1', $result); +} + +function <> meta::relational::tests::postProcessor::filterPushDown::testPushFiltersDownIntoSubQueryWithGroupByGroupingColumnsFilter():Boolean[1] +{ + let result = execute( + {|Trade.all() + ->groupBy( + [ + x|$x.date, + x|$x.product.name + ], + [ + agg(x|$x.id, y|$y->count()), + agg(x|$x.quantity, y|$y->sum()) + ], + [ + 'TradeDate', + 'Product', + 'TradeCount', + 'QtySum' + ] + ) + ->distinct() + ->restrict( + [ + 'TradeDate', + 'Product', + 'TradeCount', + 'QtySum' + ] + ) + ->filter(x | ($x.isNotNull('TradeDate')) && ($x.getString('Product') == 'Product A')) + }, + simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions() + ); + + assertSameSQL('select "tradetable_0"."TradeDate" as "TradeDate", "tradetable_0"."Product" as "Product", "tradetable_0"."TradeCount" as "TradeCount", "tradetable_0"."QtySum" as "QtySum" from (select distinct "root".tradeDate as "TradeDate", "producttable_0".NAME as "Product", count("root".ID) as "TradeCount", sum("root".quantity) as "QtySum" from tradeTable as "root" left outer join productSchema.productTable as "producttable_0" on ("root".prodId = "producttable_0".ID) where "root".tradeDate is not null and "producttable_0".NAME = \'Product A\' group by "TradeDate","Product") as "tradetable_0" where ("tradetable_0"."TradeDate" is not null and "tradetable_0"."Product" = \'Product A\')', $result); +} + +function <> meta::relational::tests::postProcessor::filterPushDown::testPushFiltersDownIntoSubQueryWithGroupByGroupingAndAggregateColumnsFilter():Boolean[1] +{ + let result = execute( + {|Trade.all() + ->groupBy( + [ + x|$x.date, + x|$x.product.name + ], + [ + agg(x|$x.id, y|$y->count()), + agg(x|$x.quantity, y|$y->sum()) + ], + [ + 'TradeDate', + 'Product', + 'TradeCount', + 'QtySum' + ] + ) + ->distinct() + ->restrict( + [ + 'TradeDate', + 'Product', + 'TradeCount', + 'QtySum' + ] + ) + ->filter(x | ($x.isNotNull('TradeDate')) && ($x.getString('Product') == 'Product A') && ($x.getInteger('TradeCount') > 2) && ($x.getFloat('QtySum') > 20)) + }, + simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions() + ); + + // Filters on aggregate columns are not pushed into having clause of the subquery, as currently targeting columns with relOp being a TableAliasColumn + assertSameSQL('select "tradetable_0"."TradeDate" as "TradeDate", "tradetable_0"."Product" as "Product", "tradetable_0"."TradeCount" as "TradeCount", "tradetable_0"."QtySum" as "QtySum" from (select distinct "root".tradeDate as "TradeDate", "producttable_0".NAME as "Product", count("root".ID) as "TradeCount", sum("root".quantity) as "QtySum" from tradeTable as "root" left outer join productSchema.productTable as "producttable_0" on ("root".prodId = "producttable_0".ID) where "root".tradeDate is not null and "producttable_0".NAME = \'Product A\' group by "TradeDate","Product") as "tradetable_0" where ((("tradetable_0"."TradeDate" is not null and "tradetable_0"."Product" = \'Product A\') and "tradetable_0"."TradeCount" > 2) and "tradetable_0"."QtySum" > 20)', $result); } function <> meta::relational::tests::postProcessor::filterPushDown::testPushFiltersDownToJoinsPostProcessorToSQL():Boolean[1] { let result = meta::relational::functions::sqlstring::toSQL(|Trade.all()->project([x|$x.id, x|$x.quantity, x|$x.latestEventDate, x|$x.initiator.firstName], ['TradeID', 'Quantity', 'LastEventDate', 'Initiator'])->filter(x | $x.getInteger('TradeID')->in([1,2,3,4,5])), simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions()).sqlQueries->at(0)->meta::relational::functions::sqlQueryToString::sqlQueryToString(DatabaseType.H2, '', [], meta::relational::extension::relationalExtensions()); - assertEquals('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate", "persontable_0".FIRSTNAME as "Initiator" 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 having "root".trade_id in (1, 2, 3, 4, 5)) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id in (1, 2, 3, 4, 5)) left outer join tradeEventTable as "tradeeventtable_1" on ("root".ID = "tradeeventtable_1".trade_id and "tradeeventtable_1".trade_id in (1, 2, 3, 4, 5) and "tradeeventtable_1".eventDate = "root".tradeDate) left outer join personTable as "persontable_0" on ("tradeeventtable_1".person_id = "persontable_0".ID) where "root".ID in (1, 2, 3, 4, 5)', $result); + assertEquals('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate", "persontable_0".FIRSTNAME as "Initiator" from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" where "root".trade_id in (1, 2, 3, 4, 5) group by "root".trade_id) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id in (1, 2, 3, 4, 5)) left outer join tradeEventTable as "tradeeventtable_1" on ("root".ID = "tradeeventtable_1".trade_id and "tradeeventtable_1".trade_id in (1, 2, 3, 4, 5) and "tradeeventtable_1".eventDate = "root".tradeDate) left outer join personTable as "persontable_0" on ("tradeeventtable_1".person_id = "persontable_0".ID) where "root".ID in (1, 2, 3, 4, 5)', $result); } function <> meta::relational::tests::postProcessor::testSqlRealiasJoin():Boolean[1] { let result = execute(|Trade.all()->project([x|$x.id, x|$x.quantity, x|$x.latestEventDate, x|$x.initiator.firstName], ['TradeID', 'Quantity', 'LastEventDate', 'Initiator'])->filter(x | $x.getInteger('TradeID')->in([1,2,3,4,5])), simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions(),debug()); - assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate", "persontable_0".FIRSTNAME as "Initiator" 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 having "root".trade_id in (1, 2, 3, 4, 5)) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id in (1, 2, 3, 4, 5)) left outer join tradeEventTable as "tradeeventtable_1" on ("root".ID = "tradeeventtable_1".trade_id and "tradeeventtable_1".trade_id in (1, 2, 3, 4, 5) and "tradeeventtable_1".eventDate = "root".tradeDate) left outer join personTable as "persontable_0" on ("tradeeventtable_1".person_id = "persontable_0".ID) where "root".ID in (1, 2, 3, 4, 5)', $result); + assertSameSQL('select "root".ID as "TradeID", "root".quantity as "Quantity", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "LastEventDate", "persontable_0".FIRSTNAME as "Initiator" from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" where "root".trade_id in (1, 2, 3, 4, 5) group by "root".trade_id) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id in (1, 2, 3, 4, 5)) left outer join tradeEventTable as "tradeeventtable_1" on ("root".ID = "tradeeventtable_1".trade_id and "tradeeventtable_1".trade_id in (1, 2, 3, 4, 5) and "tradeeventtable_1".eventDate = "root".tradeDate) left outer join personTable as "persontable_0" on ("tradeeventtable_1".person_id = "persontable_0".ID) where "root".ID in (1, 2, 3, 4, 5)', $result); } function <> meta::relational::tests::postProcessor::testSqlRealiasViews():Boolean[1] diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/tests/mapping/dynaJoin/testDynaJoin.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/tests/mapping/dynaJoin/testDynaJoin.pure index 52f5c01ee38..4fa6b64211d 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/tests/mapping/dynaJoin/testDynaJoin.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/tests/mapping/dynaJoin/testDynaJoin.pure @@ -44,7 +44,7 @@ function <> meta::relational::tests::mapping::dynajoin::testJoinWithA assertSize($result.values, 2); assertSameElements(['1','6'],$result.values->map(r |$r.id->toString())); assertSameElements([%2014-12-03,%2014-12-04],$result.values->map(r |$r.latestEventDate)); - assertEquals('select "root".ID as "pk_0", "root".ID as "id", "root".quantity as "quantity", "root".tradeDate as "date", "root".settlementDateTime as "settlementDateTime", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "latestEventDate" 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 having "root".trade_id in (1, 6)) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id in (1, 6)) where "root".ID in (1, 6)', $result->sqlRemoveFormatting()); + assertEquals('select "root".ID as "pk_0", "root".ID as "id", "root".quantity as "quantity", "root".tradeDate as "date", "root".settlementDateTime as "settlementDateTime", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "latestEventDate" from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" where "root".trade_id in (1, 6) group by "root".trade_id) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id in (1, 6)) where "root".ID in (1, 6)', $result->sqlRemoveFormatting()); } function <> meta::relational::tests::mapping::dynajoin::testFilterOnJoinWithAggregateFunction():Boolean[1] @@ -53,7 +53,7 @@ function <> meta::relational::tests::mapping::dynajoin::testFilterOnJ assertSize($result.values, 1); assertSameElements(['1'],$result.values->map(r |$r.id->toString() )); assertSameElements([%2014-12-03],$result.values->map(r |$r.latestEventDate)); - assertEquals('select "root".ID as "pk_0", "root".ID as "id", "root".quantity as "quantity", "root".tradeDate as "date", "root".settlementDateTime as "settlementDateTime", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "latestEventDate" 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 having "root".trade_id in (1, 6)) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id in (1, 6)) where ("root".ID in (1, 6) and "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate = \'2014-12-03\')', $result->sqlRemoveFormatting() ); + assertEquals('select "root".ID as "pk_0", "root".ID as "id", "root".quantity as "quantity", "root".tradeDate as "date", "root".settlementDateTime as "settlementDateTime", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "latestEventDate" from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" where "root".trade_id in (1, 6) group by "root".trade_id) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id in (1, 6)) where ("root".ID in (1, 6) and "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate = \'2014-12-03\')', $result->sqlRemoveFormatting() ); } function <> meta::relational::tests::mapping::dynajoin::testFilterOnJoinWithAggregateFunctionWithProject():Boolean[1] @@ -70,7 +70,7 @@ function <> meta::relational::tests::mapping::dynajoin::testFilterOnJ assertSize($tds.rows, 2); assertEquals([1, %2014-12-03], $tds.rows->at(0).values); assertEquals([6, %2014-12-04], $tds.rows->at(1).values); - assertEquals('select "root".ID as "id", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "latestEventDate" 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 having "root".trade_id in (1, 6)) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id in (1, 6)) where "root".ID in (1, 6)', $result->sqlRemoveFormatting()); + assertEquals('select "root".ID as "id", "tradeeventviewmaxtradeeventdate_0".maxTradeEventDate as "latestEventDate" from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" where "root".trade_id in (1, 6) group by "root".trade_id) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id in (1, 6)) where "root".ID in (1, 6)', $result->sqlRemoveFormatting()); } function <> meta::relational::tests::mapping::dynajoin::testSelfJoinWithAggregateFunction():Boolean[1] diff --git a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/tests/query/testWithFunction.pure b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/tests/query/testWithFunction.pure index bab56146219..ebd0727b961 100644 --- a/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/tests/query/testWithFunction.pure +++ b/legend-engine-xts-relationalStore/legend-engine-xt-relationalStore-generation/legend-engine-xt-relationalStore-pure/src/main/resources/core_relational/relational/tests/query/testWithFunction.pure @@ -463,7 +463,7 @@ function <> meta::relational::tests::query::function::distinct::testC function <> meta::relational::tests::query::function::divide::testDivideFunctionPrecision():Boolean[1] { let result = execute(|Trade.all()->filter(t | $t.id == 2)->map(t | [$t.quantity, 32147678342]->times()->divide(1000)), simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions()); - assertSameSQL('select ((1.0 * ("root".quantity * 32147678342)) / 1000) 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 having "root".trade_id = 2) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id = 2) where "root".ID = 2', $result); + assertSameSQL('select ((1.0 * ("root".quantity * 32147678342)) / 1000) from tradeTable as "root" left outer join (select "root".trade_id as trade_id, max("root".eventDate) as maxTradeEventDate from tradeEventTable as "root" where "root".trade_id = 2 group by "root".trade_id) as "tradeeventviewmaxtradeeventdate_0" on ("root".ID = "tradeeventviewmaxtradeeventdate_0".trade_id and "tradeeventviewmaxtradeeventdate_0".trade_id = 2) where "root".ID = 2', $result); assertEq(10287257069.44, $result.values->at(0)); // 8 decimal places let result2 = execute(|Trade.all()->filter(t | $t.id == 2)->map(t | [$t.quantity, 32147678342]->times()->divide(1000000000)), simpleRelationalMapping, meta::external::store::relational::tests::testRuntime(), meta::relational::extension::relationalExtensions());