diff --git a/src/Microsoft.SqlTools.ServiceLayer/Formatter/Impl/SqlBinaryBooleanExpressionFormatter.cs b/src/Microsoft.SqlTools.ServiceLayer/Formatter/Impl/SqlBinaryBooleanExpressionFormatter.cs index d6258352..1a3ba964 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Formatter/Impl/SqlBinaryBooleanExpressionFormatter.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Formatter/Impl/SqlBinaryBooleanExpressionFormatter.cs @@ -38,12 +38,15 @@ namespace Microsoft.SqlTools.ServiceLayer.Formatter internal override void ProcessPrefixRegion(int startTokenNumber, int firstChildStartTokenNumber) { - SpaceSeparatedListFormatter.ProcessPrefixRegion(startTokenNumber, firstChildStartTokenNumber); + // Binary boolean expressions + bool allowIncrement = !(CodeObject.Parent is SqlBinaryBooleanExpression); + SpaceSeparatedListFormatter.ProcessPrefixRegion(startTokenNumber, firstChildStartTokenNumber, allowIncrement); } internal override void ProcessSuffixRegion(int lastChildEndTokenNumber, int endTokenNumber) { - SpaceSeparatedListFormatter.ProcessSuffixRegion(lastChildEndTokenNumber, endTokenNumber); + bool allowDecrement = !(CodeObject.Parent is SqlBinaryBooleanExpression); + SpaceSeparatedListFormatter.ProcessSuffixRegion(lastChildEndTokenNumber, endTokenNumber, allowDecrement); } internal override void ProcessInterChildRegion(SqlCodeObject previousChild, SqlCodeObject nextChild) diff --git a/src/Microsoft.SqlTools.ServiceLayer/Formatter/Impl/WhiteSpaceSeparatedListFormatter.cs b/src/Microsoft.SqlTools.ServiceLayer/Formatter/Impl/WhiteSpaceSeparatedListFormatter.cs index 4ac931d2..3d55f4e2 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Formatter/Impl/WhiteSpaceSeparatedListFormatter.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Formatter/Impl/WhiteSpaceSeparatedListFormatter.cs @@ -13,7 +13,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Formatter /// internal abstract class WhiteSpaceSeparatedListFormatter : ASTNodeFormatterT { - private bool IncremenetIndentLevelOnPrefixRegion { get; set; } + private bool IncrementIndentLevelOnPrefixRegion { get; set; } /// /// This constructor initalizes the and properties since the formatter's entry point @@ -25,21 +25,30 @@ namespace Microsoft.SqlTools.ServiceLayer.Formatter internal WhiteSpaceSeparatedListFormatter(FormatterVisitor visitor, SqlCodeObject codeObject, bool incrementIndentLevelOnPrefixRegion) : base(visitor, codeObject) { - IncremenetIndentLevelOnPrefixRegion = incrementIndentLevelOnPrefixRegion; + IncrementIndentLevelOnPrefixRegion = incrementIndentLevelOnPrefixRegion; } - internal override void ProcessPrefixRegion(int startTokenNumber, int firstChildStartTokenNumber) + internal void ProcessPrefixRegion(int startTokenNumber, int firstChildStartTokenNumber, bool allowIncrement) { - if (IncremenetIndentLevelOnPrefixRegion) + if (allowIncrement && IncrementIndentLevelOnPrefixRegion) { IncrementIndentLevel(); } base.ProcessPrefixRegion(startTokenNumber, firstChildStartTokenNumber); } + internal override void ProcessPrefixRegion(int startTokenNumber, int firstChildStartTokenNumber) + { + ProcessPrefixRegion(startTokenNumber, firstChildStartTokenNumber, true); + } + internal override void ProcessSuffixRegion(int lastChildEndTokenNumber, int endTokenNumber) { - if (IncremenetIndentLevelOnPrefixRegion) + ProcessSuffixRegion(lastChildEndTokenNumber, endTokenNumber, true); + } + internal void ProcessSuffixRegion(int lastChildEndTokenNumber, int endTokenNumber, bool allowDecrement) + { + if (allowDecrement && IncrementIndentLevelOnPrefixRegion) { DecrementIndentLevel(); } diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestData/TSqlFormatter/BaselineFiles/CreateProcedure_CorrectIndents.sql b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestData/TSqlFormatter/BaselineFiles/CreateProcedure_CorrectIndents.sql new file mode 100644 index 00000000..c14b8e8f --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestData/TSqlFormatter/BaselineFiles/CreateProcedure_CorrectIndents.sql @@ -0,0 +1,12 @@ +CREATE PROCEDURE au_info + @lastname varchar(40), + @firstname varchar(20) +AS +SELECT au_lname, au_fname, title, pub_name +FROM authors a INNER JOIN titleauthor ta + ON a.au_id = ta.au_id INNER JOIN titles t + ON t.title_id = ta.title_id INNER JOIN publishers p + ON t.pub_id = p.pub_id +WHERE au_fname = @firstname + AND au_lname = @lastname +GO diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestData/TSqlFormatter/BaselineFiles/SelectWithOrderBy_CorrectIndents.sql b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestData/TSqlFormatter/BaselineFiles/SelectWithOrderBy_CorrectIndents.sql new file mode 100644 index 00000000..68e42347 --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestData/TSqlFormatter/BaselineFiles/SelectWithOrderBy_CorrectIndents.sql @@ -0,0 +1,11 @@ +select * +from myTable +where ProcessDate = '20161009' + and LoanChargeoffDate is not null --charged-off loans + --and LoandChargeoffDate is null and LoanCloseDate IS NOT null + and LoanCode IN (0,1) -- open and close ended loans only + and LoanBalloonDate IS NULL -- exclude balloon loans + and LoanType = 1 -- LoanType NOT IN (10, 51, 97) -- no lines of credit + -- and LoanCreditScore > 0 + and LoanTermMonths > 0 +order by AddrChanged diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestData/TSqlFormatter/TestFiles/SelectWithOrderBy.sql b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestData/TSqlFormatter/TestFiles/SelectWithOrderBy.sql new file mode 100644 index 00000000..d37054ce --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.Test.Common/TestData/TSqlFormatter/TestFiles/SelectWithOrderBy.sql @@ -0,0 +1,10 @@ +select * from myTable +where ProcessDate = '20161009' +and LoanChargeoffDate is not null --charged-off loans +--and LoandChargeoffDate is null and LoanCloseDate IS NOT null +and LoanCode IN (0,1) -- open and close ended loans only +and LoanBalloonDate IS NULL -- exclude balloon loans +and LoanType = 1 -- LoanType NOT IN (10, 51, 97) -- no lines of credit +-- and LoanCreditScore > 0 +and LoanTermMonths > 0 +order by AddrChanged diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Formatter/GeneralFormatterTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Formatter/GeneralFormatterTests.cs index a310a2b9..a28c6133 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.Test/Formatter/GeneralFormatterTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Formatter/GeneralFormatterTests.cs @@ -19,6 +19,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Formatter new FormatOptions() { KeywordCasing = CasingOptions.Uppercase }, verifyFormat: true); } + [Fact] public void KeywordCaseConversionLowercase() { @@ -28,5 +29,25 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Formatter new FormatOptions() { KeywordCasing = CasingOptions.Lowercase }, verifyFormat: true); } + + [Fact] + public void SelectWithOrderByShouldCorrectlyIndent() + { + LoadAndFormatAndCompare("SelectWithOrderByShouldCorrectlyIndent", + GetInputFile("SelectWithOrderBy.sql"), + GetBaselineFile("SelectWithOrderBy_CorrectIndents.sql"), + new FormatOptions(), + verifyFormat: true); + } + + [Fact] + public void SelectStatementShouldCorrectlyIndent() + { + LoadAndFormatAndCompare("SelectStatementShouldCorrectlyIndent", + GetInputFile("CreateProcedure.sql"), + GetBaselineFile("CreateProcedure_CorrectIndents.sql"), + new FormatOptions(), + verifyFormat: true); + } } }