Skip to content

Commit f09e0b8

Browse files
llaliUrvashi RajshivsoodLijun Ji
authored
Sync Repos: Release 170.128.0 (#173)
* Merged PR 1818918: Adding for Order Clause to JSON_ARRAYAGG # Pull Request Template for ScriptDom ## Description Please provide a detailed description, include the link to the design specification or SQL feature document for the new TSQL syntaxes. Make sure to add links to the Github or DevDiv issue Before submitting your pull request, please ensure you have completed the following: ## Code Change - [ ] The [Common checklist](https://msdata.visualstudio.com/SQLToolsAndLibraries/_git/Common?path=/Templates/PR%20Checklist%20for%20SQLToolsAndLibraries.md&version=GBmain&_a=preview) has been reviewed and followed - [ ] Code changes are accompanied by appropriate unit tests - [ ] Identified and included SMEs needed to review code changes - [ ] Follow the [steps](https://msdata.visualstudio.com/SQLToolsAndLibraries/_wiki/wikis/SQLToolsAndLibraries.wiki/33838/Adding-or-Extending-TSql-support-in-Sql-Dom?anchor=make-the-changes-in) here to make changes in the code ## Testing - [ ] Follow the [steps](https://msdata.visualstudio.com/SQLToolsAndLibraries/_wiki/wikis/SQLToolsAndLibraries.wiki/33838/Adding-or-Extending-TSql-support-in-Sql-Dom?anchor=to-extend-the-tests-do-the-following%3A) here to add new tests for your feature ## Documentation - [ ] Update relevant documentation in the [wiki](https://dev.azure.com/msdata/SQLToolsAndLibraries/_wiki/wikis/SQLToolsAndLibraries.wiki) and the README.md file ## Additional Information Please provide any additional information that might be helpful for the reviewers Adding for Order Clause to JSON_ARRAYAGG ---- #### AI description (iteration 1) #### PR Classification New feature addition to support an ORDER BY clause in JSON_ARRAYAGG. #### PR Summary This pull request adds comprehensive support for an ORDER BY clause in JSON_ARRAYAGG function calls by updating the parser grammar, AST definitions, and script generation logic, accompanied by new tests ensuring correct implementation. - In `SqlScriptDom/Parser/TSql/TSql170.g`, updated grammar rules to include an optional `OrderByClause` for JSON_ARRAYAGG. - In `SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.FunctionCall.cs`, added logic to generate the ORDER BY clause when present. - In `SqlScriptDom/Parser/TSql/Ast.xml`, appended a new member `JsonOrderByClause` to support the syntax. - Added new test scripts and baselines in `Test/SqlDom/TestScripts/JsonArrayAggOrderBy170.sql` and `Test/SqlDom/Baselines170/JsonArrayAggOrderBy170.sql` to validate the functionality. <!-- GitOpsUserAgent=GitOps.Apps.Server.pullrequestcopilot --> * Merged PR 1819059: Fix parsing 'WITH ARRAY WRAPPER' in json_query function # Pull Request Template for ScriptDom ## Description Please provide a detailed description, include the link to the design specification or SQL feature document for the new TSQL syntaxes. Make sure to add links to the Github or DevDiv issue Before submitting your pull request, please ensure you have completed the following: ## Code Change - [ ] The [Common checklist](https://msdata.visualstudio.com/SQLToolsAndLibraries/_git/Common?path=/Templates/PR%20Checklist%20for%20SQLToolsAndLibraries.md&version=GBmain&_a=preview) has been reviewed and followed - [ ] Code changes are accompanied by appropriate unit tests - [ ] Identified and included SMEs needed to review code changes - [ ] Follow the [steps](https://msdata.visualstudio.com/SQLToolsAndLibraries/_wiki/wikis/SQLToolsAndLibraries.wiki/33838/Adding-or-Extending-TSql-support-in-Sql-Dom?anchor=make-the-changes-in) here to make changes in the code ## Testing - [ ] Follow the [steps](https://msdata.visualstudio.com/SQLToolsAndLibraries/_wiki/wikis/SQLToolsAndLibraries.wiki/33838/Adding-or-Extending-TSql-support-in-Sql-Dom?anchor=to-extend-the-tests-do-the-following%3A) here to add new tests for your feature ## Documentation - [ ] Update relevant documentation in the [wiki](https://dev.azure.com/msdata/SQLToolsAndLibraries/_wiki/wikis/SQLToolsAndLibraries.wiki) and the README.md file ## Additional Information Please provide any additional information that might be helpful for the reviewers Fix parsing 'WITH ARRAY WRAPPER' in json_query function ---- #### AI description (iteration 1) #### PR Classification Bug fix addressing incorrect parsing of the JSON_QUERY function when using the WITH ARRAY WRAPPER clause. #### PR Summary This pull request corrects the token generation for the JSON_QUERY function so that the WITH ARRAY WRAPPER clause is correctly parsed inside the function's parameter list. The changes adjust the grammar, script generator, and test expectations to match the proper syntax. - `Test/SqlDom/ParserErrorsTests.cs`: Updated error tests to reflect new token positions for the WITH ARRAY WRAPPER clause. - `SqlScriptDom/Parser/TSql/TSql170.g`: Modified grammar rules to move the closing parenthesis generation after handling the WITH clause. - `SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.FunctionCall.cs`: Reordered token generation to include the WITH ARRAY WRAPPER clause within the function call parameters. - `Test/SqlDom/Baselines170/JsonFunctionTests170.sql` and `Test/SqlDom/TestScripts/JsonFunctionTests170.sql`: Updated baseline and test scripts to match the corrected function syntax. <!-- GitOpsUserAgent=GitOps.Apps.Server.pullrequestcopilot --> Related work items: #4716932 * Merged PR 1810300: Updated syntax for EM permissions tests # Pull Request Template for ScriptDom ## Description External Model Object are not schema - scoped and only database scoped. hence, tests scripts are updated accordingly. Before submitting your pull request, please ensure you have completed the following: ## Code Change - [ ] The [Common checklist](https://msdata.visualstudio.com/SQLToolsAndLibraries/_git/Common?path=/Templates/PR%20Checklist%20for%20SQLToolsAndLibraries.md&version=GBmain&_a=preview) has been reviewed and followed - [ ] Code changes are accompanied by appropriate unit tests - [ ] Identified and included SMEs needed to review code changes - [ ] Follow the [steps](https://msdata.visualstudio.com/SQLToolsAndLibraries/_wiki/wikis/SQLToolsAndLibraries.wiki/33838/Adding-or-Extending-TSql-support-in-Sql-Dom?anchor=make-the-changes-in) here to make changes in the code ## Testing - [ ] Follow the [steps](https://msdata.visualstudio.com/SQLToolsAndLibraries/_wiki/wikis/SQLToolsAndLibraries.wiki/33838/Adding-or-Extending-TSql-support-in-Sql-Dom?anchor=to-extend-the-tests-do-the-following%3A) here to add new tests for your feature ## Documentation - [ ] Update relevant documentation in the [wiki](https://dev.azure.com/msdata/SQLToolsAndLibraries/_wiki/wikis/SQLToolsAndLibraries.wiki) and the README.md file ## Additional Information Please provide any additional information that might be helpful for the reviewers Updated syntax for EM permissions ---- #### AI description (iteration 1) #### PR Classification Syntax update for external model permissions tests. #### PR Summary This pull request revises the SQL syntax in EM permissions tests by removing explicit schema prefixes from external model names, ensuring consistent and simplified permission statements. - Changes in `Test/SqlDom/Baselines170/SecurityStatementExternalModelTests170.sql`: Removed redundant schema qualifiers (e.g., `prod.`, `dbo.`, `schema1.`, `test.`) from external model object names. - Changes in `Test/SqlDom/TestScripts/SecurityStatementExternalModelTests170.sql`: Updated SQL statements to strip schema qualifiers, standardizing external model naming across the test scripts. <!-- GitOpsUserAgent=GitOps.Apps.Server.pullrequestcopilot --> * Merged PR 1818887: [JSON] ScriptDom support for json_value Returning syntax Adds support to scriptdom for RETURNING option for json_value. Specifically support for json_value('a', 'b' RETURNING <SQL Type>) Code Change - [ ] The Common checklist has been reviewed and followed - [x] Code changes are accompanied by appropriate unit tests - [x] Identified and included SMEs needed to review code changes - [x] Follow the steps here to make changes in the code Testing Follow the steps here to add new tests for your feature Test are added to respective json test file. Documentation Update relevant documentation in the wiki and the README.md file Additional Information Support by updating grammar rules, AST definitions, code generation, and tests to handle a returning clause for JSON_VALUE with typed data. - `SqlScriptDom/Parser/TSql/TSql170.g`: Revised grammar rules to replace the JSON returning clause with one that uses a DataTypeReference, added a new jsonValueReturningClause and jsonDataType rule to enforce JSON type restrictions, and integrated JSON_VALUE into the built-in function call logic. - `SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.FunctionCall.cs`: Modified the return type generation logic to work with DataTypeReference and introduced specific handling for JSON_VALUE, ensuring proper generation of the returning clause. - `SqlScriptDom/Parser/TSql/Ast.xml`: Updated the AST definition for the ReturnType member from Identifier to DataTypeReference to support the new syntax. - `Test/SqlDom`: Expanded test cases in multiple SQL test scripts to include JSON_VALUE with various returning types, validating the new syntax. * Merged PR 1823138: Add test cases for Json_contains and Json_modify # Pull Request Template for ScriptDom ## Description This PR added several test cases for Json_contains and Json_modify. These 2 Json functions don't have special syntax that needs special handling, so just added a few test cases. Before submitting your pull request, please ensure you have completed the following: ## Code Change - [ ] The [Common checklist](https://msdata.visualstudio.com/SQLToolsAndLibraries/_git/Common?path=/Templates/PR%20Checklist%20for%20SQLToolsAndLibraries.md&version=GBmain&_a=preview) has been reviewed and followed - [ ] Code changes are accompanied by appropriate unit tests - [ ] Identified and included SMEs needed to review code changes - [ ] Follow the [steps](https://msdata.visualstudio.com/SQLToolsAndLibraries/_wiki/wikis/SQLToolsAndLibraries.wiki/33838/Adding-or-Extending-TSql-support-in-Sql-Dom?anchor=make-the-changes-in) here to make changes in the code ## Testing - [ ] Follow the [steps](https://msdata.visualstudio.com/SQLToolsAndLibraries/_wiki/wikis/SQLToolsAndLibraries.wiki/33838/Adding-or-Extending-TSql-support-in-Sql-Dom?anchor=to-extend-the-tests-do-the-following%3A) here to add new tests for your feature ## Documentation - [ ] Update relevant documentation in the [wiki](https://dev.azure.com/msdata/SQLToolsAndLibraries/_wiki/wikis/SQLToolsAndLibraries.wiki) and the README.md file ## Additional Information Please provide any additional information that might be helpful for the reviewers add test cases for Json_contains and Json_modify Related work items: #4724160 * Merged PR 1824015: Adding the release notes for 170.128.0 Please provide a detailed description, include the link to the design specification or SQL feature document for the new TSQL syntaxes. Make sure to add links to the Github or DevDiv issue Before submitting your pull request, please ensure you have completed the following: - [ ] The [Common checklist](https://msdata.visualstudio.com/SQLToolsAndLibraries/_git/Common?path=/Templates/PR%20Checklist%20for%20SQLToolsAndLibraries.md&version=GBmain&_a=preview) has been reviewed and followed - [ ] Code changes are accompanied by appropriate unit tests - [ ] Identified and included SMEs needed to review code changes - [ ] Follow the [steps](https://msdata.visualstudio.com/SQLToolsAndLibraries/_wiki/wikis/SQLToolsAndLibraries.wiki/33838/Adding-or-Extending-TSql-support-in-Sql-Dom?anchor=make-the-changes-in) here to make changes in the code - [ ] Follow the [steps](https://msdata.visualstudio.com/SQLToolsAndLibraries/_wiki/wikis/SQLToolsAndLibraries.wiki/33838/Adding-or-Extending-TSql-support-in-Sql-Dom?anchor=to-extend-the-tests-do-the-following%3A) here to add new tests for your feature - [ ] Update relevant documentation in the [wiki](https://dev.azure.com/msdata/SQLToolsAndLibraries/_wiki/wikis/SQLToolsAndLibraries.wiki) and the README.md file Please provide any additional information that might be helpful for the reviewers Adding the release notes for 170.128.0 * fixing the test --------- Co-authored-by: Urvashi Raj <urvashiraj@microsoft.com> Co-authored-by: Shiv Prashant Sood <shivsood@microsoft.com> Co-authored-by: Lijun Ji <Lijun.Ji@microsoft.com>
1 parent 9addf20 commit f09e0b8

File tree

14 files changed

+409
-67
lines changed

14 files changed

+409
-67
lines changed

CONTRIBUTING.md

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,36 @@ Example: To run all priority 0 tests
106106
dotnet test --filter Priority=0
107107
```
108108

109+
#### ⚠️ CRITICAL: Full Test Suite for Parser Changes
110+
111+
**If you make ANY changes to grammar files (`.g` files) or AST definitions (`Ast.xml`), you MUST run the complete test suite** to ensure no regressions:
112+
113+
```cmd
114+
dotnet test Test/SqlDom/UTSqlScriptDom.csproj -c Debug
115+
```
116+
117+
**Why this is critical for parser changes:**
118+
- Grammar changes can have far-reaching effects on seemingly unrelated functionality
119+
- Shared grammar rules are used in multiple contexts throughout the parser
120+
- AST modifications can affect script generation and visitor patterns across the entire codebase
121+
- Token recognition changes can impact parsing of statements that don't even use the modified feature
122+
123+
**Example of unexpected failures:**
124+
- Modifying a shared rule like `identifierColumnReferenceExpression` can cause other tests to fail because the rule now accepts syntax that should be rejected in different contexts
125+
- Changes to operator precedence can affect unrelated expressions
126+
- Adding new AST members without proper script generation support can break round-trip parsing
127+
128+
Always verify that all ~557 tests pass before submitting your changes.
129+
109130
### Pull Request Process
110131

111132
Before sending a Pull Request, please do the following:
112133

113-
1. Ensure builds are still successful and tests, including any added or updated tests, pass prior to submitting the pull request.
114-
2. Update any documentation, user and contributor, that is impacted by your changes.
115-
3. Include your change description in `CHANGELOG.md` file as part of pull request.
116-
4. You may merge the pull request in once you have the sign-off of two other developers, or if you do not have permission to do that, you may request the second reviewer to merge it for you.
134+
1. **For parser changes (grammar/AST modifications): Run the complete test suite** (`dotnet test Test/SqlDom/UTSqlScriptDom.csproj -c Debug`) and ensure all ~557 tests pass. Grammar changes can have unexpected side effects.
135+
2. Ensure builds are still successful and tests, including any added or updated tests, pass prior to submitting the pull request.
136+
3. Update any documentation, user and contributor, that is impacted by your changes.
137+
4. Include your change description in `CHANGELOG.md` file as part of pull request.
138+
5. You may merge the pull request in once you have the sign-off of two other developers, or if you do not have permission to do that, you may request the second reviewer to merge it for you.
117139

118140
### Helpful notes for SQLDOM extensions
119141

SqlScriptDom/Parser/TSql/Ast.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,8 +652,9 @@
652652
<Member Name="IgnoreRespectNulls" Type="Identifier" Collection="true" Summary="The ignore nulls is used to eliminate rows with null value in the output. Optional may be null."/>
653653
<Member Name="TrimOptions" Type="Identifier" Summary="TRIM intrinsic can take optional arguments like 'Leading', 'Trailing' or 'Both'."/>
654654
<Member Name="JsonParameters" Type="JsonKeyValue" Collection="true" Summary="The Json parameters to the function."/>
655+
<Member Name="JsonOrderByClause" Type="OrderByClause" Summary="The order by clause used for JSON aggregation functions like JSON_ARRAYAGG. Optional may be null."/>
655656
<Member Name="AbsentOrNullOnNull" Type="Identifier" Collection="true" Summary="The Absent or Null on Null will convert or remove sql null to json null"/>
656-
<Member Name="ReturnType" Type="Identifier" Collection="true" Summary="Return type of function. Used by json_arrayagg, json_objectagg, json_array, json_object and json_value"/>
657+
<Member Name="ReturnType" Type="DataTypeReference" Collection="true" Summary="Return type of function. Used by json_arrayagg, json_objectagg, json_array, json_object and json_value"/>
657658
<Member Name="WithArrayWrapper" Type="bool" Summary="Indicates whether WITH ARRAY WRAPPER clause is specified for JSON_QUERY function."/>
658659
</Class>
659660
<Class Name="CallTarget" Abstract="true" Summary="Represents a target of a function call.">

SqlScriptDom/Parser/TSql/CodeGenerationSupporter.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ internal static class CodeGenerationSupporter
527527
internal const string JsonObjectAgg = "JSON_OBJECTAGG";
528528
internal const string JsonArrayAgg = "JSON_ARRAYAGG";
529529
internal const string JsonQuery = "JSON_QUERY";
530+
internal const string JsonValue = "JSON_VALUE";
530531
internal const string Array = "ARRAY";
531532
internal const string Wrapper = "WRAPPER";
532533
internal const string Keep = "KEEP";

SqlScriptDom/Parser/TSql/TSql170.g

Lines changed: 111 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32631,22 +32631,86 @@ expressionList [TSqlFragment vParent, IList<ScalarExpression> expressions]
3263132631
)
3263232632
;
3263332633

32634+
/* jsonReturningClause is used by json_object, json_objectagg, json_array, json_arrayagg where only
32635+
RETURNING JSON is supported. Any other type with JSON should return in error */
3263432636
jsonReturningClause [FunctionCall vParent]
3263532637
{
32636-
Identifier vJson;
32638+
DataTypeReference vDataType;
3263732639
}
3263832640
:
32639-
tReturning:Identifier tJson:Identifier
32641+
tReturning:Identifier vDataType=jsonDataType
3264032642
{
3264132643
Match(tReturning, CodeGenerationSupporter.Returning);
32642-
Match(tJson, CodeGenerationSupporter.Json);
32643-
UpdateTokenInfo(vParent,tJson);
32644-
vJson = FragmentFactory.CreateFragment<Identifier>();
32645-
AddAndUpdateTokenInfo(vParent, vParent.ReturnType, vJson);
32646-
vJson.SetUnquotedIdentifier(tJson.getText());
32644+
UpdateTokenInfo(vParent, tReturning);
32645+
vParent.ReturnType.Add(vDataType);
32646+
}
32647+
;
32648+
32649+
jsonDataType returns [SqlDataTypeReference vResult = null]
32650+
{
32651+
SchemaObjectName vJsonTypeName;
32652+
}
32653+
:
32654+
vJsonTypeName=schemaObjectTwoPartName
32655+
{
32656+
// Only allow JSON as the data type
32657+
if (vJsonTypeName.BaseIdentifier.Value.ToUpper(CultureInfo.InvariantCulture) != CodeGenerationSupporter.Json)
32658+
{
32659+
ThrowParseErrorException("SQL46005", vJsonTypeName,
32660+
TSqlParserResource.SQL46005Message, CodeGenerationSupporter.Json, vJsonTypeName.BaseIdentifier.Value);
32661+
}
32662+
32663+
vResult = FragmentFactory.CreateFragment<SqlDataTypeReference>();
32664+
vResult.Name = vJsonTypeName;
32665+
vResult.SqlDataTypeOption = SqlDataTypeOption.Json;
32666+
vResult.UpdateTokenInfo(vJsonTypeName);
32667+
}
32668+
;
32669+
32670+
/* jsonValueReturningClause is used by json_value. Only json_value support RETURNING <SQL-TYPE> syntax*/
32671+
jsonValueReturningClause [FunctionCall vParent]
32672+
{
32673+
DataTypeReference vDataType;
32674+
}
32675+
:
32676+
tReturning:Identifier vDataType=scalarDataType
32677+
{
32678+
Match(tReturning, CodeGenerationSupporter.Returning);
32679+
UpdateTokenInfo(vParent, tReturning);
32680+
32681+
// JSON_VALUE only supports specific SQL data types in RETURNING clause
32682+
if (vDataType is SqlDataTypeReference sqlDataType)
32683+
{
32684+
bool isAllowedType = sqlDataType.SqlDataTypeOption == SqlDataTypeOption.Int ||
32685+
sqlDataType.SqlDataTypeOption == SqlDataTypeOption.TinyInt ||
32686+
sqlDataType.SqlDataTypeOption == SqlDataTypeOption.SmallInt ||
32687+
sqlDataType.SqlDataTypeOption == SqlDataTypeOption.BigInt ||
32688+
sqlDataType.SqlDataTypeOption == SqlDataTypeOption.Float ||
32689+
sqlDataType.SqlDataTypeOption == SqlDataTypeOption.Real ||
32690+
sqlDataType.SqlDataTypeOption == SqlDataTypeOption.Decimal ||
32691+
sqlDataType.SqlDataTypeOption == SqlDataTypeOption.Numeric ||
32692+
sqlDataType.SqlDataTypeOption == SqlDataTypeOption.Bit ||
32693+
sqlDataType.SqlDataTypeOption == SqlDataTypeOption.VarChar ||
32694+
sqlDataType.SqlDataTypeOption == SqlDataTypeOption.NVarChar ||
32695+
sqlDataType.SqlDataTypeOption == SqlDataTypeOption.Char ||
32696+
sqlDataType.SqlDataTypeOption == SqlDataTypeOption.NChar ||
32697+
sqlDataType.SqlDataTypeOption == SqlDataTypeOption.Date ||
32698+
sqlDataType.SqlDataTypeOption == SqlDataTypeOption.Time ||
32699+
sqlDataType.SqlDataTypeOption == SqlDataTypeOption.DateTime2 ||
32700+
sqlDataType.SqlDataTypeOption == SqlDataTypeOption.DateTimeOffset;
32701+
32702+
if (!isAllowedType)
32703+
{
32704+
ThrowParseErrorException("SQL46005", vDataType,
32705+
TSqlParserResource.SQL46005Message, "supported data type", sqlDataType.SqlDataTypeOption.ToString());
32706+
}
32707+
}
32708+
32709+
vParent.ReturnType.Add(vDataType);
3264732710
}
3264832711
;
3264932712

32713+
3265032714
jsonKeyValueExpression returns [JsonKeyValue vResult = FragmentFactory.CreateFragment<JsonKeyValue>()]
3265132715
{
3265232716
ScalarExpression vKey;
@@ -32970,6 +33034,9 @@ builtInFunctionCall returns [FunctionCall vResult = FragmentFactory.CreateFragme
3297033034
|
3297133035
{(vResult.FunctionName != null && vResult.FunctionName.Value.ToUpper(CultureInfo.InvariantCulture) == CodeGenerationSupporter.JsonQuery)}?
3297233036
jsonQueryBuiltInFunctionCall[vResult]
33037+
|
33038+
{(vResult.FunctionName != null && vResult.FunctionName.Value.ToUpper(CultureInfo.InvariantCulture) == CodeGenerationSupporter.JsonValue)}?
33039+
jsonValueBuiltInFunctionCall[vResult]
3297333040
|
3297433041
{(vResult.FunctionName != null && vResult.FunctionName.Value.ToUpper(CultureInfo.InvariantCulture) == CodeGenerationSupporter.Trim) &&
3297533042
(NextTokenMatches(CodeGenerationSupporter.Leading) | NextTokenMatches(CodeGenerationSupporter.Trailing) | NextTokenMatches(CodeGenerationSupporter.Both))}?
@@ -33017,13 +33084,22 @@ jsonArrayBuiltInFunctionCall [FunctionCall vParent]
3301733084
jsonArrayAggBuiltInFunctionCall [FunctionCall vParent]
3301833085
{
3301933086
ScalarExpression vExpression;
33087+
OrderByClause vOrderByClause;
3302033088
}
3302133089
: (
3302233090
vExpression=expression
3302333091
{
3302433092
AddAndUpdateTokenInfo(vParent, vParent.Parameters, vExpression);
3302533093
}
3302633094
)
33095+
(
33096+
vOrderByClause=orderByClause
33097+
{
33098+
vParent.JsonOrderByClause = vOrderByClause;
33099+
}
33100+
|
33101+
/* empty */
33102+
)
3302733103
(
3302833104
jsonNullClauseFunction[vParent]
3302933105
|
@@ -33085,10 +33161,6 @@ jsonQueryBuiltInFunctionCall [FunctionCall vParent]
3308533161
AddAndUpdateTokenInfo(vParent, vParent.Parameters, vPath);
3308633162
}
3308733163
)?
33088-
tRParen:RightParenthesis
33089-
{
33090-
UpdateTokenInfo(vParent, tRParen);
33091-
}
3309233164
(
3309333165
With tArray:Identifier tWrapper:Identifier
3309433166
{
@@ -33103,6 +33175,34 @@ jsonQueryBuiltInFunctionCall [FunctionCall vParent]
3310333175
vParent.WithArrayWrapper = true;
3310433176
}
3310533177
)?
33178+
tRParen:RightParenthesis
33179+
{
33180+
UpdateTokenInfo(vParent, tRParen);
33181+
}
33182+
;
33183+
33184+
jsonValueBuiltInFunctionCall [FunctionCall vParent]
33185+
{
33186+
ScalarExpression vExpression;
33187+
ScalarExpression vPath;
33188+
}
33189+
: vExpression=expression
33190+
{
33191+
AddAndUpdateTokenInfo(vParent, vParent.Parameters, vExpression);
33192+
}
33193+
Comma vPath=expression
33194+
{
33195+
AddAndUpdateTokenInfo(vParent, vParent.Parameters, vPath);
33196+
}
33197+
(
33198+
jsonValueReturningClause[vParent]
33199+
|
33200+
/* empty */
33201+
)
33202+
tRParen:RightParenthesis
33203+
{
33204+
UpdateTokenInfo(vParent, tRParen);
33205+
}
3310633206
;
3310733207

3310833208
regularBuiltInFunctionCall [FunctionCall vParent]

SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.FunctionCall.cs

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ public override void ExplicitVisit(FunctionCall node)
8585
else if (node.FunctionName.Value.ToUpper(CultureInfo.InvariantCulture) == CodeGenerationSupporter.JsonArrayAgg)
8686
{
8787
GenerateCommaSeparatedList(node.Parameters);
88+
// Generate ORDER BY clause if present
89+
GenerateSpaceAndFragmentIfNotNull(node.JsonOrderByClause);
8890
if (node.Parameters?.Count > 0 && node?.AbsentOrNullOnNull?.Count > 0) //If there are values and null on null or absent on null present then generate space in between them
8991
GenerateSpace();
9092
GenerateNullOnNullOrAbsentOnNull(node?.AbsentOrNullOnNull);
@@ -96,9 +98,8 @@ public override void ExplicitVisit(FunctionCall node)
9698
else if (node.FunctionName.Value.ToUpper(CultureInfo.InvariantCulture) == CodeGenerationSupporter.JsonQuery)
9799
{
98100
GenerateCommaSeparatedList(node.Parameters);
99-
GenerateSymbol(TSqlTokenType.RightParenthesis);
100101

101-
// Handle WITH ARRAY WRAPPER clause
102+
// Handle WITH ARRAY WRAPPER clause - inside parentheses
102103
if (node.WithArrayWrapper)
103104
{
104105
GenerateSpace();
@@ -108,6 +109,18 @@ public override void ExplicitVisit(FunctionCall node)
108109
GenerateSpace();
109110
GenerateIdentifier(CodeGenerationSupporter.Wrapper);
110111
}
112+
113+
GenerateSymbol(TSqlTokenType.RightParenthesis);
114+
}
115+
else if (node.FunctionName.Value.ToUpper(CultureInfo.InvariantCulture) == CodeGenerationSupporter.JsonValue)
116+
{
117+
GenerateCommaSeparatedList(node.Parameters);
118+
if (node.ReturnType?.Count > 0) //If there are return types then generate space and return type clause
119+
{
120+
GenerateSpace();
121+
GenerateReturnType(node?.ReturnType);
122+
}
123+
GenerateSymbol(TSqlTokenType.RightParenthesis);
111124
}
112125
else
113126
{
@@ -161,13 +174,47 @@ private void GenerateNullOnNullOrAbsentOnNull(IList<Identifier> list)
161174
GenerateKeyword(TSqlTokenType.Null);
162175
}
163176
}
164-
private void GenerateReturnType(IList<Identifier> list)
177+
178+
// Generate returning clause with SQLType.
179+
private void GenerateReturnType(IList<DataTypeReference> list)
165180
{
166-
if (list?.Count > 0 && list[0].Value?.ToUpper(CultureInfo.InvariantCulture) == CodeGenerationSupporter.Json)
181+
if (list?.Count > 0)
167182
{
168183
GenerateIdentifier("RETURNING");
169184
GenerateSpace();
170-
GenerateSpaceSeparatedList(list);
185+
186+
// Generate each data type correctly
187+
for (int i = 0; i < list.Count; i++)
188+
{
189+
if (i > 0)
190+
GenerateSpace();
191+
192+
// Handle SqlDataTypeReference properly - need to generate the type name and parameters separately
193+
if (list[i] is SqlDataTypeReference sqlDataType)
194+
{
195+
// Generate the data type name (e.g., NVARCHAR)
196+
string dataTypeName = sqlDataType.SqlDataTypeOption.ToString().ToUpper(CultureInfo.InvariantCulture);
197+
GenerateIdentifier(dataTypeName);
198+
199+
// Generate parameters if any (e.g., (50))
200+
if (sqlDataType.Parameters?.Count > 0)
201+
{
202+
GenerateSymbol(TSqlTokenType.LeftParenthesis);
203+
for (int j = 0; j < sqlDataType.Parameters.Count; j++)
204+
{
205+
if (j > 0)
206+
GenerateSymbol(TSqlTokenType.Comma);
207+
GenerateFragmentIfNotNull(sqlDataType.Parameters[j]);
208+
}
209+
GenerateSymbol(TSqlTokenType.RightParenthesis);
210+
}
211+
}
212+
else
213+
{
214+
// For other data type references, use the default generation
215+
GenerateFragmentIfNotNull(list[i]);
216+
}
217+
}
171218
}
172219
}
173220
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
SELECT JSON_ARRAYAGG(value ORDER BY value)
2+
FROM mytable;
3+
4+
SELECT JSON_ARRAYAGG(name ORDER BY name ASC)
5+
FROM users;
6+
7+
SELECT JSON_ARRAYAGG(score ORDER BY score DESC)
8+
FROM scores;
9+
10+
SELECT JSON_ARRAYAGG(data ORDER BY priority DESC, created_at ASC)
11+
FROM records;
12+
13+
SELECT JSON_ARRAYAGG(value ORDER BY value NULL ON NULL)
14+
FROM data;
15+
16+
SELECT TOP (5) c.object_id,
17+
JSON_ARRAYAGG(c.name ORDER BY c.column_id) AS column_list
18+
FROM sys.columns AS c
19+
GROUP BY c.object_id;

Test/SqlDom/Baselines170/JsonFunctionTests170.sql

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ SELECT JSON_QUERY('{ "a": 1 }');
140140

141141
SELECT JSON_QUERY('{ "a": 1 }', '$.a');
142142

143-
SELECT JSON_QUERY('{ "a": [1,2,3] }', '$.a') WITH ARRAY WRAPPER;
143+
SELECT JSON_QUERY('{ "a": [1,2,3] }', '$.a' WITH ARRAY WRAPPER);
144144

145145

146146
GO
@@ -154,4 +154,34 @@ GO
154154
SELECT TOP (5) c.object_id,
155155
JSON_OBJECTAGG(c.name:c.column_id) AS columns
156156
FROM sys.columns AS c
157-
GROUP BY c.object_id;
157+
GROUP BY c.object_id;
158+
159+
SELECT JSON_VALUE('a', '$');
160+
SELECT JSON_VALUE('c', '$' RETURNING INT);
161+
SELECT JSON_VALUE('c', '$' RETURNING SMALLINT);
162+
SELECT JSON_VALUE('c', '$' RETURNING BIGINT);
163+
SELECT JSON_VALUE('c', '$' RETURNING TINYINT);
164+
SELECT JSON_VALUE('c', '$' RETURNING NUMERIC);
165+
SELECT JSON_VALUE('c', '$' RETURNING FLOAT);
166+
SELECT JSON_VALUE('c', '$' RETURNING REAL);
167+
SELECT JSON_VALUE('c', '$' RETURNING DECIMAL);
168+
SELECT JSON_VALUE('c', '$' RETURNING CHAR);
169+
SELECT JSON_VALUE('c', '$' RETURNING NVARCHAR(50));
170+
SELECT JSON_VALUE('c', '$' RETURNING NCHAR);
171+
SELECT JSON_VALUE('c', '$' RETURNING DATE);
172+
SELECT JSON_VALUE('c', '$' RETURNING DATETIME2);
173+
SELECT JSON_VALUE('c', '$' RETURNING TIME);
174+
SELECT JSON_VALUE('c', '$' RETURNING BIT);
175+
176+
SELECT id,
177+
json_col
178+
FROM tab1
179+
WHERE JSON_CONTAINS(json_col, 'abc', '$.a') = 1;
180+
181+
SELECT id,
182+
json_col
183+
FROM tab1
184+
WHERE JSON_CONTAINS(json_col, 'abc%', '$.a', 1) = 1;
185+
186+
SELECT JSON_MODIFY(json_col, '$.a', 30)
187+
FROM tab1;

0 commit comments

Comments
 (0)