/// <summary> /// Adds the column to the columns collection referenced by the argument associated with the specified parameter. /// The column's name is the name of the column referenced by the argument expression or the explicit name if specified. /// The column's type is either the argument's type or the explicit type if specified. /// </summary> public static void AddReferencedColumn(List <ColumnSymbol> columns, Signature signature, string parameterName, IReadOnlyList <Expression> args, string name = null, TypeSymbol type = null) { var parameter = signature.GetParameter(parameterName); var argumentParameters = signature.GetArgumentParameters(args); var argIndex = argumentParameters.IndexOf(parameter); if (argIndex >= 0 && argIndex < args.Count) { var arg = args[argIndex]; if (arg.ReferencedSymbol is ColumnSymbol c) { if (type != null && c.Type != type) { c = new ColumnSymbol(c.Name, type); } if (name != null && c.Name != name) { c = new ColumnSymbol(name, c.Type); } columns.Add(c); } } }
public static TypeSymbol GetAnyResult(TableSymbol table, IReadOnlyList <Expression> args) { var columns = new List <ColumnSymbol>(); var doNotRepeat = new HashSet <ColumnSymbol>(GetSummarizeByColumns(args)); for (int i = 0; i < args.Count; i++) { var arg = args[i]; if (arg is StarExpression) { foreach (var c in table.Columns) { if (!doNotRepeat.Contains(c)) { columns.Add(c.WithName("any_" + c.Name)); } } } else if (arg.ReferencedSymbol is ColumnSymbol c) { columns.Add(c.WithName("any_" + c.Name)); } else { var col = new ColumnSymbol(Binding.Binder.GetExpressionResultName(arg, "column"), arg.ResultType); columns.Add(col); } } return(new TupleSymbol(columns)); }
/// <summary> /// Adds a new undeclared column to the projection list. /// The name will be changed if it conflicts with a previously added column. /// </summary> /// <param name="column">The column to add.</param> /// <param name="baseName">The base name to use when generating an alternate unique name for this column.</param> /// <param name="replace">If true, allow this column to replace any previously added column with the same name.</param> /// <param name="doNotRepeat">If true, ignore any further attempts to add this column.</param> public ColumnSymbol Add(ColumnSymbol column, string baseName = null, bool replace = false, bool doNotRepeat = false) { if (_doNotAdd.Contains(column)) { // this column is ignored when attempting to add it. return(column); } if (replace && _columnIndexMap.TryGetValue(column.Name, out var index)) { _projection[index] = column; } else { // make sure the column name is unique. var uniqueName = _uniqueNames.GetOrAddName(column.Name, baseName); if (uniqueName != column.Name) { // include knowledge of the original column before it got renamed column = column.WithName(uniqueName); } _projection.Add(column); _columnIndexMap.Add(column.Name, _projection.Count - 1); } if (doNotRepeat) { _doNotAdd.Add(column); } return(column); }
/// <summary> /// Gets the known database's <see cref="TableSymbol"/> that contains the <see cref="ColumnSymbol"/>. /// </summary> public TableSymbol GetTable(ColumnSymbol column) { if (column == null) { return(null); } if (this.reverseTableMap == null) { var map = new Dictionary <Symbol, TableSymbol>(); foreach (var table in this.Clusters.SelectMany(c => c.Databases).SelectMany(d => d.Tables)) { foreach (var col in table.Columns) { map[col] = table; } } Interlocked.CompareExchange(ref this.reverseTableMap, map, null); } this.reverseTableMap.TryGetValue(column, out var result); return(result); }
private BoundRelation BindDerivedTableReference(DerivedTableReferenceSyntax node) { // TODO: Ensure query has no ORDER BY unless TOP is also specified var query = BindQuery(node.Query); var namedQueryColumns = query.OutputColumns.Where(c => !string.IsNullOrEmpty(c.Name)); var columns = new List <ColumnSymbol>(); var valueSlotFromColumn = new Dictionary <ColumnSymbol, ValueSlot>(); foreach (var queryColumn in namedQueryColumns) { var columnSymbol = new ColumnSymbol(queryColumn.Name, queryColumn.Type); columns.Add(columnSymbol); valueSlotFromColumn.Add(columnSymbol, queryColumn.ValueSlot); } var derivedTable = new DerivedTableSymbol(columns); var valueSlotFactory = new Func <TableInstanceSymbol, ColumnSymbol, ValueSlot>((ti, c) => valueSlotFromColumn[c]); var derivedTableInstance = new TableInstanceSymbol(node.Name.ValueText, derivedTable, valueSlotFactory); var boundTableReference = new BoundDerivedTableRelation(derivedTableInstance, query.Relation); QueryState.IntroducedTables.Add(derivedTableInstance, node.Name); return(boundTableReference); }
private static TypeSymbol GetArgMinMaxResult(TableSymbol table, IReadOnlyList <Expression> args, string prefix) { var columns = new List <ColumnSymbol>(); var doNotRepeat = new HashSet <ColumnSymbol>(GetSummarizeByColumns(args)); if (args.Count > 0) { var primaryArg = args[0]; var primaryColName = Binding.Binder.GetExpressionResultName(primaryArg); for (int i = 0; i < args.Count; i++) { var arg = args[i]; if (arg is StarExpression) { foreach (var c in table.Columns) { if (!doNotRepeat.Contains(c)) { columns.Add(c); } } } else if (arg.ReferencedSymbol is ColumnSymbol c) { // don't let * repeat this column doNotRepeat.Add(c); // change identity of explicitly referenced columns so won't match same columns already in projection list columns.Add(new ColumnSymbol(c.Name, c.Type)); } else { var expName = Binding.Binder.GetExpressionResultName(arg, null); if (expName == null) { if (i == 0) { expName = prefix + "_"; } else { expName = prefix + "_" + primaryColName + "_arg" + i; } } var col = new ColumnSymbol(expName, arg.ResultType); columns.Add(col); } } } return(new TupleSymbol(columns)); }
private static TypeSymbol GetArgMinMaxDepResult(TableSymbol table, IReadOnlyList <Expression> args) { var columns = new List <ColumnSymbol>(); if (args.Count > 0) { var primaryArg = args[0]; var primaryColName = Binding.Binder.GetExpressionResultName(primaryArg); var primaryCol = new ColumnSymbol(primaryColName, primaryArg.ResultType); columns.Add(primaryCol); // determine columns in by expression var doNotRepeat = new HashSet <ColumnSymbol>(GetSummarizeByColumns(args)); for (int i = 1; i < args.Count; i++) { var arg = args[i]; if (arg is StarExpression) { foreach (var c in table.Columns) { if (c != primaryArg.ReferencedSymbol && !doNotRepeat.Contains(c)) { columns.Add(c.WithName(primaryColName + "_" + c.Name)); } } } else if (arg.ReferencedSymbol is ColumnSymbol c) { columns.Add(c.WithName(primaryColName + "_" + c.Name)); } else { var expName = Binding.Binder.GetExpressionResultName(arg, null); if (expName == null) { expName = "arg" + i; } var col = new ColumnSymbol(primaryColName + "_" + expName, arg.ResultType); columns.Add(col); } } } return(new TupleSymbol(columns)); }
/// <summary> /// Adds columns to the columns collection for each column referenced by arguments associated with the specified parameter. /// The column's name is the name of the column referenced by the argument expression. /// The column's type is either the argument's type or the explicit type if specified. /// </summary> public static void AddReferencedColumns(List <ColumnSymbol> columns, Signature signature, string parameterName, IReadOnlyList <Syntax.Expression> args, TypeSymbol type = null) { var parameter = signature.GetParameter(parameterName); signature.GetArgumentRange(parameter, args, out var start, out var length); for (int argIndex = start; argIndex >= 0 && argIndex < start + length; argIndex++) { var arg = args[argIndex]; if (arg.ReferencedSymbol is ColumnSymbol c) { if (type != null && c.Type != type) { c = new ColumnSymbol(c.Name, type); } columns.Add(c); } } }
/// <summary> /// The column is added if a column with the same name is not already declared. /// </summary> /// <param name="column">The column to declare.</param> /// <param name="diagnostics">The diagnostics list to add diagnostics to if the column's name has already been declared.</param> /// <param name="location">The syntax location used to associate with diagnostics.</param> /// <param name="replace">If true, allow this column to replace any previously added column with the same name, but not specifically declared.</param> public void Declare(ColumnSymbol column, List <Diagnostic> diagnostics, SyntaxNode location, bool replace = false) { // is this name already explicitly declared elsewhere? if (_declaredNames.Contains(column.Name)) { diagnostics.Add(DiagnosticFacts.GetDuplicateColumnDeclaration(column.Name).WithLocation(location)); return; } if (replace && _columnIndexMap.TryGetValue(column.Name, out var index)) { _projection[index] = column; _declaredNames.Add(column.Name); } else { var added = Add(column); if (added != null) { _declaredNames.Add(added.Name); } } }
/// <summary> /// True if an attempt to add the column will succeed. /// </summary> public bool CanAdd(ColumnSymbol column) { return(!_doNotAdd.Contains(column)); }
/// <summary> /// Ignore any further attempt to add this column to the projection. /// </summary> public void DoNotAdd(ColumnSymbol column) { _doNotAdd.Add(column); }