Example #1
0
        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;
        }