Exemple #1
0
        public override ITable Evaluate(IQueryContext context)
        {
            var childTable = Child.Evaluate(context);
            var funTable = new FunctionTable(childTable, Functions, Names, context);

            // If no columns then it is implied the whole table is the group.
            if (ColumnNames == null) {
                funTable = funTable.AsGroup();
            } else {
                funTable = funTable.CreateGroupMatrix(ColumnNames);
            }

            return funTable.MergeWith(GroupMaxColumn);
        }
Exemple #2
0
 public TableGroupResolver(FunctionTable table)
 {
     this.table = table;
 }
        public static ITable Any(this ITable theTable, IQueryContext context, Expression expression, Operator op, Table rightTable)
        {
            ITable table = rightTable;

            // Check the table only has 1 column
            if (table.TableInfo.ColumnCount != 1)
            {
                throw new ApplicationException("Input table <> 1 columns.");
            }

            // Handle trivial case of no entries to select from
            if (theTable.RowCount == 0)
            {
                return(theTable);
            }

            // If 'table' is empty then we return an empty set.  ANY { empty set } is
            // always false.
            if (table.RowCount == 0)
            {
                return(theTable.EmptySelect());
            }

            // Is the lhs expression a constant?
            if (expression.IsConstant())
            {
                // We know lhs is a constant so no point passing arguments,
                DataObject value = expression.Evaluate(null, context);
                // Select from the table.
                IEnumerable <long> list = table.SelectRows(0, op, value);
                if (list.Any())
                {
                    // There's some entries so return the whole table,
                    return(theTable);
                }

                // No entries matches so return an empty table.
                return(theTable.EmptySelect());
            }

            Table sourceTable;
            int   lhsColIndex;
            // Is the lhs expression a single variable?
            ObjectName expVar = expression.AsVariable();

            // NOTE: It'll be less common for this part to be called.
            if (expVar == null)
            {
                // This is a complex expression so make a FunctionTable as our new
                // source.
                FunctionTable funTable = new FunctionTable((Table)theTable, new Expression[] { expression }, new String[] { "1" }, context);
                sourceTable = funTable;
                lhsColIndex = 0;
            }
            else
            {
                // The expression is an easy to resolve reference in this table.
                sourceTable = (Table)theTable;
                lhsColIndex = sourceTable.FindFieldName(expVar);
                if (lhsColIndex == -1)
                {
                    throw new ApplicationException("Can't find column '" + expVar + "'.");
                }
            }

            // Check that the first column of 'table' is of a compatible type with
            // source table column (lhs_col_index).
            // ISSUE: Should we convert to the correct type via a FunctionTable?
            DataColumnInfo sourceCol = sourceTable.TableInfo[lhsColIndex];
            DataColumnInfo destCol   = table.TableInfo[0];

            if (!sourceCol.DataType.IsComparable(destCol.DataType))
            {
                throw new ApplicationException("The type of the sub-query expression " +
                                               sourceCol.DataType + " is incompatible " +
                                               "with the sub-query " + destCol.DataType +
                                               ".");
            }

            // We now have all the information to solve this query.
            // We work output as follows:
            //   For >, >= type ANY we find the lowest value in 'table' and
            //   select from 'source' all the rows that are >, >= than the
            //   lowest value.
            //   For <, <= type ANY we find the highest value in 'table' and
            //   select from 'source' all the rows that are <, <= than the
            //   highest value.
            //   For = type ANY we use same method from INHelper.
            //   For <> type ANY we iterate through 'source' only including those
            //   rows that a <> query on 'table' returns size() != 0.

            IList <long> selectRows;

            if (op.IsEquivalent(Operator.Greater) ||
                op.IsEquivalent(Operator.GreaterOrEqual))
            {
                // Select the first from the set (the lowest value),
                DataObject lowestCell = table.GetFirstCell(0);
                // Select from the source table all rows that are > or >= to the
                // lowest cell,
                selectRows = sourceTable.SelectRows(lhsColIndex, op, lowestCell).ToList();
            }
            else if (op.IsEquivalent(Operator.Smaller) ||
                     op.IsEquivalent(Operator.SmallerOrEqual))
            {
                // Select the last from the set (the highest value),
                DataObject highestCell = table.GetLastCell(0);
                // Select from the source table all rows that are < or <= to the
                // highest cell,
                selectRows = sourceTable.SelectRows(lhsColIndex, op, highestCell).ToList();
            }
            else if (op.IsEquivalent(Operator.Equal))
            {
                // Equiv. to IN
                selectRows = sourceTable.In(table, lhsColIndex, 0);
            }
            else if (op.IsEquivalent(Operator.NotEqual))
            {
                // Select the value that is the same of the entire column
                DataObject cell = table.GetSingleCell(0);
                if (cell != null)
                {
                    // All values from 'source_table' that are <> than the given cell.
                    selectRows = sourceTable.SelectRows(lhsColIndex, op, cell).ToList();
                }
                else
                {
                    // No, this means there are different values in the given set so the
                    // query evaluates to the entire table.
                    return(theTable);
                }
            }
            else
            {
                throw new ApplicationException("Don't understand operator '" + op + "' in ANY.");
            }

            // Make into a table to return.
            VirtualTable rtable = new VirtualTable((Table)theTable);

            rtable.Set((Table)theTable, selectRows);

            return(rtable);
        }
        public static ITable All(this ITable table, IQueryContext context, Expression expression, Operator op, ITable other)
        {
            // Check the table only has 1 column
            if (other.TableInfo.ColumnCount != 1)
            {
                throw new ApplicationException("Input table <> 1 columns.");
            }

            // Handle trivial case of no entries to select from
            if (table.RowCount == 0)
            {
                return(table);
            }

            var theTable = table as Table;

            if (theTable == null)
            {
                return(table);
            }

            // If 'table' is empty then we return the complete set.  ALL { empty set }
            // is always true.
            if (other.RowCount == 0)
            {
                return(table);
            }

            // Is the lhs expression a constant?
            if (expression.IsConstant())
            {
                // We know lhs is a constant so no point passing arguments,
                DataObject value = expression.Evaluate(context);
                bool       comparedToTrue;

                // The various operators
                if (op.IsEquivalent(Operator.Greater) ||
                    op.IsEquivalent(Operator.GreaterOrEqual))
                {
                    // Find the maximum value in the table
                    DataObject cell = other.GetLastCell(0);
                    comparedToTrue = CompareCells(value, cell, op);
                }
                else if (op.IsEquivalent(Operator.Smaller) ||
                         op.IsEquivalent(Operator.SmallerOrEqual))
                {
                    // Find the minimum value in the table
                    DataObject cell = other.GetFirstCell(0);
                    comparedToTrue = CompareCells(value, cell, op);
                }
                else if (op.IsEquivalent(Operator.Equal))
                {
                    // Only true if rhs is a single value
                    DataObject cell = other.GetSingleCell(0);
                    comparedToTrue = (cell != null && CompareCells(value, cell, op));
                }
                else if (op.IsEquivalent(Operator.NotEqual))
                {
                    // true only if lhs_cell is not found in column.
                    comparedToTrue = !other.ColumnContainsValue(0, value);
                }
                else
                {
                    throw new ApplicationException("Don't understand operator '" + op + "' in ALL.");
                }

                // If matched return this table
                if (comparedToTrue)
                {
                    return(table);
                }

                // No entries matches so return an empty table.
                return(table.EmptySelect());
            }

            Table sourceTable;
            int   colIndex;
            // Is the lhs expression a single variable?
            ObjectName expVar = expression.AsVariable();

            // NOTE: It'll be less common for this part to be called.
            if (expVar == null)
            {
                // This is a complex expression so make a FunctionTable as our new
                // source.
                DatabaseQueryContext dbContext = (DatabaseQueryContext)context;
                FunctionTable        funTable  = new FunctionTable((Table)table, new[] { expression }, new [] { "1" }, dbContext);
                sourceTable = funTable;
                colIndex    = 0;
            }
            else
            {
                // The expression is an easy to resolve reference in this table.
                sourceTable = (Table)table;

                colIndex = sourceTable.FindFieldName(expVar);
                if (colIndex == -1)
                {
                    throw new ApplicationException("Can't find column '" + expVar + "'.");
                }
            }

            // Check that the first column of 'table' is of a compatible type with
            // source table column (lhs_col_index).
            // ISSUE: Should we convert to the correct type via a FunctionTable?
            DataColumnInfo sourceCol = sourceTable.TableInfo[colIndex];
            DataColumnInfo destCol   = other.TableInfo[0];

            if (!sourceCol.DataType.IsComparable(destCol.DataType))
            {
                throw new ApplicationException("The type of the sub-query expression " +
                                               sourceCol.DataType + " is incompatible " +
                                               "with the sub-query " + destCol.DataType +
                                               ".");
            }

            // We now have all the information to solve this query.
            // We work output as follows:
            //   For >, >= type ALL we find the highest value in 'table' and
            //   select from 'source' all the rows that are >, >= than the
            //   highest value.
            //   For <, <= type ALL we find the lowest value in 'table' and
            //   select from 'source' all the rows that are <, <= than the
            //   lowest value.
            //   For = type ALL we see if 'table' contains a single value.  If it
            //   does we select all from 'source' that equals the value, otherwise an
            //   empty table.
            //   For <> type ALL we use the 'not in' algorithm.

            IList <long> selectList;

            if (op.IsEquivalent(Operator.Greater) ||
                op.IsEquivalent(Operator.GreaterOrEqual))
            {
                // Select the last from the set (the highest value),
                DataObject highestCell = other.GetLastCell(0);
                // Select from the source table all rows that are > or >= to the
                // highest cell,
                selectList = sourceTable.SelectRows(colIndex, op, highestCell).ToList();
            }
            else if (op.IsEquivalent(Operator.Smaller) ||
                     op.IsEquivalent(Operator.SmallerOrEqual))
            {
                // Select the first from the set (the lowest value),
                DataObject lowestCell = other.GetFirstCell(0);
                // Select from the source table all rows that are < or <= to the
                // lowest cell,
                selectList = sourceTable.SelectRows(colIndex, op, lowestCell).ToList();
            }
            else if (op.IsEquivalent(Operator.Equal))
            {
                // Select the single value from the set (if there is one).
                DataObject singleCell = other.GetSingleCell(0);
                if (singleCell != null)
                {
                    // Select all from source_table all values that = this cell
                    selectList = sourceTable.SelectRows(colIndex, op, singleCell).ToList();
                }
                else
                {
                    // No single value so return empty set (no value in LHS will equal
                    // a value in RHS).
                    return(table.EmptySelect());
                }
            }
            else if (op.IsEquivalent(Operator.NotEqual))
            {
                // Equiv. to NOT IN
                selectList = sourceTable.NotIn(other, colIndex, 0).ToList();
            }
            else
            {
                throw new ApplicationException("Don't understand operator '" + op + "' in ALL.");
            }

            // Make into a table to return.
            VirtualTable rtable = new VirtualTable(theTable);

            rtable.Set((Table)table, selectList);
            return(rtable);
        }
 public override ITable Evaluate(IQueryContext context)
 {
     var childTable = Child.Evaluate(context);
     var funTable = new FunctionTable(childTable, Functions, Names, context);
     return funTable.MergeWith(null);
 }
 public TableGroupResolver(FunctionTable table)
 {
     this.table = table;
 }
        // ---------- Convenience statics ----------
        ///<summary>
        /// Returns a FunctionTable that has a single Expression evaluated in it.
        ///</summary>
        ///<param name="context"></param>
        ///<param name="expression"></param>
        /// <remarks>
        /// The column name is 'result'.
        /// </remarks>
        ///<returns></returns>
        public static Table ResultTable(IQueryContext context, Expression expression)
        {
            Expression[] exp = new Expression[] { expression };
            string[] names = new String[] {"result"};
            Table function_table = new FunctionTable(exp, names, context);
            SubsetColumnTable result = new SubsetColumnTable(function_table);

            int[] map = new int[] {0};
            ObjectName[] vars = new[] {new ObjectName("result")};
            result.SetColumnMap(map, vars);

            return result;
        }
        // ---------- Convenience statics ----------
        ///<summary>
        /// Returns a FunctionTable that has a single Expression evaluated in it.
        ///</summary>
        ///<param name="context"></param>
        ///<param name="expression"></param>
        /// <remarks>
        /// The column name is 'result'.
        /// </remarks>
        ///<returns></returns>
        public static ITable ResultTable(IQueryContext context, Expression expression)
        {
            var exp = new Expression[] { expression };
            var names = new String[] { "result" };
            Table functionTable = new FunctionTable(exp, names, context);
            var map = new int[] { 0 };
            var vars = new ObjectName[] { new ObjectName("result") };

            return new SubsetColumnTable(functionTable, map, vars);
        }
Exemple #9
0
 public override ITable Evaluate(IQueryContext context)
 {
     ITable childTable = Child.Evaluate(context);
     var dbContext = (DatabaseQueryContext)context;
     var funTable = new FunctionTable((Table)childTable, functionList, nameList, dbContext);
     // If no columns then it is implied the whole table is the group.
     if (columns == null) {
         funTable.SetWholeTableAsGroup();
     } else {
         funTable.CreateGroupMatrix(columns);
     }
     return funTable.MergeWithReference(groupMaxColumn);
 }