internal CellQuery( List <ProjectedSlot> slots, BoolExpression whereClause, MemberPath rootMember, CellQuery.SelectDistinct eliminateDuplicates) : this(slots.ToArray(), whereClause, new List <BoolExpression>(), eliminateDuplicates, rootMember) { }
internal CellQuery(CellQuery source) { this.m_basicCellRelation = source.m_basicCellRelation; this.m_boolExprs = source.m_boolExprs; this.m_selectDistinct = source.m_selectDistinct; this.m_extentMemberPath = source.m_extentMemberPath; this.m_originalWhereClause = source.m_originalWhereClause; this.m_projectedSlots = source.m_projectedSlots; this.m_whereClause = source.m_whereClause; }
// effects: Given two duplicate eliination choices, returns an OR of them static private CellQuery.SelectDistinct MergeDupl(CellQuery.SelectDistinct d1, CellQuery.SelectDistinct d2) { if (d1 == CellQuery.SelectDistinct.Yes || d2 == CellQuery.SelectDistinct.Yes) { return(CellQuery.SelectDistinct.Yes); } else { return(CellQuery.SelectDistinct.No); } }
/// <summary> /// Creates an cql block representing the <paramref name="extent"/> (the FROM part). /// SELECT is given by <paramref name="slots"/>, WHERE by <paramref name="whereClause"/> and AS by <paramref name="blockAliasNum"/>. /// </summary> internal ExtentCqlBlock(EntitySetBase extent, CellQuery.SelectDistinct selectDistinct, SlotInfo[] slots, BoolExpression whereClause, CqlIdentifiers identifiers, int blockAliasNum) : base(slots, EmptyChildren, whereClause, identifiers, blockAliasNum) { m_extent = extent; m_nodeTableAlias = identifiers.GetBlockAlias(); m_selectDistinct = selectDistinct; }
internal CellQuery( ProjectedSlot[] projectedSlots, BoolExpression whereClause, List <BoolExpression> boolExprs, CellQuery.SelectDistinct elimDupl, MemberPath rootMember) { this.m_boolExprs = boolExprs; this.m_projectedSlots = projectedSlots; this.m_whereClause = whereClause; this.m_originalWhereClause = whereClause; this.m_selectDistinct = elimDupl; this.m_extentMemberPath = rootMember; }
// effects: Merges query2 with this according to the TM/SP rules for opType and // returns the merged result. canBooleansOverlap indicates whether the bools in this and query2 can overlap, i.e. // the same cells may have contributed to query2 and this earlier in the merge process internal bool TryMergeTwoCellQueries(CellQuery query1, CellQuery query2, CellTreeOpType opType, MemberDomainMap memberDomainMap, out CellQuery mergedQuery) { mergedQuery = null; // Initialize g1 and g2 according to the TM/SP rules for IJ, LOJ, Union, FOJ cases BoolExpression g1 = null; BoolExpression g2 = null; switch (opType) { case CellTreeOpType.IJ: break; case CellTreeOpType.LOJ: case CellTreeOpType.LASJ: g2 = BoolExpression.True; break; case CellTreeOpType.FOJ: case CellTreeOpType.Union: g1 = BoolExpression.True; g2 = BoolExpression.True; break; default: Debug.Fail("Unsupported operator"); break; } Dictionary <MemberPath, MemberPath> remap = new Dictionary <MemberPath, MemberPath>(MemberPath.EqualityComparer); //Continue merging only if both queries are over the same source MemberPath newRoot; if (!query1.Extent.Equals(query2.Extent)) { // could not merge return(false); } else { newRoot = query1.SourceExtentMemberPath; } // Conjuncts for ANDing with the previous whereClauses BoolExpression conjunct1 = BoolExpression.True; BoolExpression conjunct2 = BoolExpression.True; BoolExpression whereClause = null; switch (opType) { case CellTreeOpType.IJ: // Project[D1, D2, A, B, C] Select[cond1 and cond2] (T) // We simply merge the two lists of booleans -- no conjuct is added // conjunct1 and conjunct2 don't change // query1.WhereCaluse AND query2.WhereCaluse Debug.Assert(g1 == null && g2 == null, "IJ does not affect g1 and g2"); whereClause = BoolExpression.CreateAnd(query1.WhereClause, query2.WhereClause); break; case CellTreeOpType.LOJ: // conjunct1 does not change since D1 remains as is // Project[D1, (expr2 and cond2 and G2) as D2, A, B, C] Select[cond1] (T) // D1 does not change. New d2 is the list of booleans expressions // for query2 ANDed with g2 AND query2.WhereClause Debug.Assert(g1 == null, "LOJ does not affect g1"); conjunct2 = BoolExpression.CreateAnd(query2.WhereClause, g2); // Just query1's whereclause whereClause = query1.WhereClause; break; case CellTreeOpType.FOJ: case CellTreeOpType.Union: // Project[(expr1 and cond1 and G1) as D1, (expr2 and cond2 and G2) as D2, A, B, C] Select[cond1] (T) // New D1 is a list -- newD1 = D1 AND query1.WhereClause AND g1 // New D1 is a list -- newD2 = D2 AND query2.WhereClause AND g2 conjunct1 = BoolExpression.CreateAnd(query1.WhereClause, g1); conjunct2 = BoolExpression.CreateAnd(query2.WhereClause, g2); // The new whereClause -- g1 AND query1.WhereCaluse OR g2 AND query2.WhereClause whereClause = BoolExpression.CreateOr(BoolExpression.CreateAnd(query1.WhereClause, g1), BoolExpression.CreateAnd(query2.WhereClause, g2)); break; case CellTreeOpType.LASJ: // conjunct1 does not change since D1 remains as is // Project[D1, (expr2 and cond2 and G2) as D2, A, B, C] Select[cond1] (T) // D1 does not change. New d2 is the list of booleans expressions // for query2 ANDed with g2 AND NOT query2.WhereClause Debug.Assert(g1 == null, "LASJ does not affect g1"); conjunct2 = BoolExpression.CreateAnd(query2.WhereClause, g2); whereClause = BoolExpression.CreateAnd(query1.WhereClause, BoolExpression.CreateNot(conjunct2)); break; default: Debug.Fail("Unsupported operator"); break; } // Create the various remapped parts for the cell query -- // boolean expressions, merged slots, whereclause, duplicate // elimination, join tree List <BoolExpression> boolExprs = MergeBoolExpressions(query1, query2, conjunct1, conjunct2, opType); //BoolExpression.RemapBools(boolExprs, remap); ProjectedSlot[] mergedSlots; if (false == ProjectedSlot.TryMergeRemapSlots(query1.ProjectedSlots, query2.ProjectedSlots, out mergedSlots)) { // merging failed because two different right slots go to same left slot return(false); } whereClause = whereClause.RemapBool(remap); CellQuery.SelectDistinct elimDupl = MergeDupl(query1.SelectDistinctFlag, query2.SelectDistinctFlag); whereClause.ExpensiveSimplify(); mergedQuery = new CellQuery(mergedSlots, whereClause, boolExprs, elimDupl, newRoot); return(true); }
private static CellQuery.SelectDistinct MergeDupl( CellQuery.SelectDistinct d1, CellQuery.SelectDistinct d2) { return(d1 == CellQuery.SelectDistinct.Yes || d2 == CellQuery.SelectDistinct.Yes ? CellQuery.SelectDistinct.Yes : CellQuery.SelectDistinct.No); }
internal static bool TryMergeTwoCellQueries( CellQuery query1, CellQuery query2, CellTreeOpType opType, out CellQuery mergedQuery) { mergedQuery = (CellQuery)null; BoolExpression boolExpression1 = (BoolExpression)null; BoolExpression boolExpression2 = (BoolExpression)null; switch (opType) { case CellTreeOpType.Union: case CellTreeOpType.FOJ: boolExpression1 = BoolExpression.True; boolExpression2 = BoolExpression.True; break; case CellTreeOpType.LOJ: case CellTreeOpType.LASJ: boolExpression2 = BoolExpression.True; break; } Dictionary <MemberPath, MemberPath> remap = new Dictionary <MemberPath, MemberPath>(MemberPath.EqualityComparer); if (!query1.Extent.Equals((object)query2.Extent)) { return(false); } MemberPath extentMemberPath = query1.SourceExtentMemberPath; BoolExpression and1 = BoolExpression.True; BoolExpression and2 = BoolExpression.True; BoolExpression boolExpression3 = (BoolExpression)null; switch (opType) { case CellTreeOpType.Union: case CellTreeOpType.FOJ: and1 = BoolExpression.CreateAnd(query1.WhereClause, boolExpression1); and2 = BoolExpression.CreateAnd(query2.WhereClause, boolExpression2); boolExpression3 = BoolExpression.CreateOr(BoolExpression.CreateAnd(query1.WhereClause, boolExpression1), BoolExpression.CreateAnd(query2.WhereClause, boolExpression2)); break; case CellTreeOpType.LOJ: and2 = BoolExpression.CreateAnd(query2.WhereClause, boolExpression2); boolExpression3 = query1.WhereClause; break; case CellTreeOpType.IJ: boolExpression3 = BoolExpression.CreateAnd(query1.WhereClause, query2.WhereClause); break; case CellTreeOpType.LASJ: and2 = BoolExpression.CreateAnd(query2.WhereClause, boolExpression2); boolExpression3 = BoolExpression.CreateAnd(query1.WhereClause, BoolExpression.CreateNot(and2)); break; } List <BoolExpression> boolExprs = CellTreeSimplifier.MergeBoolExpressions(query1, query2, and1, and2, opType); ProjectedSlot[] result; if (!ProjectedSlot.TryMergeRemapSlots(query1.ProjectedSlots, query2.ProjectedSlots, out result)) { return(false); } BoolExpression whereClause = boolExpression3.RemapBool(remap); CellQuery.SelectDistinct elimDupl = CellTreeSimplifier.MergeDupl(query1.SelectDistinctFlag, query2.SelectDistinctFlag); whereClause.ExpensiveSimplify(); mergedQuery = new CellQuery(result, whereClause, boolExprs, elimDupl, extentMemberPath); return(true); }