Skip to content

Commit c4dcfa4

Browse files
committed
[Trino] Adding explain query method
1 parent c8872fc commit c4dcfa4

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

desktop/libs/notebook/src/notebook/connectors/trino.py

+20
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,26 @@ def _get_columns(self, database, table):
321321
]
322322

323323

324+
@query_error_handler
325+
def explain(self, notebook, snippet):
326+
statement = snippet['statement'].rstrip(';')
327+
explanation = ''
328+
329+
if statement:
330+
try:
331+
TrinoQuery(self.trino_request, 'USE ' + snippet['database']).execute()
332+
result = TrinoQuery(self.trino_request, 'EXPLAIN ' + statement).execute()
333+
explanation = result.rows
334+
except Exception as e:
335+
explanation = str(e)
336+
337+
return {
338+
'status': 0,
339+
'explanation': explanation,
340+
'statement': statement
341+
}
342+
343+
324344
def download(self, notebook, snippet, file_format='csv'):
325345
result_wrapper = TrinoExecutionWrapper(self, notebook, snippet)
326346

desktop/libs/notebook/src/notebook/connectors/trino_tests.py

+42
Original file line numberDiff line numberDiff line change
@@ -253,3 +253,45 @@ def test_get_select_query(self):
253253
self.trino_api._get_select_query(database, table),
254254
expected_statement
255255
)
256+
257+
258+
def test_explain(self):
259+
with patch('notebook.connectors.trino.TrinoQuery') as TrinoQuery:
260+
snippet = {'statement': 'SELECT * FROM tpch.sf1.partsupp LIMIT 100;', 'database': 'tpch.sf1'}
261+
output = [['Trino version: 432\nFragment 0 [SINGLE]\n Output layout: [partkey, suppkey, availqty, supplycost, comment]\n '\
262+
'Output partitioning: SINGLE []\n Output[columnNames = [partkey, suppkey, availqty, supplycost, comment]]\n │ '\
263+
'Layout: [partkey:bigint, suppkey:bigint, availqty:integer, supplycost:double, comment:varchar(199)]\n │ '\
264+
'Estimates: {rows: 100 (15.67kB), cpu: 0, memory: 0B, network: 0B}\n └─ Limit[count = 100]\n │ '\
265+
'Layout: [partkey:bigint, suppkey:bigint, availqty:integer, supplycost:double, comment:varchar(199)]\n │ '\
266+
'Estimates: {rows: 100 (15.67kB), cpu: 15.67k, memory: 0B, network: 0B}\n └─ LocalExchange[partitioning = SINGLE]\n '\
267+
'│ Layout: [partkey:bigint, suppkey:bigint, availqty:integer, supplycost:double, comment:varchar(199)]\n │ '\
268+
'Estimates: {rows: 100 (15.67kB), cpu: 0, memory: 0B, network: 0B}\n └─ RemoteSource[sourceFragmentIds = [1]]\n'\
269+
' Layout: [partkey:bigint, suppkey:bigint, availqty:integer, supplycost:double, comment:varchar(199)]\n\n'\
270+
'Fragment 1 [SOURCE]\n Output layout: [partkey, suppkey, availqty, supplycost, comment]\n Output partitioning: SINGLE []\n'\
271+
' LimitPartial[count = 100]\n │ Layout: [partkey:bigint, suppkey:bigint, availqty:integer, supplycost:double, '\
272+
'comment:varchar(199)]\n │ Estimates: {rows: 100 (15.67kB), cpu: 15.67k, memory: 0B, network: 0B}\n └─ '\
273+
'TableScan[table = tpch:sf1:partsupp]\n Layout: [partkey:bigint, suppkey:bigint, availqty:integer, supplycost:double, '\
274+
'comment:varchar(199)]\n Estimates: {rows: 800000 (122.44MB), cpu: 122.44M, memory: 0B, network: 0B}\n '\
275+
'partkey := tpch:partkey\n availqty := tpch:availqty\n supplycost := tpch:supplycost\n '\
276+
'comment := tpch:comment\n suppkey := tpch:suppkey\n\n']]
277+
# Mock TrinoQuery object and its execute method
278+
query_instance = TrinoQuery.return_value
279+
query_instance.execute.return_value = MagicMock(next_uri=None, id='123', rows=output, columns=[])
280+
281+
# Call the explain method
282+
result = self.trino_api.explain(notebook=None, snippet=snippet)
283+
284+
# Assert the result
285+
assert_equal(result['status'], 0)
286+
assert_equal(result['explanation'], output)
287+
assert_equal(result['statement'], 'SELECT * FROM tpch.sf1.partsupp LIMIT 100')
288+
289+
query_instance = TrinoQuery.return_value
290+
query_instance.execute.side_effect = Exception('Mocked exception')
291+
292+
# Call the explain method
293+
result = self.trino_api.explain(notebook=None, snippet=snippet)
294+
295+
# Assert the exception message
296+
assert_equal(result['explanation'], 'Mocked exception')
297+

0 commit comments

Comments
 (0)