public override Table VisitWhere_clause(QueryParser.Where_clauseContext context) { var result = new Table(_table); foreach (var row in _table) { var env = new Environment(row, _table.Columns); var value = new CondExprVisitor(_zmi, env).Visit(context.cond_expr()); if (value.HasValue && value.Val.Value.GetBoolean()) result.AppendRow(row); } return result; }
public override Maybe<QueryResult> VisitSel_item(QueryParser.Sel_itemContext context) { var distinct = context.sel_modifier()?.DISTINCT() != null; var alias = context.identifier(); var dict = new Dictionary<Attribute, List<Value>>(); foreach (var son in _zmi.Sons) { foreach (var (k, v) in son.Attributes) { if (dict.TryGetValue(k, out var l)) l.Add(v); else dict.Add(k, new List<Value> {v}); } } var (attributes, values) = _table.Columns .Where(c => !Attribute.IsQuery(c)) .Select(c => (key: c, value: _table.GetColumn(c))) .ToList() .Unzip(pair => pair.key, pair => pair.value); var env = new Environment( new TableRow(values.Select(list => list.IsNull || ((AttributeTypeCollection) list.AttributeType).ElementType == AttributeTypePrimitive.Null ? ValueNull.Instance as Value : list)), attributes, true); var result = new CondExprVisitor(_zmi, env).Visit(context.cond_expr()); return result.Bind(res => { switch (res) { case ResultSingle _: break; default: throw new ArgumentException("Could not return result which is not aggregated"); } return alias == null ? new QueryResult(res.Value).Just() : new QueryResult(new Attribute(alias.GetText()), res.Value).Just(); }); }
public override Table VisitOrder_item(QueryParser.Order_itemContext context) { int Comparer(TableRow row1, TableRow row2) { var env1 = new Environment(row1, _table.Columns); var expr1 = new CondExprVisitor(_zmi, env1).Visit(context.cond_expr()); var env2 = new Environment(row2, _table.Columns); var expr2 = new CondExprVisitor(_zmi, env2).Visit(context.cond_expr()); var result = expr1.Zip(expr2).Bind(p => { var res = new NullsVisitor(p).VisitNulls(context.nulls()); if (res == 0) return new OrderVisitor(p).VisitOrder(context.order()).Just(); return res.Just(); }); return result.Match(i => i, () => 0); } _table.Sort(Compare.By<TableRow>(Comparer)); return _table; }