@@ -164,6 +164,7 @@ def test_vector_distance_methods_exist_on_column() -> None:
164164 column : Column [list [float ]] = Column ("embedding" , Vector (3 ))
165165 assert hasattr (column , "cosine_distance" )
166166 assert hasattr (column , "l2_distance" )
167+ assert hasattr (column , "l1_distance" )
167168 assert hasattr (column , "max_inner_product" )
168169
169170
@@ -183,6 +184,14 @@ def test_vector_l2_distance_postgresql_emits_operator() -> None:
183184 assert "<->" in sql
184185
185186
187+ def test_vector_l1_distance_postgresql_emits_operator () -> None :
188+ """L1 distance compiles to the pgvector ``<+>`` operator on PostgreSQL."""
189+ column : Column [list [float ]] = Column ("embedding" , Vector (3 ))
190+ statement = column .l1_distance ([1.0 , 2.0 , 3.0 ])
191+ sql = str (statement .compile (dialect = postgresql_dialect_mod .dialect ())) # type: ignore[no-untyped-call,unused-ignore]
192+ assert "<+>" in sql
193+
194+
186195def test_vector_max_inner_product_postgresql_emits_operator () -> None :
187196 """Negative inner product compiles to the pgvector ``<#>`` operator on PostgreSQL."""
188197 column : Column [list [float ]] = Column ("embedding" , Vector (3 ))
@@ -209,6 +218,15 @@ def test_vector_l2_distance_oracle_uses_euclidean_metric() -> None:
209218 assert "EUCLIDEAN" in sql
210219
211220
221+ def test_vector_l1_distance_oracle_uses_manhattan_metric () -> None :
222+ """L1 distance maps to the Oracle ``MANHATTAN`` metric."""
223+ column : Column [list [float ]] = Column ("embedding" , Vector (3 ))
224+ statement = column .l1_distance ([1.0 , 2.0 , 3.0 ])
225+ sql = str (statement .compile (dialect = oracle_dialect_mod .dialect ())) # type: ignore[no-untyped-call,unused-ignore]
226+ assert "VECTOR_DISTANCE" in sql
227+ assert "MANHATTAN" in sql
228+
229+
212230def test_vector_max_inner_product_oracle_uses_dot_metric () -> None :
213231 """Negative inner product maps to the Oracle ``DOT`` metric."""
214232 column : Column [list [float ]] = Column ("embedding" , Vector (3 ))
@@ -218,6 +236,16 @@ def test_vector_max_inner_product_oracle_uses_dot_metric() -> None:
218236 assert "DOT" in sql
219237
220238
239+ def test_vector_distance_is_cacheable () -> None :
240+ """Distance expressions generate a SQLAlchemy cache key keyed on operands and metric."""
241+ column : Column [list [float ]] = Column ("embedding" , Vector (3 ))
242+ cosine = column .cosine_distance ([1.0 , 2.0 , 3.0 ])
243+ l2 = column .l2_distance ([1.0 , 2.0 , 3.0 ])
244+ assert cosine ._generate_cache_key () is not None # pyright: ignore[reportPrivateUsage]
245+ assert cosine ._generate_cache_key () == column .cosine_distance ([1.0 , 2.0 , 3.0 ])._generate_cache_key () # pyright: ignore[reportPrivateUsage]
246+ assert cosine ._generate_cache_key () != l2 ._generate_cache_key () # pyright: ignore[reportPrivateUsage]
247+
248+
221249def test_vector_distance_unsupported_dialect_raises () -> None :
222250 """Distance operations require a native vector backend; JSON fallback raises clearly."""
223251 column : Column [list [float ]] = Column ("embedding" , Vector (3 ))
0 commit comments