Skip to content

fix(sqlserver): use not_in for $nin metadata filter operator - #853

Merged
Folashade Daniel (beccadaniel) merged 1 commit into
langchain-ai:mainfrom
0xDevNinja:fix/sqlserver-nin-operator-v2
Jul 22, 2026
Merged

fix(sqlserver): use not_in for $nin metadata filter operator#853
Folashade Daniel (beccadaniel) merged 1 commit into
langchain-ai:mainfrom
0xDevNinja:fix/sqlserver-nin-operator-v2

Conversation

@0xDevNinja

Copy link
Copy Markdown
Contributor

Description

Re-opens #812, which was merged and then reverted in #852 because the test it added broke CI.

The original bug (still present on main after the revert): _handle_field_filter handles the $nin operator with

return queried_field.nin_([str(val) for val in filter_value])

SQLAlchemy has no nin_ method, so any $nin metadata filter raises AttributeError at query time. The supported API is not_in.

What caused the revert, and the fix

tests/unit_tests/test_filters.py builds the store with __new__ (to avoid needing a live DB), so it must set every attribute _get_embedding_store reads. Between when #812 was opened and when it merged, the use_binary_collation work (#801) landed and made _get_embedding_store read self._use_binary_collation. The test helper did not set it, so once #812 merged, main failed with:

AttributeError: SQLServerVectorStore object has no attribute _use_binary_collation

This PR is the original one-line source fix plus the test helper now setting _use_binary_collation = False. Rebased on current main, so it accounts for the collation change.

Testing

tests/unit_tests/test_filters.py covers $nin, $in and $like by compiling the filter expression to SQL, so no live database is required. Verified against current main: full sqlserver unit suite passes (17 passed, 1 skipped) and make lint (ruff + ruff format + mypy) is clean.

Sorry for the CI breakage on the first attempt -- I have double-checked this one against the post-collation main.

Re-lands the fix from langchain-ai#812, which was reverted in langchain-ai#852 because its test
broke CI.

`_handle_field_filter` called `queried_field.nin_(...)` for the `$nin`
operator, but SQLAlchemy has no `nin_` method, so any `$nin` filter raised
AttributeError at query time. Use `not_in`, the supported API.

The test helper builds the store via `__new__`, so it must set every
attribute `_get_embedding_store` reads. It now also sets
`_use_binary_collation`, which that method started requiring after the
binary-collation option landed -- the omission is what failed CI and caused
the revert.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes SQL Server metadata filtering for the $nin operator by using SQLAlchemy’s supported not_in operator, and reintroduces unit coverage that validates the compiled SQL without requiring a live database.

Changes:

  • Replace the invalid nin_ call with not_in for $nin metadata filters in _handle_field_filter.
  • Add unit tests that compile filter expressions to MSSQL SQL to validate $nin, $in, and $like.
  • Update the test store factory to set _use_binary_collation so _get_embedding_store works when constructing via __new__.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
libs/sqlserver/langchain_sqlserver/vectorstores.py Fix $nin implementation to use not_in instead of a nonexistent nin_ method.
libs/sqlserver/tests/unit_tests/test_filters.py Add compile-only unit tests for $nin/$in/$like and ensure _use_binary_collation is set in the test helper.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread libs/sqlserver/tests/unit_tests/test_filters.py
@beccadaniel
Folashade Daniel (beccadaniel) merged commit 42f166f into langchain-ai:main Jul 22, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants