PostgresCollection: string/lambda filter produces an invalid WHERE clause (whole predicate collapsed into a string literal)
Los mantenedores suelen responder en 2 días
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 78/100
Línea de trabajo
Empieza en postgres.py, en _build_filter, _lambda_parser y en el ensamblado de la consulta de búsqueda alrededor de las líneas 796-801; ejecuta la reproducción offline con psycopg del issue para inspeccionar el SQL generado. Se considera terminado cuando los filtros de tipo string y callable producen un predicado booleano WHERE en lugar de un único literal de texto entre comillas, conservando el escape existente y las restricciones de nombres de campo.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Describe the bug
PostgresCollection search filters do not work. The generated SQL wraps the entire
filter predicate in a single quoted string literal instead of emitting it as SQL, so
PostgreSQL receives e.g. WHERE '"name" = ''test''' — a text value, not a boolean
predicate — and rejects it (argument of WHERE must be type boolean, not type text).
This affects both string filters and lambda/callable filters, since both flow through
the same _build_filter -> _lambda_parser -> assembly path.
Root cause
_lambda_parser (postgres.py) returns the predicate as a plain Python str
(f-strings), e.g. '"name" = \'test\''. The search query assembly then does
(postgres.py ~L796-801):
if where_clauses := self._build_filter(options.filter):
query += (
sql.SQL("WHERE {clause}").format(clause=sql.SQL(" AND ").join(where_clauses))
if isinstance(where_clauses, list)
else sql.SQL("WHERE {clause}").format(clause=where_clauses) # where_clauses is a plain str
)
psycopg.sql.SQL(...).format(clause=<plain str>) treats a plain str argument as a
literal value, not as SQL, so the pre-built fragment is quoted and its quotes are
doubled. (sql.SQL(" AND ").join([<plain str>, ...]) does the same for the list case.)
Reproduction (offline; no live DB needed to see the malformed SQL)
semantic-kernel 1.44.1, psycopg 3.3.4 (within the pinned psycopg ~= 3.2), Python 3.12:
from dataclasses import dataclass
from typing import Annotated
from psycopg import sql
from semantic_kernel.data.vector import VectorStoreField, vectorstoremodel
from semantic_kernel.connectors.postgres import PostgresCollection
@vectorstoremodel
@dataclass
class Rec:
id: Annotated[str, VectorStoreField("key")]
name: Annotated[str, VectorStoreField("data")] = ""
vector: Annotated[list[float] | None, VectorStoreField("vector", dimensions=2)] = None
col = PostgresCollection(record_type=Rec, collection_name="c")
wc = col._build_filter("lambda x: x.name == 'test'")
print(repr(wc)) # '"name" = \'test\'' (a plain str)
print(sql.SQL("WHERE {clause}").format(clause=wc).as_string(None))
# -> WHERE '"name" = ''test''' (invalid: the whole predicate is a string literal)
Expected behavior
WHERE "name" = 'test' — the predicate emitted as SQL.
Suggested fix
Mark the pre-built fragment as SQL rather than a value:
clause=sql.SQL(where_clauses) # single
clause=sql.SQL(" AND ").join(sql.SQL(w) for w in where_clauses) # list
Verified this produces the correct WHERE "name" = 'test'.
Security note (so a fix does not regress into injection)
_lambda_parser already escapes string constants (' -> '') and allowlists field
names against the data model, so wrapping the fragment as sql.SQL(...) remains
injection-safe under standard_conforming_strings = on (the PostgreSQL default). If
maintainers prefer, moving values to bound parameters would be more robust than
relying on the manual escaping. I raise this only so the correctness fix is not applied
in a way that turns the currently-collapsed (safe) literal into raw, unescaped SQL.
Notes / limitations
I confirmed the malformed SQL is generated (above); I did not run it against a live
PostgreSQL server, but WHERE '<text>' is rejected by PostgreSQL by design. If there
is a supported configuration where this path works, I'm happy to be corrected.
- Lenguaje dominante
- C#
- Estrellas
- 28.6k
- Forks
- 4.8k
- Merge medio
- 12 h 20 min
- PR fusionados (30 d)
- 12
Preparar el entorno
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de microsoft/semantic-kernel
-
python triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
microsoft/semantic-kernel#14491 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
python triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
microsoft/semantic-kernel#14490 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
Python: [Python] structured_outputs_transform reuses ChatHistory across calls (prompt pollution)Abiertopython triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
microsoft/semantic-kernel#14483 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
.NET python triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
microsoft/semantic-kernel#14482 · 2 comentarios ·
Los mantenedores suelen responder en 2 días
-
Python: [Python] as_agent_framework_tool drops parameter defaults (optionals become required)Abiertopython triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
microsoft/semantic-kernel#14481 ·
Los mantenedores suelen responder en 2 días
Todos los issues de microsoft/semantic-kernel
Issues similares
-
area-ai untriaged
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
dotnet/extensions#7790 ·
Los mantenedores suelen responder en 1 día
-
P2 testing
Dificultad 1/5 Menos de una hora Aptitud para principiantes 90/100
Los mantenedores suelen responder en 1 día
-
area-Infrastructure-coreclr os-ios os-maccatalyst os-tvos untriaged
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
dotnet/runtime#134766 · 3 comentarios ·
Los mantenedores suelen responder en 1 día
-
0 - Backlog Bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
BrighterCommand/Brighter#4444 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
Los mantenedores suelen responder en 1 día