From 3096f844fb814dd5b812378e759ae767beafde9f Mon Sep 17 00:00:00 2001 From: yangdx Date: Tue, 18 Nov 2025 21:58:36 +0800 Subject: [PATCH] fix(postgres): allow vchordrq.epsilon config when probes is empty Previously, configure_vchordrq would fail silently when probes was empty (the default), preventing epsilon from being configured. Now each parameter is handled independently with conditional execution, and configuration errors fail-fast instead of being swallowed. This fixes the documented epsilon setting being impossible to use in the default configuration. --- lightrag/kg/postgres_impl.py | 39 ++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/lightrag/kg/postgres_impl.py b/lightrag/kg/postgres_impl.py index dcd87250..ba5ec6d7 100644 --- a/lightrag/kg/postgres_impl.py +++ b/lightrag/kg/postgres_impl.py @@ -413,12 +413,27 @@ class PostgreSQLDB: pass async def configure_vchordrq(self, connection: asyncpg.Connection) -> None: - """Configure VCHORDRQ extension for vector similarity search.""" - try: + """Configure VCHORDRQ extension for vector similarity search. + + Raises: + asyncpg.exceptions.UndefinedObjectError: If VCHORDRQ extension is not installed + asyncpg.exceptions.InvalidParameterValueError: If parameter value is invalid + + Note: + This method does not catch exceptions. Configuration errors will fail-fast, + while transient connection errors will be retried by _run_with_retry. + """ + # Handle probes parameter - only set if non-empty value is provided + if self.vchordrq_probes and str(self.vchordrq_probes).strip(): await connection.execute(f"SET vchordrq.probes TO '{self.vchordrq_probes}'") + logger.debug(f"PostgreSQL, VCHORDRQ probes set to: {self.vchordrq_probes}") + + # Handle epsilon parameter independently - check for None to allow 0.0 as valid value + if self.vchordrq_epsilon is not None: await connection.execute(f"SET vchordrq.epsilon TO {self.vchordrq_epsilon}") - except Exception: - pass + logger.debug( + f"PostgreSQL, VCHORDRQ epsilon set to: {self.vchordrq_epsilon}" + ) async def _migrate_llm_cache_schema(self): """Migrate LLM cache schema: add new columns and remove deprecated mode field""" @@ -1388,12 +1403,14 @@ class PostgreSQLDB: CREATE INDEX {{vector_index_name}} ON {{k}} USING vchordrq (content_vector vector_cosine_ops) {f'WITH (options = $${self.vchordrq_build_options}$$)' if self.vchordrq_build_options else ''} - """ + """, } embedding_dim = int(os.environ.get("EMBEDDING_DIM", 1024)) for k in vdb_tables: - vector_index_name = f"idx_{k.lower()}_{self.vector_index_type.lower()}_cosine" + vector_index_name = ( + f"idx_{k.lower()}_{self.vector_index_type.lower()}_cosine" + ) check_vector_index_sql = f""" SELECT 1 FROM pg_indexes WHERE indexname = '{vector_index_name}' AND tablename = '{k.lower()}' @@ -1405,8 +1422,14 @@ class PostgreSQLDB: alter_sql = f"ALTER TABLE {k} ALTER COLUMN content_vector TYPE VECTOR({embedding_dim})" await self.execute(alter_sql) logger.debug(f"Ensured vector dimension for {k}") - logger.info(f"Creating {self.vector_index_type} index {vector_index_name} on table {k}") - await self.execute(create_sql[self.vector_index_type].format(vector_index_name=vector_index_name, k=k)) + logger.info( + f"Creating {self.vector_index_type} index {vector_index_name} on table {k}" + ) + await self.execute( + create_sql[self.vector_index_type].format( + vector_index_name=vector_index_name, k=k + ) + ) logger.info( f"Successfully created vector index {vector_index_name} on table {k}" )