EFIngresProvider/SqlGen/SqlGenerator/SqlGeneratorHelpers.cs
/// <summary>
/// This is called after a relational node's input has been visited, and the
/// input's sql statement cannot be reused.  <see cref="Visit(DbProjectExpression)"/>
///
/// When the input's sql statement cannot be reused, we create a new sql
/// statement, with the old one as the from clause of the new statement.
///
/// The old statement must be completed i.e. if it has an empty select list,
/// the list of columns must be projected out.
///
/// If the old statement being completed has a join symbol as its from extent,
/// the new statement must have a clone of the join symbol as its extent.
/// We cannot reuse the old symbol, but the new select statement must behave
/// as though it is working over the "join" record.
/// </summary>
/// <param name="oldStatement"></param>
/// <param name="inputVarName"></param>
/// <param name="inputVarType"></param>
/// <param name="finalizeOldStatement"></param>
/// <param name="fromSymbol"></param>
/// <returns>A new select statement, with the old one as the from clause.</returns>
This is called after a relational node's input has been visited, and the
input's sql statement cannot be reused.

When the input's sql statement cannot be reused, we create a new sql
statement, with the old one as the from clause of the new statement.

The old statement must be completed i.e. if it has an empty select list,
the list of columns must be projected out.

If the old statement being completed has a join symbol as its from extent,
the new statement must have a clone of the join symbol as its extent.
We cannot reuse the old symbol, but the new select statement must behave
as though it is working over the "join" record.
This is called after a relational node ' s input has been visited and the input ' s sql statement cannot be reused . When the input ' s sql statement cannot be reused we create a new sql statement with the old one as the from clause of the new statement . The old statement must be completed i . e . if it has an empty select list the list of columns must be projected out . If the old statement being completed has a join symbol as its from extent the new statement must have a clone of the join symbol as its extent . We cannot reuse the old symbol but the new select statement must behave as though it is working over the " join " record .
private SqlSelectStatement CreateNewSelectStatement(SqlSelectStatement oldStatement, string inputVarName, TypeUsage inputVarType, bool finalizeOldStatement, out Symbol fromSymbol)
        {
            fromSymbol = null;
            if (finalizeOldStatement && oldStatement.Select.IsEmpty)
            {
                List<Symbol> columns = AddDefaultColumns(oldStatement);
                Debug.Assert(oldStatement.FromExtents.Count == 1);
                JoinSymbol oldJoinSymbol = oldStatement.FromExtents[0] as JoinSymbol;
                if (oldJoinSymbol != null)
                {
                    JoinSymbol newJoinSymbol = new JoinSymbol(inputVarName, inputVarType, oldJoinSymbol.ExtentList);
                    newJoinSymbol.IsNestedJoin = true;
                    newJoinSymbol.ColumnList = columns;
                    newJoinSymbol.FlattenedExtentList = oldJoinSymbol.FlattenedExtentList;
                    fromSymbol = newJoinSymbol;
                }
            }
            if (fromSymbol == null)
            {
                if (oldStatement.OutputColumnsRenamed)
                {
                    fromSymbol = new Symbol(inputVarName, inputVarType, oldStatement.OutputColumns);
                }
                else
                {
                    fromSymbol = new Symbol(inputVarName, inputVarType);
                }
            }
            SqlSelectStatement selectStatement = new SqlSelectStatement();
            selectStatement.From.Append("( ");
            selectStatement.From.Append(oldStatement);
            selectStatement.From.AppendLine();
            selectStatement.From.Append(") ");
            return selectStatement;
        }
private SqlSelectStatement CreateNewSelectStatement ( SqlSelectStatement oldStatement , string inputVarName , TypeUsage inputVarType , bool finalizeOldStatement , out Symbol fromSymbol ) { fromSymbol = null ; if ( finalizeOldStatement && oldStatement . Select . IsEmpty ) { List < Symbol > columns = AddDefaultColumns ( oldStatement ) ; Debug . Assert ( oldStatement . FromExtents . Count == 1 ) ; JoinSymbol oldJoinSymbol = oldStatement . FromExtents [ 0 ] as JoinSymbol ; if ( oldJoinSymbol != null ) { JoinSymbol newJoinSymbol = new JoinSymbol ( inputVarName , inputVarType , oldJoinSymbol . ExtentList ) ; newJoinSymbol . IsNestedJoin = true ; newJoinSymbol . ColumnList = columns ; newJoinSymbol . FlattenedExtentList = oldJoinSymbol . FlattenedExtentList ; fromSymbol = newJoinSymbol ; } } if ( fromSymbol == null ) { if ( oldStatement . OutputColumnsRenamed ) { fromSymbol = new Symbol ( inputVarName , inputVarType , oldStatement . OutputColumns ) ; } else { fromSymbol = new Symbol ( inputVarName , inputVarType ) ; } } SqlSelectStatement selectStatement = new SqlSelectStatement ( ) ; selectStatement . From . Append ( " " ) ; selectStatement . From . Append ( oldStatement ) ; selectStatement . From . AppendLine ( ) ; selectStatement . From . Append ( " " ) ; return selectStatement ; }
This is called after a relational node's input has been visited, and the
input's sql statement cannot be reused.
This is called after a relational node ' s input has been visited and the input ' s sql statement cannot be reused .
// Finalize the old statement // Thid could not have been called from a join node. // if the oldStatement has a join as its input, ... // clone the join symbol, so that we "reuse" the // join symbol.  Normally, we create a new symbol - see the next block // of code. // Note: oldStatement.FromExtents will not do, since it might // just be an alias of joinSymbol, and we want an actual JoinSymbol. // This indicates that the oldStatement is a blocking scope // i.e. it hides/renames extent columns // This is just a simple extent/SqlSelectStatement, // and we can get the column list from the type. // Observe that the following looks like the body of Visit(ExtentExpression).
A new select statement, with the old one as the from clause.
A new select statement with the old one as the from clause .
oldStatement
SqlSelectStatement
None
inputVarName
string
None
inputVarType
TypeUsage
None
finalizeOldStatement
bool
None
Symbol
out
fromSymbol
None