Skip to content

Commit 2fdab9b

Browse files
authored
Fix completion refresher query results leak and active query error (dbcli#161)
* Adding a lock acquisition during executing a single batch query. * Fixing casing in order to retrieve proper error message. * Adding support for owner uri in json rpc response dequeueing. * Adding support for a separate connection for the completion refrehser with addt'l logging. * Marking string as unicode for py2/3 compat. * Converging all sqltoolsservice test to a single file since most of the code was redundant and hard to maintain. * Adding missing json rpc client tests and reformatted for readability. * Adding clean up for each request to remove it's owner uri from response queue when it's completed. * Adding request finished for owner uri of request when a exception occurs. * Setting response_str to None to avoid assignment exception. * Fixing build.py format. * Adding owner URI to connection complete event during failure. * Changing get response signature in jsonrpcclient to accept owner uri in addition to id. * Removing copyright headers from files I touched. * Refactored test json rpc contracts tests. * Adding unit test for ensuring query execute requests retrieve correct events based on it's owner uri. * Fixing typo in refresher name. * Renaming method for creating a new mssqlcliclient for completion refresher. * Renamed baseline files for simplicity. * Removed copyright header. * Refactoring and adding clone support to mssqlcliclient. * Removing unnecessary call to get a new mssql cli client.
1 parent 08cf7ee commit 2fdab9b

17 files changed

+385
-327
lines changed

build.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,17 @@ def unit_test():
9595
Run all unit tests.
9696
"""
9797
utility.exec_command(
98-
'pytest --cov mssqlcli tests/test_mssqlcliclient.py tests/test_main.py tests/test_fuzzy_completion.py '
99-
'tests/test_rowlimit.py tests/test_sqlcompletion.py tests/test_prioritization.py mssqlcli/jsonrpc/contracts/tests '
100-
'tests/test_telemetry.py tests/test_special.py',
98+
'pytest --cov mssqlcli '
99+
'tests/test_mssqlcliclient.py '
100+
'tests/test_main.py '
101+
'tests/test_fuzzy_completion.py '
102+
'tests/test_rowlimit.py '
103+
'tests/test_sqlcompletion.py '
104+
'tests/test_prioritization.py '
105+
'mssqlcli/jsonrpc/tests '
106+
'mssqlcli/jsonrpc/contracts/tests '
107+
'tests/test_telemetry.py '
108+
'tests/test_special.py',
101109
utility.ROOT_DIR,
102110
continue_on_error=False)
103111

mssqlcli/completion_refresher.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ def _bg_refresh(self, mssqlcliclient, callbacks, history=None,
5151
completer = MssqlCompleter(smart_completion=True, settings=settings)
5252

5353
executor = mssqlcliclient
54-
executor.connect()
54+
if not executor.connect():
55+
# If we were unable to connect, do not break the experience for the user.
56+
# Return nothing, smart completion can maintain the keywords and functions completions.
57+
logger.error(u'Completion Refresher failed to connect to the target server.')
58+
return
5559
# If callbacks is a single function then push it into a list.
5660
if callable(callbacks):
5761
callbacks = [callbacks]

mssqlcli/jsonrpc/contracts/connectionservice.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
# --------------------------------------------------------------------------------------------
2-
# Copyright (c) Microsoft Corporation. All rights reserved.
3-
# Licensed under the MIT License. See License.txt in the project root for license information.
4-
# --------------------------------------------------------------------------------------------
51
from mssqlcli.jsonrpc.contracts import Request
62

73
import sys
@@ -16,8 +12,9 @@ class ConnectionRequest(Request):
1612
"""
1713
METHOD_NAME = u'connection/connect'
1814

19-
def __init__(self, id, json_rpc_client, parameters):
15+
def __init__(self, id, owner_uri, json_rpc_client, parameters):
2016
self.id = id
17+
self.owner_uri = owner_uri
2118
self.finished = False
2219
self.json_rpc_client = json_rpc_client
2320
self.params = ConnectionParams(parameters)
@@ -31,26 +28,27 @@ def get_response(self):
3128
Get latest response, event or exception if it occured.
3229
"""
3330
try:
34-
response = self.json_rpc_client.get_response(self.id)
31+
response = self.json_rpc_client.get_response(self.id, self.owner_uri)
3532
decoded_response = None
36-
3733
if response:
3834
logger.debug(response)
3935
decoded_response = self.decode_response(response)
4036

4137
if isinstance(decoded_response, ConnectionCompleteEvent):
4238
self.finished = True
4339
self.json_rpc_client.request_finished(self.id)
40+
self.json_rpc_client.request_finished(self.owner_uri)
4441

4542
return decoded_response
4643

4744
except Exception as error:
4845
logger.debug(str(error))
4946
self.finished = True
5047
self.json_rpc_client.request_finished(self.id)
48+
self.json_rpc_client.request_finished(self.owner_uri)
5149
return ConnectionCompleteEvent({
5250
u'params': {
53-
u'ownerUri': None,
51+
u'ownerUri': self.owner_uri,
5452
u'connectionId': None,
5553
u'messages': str(error),
5654
u'errorMessage': u'Connection request encountered an exception',

mssqlcli/jsonrpc/contracts/queryexecutestringservice.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
# --------------------------------------------------------------------------------------------
2-
# Copyright (c) Microsoft Corporation. All rights reserved.
3-
# Licensed under the MIT License. See License.txt in the project root for license information.
4-
# --------------------------------------------------------------------------------------------
5-
1+
import logging
62
from mssqlcli.jsonrpc.contracts import Request
73

4+
logger = logging.getLogger(u'mssqlcli.queryexecutestringservice')
5+
86

97
class QueryExecuteStringRequest(Request):
108
"""
@@ -13,8 +11,9 @@ class QueryExecuteStringRequest(Request):
1311

1412
METHOD_NAME = u'query/executeString'
1513

16-
def __init__(self, id, json_rpc_client, parameters):
14+
def __init__(self, id, owner_uri, json_rpc_client, parameters):
1715
self.id = id
16+
self.owner_uri = owner_uri
1817
self.finished = False
1918
self.json_rpc_client = json_rpc_client
2019
self.params = QueryExecuteStringParams(parameters)
@@ -24,22 +23,24 @@ def get_response(self):
2423
Get latest response, event or exception if occured.
2524
"""
2625
try:
27-
response = self.json_rpc_client.get_response(self.id)
28-
decoded_response = None
26+
response = self.json_rpc_client.get_response(self.id, self.owner_uri)
2927

28+
decoded_response = None
3029
if response:
3130
decoded_response = self.decode_response(response)
3231

3332
if isinstance(decoded_response, QueryCompleteEvent) or \
3433
isinstance(decoded_response, QueryExecuteErrorResponseEvent):
3534
self.finished = True
3635
self.json_rpc_client.request_finished(self.id)
36+
self.json_rpc_client.request_finished(self.owner_uri)
3737

3838
return decoded_response
3939

4040
except Exception as error:
4141
self.finished = True
4242
self.json_rpc_client.request_finished(self.id)
43+
self.json_rpc_client.request_finished(self.owner_uri)
4344
return QueryCompleteEvent(
4445
{u'params': None}, exception_message=str(error)
4546
)
@@ -137,8 +138,9 @@ class QuerySubsetRequest(Request):
137138

138139
METHOD_NAME = u'query/subset'
139140

140-
def __init__(self, id, json_rpc_client, parameters):
141+
def __init__(self, id, owner_uri, json_rpc_client, parameters):
141142
self.id = id
143+
self.owner_uri = owner_uri
142144
self.finished = False
143145
self.json_rpc_client = json_rpc_client
144146
self.params = QuerySubsetParams(parameters)
@@ -151,21 +153,22 @@ def completed(self):
151153

152154
def get_response(self):
153155
try:
154-
response = self.json_rpc_client.get_response(self.id)
156+
response = self.json_rpc_client.get_response(self.id, self.owner_uri)
155157
decoded_response = None
156-
157158
if response:
158159
decoded_response = self.decode_response(response)
159160

160161
if isinstance(decoded_response, ResultSubset):
161162
self.finished = True
162163
self.json_rpc_client.request_finished(self.id)
164+
self.json_rpc_client.request_finished(self.owner_uri)
163165

164166
return decoded_response
165167

166168
except Exception as error:
167169
self.finished = True
168170
self.json_rpc_client.request_finished(self.id)
171+
self.json_rpc_client.request_finished(self.owner_uri)
169172
return ResultSubset(None, error_message=str(error))
170173

171174
def execute(self):
@@ -177,7 +180,7 @@ def decode_response(self, response):
177180
return ResultSubset(response)
178181
elif u'error' in response:
179182
return ResultSubset(
180-
None, error_message=response[u'error']['Message'])
183+
None, error_message=response[u'error']['message'])
181184

182185

183186
class QuerySubsetParams(object):
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
Content-Length: 40
2+
3+
{"jsonrpc":"2.0","id":"1","result":true}Content-Length: 40
4+
5+
{"jsonrpc":"2.0","id":"2","result":true}Content-Length: 650
6+
7+
{"jsonrpc":"2.0","method":"connection/complete","params":{"ownerUri":"mismatchquerycompleteresponse_2","connectionId":"7cd08d4a-6b39-429b-9f28-bf1b42fb75c5","messages":null,"errorMessage":null,"errorNumber":0,"serverInfo":{"serverMajorVersion":12,"serverMinorVersion":0,"serverReleaseVersion":2269,"engineEditionId":3,"serverVersion":"12.0.2269.0","serverLevel":"RTM","serverEdition":"Enterprise Edition (64-bit)","isCloud":false,"azureVersion":0,"osVersion":"Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)\n","machineName":"BRO-HB"},"connectionSummary":{"serverName":"bro-hb","databaseName":"AdventureWorks2014","userName":"sa"},"type":"Default"}}Content-Length: 650
8+
9+
{"jsonrpc":"2.0","method":"connection/complete","params":{"ownerUri":"mismatchquerycompleteresponse_1","connectionId":"eb327978-b068-4408-aeef-836f30be870a","messages":null,"errorMessage":null,"errorNumber":0,"serverInfo":{"serverMajorVersion":12,"serverMinorVersion":0,"serverReleaseVersion":2269,"engineEditionId":3,"serverVersion":"12.0.2269.0","serverLevel":"RTM","serverEdition":"Enterprise Edition (64-bit)","isCloud":false,"azureVersion":0,"osVersion":"Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)\n","machineName":"BRO-HB"},"connectionSummary":{"serverName":"bro-hb","databaseName":"AdventureWorks2014","userName":"sa"},"type":"Default"}}Content-Length: 115
10+
11+
{"jsonrpc":"2.0","method":"textDocument/intelliSenseReady","params":{"ownerUri":"mismatchquerycompleteresponse_2"}}Content-Length: 115
12+
13+
{"jsonrpc":"2.0","method":"textDocument/intelliSenseReady","params":{"ownerUri":"mismatchquerycompleteresponse_1"}}Content-Length: 38
14+
15+
{"jsonrpc":"2.0","id":"3","result":{}}Content-Length: 357
16+
17+
{"jsonrpc":"2.0","method":"query/batchStart","params":{"batchSummary":{"executionElapsed":null,"executionEnd":null,"executionStart":"2018-02-08T13:20:15.1872770-08:00","hasError":false,"id":0,"selection":{"endColumn":39,"endLine":1,"startColumn":0,"startLine":0},"resultSetSummaries":null,"specialAction":null},"ownerUri":"mismatchquerycompleteresponse_1"}}Content-Length: 212
18+
19+
{"jsonrpc":"2.0","method":"query/message","params":{"ownerUri":"mismatchquerycompleteresponse_1","message":{"batchId":0,"isError":false,"time":"2018-02-08T13:20:15.3145728-08:00","message":"(16 rows affected)"}}}Content-Length: 3196
20+
21+
{"jsonrpc":"2.0","method":"query/resultSetComplete","params":{"resultSetSummary":{"id":0,"batchId":0,"rowCount":16,"columnInfo":[{"isBytes":false,"isChars":false,"isSqlVariant":false,"isUdt":false,"isXml":false,"isJson":false,"sqlDbType":16,"isSqlXmlType":false,"isUnknownType":false,"isUpdatable":false,"allowDBNull":false,"baseCatalogName":null,"baseColumnName":null,"baseSchemaName":null,"baseServerName":null,"baseTableName":null,"columnName":"DepartmentID","columnOrdinal":0,"columnSize":2,"isAliased":null,"isAutoIncrement":true,"isExpression":null,"isHidden":null,"isIdentity":true,"isKey":null,"isLong":false,"isReadOnly":true,"isUnique":false,"numericPrecision":5,"numericScale":255,"udtAssemblyQualifiedName":null,"dataType":"System.Int16, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","dataTypeName":"smallint"},{"isBytes":false,"isChars":true,"isSqlVariant":false,"isUdt":false,"isXml":false,"isJson":false,"sqlDbType":12,"isSqlXmlType":false,"isUnknownType":false,"isUpdatable":true,"allowDBNull":false,"baseCatalogName":null,"baseColumnName":null,"baseSchemaName":null,"baseServerName":null,"baseTableName":null,"columnName":"Name","columnOrdinal":1,"columnSize":50,"isAliased":null,"isAutoIncrement":false,"isExpression":null,"isHidden":null,"isIdentity":false,"isKey":null,"isLong":false,"isReadOnly":false,"isUnique":false,"numericPrecision":255,"numericScale":255,"udtAssemblyQualifiedName":null,"dataType":"System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","dataTypeName":"nvarchar"},{"isBytes":false,"isChars":true,"isSqlVariant":false,"isUdt":false,"isXml":false,"isJson":false,"sqlDbType":12,"isSqlXmlType":false,"isUnknownType":false,"isUpdatable":true,"allowDBNull":false,"baseCatalogName":null,"baseColumnName":null,"baseSchemaName":null,"baseServerName":null,"baseTableName":null,"columnName":"GroupName","columnOrdinal":2,"columnSize":50,"isAliased":null,"isAutoIncrement":false,"isExpression":null,"isHidden":null,"isIdentity":false,"isKey":null,"isLong":false,"isReadOnly":false,"isUnique":false,"numericPrecision":255,"numericScale":255,"udtAssemblyQualifiedName":null,"dataType":"System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","dataTypeName":"nvarchar"},{"isBytes":false,"isChars":false,"isSqlVariant":false,"isUdt":false,"isXml":false,"isJson":false,"sqlDbType":4,"isSqlXmlType":false,"isUnknownType":false,"isUpdatable":true,"allowDBNull":false,"baseCatalogName":null,"baseColumnName":null,"baseSchemaName":null,"baseServerName":null,"baseTableName":null,"columnName":"ModifiedDate","columnOrdinal":3,"columnSize":8,"isAliased":null,"isAutoIncrement":false,"isExpression":null,"isHidden":null,"isIdentity":false,"isKey":null,"isLong":false,"isReadOnly":false,"isUnique":false,"numericPrecision":23,"numericScale":3,"udtAssemblyQualifiedName":null,"dataType":"System.DateTime, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","dataTypeName":"datetime"}],"specialAction":{"none":true,"expectYukonXMLShowPlan":false}},"ownerUri":"mismatchquerycompleteresponse_1"}}Content-Length: 3511
22+
23+
{"jsonrpc":"2.0","method":"query/batchComplete","params":{"batchSummary":{"executionElapsed":"00:00:00.0805260","executionEnd":"2018-02-08T13:20:15.3449966-08:00","executionStart":"2018-02-08T13:20:15.2644706-08:00","hasError":false,"id":0,"selection":{"endColumn":39,"endLine":1,"startColumn":0,"startLine":0},"resultSetSummaries":[{"id":0,"batchId":0,"rowCount":16,"columnInfo":[{"isBytes":false,"isChars":false,"isSqlVariant":false,"isUdt":false,"isXml":false,"isJson":false,"sqlDbType":16,"isSqlXmlType":false,"isUnknownType":false,"isUpdatable":false,"allowDBNull":false,"baseCatalogName":null,"baseColumnName":null,"baseSchemaName":null,"baseServerName":null,"baseTableName":null,"columnName":"DepartmentID","columnOrdinal":0,"columnSize":2,"isAliased":null,"isAutoIncrement":true,"isExpression":null,"isHidden":null,"isIdentity":true,"isKey":null,"isLong":false,"isReadOnly":true,"isUnique":false,"numericPrecision":5,"numericScale":255,"udtAssemblyQualifiedName":null,"dataType":"System.Int16, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","dataTypeName":"smallint"},{"isBytes":false,"isChars":true,"isSqlVariant":false,"isUdt":false,"isXml":false,"isJson":false,"sqlDbType":12,"isSqlXmlType":false,"isUnknownType":false,"isUpdatable":true,"allowDBNull":false,"baseCatalogName":null,"baseColumnName":null,"baseSchemaName":null,"baseServerName":null,"baseTableName":null,"columnName":"Name","columnOrdinal":1,"columnSize":50,"isAliased":null,"isAutoIncrement":false,"isExpression":null,"isHidden":null,"isIdentity":false,"isKey":null,"isLong":false,"isReadOnly":false,"isUnique":false,"numericPrecision":255,"numericScale":255,"udtAssemblyQualifiedName":null,"dataType":"System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","dataTypeName":"nvarchar"},{"isBytes":false,"isChars":true,"isSqlVariant":false,"isUdt":false,"isXml":false,"isJson":false,"sqlDbType":12,"isSqlXmlType":false,"isUnknownType":false,"isUpdatable":true,"allowDBNull":false,"baseCatalogName":null,"baseColumnName":null,"baseSchemaName":null,"baseServerName":null,"baseTableName":null,"columnName":"GroupName","columnOrdinal":2,"columnSize":50,"isAliased":null,"isAutoIncrement":false,"isExpression":null,"isHidden":null,"isIdentity":false,"isKey":null,"isLong":false,"isReadOnly":false,"isUnique":false,"numericPrecision":255,"numericScale":255,"udtAssemblyQualifiedName":null,"dataType":"System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","dataTypeName":"nvarchar"},{"isBytes":false,"isChars":false,"isSqlVariant":false,"isUdt":false,"isXml":false,"isJson":false,"sqlDbType":4,"isSqlXmlType":false,"isUnknownType":false,"isUpdatable":true,"allowDBNull":false,"baseCatalogName":null,"baseColumnName":null,"baseSchemaName":null,"baseServerName":null,"baseTableName":null,"columnName":"ModifiedDate","columnOrdinal":3,"columnSize":8,"isAliased":null,"isAutoIncrement":false,"isExpression":null,"isHidden":null,"isIdentity":false,"isKey":null,"isLong":false,"isReadOnly":false,"isUnique":false,"numericPrecision":23,"numericScale":3,"udtAssemblyQualifiedName":null,"dataType":"System.DateTime, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","dataTypeName":"datetime"}],"specialAction":{"none":true,"expectYukonXMLShowPlan":false}}],"specialAction":{"none":true,"expectYukonXMLShowPlan":false}},"ownerUri":"mismatchquerycompleteresponse_1"}}Content-Length: 3510
24+
25+
{"jsonrpc":"2.0","method":"query/complete","params":{"ownerUri":"mismatchquerycompleteresponse_1","batchSummaries":[{"executionElapsed":"00:00:00.0805260","executionEnd":"2018-02-08T13:20:15.3449966-08:00","executionStart":"2018-02-08T13:20:15.2644706-08:00","hasError":false,"id":0,"selection":{"endColumn":39,"endLine":1,"startColumn":0,"startLine":0},"resultSetSummaries":[{"id":0,"batchId":0,"rowCount":16,"columnInfo":[{"isBytes":false,"isChars":false,"isSqlVariant":false,"isUdt":false,"isXml":false,"isJson":false,"sqlDbType":16,"isSqlXmlType":false,"isUnknownType":false,"isUpdatable":false,"allowDBNull":false,"baseCatalogName":null,"baseColumnName":null,"baseSchemaName":null,"baseServerName":null,"baseTableName":null,"columnName":"DepartmentID","columnOrdinal":0,"columnSize":2,"isAliased":null,"isAutoIncrement":true,"isExpression":null,"isHidden":null,"isIdentity":true,"isKey":null,"isLong":false,"isReadOnly":true,"isUnique":false,"numericPrecision":5,"numericScale":255,"udtAssemblyQualifiedName":null,"dataType":"System.Int16, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","dataTypeName":"smallint"},{"isBytes":false,"isChars":true,"isSqlVariant":false,"isUdt":false,"isXml":false,"isJson":false,"sqlDbType":12,"isSqlXmlType":false,"isUnknownType":false,"isUpdatable":true,"allowDBNull":false,"baseCatalogName":null,"baseColumnName":null,"baseSchemaName":null,"baseServerName":null,"baseTableName":null,"columnName":"Name","columnOrdinal":1,"columnSize":50,"isAliased":null,"isAutoIncrement":false,"isExpression":null,"isHidden":null,"isIdentity":false,"isKey":null,"isLong":false,"isReadOnly":false,"isUnique":false,"numericPrecision":255,"numericScale":255,"udtAssemblyQualifiedName":null,"dataType":"System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","dataTypeName":"nvarchar"},{"isBytes":false,"isChars":true,"isSqlVariant":false,"isUdt":false,"isXml":false,"isJson":false,"sqlDbType":12,"isSqlXmlType":false,"isUnknownType":false,"isUpdatable":true,"allowDBNull":false,"baseCatalogName":null,"baseColumnName":null,"baseSchemaName":null,"baseServerName":null,"baseTableName":null,"columnName":"GroupName","columnOrdinal":2,"columnSize":50,"isAliased":null,"isAutoIncrement":false,"isExpression":null,"isHidden":null,"isIdentity":false,"isKey":null,"isLong":false,"isReadOnly":false,"isUnique":false,"numericPrecision":255,"numericScale":255,"udtAssemblyQualifiedName":null,"dataType":"System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","dataTypeName":"nvarchar"},{"isBytes":false,"isChars":false,"isSqlVariant":false,"isUdt":false,"isXml":false,"isJson":false,"sqlDbType":4,"isSqlXmlType":false,"isUnknownType":false,"isUpdatable":true,"allowDBNull":false,"baseCatalogName":null,"baseColumnName":null,"baseSchemaName":null,"baseServerName":null,"baseTableName":null,"columnName":"ModifiedDate","columnOrdinal":3,"columnSize":8,"isAliased":null,"isAutoIncrement":false,"isExpression":null,"isHidden":null,"isIdentity":false,"isKey":null,"isLong":false,"isReadOnly":false,"isUnique":false,"numericPrecision":23,"numericScale":3,"udtAssemblyQualifiedName":null,"dataType":"System.DateTime, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","dataTypeName":"datetime"}],"specialAction":{"none":true,"expectYukonXMLShowPlan":false}}],"specialAction":{"none":true,"expectYukonXMLShowPlan":false}}]}}

0 commit comments

Comments
 (0)