Skip to content

Commit 7b844f5

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

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

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

+22
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,28 @@ 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+
query_client = TrinoQuery(self.trino_request, 'USE ' + snippet['database'])
332+
query_client.execute()
333+
query_client = TrinoQuery(self.trino_request, 'EXPLAIN ' + statement)
334+
result = query_client.execute()
335+
explanation = result.rows
336+
except Exception as e:
337+
explanation = str(e)
338+
339+
return {
340+
'status': 0,
341+
'explanation': explanation,
342+
'statement': statement
343+
}
344+
345+
324346
def download(self, notebook, snippet, file_format='csv'):
325347
result_wrapper = TrinoExecutionWrapper(self, notebook, snippet)
326348

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

+32
Original file line numberDiff line numberDiff line change
@@ -253,3 +253,35 @@ 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, comment:varchar(199)]\n'\
274+
' Estimates: {rows: 800000 (122.44MB), cpu: 122.44M, memory: 0B, network: 0B}\n partkey := tpch:partkey\n'\
275+
' availqty := tpch:availqty\n supplycost := tpch:supplycost\n comment := tpch:comment\n '\
276+
' 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+
self.assertEqual(result['status'], 0)
286+
self.assertEqual(result['explanation'], output)
287+
self.assertEqual(result['statement'], 'SELECT * FROM tpch.sf1.partsupp LIMIT 100')

0 commit comments

Comments
 (0)