Repository navigation
ButtercupQL changes data and the database itself, combines queries, and runs from Python and in notebooks. A formal
specification defines the language, and a conformance suite checks it on all four databases.
Added
- Changing data (docs/book/src/changing-data.md):
update,deleteand
insert intoas steps at the end of a query, on the rows the steps before them choose; rows written in the query,
from [{...}]; aselectafter a change for the rows it changed; anddefs that change rows, called on a line of
their own. - Tables and permissions (docs/book/src/tables.md):
create tablewith its columns as
Python's annotations, indexes,alter table,drop tableanddrop index;with transaction:;grantand
revoke; and@stored, which keeps adefin the database as a function, a macro, a view or a procedure. A
script's statements are checked against the tables it creates and changes. - Combining queries (docs/book/src/combining.md) with
+,|,&and-, recursive
named queries, andpivot. - Each in its database's own form, ClickHouse's mutations and parameterized views among them, and refused with a
message where the database has no such thing. - A formal specification (docs/book/src/spec): the lexical structure, the grammar in
EBNF, what each form means, and what each database is given and can't do. A test checks that the grammar defines
every rule it uses and names every word of the language. - The conformance suite (conformance): 143 cases, each a text and the rows or the errors it gives,
from tables written in ButtercupQL, which the tests run on SQLite, PostgreSQL, DuckDB and ClickHouse. bcql compilewrites each statement of a script, ended with;, with its own parameters;--jsongives them as
statements. The language server completes, describes and outlines statements, and the VS Code extension colours
them and shows each in Show SQL. The playground shows each statement's parameters, with examples of changes, a
recursive query and a pivot.- Python:
buttercupql.run(connection, text)compiles a text for the database a connection is to and runs it with
the database's own driver (sqlite3,psycopg,psycopg2,pg8000,duckdb, or aclickhouse_connect
client), as one transaction, and gives the rows with their columns' names.read_schema(connection)reads the
database's tables and the links between them.Compiled.statementsgives each statement of a text. - Notebooks:
%load_ext buttercupql, then a cell under%%bcql dbruns on the connectiondband shows its rows,
as a pandas DataFrame when pandas is installed, with its names checked against the database's own tables first.
Fixed
notof a value that can be missing, such aswhere not notes, kept no row where the value was missing; as
not NoneisTruein Python, it now keeps them. The same holds forandandorread by anot, and for a
truth used as a value:select either = notes or assignee.**with a whole power above 4 usedpower(), which SQLite's builds may leave out: on SQLite, whole powers up to
16 are multiplied out.round()took a half away from 0, as SQL's does: it now takes it to the even neighbour, as Python's does, so
round(2.5)is2, on every database.- A sort before a
selectthat gives a column the name of one it reads, as insort riskand then
select key, risk = -risk, sorted the rows by the new column on every database. InORDER BY, the old column is
now named with its table:ORDER BY cases.risk. ClickHouse reads such a name as the new column wherever it is
written alone, so there the query's columns are all named with their tables, and awherebefore theselect
keeps the rows it means.