Python API¶
The synalog package exposes five functions that take a program (parse, compile, search, compile_all, check) and two that take nothing and return the names Synalog has already reserved (reserved_predicates, builtin_functions). The program functions all accept an optional engine keyword that overrides the program's @Engine annotation (one of sqlite, duckdb, bigquery, psql, presto, trino, databricks; default duckdb) and an optional import_root keyword listing directories where import statements look up .l files (default: the current directory). They raise ValueError on syntax or compilation errors.
parse¶
Parse source and return the AST as a JSON string.
compile¶
Compile a single predicate to SQL.
limit is combined with the @Limit directive: the effective limit is min(limit, @Limit). Use limit/offset for pagination, and make sure every predicate has an @OrderBy so page boundaries are deterministic.
search¶
Compile a predicate to SQL that keeps only rows where some column matches the regular expression pattern. Each column is cast to text and matched with the OR of the per-column conditions, using the target engine's native regex operator (~ on PostgreSQL, REGEXP on SQLite, regexp_matches on DuckDB, REGEXP_LIKE elsewhere). This is a real regular expression, not a SQL LIKE pattern. limit/offset apply to the filtered rows.
compile_all¶
Compile every defined predicate in the program. Returns a mapping predicate_name -> sql.
check¶
Run structural verification. Returns a list of error messages; empty if the program is valid.
reserved_predicates¶
The predicate names Synalog defines itself, sorted: the built-in temporal concepts (Today, Now) and every head of every dialect's library program (Num, Str, Epoch, ArgMax, ...). A program may reference these but must not define them.
builtin_functions¶
The function and operator names Synalog compiles to SQL, sorted (Substr, ToString, Like, IsNull, ...). These live in a different namespace from predicates: they appear in call position, not as relations.
Both lists exist for hosts that resolve references themselves. If your rules live in a database rather than in .l files, check alone cannot tell a typo from a predicate defined elsewhere, so you need to know which names are already taken — and which of them are function calls rather than relational references:
reserved = set(synalog.reserved_predicates()) | set(synalog.builtin_functions())
unknown = [name for name in referenced_names(rule) if name not in reserved | defined_in_catalogue]
Executing the generated SQL¶
Synalog returns SQL strings; execution is up to you. Any driver works: sqlite3, duckdb, psycopg, google-cloud-bigquery, trino, databricks-sql-connector: