// check dyadic ops and compute result type void CheckDyadicType(Symbol sym, DataType datatype1, DataType datatype2, ref DataType datatype) { var joinop = sym.JoinOp; if (datatype1 is DataTypeRelation && datatype2 is DataTypeRelation) { var cols = DataColumn.Merge(Symbol.ToMergeOp(joinop), datatype1.Heading.Columns, datatype2.Heading.Columns); var dups = cols.GroupBy(c => c.Name).Where(g => g.Count() > 1).Select(g => g.Key).ToArray(); if (dups.Length > 0) { Parser.ParseError($"{sym.Name}: duplicate attribute: {dups.Join(",")}"); } datatype = DataTypeRelation.Get(DataHeading.Create(cols)); } else if (datatype1 is DataTypeTuple && datatype2 is DataTypeTuple) { var cols = DataColumn.Merge(Symbol.ToTupleOp(joinop), datatype1.Heading.Columns, datatype2.Heading.Columns); var dups = cols.GroupBy(c => c.Name).Where(g => g.Count() > 1).Select(g => g.Key).ToArray(); if (dups.Length > 0) { Parser.ParseError($"{sym.Name}: duplicate attribute: {dups.Join(",")}"); } datatype = DataTypeTuple.Get(DataHeading.Create(cols)); } else { Parser.ParseError($"{sym.Name}: expected relational or tuple arguments"); } }
public void Update(string callname, bool lift, ExpressionBlock[] atexprs) { CallName = callname; AttributeExprs = atexprs; Lift = lift; Heading = DataHeading.Create(atexprs.Select(a => DataColumn.Create(a.Name, a.DataType)).ToArray()); }
///-------------------------------------------------------------------------------------------- ///--- internal functions /// // Code node: Datatype used as return value AstCode Code(AstValue value, DataHeading lookup = null, string name = "&c", bool ascode = false, int accums = -1, bool hasord = false) { return(new AstCode { Name = name, Value = value, DataType = value.DataType, Lookup = lookup, Accums = accums, AsCode = ascode, HasWin = hasord, }); }
// get a heading type public DataHeading Headingof(IEnumerable <AstField> fields) { if (fields == null) { return(null); } var typelist = fields.Select(f => DataColumn.Create(f.Name, f.DataType)); return(DataHeading.Create(typelist, false)); }
// set current heading and add fields/components to symbol table void SetHeading(DataType datatype) { Logger.Assert(datatype != null); Logger.WriteLine(4, "Set heading {0}", datatype.Heading); _heading = datatype.Heading; foreach (var c in _heading.Columns) { Add(new Symbol { Kind = (datatype is DataTypeUser) ? SymKinds.COMPONENT : SymKinds.FIELD, DataType = c.DataType, }, c.Name); } }
// Where is just a funcall with a code predicate (that may have a fold) public AstWhere Where(string name, AstValue predicate) { var lookup = DataHeading.Create(Symbols.CurrentScope.LookupItems.Items); var code = Code(predicate, lookup, "&p", false, _accum.Total, _accum.HasWin); _accum = _accum.Push(); return(new AstWhere { Func = FindFunc(name), DataType = Types.Relof(CurrentHeading()), Arguments = Args(code), }); }
// implement allbut: remove projects, add renames, extends and other columns as projects AstField[] Allbut(DataHeading heading, AstField[] fields) { // deletions first -- remove all columns matching a project var newcols = heading.Columns.Where(c => !fields.Any(f => f is AstProject && (f as AstProject).Name == c.Name)); // changes var newfields = newcols.Select(c => { var field = fields.FirstOrDefault(f => (f is AstRename) ? (f as AstRename).OldName == c.Name : f.Name == c.Name); return(field ?? new AstProject { Name = c.Name, DataType = c.DataType }); }); // additions var newext = fields.Where(f => f is AstExtend && !newcols.Any(c => c.Name == f.Name)); return(newfields.Concat(newext).ToArray()); }
// handle generic transform rule and create specific node with all required info // each element tracks lookup items and folds public AstField Transfield(string name, string rename = null, AstValue value = null) { // Add symbols that were never referenced as variables if (rename != null) // Rename { Symbols.CurrentScope.LookupItems.Add(DataColumn.Create(rename, FindField(rename).DataType)); } else if (value == null) // Project { Symbols.CurrentScope.LookupItems.Add(DataColumn.Create(name, FindField(name).DataType)); } var lookup = DataHeading.Create(Symbols.CurrentScope.LookupItems.Items); //Symbols.CurrentScope.LookupItems.Clear(); var accums = _accum.Count; var haswin = _accum.HasWin; _accum.Reset(false); if (name == null) { return new AstLift { Name = "^", Value = value, DataType = value.DataType, Lookup = lookup, Accums = accums, HasWin = haswin, } } ; if (rename != null) { return new AstRename { Name = name, OldName = rename, DataType = FindField(rename).DataType } } ; if (value != null) { return new AstExtend { Name = name, DataType = value.DataType, Value = value, Lookup = lookup, Accums = accums, HasWin = haswin, } } ; return(new AstProject { Name = name, DataType = FindField(name).DataType }); }
public static TransformInfo Create(ExpressionBlock[] ebs, List <OrderInfo> orderinfo, DataHeading heading) { return(new TransformInfo { Restrict = ebs, AttributeExprs = new ExpressionBlock[0], OrderInfo = orderinfo, Heading = heading, }); }
// Create an expression block with a specified name (specially for fields) internal ExpressionBlock Expression(string name, DataHeading lookup = null) { Logger.Assert(!(IsFolded && HasFold), name); return(ExpressionBlock.Create(name, Kind, Code, DataType, AccumCount, lookup)); }
// Create an expression block using the symbol as name internal ExpressionBlock Expression(DataHeading lookup = null, bool lazy = false) { Logger.Assert(!(IsFolded && HasFold), Name); return(ExpressionBlock.Create(Name, Kind, Code, DataType, AccumCount, lookup ?? GetLookup(), lazy)); }
internal DataHeading GetLookup() { return((LookupItems == null) ? null : DataHeading.Create(LookupItems, false)); // preserve order }
internal DataType Relof(DataHeading heading) { return(DataTypeRelation.Get(heading)); }
internal DataType Tupof(DataHeading heading) { return(DataTypeTuple.Get(heading)); }
internal DataType Find(IEnumerable <DataColumn> columns) { return(DataTypeRelation.Get(DataHeading.Create(columns))); }