Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -1426,7 +1426,7 @@
"filename": "sdk/python/tests/unit/infra/utils/snowflake/test_snowflake_utils.py",
"hashed_secret": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3",
"is_verified": false,
"line_number": 10
"line_number": 14
}
],
"sdk/python/tests/unit/local_feast_tests/test_init.py": [
Expand Down Expand Up @@ -1539,5 +1539,5 @@
}
]
},
"generated_at": "2026-04-07T15:56:56Z"
"generated_at": "2026-04-09T03:30:18Z"
}
2 changes: 2 additions & 0 deletions sdk/python/feast/infra/utils/snowflake/snowflake_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ def assert_snowflake_feature_names(feature_view: FeatureView) -> None:


def execute_snowflake_statement(conn: SnowflakeConnection, query) -> SnowflakeCursor:
if not query.strip():
return conn.cursor()
cursor = conn.cursor().execute(query)
if cursor is None:
raise SnowflakeQueryUnknownError(query)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import tempfile
from typing import Optional
from unittest.mock import MagicMock

import pytest
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa

from feast.infra.utils.snowflake.snowflake_utils import parse_private_key_path
from feast.infra.utils.snowflake.snowflake_utils import (
execute_snowflake_statement,
parse_private_key_path,
)

PRIVATE_KEY_PASSPHRASE = "test"

Expand Down Expand Up @@ -69,3 +73,48 @@ def test_parse_private_key_path_key_path_encrypted(encrypted_private_key):
f.name,
None,
)


class TestExecuteSnowflakeStatement:
def test_empty_query_returns_cursor_without_executing(self):
mock_conn = MagicMock()
mock_cursor = MagicMock()
mock_conn.cursor.return_value = mock_cursor

result = execute_snowflake_statement(mock_conn, "")

assert result is mock_cursor
mock_conn.cursor.assert_called_once()
mock_cursor.execute.assert_not_called()

def test_whitespace_only_query_returns_cursor_without_executing(self):
mock_conn = MagicMock()
mock_cursor = MagicMock()
mock_conn.cursor.return_value = mock_cursor

result = execute_snowflake_statement(mock_conn, " \t\n ")

assert result is mock_cursor
mock_conn.cursor.assert_called_once()
mock_cursor.execute.assert_not_called()

def test_valid_query_executes_and_returns_cursor(self):
mock_conn = MagicMock()
mock_cursor = MagicMock()
mock_executed_cursor = MagicMock()
mock_conn.cursor.return_value = mock_cursor
mock_cursor.execute.return_value = mock_executed_cursor

result = execute_snowflake_statement(mock_conn, "SELECT 1")

assert result is mock_executed_cursor
mock_cursor.execute.assert_called_once_with("SELECT 1")

def test_valid_query_raises_on_none_cursor(self):
mock_conn = MagicMock()
mock_cursor = MagicMock()
mock_conn.cursor.return_value = mock_cursor
mock_cursor.execute.return_value = None

with pytest.raises(Exception, match="Snowflake query failed"):
execute_snowflake_statement(mock_conn, "SELECT 1")