Esempio n. 1
0
        public IXTable Build(IXTable source, XDatabaseContext context)
        {
            List <IXColumn>    groupByColumns = new List <IXColumn>();
            List <IAggregator> aggregators    = new List <IAggregator>();

            // Parse GroupBy columns
            do
            {
                IXColumn column = context.Parser.NextColumn(source, context);
                if (column.IsConstantColumn())
                {
                    throw new ArgumentException("GroupBy can't aggregate across a constant.");
                }

                groupByColumns.Add(column);
            } while (context.Parser.HasAnotherPart && !context.Parser.NextTokenText.Equals("with", StringComparison.OrdinalIgnoreCase));


            // If 'GET', parse Aggregators
            if (context.Parser.HasAnotherPart)
            {
                context.Parser.NextSingleKeyword("with");

                do
                {
                    aggregators.Add(context.Parser.NextAggregator(source, context));
                } while (context.Parser.HasAnotherPart);
            }

            return(new GroupBy(source, groupByColumns, aggregators));
        }
Esempio n. 2
0
        public SumAggregator(IXColumn sumOverColumn)
        {
            _sumColumn        = sumOverColumn;
            _sumCurrentGetter = sumOverColumn.CurrentGetter();

            ColumnDetails = new ColumnDetails($"{sumOverColumn.ColumnDetails.Name}.Sum", typeof(long));
        }
Esempio n. 3
0
        public IXColumn Build(IXTable source, XDatabaseContext context)
        {
            // Column and ToType are required
            IXColumn column = context.Parser.NextColumn(source, context);
            Type     toType = context.Parser.NextType();

            // ErrorOn, DefaultValue, and ChangeToDefaultOn are optional
            ValueKinds errorOn           = ValueKindsDefaults.ErrorOn;
            object     defaultValue      = null;
            ValueKinds changeToDefaultOn = ValueKindsDefaults.ChangeToDefault;

            if (context.Parser.HasAnotherArgument)
            {
                // Parse ErrorOn if there's another argument
                errorOn = context.Parser.NextEnum <ValueKinds>();

                // If there's another argument, both of the last two are required
                if (context.Parser.HasAnotherArgument)
                {
                    defaultValue      = context.Parser.NextLiteralValue();
                    changeToDefaultOn = context.Parser.NextEnum <ValueKinds>();
                }
            }

            return(CastedColumn.Build(source, column, toType, errorOn, defaultValue, changeToDefaultOn));
        }
Esempio n. 4
0
        public IXColumn Build(IXTable source, XDatabaseContext context)
        {
            IXColumn        left     = CastedColumn.Build(source, context.Parser.NextColumn(source, context), typeof(long));
            IXColumn        right    = CastedColumn.Build(source, context.Parser.NextColumn(source, context), typeof(long));
            IXArrayComputer computer = new LongComputer();

            return(BlockTwoArgumentFunction.Build("Sum", ReturnType, source, left, right, computer.Add));
        }
Esempio n. 5
0
 public static IXColumn Build(IXColumn column, string newName)
 {
     if (column.ColumnDetails.Name.Equals(newName))
     {
         return(column);
     }
     return(new RenamedColumn(column, newName));
 }
 private SimpleTransformFunction(string name, IXColumn column, Func <T, U> function, Action beforeBatch = null)
 {
     _name              = name;
     _column            = column;
     _function          = function;
     _beforeBatch       = beforeBatch;
     this.ColumnDetails = column.ColumnDetails.ChangeType(typeof(U));
 }
 public static IXColumn Build(string name, IXTable source, IXColumn column, Func <T, U> function, Action beforeBatch = null)
 {
     if (column.ColumnDetails.Type != typeof(T))
     {
         throw new ArgumentException($"Function required argument of type {typeof(T).Name}, but argument was {column.ColumnDetails.Type.Name} instead.");
     }
     return(new SimpleTransformFunction <T, U>(name, column, function, beforeBatch));
 }
Esempio n. 8
0
        /// <summary>
        ///  ConvertToEnumIndexComparer takes a comparer on the values of the enum and translates it to a comparer
        ///  which can operate on the byte[] indices instead.
        /// </summary>
        /// <param name="leftColumn">EnumColumn being compared</param>
        /// <param name="currentComparer">Current Comparison function requested by TermExpression</param>
        /// <param name="rightColumn">Constant being compared against</param>
        /// <param name="source">IXTable containing comparison</param>
        /// <returns>Comparer to compare the (updated) right Constant to the EnumColumn.Indices (rather than Values)</returns>
        public static ComparerExtensions.Comparer ConvertToEnumIndexComparer(IXColumn leftColumn, ComparerExtensions.Comparer currentComparer, ref IXColumn rightColumn, IXTable source)
        {
            Func <XArray> valuesGetter = leftColumn.ValuesGetter();

            if (valuesGetter == null)
            {
                throw new ArgumentException("ConvertToEnumIndexComparer is only valid for columns implementing Values.");
            }

            // Get all distinct values from the left side
            XArray left = valuesGetter();

            // If there are no values, return none
            if (left.Count == 0)
            {
                return(None);
            }

            // Get right side and compare
            XArray    right = rightColumn.ValuesGetter()();
            BitVector set   = new BitVector(left.Count);

            currentComparer(left, right, set);

            // NOTE: When EnumColumn values are sorted, can convert comparisons to non-equality native accelerated compare.

            if (set.Count == 0)
            {
                // If there were no matches, always return none
                return(None);
            }
            else if (set.Count == left.Count)
            {
                // If everything matched, always return everything
                return(All);
            }
            else if (set.Count == 1)
            {
                // Convert the constant to the one matching index and make the comparison for index equals that
                rightColumn = new ConstantColumn(source, (byte)set.GetSingle(), typeof(byte));

                return(TypeProviderFactory.Get(typeof(byte)).TryGetComparer(CompareOperator.Equal));
            }
            else if (set.Count == left.Count - 1)
            {
                set.Not();

                // Convert the constant to the one non-matching index and make the comparison for index doesn't equal that
                rightColumn = new ConstantColumn(source, (byte)set.GetSingle(), typeof(byte));

                return(TypeProviderFactory.Get(typeof(byte)).TryGetComparer(CompareOperator.NotEqual));
            }
            else
            {
                // Otherwise, build a matcher for values in the set
                return(new SetComparer(set).Evaluate);
            }
        }
 private SimpleTwoArgumentFunction(string name, IXColumn column1, IXColumn column2, Func <T, U, V> function, Action beforeBatch = null)
 {
     _name              = name;
     _column1           = column1;
     _column2           = column2;
     _function          = function;
     _beforeBatch       = beforeBatch;
     this.ColumnDetails = new ColumnDetails(name, typeof(V));
 }
 private BlockTwoArgumentFunction(string name, Type returnType, IXColumn column1, IXColumn column2, Func <XArray, XArray, XArray> function, Action beforeBatch = null)
 {
     _name              = name;
     _column1           = column1;
     _column2           = column2;
     _function          = function;
     _beforeBatch       = beforeBatch;
     this.ColumnDetails = new ColumnDetails(name, returnType);
 }
Esempio n. 11
0
        public void SetCurrentSourceIndex(int index)
        {
            IXColumn source = _sources[index];

            if (_isSubscribed && source != null)
            {
                _currentGetter = source.CurrentGetter();
            }
        }
Esempio n. 12
0
        public Cast(IXTable source, IXColumn castedColumn) : base(source)
        {
            _sourceColumnIndex = source.Columns.IndexOfColumn(castedColumn.ColumnDetails.Name);
            _castedColumn      = castedColumn;

            _columns = new List <IXColumn>();
            for (int i = 0; i < source.Columns.Count; ++i)
            {
                _columns.Add((i == _sourceColumnIndex ? castedColumn : source.Columns[i]));
            }
        }
Esempio n. 13
0
        private CastedColumn(IXColumn column, Type targetType, ValueKinds errorOnKinds = ValueKindsDefaults.ErrorOn, object defaultValue = null, ValueKinds changeToDefaultKinds = ValueKindsDefaults.ChangeToDefault)
        {
            _column       = column;
            ColumnDetails = column.ColumnDetails.ChangeType(targetType);
            _converter    = TypeConverterFactory.GetConverter(column.ColumnDetails.Type, targetType, errorOnKinds, defaultValue, changeToDefaultKinds);

            _targetType           = targetType;
            _errorOnKinds         = errorOnKinds;
            _defaultValue         = defaultValue;
            _changeToDefaultKinds = changeToDefaultKinds;
        }
Esempio n. 14
0
        public IXColumn Build(IXTable source, XDatabaseContext context)
        {
            IXColumn value = context.Parser.NextColumn(source, context, typeof(String8));
            int      limit = context.Parser.NextInteger();

            return(SimpleTransformFunction <String8, String8> .Build(
                       Name,
                       source,
                       value,
                       (string8) => Truncate(string8, limit)));
        }
Esempio n. 15
0
        public static bool IsNullConstant(this IXColumn column)
        {
            if (!column.IsConstantColumn())
            {
                return(false);
            }

            XArray value = column.ValuesGetter()();

            return(value.HasNulls && value.NullRows[value.Index(0)]);
        }
Esempio n. 16
0
        public IXColumn Build(IXTable source, XDatabaseContext context)
        {
            IXColumn baseDateTime = context.Parser.NextColumn(source, context, typeof(DateTime));
            DatePart part         = context.Parser.NextEnum <DatePart>();
            Func <DateTime, ushort> extractMethod = DatePartMethod(part);

            return(SimpleTransformFunction <DateTime, ushort> .Build(
                       Name,
                       source,
                       baseDateTime,
                       (dateTime) => extractMethod(dateTime)));
        }
Esempio n. 17
0
        public IXColumn Build(IXTable source, XDatabaseContext context)
        {
            IXColumn baseDateTime = context.Parser.NextColumn(source, context, typeof(DateTime));
            TimeSpan offsetSpan   = context.Parser.NextTimeSpan();

            return(SimpleTransformFunction <DateTime, DateTime> .Build(
                       Name,
                       source,
                       baseDateTime,
                       (dateTime) => dateTime.Add(offsetSpan)
                       ));
        }
Esempio n. 18
0
        public IXColumn Build(IXTable source, XDatabaseContext context)
        {
            IXColumn value   = context.Parser.NextColumn(source, context, typeof(String8));
            string   prefix  = context.Parser.NextString();
            String8  prefix8 = String8.Convert(prefix, new byte[String8.GetLength(prefix)]);

            return(SimpleTransformFunction <String8, String8> .Build(
                       Name,
                       source,
                       value,
                       (string8) => AfterFirst(string8, prefix8)));
        }
 public static IXColumn Build(string name, IXTable source, IXColumn column1, IXColumn column2, Func <T, U, V> function, Action beforeBatch = null)
 {
     if (column1.ColumnDetails.Type != typeof(T))
     {
         throw new ArgumentException($"Function required first argument of type {typeof(T).Name}, but argument was {column1.ColumnDetails.Type.Name} instead.");
     }
     if (column2.ColumnDetails.Type != typeof(U))
     {
         throw new ArgumentException($"Function required second argument of type {typeof(U).Name}, but argument was {column2.ColumnDetails.Type.Name} instead.");
     }
     return(new SimpleTwoArgumentFunction <T, U, V>(name, column1, column2, function, beforeBatch));
 }
Esempio n. 20
0
        public IXColumn Build(IXTable source, XDatabaseContext context)
        {
            IXColumn text   = context.Parser.NextColumn(source, context, typeof(String8));
            string   value  = context.Parser.NextString();
            String8  value8 = String8.Convert(value, new byte[String8.GetLength(value)]);

            return(SimpleTransformFunction <String8, int> .Build(
                       Name,
                       source,
                       text,
                       (string8) => string8.IndexOf(value8)));
        }
Esempio n. 21
0
        public IXColumn Build(IXTable source, XDatabaseContext context)
        {
            IXColumn endColumn   = context.Parser.NextColumn(source, context, typeof(DateTime));
            IXColumn startColumn = context.Parser.NextColumn(source, context, typeof(DateTime));

            return(SimpleTwoArgumentFunction <DateTime, DateTime, TimeSpan> .Build(
                       Name,
                       source,
                       endColumn,
                       startColumn,
                       (end, start) => end - start
                       ));
        }
Esempio n. 22
0
        public IXTable Build(IXTable source, XDatabaseContext context)
        {
            ChooseDirection direction  = context.Parser.NextEnum <ChooseDirection>();
            IXColumn        rankColumn = context.Parser.NextColumn(source, context);

            List <IXColumn> identityColumns = new List <IXColumn>();

            do
            {
                identityColumns.Add(context.Parser.NextColumn(source, context));
            } while (context.Parser.HasAnotherPart);

            return(new Choose(source, direction, rankColumn, identityColumns));
        }
Esempio n. 23
0
        public CoalesceTransformFunction(IXTable source, XDatabaseContext context)
        {
            while (context.Parser.HasAnotherArgument)
            {
                IXColumn column = context.Parser.NextColumn(source, context);
                _columns.Add(column);
            }

            ValidateAllTypesMatch(_columns);
            IXColumn firstColumn = _columns[0];

            IndicesType   = firstColumn.IndicesType;
            ColumnDetails = new ColumnDetails(nameof(Coalesce), firstColumn.ColumnDetails.Type);
            _coalescer    = (ICoalescer)Allocator.ConstructGenericOf(typeof(Coalescer <>), firstColumn.ColumnDetails.Type);
        }
Esempio n. 24
0
 public void SetCurrentSourceIndex(int index)
 {
     if (index < _sources.Count)
     {
         IXColumn source = _sources[index];
         if (_isSubscribed)
         {
             _currentGetter = source?.CurrentGetter() ?? null;
         }
     }
     else
     {
         _currentGetter = null;
     }
 }
Esempio n. 25
0
        public Set(IXTable source, string outputColumnName, IXColumn column) : base(source)
        {
            _calculatedColumn = column;
            _columns          = new List <IXColumn>(source.Columns);

            // Determine whether we're replacing or adding a column
            if (source.Columns.TryGetIndexOfColumn(outputColumnName, out _computedColumnIndex))
            {
                _columns[_computedColumnIndex] = RenamedColumn.Build(_calculatedColumn, outputColumnName);
            }
            else
            {
                _columns.Add(RenamedColumn.Build(_calculatedColumn, outputColumnName));
                _computedColumnIndex = source.Columns.Count;
            }
        }
Esempio n. 26
0
        public IXTable Build(IXTable source, XDatabaseContext context)
        {
            List <IXColumn> columns = new List <IXColumn>();

            do
            {
                IXColumn column = context.Parser.NextColumn(source, context);
                columns.Add(column);
                if (String.IsNullOrEmpty(column.ColumnDetails.Name))
                {
                    throw new ArgumentException($"Column {columns.Count} passed to 'Column' wasn't assigned a name. Use 'AS [Name]' to assign names to every column selected.");
                }
            } while (context.Parser.HasAnotherPart);

            return(new Select(source, columns));
        }
Esempio n. 27
0
        public IXColumn Build(IXTable source, XDatabaseContext context)
        {
            IXColumn left  = context.Parser.NextColumn(source, context, typeof(float));
            IXColumn right = context.Parser.NextColumn(source, context, typeof(float));

            if (left.ColumnDetails.Type != right.ColumnDetails.Type)
            {
                throw new ArgumentException("Multiply requires two columns of the same type. Cast first if needed.");
            }

            // ISSUE: How do I make math generic?

            // TODO: If left or right is a constant, make a SimpleTransformFunction

            return(new Multiply("Multiply", left, right));
        }
Esempio n. 28
0
        public IXColumn Build(IXTable source, XDatabaseContext context)
        {
            IXColumn numerator   = context.Parser.NextColumn(source, context, typeof(float));
            IXColumn denominator = context.Parser.NextColumn(source, context, typeof(float));

            if (numerator.ColumnDetails.Type != denominator.ColumnDetails.Type)
            {
                throw new ArgumentException("Divide requires two columns of the same type. Cast first if needed.");
            }

            // ISSUE: How do I make math generic?

            // TODO: If numerator or denominator is a constant, make a SimpleTransformFunction

            return(new Divide("Divide", numerator, denominator));
        }
Esempio n. 29
0
        public Join(IXTable source, string joinFromColumn, IXTable joinToSource, string joinToColumn, string joinSidePrefix)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }

            _source       = source;
            _joinToSource = joinToSource;

            // Request the JoinFromColumn Getter
            IXColumn joinFrom = source.Columns.Find(joinFromColumn);

            _joinColumnType       = joinFrom.ColumnDetails.Type;
            _joinFromColumnGetter = joinFrom.CurrentGetter();

            // Request the JoinToColumn Reader (we'll need it cached)
            _joinToColumn = _joinToSource.Columns.Find(joinToColumn);
            Type joinToColumnType = _joinToColumn.ColumnDetails.Type;

            if (joinToColumnType != _joinColumnType)
            {
                throw new ArgumentException($"Join requires columns of matching types; join from {_joinColumnType.Name} to {joinToColumnType.Name} not supported.");
            }
            _joinToSeekGetter = _joinToColumn.SeekGetter();

            // Build a remapper for left side columns
            _sourceJoinedRowsFilter = new RowRemapper();

            // Build column wrappers
            _columns          = new IXColumn[source.Columns.Count + joinToSource.Columns.Count];
            _rightSideColumns = new SeekedColumn[joinToSource.Columns.Count];

            // Left Side columns are filtered to rows that joined (inner join)
            for (int i = 0; i < source.Columns.Count; ++i)
            {
                _columns[i] = new RemappedColumn(source.Columns[i], _sourceJoinedRowsFilter);
            }

            // Right side columns are seeked to the right side matching rows
            for (int i = 0; i < joinToSource.Columns.Count; ++i)
            {
                SeekedColumn column = new SeekedColumn(RenamedColumn.Build(joinToSource.Columns[i], joinSidePrefix + joinToSource.Columns[i].ColumnDetails.Name));
                _rightSideColumns[i] = column;
                _columns[i + source.Columns.Count] = column;
            }
        }
Esempio n. 30
0
        public string NextColumnName(IXTable source, Type requiredType = null)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            IXColumn column = null;

            ParseNextOrThrow(
                () => source.Columns.TryFind(_scanner.Current.Value, out column) &&
                (requiredType == null || column.ColumnDetails.Type == requiredType),
                "[Column]",
                TokenType.ColumnName,
                EscapedColumnList(source, requiredType));

            return(column.ColumnDetails.Name);
        }