From ab0b70b72dc805d7b02e44f8449ab5c3a4915bc3 Mon Sep 17 00:00:00 2001 From: MinhyukK0 <88814888+MinhyukK0@users.noreply.github.com> Date: Mon, 30 Mar 2026 14:58:35 +0900 Subject: [PATCH 1/2] fix(trino): filter schema browser by configured schema When a `schema` is set in the Trino data source configuration, `get_schema()` now adds a `table_schema` filter to the `information_schema.columns` query. This prevents fetching metadata for all schemas in the catalog, which can cause timeouts or partial results on large catalogs (e.g., Iceberg with AWS Glue metastore). Fixes #7680 Related: #6059 Co-Authored-By: Claude Opus 4.6 (1M context) --- redash/query_runner/trino.py | 5 ++++ tests/query_runner/test_trino.py | 40 ++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/redash/query_runner/trino.py b/redash/query_runner/trino.py index 6bb6c5bccc..50dc77ef71 100644 --- a/redash/query_runner/trino.py +++ b/redash/query_runner/trino.py @@ -123,6 +123,8 @@ def get_schema(self, get_stats=False): else: catalogs = self._get_catalogs() + schema_filter = self.configuration.get("schema") + schema = {} for catalog in catalogs: query = f""" @@ -130,6 +132,9 @@ def get_schema(self, get_stats=False): FROM {catalog}.information_schema.columns WHERE table_schema NOT IN ('pg_catalog', 'information_schema') """ + if schema_filter: + query += f" AND table_schema = '{schema_filter}'" + results, error = self.run_query(query, None) if error is not None: diff --git a/tests/query_runner/test_trino.py b/tests/query_runner/test_trino.py index b5fad8e6ea..2ef14ff0ed 100644 --- a/tests/query_runner/test_trino.py +++ b/tests/query_runner/test_trino.py @@ -29,6 +29,46 @@ def test_get_schema_catalog_set(self, mock_run_query, mock__get_catalogs): runner = Trino({"catalog": TestTrino.catalog_name}) self._assert_schema_catalog(mock_run_query, mock__get_catalogs, runner) + @patch.object(Trino, "run_query") + def test_get_schema_with_schema_filter(self, mock_run_query): + runner = Trino({"catalog": TestTrino.catalog_name, "schema": TestTrino.schema_name}) + mock_run_query.return_value = ( + { + "rows": [ + { + "table_schema": TestTrino.schema_name, + "table_name": TestTrino.table_name, + "column_name": TestTrino.column_name, + "data_type": TestTrino.column_type, + } + ] + }, + None, + ) + runner.get_schema() + query_arg = mock_run_query.call_args[0][0] + self.assertIn(f"AND table_schema = '{TestTrino.schema_name}'", query_arg) + + @patch.object(Trino, "run_query") + def test_get_schema_without_schema_filter(self, mock_run_query): + runner = Trino({"catalog": TestTrino.catalog_name}) + mock_run_query.return_value = ( + { + "rows": [ + { + "table_schema": TestTrino.schema_name, + "table_name": TestTrino.table_name, + "column_name": TestTrino.column_name, + "data_type": TestTrino.column_type, + } + ] + }, + None, + ) + runner.get_schema() + query_arg = mock_run_query.call_args[0][0] + self.assertNotIn("AND table_schema =", query_arg) + def _assert_schema_catalog(self, mock_run_query, mock__get_catalogs, runner): mock_run_query.return_value = ( { From 0befe42ceae40f70fbed1bb6b89e8bd645f990d5 Mon Sep 17 00:00:00 2001 From: MinhyukK0 <88814888+MinhyukK0@users.noreply.github.com> Date: Mon, 30 Mar 2026 15:11:06 +0900 Subject: [PATCH 2/2] fix(trino): escape schema filter to prevent SQL injection Escape single quotes in the schema_filter value before interpolating into the information_schema.columns query. Co-Authored-By: Claude Opus 4.6 (1M context) --- redash/query_runner/trino.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/redash/query_runner/trino.py b/redash/query_runner/trino.py index 50dc77ef71..94304d65b4 100644 --- a/redash/query_runner/trino.py +++ b/redash/query_runner/trino.py @@ -133,7 +133,8 @@ def get_schema(self, get_stats=False): WHERE table_schema NOT IN ('pg_catalog', 'information_schema') """ if schema_filter: - query += f" AND table_schema = '{schema_filter}'" + safe_schema_filter = schema_filter.replace("'", "''") + query += f" AND table_schema = '{safe_schema_filter}'" results, error = self.run_query(query, None)