private static ExprNode[] GetInNodeSetExpressions(ExprInNode inNode) { var setExpressions = new ExprNode[inNode.ChildNodes.Length - 1]; var count = 0; for (var i = 1; i < inNode.ChildNodes.Length; i++) { setExpressions[count++] = inNode.ChildNodes[i]; } return setExpressions; }
private static void AnalyzeInNodeSingleIndex(ExprInNode inNode, QueryGraph queryGraph) { if (!(inNode.ChildNodes[0] is ExprIdentNode)) { return; } var testIdent = (ExprIdentNode)inNode.ChildNodes[0]; var testIdentClass = TypeHelper.GetBoxedType(testIdent.ExprEvaluator.ReturnType); int indexedStream = testIdent.StreamId; ExprNode[] setExpressions = GetInNodeSetExpressions(inNode); if (setExpressions.Length == 0) { return; } var perStreamExprs = new LinkedHashMap <int?, IList <ExprNode> >(); foreach (ExprNode exprNodeSet in setExpressions) { if (exprNodeSet.ExprEvaluator.ReturnType.GetBoxedType() != testIdentClass) { continue; } if (exprNodeSet is ExprIdentNode) { var setIdent = (ExprIdentNode)exprNodeSet; AddToList(setIdent.StreamId, setIdent, perStreamExprs); } else { EligibilityDesc eligibility = EligibilityUtil.VerifyInputStream(exprNodeSet, indexedStream); if (!eligibility.Eligibility.IsEligible()) { continue; } AddToList(eligibility.StreamNum, exprNodeSet, perStreamExprs); } } foreach (var entry in perStreamExprs) { ExprNode[] exprNodes = ExprNodeUtility.ToArray(entry.Value); if (entry.Key == null) { queryGraph.AddInSetSingleIndexUnkeyed(testIdent.StreamId, testIdent, exprNodes); continue; } if (entry.Key.Value != indexedStream) { queryGraph.AddInSetSingleIndex(testIdent.StreamId, testIdent, entry.Key.Value, exprNodes); } } }
private void TryInvalidValidate(ExprInNode exprInNode) { try { exprInNode.Validate(SupportExprValidationContextFactory.MakeEmpty(_container)); Assert.Fail(); } catch (ExprValidationException) { // expected } }
private static ExprNode[] GetInNodeSetExpressions(ExprInNode inNode) { var setExpressions = new ExprNode[inNode.ChildNodes.Count - 1]; var count = 0; for (int i = 1; i < inNode.ChildNodes.Count; i++) { setExpressions[count++] = inNode.ChildNodes[i]; } return(setExpressions); }
private static void AnalyzeInNode(ExprInNode inNode, QueryGraph queryGraph) { if (inNode.IsNotIn) { return; } // direction of lookup is value-set (keys) to single-expression (single index) AnalyzeInNodeSingleIndex(inNode, queryGraph); // direction of lookup is single-expression (key) to value-set (multi index) AnalyzeInNodeMultiIndex(inNode, queryGraph); }
public void TestEquals() { ExprInNode otherInNodeNormal = SupportExprNodeFactory.MakeInSetNode(false); ExprInNode otherInNodeNotIn = SupportExprNodeFactory.MakeInSetNode(true); Assert.IsTrue(_inNodeNormal.EqualsNode(otherInNodeNormal, false)); Assert.IsTrue(_inNodeNotIn.EqualsNode(otherInNodeNotIn, false)); Assert.IsFalse(_inNodeNormal.EqualsNode(otherInNodeNotIn, false)); Assert.IsFalse(_inNodeNotIn.EqualsNode(otherInNodeNormal, false)); Assert.IsFalse(_inNodeNotIn.EqualsNode(SupportExprNodeFactory.MakeCaseSyntax1Node(), false)); Assert.IsFalse(_inNodeNormal.EqualsNode(SupportExprNodeFactory.MakeCaseSyntax1Node(), false)); }
public void TestEquals() { ExprInNode otherInNode = SupportExprNodeFactory.MakeInSetNode(false); ExprVariableNode otherVarOne = new ExprVariableNodeImpl(_variableService.GetVariableMetaData("dummy"), null); ExprVariableNode otherVarTwo = new ExprVariableNodeImpl(_variableService.GetVariableMetaData("var1"), null); ExprVariableNode otherVarThree = new ExprVariableNodeImpl(_variableService.GetVariableMetaData("var1"), "abc"); Assert.IsTrue(_varNode.EqualsNode(_varNode)); Assert.IsTrue(_varNode.EqualsNode(otherVarTwo)); Assert.IsFalse(_varNode.EqualsNode(otherVarOne)); Assert.IsFalse(_varNode.EqualsNode(otherInNode)); Assert.IsFalse(otherVarTwo.EqualsNode(otherVarThree)); }
/// <summary> /// Analyzes filter expression to build query graph model. /// </summary> /// <param name="topNode">filter top node</param> /// <param name="queryGraph">model containing relationships between streams, to be written to</param> /// <param name="isOuterJoin">if set to <c>true</c> [is outer join].</param> public static void Analyze(ExprNode topNode, QueryGraph queryGraph, bool isOuterJoin) { // Analyze relationships between streams. Relationships are properties in AND and EQUALS nodes of joins. if (topNode is ExprEqualsNode) { var equalsNode = (ExprEqualsNode)topNode; if (!equalsNode.IsNotEquals) { AnalyzeEqualsNode(equalsNode, queryGraph, isOuterJoin); } } else if (topNode is ExprAndNode) { var andNode = (ExprAndNode)topNode; AnalyzeAndNode(andNode, queryGraph, isOuterJoin); } else if (topNode is ExprBetweenNode) { var betweenNode = (ExprBetweenNode)topNode; AnalyzeBetweenNode(betweenNode, queryGraph); } else if (topNode is ExprRelationalOpNode) { var relNode = (ExprRelationalOpNode)topNode; AnalyzeRelationalOpNode(relNode, queryGraph); } else if (topNode is ExprDotNode && !isOuterJoin) { var dotNode = (ExprDotNode)topNode; AnalyzeDotNode(dotNode, queryGraph); } else if (topNode is ExprInNode) { ExprInNode inNode = (ExprInNode)topNode; AnalyzeInNode(inNode, queryGraph); } else if (topNode is ExprOrNode) { ExprNode rewritten = FilterSpecCompilerMakeParamUtil.RewriteOrToInIfApplicable(topNode); if (rewritten is ExprInNode) { var inNode = (ExprInNode)rewritten; AnalyzeInNode(inNode, queryGraph); } } }
public void TestValidate() { _inNodeNormal = SupportExprNodeFactory.MakeInSetNode(true); _inNodeNormal.Validate(SupportExprValidationContextFactory.MakeEmpty(_container)); // No subnodes: Exception is thrown. TryInvalidValidate(new ExprInNodeImpl(true)); // singe child node not possible, must be 2 at least _inNodeNormal = new ExprInNodeImpl(true); _inNodeNormal.AddChildNode(new SupportExprNode(4)); TryInvalidValidate(_inNodeNormal); // test a type mismatch _inNodeNormal = new ExprInNodeImpl(true); _inNodeNormal.AddChildNode(new SupportExprNode("sx")); _inNodeNormal.AddChildNode(new SupportExprNode(4)); TryInvalidValidate(_inNodeNormal); }
private static void AnalyzeInNodeMultiIndex(ExprInNode inNode, QueryGraph queryGraph) { ExprNode[] setExpressions = GetInNodeSetExpressions(inNode); if (setExpressions.Length == 0) { return; } var perStreamExprs = new LinkedHashMap <int?, IList <ExprNode> >(); foreach (ExprNode exprNodeSet in setExpressions) { if (!(exprNodeSet is ExprIdentNode)) { continue; } var setIdent = (ExprIdentNode)exprNodeSet; AddToList(setIdent.StreamId, setIdent, perStreamExprs); } if (perStreamExprs.IsEmpty()) { return; } var testExpr = inNode.ChildNodes[0]; var testExprType = testExpr.ExprEvaluator.ReturnType.GetBoxedType(); if (perStreamExprs.Count > 1) { return; } var entry = perStreamExprs.First(); ExprNode[] exprNodes = ExprNodeUtility.ToArray(entry.Value); foreach (ExprNode node in exprNodes) { var exprType = node.ExprEvaluator.ReturnType; if (exprType.GetBoxedType() != testExprType) { return; } } int?testStreamNum; int setStream = entry.Key.Value; if (!(testExpr is ExprIdentNode)) { EligibilityDesc eligibility = EligibilityUtil.VerifyInputStream(testExpr, setStream); if (!eligibility.Eligibility.IsEligible()) { return; } if (eligibility.Eligibility == Eligibility.REQUIRE_ONE && setStream == eligibility.StreamNum) { return; } testStreamNum = eligibility.StreamNum; } else { testStreamNum = ((ExprIdentNode)testExpr).StreamId; } if (testStreamNum == null) { queryGraph.AddInSetMultiIndexUnkeyed(testExpr, setStream, exprNodes); } else { if (testStreamNum.Equals(entry.Key)) { return; } queryGraph.AddInSetMultiIndex(testStreamNum.Value, testExpr, setStream, exprNodes); } }
public void SetUp() { _container = SupportContainer.Reset(); _inNodeNormal = SupportExprNodeFactory.MakeInSetNode(false); _inNodeNotIn = SupportExprNodeFactory.MakeInSetNode(true); }
private static FilterSpecParam HandleInSetNode( ExprInNode constituent, IDictionary<string, Pair<EventType, string>> arrayEventTypes, ExprEvaluatorContext exprEvaluatorContext, string statementName) { var left = constituent.ChildNodes[0]; if (!(left is ExprFilterOptimizableNode)) { return null; } var filterOptimizableNode = (ExprFilterOptimizableNode) left; var lookupable = filterOptimizableNode.FilterLookupable; var op = FilterOperator.IN_LIST_OF_VALUES; if (constituent.IsNotIn) { op = FilterOperator.NOT_IN_LIST_OF_VALUES; } var expectedNumberOfConstants = constituent.ChildNodes.Length - 1; IList<FilterSpecParamInValue> listofValues = new List<FilterSpecParamInValue>(); foreach (var subNode in constituent.ChildNodes.Skip(1)) // ignore the first node as it's the identifier { if (ExprNodeUtility.IsConstantValueExpr(subNode)) { var constantNode = (ExprConstantNode) subNode; var constant = constantNode.GetConstantValue(exprEvaluatorContext); if (constant != null && !constant.GetType().IsArray) { var constantType = constant.GetType(); if (constantType.IsGenericCollection()) return null; if (constantType.IsGenericDictionary()) return null; } var asArray = constant as Array; if (asArray != null) { for (var i = 0; i < asArray.Length; i++) { var arrayElement = asArray.GetValue(i); var arrayElementCoerced = HandleConstantsCoercion(lookupable, arrayElement); listofValues.Add(new InSetOfValuesConstant(arrayElementCoerced)); if (i > 0) { expectedNumberOfConstants++; } } } else { constant = HandleConstantsCoercion(lookupable, constant); listofValues.Add(new InSetOfValuesConstant(constant)); } } if (subNode is ExprContextPropertyNode) { var contextPropertyNode = (ExprContextPropertyNode) subNode; var returnType = contextPropertyNode.ReturnType; if (contextPropertyNode.ReturnType.IsImplementsInterface(typeof (ICollection<>)) || contextPropertyNode.ReturnType.IsImplementsInterface(typeof (IDictionary<,>))) { return null; } if ((returnType != null) && (returnType.GetType().IsArray)) { return null; } var coercer = GetNumberCoercer( left.ExprEvaluator.ReturnType, contextPropertyNode.ReturnType, lookupable.Expression); listofValues.Add( new InSetOfValuesContextProp( contextPropertyNode.PropertyName, contextPropertyNode.Getter, coercer)); } if (subNode is ExprIdentNode) { var identNodeInner = (ExprIdentNode) subNode; if (identNodeInner.StreamId == 0) { break; // for same event evals use the boolean expression, via count compare failing below } var isMustCoerce = false; var numericCoercionType = lookupable.ReturnType.GetBoxedType(); if (identNodeInner.ExprEvaluator.ReturnType != lookupable.ReturnType) { if (lookupable.ReturnType.IsNumeric()) { if (!identNodeInner.ExprEvaluator.ReturnType.CanCoerce(lookupable.ReturnType)) { ThrowConversionError( identNodeInner.ExprEvaluator.ReturnType, lookupable.ReturnType, lookupable.Expression); } isMustCoerce = true; } else { break; // assumed not compatible } } FilterSpecParamInValue inValue; var streamName = identNodeInner.ResolvedStreamName; if (arrayEventTypes != null && !arrayEventTypes.IsEmpty() && arrayEventTypes.ContainsKey(streamName)) { var indexAndProp = GetStreamIndex(identNodeInner.ResolvedPropertyName); inValue = new InSetOfValuesEventPropIndexed( identNodeInner.ResolvedStreamName, indexAndProp.First.Value, indexAndProp.Second, isMustCoerce, numericCoercionType, statementName); } else { inValue = new InSetOfValuesEventProp( identNodeInner.ResolvedStreamName, identNodeInner.ResolvedPropertyName, isMustCoerce, numericCoercionType); } listofValues.Add(inValue); } } // Fallback if not all values in the in-node can be resolved to properties or constants if (listofValues.Count == expectedNumberOfConstants) { return new FilterSpecParamIn(lookupable, op, listofValues); } return null; }
internal static FilterSpecParamForge HandleInSetNode( ExprInNode constituent, IDictionary <string, Pair <EventType, string> > taggedEventTypes, IDictionary <string, Pair <EventType, string> > arrayEventTypes, ISet <string> allTagNamesOrdered, StatementRawInfo raw, StatementCompileTimeServices services) { var left = constituent.ChildNodes[0]; ExprFilterSpecLookupableForge lookupable = null; if (left is ExprFilterOptimizableNode) { var filterOptimizableNode = (ExprFilterOptimizableNode)left; lookupable = filterOptimizableNode.FilterLookupable; } else if (FilterSpecCompilerIndexPlannerHelper.HasLevelOrHint(FilterSpecCompilerIndexPlannerHint.LKUPCOMPOSITE, raw, services) && IsLimitedLookupableExpression(left)) { lookupable = MakeLimitedLookupableForgeMayNull(left, raw, services); } if (lookupable == null) { return(null); } var op = FilterOperator.IN_LIST_OF_VALUES; if (constituent.IsNotIn) { op = FilterOperator.NOT_IN_LIST_OF_VALUES; } var expectedNumberOfConstants = constituent.ChildNodes.Length - 1; IList <FilterSpecParamInValueForge> listofValues = new List <FilterSpecParamInValueForge>(); var it = Arrays.AsList(constituent.ChildNodes).GetEnumerator(); it.MoveNext(); // ignore the first node as it's the identifier while (it.MoveNext()) { var subNode = it.Current; if (subNode.Forge.ForgeConstantType.IsCompileTimeConstant) { var constant = subNode.Forge.ExprEvaluator.Evaluate(null, true, null); if (constant is ICollection <object> ) { return(null); } if (constant is IDictionary <object, object> ) { return(null); } if ((constant != null) && (constant is Array arrayConstant)) { for (var i = 0; i < arrayConstant.Length; i++) { var arrayElement = arrayConstant.GetValue(i); var arrayElementCoerced = HandleConstantsCoercion(lookupable, arrayElement); listofValues.Add(new FilterForEvalConstantAnyTypeForge(arrayElementCoerced)); if (i > 0) { expectedNumberOfConstants++; } } } else { constant = HandleConstantsCoercion(lookupable, constant); listofValues.Add(new FilterForEvalConstantAnyTypeForge(constant)); } } else if (subNode is ExprContextPropertyNode) { var contextPropertyNode = (ExprContextPropertyNode)subNode; var returnType = contextPropertyNode.Type; Coercer coercer; if (TypeHelper.IsCollectionMapOrArray(returnType)) { CheckArrayCoercion(returnType, lookupable.ReturnType, lookupable.Expression); coercer = null; } else { coercer = GetNumberCoercer(left.Forge.EvaluationType, contextPropertyNode.Type, lookupable.Expression); } var finalReturnType = coercer != null ? coercer.ReturnType : returnType; listofValues.Add(new FilterForEvalContextPropForge(contextPropertyNode.PropertyName, contextPropertyNode.Getter, coercer, finalReturnType)); } else if (subNode.Forge.ForgeConstantType.IsDeployTimeTimeConstant && subNode is ExprNodeDeployTimeConst) { var deployTimeConst = (ExprNodeDeployTimeConst)subNode; var returnType = subNode.Forge.EvaluationType; Coercer coercer; if (TypeHelper.IsCollectionMapOrArray(returnType)) { CheckArrayCoercion(returnType, lookupable.ReturnType, lookupable.Expression); coercer = null; } else { coercer = GetNumberCoercer(left.Forge.EvaluationType, returnType, lookupable.Expression); } listofValues.Add(new FilterForEvalDeployTimeConstForge(deployTimeConst, coercer, returnType)); } else if (subNode is ExprIdentNode) { var identNodeInner = (ExprIdentNode)subNode; if (identNodeInner.StreamId == 0) { break; // for same event evals use the boolean expression, via count compare failing below } var isMustCoerce = false; var coerceToType = Boxing.GetBoxedType(lookupable.ReturnType); var identReturnType = identNodeInner.Forge.EvaluationType; if (TypeHelper.IsCollectionMapOrArray(identReturnType)) { CheckArrayCoercion(identReturnType, lookupable.ReturnType, lookupable.Expression); coerceToType = identReturnType; // no action } else if (identReturnType != lookupable.ReturnType) { if (TypeHelper.IsNumeric(lookupable.ReturnType)) { if (!TypeHelper.CanCoerce(identReturnType, lookupable.ReturnType)) { ThrowConversionError(identReturnType, lookupable.ReturnType, lookupable.Expression); } isMustCoerce = true; } else { break; // assumed not compatible } } FilterSpecParamInValueForge inValue; var streamName = identNodeInner.ResolvedStreamName; if (arrayEventTypes != null && !arrayEventTypes.IsEmpty() && arrayEventTypes.ContainsKey(streamName)) { var indexAndProp = GetStreamIndex(identNodeInner.ResolvedPropertyName); var innerEventType = GetArrayInnerEventType(arrayEventTypes, streamName); inValue = new FilterForEvalEventPropIndexedForge( identNodeInner.ResolvedStreamName, indexAndProp.First, indexAndProp.Second, innerEventType, isMustCoerce, coerceToType); } else { inValue = new FilterForEvalEventPropForge( identNodeInner.ResolvedStreamName, identNodeInner.ResolvedPropertyName, identNodeInner.ExprEvaluatorIdent, isMustCoerce, coerceToType); } listofValues.Add(inValue); } else if (FilterSpecCompilerIndexPlannerHelper.HasLevelOrHint(FilterSpecCompilerIndexPlannerHint.VALUECOMPOSITE, raw, services) && IsLimitedValueExpression(subNode)) { var convertor = GetMatchEventConvertor(subNode, taggedEventTypes, arrayEventTypes, allTagNamesOrdered); var valueType = subNode.Forge.EvaluationType; var lookupableType = lookupable.ReturnType; var numberCoercer = GetNumberCoercer(lookupableType, valueType, lookupable.Expression); var forge = new FilterForEvalLimitedExprForge(subNode, convertor, numberCoercer); listofValues.Add(forge); } } // Fallback if not all values in the in-node can be resolved to properties or constants if (listofValues.Count == expectedNumberOfConstants) { return(new FilterSpecParamInForge(lookupable, op, listofValues)); } return(null); }
public void SetUp() { _inNodeNormal = SupportExprNodeFactory.MakeInSetNode(false); _inNodeNotIn = SupportExprNodeFactory.MakeInSetNode(true); }
private static FilterSpecParam HandleInSetNode( ExprInNode constituent, IDictionary <string, Pair <EventType, string> > arrayEventTypes, ExprEvaluatorContext exprEvaluatorContext, string statementName) { var left = constituent.ChildNodes[0]; if (!(left is ExprFilterOptimizableNode)) { return(null); } var filterOptimizableNode = (ExprFilterOptimizableNode)left; var lookupable = filterOptimizableNode.FilterLookupable; var op = FilterOperator.IN_LIST_OF_VALUES; if (constituent.IsNotIn) { op = FilterOperator.NOT_IN_LIST_OF_VALUES; } var expectedNumberOfConstants = constituent.ChildNodes.Count - 1; var listofValues = new List <FilterSpecParamInValue>(); var enumerator = constituent.ChildNodes.GetEnumerator(); enumerator.MoveNext(); // ignore the first node as it's the identifier while (enumerator.MoveNext()) { ExprNode subNode = enumerator.Current; if (ExprNodeUtility.IsConstantValueExpr(subNode)) { var constantNode = (ExprConstantNode)subNode; var constant = constantNode.GetConstantValue(exprEvaluatorContext); if (constant is Array asArray) { for (var i = 0; i < asArray.Length; i++) { var arrayElement = asArray.GetValue(i); var arrayElementCoerced = HandleConstantsCoercion(lookupable, arrayElement); listofValues.Add(new FilterForEvalConstantAnyType(arrayElementCoerced)); if (i > 0) { expectedNumberOfConstants++; } } } else if (constant is ICollection <object> ) { return(null); } else if (constant is IDictionary <string, object> ) { return(null); } else { constant = HandleConstantsCoercion(lookupable, constant); listofValues.Add(new FilterForEvalConstantAnyType(constant)); } } if (subNode is ExprContextPropertyNode) { var contextPropertyNode = (ExprContextPropertyNode)subNode; var returnType = contextPropertyNode.ReturnType; Coercer coercer; Type coercerType; if (returnType.IsCollectionMapOrArray()) { CheckArrayCoercion(returnType, lookupable.ReturnType, lookupable.Expression); coercer = null; coercerType = null; } else { coercer = GetNumberCoercer( left.ExprEvaluator.ReturnType, contextPropertyNode.ReturnType, lookupable.Expression, out coercerType); } var finalReturnType = coercer != null ? coercerType : returnType; listofValues.Add(new FilterForEvalContextPropMayCoerce(contextPropertyNode.PropertyName, contextPropertyNode.Getter, coercer, finalReturnType)); } if (subNode is ExprIdentNode) { var identNodeInner = (ExprIdentNode)subNode; if (identNodeInner.StreamId == 0) { break; // for same event evals use the bool expression, via count compare failing below } var isMustCoerce = false; var coerceToType = lookupable.ReturnType.GetBoxedType(); var identReturnType = identNodeInner.ExprEvaluator.ReturnType; if (identReturnType.IsCollectionMapOrArray()) { CheckArrayCoercion(identReturnType, lookupable.ReturnType, lookupable.Expression); coerceToType = identReturnType; // no action } else if (identReturnType != lookupable.ReturnType) { if (lookupable.ReturnType.IsNumeric()) { if (!identReturnType.CanCoerce(lookupable.ReturnType)) { ThrowConversionError(identReturnType, lookupable.ReturnType, lookupable.Expression); } isMustCoerce = true; } else { break; // assumed not compatible } } FilterSpecParamInValue inValue; var streamName = identNodeInner.ResolvedStreamName; if (arrayEventTypes != null && !arrayEventTypes.IsEmpty() && arrayEventTypes.ContainsKey(streamName)) { var indexAndProp = GetStreamIndex(identNodeInner.ResolvedPropertyName); inValue = new FilterForEvalEventPropIndexedMayCoerce(identNodeInner.ResolvedStreamName, indexAndProp.First, indexAndProp.Second, isMustCoerce, coerceToType, statementName); } else { inValue = new FilterForEvalEventPropMayCoerce(identNodeInner.ResolvedStreamName, identNodeInner.ResolvedPropertyName, isMustCoerce, coerceToType); } listofValues.Add(inValue); } } // Fallback if not all values in the in-node can be resolved to properties or constants if (listofValues.Count == expectedNumberOfConstants) { return(new FilterSpecParamIn(lookupable, op, listofValues)); } return(null); }