Changelog#
All notable changes to this project are documented on this page.
[v0.6.0] - 2026-10-12#
Changed#
Reworked the Data Step parser and unified row execution in the Rust runtime.
Extended string expressions and
apply()support for registered Python functions.Standard string functions now support Unicode and count characters instead of bytes, similar to K functions.
Custom format/informat catalogs now accept dictionary mappings only.
Added warnings for repeated BY values across MERGE inputs.
Fixed#
Improved missing-value handling and preservation of Arrow values, types, and metadata.
[v0.5.0] - 2026-06-04#
v0.3.x and v0.4.x are treated as internal development milestones, and this section summarizes the changes rolled up into v0.5.0.
Added#
Session.transpose(...)andDatasetView.transpose(...)for minimal PROC TRANSPOSE-like reshaping withby,id,var, andout.Session.assign(...)andDatasetView.assign(...)for ordered Data Step-style column creation with literals, expressions, built-in functions, andcase when ... then ... else ... end, executed left-to-right through Polars column expressions for supported assignment syntax.Built-in
put(...)andinput(...)support in helper expressions, backed by a shared session format / informat registry.Session.dictionary.tables,Session.dictionary.columns,Session.dictionary(name), andDatasetView.dictionaryfor dynamic Arrow-metadata-backed dictionary views.Structured diagnostics now carry span/label/source metadata across parse and validation failures.
Changed#
SubmitResult.format_log()now renders structured diagnostics through the diagnostic renderer, includes error counts, and shows source excerpts when available.Case-insensitive resolution is now applied more consistently across Session/DatasetView column helpers, runtime variable lookup, and
WORK.-prefixed dataset references.The execution pipeline now reserves a
validatestage ahead of input resolution, and rejects unresolved input datasets plusDICTIONARY.*output targets before execution.Unsupported
%let,%put,%*,%macro ... %mend, andproc ... run|quit;blocks are now skipped through parser-based split-stage region detection so surrounding supported code can still execute without string-scanner false positives.Numeric
put(...)formatting now treatswas total width, defaultsdto0, supportszw.dzero-filled output, and keeps limulus’s no-space-padding rule for short values.astype(...)/cast(...)also supportalias=for writing typed results into new columns.Session.sql(...)now supportsDROP TABLE ...and DICTIONARY table queries in addition to read queries andCREATE TABLE ... AS ....Session dataset lookup now strips a
WORK.prefix consistently and normalizes through a shared dataset-key helper.The Rust backend now consumes parser-provided structured AST payloads for
IF/DO/ARRAYand dataset references instead of maintaining a separate subset parse path.Helper pipelines now preserve Arrow metadata and numeric column types more consistently across transpose and Arrow/Polars roundtrips.
The Python backend now has a narrower role, and data handoff is now Arrow-based.
Fixed#
Multi-block
Session.submit(...)now prefers datasets created earlier in the same submit call when a laterSETreuses the same dataset name, preventing stale rows from pre-existing session tables from being mixed into rewritten outputs.
[v0.2.0] - 2026-03-17#
Added#
firstobs=andobs=source dataset optionsSession.sql(query).DatasetView.astype(mapping)for dataset-scoped type conversion in chained workflows.Dataset labels in Arrow schema metadata under
memlabel, and column labels in per-field Arrow metadata.Session.include(path)for loading and executing external Data Step scripts from the current session.DatasetView.select(columns, out=...)for explicit column selection.Dictionary-based
Session.set_option({...})andSession.get_option(...)as reserved session options for future use.
Changed#
Source-side dataset option processing order is now
keep/drop→where→rename→obs/firstobs.out=is now the primary user-facing output parameter for Session/DatasetView column-oriented helpers;DatasetViewno longer exposestarget=andSessionkeeps it only as a compatibility alias.The Python backend implementation was split into
executor_python.py,executor_py_stage.py,executor_py_stmt.py, andexecutor_py_data.py.
Fixed#
Parsing now accepts
MERGE ... END=.
[v0.1.0] - 2026-03-03#
Initial release.