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)); }
public SumAggregator(IXColumn sumOverColumn) { _sumColumn = sumOverColumn; _sumCurrentGetter = sumOverColumn.CurrentGetter(); ColumnDetails = new ColumnDetails($"{sumOverColumn.ColumnDetails.Name}.Sum", typeof(long)); }
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)); }
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)); }
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)); }
/// <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); }
public void SetCurrentSourceIndex(int index) { IXColumn source = _sources[index]; if (_isSubscribed && source != null) { _currentGetter = source.CurrentGetter(); } }
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])); } }
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; }
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))); }
public static bool IsNullConstant(this IXColumn column) { if (!column.IsConstantColumn()) { return(false); } XArray value = column.ValuesGetter()(); return(value.HasNulls && value.NullRows[value.Index(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))); }
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) )); }
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)); }
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))); }
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 )); }
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)); }
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); }
public void SetCurrentSourceIndex(int index) { if (index < _sources.Count) { IXColumn source = _sources[index]; if (_isSubscribed) { _currentGetter = source?.CurrentGetter() ?? null; } } else { _currentGetter = null; } }
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; } }
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)); }
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)); }
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)); }
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; } }
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); }