fix: Trino get_columns (#29566)

This commit is contained in:
Beto Dealmeida
2024-07-12 16:37:49 -04:00
committed by GitHub
parent 0d352b4e06
commit fa095a98ed
7 changed files with 331 additions and 226 deletions

View File

@@ -311,3 +311,26 @@ def test_get_default_catalog(mocker: MockerFixture) -> None:
database = mocker.MagicMock()
assert BaseEngineSpec.get_default_catalog(database) is None
def test_quote_table() -> None:
"""
Test the `quote_table` function.
"""
from superset.db_engine_specs.base import BaseEngineSpec
dialect = sqlite.dialect()
assert BaseEngineSpec.quote_table(Table("table"), dialect) == '"table"'
assert (
BaseEngineSpec.quote_table(Table("table", "schema"), dialect)
== 'schema."table"'
)
assert (
BaseEngineSpec.quote_table(Table("table", "schema", "catalog"), dialect)
== 'catalog.schema."table"'
)
assert (
BaseEngineSpec.quote_table(Table("ta ble", "sche.ma", 'cata"log'), dialect)
== '"cata""log"."sche.ma"."ta ble"'
)

View File

@@ -16,6 +16,7 @@
# under the License.
# pylint: disable=unused-argument, import-outside-toplevel, protected-access
import copy
from collections import namedtuple
from datetime import datetime
from typing import Any, Optional
from unittest.mock import MagicMock, Mock, patch
@@ -25,7 +26,9 @@ import pytest
from pytest_mock import MockerFixture
from requests.exceptions import ConnectionError as RequestsConnectionError
from sqlalchemy import sql, text, types
from sqlalchemy.dialects import sqlite
from sqlalchemy.engine.url import make_url
from sqlalchemy.exc import NoSuchTableError
from trino.exceptions import TrinoExternalError, TrinoInternalError, TrinoUserError
from trino.sqlalchemy import datatype
from trino.sqlalchemy.dialect import TrinoDialect
@@ -464,6 +467,64 @@ def test_get_columns(mocker: MockerFixture):
_assert_columns_equal(actual, expected)
def test_get_columns_error(mocker: MockerFixture):
"""
Test that we fallback to a `SHOW COLUMNS FROM ...` query.
"""
from superset.db_engine_specs.trino import TrinoEngineSpec
field1_type = datatype.parse_sqltype("row(a varchar, b date)")
field2_type = datatype.parse_sqltype("row(r1 row(a varchar, b varchar))")
field3_type = datatype.parse_sqltype("int")
mock_inspector = mocker.MagicMock()
mock_inspector.engine.dialect = sqlite.dialect()
mock_inspector.get_columns.side_effect = NoSuchTableError(
"The specified table does not exist."
)
Row = namedtuple("Row", ["Column", "Type"])
mock_inspector.bind.execute().fetchall.return_value = [
Row("field1", "row(a varchar, b date)"),
Row("field2", "row(r1 row(a varchar, b varchar))"),
Row("field3", "int"),
]
actual = TrinoEngineSpec.get_columns(mock_inspector, Table("table", "schema"))
expected = [
ResultSetColumnType(
name="field1",
column_name="field1",
type=field1_type,
is_dttm=None,
type_generic=None,
default=None,
nullable=True,
),
ResultSetColumnType(
name="field2",
column_name="field2",
type=field2_type,
is_dttm=None,
type_generic=None,
default=None,
nullable=True,
),
ResultSetColumnType(
name="field3",
column_name="field3",
type=field3_type,
is_dttm=None,
type_generic=None,
default=None,
nullable=True,
),
]
_assert_columns_equal(actual, expected)
mock_inspector.bind.execute.assert_called_with('SHOW COLUMNS FROM schema."table"')
def test_get_columns_expand_rows(mocker: MockerFixture):
"""Test that ROW columns are correctly expanded with expand_rows"""
from superset.db_engine_specs.trino import TrinoEngineSpec
@@ -536,8 +597,6 @@ def test_get_columns_expand_rows(mocker: MockerFixture):
def test_get_indexes_no_table():
from sqlalchemy.exc import NoSuchTableError
from superset.db_engine_specs.trino import TrinoEngineSpec
db_mock = Mock()