| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| qsv-20.1.0-x86_64-pc-windows-gnu.zip | 2026-05-18 | 218.5 MB | |
| qsv-20.1.0-x86_64-pc-windows-msvc.zip | 2026-05-18 | 394.8 MB | |
| qsv-20.1.0-x86_64-unknown-linux-gnu.zip | 2026-05-18 | 412.0 MB | |
| qsv-20.1.0-aarch64-unknown-linux-gnu.zip | 2026-05-18 | 57.9 MB | |
| qsv-20.1.0-x86_64-unknown-linux-musl.zip | 2026-05-18 | 63.1 MB | |
| qsv-data-wrangling-20.1.0.plugin | 2026-05-18 | 93.5 kB | |
| qsv-mcp-server-20.1.0.mcpb | 2026-05-18 | 15.3 MB | |
| qsv-20.1.0-aarch64-apple-darwin.zip | 2026-05-18 | 245.4 MB | |
| qsv-20.1.0-aarch64-pc-windows-msvc.zip | 2026-05-18 | 51.4 MB | |
| qsv-20.1.0-powerpc64le-unknown-linux-gnu.zip | 2026-05-18 | 23.7 MB | |
| qsv-20.1.0-s390x-unknown-linux-gnu.zip | 2026-05-18 | 25.8 MB | |
| qsv-20.1.0-geocode-index.rkyv.cities15000 | 2026-05-18 | 23.5 MB | |
| qsv-20.1.0-geocode-index.rkyv.cities15000.sz | 2026-05-18 | 9.4 MB | |
| qsv-20.1.0-geocode-index.rkyv | 2026-05-18 | 23.5 MB | |
| 20.1.0 source code.tar.gz | 2026-05-18 | 20.0 MB | |
| 20.1.0 source code.zip | 2026-05-18 | 20.5 MB | |
| README.md | 2026-05-18 | 12.5 kB | |
| Totals: 17 Items | 1.6 GB | 0 | |
[20.1.0] - 2026-05-18 🤖 The "Synthetic Data" Release 🎲
A feature-packed minor release headlined by a brand-new synthesize command for generating realistic fake CSV data, a much smarter describegpt that can now describe what your columns mean (not just their data types), and new "approximate stats" modes that let stats and frequency keep working on files that are bigger than your computer's memory. No breaking changes — pipelines built on 20.0.0 will upgrade in place.
Highlights
- 🆕
synthesize— generate realistic fake CSVs from a real one. Point it at a source file and it produces a new CSV of any size whose columns look and behave like the original — same value mix, same distribution shape, same null rate — but without any of the original records. Useful for sharing test data, populating staging environments, or building demos without leaking real customer data. - Categorical columns (e.g.
country,status) are rebuilt by sampling the real values in the same proportions they appear. - Numeric and date columns preserve the shape of the distribution, not just the min/max — so the synthetic data has realistic clusters, not a flat random spread.
- Null rates are matched per column.
--seedmakes output fully reproducible — same seed, same file, every time.--dictionary/--infer-content-typeplugs in the newdescribegptContent Types (see next bullet) so columns recognized as e.g.email,phone,city, orcredit_cardare filled with realistic-looking fakes instead of generic random strings.--localepicks from 14 regional flavors (US, FR, JP, etc.) so the fakes match your audience.-
Cross-column correlations (e.g. keeping
city↔zip_codeconsistent within a row) aren't modeled by default — but turning ondescribegpt's--two-passoption (see next bullet) lets the LLM detect related fields, andsynthesizewill then keep those relationships consistent in the generated rows. -
🧠
describegptgot a lot smarter — it can now label what your columns mean. In addition to qsv's existing type detection (Integer, Float, Date, etc.),describegptcan now ask an LLM to classify each column with a semantic label from a 47-token vocabulary covering people, addresses, companies, technical identifiers, and more — so a column of strings isn't just "String", it'semail,street_address,job_title, orcredit_card. These labels are what powerssynthesize's realistic fakes, but they're also useful on their own as auto-generated data dictionaries. --two-passruns the LLM a second time over the ENTIRE Data Dictionary so it can spot relationships between columns (e.g. "this is astate_abbrbecause the next column is azip_code") and fix sloppy first-pass labels. This is also what unlocks cross-column consistency insynthesize(see previous bullet).- Deterministic
unique_idtag — columns where every value is unique (like IDs and UUIDs) are tagged by qsv directly, before the LLM ever sees them. That means the label is 100% reproducible and doesn't drift between LLM versions. - Smarter time/duration handling — duration columns can carry a realistic upper bound (e.g. "0–1 hour") so synthetic latency or TTL values stay believable instead of ranging out to absurd numbers.
--markdown-templatelets you customize the generated Data Dictionary's Markdown output — add your team's review checklist, restructure the per-column layout, whatever fits your docs.-
Lower LLM costs — the default prompts were restructured to stop re-sending the dictionary on every step, measurably cutting token usage on multi-phase runs.
-
📊 Approximate stats for huge files —
statsandfrequencyno longer give up when a file is bigger than your RAM. New opt-in modes use Apache DataSketches algorithms that compute approximate-but-bounded-error answers in a tiny fraction of the memory. Three new modes across two commands: - For
stats:--quantile-method tdigestfor approximate percentiles (t-digest) and--cardinality-method hllfor approximate distinct counts (HyperLogLog). - For
frequency:--sketch-method misra-griesfor approximate top-K most-frequent values (Misra-Gries Frequent Items). - Automatic when you'd otherwise OOM: if qsv detects the file is too big to fit in memory, it now auto-switches to the approximate modes (and tells you which ones), instead of failing. Pass
--quantile-method exact(etc.) to force the precise calculation regardless. - Cache stays correct: the
statscache key now includes the chosen mode, so switching between exact and approximate modes won't accidentally return stale results. - Note: these modes require a "little-endian" CPU, which covers all common hardware (Intel, AMD, Apple Silicon, ARM, etc.). Exotic platforms like IBM s390x get a clear error message instead.
Detailed MCP Server and Cowork Plugin changes are documented in the MCP Server/Cowork Plugin CHANGELOG.
Added
synthesize: new top-level command (see Headline) #3854synthesize:--consistent-fakesfor stable source→fake mapping #3865synthesize:--localeoption for 14 fake-rs locales #3860describegpt:--two-passcross-field Data Dictionary refinement #3863describegpt: deterministicunique_idContent Type for ALL_UNIQUE fields #3862describegpt,synthesize: infer Content Type for temporal fields with LLM-hinted duration cap #3861describegpt,synthesize: 5 new Content Type tokens —street_name,license_plate,industry,profession,ipv6_addressdescribegpt:--markdown-templatefor customizable Markdown output #3834pivotp:--agg quantile@<p>(aliasq@<p>) with linear interpolation #3842stats/frequency: opt-in Apache DataSketches modes — HLL cardinality, Frequent Items top-K #3840stats: widened BLAKE3 fingerprint to cover all streaming stats #3824
Changed
stats/frequency: auto-enable Apache DataSketches estimators (t-digest + HyperLogLog forstats; Misra-Gries Frequent Items forfrequency) whenutil::mem_file_checkreports OOM, in addition to the existing auto-index fallback. Awwarn!is emitted listing the auto-enabled estimators; explicit--quantile-method exact/--cardinality-method exact/--sketch-method exactstill suppresses the auto-enable #3843stats: three opt-in micro-optimizations — simdutf8 output, t-digest quantiles, mode-cardinality cap #3839synthesize: use string-length stats for unstructured text columns #3864describegpt: inline{{ dictionary }}in default description/tags prompts; skip redundant chat-message dictionary injection when the template already inlines itsynthesize: handle both describegpt-wrapped and raw dictionary JSONrefactor: adopt Rust 1.95cfg_select!macro at platform-conditional sites #3846perf: promotebytes_to_cow_strhelper toutiland sweep callsitesperf(moarstats): hint rare branches withcore::hint::cold_path()#3823perf(stats): mark non-UTF-8 branch coldperf(frequency): hint UTF-8 failure as cold in the ignore-case hot loop #3821refactor(stats): shrink and tidyWhichStats#3822refactor(publish): fetch tags and enforce SemVer for debian package releasesrefactor(benchmarks): hardenbenchmarks.sherror handling and cross-platform support #3814deps: bump polars (latest upstream), calamine 0.34→0.35, csvlens fork with bumped arrow, sysinfo 0.38.4→0.39.2, rust_decimal 1.41→1.42, tokio 1.52.1→1.52.3, filetime 0.2.27→0.2.29, jsonschema 0.46.4→0.46.5, rand_xoshiro 0.8.0→0.8.1, redis 1.2.0→1.2.1, qsv-dateparser 0.14→0.15 (adds support for ISO 8601T-separated datetimes without a timezone suffix — e.g.2020-01-15T08:00:00, the form produced by Python'sdatetime.isoformat()withoutastimezone(); previously misclassified byqsv stats --infer-datesasString)- assorted clippy cleanups across
stats,frequency,pivotp,partition
Fixed
stats: preserve length & lex stats when column type widens to String #3856stats: remove duplicate big-endianTDigestStub/HllSketchStubdefs #3857stats: restore big-endian build by giving slot fallbacks an accessible.0#3850stats/frequency: gate Apache DataSketches behind little-endian targets #3847apply/applydp: thousands negative fractions; scope<NULL>toregex_replace#3845moarstats: retry on stats coverage mismatch + fsync joined CSV parent dir #3838moarstats: close fsync race that silently dropped joined columns on macOS #3830util: open subprocess output with write access for fsync (Windows) #3831qsvdp: only list commands actually compiled into the binary #3816 #3819help-md-gen: infer real argument type for Options "Type" column #3858 #3859synthesize: Date/DateTime columns now always usebuild_date()with the source's real min/max bounds — previously, if the LLM (incorrectly) tagged a date column with a faker-mappedcontent_typeliketime(which is time-of-day, e.g.14:30:45) or any other temporal token, either faker branch inColumnGenerator::build()could fire before the type-based match and emit a time-of-day string for a date column. Suppress any LLM-emittedcontent_typefor Date/DateTime columns at function entry so both faker branches fall through to the type-based fallback (regression test intests/test_synthesize.rs::synthesize_date_column_ignores_time_content_type)test(fetch,sample): bind to ephemeral port to fix flaky macOS CI #3827test(moarstats): serially execute some flaky CI tests; add missingserial_test::serialimporttest(stats): fix s390x big-endian quantile-method rejection test
Docs
- AI Policy section added to README.md and CONTRIBUTING.md, with cross-links and contributor attribution guidance
docs-driftCI check added; audit-detected drift fixed #3868- README emoji legend audited and normalized; help docs regenerated #3832
- "Processing Very Large Files" guidance added; large-file recipe inline-comment fixes
stats: explicit Count Reference tables for 47stats/ 55moarstatsmeasures; count conventions clarifiedSTATS_DEFINITIONSaudit;statsDEVELOPER NOTE wordsmithedfeatures: correctedself_updateprobability + nightly sub-features documentation #3833- Test count updated to the verified exact total (3,094)
Full Changelog: https://github.com/dathere/qsv/compare/20.0.0...20.1.0