private static bool AttemptRangeSetMerge(Variable v, FunctionExpression rangeSetTerm, Expression toMergeWith, string logicalOpName) { if (toMergeWith is FunctionExpression) { FunctionExpression functionExp = (FunctionExpression) toMergeWith; // If the type is the same logical operation, we recurse string funType = functionExp.Name; if (funType.Equals(logicalOpName)) { // Recurse condition, we try left and right merge // We attempt left and right param if (AttemptRangeSetMerge(v, rangeSetTerm, (Expression)functionExp.Parameters[0], logicalOpName)) return true; return AttemptRangeSetMerge(v, rangeSetTerm, (Expression) functionExp.Parameters[1], logicalOpName); } // If it's a range set, if (funType.Equals("range_set")) { // Get the var Variable targetVariable = ((FetchVariableExpression) functionExp.Parameters[0]).Variable; // If they match, we merge if (v.Equals(targetVariable)) { // Get the range sets SelectableRange rangeSet1 = (SelectableRange) functionExp.Parameters[1]; SelectableRange rangeSet2 = (SelectableRange) rangeSetTerm.Parameters[1]; // Make sure the range types are the same SqlObject[] ob1 = (SqlObject[])toMergeWith.GetArgument("full_range_object"); SqlObject[] ob2 = (SqlObject[])rangeSetTerm.GetArgument("full_range_object"); if (ob1.Length != 1 || ob2.Length != 1) // PENDING: Handle composite terms, return false; SqlType rs1Type = ob1[0].Type; SqlType rs2Type = ob2[0].Type; if (!rs1Type.Equals(rs2Type)) // Types are not strictly comparable, therefore can't merge, return false; // Merge (note that range_set1 which is part of 'to_merge_with' // will be modified). if (logicalOpName.Equals("@and_sql")) { // intersect (and) rangeSet1 = rangeSet1.Intersect(rangeSet2); } else { // union (or) rangeSet1 = rangeSet1.Union(rangeSet2); } // Update the simplified term, functionExp.Parameters[1] = rangeSet1; return true; } // Not equal variables so return false return false; } // fun_type isn't named "range_set", "or" or "and" so we return false // indicating no merge is possible. return false; } return false; }