Skip to content

Commit b47f25e

Browse files
fix(kernel): classify invalid transfer paths and track release gate
Signed-off-by: Aakash Saravanan <aakash.saravanan@databricks.com>
1 parent 67efcd9 commit b47f25e

4 files changed

Lines changed: 31 additions & 13 deletions

File tree

‎KERNEL_REV‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2f317d97212f00d73b89d947f5261a2145ea7a10
1+
95f294c8c2c825440191af9f58a9b6071aa68408

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ requests-kerberos = {version = "^0.15.0", optional = true}
7070
# Floor is 1.4.0 (``^1.4.0`` == ``>=1.4.0,<2.0.0``), allowing compatible
7171
# 1.x releases while keeping the next major upgrade deliberate. The kernel's
7272
# pyarrow constraint remains >=23.0.1,<24.
73-
# TODO: raise the release floor after databricks/databricks-sql-kernel#439 is published.
73+
# TODO: gate merge/release on https://github.com/databricks/databricks-sql-kernel/issues/443.
7474
databricks-sql-kernel = {version = "^1.4.0", optional = true, python = ">=3.10"}
7575

7676

‎src/databricks/sql/backend/kernel/client.py‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,7 @@
7474
# per-request skip-and-warn.
7575
_KERNEL_MANAGED_HEADERS = frozenset({"authorization", "x-databricks-org-id"})
7676

77-
78-
# Leading verbs of SQL volume/staging statements. Detected by the
79-
# leading token (case-insensitive) so the kernel backend can fail loud
80-
# on staging ops it can't service — see ``execute_command``.
77+
# Transfer detection controls local-path forwarding and the older-wheel guard.
8178
_STAGING_VERBS = ("PUT", "GET", "REMOVE")
8279

8380

@@ -597,7 +594,15 @@ def execute_command(
597594
allowed_paths = [allowed_paths]
598595
set_paths = getattr(stmt, "set_staging_allowed_local_paths", None)
599596
if callable(set_paths):
600-
set_paths([os.fsdecode(path) for path in allowed_paths or []])
597+
try:
598+
normalized_paths = [
599+
os.fsdecode(path) for path in allowed_paths or []
600+
]
601+
except (TypeError, ValueError) as exc:
602+
raise ProgrammingError(
603+
"staging_allowed_local_path must be a path or a list of paths"
604+
) from exc
605+
set_paths(normalized_paths)
601606
elif _is_staging_statement(operation):
602607
raise NotSupportedError(
603608
"Volume transfers require a databricks-sql-kernel wheel "

‎tests/unit/test_kernel_client.py‎

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,10 @@ def test_execute_command_forwards_allowed_local_paths(allowed, expected, async_o
848848

849849

850850
@pytest.mark.parametrize("allowed", [123, [object()]])
851-
def test_non_transfer_query_ignores_malformed_local_paths(allowed):
851+
@pytest.mark.parametrize(
852+
"operation", ["SELECT 1", "PUT 'input' INTO '/Volumes/c/s/v/file'"]
853+
)
854+
def test_malformed_local_paths_only_reject_transfers(allowed, operation):
852855
c = _make_client()
853856
c._kernel_session = MagicMock()
854857
cursor = MagicMock()
@@ -858,11 +861,21 @@ def test_non_transfer_query_ignores_malformed_local_paths(allowed):
858861
statement_id="00000000-0000-0000-0000-000000000001",
859862
arrow_schema=MagicMock(return_value=pa.schema([("x", pa.int64())])),
860863
)
861-
c.execute_command(
862-
"SELECT 1", MagicMock(), 1, 1, False, cursor, False, [], False, False
863-
)
864-
stmt.set_staging_allowed_local_paths.assert_called_once_with([])
865-
stmt.execute.assert_called_once()
864+
865+
def execute():
866+
c.execute_command(
867+
operation, MagicMock(), 1, 1, False, cursor, False, [], False, False
868+
)
869+
870+
if operation.startswith("PUT"):
871+
with pytest.raises(ProgrammingError, match="staging_allowed_local_path"):
872+
execute()
873+
stmt.execute.assert_not_called()
874+
stmt.set_staging_allowed_local_paths.assert_not_called()
875+
else:
876+
execute()
877+
stmt.set_staging_allowed_local_paths.assert_called_once_with([])
878+
stmt.execute.assert_called_once()
866879

867880

868881
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)