From def46f9c135b79cbf3f10cb140e5a64c4fef54a5 Mon Sep 17 00:00:00 2001 From: liangming Date: Sun, 23 Aug 2026 14:37:12 +0800 Subject: [PATCH] Render PostgreSQL filter clauses as SQL --- python/semantic_kernel/connectors/postgres.py | 6 ++++-- .../connectors/memory/test_postgres_store.py | 20 ++++++++++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/python/semantic_kernel/connectors/postgres.py b/python/semantic_kernel/connectors/postgres.py index 5a7e66c15880..24ee3b40f320 100644 --- a/python/semantic_kernel/connectors/postgres.py +++ b/python/semantic_kernel/connectors/postgres.py @@ -795,9 +795,11 @@ def _construct_vector_query( if where_clauses := self._build_filter(options.filter): # type: ignore query += ( - sql.SQL("WHERE {clause}").format(clause=sql.SQL(" AND ").join(where_clauses)) + sql.SQL("WHERE {clause}").format( + clause=sql.SQL(" AND ").join(sql.SQL(clause) for clause in where_clauses) + ) if isinstance(where_clauses, list) - else sql.SQL("WHERE {clause}").format(clause=where_clauses) + else sql.SQL("WHERE {clause}").format(clause=sql.SQL(where_clauses)) ) query += sql.SQL(" ORDER BY {dist_col} LIMIT {limit}").format( diff --git a/python/tests/unit/connectors/memory/test_postgres_store.py b/python/tests/unit/connectors/memory/test_postgres_store.py index 8f417cf7036b..68dbc87fa959 100644 --- a/python/tests/unit/connectors/memory/test_postgres_store.py +++ b/python/tests/unit/connectors/memory/test_postgres_store.py @@ -17,7 +17,13 @@ PostgresSettings, PostgresStore, ) -from semantic_kernel.data.vector import DistanceFunction, IndexKind, VectorStoreField, vectorstoremodel +from semantic_kernel.data.vector import ( + DistanceFunction, + IndexKind, + VectorSearchOptions, + VectorStoreField, + vectorstoremodel, +) @fixture(scope="function") @@ -322,6 +328,18 @@ def model_post_init(self, context: Any) -> None: assert statement_str == expected_statement +async def test_vector_search_filter_is_rendered_as_sql(vector_store: PostgresStore) -> None: + collection = vector_store.get_collection(collection_name="test_collection", record_type=SimpleDataModel) + assert isinstance(collection, PostgresCollection) + + query, _, _ = collection._construct_vector_query( + [1.0, 2.0, 3.0], + VectorSearchOptions(filter="lambda x: x.id == 1"), + ) + + assert 'WHERE "id" = 1' in query.as_string() + + async def test_model_post_init_conflicting_distance_column_name(vector_store: PostgresStore) -> None: @vectorstoremodel @dataclass