예제 #1
0
        public static IEnumerable <long> SelectRows(this ITable table, int column, Operator op, DataObject cell)
        {
            // If the cell is of an incompatible type, return no results,
            DataType colType = table.TableInfo[column].DataType;

            if (!cell.DataType.IsComparable(colType))
            {
                // Types not comparable, so return 0
                return(new List <long>(0));
            }

            // Get the selectable scheme for this column
            SelectableScheme ss = table.GetScheme(column);

            // If the operator is a standard operator, use the interned SelectableScheme
            // methods.
            if (op.IsEquivalent(Operator.Equal))
            {
                return(ss.SelectEqual(cell));
            }
            if (op.IsEquivalent(Operator.NotEqual))
            {
                return(ss.SelectNotEqual(cell));
            }
            if (op.IsEquivalent(Operator.Greater))
            {
                return(ss.SelectGreater(cell));
            }
            if (op.IsEquivalent(Operator.Smaller))
            {
                return(ss.SelectLess(cell));
            }
            if (op.IsEquivalent(Operator.GreaterOrEqual))
            {
                return(ss.SelectGreaterOrEqual(cell));
            }
            if (op.IsEquivalent(Operator.SmallerOrEqual))
            {
                return(ss.SelectLessOrEqual(cell));
            }

            // If it's not a standard operator (such as IS, NOT IS, etc) we generate the
            // range set especially.
            SelectableRangeSet rangeSet = new SelectableRangeSet();

            rangeSet.Intersect(op, cell);
            return(ss.SelectRange(rangeSet.ToArray()));
        }
예제 #2
0
        /// <summary>
        /// Calculates a list of <see cref="SelectableRange"/> objects that represent
        /// the range of the expression.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="field"></param>
        /// <param name="range"></param>
        /// <param name="exp"></param>
        private static void CalcRange(IQueryContext context, DataColumnInfo field, SelectableRangeSet range, Expression exp)
        {
            var      binary = (BinaryExpression)exp;
            Operator op     = binary.Operator;

            if (op.IsLogical())
            {
                if (op == Operator.And)
                {
                    IList <Expression> andList = CreateAndList(new List <Expression>(), exp);
                    foreach (Expression expr in andList)
                    {
                        UpdateRange(context, range, field, expr);
                    }
                }
                else if (op == Operator.Or)
                {
                    // Split left and right of logical operator.
                    Expression[] exps = { binary.Left, binary.Right };
                    // Calculate the range of the left and right
                    SelectableRangeSet left = new SelectableRangeSet();
                    CalcRange(context, field, left, exps[0]);
                    SelectableRangeSet right = new SelectableRangeSet();
                    CalcRange(context, field, right, exps[1]);

                    // Union the left and right range with the current range
                    range.Union(left);
                    range.Union(right);
                }
                else
                {
                    throw new ApplicationException("Unrecognised logical operator.");
                }
            }
            else
            {
                // Not an operator so this is the value.
                UpdateRange(context, range, field, exp);
            }
        }
예제 #3
0
        /// <summary>
        /// Updates a range with the given expression.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="range"></param>
        /// <param name="field"></param>
        /// <param name="e"></param>
        private static void UpdateRange(IQueryContext context, SelectableRangeSet range, DataColumnInfo field, Expression e)
        {
            var      binary = (BinaryExpression)e;
            Operator op     = binary.Operator;

            Expression[] exps = { binary.Left, binary.Right };

            // Evaluate to an object
            DataObject cell = exps[1].Evaluate(context);

            // If the evaluated object is not of a comparable type, then it becomes
            // null.
            DataType fieldType = field.DataType;

            if (!cell.DataType.IsComparable(fieldType))
            {
                cell = new DataObject(fieldType, null);
            }

            // Intersect this in the range set
            range.Intersect(op, cell);
        }
예제 #4
0
        public override ITable Evaluate(IQueryContext context)
        {
            ITable t = Child.Evaluate(context);

            Expression exp = expression;

            // Assert that all variables in the expression are identical.
            IEnumerable <ObjectName> allVars = exp.AllVariables();
            ObjectName v = null;

            foreach (ObjectName cv in allVars)
            {
                if (v != null && !cv.Equals(v))
                {
                    throw new ApplicationException("Assertion failed: Range plan does not contain common variable.");
                }

                v = cv;
            }

            // Find the variable field in the table.
            int col = ((Table)t).FindFieldName(v);

            if (col == -1)
            {
                throw new ApplicationException("Couldn't find column reference in table: " + v);
            }

            DataColumnInfo field = t.TableInfo[col];
            // Calculate the range
            SelectableRangeSet range = new SelectableRangeSet();

            CalcRange(context, field, range, exp);

            // Select the range from the table
            SelectableRange[] ranges = range.ToArray();
            return(t.RangeSelect(v, ranges));
        }