Skip to content

Commit

Permalink
Fix - In processing with Literal list For Snowflake (#2415)
Browse files Browse the repository at this point in the history
* Fix - In processing with Literal list

* Add unit test - Execution plan test for In processing with literal list in snowflake

* Refactor - Use a function that processes temp table name literal based on db type
  • Loading branch information
gs-kotang authored Nov 4, 2023
1 parent acf1f6e commit 5b6d766
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,21 @@ function <<test.Test>> meta::pure::executionPlan::tests::snowflake::testRelation
let expectedPlan = 'Relational(type=TDS[(Name,String,VARCHAR(200),"")]resultColumns=[("Name",VARCHAR(200))]sql=select"root".NAMEas"Name"fromproductSchema.productTableas"root"connection=RelationalDatabaseConnection(type="Snowflake"))';
assertEquals($expectedPlan, $generatedPlan->planToStringWithoutFormatting(meta::relational::extension::relationalExtensions()));
}

function <<test.Test>> meta::pure::executionPlan::tests::snowflake::testInExecutionWithLiteralListSnowflake():Boolean[1]
{
let intList = range(1,17000);
let generatedPlan = executionPlan({|Person.all()->filter(p|$p.age->in($intList))->project([x |$x.name], ['fullName'])}, simpleRelationalMapping, ^Runtime(connectionStores=^ConnectionStore(element = meta::relational::tests::db,connection=meta::pure::executionPlan::tests::snowflake::relationalConnectionForSnowflake(true))), meta::relational::extension::relationalExtensions());
let execNodesInRelBlockNode = $generatedPlan.rootExecutionNode.executionNodes;

let createAndPopulateTempTableNode = $execNodesInRelBlockNode->filter(e|$e->instanceOf(CreateAndPopulateTempTableExecutionNode));

let tempTableName = $createAndPopulateTempTableNode->at(0)->cast(@CreateAndPopulateTempTableExecutionNode).tempTableName;
assertEquals('LEGEND_TEMP_DB.LEGEND_TEMP_SCHEMA.tempTableForIn_8', $tempTableName);
let inputVarNames = $createAndPopulateTempTableNode->at(0)->cast(@CreateAndPopulateTempTableExecutionNode).inputVarNames;
assertEquals('tempVarForIn_8', $inputVarNames->at(0));

let allocationNode = $execNodesInRelBlockNode->filter(e|$e->instanceOf(AllocationExecutionNode));
let varName = $allocationNode->at(0)->cast(@AllocationExecutionNode).varName;
assertEquals('tempVarForIn_8', $varName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ function <<access.private>> meta::relational::postProcessor::prefixForWrapperAll
'inFilterClause_';
}

function <<access.private>> meta::relational::postProcessor::processedTempTableNameForIn(dbType: DatabaseType[1]):String[1]
{
$dbType->createDbConfig([]).procesTempTableName('tempTableForIn_');
}

function meta::relational::postProcessor::processInOperation(query:SQLQuery[1], runtime:Runtime[1], store:Database[0..1], exeCtx:ExecutionContext[1], extensions:Extension[*]):PostProcessorResult[1]
{
let connection = $runtime->connectionByElement($store->toOne())->meta::relational::mapping::updateConnection($extensions)->cast(@DatabaseConnection);
Expand All @@ -68,12 +73,12 @@ function meta::relational::postProcessor::processInOperation(query:SQLQuery[1],
d : DynaFunction[1] | if($d.name == 'in' && $d.parameters->at(1)->instanceOf(LiteralList) && ($d.parameters->at(1)->cast(@LiteralList).values->size() > $dbThreshold->toOne()),
|
let dbType = $connection.type;
let tempTableName = 'tempTableForIn_' + $uniqueId->toString();
let tempTableName = $dbType->processedTempTableNameForIn() + $uniqueId->toString();
let tempTableColumnName = 'ColumnForStoringInCollection';

let firstLiteralValue = $d.parameters->at(1)->cast(@LiteralList).values->map(l | $l.value)->at(0);
let collectionValueType = if($firstLiteralValue->instanceOf(VarPlaceHolder), | $firstLiteralValue->cast(@VarPlaceHolder).type, | $firstLiteralValue->type());
let selectSQLQuery = generateTempTableSelectSQLQuery('default', $dbType->createDbConfig([]).procesTempTableName($tempTableName), $tempTableColumnName, meta::relational::transform::fromPure::pureTypeToDataTypeMap()->get($collectionValueType)->translateCoreTypeToDbSpecificType(^TranslationContext(dbType=$dbType))->toOne());
let selectSQLQuery = generateTempTableSelectSQLQuery('default', $tempTableName, $tempTableColumnName, meta::relational::transform::fromPure::pureTypeToDataTypeMap()->get($collectionValueType)->translateCoreTypeToDbSpecificType(^TranslationContext(dbType=$dbType))->toOne());

^$d(parameters = [$d.parameters->at(0), $selectSQLQuery]);,
|$d);,
Expand Down Expand Up @@ -112,8 +117,8 @@ function meta::relational::postProcessor::generatePostProcessorResult(changedFun

let outerAllocationNodeName = if($newInFunction.parameters->at(1)->instanceOf(VarPlaceHolder),
|$newInFunction.parameters->at(1)->cast(@VarPlaceHolder).name,
|$newInFunction.parameters->at(1)->cast(@SelectSQLQuery).data.alias.name->toOne()->replace('tempTableForIn_', prefixForWrapperAllocationNodeName()));
let tempTableName = $dbType->createDbConfig([]).procesTempTableName($outerAllocationNodeName->replace(prefixForWrapperAllocationNodeName(), 'tempTableForIn_'));
|$newInFunction.parameters->at(1)->cast(@SelectSQLQuery).data.alias.name->toOne()->replace($dbType->processedTempTableNameForIn(), prefixForWrapperAllocationNodeName()));
let tempTableName = $outerAllocationNodeName->replace(prefixForWrapperAllocationNodeName(), $dbType->processedTempTableNameForIn());
let tempTableColumnName = 'ColumnForStoringInCollection';
let allocationNodeName = $outerAllocationNodeName->replace(prefixForWrapperAllocationNodeName(), 'tempVarForIn_');

Expand Down

0 comments on commit 5b6d766

Please sign in to comment.