private void CreateProjectionColumns()

in src/Kusto.Language/Binder/Binder.cs [4525:4825]


        private void CreateProjectionColumns(
            Expression expression,
            ProjectionBuilder builder,
            List<Diagnostic> diagnostics,
            ProjectionStyle style = ProjectionStyle.Default,
            bool doNotRepeat = false,
            TypeSymbol columnType = null,
            string columnName = null)
        {
            ColumnSymbol col;
            TypeSymbol type;

            // look through ordered expressions to find column references
            var oe = expression as OrderedExpression;
            if (oe != null)
            {
                expression = oe.Expression;
            }

            if (style == ProjectionStyle.Rename)
            {
                switch (expression)
                {
                    case SimpleNamedExpression n:
                        if (GetReferencedSymbol(n.Expression) is ColumnSymbol cs)
                        {
                            col = builder.Rename(cs.Name, n.Name.SimpleName, diagnostics, n.Name);
                            if (col != null)
                            {
                                SetSemanticInfo(n.Name, CreateSemanticInfo(col));
                            }
                        }
                        else
                        {
                            diagnostics.Add(DiagnosticFacts.GetColumnExpected().WithLocation(n.Expression));
                        }
                        break;

                    default:
                        diagnostics.Add(DiagnosticFacts.GetRenameAssignmentExpected().WithLocation(expression));
                        break;
                }
            }
            else
            {
                switch (expression)
                {
                    case SimpleNamedExpression n:
                        {
                            // single name assigned from multi-value tuple just assigns the first value. equivalant to (name) = tuple
                            if (n.Expression.RawResultType is TupleSymbol tu)
                            {
                                // first column has declared name so it uses declared name add/replace rule
                                col = new ColumnSymbol(n.Name.SimpleName, columnType ?? tu.Columns[0].Type);
                                builder.Declare(col, diagnostics, n.Name, replace: true);
                                SetSemanticInfo(n.Name, CreateSemanticInfo(col));

                                if (doNotRepeat)
                                {
                                    builder.DoNotAdd(tu.Columns[0]);
                                }

                                // don't add unnamed tuple columns if print style
                                if (style == ProjectionStyle.Print)
                                    break;

                                // all other columns are not declared, so they must be unique
                                for (int i = 1; i < tu.Members.Count; i++)
                                {
                                    if (GetReferencedSymbol(n.Expression) is FunctionSymbol fs1)
                                    {
                                        AddFunctionTupleResultColumn(fs1, tu.Columns[i], builder, doNotRepeat, style == ProjectionStyle.Summarize);
                                    }
                                    else
                                    {
                                        builder.Add(tu.Columns[i], doNotRepeat: doNotRepeat);
                                    }
                                }
                            }
                            else if (n.Expression.ReferencedSymbol is ColumnSymbol c)
                            {
                                col = new ColumnSymbol(n.Name.SimpleName, columnType ?? c.Type);
                                builder.Declare(col, diagnostics, n.Name, replace: true);
                                SetSemanticInfo(n.Name, CreateSemanticInfo(col));

                                if (doNotRepeat)
                                {
                                    builder.DoNotAdd(c);
                                }
                            }
                            else
                            {
                                col = new ColumnSymbol(n.Name.SimpleName, columnType ?? GetResultTypeOrError(n.Expression));
                                builder.Declare(col, diagnostics, n.Name, replace: style == ProjectionStyle.Replace || style == ProjectionStyle.Extend);
                                SetSemanticInfo(n.Name, CreateSemanticInfo(col));
                            }
                        }
                        break;

                    case CompoundNamedExpression cn:
                        {
                            if (cn.Expression.RawResultType is TupleSymbol tupleType)
                            {
                                for (int i = 0; i < tupleType.Columns.Count; i++)
                                {
                                    col = tupleType.Columns[i];
                                    type = columnType ?? col.Type;

                                    // if element has name declaration then use name declaration rule
                                    if (i < cn.Names.Names.Count)
                                    {
                                        var nameDecl = cn.Names.Names[i].Element;
                                        var name = nameDecl.SimpleName;
                                        col = new ColumnSymbol(name, type);

                                        builder.Declare(col, diagnostics, nameDecl, replace: style == ProjectionStyle.Replace || style == ProjectionStyle.Extend);
                                        SetSemanticInfo(nameDecl, CreateSemanticInfo(col));

                                        if (doNotRepeat)
                                        {
                                            builder.DoNotAdd(tupleType.Columns[i]);
                                        }
                                    }
                                    else if (style != ProjectionStyle.Print)
                                    {
                                        if (GetReferencedSymbol(cn.Expression) is FunctionSymbol fs1)
                                        {
                                            AddFunctionTupleResultColumn(fs1, col, builder, doNotRepeat, style == ProjectionStyle.Summarize);
                                        }
                                        else
                                        {
                                            // not-declared so make unique column
                                            builder.Add(col, replace: style == ProjectionStyle.Replace || style == ProjectionStyle.Extend, doNotRepeat: doNotRepeat);
                                        }
                                    }
                                }

                                // any additional names without matching tuple members gets a diagnostic
                                for (int i = tupleType.Members.Count; i < cn.Names.Names.Count; i++)
                                {
                                    var nameDecl = cn.Names.Names[i];
                                    diagnostics.Add(DiagnosticFacts.GetTheNameDoesNotHaveCorrespondingExpression().WithLocation(nameDecl));
                                }
                            }
                            else if (cn.Names.Names.Count == 1)
                            {
                                var expr = cn.Expression;
                                var name = cn.Names.Names[0].Element;
                                if (expr.ReferencedSymbol is ColumnSymbol c)
                                {
                                    col = new ColumnSymbol(name.SimpleName, columnType ?? c.Type);
                                    builder.Declare(col, diagnostics, name, replace: true);
                                    SetSemanticInfo(name, CreateSemanticInfo(col));

                                    if (doNotRepeat)
                                    {
                                        builder.DoNotAdd(c);
                                    }
                                }
                                else
                                {
                                    col = new ColumnSymbol(name.SimpleName, columnType ?? GetResultTypeOrError(cn.Expression));
                                    builder.Declare(col, diagnostics, name, replace: style == ProjectionStyle.Replace || style == ProjectionStyle.Extend);
                                    SetSemanticInfo(name, CreateSemanticInfo(col));
                                }
                            }
                            else
                            {
                                diagnostics.Add(DiagnosticFacts.GetTheExpressionDoesNotHaveMultipleValues().WithLocation(cn.Names));
                            }
                        }
                        break;

                    case FunctionCallExpression f:
                        // check for trivial case of no-op conversion operator
                        col = GetResultColumn(f);
                        if (col != null)
                        {
                            // if the expression is a column reference, then consider it a declaration
                            builder.Declare(col.WithType(columnType ?? col.Type), diagnostics, expression, replace: style == ProjectionStyle.Replace);

                            if (doNotRepeat)
                            {
                                builder.DoNotAdd(col);
                            }
                        }
                        else
                        {
                            var ftype = f.RawResultType ?? ErrorSymbol.Instance;
                            var ts = ftype as TupleSymbol;

                            if (style == ProjectionStyle.Print
                                && columnName != null
                                && (ts == null || ts.Columns.Count == 1))
                            {
                                if (ts != null && ts.Columns.Count == 1)
                                    ftype = ts.Columns[0].Type;

                                col = new ColumnSymbol(columnName, columnType ?? ftype);
                                builder.Add(col, columnName, replace: false);
                            }
                            else if (ts != null && GetReferencedSymbol(f) is FunctionSymbol fs)
                            {
                                foreach (ColumnSymbol c in ts.Members)
                                {
                                    AddFunctionTupleResultColumn(fs, c, builder, doNotRepeat, style == ProjectionStyle.Summarize);
                                }
                            }
                            else
                            {
                                var name = GetFunctionResultName(f, null, _rowScope);
                                col = new ColumnSymbol(name ?? columnName ?? "Column1", columnType ?? ftype);
                                builder.Add(col, name ?? "Column", replace: style == ProjectionStyle.Replace || style == ProjectionStyle.Extend);
                            }
                        }
                        break;

                    case StarExpression s:
                        foreach (ColumnSymbol c in GetDeclaredAndInferredColumns(RowScopeOrEmpty))
                        {
                            builder.Add(c, replace: true, doNotRepeat: doNotRepeat);
                        }
                        break;

                    default:
                        var rs = GetReferencedSymbol(expression);
                        col = GetResultColumn(expression);
                        if (col != null)
                        {
                            // if the expression is a column reference, then consider it a declaration
                            builder.Declare(col.WithType(columnType ?? col.Type), diagnostics, expression, replace: style == ProjectionStyle.Replace);

                            if (doNotRepeat)
                            {
                                builder.DoNotAdd(col);
                            }
                        }
                        else if (rs is GroupSymbol group && style == ProjectionStyle.Reorder)
                        {
                            var members = s_symbolListPool.AllocateFromPool();
                            try
                            {
                                if (oe != null && oe.Ordering != null)
                                {
                                    if (oe.Ordering.AscOrDescKeyword.Kind == SyntaxKind.DescKeyword)
                                    {
                                        members.AddRange(group.Members.OrderByDescending(m => m.Name));
                                    }
                                    else
                                    {
                                        members.AddRange(group.Members.OrderBy(m => m.Name));
                                    }
                                }
                                else
                                {
                                    members.AddRange(group.Members);
                                }

                                // add any columns referenced in group
                                foreach (var m in members)
                                {
                                    if (m is ColumnSymbol c)
                                    {
                                        builder.Add(c, doNotRepeat: true);
                                    }
                                }
                            }
                            finally
                            {
                                s_symbolListPool.ReturnToPool(members);
                            }
                        }
                        else if (GetResultType(expression) is GroupSymbol g)
                        {
                            diagnostics.Add(DiagnosticFacts.GetTheExpressionRefersToMoreThanOneColumn().WithLocation(expression));
                        }
                        else
                        {
                            type = GetResultTypeOrError(expression);
                            if (!type.IsError && !type.IsScalar)
                            {
                                diagnostics.Add(DiagnosticFacts.GetScalarTypeExpected().WithLocation(expression));
                                type = ScalarTypes.Unknown;
                            }
                            
                            if (style == ProjectionStyle.Print && columnName != null)
                            {
                                col = new ColumnSymbol(columnName, columnType ?? type);
                                builder.Add(col, columnName, replace: false);
                            }
                            else
                            {
                                var name = GetExpressionResultName(expression, null);
                                col = new ColumnSymbol(name ?? columnName ?? "Column1", columnType ?? type);
                                builder.Add(col, name ?? "Column", replace: style == ProjectionStyle.Replace || style == ProjectionStyle.Extend);
                            }
                        }
                        break;
                }
            }
        }