public static OnDemandQueryRuntime parse(OnDemandQuery onDemandQuery, String onDemandQueryString,
                                             SiddhiAppContext siddhiAppContext,
                                             Map<String, Table> tableMap, Map<String, Window> windowMap,
                                             Map<String, AggregationRuntime> aggregationMap) {

        final LockWrapper lockWrapper = new LockWrapper("OnDemandQueryLock");
        lockWrapper.setLock(new ReentrantLock());

        MetaStreamEvent metaStreamEvent = new MetaStreamEvent();

        int metaPosition = SiddhiConstants.UNKNOWN_STATE;
        String queryName;
        Table table;
        SiddhiQueryContext siddhiQueryContext;
        Expression onCondition;

        SnapshotService.getSkipStateStorageThreadLocal().set(true);

        switch (onDemandQuery.getType()) {
            case FIND:
                Within within = null;
                Expression per = null;
                queryName = "store_select_query_" + onDemandQuery.getInputStore().getStoreId();
                siddhiQueryContext = new SiddhiOnDemandQueryContext(siddhiAppContext, queryName, onDemandQueryString);
                InputStore inputStore = onDemandQuery.getInputStore();
                try {
                    onCondition = Expression.value(true);
                    metaStreamEvent.setInputReferenceId(inputStore.getStoreReferenceId());

                    if (inputStore instanceof AggregationInputStore) {
                        AggregationInputStore aggregationInputStore = (AggregationInputStore) inputStore;
                        if (aggregationMap.get(inputStore.getStoreId()) == null) {
                            throw new OnDemandQueryCreationException("Aggregation \"" + inputStore.getStoreId() +
                                    "\" has not been defined");
                        }
                        if (aggregationInputStore.getPer() != null && aggregationInputStore.getWithin() != null) {
                            within = aggregationInputStore.getWithin();
                            per = aggregationInputStore.getPer();
                        } else if (aggregationInputStore.getPer() != null ||
                                aggregationInputStore.getWithin() != null) {
                            throw new OnDemandQueryCreationException(
                                    inputStore.getStoreId() + " should either have both 'within' and 'per' " +
                                            "defined or none.");
                        }
                        if (((AggregationInputStore) inputStore).getOnCondition() != null) {
                            onCondition = ((AggregationInputStore) inputStore).getOnCondition();
                        }
                    } else if (inputStore instanceof ConditionInputStore) {
                        if (((ConditionInputStore) inputStore).getOnCondition() != null) {
                            onCondition = ((ConditionInputStore) inputStore).getOnCondition();
                        }
                    }
                    List<VariableExpressionExecutor> variableExpressionExecutors = new ArrayList<>();
                    table = tableMap.get(inputStore.getStoreId());
                    if (table != null) {
                        return constructOnDemandQueryRuntime(table, onDemandQuery, tableMap, windowMap,
                                metaPosition, onCondition, metaStreamEvent, variableExpressionExecutors, lockWrapper,
                                siddhiQueryContext);
                    } else {
                        AggregationRuntime aggregation = aggregationMap.get(inputStore.getStoreId());
                        if (aggregation != null) {
                            return constructOnDemandQueryRuntime(aggregation, onDemandQuery, tableMap,
                                    windowMap, within, per, onCondition, metaStreamEvent,
                                    variableExpressionExecutors, lockWrapper, siddhiQueryContext);
                        } else {
                            Window window = windowMap.get(inputStore.getStoreId());
                            if (window != null) {
                                return constructOnDemandQueryRuntime(window, onDemandQuery,
                                        tableMap, windowMap, metaPosition, onCondition, metaStreamEvent,
                                        variableExpressionExecutors, lockWrapper, siddhiQueryContext);
                            } else {
                                throw new OnDemandQueryCreationException(
                                        inputStore.getStoreId() + " is neither a table, aggregation or window");
                            }
                        }
                    }

                } finally {
                    SnapshotService.getSkipStateStorageThreadLocal().set(null);
                }
            case INSERT:
                InsertIntoStream inserIntoStreamt = (InsertIntoStream) onDemandQuery.getOutputStream();
                queryName = "store_insert_query_" + inserIntoStreamt.getId();
                siddhiQueryContext = new SiddhiOnDemandQueryContext(siddhiAppContext, queryName, onDemandQueryString);
                onCondition = Expression.value(true);

                return getOnDemandQueryRuntime(onDemandQuery, tableMap, windowMap, metaPosition,
                        lockWrapper, metaStreamEvent, inserIntoStreamt, onCondition, siddhiQueryContext);
            case DELETE:
                DeleteStream deleteStream = (DeleteStream) onDemandQuery.getOutputStream();
                queryName = "store_delete_query_" + deleteStream.getId();
                siddhiQueryContext = new SiddhiOnDemandQueryContext(siddhiAppContext, queryName, onDemandQueryString);
                onCondition = deleteStream.getOnDeleteExpression();

                return getOnDemandQueryRuntime(onDemandQuery, tableMap, windowMap, metaPosition,
                        lockWrapper, metaStreamEvent, deleteStream, onCondition, siddhiQueryContext);
            case UPDATE:
                UpdateStream outputStream = (UpdateStream) onDemandQuery.getOutputStream();
                queryName = "store_update_query_" + outputStream.getId();
                siddhiQueryContext = new SiddhiOnDemandQueryContext(siddhiAppContext, queryName, onDemandQueryString);
                onCondition = outputStream.getOnUpdateExpression();

                return getOnDemandQueryRuntime(onDemandQuery, tableMap, windowMap, metaPosition,
                        lockWrapper, metaStreamEvent, outputStream, onCondition, siddhiQueryContext);
            case UPDATE_OR_INSERT:
                UpdateOrInsertStream onDemandQueryOutputStream = (UpdateOrInsertStream) onDemandQuery.getOutputStream();
                queryName = "store_update_or_insert_query_" + onDemandQueryOutputStream.getId();
                siddhiQueryContext = new SiddhiOnDemandQueryContext(siddhiAppContext, queryName, onDemandQueryString);
                onCondition = onDemandQueryOutputStream.getOnUpdateExpression();

                return getOnDemandQueryRuntime(onDemandQuery, tableMap, windowMap, metaPosition,
                        lockWrapper, metaStreamEvent, onDemandQueryOutputStream, onCondition, siddhiQueryContext);
            default:
                return null;
        }
    }
Parse a onDemandQuery and return corresponding OnDemandQueryRuntime.

@param onDemandQuery       onDemandQuery to be parsed.
@param siddhiQueryContext associated Siddhi query context.
@param tableMap         keyvalue containing tables.
@param windowMap        keyvalue containing windows.
@param aggregationMap   keyvalue containing aggregation runtimes.
@return OnDemandQueryRuntime
modules/siddhi-core/src/main/java/io/siddhi/core/util/parser/OnDemandQueryParser.java