QuackDB's Ecto adapter covers analytical reads plus common write and setup workflows. DuckDB's SQL surface is larger than Ecto's native AST, so coverage is tracked in three buckets:

This file is a roadmap, not a claim of complete DuckDB support.

Coverage matrix

AreaFeaturePathSQL generationReal serverStatus
Basic readsselect/where/order/limit/offsetEcto-nativeyesyescovered
Schema readsfull schema select / Repo.get!/2Ecto-nativeyesyescovered
Parameterspinned params and raw paramsEcto-native/rawyesyescovered
Joinsinner/left/right/full/crossEcto-nativeyesyescovered
Aggregatescount/sum/avg/min/maxEcto-nativepartialyespartial
Analytical aggregatesmedian/quantile/list/string_agg/arg_max/arg_minHelperyesyescovered
Aggregate filterFILTER (WHERE ...)Ecto-nativeyespartialpartial
Groupinggroup by/havingEcto-nativeyesyescovered
CTEsnon-recursive CTEsEcto-nativeyesyescovered
Windowsrow_number/rank/dense_rank/percent_rank/cume_distEcto-nativeyespartialpartial
Windowslag/lead/first_value/last_value/nth_valueFragment/rawpartialnomissing
Windowscustom frame clausesFragment/rawnonomissing
SourcesCSV/Parquet helpersSource helpersyesyescovered
SourcesJSON/XLSX helpersSource helpers/rawpartialpartialpartial
Source analyticssource helper + aggregate/windowEcto-native/sourceyespartialpartial
Nested analyticslist/struct/map functionsFragment/rawpartialnomissing
JSON analyticsjson_extract/path queriesHelper/source/rawyesyespartial
Time seriesdate_trunc/time_bucket/generate_seriesHelper/rawyesyespartial
Grouping extensionsgrouping sets/rollup/cubeRaw SQLnoyespartial
QUALIFYwindow filteringRaw SQLnoyespartial
Pivotingpivot/unpivotRaw SQLnoyespartial
Samplingusing sampleRaw SQLnoyespartial
Set operationsunion/intersect/exceptEcto combinationsyesyescovered
InsertsRepo.insert/2, Repo.insert_all/3Ecto-nativeyesyescovered
UpsertsDO NOTHING, set, inc, replacement fieldsEcto-nativeyesyescovered
Native appendinsert_all(..., insert_method: :append)Adapter optionyesyescovered
Mutationsupdate_all / delete_allEcto-nativeyesyescovered
Schema lifecycleRepo.update/2 / Repo.delete/2Ecto-nativeyesyescovered
Migrationscreate/drop/alter table, rename table/column, indexes, referencesEcto migration DDLyesyescovered
ExplainEcto.Adapters.SQL.explain/4Ecto SQLyesyescovered
Full-text searchBM25 ranking and stemmingEcto helper fragmentsyesyescovered
Advanced joinssemi/anti/asof/positionalRaw SQLnonomissing
DuckDB select extensions* EXCLUDE, * REPLACE, COLUMNS(*)Raw SQLnonomissing
Introspectionsummarize/describe/pragmaRaw SQLnonomissing

Migration boundaries

Basic migration DDL is generated for table creation/drop, column add/drop/modify, table and column renames, references, primary keys, composite primary keys, and ordinary/unique indexes. DuckDB-incompatible index options such as concurrent indexes, covering indexes, raw index options, index comments, custom USING, and nulls_distinct raise explicit QuackDB errors instead of being ignored.

Advanced constraints and comments should be added only where DuckDB can enforce the same semantics. Until then, prefer raw SQL for DuckDB-specific DDL.

Test organization

Coverage should stay split by expression path:

test/quack_db/ecto/sql_generation/
  analytical_test.exs
  aggregates_test.exs
  fragments_test.exs
  migration_test.exs
  source_analytics_test.exs
  sources_test.exs
  update_delete_test.exs
  window_functions_test.exs

test/quack_db/integration/ecto/
  migration_test.exs
  query_test.exs

Use SQL generation tests to pin what QuackDB emits for Ecto-native queries. Use real-server tests for DuckDB-native semantics and raw SQL pass-through.

Boundaries

QuackDB should not try to reimplement all DuckDB syntax as Ecto macros. For DuckDB-specific syntax that Ecto cannot represent cleanly, prefer:

  1. raw SQL through Repo.query/3 or QuackDB.query/4;
  2. QuackDB.Ecto.Analytics for common DuckDB analytical expressions;
  3. QuackDB.Ecto.Spatial for common spatial expressions;
  4. source helpers for table functions such as CSV/Parquet/JSON;
  5. fragment/1 for expressions inside otherwise-normal Ecto queries;
  6. explicit unsupported errors for Ecto AST shapes that would generate misleading SQL.

Future adapter-specific helpers may make sense for repeated patterns such as QUALIFY, lakehouse sources, or Arrow handoff, but those should be added only after the protocol and result semantics are stable.