Repository navigation
Match depends_on in SQLite exactly as did.query does - #235
Merged
Merged
Conversation
did.query documents depends_on(NAME, VALUE) as an exact, case-sensitive match of a dependency's name and value, with only NAME '*' a wildcard, and to_searchstructure/fieldsearch implement exactly that. The SQLite search instead tested meta.depends_on with LIKE "%NAME,VALUE;%", which was neither anchored nor case-sensitive: an empty NAME matched any name, 'id' also matched 'subject_id', 'ID' matched 'id', and '*' inside a name acted as a glob. query_struct_to_sql_str now tests meta.depends_on (stored by doc2sql as 'name1,value1;name2,value2;') with instr: ';' || value must contain ';NAME,VALUE;', or, for '*', value must contain ',VALUE;'. That is still a single SQL test of one row per document, as before. ifnull keeps documents with no dependencies in the result of ~depends_on. A NAME or VALUE that is empty or contains ',' or ';' cannot be matched exactly in that string, so search_doc_ids tests such a query document by document with fieldsearch (brute_force_search), and ranks it last in an AND so that it only sees the documents the other terms found. This is what DID-python's _depends_on_sql_clause does (DID-python#101). TestDependsOnParity runs the same documents and cases on the SQLite search and on fieldsearch; DID-python's tests/test_depends_on_parity.py asserts identical expectations. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014BLjcMbQRXr5MDdivxzYEc
Contributor
did.query(STRUCT) rejected the search structure ('Field names of search
structure do not match expected fields'), so every depends_on that falls
back to brute force (an empty name) errored. Pass field, operation and
parameters to did.query instead.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014BLjcMbQRXr5MDdivxzYEc
hasanysubfield_contains_string / _exact_string returned early when the
field held something other than a struct or cell, skipping the negation at
the end of fieldsearch, so the ~ form reported 'no match' as well. A
document with no dependencies has depends_on = [] once read back from a
database (an empty struct array is saved as []), so ~depends_on('', V) -
searched by brute force - left it out, where the SQL search, brute force on
the document as made, and DID-python all include it. A non-struct value now
simply does not match, and the negation applies as for any other value.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014BLjcMbQRXr5MDdivxzYEc
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #235 +/- ##
==========================================
+ Coverage 66.41% 66.91% +0.50%
==========================================
Files 67 67
Lines 4710 4748 +38
==========================================
+ Hits 3128 3177 +49
+ Misses 1582 1571 -11 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
stevewds
approved these changes
Oct 24, 2026
stevevanhooser
pushed a commit
that referenced
this pull request
Oct 24, 2026
#235 brute-forces the depends_on queries SQL cannot match exactly (isBruteForceDependsOn), and query_struct_to_sql_str now errors on them. search_or_operands keeps such operands out of its SQL batches, so they are searched one at a time by search_doc_ids, which brute-forces them. TestBatchedOr covers depends_on with an empty name, alone in an OR and inside an AND. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Z8rXBFDpnZo3FeCE3ymyZ
stevevanhooser
pushed a commit
that referenced
this pull request
Oct 24, 2026
Resolving the merge with #235 dropped the 'end's that close the last loop of search_or_operands and the function, so it ran on into brute_force_search. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Z8rXBFDpnZo3FeCE3ymyZ
jesshaley
pushed a commit
that referenced
this pull request
Oct 29, 2026
did-schema #235 adds the register rows. Each marker now names its row and each note opens with the row's tag and kind instead of 'unplaced:'. private/jModelFit.m tags carry-136 for fitcurve, carry-137 for vmspikefit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FxKLA8Tbf9cpvDe7fuVeKf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
did.querysaysdepends_on(NAME, VALUE)is an exact, case-sensitive match of a dependency's name and value. Only NAME'*'is a wildcard.to_searchstructureandfieldsearchwork that way.The SQLite search did not.
query_struct_to_sql_strsearchedmeta.depends_onwithLIKE "%NAME,VALUE;%", which is unanchored and ignores case. doc2sql stores that field asname1,value1;name2,value2;. As a result:depends_on('', V)matched any dependency name. Brute force matches none.depends_on('id', V)also matchedsubject_id,V;.depends_on('ID', V)matchedid,V;.*inside a name ('subject*') acted as a wildcard.DID-python already matches exactly (DID-python#101), so the two languages disagreed.
Change
src/did/+did/database.m:New SQL test.
dependsOnSqlMatch(name, value)builds the test withinstr, a plain case-sensitive substring test:instr(';' || ifnull(doc_data.value,''), ';NAME,VALUE;') > 0'*':instr(ifnull(doc_data.value,''), ',VALUE;') > 0This is the same test as DID-python's
_depends_on_sql_clause. It is still one test on onemeta.depends_onrow per document, so it costs about the same as the oldLIKE.Negated form.
ifnullmakes~depends_oninclude documents with no dependencies, as brute force does.Brute-force fallback. A NAME or VALUE that is empty, or that contains
,or;, cannot be matched exactly in the stored string.search_doc_idssends those queries to the newbrute_force_search, which runsfieldsearchon the candidate documents, or on the whole branch if there are none. Inside an AND these terms are searched last, so they only test the documents the other terms found. DID-python does the same.src/did/+did/+datastructures/fieldsearch.m:hasanysubfield_*used to return early when the field held something other than a struct or cell. That skipped the negation, so~depends_onleft the document out.depends_on = [], because an empty struct array is saved as[].~makes it a match. DID-python'sfield_searchalready behaved this way.src/did/+did/query.m: the help text now states the rule.Tests
tests/+did/+unittest/TestDependsOnParity.muses five documents:subject_id→Xid→Xandelement_id→YID→Xelement_id→xIt runs 16 cases on the SQLite search, on
fieldsearch, and inside an AND. The cases cover:'''*'id/subject_id)'subject*'is not a glob~depends_onwith an exact name,'*',''and a case differenceThere is also a test with two
depends_onterms ANDed together. DID-python gets a matchingtests/test_depends_on_parity.pywith the same documents and the same expected results; DID-python main already passes it.Compatibility
NDI-matlab only uses
'*'as a wildcard, and NDI-python moved from''to'*'(Waltham-Data-Science/NDI-python#344), so tightening''does not affect NDI.🤖 Generated with Claude Code
https://claude.ai/code/session_014BLjcMbQRXr5MDdivxzYEc