SQL-like Queries in FSRS Plugin for Obsidian The FSRS plugin for Obsidian now supports SQL-like queries, allowing users to filter, sort, and select spaced repetition cards using a custom query language embedded in markdown blocks. The plugin processes queries entirely in Rust/WASM, with a hand-written parser that provides readable error messages, and can filter through 5,000 cards in under 0.1 seconds. Spaced repetition in Obsidian usually works as "show all cards with due earlier than today." That's enough for simple cases, but once you have hundreds of notes, you want to filter, sort, and select. My FSRS https://community.obsidian.md/plugins/fsrs plugin now has a query language resembling SQL. It turns a markdown block into a live table that updates with every review. fsrs-table SELECT file as "Note", r as "Retrievability", date format due, '%d.%m.%Y' as "Due" WHERE r < 0.7 ORDER BY r ASC LIMIT 20 → the table shows the 20 most "forgotten" cards, sorted by retrieval probability. Initially I planned to offer table settings using standard SQL syntax. But pretty quickly the syntax became a real query language, and the implementation itself — an embedded lightweight DB. High-level test coverage in TypeScript made it easy to iterate on functionality located in the WASM module via an AI agent. When faced with dual-language testing TypeScript + Rust , the artificial intelligence prefers to do the job properly rather than fake it. After implementing the lexer → parser → AST → evaluator pipeline for numeric values, I extended it to strings, added filtering via WHERE, then functions. Extending the syntax or adding a function came down to a single request to the agent — and a feasibility check. fsrs-table SELECT AS . WHERE = , = , < , , <= , = , AND , OR . ORDER BY ASC or descending DESC . LIMIT date format due date to any text format. Available fields: | Field alias | Type | Description | |---|---|---| file | string | path to the note | due | date | next review date | stability s | number | stability in days | difficulty d | number | difficulty | retrievability r | number | probability of recall 0…1 | reps | number | total number of reviews | state | string | New, Learning, Review, or Relearning | elapsed | number | days since last review | scheduled | number | scheduled interval in days | fsrs-table Can't Do and Shouldn't JOIN , aggregations COUNT , SUM … . INSERT , UPDATE , DELETE . LIMIT doesn't short-circuit processing to guarantee the first N rows by sort order, all cards must be evaluated .This is not a database — it's a filter + sort over a cached set of cards. All query processing happens inside Rust/WASM : SELECT , WHERE , LIMIT , identifiers, operators . // simplified: WHERE clause AST pub enum Expression { Comparison { field: String, operator: ComparisonOp, value: Value, }, Logical { left: Box