EFIngresProvider/SqlGen/SqlGenerator/SqlGeneratorCommonVisitors.cs
/// <summary>
/// <see cref="AddDefaultColumns"/>
/// Add the column names from the referenced extent/join to the
/// select statement.
///
/// If the symbol is a JoinSymbol, we recursively visit all the extents,
/// halting at real extents and JoinSymbols that have an associated SqlSelectStatement.
///
/// The column names for a real extent can be derived from its type.
/// The column names for a Join Select statement can be got from the
/// list of columns that was created when the Join's select statement
/// was created.
///
/// We do the following for each column.
/// <list type="number">
/// <item>Add the SQL string for each column to the SELECT clause</item>
/// <item>Add the column to the list of columns - so that it can
/// become part of the "type" of a JoinSymbol</item>
/// <item>Check if the column name collides with a previous column added
/// to the same select statement.  Flag both the columns for renaming if true.</item>
/// <item>Add the column to a name lookup dictionary for collision detection.</item>
/// </list>
/// </summary>
/// <param name="selectStatement">The select statement that started off as SELECT *</param>
/// <param name="symbol">The symbol containing the type information for
/// the columns to be added.</param>
/// <param name="columnList">Columns that have been added to the Select statement.
/// This is created in <see cref="AddDefaultColumns"/>.</param>
/// <param name="columnDictionary">A dictionary of the columns above.</param>
Add the column names from the referenced extent/join to the
select statement.

If the symbol is a JoinSymbol, we recursively visit all the extents,
halting at real extents and JoinSymbols that have an associated SqlSelectStatement.

The column names for a real extent can be derived from its type.
The column names for a Join Select statement can be got from the
list of columns that was created when the Join's select statement
was created.

We do the following for each column.
Add the SQL string for each column to the SELECT clauseAdd the column to the list of columns - so that it can
become part of the "type" of a JoinSymbolCheck if the column name collides with a previous column added
to the same select statement.  Flag both the columns for renaming if true.Add the column to a name lookup dictionary for collision detection.
Add the column names from the referenced extent / join to the select statement . If the symbol is a JoinSymbol we recursively visit all the extents halting at real extents and JoinSymbols that have an associated SqlSelectStatement . The column names for a real extent can be derived from its type . The column names for a Join Select statement can be got from the list of columns that was created when the Join ' s select statement was created . We do the following for each column . Add the SQL string for each column to the SELECT clauseAdd the column to the list of columns - so that it can become part of the " type " of a JoinSymbolCheck if the column name collides with a previous column added to the same select statement . Flag both the columns for renaming if true . Add the column to a name lookup dictionary for collision detection .
private void AddColumns(SqlSelectStatement selectStatement, Symbol symbol, List<Symbol> columnList, Dictionary<string, Symbol> columnDictionary)
        {
            var joinSymbol = symbol as JoinSymbol;
            if (joinSymbol != null)
            {
                if (!joinSymbol.IsNestedJoin)
                {
                    foreach (Symbol sym in joinSymbol.ExtentList)
                    {
                        if ((sym.Type == null) || MetadataHelpers.IsPrimitiveType(sym.Type.EdmType))
                        {
                            continue;
                        }
                        AddColumns(selectStatement, sym, columnList, columnDictionary);
                    }
                }
                else
                {
                    foreach (Symbol joinColumn in joinSymbol.ColumnList)
                    {
                         We use the symbols for both the table and the column,
                         since they are subject to renaming.
                        selectStatement.Select.Append(new SelectColumn(joinColumn, symbol, joinColumn));
                         check for name collisions.  If there is,
                         flag both the colliding symbols.
                        if (columnDictionary.ContainsKey(joinColumn.Name))
                        {
                            columnDictionary[joinColumn.Name].NeedsRenaming = true;  the original symbol
                            joinColumn.NeedsRenaming = true;  the current symbol.
                        }
                        else
                        {
                            columnDictionary[joinColumn.Name] = joinColumn;
                        }
                        columnList.Add(joinColumn);
                    }
                }
            }
            else
            {
                 This is a non-join extent/select statement, and the CQT type has
                 the relevant column information.
                 The type could be a record type(e.g. Project(...),
                 or an entity type ( e.g. EntityExpression(...)
                 so, we check whether it is a structuralType.
                 Consider an expression of the form J(a, b=P(E))
                 The inner P(E) would have been translated to a SQL statement
                 We should not use the raw names from the type, but the equivalent
                 symbols (they are present in symbol.Columns) if they exist.
                 We add the new columns to the symbol's columns if they do
                 not already exist.
                 If the symbol represents a SqlStatement with renamed output columns,
                 we should use these instead of the rawnames and we should also mark
                 this selectStatement as one with renamed columns
                if (symbol.OutputColumnsRenamed)
                {
                    selectStatement.OutputColumnsRenamed = true;
                    selectStatement.OutputColumns = new Dictionary<string, Symbol>();
                }
                if ((symbol.Type == null) || MetadataHelpers.IsPrimitiveType(symbol.Type.EdmType))
                {
                    AddColumn(selectStatement, symbol, columnList, columnDictionary, "X");
                }
                else
                {
                    foreach (EdmProperty property in MetadataHelpers.GetProperties(symbol.Type))
                    {
                        AddColumn(selectStatement, symbol, columnList, columnDictionary, property.Name);
                    }
                }
            }
        }
private void AddColumns ( SqlSelectStatement selectStatement , Symbol symbol , List < Symbol > columnList , Dictionary < string , Symbol > columnDictionary ) { var joinSymbol = symbol as JoinSymbol ; if ( joinSymbol != null ) { if ( ! joinSymbol . IsNestedJoin ) { foreach ( Symbol sym in joinSymbol . ExtentList ) { if ( ( sym . Type == null ) || MetadataHelpers . IsPrimitiveType ( sym . Type . EdmType ) ) { continue ; } AddColumns ( selectStatement , sym , columnList , columnDictionary ) ; } } else { foreach ( Symbol joinColumn in joinSymbol . ColumnList ) { selectStatement . Select . Append ( new SelectColumn ( joinColumn , symbol , joinColumn ) ) ; if ( columnDictionary . ContainsKey ( joinColumn . Name ) ) { columnDictionary [ joinColumn . Name ] . NeedsRenaming = true ; joinColumn . NeedsRenaming = true ; } else { columnDictionary [ joinColumn . Name ] = joinColumn ; } columnList . Add ( joinColumn ) ; } } } else { if ( symbol . OutputColumnsRenamed ) { selectStatement . OutputColumnsRenamed = true ; selectStatement . OutputColumns = new Dictionary < string , Symbol > ( ) ; } if ( ( symbol . Type == null ) || MetadataHelpers . IsPrimitiveType ( symbol . Type . EdmType ) ) { AddColumn ( selectStatement , symbol , columnList , columnDictionary , " " ) ; } else { foreach ( EdmProperty property in MetadataHelpers . GetProperties ( symbol . Type ) ) { AddColumn ( selectStatement , symbol , columnList , columnDictionary , property . Name ) ; } } } }
Add the column names from the referenced extent/join to the
select statement.
Add the column names from the referenced extent / join to the select statement .
// Recurse if the join symbol is a collection of flattened extents // if sym is ScalarType means we are at base case in the // recursion and there are not columns to add, just skip // we write tableName.columnName // rather than tableName.columnName as alias // since the column name is unique (by the way we generate new column names) // // We use the symbols for both the table and the column, // since they are subject to renaming. // check for name collisions.  If there is, // flag both the colliding symbols. // the original symbol // the current symbol. // This is a non-join extent/select statement, and the CQT type has // the relevant column information. // The type could be a record type(e.g. Project(...), // or an entity type ( e.g. EntityExpression(...) // so, we check whether it is a structuralType. // Consider an expression of the form J(a, b=P(E)) // The inner P(E) would have been translated to a SQL statement // We should not use the raw names from the type, but the equivalent // symbols (they are present in symbol.Columns) if they exist. // // We add the new columns to the symbol's columns if they do // not already exist. // // If the symbol represents a SqlStatement with renamed output columns, // we should use these instead of the rawnames and we should also mark // this selectStatement as one with renamed columns
selectStatement
SqlSelectStatement
The select statement that started off as SELECT
The select statement that started off as SELECT
symbol
Symbol
The symbol containing the type information for
the columns to be added.
The symbol containing the type information for the columns to be added .
columnList
List<Symbol>
Columns that have been added to the Select statement.
This is created in .
Columns that have been added to the Select statement . This is created in .
columnDictionary
Dictionary<string, Symbol>
A dictionary of the columns above.
A dictionary of the columns above .