/// <summary> /// Visits a <see cref="FieldReferenceSqlExpression"/> expression. /// </summary> /// <param name="node"> /// The node. /// </param> /// <returns> /// The node, or a new version of the node. /// </returns> protected internal override Node VisitFieldReferenceSqlExpression(FieldReferenceSqlExpression node) { var replacer = this.Data.GetFieldReplacer(node); if (replacer != null) { return(this.Visit(replacer)); } this.Data.SetType(node, new TypeDescriptor(typeof(object))); this.Data.SetScope(node, this.Scope.IsGroupByExpression(node) ? NodeScope.Group : NodeScope.Row); if (node.Source == null) { this.AddError(node, $"Field {node.Name} must have a source."); return(node); } var source = this.Scope.GetSource(node.Source); if (source == null) { this.AddError(node, $"Source {node.Source} is referenced before it is declared."); } this.Data.Set(node, "Source", source); return(node); }
/// <summary> /// Checks if the node is a grouped node, and adds it to the list of grouped nodes if so. /// </summary> /// <typeparam name="T"> /// The type of the node. /// </typeparam> /// <param name="node"> /// The node. /// </param> /// <param name="baseCall"> /// The method to call when the expression is not a grouped node. /// </param> /// <returns> /// The node or the result of the <paramref name="baseCall"/>. /// </returns> private Node CheckForGroups <T>(T node, Func <T, Node> baseCall) where T : SqlExpressionBase { var isGrouping = this.select.Groupings.Contains(node); if ((this.data.GetScope(node) == NodeScope.Row) || isGrouping) { if (this.groupedNodes.IndexOf(node) == -1) { this.groupedNodes.Add(node); } var field = new FieldReferenceSqlExpression($"group{this.groupedNodes.IndexOf(node)}"); if (!isGrouping || this.visitingGroupings > 0) { return(field); } var fields = new List <SqlExpressionBase> { field, }; var result = new FunctionCallSqlExpression("$GROUP_FIRST", new ReadOnlyCollection <SqlExpressionBase>(fields)); this.data.MarkAsGroupFunction(result); this.data.SetScope(node, NodeScope.Group); this.data.SetFunction(result, new FunctionDescriptor(result.Name, false, (Expression <Func <IAsyncEnumerable <object>, Task <object> > >)(objs => objs.FirstAsync()))); return(result); } if (this.data.GetScope(node) == NodeScope.Group && node is FunctionCallSqlExpression) { this.visitingGroupings++; } var nodeResult = baseCall(node); if (this.data.GetScope(node) == NodeScope.Group && node is FunctionCallSqlExpression) { this.visitingGroupings--; } if (!ReferenceEquals(node, nodeResult)) { this.data.CopyValues(node, nodeResult); } return(nodeResult); }
/// <summary> /// Visits a <see cref="FieldReferenceSqlExpression"/> expression. /// </summary> /// <param name="node"> /// The node. /// </param> /// <returns> /// The node, or a new version of the node. /// </returns> protected internal virtual Node VisitFieldReferenceSqlExpression([NotNull] FieldReferenceSqlExpression node) { return(node.VisitChildren(this)); }
/// <summary> /// Visits a <see cref="FieldReferenceSqlExpression"/> expression. /// </summary> /// <param name="node"> /// The node. /// </param> /// <returns> /// The node, or a new version of the node. /// </returns> protected internal override Node VisitFieldReferenceSqlExpression(FieldReferenceSqlExpression node) { return(this.CheckForGroups(node, n => base.VisitFieldReferenceSqlExpression(n))); }
protected internal override Node VisitFieldReferenceSqlExpression([NotNull] FieldReferenceSqlExpression node) { this.Builder.Append(node.Source == null ? $"[{node.Name}]" : $"[{node.Source}].[{node.Name}]"); return(node); }
/// <summary> /// Visits a <see cref="FieldReferenceSqlExpression"/> expression. /// </summary> /// <param name="node"> /// The node. /// </param> /// <returns> /// The node, or a new version of the node. /// </returns> protected internal override Node VisitFieldReferenceSqlExpression(FieldReferenceSqlExpression node) { return(this.VisitImplementation(node) ?? base.VisitFieldReferenceSqlExpression(node)); }
/// <summary> /// Sets the expression that will replace a <see cref="FieldReferenceSqlExpression"/> in an ORDER BY clause. /// </summary> /// <param name="dataProvider"> /// The data provider. /// </param> /// <param name="field"> /// The field. /// </param> /// <param name="expression"> /// The expression. /// </param> public static void SetFieldReplacer([NotNull] this INodeDataProvider dataProvider, FieldReferenceSqlExpression field, SqlExpressionBase expression) { dataProvider.Set(field, "FieldReplacer", expression); }
public static SqlExpressionBase GetFieldReplacer([NotNull] this INodeDataProvider dataProvider, FieldReferenceSqlExpression field) { return(dataProvider.TryGet(field, "FieldReplacer", out SqlExpressionBase result) ? result : null); }