/// <summary> /// Format any sub queries that need to appear in the where/on clause. /// </summary> internal void RenderSubqueryChildren(ConjunctionTracker conjunctions, SqlBuilderContext sb) { foreach (SqlTable child in SubqueryChildren) { conjunctions.RenderSql(sb); if (child.JoinHint == JoinHint.NotExists) { sb.Append("not "); } sb.Append("exists ("); sb.Indent( ); sb.AppendOnNewLine("select 1"); var fromClause = new SqlFromClause { RootTable = child }; fromClause.RenderSql(sb); sb.AddJoinCondition(child, this, child.JoinColumn, child.ForeignColumn); child.RenderTableConditions("where", false, sb); sb.EndIndent( ); sb.AppendOnNewLine(")"); } }
/// <summary> /// Renders any additional conditions that apply to this specific table. /// </summary> /// <param name="conjunctions">Tracks where/on/and keywords. Call MUST ensure FinishSql gets called.</param> /// <param name="sb">The SQL builder.</param> internal void RenderTableConditions(ConjunctionTracker conjunctions, SqlBuilderContext sb) { // Conditions foreach (string condition in FullJoinConditions.Concat(Conditions)) { conjunctions.RenderSql(sb); string conditionSql = condition.Replace("$", TableAlias); sb.Append(conditionSql); } RenderSubqueryChildren(conjunctions, sb); }
/// <summary> /// Renders any additional conditions that apply to this specific table. /// </summary> /// <param name="sqlClause">The SQL clause used to render conditions ('on' or 'where').</param> /// <param name="inline"></param> /// <param name="sb">The SQL builder.</param> internal void RenderTableConditions(string sqlClause, bool inline, SqlBuilderContext sb) { var conjunction = new ConjunctionTracker(sqlClause, "and", inline); RenderTableConditions(conjunction, sb); // Ensure that there is at least some clause if (sqlClause == "on" && !conjunction.AnyRendered) { conjunction.RenderSql(sb); sb.Append("1=1"); } conjunction.FinishSql(sb); }
/// <summary> /// Writes the SQL having clause. /// </summary> public void RenderSql(SqlBuilderContext sb, SqlQuery query) { var conjunctions = new ConjunctionTracker("where", "and", false); // Render individual table conditions that want to be moved to the query // This will include the root table foreach (SqlTable table in query.FromClause.ConstrainInWhereClause) { table.PrepareTableConditions( ); table.RenderTableConditions(conjunctions, sb); } // Render query-level conditions foreach (SqlExpression condition in Conditions) { conjunctions.RenderSql(sb); sb.Append(condition.Sql); } conjunctions.FinishSql(sb); }