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(); }); }
/// <summary> /// Visit a parse tree produced by <see cref="QueryParser.sel_item"/>. /// <para> /// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/> /// on <paramref name="context"/>. /// </para> /// </summary> /// <param name="context">The parse tree.</param> /// <return>The visitor result.</return> public virtual Result VisitSel_item([NotNull] QueryParser.Sel_itemContext context) { return(VisitChildren(context)); }