Search in sources :

Example 1 with ClassResultType

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();
        }
    }
}
Also used : ClassResultType(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.result.ClassResultType) ExecutionNodeExecutor(org.finos.legend.engine.plan.execution.nodes.ExecutionNodeExecutor) ResultSet(java.sql.ResultSet) DatabaseConnection(org.finos.legend.engine.protocol.pure.v1.model.packageableElement.store.relational.connection.DatabaseConnection) org.finos.legend.engine.plan.dependencies.store.relational.graphFetch(org.finos.legend.engine.plan.dependencies.store.relational.graphFetch) org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.graphFetch) RealizedRelationalResult(org.finos.legend.engine.plan.execution.stores.relational.result.RealizedRelationalResult) GraphExecutionState(org.finos.legend.engine.plan.execution.nodes.state.GraphExecutionState) ResultColumn(org.finos.legend.engine.plan.execution.stores.relational.result.ResultColumn) DoubleStrategyHashMap(org.finos.legend.engine.shared.core.collectionsExtensions.DoubleStrategyHashMap) Method(java.lang.reflect.Method) InvocationTargetException(java.lang.reflect.InvocationTargetException) SQLException(java.sql.SQLException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) Scope(io.opentracing.Scope) IReferencedObject(org.finos.legend.engine.plan.dependencies.store.shared.IReferencedObject) SQLExecutionResult(org.finos.legend.engine.plan.execution.stores.relational.result.SQLExecutionResult)

Example 2 with ClassResultType

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);
    }
}
Also used : ExecutionState(org.finos.legend.engine.plan.execution.nodes.state.ExecutionState) IGraphInstance(org.finos.legend.engine.plan.dependencies.domain.graphFetch.IGraphInstance) ClassResultType(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.result.ClassResultType) ExecutionNodeExecutor(org.finos.legend.engine.plan.execution.nodes.ExecutionNodeExecutor) Span(io.opentracing.Span) GraphFetchResult(org.finos.legend.engine.plan.execution.result.graphFetch.GraphFetchResult) StoreStreamReadingResult(org.finos.legend.engine.plan.execution.stores.inMemory.result.graphFetch.StoreStreamReadingResult) StreamingObjectResult(org.finos.legend.engine.plan.execution.result.object.StreamingObjectResult) ConstantResult(org.finos.legend.engine.plan.execution.result.ConstantResult) Result(org.finos.legend.engine.plan.execution.result.Result) Consumer(java.util.function.Consumer) MutableList(org.eclipse.collections.api.list.MutableList) GraphObjectsBatch(org.finos.legend.engine.plan.execution.result.graphFetch.GraphObjectsBatch) StreamingObjectResult(org.finos.legend.engine.plan.execution.result.object.StreamingObjectResult) GraphFetchResult(org.finos.legend.engine.plan.execution.result.graphFetch.GraphFetchResult) AtomicLong(java.util.concurrent.atomic.AtomicLong) IChecked(org.finos.legend.engine.plan.dependencies.domain.dataQuality.IChecked) StoreStreamReadingResult(org.finos.legend.engine.plan.execution.stores.inMemory.result.graphFetch.StoreStreamReadingResult)

Example 3 with ClassResultType

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);
}
Also used : List(java.util.List) ClassMappingInfo(org.finos.legend.engine.plan.execution.result.builder._class.ClassMappingInfo) Function(org.eclipse.collections.api.block.function.Function) Map(java.util.Map) JsonIgnore(com.fasterxml.jackson.annotation.JsonIgnore) ExecutionNode(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.nodes.ExecutionNode) ListIterate(org.eclipse.collections.impl.utility.ListIterate) PropertyInfo(org.finos.legend.engine.plan.execution.result.builder._class.PropertyInfo) ClassResultType(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.result.ClassResultType) MutableList(org.eclipse.collections.api.list.MutableList) FastList(org.eclipse.collections.impl.list.mutable.FastList) ClassResultType(org.finos.legend.engine.protocol.pure.v1.model.executionPlan.result.ClassResultType) List(java.util.List) MutableList(org.eclipse.collections.api.list.MutableList) FastList(org.eclipse.collections.impl.list.mutable.FastList) JsonIgnore(com.fasterxml.jackson.annotation.JsonIgnore)

Aggregations

ClassResultType (org.finos.legend.engine.protocol.pure.v1.model.executionPlan.result.ClassResultType)3 MutableList (org.eclipse.collections.api.list.MutableList)2 ExecutionNodeExecutor (org.finos.legend.engine.plan.execution.nodes.ExecutionNodeExecutor)2 JsonIgnore (com.fasterxml.jackson.annotation.JsonIgnore)1 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)1 Scope (io.opentracing.Scope)1 Span (io.opentracing.Span)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Method (java.lang.reflect.Method)1 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 List (java.util.List)1 Map (java.util.Map)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1 Consumer (java.util.function.Consumer)1 Function (org.eclipse.collections.api.block.function.Function)1 FastList (org.eclipse.collections.impl.list.mutable.FastList)1 ListIterate (org.eclipse.collections.impl.utility.ListIterate)1 IChecked (org.finos.legend.engine.plan.dependencies.domain.dataQuality.IChecked)1 IGraphInstance (org.finos.legend.engine.plan.dependencies.domain.graphFetch.IGraphInstance)1