use of org.finos.legend.engine.protocol.pure.v1.model.executionPlan.result.ClassResultType in project legend-engine by finos.
the class RelationalExecutionNodeExecutor method executeLocalRelationalGraphOperation.
private void executeLocalRelationalGraphOperation(RelationalGraphFetchExecutionNode node, DoubleStrategyHashMap<Object, Object, SQLExecutionResult> parentMap, List<Method> parentKeyGetters) {
GraphExecutionState graphExecutionState = (GraphExecutionState) executionState;
List<Object> childObjects = FastList.newList();
graphExecutionState.setObjectsForNodeIndex(node.nodeIndex, childObjects);
SQLExecutionResult childResult = null;
try {
/* Get Java executor */
Class<?> executeClass = this.getExecuteClass(node);
if (Arrays.asList(executeClass.getInterfaces()).contains(IRelationalChildGraphNodeExecutor.class)) {
IRelationalChildGraphNodeExecutor executor = (IRelationalChildGraphNodeExecutor) executeClass.getConstructor().newInstance();
/* Execute relational node corresponding to the child */
childResult = (SQLExecutionResult) node.relationalNode.accept(new ExecutionNodeExecutor(profiles, executionState));
boolean nonPrimitiveNode = node.resultType instanceof ClassResultType;
boolean childrenExist = node.children != null && !node.children.isEmpty();
/* Change the second strategy to suit the primary key indices of parent PKs in the child result set*/
List<String> parentSQLKeyColumns = executor.parentSQLColumnsInResultSet(childResult.getResultColumns().stream().map(ResultColumn::getNonQuotedLabel).collect(Collectors.toList()));
List<Integer> parentPrimaryKeyIndices = FastList.newList();
for (String pkCol : parentSQLKeyColumns) {
parentPrimaryKeyIndices.add(childResult.getResultSet().findColumn(pkCol));
}
RelationalGraphFetchUtils.switchSecondKeyHashingStrategy(parentMap, parentKeyGetters, parentPrimaryKeyIndices);
String databaseConnectionString = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports().writeValueAsString(childResult.getSQLExecutionNode().connection);
if (nonPrimitiveNode) {
List<Method> primaryKeyGetters = executor.primaryKeyGetters();
int primaryKeyCount = primaryKeyGetters.size();
DoubleStrategyHashMap<Object, Object, SQLExecutionResult> currentMap = new DoubleStrategyHashMap<>(RelationalGraphFetchUtils.objectSQLResultDoubleHashStrategyWithEmptySecondStrategy(primaryKeyGetters));
String tempTableName = childrenExist ? ((RelationalTempTableGraphFetchExecutionNode) node).tempTableName : null;
RealizedRelationalResult realizedRelationalResult = childrenExist ? RealizedRelationalResult.emptyRealizedRelationalResult(((RelationalTempTableGraphFetchExecutionNode) node).columns) : null;
DatabaseConnection databaseConnection = childResult.getSQLExecutionNode().connection;
String databaseType = childResult.getDatabaseType();
String databaseTimeZone = childResult.getDatabaseTimeZone();
ResultSet childResultSet = childResult.getResultSet();
try (Scope ignored1 = GlobalTracer.get().buildSpan("Graph Query Relational: Read Child Batch").startActive(true)) {
while (childResultSet.next()) {
graphExecutionState.incrementRowCount();
Object parent = parentMap.getWithSecondKey(childResult);
if (parent == null) {
throw new RuntimeException("No parent");
}
org.finos.legend.engine.plan.dependencies.domain.graphFetch.IGraphInstance<?> childGraphInstance = executor.getObjectFromResultSet(childResultSet, childResult.getDatabaseTimeZone(), databaseConnectionString);
Object child = childGraphInstance.getValue();
Object mapObject = currentMap.putIfAbsent(child, child);
if (mapObject == null) {
mapObject = child;
graphExecutionState.addObjectMemoryUtilization(childGraphInstance.instanceSize());
childObjects.add(mapObject);
if (childrenExist) {
this.addKeyRowToRealizedRelationalResult(child, primaryKeyGetters, realizedRelationalResult);
}
}
executor.addChildToParent(parent, mapObject, DefaultExecutionNodeContext.factory().create(graphExecutionState, null));
}
}
childResult.close();
childResult = null;
if (childrenExist) {
this.executeRelationalChildren(node, tempTableName, realizedRelationalResult, databaseConnection, databaseType, databaseTimeZone, currentMap, primaryKeyGetters);
}
} else {
ResultSet childResultSet = childResult.getResultSet();
while (childResultSet.next()) {
Object parent = parentMap.getWithSecondKey(childResult);
if (parent == null) {
throw new RuntimeException("No parent");
}
org.finos.legend.engine.plan.dependencies.domain.graphFetch.IGraphInstance<?> childGraphInstance = executor.getObjectFromResultSet(childResultSet, childResult.getDatabaseTimeZone(), databaseConnectionString);
Object child = childGraphInstance.getValue();
childObjects.add(child);
graphExecutionState.addObjectMemoryUtilization(childGraphInstance.instanceSize());
executor.addChildToParent(parent, child, DefaultExecutionNodeContext.factory().create(graphExecutionState, null));
}
childResult.close();
childResult = null;
}
} else {
throw new RuntimeException("Unknown execute class " + executeClass.getCanonicalName());
}
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (childResult != null) {
childResult.close();
}
}
}
use of org.finos.legend.engine.protocol.pure.v1.model.executionPlan.result.ClassResultType in project legend-engine by finos.
the class InMemoryExecutionNodeExecutor method visit.
@Override
public Result visit(InMemoryRootGraphFetchExecutionNode node) {
int batchSize = node.batchSize == null ? 1 : node.batchSize;
boolean isLeaf = node.children == null || node.children.isEmpty();
boolean checked = node.checked;
ClassResultType classResultType = (ClassResultType) node.resultType;
String _class = classResultType._class;
Result childResult = null;
JavaPlatformImplementation javaPlatformImpl = (JavaPlatformImplementation) node.implementation;
String executionClassName = JavaHelper.getExecutionClassFullName(javaPlatformImpl);
Class<?> clazz = ExecutionNodeJavaPlatformHelper.getClassToExecute(node, executionClassName, this.executionState, this.pm);
Span graphFetchSpan = GlobalTracer.get().buildSpan("graph fetch").withTag("rootStoreType", "inMemory").withTag("batchSizeConfig", batchSize).start();
GlobalTracer.get().activateSpan(graphFetchSpan);
try {
if ((Arrays.asList(clazz.getInterfaces()).contains(IInMemoryRootGraphFetchMergeExecutionNodeSpecifics.class))) {
return mergeInMemoryNode(node);
} else {
IInMemoryRootGraphFetchExecutionNodeSpecifics nodeSpecifics = ExecutionNodeJavaPlatformHelper.getNodeSpecificsInstance(node, this.executionState, this.pm);
childResult = node.executionNodes.get(0).accept(new ExecutionNodeExecutor(this.pm, this.executionState));
Iterator<?> sourceObjectsIterator;
if (childResult instanceof StoreStreamReadingResult) {
StoreStreamReadingResult<?> storeStreamReadingResult = (StoreStreamReadingResult) childResult;
sourceObjectsIterator = storeStreamReadingResult.getObjectsIterator();
} else if (childResult instanceof StreamingObjectResult) {
StreamingObjectResult<?> streamingObjectResult = (StreamingObjectResult) childResult;
sourceObjectsIterator = streamingObjectResult.getObjectStream().iterator();
} else {
throw new IllegalStateException("Unsupported result type: " + childResult.getClass().getSimpleName());
}
AtomicLong batchIndex = new AtomicLong(0L);
Spliterator<GraphObjectsBatch> graphObjectsBatchSpliterator = new Spliterators.AbstractSpliterator<GraphObjectsBatch>(Long.MAX_VALUE, Spliterator.ORDERED) {
@Override
public boolean tryAdvance(Consumer<? super GraphObjectsBatch> action) {
long currentBatch = batchIndex.incrementAndGet();
GraphObjectsBatch inMemoryGraphObjectsBatch = new GraphObjectsBatch(currentBatch, executionState.getGraphFetchBatchMemoryLimit());
List<Object> resultObjects = new ArrayList<>();
int objectCount = 0;
if (checked) {
while (sourceObjectsIterator.hasNext()) {
IChecked<?> checkedSource = (IChecked<?>) sourceObjectsIterator.next();
Object value = checkedSource.getValue();
if (value == null) {
resultObjects.add(newDynamicChecked(Collections.singletonList(BasicDefect.newNoInputDefect(_class)), checkedSource, null));
} else {
Object targetObject = nodeSpecifics.transform(value);
if (targetObject != null) {
if (targetObject instanceof List) {
((List<?>) targetObject).forEach(x -> {
IGraphInstance<?> target = (IGraphInstance<?>) x;
inMemoryGraphObjectsBatch.addObjectMemoryUtilization(target.instanceSize());
resultObjects.add(newDynamicChecked(Collections.emptyList(), checkedSource, target.getValue()));
});
} else {
IGraphInstance<?> target = (IGraphInstance<?>) targetObject;
inMemoryGraphObjectsBatch.addObjectMemoryUtilization(target.instanceSize());
resultObjects.add(newDynamicChecked(Collections.emptyList(), checkedSource, target.getValue()));
}
}
}
objectCount += 1;
if (objectCount >= batchSize)
break;
}
} else {
while (sourceObjectsIterator.hasNext()) {
Object targetObject = nodeSpecifics.transform(sourceObjectsIterator.next());
if (targetObject != null) {
if (targetObject instanceof List) {
((List<?>) targetObject).forEach(x -> {
IGraphInstance<?> target = (IGraphInstance<?>) x;
inMemoryGraphObjectsBatch.addObjectMemoryUtilization(target.instanceSize());
resultObjects.add(target.getValue());
});
} else {
IGraphInstance<?> target = (IGraphInstance<?>) targetObject;
inMemoryGraphObjectsBatch.addObjectMemoryUtilization(target.instanceSize());
resultObjects.add(target.getValue());
}
}
objectCount += 1;
if (objectCount >= batchSize)
break;
}
}
inMemoryGraphObjectsBatch.setObjectsForNodeIndex(node.nodeIndex, resultObjects);
if (!resultObjects.isEmpty() && (!isLeaf)) {
ExecutionState newState = new ExecutionState(executionState);
newState.graphObjectsBatch = inMemoryGraphObjectsBatch;
node.children.forEach(x -> x.accept(new ExecutionNodeExecutor(InMemoryExecutionNodeExecutor.this.pm, newState)));
}
action.accept(inMemoryGraphObjectsBatch);
return objectCount != 0;
}
};
Stream<GraphObjectsBatch> graphObjectsBatchStream = StreamSupport.stream(graphObjectsBatchSpliterator, false);
return new GraphFetchResult(graphObjectsBatchStream, childResult).withGraphFetchSpan(graphFetchSpan);
}
} catch (Exception e) {
if (childResult != null) {
childResult.close();
}
if (graphFetchSpan != null) {
graphFetchSpan.finish();
}
if (e instanceof RuntimeException) {
throw e;
}
Throwable cause = e.getCause();
if (cause instanceof RuntimeException)
throw (RuntimeException) cause;
if (cause instanceof Error)
throw (Error) cause;
throw new RuntimeException(cause);
}
}
use of org.finos.legend.engine.protocol.pure.v1.model.executionPlan.result.ClassResultType in project legend-engine by finos.
the class ExecutionNodeClassResultHelper method getClassEnumTransformer.
@JsonIgnore
public static Function<Object, Object> getClassEnumTransformer(ExecutionNode executionNode, String setImplementId, String name) {
ClassResultType classResultType = (ClassResultType) executionNode.resultType;
Map<String, List<String>> enumMapping = ListIterate.select(ListIterate.select(classResultType.setImplementations, s -> s.id.equals(setImplementId)).getFirst().propertyMappings, p -> p.property.equals(name)).getFirst().enumMapping;
return ExecutionNodeResultHelper.buildReverseEnumFunc(executionNode, enumMapping);
}
Aggregations