Example #1
0
 public CodegenExpression ToExpression(
     string rowFactory,
     string rowSerde,
     CodegenExpression groupKeyEval)
 {
     return NewInstance<AggregationLocalGroupByLevel>(
         NewInstance(rowFactory, Ref("this")),
         NewInstance(rowSerde, Ref("this")),
         Constant(ExprNodeUtilityQuery.GetExprResultTypes(PartitionForges)),
         groupKeyEval,
         Constant(IsDefaultLevel));
 }
Example #2
0
        private static void AnalyzeInNodeSingleIndex(
            ExprInNode inNode,
            QueryGraphForge queryGraph)
        {
            if (!(inNode.ChildNodes[0] is ExprIdentNode)) {
                return;
            }

            var testIdent = (ExprIdentNode) inNode.ChildNodes[0];
            var testIdentClass = testIdent.Forge.EvaluationType.GetBoxedType();
            var indexedStream = testIdent.StreamId;

            var setExpressions = GetInNodeSetExpressions(inNode);
            if (setExpressions.Length == 0) {
                return;
            }

            var perStreamExprs = new LinkedHashMap<int?, IList<ExprNode>>();

            foreach (var exprNodeSet in setExpressions) {
                if (exprNodeSet.Forge.EvaluationType.GetBoxedType() != testIdentClass) {
                    continue;
                }

                if (exprNodeSet is ExprIdentNode) {
                    var setIdent = (ExprIdentNode) exprNodeSet;
                    AddToList(setIdent.StreamId, setIdent, perStreamExprs);
                }
                else {
                    var eligibility = EligibilityUtil.VerifyInputStream(exprNodeSet, indexedStream);
                    if (!eligibility.Eligibility.IsEligible()) {
                        continue;
                    }

                    AddToList(eligibility.StreamNum, exprNodeSet, perStreamExprs);
                }
            }

            foreach (var entry in perStreamExprs) {
                var exprNodes = ExprNodeUtilityQuery.ToArray(entry.Value);
                if (entry.Key == null) {
                    queryGraph.AddInSetSingleIndexUnkeyed(testIdent.StreamId, testIdent, exprNodes);
                    continue;
                }

                if (entry.Key != indexedStream) {
                    queryGraph.AddInSetSingleIndex(testIdent.StreamId, testIdent, entry.Key.Value, exprNodes);
                }
            }
        }
Example #3
0
        public AggregatorAccessSortedImpl(
            bool join,
            AggregationStateSortedForge forge,
            int col,
            CodegenCtor ctor,
            CodegenMemberCol membersColumnized,
            CodegenClassScope classScope,
            ExprNode optionalFilter)
            : base(optionalFilter)

        {
            this.forge = forge;
            sorted = membersColumnized.AddMember(col, typeof(OrderedDictionary<object,object>), "sorted");
            size = membersColumnized.AddMember(col, typeof(int), "size");
            var types = ExprNodeUtilityQuery.GetExprResultTypes(forge.Spec.Criteria);
            comparator = classScope.AddOrGetDefaultFieldSharable(
                new CodegenFieldSharableComparator(
                    COMPARATORHASHABLEMULTIKEYS,
                    types,
                    forge.Spec.IsSortUsingCollator,
                    forge.Spec.SortDescending));
            ctor.Block.AssignRef(sorted, NewInstance(typeof(OrderedDictionary<object, object>), comparator));

            sortedSerde = classScope.AddOrGetDefaultFieldSharable(
                new ProxyCodegenFieldSharable {
                    ProcType = () => { return typeof(DIOSerdeTreeMapEventsMayDeque); },
                    ProcInitCtorScoped = () => {
                        var type = EventTypeUtility.ResolveTypeCodegen(
                            forge.Spec.StreamEventType,
                            EPStatementInitServicesConstants.REF);
                        return ExprDotMethodChain(EPStatementInitServicesConstants.REF)
                            .Get(EPStatementInitServicesConstants.DATAINPUTOUTPUTSERDEPROVIDER)
                            .Add(
                                "TreeMapEventsMayDeque",
                                Constant(forge.Spec.CriteriaTypes),
                                type);
                    }
                });

            if (join) {
                joinRefs = membersColumnized.AddMember(col, typeof(RefCountedSetAtomicInteger<object>), "refs");
                ctor.Block.AssignRef(joinRefs, NewInstance(typeof(RefCountedSetAtomicInteger<object>)));
                joinRefsSerde = classScope.AddOrGetDefaultFieldSharable(
                    new CodegenSharableSerdeEventTyped(REFCOUNTEDSETATOMICINTEGER, forge.Spec.StreamEventType));
            }
            else {
                joinRefs = null;
                joinRefsSerde = null;
            }
        }
 public AdvancedIndexConfigContextPartition ValidateConfigureFilterIndex(
     string indexName,
     string indexTypeName,
     ExprNode[] parameters,
     ExprValidationContext validationContext)
 {
     ValidateParameters(indexTypeName, parameters);
     try {
         return ConfigureQuadTree(indexName, ExprNodeUtilityQuery.GetEvaluatorsNoCompile(parameters), null);
     }
     catch (EPException ex) {
         throw new ExprValidationException(ex.Message, ex);
     }
 }
Example #5
0
        private AggregationForgeFactoryAccessSorted HandleCreateTable(ExprValidationContext validationContext)
        {
            if (positionalParams.Length == 0) {
                throw new ExprValidationException("Missing the sort criteria expression");
            }

            var message = "For tables columns, the aggregation function requires the 'sorted(*)' declaration";
            if (!sortedwin && !ever) {
                throw new ExprValidationException(message);
            }

            if (validationContext.StreamTypeService.StreamNames.Length == 0) {
                throw new ExprValidationException("'Sorted' requires that the event type is provided");
            }

            var containedType = validationContext.StreamTypeService.EventTypes[0];
            var componentType = containedType.UnderlyingType;
            var criteriaExpressions = CriteriaExpressions;
            var accessorResultType = componentType;
            AggregationAccessorForge accessor;
            if (!sortedwin) {
                accessor = new AggregationAccessorMinMaxByNonTable(IsMax);
            }
            else {
                accessor = new AggregationAccessorSortedNonTable(IsMax, componentType);
                accessorResultType = TypeHelper.GetArrayType(accessorResultType);
            }

            var criteriaTypes = ExprNodeUtilityQuery.GetExprResultTypes(criteriaExpressions.First);
            var stateDesc = new SortedAggregationStateDesc(
                IsMax,
                validationContext.ImportService,
                criteriaExpressions.First,
                criteriaTypes,
                criteriaExpressions.Second,
                ever,
                0,
                this,
                null,
                containedType);
            return new AggregationForgeFactoryAccessSorted(
                this,
                accessor,
                accessorResultType,
                containedType,
                null,
                stateDesc,
                null);
        }
 public CodegenExpression ToExpression(
     string rowFactory,
     string rowSerde,
     CodegenExpression groupKeyEval,
     CodegenMethod method,
     CodegenClassScope classScope)
 {
     return NewInstance<AggregationLocalGroupByLevel>(
         NewInstanceInner(rowFactory, Ref("this")),
         NewInstanceInner(rowSerde, Ref("this")),
         Constant(ExprNodeUtilityQuery.GetExprResultTypes(PartitionForges)),
         groupKeyEval,
         Constant(IsDefaultLevel),
         PartitionMKClasses.GetExprMKSerde(method, classScope));
 }
Example #7
0
        protected void ValidateGroupKeys(
            TableMetaData metadata,
            ExprValidationContext validationContext)
        {
            if (ChildNodes.Length > 0) {
                groupKeyEvaluators = ExprNodeUtilityQuery.GetForges(ChildNodes);
            }
            else {
                groupKeyEvaluators = new ExprForge[0];
            }

            var typesReturned = ExprNodeUtilityQuery.GetExprResultTypes(ChildNodes);
            var keyTypes = metadata.IsKeyed ? metadata.KeyTypes : new Type[0];
            ExprTableNodeUtil.ValidateExpressions(TableName, typesReturned, "key", ChildNodes, keyTypes, "key");
        }
Example #8
0
        public static void Assign(
            ExprNode[] criteriaExpressions,
            MultiKeyClassRef multiKeyClassNames,
            CodegenMethod method,
            CodegenExpressionRef factory,
            SAIFFInitializeSymbol symbols,
            CodegenClassScope classScope)
        {
            CodegenExpression criteriaEval = MultiKeyCodegen.CodegenExprEvaluatorMayMultikey(criteriaExpressions, null, multiKeyClassNames, method, classScope);

            method.Block
            .SetProperty(factory, "CriteriaEval", criteriaEval)
            .SetProperty(factory, "CriteriaTypes", Constant(ExprNodeUtilityQuery.GetExprResultTypes(criteriaExpressions)))
            .SetProperty(factory, "KeySerde", multiKeyClassNames.GetExprMKSerde(method, classScope));
        }
        public override IList<StmtClassForgeableFactory> Validate(
            StreamTypeService typeService,
            StatementBaseInfo @base,
            StatementCompileTimeServices services)
        {
            int count = 0;
            ExprValidationContext validationContext =
                new ExprValidationContextBuilder(typeService, @base.StatementRawInfo, services)
                    .WithAllowBindingConsumption(true)
                    .Build();
            ExprNode[] inputParamNodes = new ExprNode[inputParameters.Length];
            foreach (string inputParam in inputParameters) {
                ExprNode raw = FindSQLExpressionNode(StreamNum, count, @base.StatementSpec.Raw.SqlParameters);
                if (raw == null) {
                    throw new ExprValidationException(
                        "Internal error find expression for historical stream parameter " +
                        count +
                        " stream " +
                        StreamNum);
                }

                ExprNode evaluator = ExprNodeUtilityValidate.GetValidatedSubtree(
                    ExprNodeOrigin.DATABASEPOLL,
                    raw,
                    validationContext);
                inputParamNodes[count++] = evaluator;

                ExprNodeIdentifierCollectVisitor visitor = new ExprNodeIdentifierCollectVisitor();
                visitor.Visit(evaluator);
                foreach (ExprIdentNode identNode in visitor.ExprProperties) {
                    if (identNode.StreamId == StreamNum) {
                        throw new ExprValidationException(
                            "Invalid expression '" + inputParam + "' resolves to the historical data itself");
                    }

                    SubordinateStreams.Add(identNode.StreamId);
                }
            }

            InputParamEvaluators = ExprNodeUtilityQuery.GetForges(inputParamNodes);
            
            
            // plan multikey
            MultiKeyPlan multiKeyPlan = MultiKeyPlanner.PlanMultiKey(InputParamEvaluators, false, @base.StatementRawInfo, services.SerdeResolver);
            MultiKeyClassRef = multiKeyPlan.ClassRef;

            return multiKeyPlan.MultiKeyForgeables;
        }
 public CodegenExpression Make(
     CodegenMethodScope parentInitMethod,
     CodegenClassScope classScope)
 {
     var method = parentInitMethod.MakeChild(typeof(ScriptDescriptorRuntime), GetType(), classScope)
         .AddParam(
             typeof(EPStatementInitServices),
             EPStatementInitServicesConstants.REF.Ref);
     method.Block
         .DeclareVar<ScriptDescriptorRuntime>("sd", NewInstance(typeof(ScriptDescriptorRuntime)))
         .SetProperty(Ref("sd"), "OptionalDialect", Constant(OptionalDialect))
         .SetProperty(Ref("sd"), "ScriptName", Constant(ScriptName))
         .SetProperty(Ref("sd"), "Expression", Constant(Expression))
         .SetProperty(Ref("sd"), "ParameterNames", Constant(ParameterNames))
         .SetProperty(
             Ref("sd"),
             "EvaluationTypes",
             Constant(ExprNodeUtilityQuery.GetExprResultTypes(Parameters)))
         .SetProperty(
             Ref("sd"),
             "Parameters",
             ExprNodeUtilityCodegen.CodegenEvaluators(Parameters, method, GetType(), classScope))
         .SetProperty(Ref("sd"), "DefaultDialect", Constant(_defaultDialect))
         .SetProperty(
             Ref("sd"),
             "ImportService",
             ExprDotName(
                     EPStatementInitServicesConstants.REF,
                     EPStatementInitServicesConstants.IMPORTSERVICERUNTIME))
         .SetProperty(
             Ref("sd"),
             "ScriptCompiler",
             ExprDotName(
                 EPStatementInitServicesConstants.REF,
                 EPStatementInitServicesConstants.SCRIPTCOMPILER))
         .SetProperty(
             Ref("sd"),
             "Coercer",
             ReturnType.IsNumeric()
                 ? StaticMethod(
                     typeof(SimpleNumberCoercerFactory),
                     "GetCoercer",
                     Constant(typeof(object)),
                     Constant(ReturnType.GetBoxedType()))
                 : ConstantNull())
         .MethodReturn(Ref("sd"));
     return LocalMethod(method, EPStatementInitServicesConstants.REF);
 }
Example #11
0
        public CodegenExpression Make(
            CodegenMethodScope parent,
            SAIFFInitializeSymbol symbols,
            CodegenClassScope classScope)
        {
            var method = parent.MakeChild(TypeOfPlanFactory(), GetType(), classScope);
            IList<CodegenExpression> @params = new List<CodegenExpression>(6);
            @params.Add(Constant(lookupStream));
            @params.Add(Constant(indexedStream));
            @params.Add(
                CodegenMakeableUtil.MakeArray(
                    "reqIdxKeys",
                    typeof(TableLookupIndexReqKey),
                    IndexNum,
                    GetType(),
                    method,
                    symbols,
                    classScope));
            @params.AddAll(AdditionalParams(method, symbols, classScope));
            method.Block
                .DeclareVar(TypeOfPlanFactory(), "plan", NewInstance(TypeOfPlanFactory(), @params.ToArray()));

            // inject additional information for virtual data windows
            if (indexedStreamIsVDW) {
                var keyDesc = KeyDescriptor;
                var hashes = keyDesc.HashExpressions;
                var ranges = keyDesc.Ranges.ToArray();
                var rangeResults = QueryGraphValueEntryRangeForge.GetRangeResultTypes(ranges);
                method.Block
                    .SetProperty(
                        Ref("plan"),
                        "VirtualDWHashEvals",
                        ExprNodeUtilityCodegen.CodegenEvaluators(hashes, method, GetType(), classScope))
                    .SetProperty(
                        Ref("plan"),
                        "VirtualDWHashTypes",
                        Constant(ExprNodeUtilityQuery.GetExprResultTypes(hashes)))
                    .SetProperty(
                        Ref("plan"),
                        "VirtualDWRangeEvals",
                        QueryGraphValueEntryRangeForge.MakeArray(ranges, method, symbols, classScope))
                    .SetProperty(Ref("plan"), "VirtualDWRangeTypes", Constant(rangeResults));
            }

            method.Block.MethodReturn(Ref("plan"));
            return LocalMethod(method);
        }
        public void ProviderCodegen(
            CodegenMethod method,
            CodegenClassScope classScope,
            AggregationClassNames classNames)
        {
            var groupByTypes = ExprNodeUtilityQuery.GetExprResultTypes(aggGroupByDesc.GroupByNodes);

            if (aggGroupByDesc.IsReclaimAged) {
                reclaimAge = aggGroupByDesc.ReclaimEvaluationFunctionMaxAge.Make(classScope);
                reclaimFreq = aggGroupByDesc.ReclaimEvaluationFunctionFrequency.Make(classScope);
            }
            else {
                reclaimAge = ConstantNull();
                reclaimFreq = ConstantNull();
            }

            var stmtFields = ResultSetProcessorCodegenNames.REF_STATEMENT_FIELDS;
            var timeAbacus = classScope.AddOrGetDefaultFieldSharable(TimeAbacusField.INSTANCE);

            method.Block
                .DeclareVar<AggregationRowFactory>(
                    "rowFactory",
                    NewInstanceInner(classNames.RowFactoryTop, Ref("this")))
                .DeclareVar<DataInputOutputSerde<AggregationRow>>(
                    "rowSerde",
                    NewInstanceInner(classNames.RowSerdeTop, Ref("this")))
                .DeclareVar<AggregationServiceFactory>(
                    "svcFactory",
                    NewInstanceInner(classNames.ServiceFactory, Ref("this")))
                .DeclareVar<DataInputOutputSerde>(
                    "serde", aggGroupByDesc.GroupByMultiKey.GetExprMKSerde(method, classScope))
                .MethodReturn(
                    ExprDotMethodChain(EPStatementInitServicesConstants.REF)
                        .Get(EPStatementInitServicesConstants.AGGREGATIONSERVICEFACTORYSERVICE)
                        .Add(
                            "GroupBy",
                            Ref("svcFactory"),
                            Ref("rowFactory"),
                            aggGroupByDesc.RowStateForgeDescs.UseFlags.ToExpression(),
                            Ref("rowSerde"),
                            Constant(groupByTypes),
                            reclaimAge,
                            reclaimFreq,
                            timeAbacus,
                            Ref("serde")));
        }
Example #13
0
        public CodegenExpression MakeCodegen(
            CodegenMethodScope parent,
            SAIFFInitializeSymbol symbols,
            CodegenClassScope classScope)
        {
            if (scheduleCallbackId == -1) {
                throw new IllegalStateException("Unassigned schedule callback id");
            }

            var method = parent.MakeChild(
                typeof(TimerAtObserverFactory),
                typeof(TimerIntervalObserverForge),
                classScope);

            CodegenExpression parametersExpr;
            CodegenExpression optionalConvertorExpr;
            CodegenExpression specExpr;
            if (spec != null) { // handle all-constant specification
                parametersExpr = ConstantNull();
                optionalConvertorExpr = ConstantNull();
                specExpr = spec.Make(method, classScope);
            }
            else {
                specExpr = ConstantNull();
                optionalConvertorExpr = convertor.MakeAnonymous(method, classScope);
                parametersExpr = ExprNodeUtilityCodegen.CodegenEvaluators(
                    ExprNodeUtilityQuery.ToArray(parameters),
                    method,
                    GetType(),
                    classScope);
            }

            method.Block
                .DeclareVar<TimerAtObserverFactory>(
                    "factory",
                    ExprDotMethodChain(symbols.GetAddInitSvc(method))
                        .Get(EPStatementInitServicesConstants.PATTERNFACTORYSERVICE)
                        .Add("ObserverTimerAt"))
                .SetProperty(Ref("factory"), "ScheduleCallbackId", Constant(scheduleCallbackId))
                .SetProperty(Ref("factory"), "Parameters", parametersExpr)
                .SetProperty(Ref("factory"), "OptionalConvertor", optionalConvertorExpr)
                .SetProperty(Ref("factory"), "Spec", specExpr)
                .MethodReturn(Ref("factory"));
            return LocalMethod(method);
        }
        private static CodegenFieldSharable GetComparator(
            OrderByElementForge[] orderBy,
            bool isSortUsingCollator)
        {
            var nodes = new ExprNode[orderBy.Length];
            var descending = new bool[orderBy.Length];
            for (var i = 0; i < orderBy.Length; i++) {
                nodes[i] = orderBy[i].ExprNode;
                descending[i] = orderBy[i].IsDescending();
            }

            var types = ExprNodeUtilityQuery.GetExprResultTypes(nodes);
            return new CodegenFieldSharableComparator(
                COMPARATORHASHABLEMULTIKEYS,
                types,
                isSortUsingCollator,
                descending);
        }
Example #15
0
        public static InstanceManufacturerFactory GetManufacturer(
            Type targetClass,
            ImportServiceCompileTime importService,
            ExprNode[] childNodes)
        {
            var forgesUnmodified = ExprNodeUtilityQuery.GetForges(childNodes);
            var returnTypes = new object[forgesUnmodified.Length];
            for (var i = 0; i < forgesUnmodified.Length; i++) {
                returnTypes[i] = forgesUnmodified[i].EvaluationType;
            }

            var ctor = InstanceManufacturerUtil.GetManufacturer(
                targetClass,
                importService,
                forgesUnmodified,
                returnTypes);
            return new InstanceManufacturerFactoryFastCtor(targetClass, ctor.First, ctor.Second);
        }
Example #16
0
        public override void Attach(
            EventType parentEventType,
            int streamNumber,
            ViewForgeEnv viewForgeEnv)
        {
            eventType = parentEventType;
            var message =
                NAME + " window requires a numeric size parameter and a list of expressions providing sort keys";
            if (viewParameters.Count < 2) {
                throw new ViewParameterException(message);
            }

            var validated = ViewForgeSupport.Validate(
                NAME + " window",
                parentEventType,
                viewParameters,
                true,
                viewForgeEnv,
                streamNumber);
            for (var i = 1; i < validated.Length; i++) {
                ViewForgeSupport.AssertReturnsNonConstant(NAME + " window", validated[i], i);
            }

            ViewForgeSupport.ValidateNoProperties(ViewName, validated[0], 0);
            sizeForge = ViewForgeSupport.ValidateSizeParam(ViewName, validated[0], 0);

            sortCriteriaExpressions = new ExprNode[validated.Length - 1];
            isDescendingValues = new bool[sortCriteriaExpressions.Length];

            for (var i = 1; i < validated.Length; i++) {
                if (validated[i] is ExprOrderedExpr) {
                    isDescendingValues[i - 1] = ((ExprOrderedExpr) validated[i]).IsDescending;
                    sortCriteriaExpressions[i - 1] = validated[i].ChildNodes[0];
                }
                else {
                    sortCriteriaExpressions[i - 1] = validated[i];
                }
            }

            sortSerdes = viewForgeEnv.SerdeResolver.SerdeForDataWindowSortCriteria(
                ExprNodeUtilityQuery.GetExprResultTypes(sortCriteriaExpressions),
                viewForgeEnv.StatementRawInfo);
        }
Example #17
0
        public static ISet<string> GetUniqueCandidateProperties(
            IList<ViewFactoryForge> forges,
            Attribute[] annotations)
        {
            var disableUniqueImplicit = HintEnum.DISABLE_UNIQUE_IMPLICIT_IDX.GetHint(annotations) != null;
            if (forges == null || forges.IsEmpty()) {
                return null;
            }

            if (forges[0] is GroupByViewFactoryForge) {
                var grouped = (GroupByViewFactoryForge) forges[0];
                var criteria = grouped.CriteriaExpressions;
                var groupedCriteria = ExprNodeUtilityQuery.GetPropertyNamesIfAllProps(criteria);
                if (groupedCriteria == null) {
                    return null;
                }

                var inner = grouped.Groupeds[0];
                if (inner is DataWindowViewForgeUniqueCandidate && !disableUniqueImplicit) {
                    var uniqueFactory = (DataWindowViewForgeUniqueCandidate) inner;
                    var uniqueCandidates = uniqueFactory.UniquenessCandidatePropertyNames;
                    if (uniqueCandidates != null) {
                        uniqueCandidates.AddAll(groupedCriteria);
                    }

                    return uniqueCandidates;
                }

                return null;
            }

            if (forges[0] is DataWindowViewForgeUniqueCandidate && !disableUniqueImplicit) {
                var uniqueFactory = (DataWindowViewForgeUniqueCandidate) forges[0];
                return uniqueFactory.UniquenessCandidatePropertyNames;
            }

            if (forges[0] is VirtualDWViewFactoryForge) {
                var vdw = (VirtualDWViewFactoryForge) forges[0];
                return vdw.UniqueKeys;
            }

            return null;
        }
Example #18
0
        public static CodegenExpression CodegenExprEvaluatorMayMultikey(
            ExprNode[] expressionNodes,
            Type[] optionalCoercionTypes,
            MultiKeyClassRef multiKeyClassRef,
            CodegenMethod method,
            CodegenClassScope classScope)
        {
            if (expressionNodes == null || expressionNodes.Length == 0)
            {
                return(ConstantNull());
            }

            return(CodegenExprEvaluatorMayMultikey(
                       ExprNodeUtilityQuery.GetForges(expressionNodes),
                       optionalCoercionTypes,
                       multiKeyClassRef,
                       method,
                       classScope));
        }
Example #19
0
        public override EventBean[] GetEventsPerStreamRewritten(
            EventBean[] eps,
            bool isNewData,
            ExprEvaluatorContext context)
        {
            if (_evaluators == null) {
                _evaluators = ExprNodeUtilityQuery.GetEvaluatorsNoCompile(_valueExpressions);
            }

            var props = new object[_valueEventType.PropertyNames.Length];
            for (var i = 0; i < _evaluators.Length; i++) {
                props[i] = _evaluators[i].Evaluate(eps, isNewData, context);
            }

            var events = new EventBean[_eventEnumerationForges.Length];
            for (var i = 0; i < _eventEnumerationForges.Length; i++) {
                events[i] = _eventEnumerationForges[i].ExprEvaluatorEnumeration.EvaluateGetEventBean(eps, isNewData, context);
            }

            return events;
        }
Example #20
0
        internal override void Assign(
            CodegenMethod method,
            CodegenExpressionRef factory,
            SAIFFInitializeSymbol symbols,
            CodegenClassScope classScope)
        {
            method.Block
                .SetProperty(factory, "SizeEvaluator", CodegenEvaluator(sizeForge, method, GetType(), classScope))
                .SetProperty(
                    factory,
                    "SortCriteriaEvaluators",
                    CodegenEvaluators(sortCriteriaExpressions, method, GetType(), classScope))
                .SetProperty(
                    factory,
                    "SortCriteriaTypes",
                    Constant(ExprNodeUtilityQuery.GetExprResultTypes(sortCriteriaExpressions)))
                .SetProperty(factory, "IsDescendingValues", Constant(isDescendingValues))
                .SetProperty(factory, "IsUseCollatorSort", Constant(useCollatorSort))
                .SetProperty(factory, "SortSerdes", DataInputOutputSerdeForgeExtensions.CodegenArray(sortSerdes, method, classScope, null));

        }
        private void ValidateIndexNamedParameter(ExprValidationContext validationContext)
        {
            if (indexNamedParameter.Length != 1 || !(indexNamedParameter[0] is ExprDeclaredNode)) {
                throw GetIndexNameMessage("requires an expression name");
            }

            var node = (ExprDeclaredNode) indexNamedParameter[0];
            if (!(node.Body is ExprDotNode)) {
                throw GetIndexNameMessage("requires an index expression");
            }

            var dotNode = (ExprDotNode) node.Body;
            if (dotNode.ChainSpec.Count > 1) {
                throw GetIndexNameMessage("invalid chained index expression");
            }

            IList<ExprNode> @params = dotNode.ChainSpec[0].GetParametersOrEmpty();
            string indexTypeName = dotNode.ChainSpec[0].GetRootNameOrEmptyString();
            optionalIndexName = node.Prototype.Name;

            AdvancedIndexFactoryProvider provider = null;
            try {
                provider = validationContext.ImportService.ResolveAdvancedIndexProvider(indexTypeName);
            }
            catch (ImportException e) {
                throw new ExprValidationException(e.Message, e);
            }

            if (!indexTypeName.ToLowerInvariant().Equals(IndexTypeName)) {
                throw new ExprValidationException(
                    "Invalid index type '" + indexTypeName + "', expected '" + IndexTypeName + "'");
            }

            optionalIndexConfig = provider.ValidateConfigureFilterIndex(
                optionalIndexName,
                indexTypeName,
                ExprNodeUtilityQuery.ToArray(@params),
                validationContext);
        }
 public ResultSetProcessorRowPerGroupRollupForge(
     EventType resultEventType,
     GroupByRollupPerLevelForge perLevelForges,
     ExprNode[] groupKeyNodeExpressions,
     bool isSelectRStream,
     bool isUnidirectional,
     OutputLimitSpec outputLimitSpec,
     bool isSorting,
     bool noDataWindowSingleStream,
     AggregationGroupByRollupDescForge groupByRollupDesc,
     bool isJoin,
     bool isHistoricalOnly,
     bool iterateUnbounded,
     ResultSetProcessorOutputConditionType? outputConditionType,
     OutputConditionPolledFactoryForge optionalOutputFirstConditionFactory,
     EventType[] eventTypes,
     MultiKeyClassRef multiKeyClassRef)
 {
     ResultEventType = resultEventType;
     GroupKeyNodeExpressions = groupKeyNodeExpressions;
     PerLevelForges = perLevelForges;
     IsSorting = isSorting;
     IsSelectRStream = isSelectRStream;
     IsUnidirectional = isUnidirectional;
     OutputLimitSpec = outputLimitSpec;
     var noDataWindowSingleSnapshot = iterateUnbounded ||
                                      outputLimitSpec != null &&
                                      outputLimitSpec.DisplayLimit == OutputLimitLimitType.SNAPSHOT &&
                                      noDataWindowSingleStream;
     unbounded = noDataWindowSingleSnapshot && !isHistoricalOnly;
     GroupByRollupDesc = groupByRollupDesc;
     IsJoin = isJoin;
     IsHistoricalOnly = isHistoricalOnly;
     OutputConditionType = outputConditionType;
     OptionalOutputFirstConditionFactory = optionalOutputFirstConditionFactory;
     EventTypes = eventTypes;
     GroupKeyTypes = ExprNodeUtilityQuery.GetExprResultTypes(groupKeyNodeExpressions);
     MultiKeyClassRef = multiKeyClassRef;
 }
Example #23
0
 public override void Accept(ExprNodeVisitorWithParent visitor)
 {
     base.Accept(visitor);
     ExprNodeUtilityQuery.AcceptParams(visitor, Parameters);
 }
        public override IList<StmtClassForgeableFactory> Validate(
            StreamTypeService typeService,
            StatementBaseInfo @base,
            StatementCompileTimeServices services)
        {
            // validate and visit
            var validationContext = new ExprValidationContextBuilder(typeService, @base.StatementRawInfo, services)
                .WithAllowBindingConsumption(true)
                .Build();

            var visitor = new ExprNodeIdentifierAndStreamRefVisitor(true);
            var validatedInputParameters = new List<ExprNode>();

            foreach (var exprNode in methodStreamSpec.Expressions) {
                var validated = ExprNodeUtilityValidate.GetValidatedSubtree(
                    ExprNodeOrigin.METHODINVJOIN,
                    exprNode,
                    validationContext);
                validatedInputParameters.Add(validated);
                validated.Accept(visitor);
            }

            // determine required streams
            foreach (ExprNodePropOrStreamDesc @ref in visitor.Refs) {
                SubordinateStreams.Add(@ref.StreamNum);
            }

            // class-based evaluation
            MethodInfo targetMethod = null;
            if (metadata.MethodProviderClass != null) {
                // resolve actual method to use
                ExprNodeUtilResolveExceptionHandler handler = new ProxyExprNodeUtilResolveExceptionHandler {
                    ProcHandle = e => {
                        if (methodStreamSpec.Expressions.Count == 0) {
                            return new ExprValidationException(
                                "Method footprint does not match the number or type of expression parameters, expecting no parameters in method: " +
                                e.Message);
                        }

                        var resultTypes = ExprNodeUtilityQuery.GetExprResultTypes(validatedInputParameters);
                        return new ExprValidationException(
                            "Method footprint does not match the number or type of expression parameters, expecting a method where parameters are typed '" +
                            TypeHelper.GetParameterAsString(resultTypes) +
                            "': " +
                            e.Message);
                    }
                };
                var desc = ExprNodeUtilityResolve.ResolveMethodAllowWildcardAndStream(
                    metadata.MethodProviderClass.FullName,
                    metadata.IsStaticMethod ? null : metadata.MethodProviderClass,
                    methodStreamSpec.MethodName,
                    validatedInputParameters,
                    false,
                    null,
                    handler,
                    methodStreamSpec.MethodName,
                    @base.StatementRawInfo,
                    services);
                InputParamEvaluators = desc.ChildForges;
                targetMethod = desc.ReflectionMethod;
            }
            else {
                // script-based evaluation
                InputParamEvaluators = ExprNodeUtilityQuery.GetForges(ExprNodeUtilityQuery.ToArray(validatedInputParameters));
            }
            
            // plan multikey
            MultiKeyPlan multiKeyPlan = MultiKeyPlanner.PlanMultiKey(InputParamEvaluators, false, @base.StatementRawInfo, services.SerdeResolver);
            MultiKeyClassRef = multiKeyPlan.ClassRef;

            Pair<MethodTargetStrategyForge, MethodConversionStrategyForge> strategies =
                PollExecStrategyPlanner.Plan(metadata, targetMethod, EventType);
            target = strategies.First;
            conversion = strategies.Second;
            
            return multiKeyPlan.MultiKeyForgeables;
        }
Example #25
0
        public override ExprNode Validate(ExprValidationContext validationContext)
        {
            if (Script.ParameterNames.Length != Parameters.Count) {
                throw new ExprValidationException(
                    string.Format(
                        "Invalid number of parameters for script '{0}', expected {1} parameters but received {2} parameters",
                        Script.Name,
                        Script.ParameterNames.Length,
                        Parameters.Count));
            }

            if (!validationContext.StatementCompileTimeService.Configuration.Compiler.Scripts.IsEnabled) {
                throw new ExprValidationException("Script compilation has been disabled by configuration");
            }

            // validate all expression parameters
            var validatedParameters = Parameters
                .Select(
                    expr => ExprNodeUtilityValidate.GetValidatedSubtree(
                        ExprNodeOrigin.SCRIPTPARAMS,
                        expr,
                        validationContext))
                .ToList();

            // set up map of input parameter names and evaluators
            var forges = new ExprForge[Script.ParameterNames.Length];
            for (var i = 0; i < Script.ParameterNames.Length; i++) {
                forges[i] = validatedParameters[i].Forge;
            }

            Parameters = validatedParameters;

            // Compile script
            var parameterTypes = ExprNodeUtilityQuery.GetExprResultTypes(forges);
            var dialect = Script.OptionalDialect ?? _defaultDialect;
            var compiled = CompileScript(
                dialect,
                Script.Name,
                Script.Expression,
                Script.ParameterNames,
                parameterTypes,
                Script.CompiledBuf,
                validationContext.ImportService,
                validationContext.ScriptCompiler);

            // Determine declared return type
            var declaredReturnType = GetDeclaredReturnType(Script.OptionalReturnTypeName, validationContext);
            if (Script.IsOptionalReturnTypeIsArray && declaredReturnType != null) {
                declaredReturnType = TypeHelper.GetArrayType(declaredReturnType);
            }

            Type returnType;
            if (compiled.KnownReturnType == null && Script.OptionalReturnTypeName == null) {
                returnType = typeof(object);
            }
            else if (compiled.KnownReturnType != null) {
                if (declaredReturnType == null) {
                    returnType = compiled.KnownReturnType;
                }
                else {
                    var knownReturnType = compiled.KnownReturnType;
                    if (declaredReturnType.IsArray && knownReturnType.IsArray) {
                        // we are fine
                    }
                    else if (!knownReturnType.IsAssignmentCompatible(declaredReturnType)) {
                        throw new ExprValidationException(
                            "Return type and declared type not compatible for script '" +
                            Script.Name +
                            "', known return type is " +
                            knownReturnType.Name +
                            " versus declared return type " +
                            declaredReturnType.Name);
                    }

                    returnType = declaredReturnType;
                }
            }
            else {
                returnType = declaredReturnType;
            }

            if (returnType == null) {
                returnType = typeof(object);
            }

            _eventTypeCollection = null;
            if (Script.OptionalEventTypeName != null) {
                if (returnType.IsArray && returnType.GetElementType() == typeof(EventBean)) {
                    _eventTypeCollection = EventTypeUtility.RequireEventType(
                        "Script",
                        Script.Name,
                        Script.OptionalEventTypeName,
                        validationContext.StatementCompileTimeService.EventTypeCompileTimeResolver);
                }
                else {
                    throw new ExprValidationException(EventTypeUtility.DisallowedAtTypeMessage());
                }
            }

            _scriptDescriptor = new ScriptDescriptorCompileTime(
                Script.OptionalDialect,
                Script.Name,
                Script.Expression,
                Script.ParameterNames,
                Parameters.ToArray(),
                returnType,
                _defaultDialect);
            return null;
        }
Example #26
0
        // Obtain those method and state factories for each level
        private static AggregationLocalGroupByLevelForge GetLevel(
            int levelNumber,
            AggregationGroupByLocalGroupLevel level,
            ExprForge[][] methodForgesAll,
            AggregationForgeFactory[] methodFactoriesAll,
            AggregationStateFactoryForge[] accessForges,
            AggregationLocalGroupByColumnForge[] columns,
            bool defaultLevel,
            AggregationAccessorSlotPairForge[] accessors,
            ImportService importService,
            bool isFireAndForget,
            string statementName)
        {
            var partitionExpr = level.PartitionExpr;
            ExprForge[] partitionForges = ExprNodeUtilityQuery.GetForges(partitionExpr);

            IList<ExprForge[]> methodForges = new List<ExprForge[]>();
            IList<AggregationForgeFactory> methodFactories = new List<AggregationForgeFactory>();
            IList<AggregationStateFactoryForge> stateFactories = new List<AggregationStateFactoryForge>();

            foreach (var expr in level.Expressions) {
                int column = expr.AggregationNode.Column;
                var methodOffset = -1;
                var methodAgg = true;
                AggregationAccessorSlotPairForge pair = null;

                if (column < methodForgesAll.Length) {
                    methodForges.Add(methodForgesAll[column]);
                    methodFactories.Add(methodFactoriesAll[column]);
                    methodOffset = methodFactories.Count - 1;
                }
                else {
                    // slot gives us the number of the state factory
                    int absoluteSlot = accessors[column - methodForgesAll.Length].Slot;
                    AggregationAccessorForge accessor = accessors[column - methodForgesAll.Length].AccessorForge;
                    var factory = accessForges[absoluteSlot];
                    var relativeSlot = stateFactories.IndexOf(factory);
                    if (relativeSlot == -1) {
                        stateFactories.Add(factory);
                        relativeSlot = stateFactories.Count - 1;
                    }

                    methodAgg = false;
                    pair = new AggregationAccessorSlotPairForge(relativeSlot, accessor);
                }

                columns[column] = new AggregationLocalGroupByColumnForge(
                    defaultLevel,
                    partitionForges,
                    methodOffset,
                    methodAgg,
                    pair,
                    levelNumber);
            }

            return new AggregationLocalGroupByLevelForge(
                methodForges.ToArray(),
                methodFactories.ToArray(),
                stateFactories.ToArray(),
                partitionForges,
                defaultLevel);
        }
 public InstanceManufacturer MakeEvaluator()
 {
     return new InstanceManufacturerFastCtor(this, ExprNodeUtilityQuery.GetEvaluatorsNoCompile(forges));
 }
Example #28
0
 public override void Accept(ExprNodeVisitorWithParent visitor)
 {
     base.Accept(visitor);
     ExprNodeUtilityQuery.AcceptChain(visitor, ChainSpec, this);
 }
Example #29
0
        private AggregationForgeFactoryAccessSorted HandleNonTable(ExprValidationContext validationContext)
        {
            if (positionalParams.Length == 0) {
                throw new ExprValidationException("Missing the sort criteria expression");
            }

            // validate that the streams referenced in the criteria are a single stream's
            var streams = ExprNodeUtilityQuery.GetIdentStreamNumbers(positionalParams[0]);
            if (streams.Count > 1 || streams.IsEmpty()) {
                throw new ExprValidationException(
                    ErrorPrefix + " requires that any parameter expressions evaluate properties of the same stream");
            }

            var streamNum = streams.First();

            // validate that there is a remove stream, use "ever" if not
            if (!ever &&
                ExprAggMultiFunctionLinearAccessNode.GetIstreamOnly(
                    validationContext.StreamTypeService,
                    streamNum)) {
                if (sortedwin) {
                    throw new ExprValidationException(
                        ErrorPrefix + " requires that a data window is declared for the stream");
                }
            }

            // determine typing and evaluation
            containedType = validationContext.StreamTypeService.EventTypes[streamNum];

            var componentType = containedType.UnderlyingType;
            var accessorResultType = componentType;
            AggregationAccessorForge accessor;
            var tableMetadata = validationContext.TableCompileTimeResolver.ResolveTableFromEventType(containedType);
            if (!sortedwin) {
                if (tableMetadata != null) {
                    accessor = new AggregationAccessorMinMaxByTable(IsMax, tableMetadata);
                }
                else {
                    accessor = new AggregationAccessorMinMaxByNonTable(IsMax);
                }
            }
            else {
                if (tableMetadata != null) {
                    accessor = new AggregationAccessorSortedTable(IsMax, componentType, tableMetadata);
                }
                else {
                    accessor = new AggregationAccessorSortedNonTable(IsMax, componentType);
                }

                accessorResultType = TypeHelper.GetArrayType(accessorResultType);
            }

            var criteriaExpressions = CriteriaExpressions;

            AggregationStateTypeWStream type;
            if (ever) {
                type = IsMax ? AggregationStateTypeWStream.MAXEVER : AggregationStateTypeWStream.MINEVER;
            }
            else {
                type = AggregationStateTypeWStream.SORTED;
            }

            var stateKey = new AggregationStateKeyWStream(
                streamNum,
                containedType,
                type,
                criteriaExpressions.First,
                optionalFilter);

            var optionalFilterForge = optionalFilter == null ? null : optionalFilter.Forge;
            var streamEventType = validationContext.StreamTypeService.EventTypes[streamNum];
            var criteriaTypes = ExprNodeUtilityQuery.GetExprResultTypes(criteriaExpressions.First);
            var sortedDesc = new
                SortedAggregationStateDesc(
                    IsMax,
                    validationContext.ImportService,
                    criteriaExpressions.First,
                    criteriaTypes,
                    criteriaExpressions.Second,
                    ever,
                    streamNum,
                    this,
                    optionalFilterForge,
                    streamEventType);

            return new AggregationForgeFactoryAccessSorted(
                this,
                accessor,
                accessorResultType,
                containedType,
                stateKey,
                sortedDesc,
                AggregationAgentDefault.INSTANCE);
        }
Example #30
0
        public static SubordPropPlan GetJoinProps(
            ExprNode filterExpr,
            int outsideStreamCount,
            EventType[] allStreamTypesZeroIndexed,
            ExcludePlanHint excludePlanHint)
        {
            // No filter expression means full table scan
            if (filterExpr == null) {
                return new SubordPropPlan();
            }

            // analyze query graph
            var queryGraph = new QueryGraphForge(outsideStreamCount + 1, excludePlanHint, true);
            FilterExprAnalyzer.Analyze(filterExpr, queryGraph, false);

            // Build a list of streams and indexes
            var joinProps = new LinkedHashMap<string, SubordPropHashKeyForge>();
            var rangeProps = new LinkedHashMap<string, SubordPropRangeKeyForge>();
            IDictionary<QueryGraphValueEntryCustomKeyForge, QueryGraphValueEntryCustomOperationForge> customIndexOps =
                EmptyDictionary<QueryGraphValueEntryCustomKeyForge, QueryGraphValueEntryCustomOperationForge>.Instance;

            for (var stream = 0; stream < outsideStreamCount; stream++) {
                var lookupStream = stream + 1;

                var queryGraphValue = queryGraph.GetGraphValue(lookupStream, 0);
                var hashKeysAndIndexes = queryGraphValue.HashKeyProps;

                // determine application functions
                foreach (var item in queryGraphValue.Items) {
                    if (item.Entry is QueryGraphValueEntryCustomForge) {
                        if (customIndexOps.IsEmpty()) {
                            customIndexOps =
                                new Dictionary<QueryGraphValueEntryCustomKeyForge,
                                    QueryGraphValueEntryCustomOperationForge>();
                        }

                        var custom = (QueryGraphValueEntryCustomForge) item.Entry;
                        custom.MergeInto(customIndexOps);
                    }
                }

                // handle key-lookups
                var keyPropertiesJoin = hashKeysAndIndexes.Keys;
                var indexPropertiesJoin = hashKeysAndIndexes.Indexed;
                if (!keyPropertiesJoin.IsEmpty()) {
                    if (keyPropertiesJoin.Count != indexPropertiesJoin.Length) {
                        throw new IllegalStateException(
                            "Invalid query key and index property collection for stream " + stream);
                    }

                    for (var i = 0; i < keyPropertiesJoin.Count; i++) {
                        QueryGraphValueEntryHashKeyedForge keyDesc = keyPropertiesJoin[i];
                        var compareNode = keyDesc.KeyExpr;

                        var keyPropType = compareNode.Forge.EvaluationType.GetBoxedType();
                        var indexedPropType = allStreamTypesZeroIndexed[0]
                            .GetPropertyType(indexPropertiesJoin[i])
                            .GetBoxedType();
                        var coercionType = indexedPropType;
                        if (keyPropType != indexedPropType) {
                            coercionType = keyPropType.GetCompareToCoercionType(indexedPropType);
                        }

                        SubordPropHashKeyForge desc;
                        if (keyPropertiesJoin[i] is QueryGraphValueEntryHashKeyedForgeExpr) {
                            var keyExpr = (QueryGraphValueEntryHashKeyedForgeExpr) keyPropertiesJoin[i];
                            var keyStreamNum = keyExpr.IsRequiresKey ? (int?) stream : null;
                            desc = new SubordPropHashKeyForge(keyDesc, keyStreamNum, coercionType);
                        }
                        else {
                            var prop = (QueryGraphValueEntryHashKeyedForgeProp) keyDesc;
                            desc = new SubordPropHashKeyForge(prop, stream, coercionType);
                        }

                        joinProps.Put(indexPropertiesJoin[i], desc);
                    }
                }

                // handle range lookups
                var rangeKeysAndIndexes = queryGraphValue.RangeProps;
                var rangeIndexes = rangeKeysAndIndexes.Indexed;
                var rangeDescs = rangeKeysAndIndexes.Keys;
                if (rangeDescs.IsEmpty()) {
                    continue;
                }

                // get all ranges lookups
                var count = -1;
                foreach (var rangeDesc in rangeDescs) {
                    count++;
                    var rangeIndexProp = rangeIndexes[count];

                    var subqRangeDesc = rangeProps.Get(rangeIndexProp);

                    // other streams may specify the start or end endpoint of a range, therefore this operation can be additive
                    if (subqRangeDesc != null) {
                        if (subqRangeDesc.RangeInfo.Type.IsRange()) {
                            continue;
                        }

                        // see if we can make this additive by using a range
                        var relOpOther = (QueryGraphValueEntryRangeRelOpForge) subqRangeDesc.RangeInfo;
                        var relOpThis = (QueryGraphValueEntryRangeRelOpForge) rangeDesc;

                        var opsDesc = QueryGraphRangeUtil.GetCanConsolidate(relOpThis.Type, relOpOther.Type);
                        if (opsDesc != null) {
                            ExprNode start;
                            ExprNode end;
                            if (!opsDesc.IsReverse) {
                                start = relOpOther.Expression;
                                end = relOpThis.Expression;
                            }
                            else {
                                start = relOpThis.Expression;
                                end = relOpOther.Expression;
                            }

                            var allowRangeReversal = relOpOther.IsBetweenPart && relOpThis.IsBetweenPart;
                            var rangeIn = new QueryGraphValueEntryRangeInForge(
                                opsDesc.Type,
                                start,
                                end,
                                allowRangeReversal);

                            var indexedPropType = allStreamTypesZeroIndexed[0]
                                .GetPropertyType(rangeIndexProp)
                                .GetBoxedType();
                            var coercionType = indexedPropType;
                            var proposedType = CoercionUtil.GetCoercionTypeRangeIn(
                                indexedPropType,
                                rangeIn.ExprStart,
                                rangeIn.ExprEnd);
                            if (proposedType != null && proposedType != indexedPropType) {
                                coercionType = proposedType;
                            }

                            subqRangeDesc = new SubordPropRangeKeyForge(rangeIn, coercionType);
                            rangeProps.Put(rangeIndexProp, subqRangeDesc);
                        }

                        // ignore
                        continue;
                    }

                    // an existing entry has not been found
                    if (rangeDesc.Type.IsRange()) {
                        var rangeIn = (QueryGraphValueEntryRangeInForge) rangeDesc;
                        var indexedPropType =
                            allStreamTypesZeroIndexed[0].GetPropertyType(rangeIndexProp).GetBoxedType();
                        var coercionType = indexedPropType;
                        var proposedType = CoercionUtil.GetCoercionTypeRangeIn(
                            indexedPropType,
                            rangeIn.ExprStart,
                            rangeIn.ExprEnd);
                        if (proposedType != null && proposedType != indexedPropType) {
                            coercionType = proposedType;
                        }

                        subqRangeDesc = new SubordPropRangeKeyForge(rangeDesc, coercionType);
                    }
                    else {
                        var relOp = (QueryGraphValueEntryRangeRelOpForge) rangeDesc;
                        var keyPropType = relOp.Expression.Forge.EvaluationType;
                        var indexedPropType =
                            allStreamTypesZeroIndexed[0].GetPropertyType(rangeIndexProp).GetBoxedType();
                        var coercionType = indexedPropType;
                        if (keyPropType != indexedPropType) {
                            coercionType = keyPropType.GetCompareToCoercionType(indexedPropType);
                        }

                        subqRangeDesc = new SubordPropRangeKeyForge(rangeDesc, coercionType);
                    }

                    rangeProps.Put(rangeIndexProp, subqRangeDesc);
                }
            }

            SubordPropInKeywordSingleIndex inKeywordSingleIdxProp = null;
            SubordPropInKeywordMultiIndex inKeywordMultiIdxProp = null;
            if (joinProps.IsEmpty() && rangeProps.IsEmpty()) {
                for (var stream = 0; stream < outsideStreamCount; stream++) {
                    var lookupStream = stream + 1;
                    var queryGraphValue = queryGraph.GetGraphValue(lookupStream, 0);

                    var inkwSingles = queryGraphValue.InKeywordSingles;
                    if (inkwSingles.Indexed.Length != 0) {
                        ExprNode[] keys = inkwSingles.Key[0].KeyExprs;
                        var key = inkwSingles.Indexed[0];
                        if (inKeywordSingleIdxProp != null) {
                            continue;
                        }

                        var coercionType = keys[0].Forge.EvaluationType; // for in-comparison the same type is required
                        inKeywordSingleIdxProp = new SubordPropInKeywordSingleIndex(key, coercionType, keys);
                    }

                    var inkwMultis = queryGraphValue.InKeywordMulti;
                    if (!inkwMultis.IsEmpty()) {
                        QueryGraphValuePairInKWMultiIdx multi = inkwMultis[0];
                        inKeywordMultiIdxProp = new SubordPropInKeywordMultiIndex(
                            ExprNodeUtilityQuery.GetIdentResolvedPropertyNames(multi.Indexed),
                            multi.Indexed[0].Forge.EvaluationType,
                            multi.Key.KeyExpr);
                    }

                    if (inKeywordSingleIdxProp != null && inKeywordMultiIdxProp != null) {
                        inKeywordMultiIdxProp = null;
                    }
                }
            }

            return new SubordPropPlan(
                joinProps,
                rangeProps,
                inKeywordSingleIdxProp,
                inKeywordMultiIdxProp,
                customIndexOps);
        }