private void GenerateSetOperationHelper(SetOperationBase setOperation) { _relationalCommandBuilder.AppendLine("("); using (_relationalCommandBuilder.Indent()) { this.GenerateSetOperation(setOperation); } _relationalCommandBuilder.AppendLine() .Append(")") .Append(AliasSeparator) .Append(_sqlGenerationHelper.DelimitIdentifier(setOperation.Alias)); }
protected virtual void GenerateSetOperation(SetOperationBase setOperation) { string getSetOperation() => setOperation switch { ExceptExpression _ => "EXCEPT", IntersectExpression _ => "INTERSECT", UnionExpression _ => "UNION", _ => throw new InvalidOperationException("Unknown SetOperationType."), }; GenerateSetOperationOperand(setOperation, setOperation.Source1); _relationalCommandBuilder.AppendLine(); _relationalCommandBuilder.AppendLine($"{getSetOperation()}{(setOperation.IsDistinct ? "" : " ALL")}"); GenerateSetOperationOperand(setOperation, setOperation.Source2); }
protected virtual void GenerateSetOperationOperand(SetOperationBase setOperation, SelectExpression operand) { // INTERSECT has higher precedence over UNION and EXCEPT, but otherwise evaluation is left-to-right. // To preserve meaning, add parentheses whenever a set operation is nested within a different set operation. if (IsNonComposedSetOperation(operand) && operand.Tables[0].GetType() != setOperation.GetType()) { _relationalCommandBuilder.AppendLine("("); using (_relationalCommandBuilder.Indent()) { Visit(operand); } _relationalCommandBuilder.AppendLine().Append(")"); } else { Visit(operand); } }