public override SnQueryPredicate VisitLogicalPredicate(LogicalPredicate logic) { _queryTree.Push(new BooleanQuery()); var visited = base.VisitLogicalPredicate(logic); return(visited); }
internal static void PrepareQuery(SnQuery query, IQueryContext context) { if (query.FiltersPrepared) { return; } var autoFiltersEnabled = IsAutofilterEnabled(query.EnableAutofilters); var lifespanFiltersEnabled = IsLifespanFilterEnabled(query.EnableLifespanFilter); if (autoFiltersEnabled || lifespanFiltersEnabled) { var topLevelPredicate = new LogicalPredicate(); topLevelPredicate.Clauses.Add(new LogicalClause(query.QueryTree, Occurence.Must)); if (autoFiltersEnabled) { topLevelPredicate.Clauses.Add(new LogicalClause(GetAutoFilterClause(context), Occurence.Must)); } if (lifespanFiltersEnabled) { topLevelPredicate.Clauses.Add(new LogicalClause(GetLifespanFilterClause(context), Occurence.Must)); } query.QueryTree = topLevelPredicate; } query.FiltersPrepared = true; }
public static string ToString(LogicalPredicate predicate) { var visitor = new SnQueryToStringVisitor(); visitor.VisitLogicalPredicate(predicate); return(visitor.Output); }
private SnQueryPredicate ParseQueryExpList() { // QueryExpList ==> QueryExp | QueryExpList QueryExp var queries = new List <SnQueryPredicate>(); while (!IsEof() && _lexer.CurrentToken != CqlLexer.Token.RParen) { var q = ParseQueryExp(); if (q != null) { queries.Add(q); } } if (queries.Count == 0) { return(null); } if (queries.Count == 1) { return(queries[0]); } var boolQuery = new LogicalPredicate(); foreach (var q in queries) { AddBooleanClause(boolQuery, q, Occurence.Default); } return(boolQuery); }
/* ============================================================================ Recursive descent methods */ private SnQueryPredicate ParseTopLevelQueryExpList() { // QueryExpList ==> QueryExp | QueryExpList QueryExp var queries = new List <SnQueryPredicate>(); while (!IsEof()) { var q = ParseQueryExp(); if (q != null) { queries.Add(q); } } if (queries.Count == 0) { throw ParserError("Empty query is not allowed."); } if (queries.Count == 1) { return(queries[0]); } var boolQuery = new LogicalPredicate(); foreach (var q in queries) { AddBooleanClause(boolQuery, q, Occurence.Default); } return(boolQuery); }
private static bool HasSharingRelatedClause(LogicalPredicate logicalPredicate) { var visitor = new SharingRelatedPredicateFinderVisitor(); visitor.Visit(logicalPredicate); return(visitor.SharingRelatedPredicates.Count > 0); }
public override SnQueryPredicate VisitLogicalPredicate(LogicalPredicate logic) { // Merge clauses with sub levels if the occurences are equal. var visited = (LogicalPredicate)base.VisitLogicalPredicate(logic); var occur = visited.Clauses[0].Occur; var subClausesToMerge = visited.Clauses .Where(x => x.Predicate is LogicalPredicate y && OccursAreEqual(y.Clauses[0].Occur, occur)) .ToArray(); if (subClausesToMerge.Length == 0) { return(visited); } var mergedclauses = visited.Clauses.ToList(); foreach (var subClause in subClausesToMerge) { var subLevel = (LogicalPredicate)subClause.Predicate; mergedclauses.Remove(subClause); mergedclauses.AddRange(subLevel.Clauses); } return(new LogicalPredicate(mergedclauses)); }
public void SnQuery_Visitor_Rewrite_CSrv() { var tree = new LogicalPredicate( new [] { new LogicalClause(new LogicalPredicate( new [] { new LogicalClause(new SimplePredicate("F1", new IndexValue("V1")), Occurence.Should), new LogicalClause(new SimplePredicate("F2", new IndexValue("V2")), Occurence.Should) }), Occurence.Must), new LogicalClause(new LogicalPredicate( new [] { new LogicalClause(new SimplePredicate("F3", new IndexValue("V3")), Occurence.Should), new LogicalClause(new RangePredicate("F4", null, new IndexValue(10), true, true), Occurence.Should), }), Occurence.Must), }); var visitor = new TestVisitor(); var rewritten = visitor.Visit(tree); var dumper = new SnQueryToStringVisitor(); dumper.Visit(rewritten); Assert.AreEqual("+(F1:V1 F2:V2222) +(F3:V3 F4:<10)", dumper.Output); }
/// <summary> /// Replaces the top level predicate to a new LogicalPredicate that /// contains the original top level predicate and a given predicate /// encapsulated by two individual LogicalClause with the given occurence. /// </summary> public void AddClause(SnQueryPredicate clause, Occurence occurence) { QueryTree = new LogicalPredicate(new[] { new LogicalClause(QueryTree, occurence), new LogicalClause(clause, occurence), }); }
public override SnQueryPredicate Visit(SnQueryPredicate predicate) { if (!_initialized) { _topLevelLogicalPredicate = predicate as LogicalPredicate; _initialized = true; } return(base.Visit(predicate)); }
/// <summary> /// Visits the given LogicalPredicate and it's children. /// </summary> /// <param name="logic">The predicate to visit.</param> /// <returns>The modified predicate, if it or any child was modified; otherwise, returns the original predicate.</returns> public virtual SnQueryPredicate VisitLogicalPredicate(LogicalPredicate logic) { var clauses = logic.Clauses; var visitedClauses = VisitLogicalClauses(clauses); LogicalPredicate rewritten = null; if (visitedClauses != clauses) { rewritten = new LogicalPredicate(visitedClauses); } return(rewritten ?? logic); }
private static AssortedPredicates AssortPredicates(LogicalPredicate visited) { var result = new AssortedPredicates(); foreach (var clause in visited.Clauses) { if (clause.Predicate is SimplePredicate simplePredicate) { if (simplePredicate.FieldName == SharingVisitor.Sharing) { switch (clause.Occur) { case Occurence.Must: result.SimpleMust.Add(simplePredicate); break; case Occurence.MustNot: throw new InvalidContentSharingQueryException("Sharing related query clause cannot be negation."); } } else { result.GeneralClauses.Add(clause); } } else if (clause.Predicate is LogicalPredicate logicalPredicate) { if (HasSharingRelatedClause(logicalPredicate)) { switch (clause.Occur) { case Occurence.Must: result.LogicalMust.Add(logicalPredicate); break; case Occurence.MustNot: throw new InvalidContentSharingQueryException("Sharing related query clause cannot be negation."); } } else { result.GeneralClauses.Add(clause); } } else { result.GeneralClauses.Add(clause); } } return(result); }
public override SnQueryPredicate VisitLogicalPredicate(LogicalPredicate logic) { var clauses = logic.Clauses; var visitedClauses = VisitLogicalClauses(clauses); var newClauses = new List <LogicalClause>(); var changed = false; foreach (var clause in visitedClauses) { if (!(clause.Predicate is LogicalPredicate lp)) { newClauses.Add(clause); }
public override SnQueryPredicate VisitLogicalPredicate(LogicalPredicate logic) { if (_booleanCount++ > 0) { _output.Append("("); } var list = base.VisitLogicalPredicate(logic); if (--_booleanCount > 0) { _output.Append(")"); } return(list); }
public override SnQueryPredicate VisitLogicalPredicate(LogicalPredicate logic) { var clauses = logic.Clauses; var visitedClauses = VisitLogicalClauses(clauses); if (visitedClauses == clauses) { return(logic); } if (visitedClauses == null) { return(null); } var newList = new LogicalPredicate(); newList.Clauses.AddRange(visitedClauses); return(newList); }
private SnQueryPredicate ParseClause() { var occur = ParseOccur(); var query = ParseQueryExpGroup(); var boost = ParseBoost(); if (boost != null) { query.Boost = Convert.ToSingle(boost.Value); } if (occur == Occurence.Default || occur == Occurence.Should) { return(query); } var boolq = new LogicalPredicate(); AddBooleanClause(boolq, query, occur); return(boolq); }
private SnQueryPredicate ParseValueClause() { // ValueClause ==> [Occur] ValueGroup var occur = ParseOccur(); var query = ParseValueGroup(); if (query == null) { throw ParserError("Empty clause list is not allowed: '()'."); } query.Boost = ParseBoost(); if (occur == Occurence.Default || occur == Occurence.Should) { return(query); } var boolq = new LogicalPredicate(); AddBooleanClause(boolq, query, occur); return(boolq); }
private SnQueryPredicate ParseUnaryNot() { var not = false; if (_lexer.CurrentToken == CqlLexer.Token.Not) { _lexer.NextToken(); not = true; } var query = ParseClause(); if (!not) { return(query); } var boolq = new LogicalPredicate(); AddBooleanClause(boolq, query, Occurence.MustNot); return(boolq); }
private LogicalPredicate VisitTopLevelSharingPredicate(LogicalPredicate logic, bool[] isSharingFlags) { var generalClauses = new List <LogicalClause>(); var sharingClauses = new List <LogicalClause>(); for (int i = 0; i < logic.Clauses.Count; i++) { if (isSharingFlags[i]) { sharingClauses.Add(logic.Clauses[i]); } else { generalClauses.Add(logic.Clauses[i]); } } // --------------------------------------------------- // Handle logical predicates var sharingPredicate = new LogicalPredicate(sharingClauses); var normalizer = new SharingNormalizerVisitor(); var normalizedSharingPredicate = normalizer.Visit(sharingPredicate); // Make combinations var composer = new SharingComposerVisitor(); var composition = (LogicalPredicate)composer.Visit(normalizedSharingPredicate); // Last normalization var normalizedComposition = new SharingNormalizerVisitor().Visit(composition); // Convert sharing combined values from string array to one comma separated string var finalizer = new SharingFinalizerVisitor(); var finalTree = (LogicalPredicate)finalizer.Visit(normalizedComposition); // Return the final product var allClauses = generalClauses.Union(finalTree.Clauses); return(new LogicalPredicate(allClauses)); }
private SnQueryPredicate ParseUnaryTermExp() { // UnaryTermExp ==> UnaryFieldHead UnaryFieldValue | ControlExp // UnaryFieldHead ==> STRING COLON | STRING NEQ // UnaryFieldValue ==> ValueGroup | Range var fieldInfo = _currentField.Peek(); if (fieldInfo == null) { return(null); } if (fieldInfo.IsBinary) { return(null); } if (fieldInfo.OperatorToken == CqlLexer.Token.NEQ) { var value = ParseExactValue(true); var bq = new LogicalPredicate(); bq.Clauses.Add(new LogicalClause(CreateValueQuery(value), Occurence.MustNot)); return(bq); } var result = ParseValueGroup(); if (result != null) { return(result); } result = ParseRange(); if (result != null) { return(result); } throw ParserError(String.Concat("Unexpected '", _lexer.StringValue, "'")); }
private SnQueryPredicate ParseValueExpList() { // ValueExpList ==> ValueExp | ValueExpList ValueExp var first = ParseValueExp(); if (_lexer.CurrentToken == CqlLexer.Token.RParen) { return(first); } var boolQuery = new LogicalPredicate(); AddBooleanClause(boolQuery, first, Occurence.Default); while (!IsEof() && _lexer.CurrentToken != CqlLexer.Token.RParen) { var q = ParseValueExp(); AddBooleanClause(boolQuery, q, Occurence.Default); } return(boolQuery); }
public override SnQueryPredicate VisitLogicalPredicate(LogicalPredicate logic) { var isTopLevel = _topLevelLogicalPredicate == logic; var visited = (LogicalPredicate)base.VisitLogicalPredicate(logic); var clauseCount = visited.Clauses.Count; // Get all sub-item types in righr order var isSharingFlags = new bool[clauseCount]; for (var i = 0; i < clauseCount; i++) { isSharingFlags[clauseCount - i - 1] = _isSharingStack.Pop(); } var isSharing = isSharingFlags.Any(x => x); var isMixed = isSharingFlags.Any(x => x == !isSharingFlags[0]); if (isSharing && _isSharinglDisabled) { throw new InvalidContentSharingQueryException("Only one parenthesis can contain sharing related and not-sharing related clauses."); } if (!isMixed && !(isSharing && isTopLevel)) { _isSharingStack.Push(isSharingFlags[0]); return(visited); } var visitedSharing = VisitTopLevelSharingPredicate(visited, isSharingFlags); _isSharinglDisabled = true; // push false to avoid "mixed" rank in any higher level _isSharingStack.Push(false); return(visitedSharing); }
private SnQueryPredicate ParseValueBinaryAnd() { // ValueBinaryAnd ==> ValueUnaryNot | ValueBinaryAnd AND ValueUnaryNot var queries = new List <SnQueryPredicate> { ParseValueUnaryNot() }; while (_lexer.CurrentToken == CqlLexer.Token.And) { _lexer.NextToken(); queries.Add(ParseValueUnaryNot()); } if (queries.Count == 1) { return(queries[0]); } var boolq = new LogicalPredicate(); foreach (var query in queries) { AddBooleanClause(boolq, query, Occurence.Must); } return(boolq); }
private SnQueryPredicate ParseBinaryOr() { // BinaryOr ==> BinaryAnd | BinaryOr OR BinaryAnd var queries = new List <SnQueryPredicate> { ParseBinaryAnd() }; while (_lexer.CurrentToken == CqlLexer.Token.Or) { _lexer.NextToken(); queries.Add(ParseBinaryAnd()); } if (queries.Count == 1) { return(queries[0]); } var boolq = new LogicalPredicate(); foreach (var query in queries) { AddBooleanClause(boolq, query, Occurence.Should); } return(boolq); }
/* ============================================================================ */ private void AddBooleanClause(LogicalPredicate boolNode, SnQueryPredicate query, Occurence occur) { if (!(query is LogicalPredicate boolQ)) { boolNode.Clauses.Add(new LogicalClause(query, occur)); return; } var clauses = boolQ.Clauses; if (clauses.Count == 0) { throw ParserError("Empty BooleanNode"); } if (clauses.Count > 1) { boolNode.Clauses.Add(new LogicalClause(query, occur)); return; } // boolQ has one clause: combine occurs var clause = clauses[0]; var clauseOccur = clause.Occur; Occurence effectiveOccur; if (_defaultOperator == DefaultOperator.Or) { // in cl eff // ? _ ==> _ // ? + ==> + // ? - ==> - // _ _ ==> _ // _ + ==> + // _ - ==> - // + _ ==> + // + + ==> + // + - ==> - // - _ ==> - // - + ==> - // - - ==> - if (occur == Occurence.Default || occur == Occurence.Should) { effectiveOccur = clauseOccur; } else if (occur == Occurence.MustNot) { effectiveOccur = occur; } else if (clauseOccur == Occurence.MustNot) { effectiveOccur = clauseOccur; } else { effectiveOccur = occur; } } else { // in cl eff // ? _ ==> _ // ? + ==> + // ? - ==> - // _ _ ==> _ // _ + ==> _ // _ - ==> - // + _ ==> + // + + ==> + // + - ==> - // - _ ==> - // - + ==> - // - - ==> - if (occur == Occurence.Default) { effectiveOccur = clauseOccur; } else if (occur == Occurence.MustNot) { effectiveOccur = occur; } else if (clauseOccur == Occurence.MustNot) { effectiveOccur = clauseOccur; } else { effectiveOccur = occur; } } clause.Occur = effectiveOccur; boolNode.Clauses.Add(clause); }
public override SnQueryPredicate VisitLogicalPredicate(LogicalPredicate logic) { _queryInfo.BooleanQueries++; return(base.VisitLogicalPredicate(logic)); }
public override SnQueryPredicate VisitLogicalPredicate(LogicalPredicate logic) { var visited = logic; var clauses = logic.Clauses; var visitedClauses = VisitLogicalClauses(clauses); if (visitedClauses != clauses) { visited = new LogicalPredicate(visitedClauses); } var assortedLevel = AssortPredicates(visited); var mustClauseCount = assortedLevel.SimpleMust.Count + assortedLevel.LogicalMust.Count; List <LogicalClause> newClauses; // 1 - If there are only "SHOULD" clauses or there is only one "MUST" clause, it is not necessary to do any transformation. // Note that the query tree is normalized that means "MUST" clause existence excludes any "SHOULD" clause // so "SHOULD" clause can only exist if the count of "MUST" clauses is 0. if (mustClauseCount < 2) { return(visited); } // 2 - If there are only "MUST" simple clauses but two or more: combine them and not sharing clauses be unchanged // Consider that the values may already be combined. if (assortedLevel.SimpleMust.Count >= 2 && assortedLevel.LogicalMust.Count == 0) { newClauses = assortedLevel.GeneralClauses.ToList(); var values = assortedLevel.SimpleMust .SelectMany(x => x.Value.StringArrayValue) .ToArray(); newClauses.Add( new LogicalClause( CreateSharingSimplePredicate(values), Occurence.Must)); return(new LogicalPredicate(newClauses)); } // 3 - If there are any "MUST" simple clauses and logical clauses: combine everything // Combine all clauses for example: +a +b +(c d) +(e f) --> +(abce abcf abde abdf) // In the temporary storage the inner collection stores the items of the combined values and the // outer collection contains the future terms (List<List<string>>). // 3.1 - Combine all simple values (with breaking the already combined values) var combinedSimpleValues = assortedLevel.SimpleMust .SelectMany(x => x.Value.StringArrayValue).ToList(); // 3.2 - create a temporary storage from the combined simple values. var combinedValues = new List <List <string> > { combinedSimpleValues }; // 3.3 - Combine the current list with each values of each logical predicate foreach (var logical in assortedLevel.LogicalMust) { var values = logical.Clauses .Where(x => x.Predicate is SimplePredicate) .Select(x => (SimplePredicate)x.Predicate) .Where(x => x.FieldName == SharingVisitor.Sharing) .Select(x => x.Value.StringArrayValue.ToList()) .ToList(); combinedValues = CombineValues(values, combinedValues); } // 3.4 - Create a new logical clause from the combined values var newPredicate = CreateSharingLogicalPredicate(combinedValues); var finalSharingClause = new LogicalClause(newPredicate, Occurence.Must); // 3.5 - Create a list of output logical clauses. newClauses = assortedLevel.GeneralClauses.ToList(); newClauses.Add(finalSharingClause); // 3.6 - Return with the rewritten level return(new LogicalPredicate(newClauses)); }