예제 #1
0
        /// <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);
                }
            }
        }
예제 #2
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        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));
        }
예제 #7
0
        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));
        }
예제 #8
0
        /// <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);
 }