├── .cargo └── config.toml ├── .config ├── .markdown-link-check-all.json ├── .markdown-link-check-local.json ├── insta.yaml ├── nextest.toml └── vscode-recommended │ ├── launch.json │ ├── settings.json │ └── tasks.json ├── .devcontainer ├── base-image │ └── Dockerfile └── devcontainer.json ├── .gitattributes ├── .github ├── .codecov.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── bug_report.yaml │ ├── config.yaml │ └── something_else.yaml ├── actions │ ├── build-prqlc-c │ │ └── action.yaml │ ├── build-prqlc │ │ └── action.yaml │ ├── build-python │ │ └── action.yaml │ └── time-compilation │ │ └── action.yaml ├── dependabot.yml ├── nightly-failure.md └── workflows │ ├── README.md │ ├── build-devcontainer.yaml │ ├── build-web.yaml │ ├── lint-megalinter.yaml │ ├── nightly.yaml │ ├── publish-web.yaml │ ├── pull-request-target.yaml │ ├── release.yaml │ ├── scripts │ ├── set_version.sh │ └── util_free_space.sh │ ├── test-dotnet.yaml │ ├── test-elixir.yaml │ ├── test-java.yaml │ ├── test-js.yaml │ ├── test-php.yaml │ ├── test-prqlc-c.yaml │ ├── test-python.yaml │ ├── test-rust.yaml │ └── tests.yaml ├── .gitignore ├── .markdownlint-cli2.yaml ├── .mega-linter.yaml ├── .pre-commit-config.yaml ├── .prettierignore ├── .prettierrc.yaml ├── .sqlfluff ├── .typos.toml ├── .vscode └── extensions.json ├── CHANGELOG.md ├── CLAUDE.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── Taskfile.yaml ├── bacon.toml ├── flake.lock ├── flake.nix ├── grammars ├── CotEditor │ ├── PRQL.yml │ └── README.md ├── GtkSourceView │ ├── README.md │ └── prql.lang ├── KSyntaxHighlighting │ ├── README.md │ └── prql.xml ├── README.md ├── emacs │ ├── README.md │ └── prql-mode.el ├── micro │ ├── README.md │ └── prql.yaml ├── nano │ ├── README.md │ └── prql.nanorc ├── prql-lezer │ ├── .gitignore │ ├── README.md │ ├── dist │ │ ├── index.d.cts │ │ └── index.d.ts │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── highlight.js │ │ └── prql.grammar │ └── test │ │ ├── arithmetics.txt │ │ ├── arrays.txt │ │ ├── datetime.txt │ │ ├── full_queries.txt │ │ ├── identifiers.txt │ │ ├── misc.txt │ │ ├── numbers.txt │ │ ├── operators.txt │ │ ├── strings.txt │ │ ├── test-prql.js │ │ └── tuples.txt └── vim │ └── README.md ├── prqlc ├── README.md ├── Taskfile.yaml ├── bindings │ ├── dotnet │ │ ├── .gitignore │ │ ├── PrqlCompiler.Tests │ │ │ ├── CompilerTest.cs │ │ │ ├── PrqlCompiler.Tests.csproj │ │ │ └── Usings.cs │ │ ├── PrqlCompiler │ │ │ ├── Message.cs │ │ │ ├── MessageKind.cs │ │ │ ├── NativePrqlCompilerOptions.cs │ │ │ ├── NativeResult.cs │ │ │ ├── PrqlCompiler.cs │ │ │ ├── PrqlCompiler.csproj │ │ │ ├── PrqlCompilerOptions.cs │ │ │ ├── Result.cs │ │ │ ├── SourceLocation.cs │ │ │ └── Span.cs │ │ ├── README.md │ │ └── prql-net.sln │ ├── elixir │ │ ├── .formatter.exs │ │ ├── .gitignore │ │ ├── README.md │ │ ├── lib │ │ │ ├── prql.ex │ │ │ └── prql │ │ │ │ ├── errors.ex │ │ │ │ └── native.ex │ │ ├── mix.exs │ │ ├── mix.lock │ │ ├── native │ │ │ └── prql │ │ │ │ ├── .cargo │ │ │ │ └── config.toml │ │ │ │ ├── Cargo.toml │ │ │ │ ├── README.md │ │ │ │ └── src │ │ │ │ └── lib.rs │ │ └── test │ │ │ ├── prql_test.exs │ │ │ └── test_helper.exs │ ├── java │ │ ├── .gitignore │ │ ├── Cargo.toml │ │ ├── DEVELOPMENT.md │ │ ├── README.md │ │ ├── cross.sh │ │ ├── java │ │ │ ├── .mvn │ │ │ │ └── wrapper │ │ │ │ │ ├── maven-wrapper.jar │ │ │ │ │ └── maven-wrapper.properties │ │ │ ├── build.sh │ │ │ ├── mvnw │ │ │ ├── mvnw.cmd │ │ │ ├── pom.xml │ │ │ └── src │ │ │ │ ├── main │ │ │ │ ├── java │ │ │ │ │ └── org │ │ │ │ │ │ └── prql │ │ │ │ │ │ └── prql4j │ │ │ │ │ │ ├── Environment.java │ │ │ │ │ │ ├── NativeLibraryLoader.java │ │ │ │ │ │ └── PrqlCompiler.java │ │ │ │ └── resources │ │ │ │ │ └── .gitkeep │ │ │ │ └── test │ │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── prql │ │ │ │ │ └── prql4j │ │ │ │ │ └── PrqlCompilerTest.java │ │ │ │ └── resources │ │ │ │ └── .gitkeep │ │ └── src │ │ │ └── lib.rs │ ├── js │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ │ └── lib.rs │ │ └── tests │ │ │ └── test_all.mjs │ ├── php │ │ ├── .editorconfig │ │ ├── .gitignore │ │ ├── README.md │ │ ├── composer.json │ │ ├── composer.lock │ │ ├── phpstan.neon │ │ ├── src │ │ │ ├── Compiler.php │ │ │ ├── Message.php │ │ │ ├── MessageKind.php │ │ │ ├── Options.php │ │ │ ├── Result.php │ │ │ ├── SourceLocation.php │ │ │ └── Span.php │ │ └── tests │ │ │ └── CompilerTest.php │ ├── prqlc-c │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── cbindgen.toml │ │ ├── examples │ │ │ ├── minimal-c │ │ │ │ ├── Makefile │ │ │ │ ├── README.md │ │ │ │ └── main.c │ │ │ ├── minimal-cpp │ │ │ │ ├── Makefile │ │ │ │ ├── README.md │ │ │ │ └── main.cpp │ │ │ └── minimal-zig │ │ │ │ ├── .gitignore │ │ │ │ ├── README.md │ │ │ │ ├── Taskfile.yaml │ │ │ │ ├── build.zig │ │ │ │ └── src │ │ │ │ └── main.zig │ │ ├── prqlc.h │ │ ├── prqlc.hpp │ │ └── src │ │ │ └── lib.rs │ └── prqlc-python │ │ ├── .gitignore │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── Taskfile.yaml │ │ ├── build.rs │ │ ├── noxfile.py │ │ ├── pyproject.toml │ │ ├── python │ │ ├── prqlc │ │ │ ├── __init__.py │ │ │ ├── __init__.pyi │ │ │ ├── debug.pyi │ │ │ └── py.typed │ │ └── tests │ │ │ └── test_all.py │ │ └── src │ │ └── lib.rs ├── packages │ └── snap │ │ └── snapcraft.yaml ├── prqlc-macros │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── prqlc-parser │ ├── Cargo.toml │ └── src │ │ ├── error.rs │ │ ├── generic.rs │ │ ├── lexer │ │ ├── lr.rs │ │ ├── mod.rs │ │ └── test.rs │ │ ├── lib.rs │ │ ├── parser │ │ ├── expr.rs │ │ ├── interpolation.rs │ │ ├── mod.rs │ │ ├── perror.rs │ │ ├── pr │ │ │ ├── expr.rs │ │ │ ├── ident.rs │ │ │ ├── mod.rs │ │ │ ├── ops.rs │ │ │ ├── stmt.rs │ │ │ └── types.rs │ │ ├── stmt.rs │ │ ├── test.rs │ │ └── types.rs │ │ ├── snapshots │ │ └── prqlc_parser__test__pipeline_parse_tree.snap │ │ ├── span.rs │ │ └── test.rs └── prqlc │ ├── ARCHITECTURE.md │ ├── Cargo.toml │ ├── README.md │ ├── benches │ └── bench.rs │ ├── build.rs │ ├── examples │ └── compile-files │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── build.rs │ │ ├── queries │ │ ├── query1.prql │ │ └── variables.prql │ │ └── src │ │ └── main.rs │ ├── src │ ├── cli │ │ ├── docs_generator.rs │ │ ├── highlight.rs │ │ ├── jinja.rs │ │ ├── lsp.rs │ │ ├── mod.rs │ │ ├── snapshots │ │ │ ├── prqlc__cli__test__shell_completion-2.snap │ │ │ ├── prqlc__cli__test__shell_completion-3.snap │ │ │ ├── prqlc__cli__test__shell_completion-4.snap │ │ │ └── prqlc__cli__test__shell_completion.snap │ │ ├── test.rs │ │ └── watch.rs │ ├── codegen │ │ ├── ast.rs │ │ ├── mod.rs │ │ └── types.rs │ ├── debug │ │ ├── log.rs │ │ ├── messages.rs │ │ ├── mod.rs │ │ └── render_html.rs │ ├── error_message.rs │ ├── ir │ │ ├── decl.rs │ │ ├── generic.rs │ │ ├── mod.rs │ │ ├── pl │ │ │ ├── expr.rs │ │ │ ├── extra.rs │ │ │ ├── fold.rs │ │ │ ├── lineage.rs │ │ │ ├── mod.rs │ │ │ ├── stmt.rs │ │ │ └── utils.rs │ │ └── rq │ │ │ ├── expr.rs │ │ │ ├── fold.rs │ │ │ ├── ids.rs │ │ │ ├── mod.rs │ │ │ ├── transform.rs │ │ │ └── utils.rs │ ├── lib.rs │ ├── main.rs │ ├── parser.rs │ ├── semantic │ │ ├── ast_expand.rs │ │ ├── lowering.rs │ │ ├── mod.rs │ │ ├── module.rs │ │ ├── reporting.rs │ │ ├── resolver │ │ │ ├── expr.rs │ │ │ ├── flatten.rs │ │ │ ├── functions.rs │ │ │ ├── inference.rs │ │ │ ├── mod.rs │ │ │ ├── names.rs │ │ │ ├── snapshots │ │ │ │ ├── prqlc__semantic__resolver__test__frames_and_names-2.snap │ │ │ │ ├── prqlc__semantic__resolver__test__frames_and_names-3.snap │ │ │ │ ├── prqlc__semantic__resolver__test__frames_and_names.snap │ │ │ │ ├── prqlc__semantic__resolver__test__functions_1.snap │ │ │ │ ├── prqlc__semantic__resolver__test__functions_nested.snap │ │ │ │ ├── prqlc__semantic__resolver__test__functions_pipeline-2.snap │ │ │ │ ├── prqlc__semantic__resolver__test__functions_pipeline.snap │ │ │ │ ├── prqlc__semantic__resolver__test__named_args.snap │ │ │ │ ├── prqlc__semantic__resolver__test__variables_1.snap │ │ │ │ └── prqlc__semantic__resolver__transforms__tests__aggregate_positional_arg-2.snap │ │ │ ├── static_eval.rs │ │ │ ├── stmt.rs │ │ │ ├── transforms.rs │ │ │ └── types.rs │ │ └── std.prql │ ├── sql │ │ ├── dialect.rs │ │ ├── gen_expr.rs │ │ ├── gen_projection.rs │ │ ├── gen_query.rs │ │ ├── keywords.rs │ │ ├── mod.rs │ │ ├── operators.rs │ │ ├── pq │ │ │ ├── anchor.rs │ │ │ ├── ast.rs │ │ │ ├── context.rs │ │ │ ├── gen_query.rs │ │ │ ├── mod.rs │ │ │ ├── postprocess.rs │ │ │ └── preprocess.rs │ │ └── std.sql.prql │ └── utils │ │ ├── id_gen.rs │ │ ├── mod.rs │ │ └── toposort.rs │ └── tests │ └── integration │ ├── bad_error_messages.rs │ ├── data │ └── chinook │ │ ├── albums.csv │ │ ├── artists.csv │ │ ├── customers.csv │ │ ├── employees.csv │ │ ├── genres.csv │ │ ├── invoice_items.csv │ │ ├── invoices.csv │ │ ├── media_types.csv │ │ ├── playlist_track.csv │ │ ├── playlists.csv │ │ ├── schema.sql │ │ └── tracks.csv │ ├── dbs │ ├── README.md │ ├── docker-compose.yml │ ├── dockerfiles │ │ └── glaredb.Dockerfile │ ├── mod.rs │ ├── protocol.rs │ └── runner.rs │ ├── error_messages.rs │ ├── main.rs │ ├── project │ ├── Project.prql │ └── artists.prql │ ├── queries.rs │ ├── queries │ ├── aggregation.prql │ ├── arithmetic.prql │ ├── cast.prql │ ├── constants_only.prql │ ├── date_to_text.prql │ ├── distinct.prql │ ├── distinct_on.prql │ ├── genre_counts.prql │ ├── group_all.prql │ ├── group_sort.prql │ ├── group_sort_limit_take.prql │ ├── invoice_totals.prql │ ├── loop_01.prql │ ├── math_module.prql │ ├── pipelines.prql │ ├── read_csv.prql │ ├── set_ops_remove.prql │ ├── sort.prql │ ├── sort_2.prql │ ├── sort_3.prql │ ├── switch.prql │ ├── take.prql │ ├── text_module.prql │ └── window.prql │ ├── snapshots │ ├── integration__queries__compile__aggregation.snap │ ├── integration__queries__compile__arithmetic.snap │ ├── integration__queries__compile__cast.snap │ ├── integration__queries__compile__constants_only.snap │ ├── integration__queries__compile__distinct.snap │ ├── integration__queries__compile__distinct_on.snap │ ├── integration__queries__compile__genre_counts.snap │ ├── integration__queries__compile__group_all.snap │ ├── integration__queries__compile__group_sort.snap │ ├── integration__queries__compile__group_sort_limit_take.snap │ ├── integration__queries__compile__invoice_totals.snap │ ├── integration__queries__compile__loop_01.snap │ ├── integration__queries__compile__math_module.snap │ ├── integration__queries__compile__pipelines.snap │ ├── integration__queries__compile__read_csv.snap │ ├── integration__queries__compile__set_ops_remove.snap │ ├── integration__queries__compile__sort.snap │ ├── integration__queries__compile__sort_2.snap │ ├── integration__queries__compile__sort_3.snap │ ├── integration__queries__compile__switch.snap │ ├── integration__queries__compile__take.snap │ ├── integration__queries__compile__text_module.snap │ ├── integration__queries__compile__window.snap │ ├── integration__queries__debug_lineage__aggregation.snap │ ├── integration__queries__debug_lineage__arithmetic.snap │ ├── integration__queries__debug_lineage__cast.snap │ ├── integration__queries__debug_lineage__constants_only.snap │ ├── integration__queries__debug_lineage__date_to_text.snap │ ├── integration__queries__debug_lineage__distinct.snap │ ├── integration__queries__debug_lineage__distinct_on.snap │ ├── integration__queries__debug_lineage__genre_counts.snap │ ├── integration__queries__debug_lineage__group_all.snap │ ├── integration__queries__debug_lineage__group_sort.snap │ ├── integration__queries__debug_lineage__group_sort_limit_take.snap │ ├── integration__queries__debug_lineage__invoice_totals.snap │ ├── integration__queries__debug_lineage__loop_01.snap │ ├── integration__queries__debug_lineage__math_module.snap │ ├── integration__queries__debug_lineage__pipelines.snap │ ├── integration__queries__debug_lineage__read_csv.snap │ ├── integration__queries__debug_lineage__set_ops_remove.snap │ ├── integration__queries__debug_lineage__sort.snap │ ├── integration__queries__debug_lineage__sort_2.snap │ ├── integration__queries__debug_lineage__sort_3.snap │ ├── integration__queries__debug_lineage__switch.snap │ ├── integration__queries__debug_lineage__take.snap │ ├── integration__queries__debug_lineage__text_module.snap │ ├── integration__queries__debug_lineage__window.snap │ ├── integration__queries__fmt__aggregation.snap │ ├── integration__queries__fmt__arithmetic.snap │ ├── integration__queries__fmt__cast.snap │ ├── integration__queries__fmt__constants_only.snap │ ├── integration__queries__fmt__date_to_text.snap │ ├── integration__queries__fmt__distinct.snap │ ├── integration__queries__fmt__distinct_on.snap │ ├── integration__queries__fmt__genre_counts.snap │ ├── integration__queries__fmt__group_all.snap │ ├── integration__queries__fmt__group_sort.snap │ ├── integration__queries__fmt__group_sort_limit_take.snap │ ├── integration__queries__fmt__invoice_totals.snap │ ├── integration__queries__fmt__loop_01.snap │ ├── integration__queries__fmt__math_module.snap │ ├── integration__queries__fmt__pipelines.snap │ ├── integration__queries__fmt__read_csv.snap │ ├── integration__queries__fmt__set_ops_remove.snap │ ├── integration__queries__fmt__sort.snap │ ├── integration__queries__fmt__sort_2.snap │ ├── integration__queries__fmt__sort_3.snap │ ├── integration__queries__fmt__switch.snap │ ├── integration__queries__fmt__take.snap │ ├── integration__queries__fmt__text_module.snap │ ├── integration__queries__fmt__window.snap │ ├── integration__queries__lex__aggregation.snap │ ├── integration__queries__lex__arithmetic.snap │ ├── integration__queries__lex__cast.snap │ ├── integration__queries__lex__constants_only.snap │ ├── integration__queries__lex__date_to_text.snap │ ├── integration__queries__lex__distinct.snap │ ├── integration__queries__lex__distinct_on.snap │ ├── integration__queries__lex__genre_counts.snap │ ├── integration__queries__lex__group_all.snap │ ├── integration__queries__lex__group_sort.snap │ ├── integration__queries__lex__group_sort_limit_take.snap │ ├── integration__queries__lex__invoice_totals.snap │ ├── integration__queries__lex__loop_01.snap │ ├── integration__queries__lex__math_module.snap │ ├── integration__queries__lex__pipelines.snap │ ├── integration__queries__lex__read_csv.snap │ ├── integration__queries__lex__set_ops_remove.snap │ ├── integration__queries__lex__sort.snap │ ├── integration__queries__lex__sort_2.snap │ ├── integration__queries__lex__sort_3.snap │ ├── integration__queries__lex__switch.snap │ ├── integration__queries__lex__take.snap │ ├── integration__queries__lex__text_module.snap │ ├── integration__queries__lex__window.snap │ ├── integration__queries__results__aggregation.snap │ ├── integration__queries__results__arithmetic.snap │ ├── integration__queries__results__cast.snap │ ├── integration__queries__results__constants_only.snap │ ├── integration__queries__results__date_to_text.snap │ ├── integration__queries__results__distinct.snap │ ├── integration__queries__results__distinct_on.snap │ ├── integration__queries__results__genre_counts.snap │ ├── integration__queries__results__group_all.snap │ ├── integration__queries__results__group_sort.snap │ ├── integration__queries__results__group_sort_limit_take.snap │ ├── integration__queries__results__invoice_totals.snap │ ├── integration__queries__results__loop_01.snap │ ├── integration__queries__results__math_module.snap │ ├── integration__queries__results__pipelines.snap │ ├── integration__queries__results__read_csv.snap │ ├── integration__queries__results__set_ops_remove.snap │ ├── integration__queries__results__sort.snap │ ├── integration__queries__results__sort_2.snap │ ├── integration__queries__results__sort_3.snap │ ├── integration__queries__results__switch.snap │ ├── integration__queries__results__take.snap │ ├── integration__queries__results__text_module.snap │ └── integration__queries__results__window.snap │ └── sql.rs ├── rust-toolchain.toml └── web ├── .gitignore ├── Taskfile.yaml ├── book ├── Cargo.toml ├── README.md ├── book.toml ├── comparison-table.css ├── highlight-prql.js ├── mdbook-admonish.css ├── src │ ├── README.md │ ├── SUMMARY.md │ ├── lib.rs │ ├── main.rs │ ├── project │ │ ├── bindings │ │ │ ├── README.md │ │ │ ├── dotnet.md │ │ │ ├── elixir.md │ │ │ ├── java.md │ │ │ ├── javascript.md │ │ │ ├── php.md │ │ │ ├── python.md │ │ │ ├── r.md │ │ │ └── rust.md │ │ ├── changelog.md │ │ ├── contributing │ │ │ ├── README.md │ │ │ ├── development.md │ │ │ ├── fortnightly-dev-call.ics │ │ │ └── language-design.md │ │ ├── integrations │ │ │ ├── README.md │ │ │ ├── clickhouse.md │ │ │ ├── databend.md │ │ │ ├── duckdb.md │ │ │ ├── jupyter.md │ │ │ ├── postgresql.md │ │ │ ├── prefect.md │ │ │ ├── prqlc-cli.md │ │ │ ├── qstudio.md │ │ │ ├── rill.md │ │ │ ├── syntax-highlighting.md │ │ │ └── vscode.md │ │ └── target.md │ ├── reference │ │ ├── data │ │ │ ├── README.md │ │ │ ├── from.md │ │ │ ├── read-files.md │ │ │ └── relation-literals.md │ │ ├── declarations │ │ │ ├── README.md │ │ │ ├── functions.md │ │ │ └── variables.md │ │ ├── spec │ │ │ ├── README.md │ │ │ ├── modules.md │ │ │ ├── name-resolution.md │ │ │ ├── null.md │ │ │ └── type-system.md │ │ ├── stdlib │ │ │ ├── README.md │ │ │ ├── date.md │ │ │ ├── distinct.md │ │ │ ├── math.md │ │ │ ├── text.md │ │ │ └── transforms │ │ │ │ ├── README.md │ │ │ │ ├── aggregate.md │ │ │ │ ├── append.md │ │ │ │ ├── derive.md │ │ │ │ ├── filter.md │ │ │ │ ├── group.md │ │ │ │ ├── join.md │ │ │ │ ├── loop.md │ │ │ │ ├── select.md │ │ │ │ ├── sort.md │ │ │ │ ├── take.md │ │ │ │ └── window.md │ │ └── syntax │ │ │ ├── README.md │ │ │ ├── arrays.md │ │ │ ├── case.md │ │ │ ├── comments.md │ │ │ ├── f-strings.md │ │ │ ├── function-calls.md │ │ │ ├── keywords.md │ │ │ ├── literals.md │ │ │ ├── operators.md │ │ │ ├── parameters.md │ │ │ ├── pipes.md │ │ │ ├── r-strings.md │ │ │ ├── ranges.md │ │ │ ├── s-strings.md │ │ │ ├── strings.md │ │ │ └── tuples.md │ └── tutorial │ │ ├── aggregation.md │ │ ├── annotated_example.md │ │ ├── filtering.md │ │ └── relations.md ├── tests │ └── documentation │ │ ├── README.md │ │ ├── book.rs │ │ ├── main.rs │ │ ├── readme.rs │ │ ├── snapshots │ │ ├── documentation__book__README__prql-language-book__0.snap │ │ ├── documentation__book__README__prql-language-book__1.snap │ │ ├── documentation__book__project__target__examples__0.snap │ │ ├── documentation__book__project__target__examples__1.snap │ │ ├── documentation__book__project__target__version__0.snap │ │ ├── documentation__book__project__target__version__1.snap │ │ ├── documentation__book__reference__data__from__0.snap │ │ ├── documentation__book__reference__data__from__1.snap │ │ ├── documentation__book__reference__data__from__2.snap │ │ ├── documentation__book__reference__data__from__3.snap │ │ ├── documentation__book__reference__data__read-files__reading-files__0.snap │ │ ├── documentation__book__reference__data__read-files__reading-files__1.snap │ │ ├── documentation__book__reference__data__relation-literals__array-literals__0.snap │ │ ├── documentation__book__reference__data__relation-literals__array-literals__1.snap │ │ ├── documentation__book__reference__data__relation-literals__array-literals__2.snap │ │ ├── documentation__book__reference__data__relation-literals__array-literals__3.snap │ │ ├── documentation__book__reference__data__relation-literals__array-literals__4.snap │ │ ├── documentation__book__reference__declarations__functions__0.snap │ │ ├── documentation__book__reference__declarations__functions__1.snap │ │ ├── documentation__book__reference__declarations__functions__late-binding__0.snap │ │ ├── documentation__book__reference__declarations__functions__other-examples__0.snap │ │ ├── documentation__book__reference__declarations__functions__piping-values-into-functions__0.snap │ │ ├── documentation__book__reference__declarations__functions__piping-values-into-functions__1.snap │ │ ├── documentation__book__reference__declarations__functions__piping-values-into-functions__2.snap │ │ ├── documentation__book__reference__declarations__variables__variables--__0.snap │ │ ├── documentation__book__reference__declarations__variables__variables--__1.snap │ │ ├── documentation__book__reference__declarations__variables__variables--__2.snap │ │ ├── documentation__book__reference__spec__name-resolution__translating-to-sql__0.snap │ │ ├── documentation__book__reference__spec__name-resolution__translating-to-sql__1.snap │ │ ├── documentation__book__reference__spec__null__null-handling__0.snap │ │ ├── documentation__book__reference__stdlib__README__standard-library__0.snap │ │ ├── documentation__book__reference__stdlib__README__standard-library__1.snap │ │ ├── documentation__book__reference__stdlib__README__standard-library__2.snap │ │ ├── documentation__book__reference__stdlib__date__date-functions__0.snap │ │ ├── documentation__book__reference__stdlib__date__date-functions__1.snap │ │ ├── documentation__book__reference__stdlib__date__date-functions__2.snap │ │ ├── documentation__book__reference__stdlib__distinct__how-do-i-remove-duplicates__0.snap │ │ ├── documentation__book__reference__stdlib__distinct__how-do-i-remove-duplicates__1.snap │ │ ├── documentation__book__reference__stdlib__distinct__remove-duplicates-from-each-group__0.snap │ │ ├── documentation__book__reference__stdlib__distinct__remove-duplicates-from-each-group__1.snap │ │ ├── documentation__book__reference__stdlib__math__example__0.snap │ │ ├── documentation__book__reference__stdlib__text__example__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__aggregate__aggregate-is-required__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__aggregate__examples__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__aggregate__examples__1.snap │ │ ├── documentation__book__reference__stdlib__transforms__append__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__append__intersection__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__append__remove__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__derive__examples__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__derive__examples__1.snap │ │ ├── documentation__book__reference__stdlib__transforms__filter__examples__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__filter__examples__1.snap │ │ ├── documentation__book__reference__stdlib__transforms__filter__examples__2.snap │ │ ├── documentation__book__reference__stdlib__transforms__filter__examples__3.snap │ │ ├── documentation__book__reference__stdlib__transforms__group__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__group__1.snap │ │ ├── documentation__book__reference__stdlib__transforms__group__2.snap │ │ ├── documentation__book__reference__stdlib__transforms__join__examples__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__join__examples__1.snap │ │ ├── documentation__book__reference__stdlib__transforms__join__examples__2.snap │ │ ├── documentation__book__reference__stdlib__transforms__join__examples__3.snap │ │ ├── documentation__book__reference__stdlib__transforms__join__examples__4.snap │ │ ├── documentation__book__reference__stdlib__transforms__loop__examples__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__select__examples__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__select__examples__1.snap │ │ ├── documentation__book__reference__stdlib__transforms__select__examples__2.snap │ │ ├── documentation__book__reference__stdlib__transforms__select__examples__3.snap │ │ ├── documentation__book__reference__stdlib__transforms__select__excluding-columns__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__select__excluding-columns__1.snap │ │ ├── documentation__book__reference__stdlib__transforms__select__excluding-columns__2.snap │ │ ├── documentation__book__reference__stdlib__transforms__select__excluding-columns__3.snap │ │ ├── documentation__book__reference__stdlib__transforms__sort__examples__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__sort__examples__1.snap │ │ ├── documentation__book__reference__stdlib__transforms__sort__examples__2.snap │ │ ├── documentation__book__reference__stdlib__transforms__sort__examples__3.snap │ │ ├── documentation__book__reference__stdlib__transforms__sort__ordering-guarantees__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__take__examples__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__take__examples__1.snap │ │ ├── documentation__book__reference__stdlib__transforms__window__example__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__window__example__1.snap │ │ ├── documentation__book__reference__stdlib__transforms__window__example__2.snap │ │ ├── documentation__book__reference__stdlib__transforms__window__window-functions-as-first-class-citizens__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__window__windowing-by-default__0.snap │ │ ├── documentation__book__reference__stdlib__transforms__window__windowing-by-default__1.snap │ │ ├── documentation__book__reference__syntax__case__0.snap │ │ ├── documentation__book__reference__syntax__case__1.snap │ │ ├── documentation__book__reference__syntax__comments__0.snap │ │ ├── documentation__book__reference__syntax__f-strings__0.snap │ │ ├── documentation__book__reference__syntax__f-strings__1.snap │ │ ├── documentation__book__reference__syntax__f-strings__2.snap │ │ ├── documentation__book__reference__syntax__keywords__0.snap │ │ ├── documentation__book__reference__syntax__keywords__identifiers--keywords__0.snap │ │ ├── documentation__book__reference__syntax__keywords__identifiers--keywords__1.snap │ │ ├── documentation__book__reference__syntax__keywords__identifiers--keywords__2.snap │ │ ├── documentation__book__reference__syntax__keywords__identifiers--keywords__3.snap │ │ ├── documentation__book__reference__syntax__keywords__quoting__0.snap │ │ ├── documentation__book__reference__syntax__keywords__quoting__1.snap │ │ ├── documentation__book__reference__syntax__keywords__quoting__2.snap │ │ ├── documentation__book__reference__syntax__keywords__schemas--database-names__0.snap │ │ ├── documentation__book__reference__syntax__literals__dates__0.snap │ │ ├── documentation__book__reference__syntax__literals__durations__0.snap │ │ ├── documentation__book__reference__syntax__literals__numbers__0.snap │ │ ├── documentation__book__reference__syntax__literals__times__0.snap │ │ ├── documentation__book__reference__syntax__literals__timestamps__0.snap │ │ ├── documentation__book__reference__syntax__operators__0.snap │ │ ├── documentation__book__reference__syntax__operators__coalesce__0.snap │ │ ├── documentation__book__reference__syntax__operators__division-and-integer-division__0.snap │ │ ├── documentation__book__reference__syntax__operators__parentheses__0.snap │ │ ├── documentation__book__reference__syntax__operators__parentheses__1.snap │ │ ├── documentation__book__reference__syntax__operators__parentheses__2.snap │ │ ├── documentation__book__reference__syntax__operators__regex-expressions__0.snap │ │ ├── documentation__book__reference__syntax__operators__regex-expressions__1.snap │ │ ├── documentation__book__reference__syntax__operators__regex-expressions__2.snap │ │ ├── documentation__book__reference__syntax__operators__regex-expressions__3.snap │ │ ├── documentation__book__reference__syntax__operators__regex-expressions__4.snap │ │ ├── documentation__book__reference__syntax__operators__regex-expressions__5.snap │ │ ├── documentation__book__reference__syntax__operators__wrapping-lines__0.snap │ │ ├── documentation__book__reference__syntax__operators__wrapping-lines__1.snap │ │ ├── documentation__book__reference__syntax__parameters__0.snap │ │ ├── documentation__book__reference__syntax__pipes__0.snap │ │ ├── documentation__book__reference__syntax__pipes__1.snap │ │ ├── documentation__book__reference__syntax__pipes__ceci-nest-pas-une-pipe__0.snap │ │ ├── documentation__book__reference__syntax__pipes__ceci-nest-pas-une-pipe__1.snap │ │ ├── documentation__book__reference__syntax__pipes__inner-transforms__0.snap │ │ ├── documentation__book__reference__syntax__r-strings__0.snap │ │ ├── documentation__book__reference__syntax__ranges__0.snap │ │ ├── documentation__book__reference__syntax__ranges__1.snap │ │ ├── documentation__book__reference__syntax__s-strings__0.snap │ │ ├── documentation__book__reference__syntax__s-strings__1.snap │ │ ├── documentation__book__reference__syntax__s-strings__2.snap │ │ ├── documentation__book__reference__syntax__s-strings__3.snap │ │ ├── documentation__book__reference__syntax__s-strings__braces__0.snap │ │ ├── documentation__book__reference__syntax__s-strings__precedence-within-s-strings__0.snap │ │ ├── documentation__book__reference__syntax__s-strings__precedence-within-s-strings__1.snap │ │ ├── documentation__book__reference__syntax__strings__0.snap │ │ ├── documentation__book__reference__syntax__strings__quoting-and-escape-characters__0.snap │ │ ├── documentation__book__reference__syntax__strings__quoting-and-escape-characters__1.snap │ │ ├── documentation__book__reference__syntax__tuples__0.snap │ │ └── documentation__book__reference__syntax__tuples__1.snap │ │ └── website.rs └── theme │ ├── head.hbs │ └── highlight.js ├── playground ├── .eslintrc.cjs ├── .gitignore ├── README.md ├── generateBook.cjs ├── index.html ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── manifest.json │ └── robots.txt ├── src │ ├── app │ │ ├── App.css │ │ └── App.jsx │ ├── examples.js │ ├── highlight.css │ ├── index.css │ ├── main.jsx │ ├── output │ │ ├── Output.css │ │ └── Output.jsx │ ├── reportWebVitals.js │ ├── setupTests.js │ ├── sidebar │ │ ├── Sidebar.css │ │ └── Sidebar.jsx │ └── workbench │ │ ├── Workbench.css │ │ ├── Workbench.jsx │ │ ├── duckdb.js │ │ ├── monaco-theme.json │ │ └── prql-syntax.js └── vite.config.js ├── prql-codemirror-demo ├── .gitignore ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── src │ ├── codemirror.ts │ ├── lang-prql │ │ ├── complete.ts │ │ └── prql.ts │ ├── main.ts │ ├── style.css │ └── vite-env.d.ts └── tsconfig.json └── website ├── .gitignore ├── README.md ├── archetypes └── default.md ├── config.yml ├── content ├── _index.md ├── demos │ └── ace-demo.html ├── faq.md ├── playground.html ├── posts │ ├── 2022-05-19-examples.md │ ├── 2023-01-07-functional-relations.md │ ├── 2023-01-27-prql-query.md │ ├── 2023-01-28-format-pretty-reports │ │ ├── _index.md │ │ └── query_result.png │ ├── 2023-02-02-one-year │ │ ├── 7cpDySb.png │ │ ├── FQ9QSOo.png │ │ ├── GXLvoXn.png │ │ ├── URpCf29.png │ │ ├── _index.md │ │ └── ncVXken.png │ └── 2023-03-14-pi-day.md └── roadmap.md ├── data ├── examples │ ├── basic.yaml │ ├── dialects.yaml │ ├── expressions.yaml │ ├── f-strings.yaml │ ├── friendly-syntax.yaml │ ├── functions.yaml │ ├── hero.yaml │ ├── joins.yaml │ ├── null-handling.yaml │ ├── orthogonal.yaml │ ├── s-strings.yaml │ ├── top-n.yaml │ └── windows.yaml └── testimonials.yaml ├── static ├── CNAME └── img │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ └── icon.svg └── themes └── prql-theme ├── archetypes └── default.md ├── layouts ├── 404.html ├── _default │ ├── _markup │ │ └── render-link.html │ ├── article.html │ ├── baseof.html │ ├── big_iframe.html │ ├── home.html │ ├── list.html │ └── single.html ├── partials │ ├── footer.html │ ├── head.html │ ├── header.html │ ├── section-cards.html │ └── section-testimonials.html └── shortcodes │ ├── cite.html │ ├── columns.html │ ├── faq.html │ └── link.html ├── static ├── apple-touch-icon.png ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── fonts │ ├── boxicons.eot │ ├── boxicons.min.css │ ├── boxicons.ttf │ ├── boxicons.woff │ ├── boxicons.woff2 │ ├── inter-extra-bold.woff2 │ └── inter-extra-nold.woff ├── icon.svg ├── main.js ├── plugins │ ├── bootstrap │ │ ├── bootstrap.bundle.min.js │ │ ├── bootstrap.bundle.min.js.map │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ └── highlight │ │ ├── highlight.css │ │ ├── highlight.min.js │ │ └── prql.js └── style.css └── theme.toml /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [target.wasm32-unknown-unknown] 2 | runner = 'wasm-bindgen-test-runner' 3 | -------------------------------------------------------------------------------- /.config/insta.yaml: -------------------------------------------------------------------------------- 1 | behavior: 2 | # Disabling because of issues with running on Windows 3 | # force_update: true 4 | review: 5 | # The default (true) has a small performance hit and never needed for us 6 | warn_undiscovered: false 7 | include_ignored: false 8 | include_hidden: false 9 | -------------------------------------------------------------------------------- /.config/vscode-recommended/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "lldb", 9 | "request": "launch", 10 | "name": "prqlc _a.prql", 11 | "program": "${workspaceFolder}/target/debug/prqlc", 12 | "args": ["debug", "semantics", "_a.prql"], 13 | "env": { 14 | "RUST_LOG": "debug", 15 | "RUST_BACKTRACE": "1" 16 | }, 17 | "preLaunchTask": "prqlc-build", 18 | "cwd": "${workspaceFolder}" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /.config/vscode-recommended/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | "**/.git": true, 4 | "**/.svn": true, 5 | "**/.hg": true, 6 | "**/CVS": true, 7 | "**/.DS_Store": true, 8 | "**/Thumbs.db": true, 9 | "web/book/book": true, 10 | "web/build": true, 11 | ".direnv": true, 12 | ".pytest_cache": true, 13 | ".mypy_cache": true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.config/vscode-recommended/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "prqlc-build", 6 | "type": "cargo", 7 | "command": "build", 8 | "args": ["--package=prqlc"], 9 | "presentation": { 10 | "reveal": "silent", 11 | "clear": true 12 | }, 13 | "problemMatcher": ["$rustc"] 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /.devcontainer/base-image/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1.4 2 | 3 | FROM mcr.microsoft.com/devcontainers/rust:1-1-bookworm 4 | 5 | # ========= Install cargo-tools for non-root user (vscode) ========= 6 | USER vscode 7 | 8 | ARG cargo_crates 9 | 10 | RUN <<"EOF" 11 | curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash 12 | cargo binstall -y --locked ${cargo_crates} 13 | EOF 14 | 15 | USER root 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Currently required for: 2 | # - Elixir tests at 3 | # https://github.com/PRQL/prql/blob/5eb4063dbd36bdac07529797dd2cec8c55127263/.github/workflows/test-elixir.yaml#L31 4 | # - Previously for Readme tests, those those now should support either lf or 5 | # crlf, at https://github.com/PRQL/prql/blob/6d4662b4e6e0f07dc3cd8eb5c19cc78fc199d0b2/web/book/tests/documentation/readme.rs#L9 6 | * text=auto eol=lf 7 | 8 | # Prevent files from cluttering `git grep` results 9 | *.min.js -diff 10 | *.min.js.map -diff 11 | *.min.css -diff 12 | *.min.css.map -diff 13 | package-lock.json -diff 14 | # mdbook expects the file to be named highlight.js so we cannot rename it to .min.js 15 | highlight.js -diff 16 | -------------------------------------------------------------------------------- /.github/.codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | ignore: 4 | - "**/tests/**" 5 | 6 | coverage: 7 | status: 8 | project: 9 | default: 10 | removed_code_behavior: adjust_base 11 | # This disables report a success/failure. That's not helpful on `main` 12 | # and we get the success/failure from the patch status on PRs. 13 | informational: true 14 | 15 | patch: 16 | default: 17 | only_pulls: true 18 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | We prefer keeping our rules as short as possible and filling the gaps with the 4 | mortar of human interaction: empathy. 5 | 6 | All we ask of members of this project is this: 7 | 8 | - Please treat each other with respect and understanding. 9 | - Please respect our wish to not serve as a stage for disputes about fairness or 10 | personal differences. 11 | 12 | If you can agree to these conditions, your contributions are welcome. If you can 13 | not, please don’t spoil it for the rest of us. 14 | 15 | To report a violation of these rules, please email 16 | [prql@prql-lang.org](mailto:prql@prql-lang.org) or contact one of the 17 | [project maintainers](https://github.com/orgs/PRQL/people). 18 | 19 | --- 20 | 21 | (based on ) 22 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Check out our 4 | [Contributing Docs](https://prql-lang.org/book/project/contributing/) 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yaml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/something_else.yaml: -------------------------------------------------------------------------------- 1 | name: Something else 2 | description: Anything that's not a bug report 3 | body: 4 | - type: textarea 5 | id: what-happened 6 | attributes: 7 | label: What's up? 8 | -------------------------------------------------------------------------------- /.github/nightly-failure.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Nightly tests failed 3 | labels: github_actions 4 | --- 5 | 6 | Nightly tests [failed on {{ date | date('YYYY-MM-DD') }}]({{ env.LINK }}) 7 | -------------------------------------------------------------------------------- /.github/workflows/README.md: -------------------------------------------------------------------------------- 1 | # GitHub Workflows 2 | 3 | See 4 | [our development docs](https://prql-lang.org/book/project/contributing/development.html) 5 | for docs & discussion. 6 | -------------------------------------------------------------------------------- /.github/workflows/scripts/set_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # We set prefix-key to the version from Cargo.toml for Swatinem/rust-cache@v2 4 | # since the caches seem to accumulate cruft over time; 5 | # ref https://github.com/PRQL/prql/pull/2407 6 | 7 | version=$(cargo metadata --format-version=1 --no-deps | jq --raw-output '.packages[] | select(.name == "prqlc") | .version') 8 | echo "version=${version}" >>"$GITHUB_ENV" 9 | -------------------------------------------------------------------------------- /.markdownlint-cli2.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | # We use prettier for line length & wrapping 3 | MD013: false 4 | # Code block style — generally this is fine, but it has false positives on 5 | # footnotes. See below re markdown-it-footnote issue. If we could resolve 6 | # that, we could turn this back on. 7 | MD046: false 8 | # markdownItPlugins: 9 | # 10 | # Doesn't seem to help with some issues — if someone wants to help resolve then 11 | # great, but it's no huge stress to have some false positives. 12 | # 13 | # https://github.com/DavidAnson/markdownlint/issues/689 14 | # - ["markdown-it-footnote"] 15 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # prettier respects the root `.gitignore` file, so prefer that for files which 2 | # we also want to ignore from our version control. This should contain files we 3 | # want to track but not format. 4 | 5 | **/*.rs 6 | **/*.min.* 7 | 8 | /web/book/theme/highlight.js 9 | /web/playground/build 10 | /web/website/public 11 | /web/book/book 12 | 13 | # TODO: move these into content out of layouts 14 | /web/website/themes/prql-theme/layouts/_default/_markup/render-link.html 15 | 16 | # TODO: fix the go-template issue in `.prettierrc.yaml` 17 | **/*.html 18 | -------------------------------------------------------------------------------- /.prettierrc.yaml: -------------------------------------------------------------------------------- 1 | proseWrap: always 2 | # TODO: fix 3 | # overrides: 4 | # # https://github.com/NiklasPor/prettier-plugin-go-template 5 | # - files: 6 | # - "*.html" 7 | # options: 8 | # parser: "go-template" 9 | -------------------------------------------------------------------------------- /.sqlfluff: -------------------------------------------------------------------------------- 1 | [sqlfluff] 2 | dialect = ansi 3 | exclude_rules = references.keywords 4 | -------------------------------------------------------------------------------- /.typos.toml: -------------------------------------------------------------------------------- 1 | [files] 2 | extend-exclude = [ 3 | "web/book/theme/highlight.js", 4 | "prqlc/prqlc/tests/integration/data/", 5 | "prqlc/prqlc/tests/integration/snapshots/", 6 | "web/website/themes/prql-theme/static/plugins/bootstrap", 7 | "web/website/themes/prql-theme/static/plugins/highlight/highlight.min.js", 8 | ] 9 | 10 | [default.extend-words] 11 | # in grammars/KSyntaxHighlighting/prql.xml 12 | datas = "datas" 13 | # Java test framework 14 | testng = "testng" 15 | # Readme highlighting the first characters of these words 16 | anguage = "anguage" 17 | elational = "elational" 18 | ipelined = "ipelined" 19 | uery = "uery" 20 | # `wee-alloc` is a crate name 21 | wee = "wee" 22 | flate = "flate" 23 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | // Keep in sync with Taskfile.yaml 4 | "prql-lang.prql-vscode", 5 | "rust-lang.rust-analyzer", 6 | "mitsuhiko.insta", 7 | "esbenp.prettier-vscode", 8 | "budparr.language-hugo-vscode" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /grammars/CotEditor/README.md: -------------------------------------------------------------------------------- 1 | # PRQL syntax style for CotEditor 2 | 3 | [CotEditor](https://coteditor.com/)'s syntax style file for the PRQL query 4 | language. 5 | 6 | ## Install 7 | 8 | 1. Go to _Preferences > Format_ and choose _Import…_ in the gear icon menu that 9 | is just below the installed style list. 10 | 2. Choose the `PRQL.yml` file. 11 | -------------------------------------------------------------------------------- /grammars/emacs/README.md: -------------------------------------------------------------------------------- 1 | # Syntax highlighting for GNU Emacs 2 | 3 | This is a syntax highlighting file for GNU Emacs. 4 | 5 | ## Installation 6 | 7 | Copy the `prql-mode.el` file to: 8 | 9 | ~/.emacs.d/custom-modes/ 10 | 11 | Then, edit your `~/emacs.d/init.el` file and add the following: 12 | 13 | ```emacs 14 | (add-to-list 'load-path "~/.emacs.d/custom-modes/") 15 | (require 'prql-mode) 16 | 17 | (add-to-list 'auto-mode-alist '("\\.prql\\'" . prql-mode)) 18 | ``` 19 | -------------------------------------------------------------------------------- /grammars/micro/README.md: -------------------------------------------------------------------------------- 1 | # Syntax highlighting for micro 2 | 3 | This is a syntax highlighting file the [micro](https://micro-editor.github.io/) 4 | text editor. 5 | 6 | ## Installation 7 | 8 | To install place the `prql.yaml` file in: 9 | 10 | ~/.config/micro/syntax/ 11 | -------------------------------------------------------------------------------- /grammars/nano/README.md: -------------------------------------------------------------------------------- 1 | # Syntax highlighting for GNU nano 2 | 3 | This is a syntax highlighting file the [GNU nano](https://nano-editor.org/) text 4 | editor. 5 | 6 | ## Installation 7 | 8 | To install place the `prql.nanorc` file in the `~/.nano/` directory and and 9 | include the following line in your `.nanorc` file. 10 | 11 | include "~/.nano/prql.nanorc" 12 | 13 | You can append it with this command: 14 | 15 | echo 'include "~/.nano/prql.nanorc"' >> ~/.nanorc 16 | -------------------------------------------------------------------------------- /grammars/prql-lezer/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /src/parser.* 3 | /dist 4 | -------------------------------------------------------------------------------- /grammars/prql-lezer/dist/index.d.cts: -------------------------------------------------------------------------------- 1 | import { LRParser } from "@lezer/lr"; 2 | 3 | export const parser: LRParser; 4 | -------------------------------------------------------------------------------- /grammars/prql-lezer/dist/index.d.ts: -------------------------------------------------------------------------------- 1 | import { LRParser } from "@lezer/lr"; 2 | 3 | export const parser: LRParser; 4 | -------------------------------------------------------------------------------- /grammars/prql-lezer/rollup.config.js: -------------------------------------------------------------------------------- 1 | import { nodeResolve } from "@rollup/plugin-node-resolve"; 2 | 3 | export default { 4 | input: "./src/parser.js", 5 | output: [ 6 | { 7 | format: "cjs", 8 | file: "./dist/index.cjs", 9 | }, 10 | { 11 | format: "es", 12 | file: "./dist/index.js", 13 | }, 14 | ], 15 | external(id) { 16 | return !/^[\.\/]/.test(id); 17 | }, 18 | plugins: [nodeResolve()], 19 | }; 20 | -------------------------------------------------------------------------------- /grammars/prql-lezer/test/identifiers.txt: -------------------------------------------------------------------------------- 1 | # Basic identifier 2 | 3 | filter foo 4 | 5 | ==> 6 | 7 | Query(Pipeline(CallExpression(Identifier,ArgList(Identifier)))) 8 | 9 | 10 | # Identifier with underscore and digit 11 | 12 | filter foo_123 13 | 14 | ==> 15 | 16 | Query(Pipeline(CallExpression(Identifier,ArgList(Identifier)))) 17 | 18 | # Unicode identifier 19 | 20 | filter räksmörgås 21 | 22 | ==> 23 | 24 | Query(Pipeline(CallExpression(Identifier,ArgList(Identifier)))) 25 | -------------------------------------------------------------------------------- /grammars/prql-lezer/test/test-prql.js: -------------------------------------------------------------------------------- 1 | import { parser } from "../dist/index.js"; 2 | import { fileTests } from "@lezer/generator/dist/test"; 3 | 4 | import * as fs from "fs"; 5 | import * as path from "path"; 6 | import { fileURLToPath } from "url"; 7 | let caseDir = path.dirname(fileURLToPath(import.meta.url)); 8 | 9 | for (let file of fs.readdirSync(caseDir)) { 10 | if (!/\.txt$/.test(file)) continue; 11 | 12 | let name = /^[^\.]*/.exec(file)[0]; 13 | describe(name, () => { 14 | for (let { name, run } of fileTests( 15 | fs.readFileSync(path.join(caseDir, file), "utf8"), 16 | file, 17 | )) 18 | it(name, () => run(parser)); 19 | }); 20 | } 21 | -------------------------------------------------------------------------------- /grammars/vim/README.md: -------------------------------------------------------------------------------- 1 | # Syntax highlighting for Vim 2 | 3 | This is a syntax highlighting file for Vim and Neovim. 4 | 5 | ## Installation 6 | 7 | ### For Vim 8 | 9 | Copy the `prql.vim` file to: 10 | 11 | ~/.vim/syntax/ 12 | 13 | Then, edit your `~/.vimrc` file and add the following: 14 | 15 | ```vim 16 | augroup PrqlFileType 17 | autocmd! 18 | autocmd BufRead,BufNewFile *.prql setfiletype prql 19 | augroup END 20 | ``` 21 | 22 | ### For Neovim 23 | 24 | Copy the `prql.vim` file to: 25 | 26 | ~/.config/nvim/syntax/ 27 | 28 | Then, edit your `~/.config/nvim/init.vim` file. 29 | -------------------------------------------------------------------------------- /prqlc/README.md: -------------------------------------------------------------------------------- 1 | # PRQL compiler 2 | 3 | Reference implementation of a compiler from PRQL to SQL, written in Rust. 4 | 5 | The bindings for other programming languages can be found in 6 | [./bindings/](./bindings/). 7 | 8 | `prqlc` is the CLI for the compiler. 9 | -------------------------------------------------------------------------------- /prqlc/bindings/dotnet/.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj 3 | -------------------------------------------------------------------------------- /prqlc/bindings/dotnet/PrqlCompiler.Tests/Usings.cs: -------------------------------------------------------------------------------- 1 | global using Xunit; 2 | -------------------------------------------------------------------------------- /prqlc/bindings/dotnet/PrqlCompiler/MessageKind.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Prql.Compiler 4 | { 5 | /// 6 | /// Compile message kind. Currently only Error is implemented. 7 | /// 8 | [Serializable] 9 | public enum MessageKind 10 | { 11 | /// 12 | /// Error message. 13 | /// 14 | Error, 15 | /// 16 | /// Warning message. 17 | /// 18 | Warning, 19 | /// 20 | /// Lint message. 21 | /// 22 | Lint 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /prqlc/bindings/dotnet/PrqlCompiler/NativePrqlCompilerOptions.cs: -------------------------------------------------------------------------------- 1 | namespace Prql.Compiler 2 | { 3 | internal struct NativePrqlCompilerOptions 4 | { 5 | public bool Format; 6 | public string Target; 7 | public bool SignatureComment; 8 | 9 | public NativePrqlCompilerOptions(PrqlCompilerOptions options) 10 | { 11 | Format = options.Format; 12 | Target = options.Target; 13 | SignatureComment = options.SignatureComment; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /prqlc/bindings/dotnet/PrqlCompiler/NativeResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Prql.Compiler 4 | { 5 | internal struct NativeResult 6 | { 7 | #pragma warning disable CS0649 // Field is never assigned to 8 | public string Output; 9 | public IntPtr Messages; 10 | public int MessagesLen; 11 | #pragma warning restore CS0649 // Field is never assigned to 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /prqlc/bindings/dotnet/PrqlCompiler/SourceLocation.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace Prql.Compiler 4 | { 5 | /// 6 | /// Location within a source file. 7 | /// 8 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 9 | public struct SourceLocation 10 | { 11 | /// 12 | /// Start line. 13 | /// 14 | public int StartLine { get; set; } 15 | 16 | /// 17 | /// Start column. 18 | /// 19 | public int StartCol { get; set; } 20 | 21 | /// 22 | /// End line. 23 | /// 24 | public int EndLine { get; set; } 25 | 26 | /// 27 | /// End column. 28 | /// 29 | public int EndCol { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /prqlc/bindings/dotnet/PrqlCompiler/Span.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | namespace Prql.Compiler 4 | { 5 | /// 6 | /// Identifier of a location in source. 7 | /// Contains offsets in terms of chars. 8 | /// 9 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 10 | public struct Span 11 | { 12 | /// 13 | /// Start offset. 14 | /// 15 | public int Start { get; set; } 16 | 17 | /// 18 | /// End offset. 19 | /// 20 | public int End { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /prqlc/bindings/elixir/.formatter.exs: -------------------------------------------------------------------------------- 1 | # Used by "mix format" 2 | [ 3 | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] 4 | ] 5 | -------------------------------------------------------------------------------- /prqlc/bindings/elixir/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build/ 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover/ 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps/ 9 | 10 | # Where third-party dependencies like ExDoc output generated docs. 11 | /doc/ 12 | 13 | # Ignore .fetch files in case you like to edit your project deps locally. 14 | /.fetch 15 | 16 | # If the VM crashes, it generates a dump, let's ignore it too. 17 | erl_crash.dump 18 | 19 | # Also ignore archive artifacts (built via "mix archive.build"). 20 | *.ez 21 | 22 | # Ignore package tarball (built via "mix hex.build"). 23 | prql_elixir-*.tar 24 | 25 | # Temporary files, for example, from tests. 26 | /tmp/ 27 | 28 | /priv/native/* 29 | -------------------------------------------------------------------------------- /prqlc/bindings/elixir/lib/prql/errors.ex: -------------------------------------------------------------------------------- 1 | defmodule PRQL.PRQLError do 2 | @moduledoc """ 3 | Represents an error returned from PRQL compiler. 4 | 5 | `:error` contains the message from compiler as a **JSON string**. 6 | """ 7 | defexception [:message, :error] 8 | 9 | @impl true 10 | def exception(err) do 11 | %__MODULE__{message: "Error compiling PRQL query", error: err} 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /prqlc/bindings/elixir/native/prql/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | # Note that this doesn't apply when compiling from the workspace root 2 | 3 | # (also it seems to work at first glance without this? but it's referenced at 4 | # https://github.com/philss/rustler_precompiled/blob/main/PRECOMPILATION_GUIDE.md, 5 | # and I don't know enough to remove it 6 | [target.'cfg(target_os = "macos")'] 7 | rustflags = ["-C", "link-arg=-undefined", "-C", "link-arg=dynamic_lookup"] 8 | -------------------------------------------------------------------------------- /prqlc/bindings/elixir/native/prql/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["Kasun Vithanage "] 3 | description = "Elixir NIF bindings for prqlc" 4 | name = "prql" 5 | publish = false 6 | 7 | edition.workspace = true 8 | license.workspace = true 9 | repository.workspace = true 10 | rust-version.workspace = true 11 | version.workspace = true 12 | 13 | [lib] 14 | bench = false 15 | crate-type = ["cdylib"] 16 | doc = false 17 | doctest = false 18 | name = "prql" 19 | path = "src/lib.rs" 20 | test = false 21 | 22 | [target.'cfg(not(any(target_family="wasm")))'.dependencies] 23 | prqlc = { path = "../../../../prqlc", default-features = false, version = "0.13.5" } 24 | rustler = "0.36.1" 25 | -------------------------------------------------------------------------------- /prqlc/bindings/elixir/native/prql/README.md: -------------------------------------------------------------------------------- 1 | # NIF for Elixir.PRQL 2 | 3 | ## To build the NIF module: 4 | 5 | - Your NIF will now build along with your project. 6 | - NIFs are loaded into `PRQL.Native` module in Elixir(`lib/prql/native.ex`) 7 | -------------------------------------------------------------------------------- /prqlc/bindings/elixir/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | -------------------------------------------------------------------------------- /prqlc/bindings/java/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | 3 | **/libprql_java* 4 | **/prql_java.dll 5 | -------------------------------------------------------------------------------- /prqlc/bindings/java/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "prql-java" 3 | publish = false 4 | 5 | edition.workspace = true 6 | license.workspace = true 7 | repository.workspace = true 8 | rust-version.workspace = true 9 | version.workspace = true 10 | 11 | [lib] 12 | bench = false 13 | crate-type = ["cdylib"] 14 | doc = false 15 | doctest = false 16 | test = false 17 | 18 | [dependencies] 19 | jni = "0.21.1" 20 | prqlc = {path = "../../prqlc", default-features = false} 21 | 22 | [package.metadata.release] 23 | tag-name = "{{version}}" 24 | tag-prefix = "" 25 | -------------------------------------------------------------------------------- /prqlc/bindings/java/README.md: -------------------------------------------------------------------------------- 1 | # prql-java 2 | 3 | `prql-java` offers Java bindings to the `prqlc` Rust library. It exposes a Java 4 | native method `public static native String toSql(String query)`. 5 | 6 | It's still at an early stage, and currently requires compiling locally, and 7 | isn't published to Maven. Contributions are welcome. 8 | 9 | ## Installation 10 | 11 | ```xml 12 | 13 | org.prqllang 14 | prql-java 15 | ${PRQL_VERSION} 16 | 17 | ``` 18 | 19 | ## Usage 20 | 21 | ```java 22 | import org.prqllang.prql4j.PrqlCompiler; 23 | 24 | class Main { 25 | public static void main(String[] args) { 26 | String sql = PrqlCompiler.toSql("from table"); 27 | System.out.println(sql); 28 | } 29 | } 30 | ``` 31 | -------------------------------------------------------------------------------- /prqlc/bindings/java/java/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/prqlc/bindings/java/java/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /prqlc/bindings/java/java/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/prqlc/bindings/java/java/src/main/resources/.gitkeep -------------------------------------------------------------------------------- /prqlc/bindings/java/java/src/test/java/org/prql/prql4j/PrqlCompilerTest.java: -------------------------------------------------------------------------------- 1 | package org.prql.prql4j; 2 | 3 | import org.junit.Test; 4 | 5 | public class PrqlCompilerTest { 6 | @Test 7 | public void compile() throws Exception { 8 | String found = PrqlCompiler.toSql("from my_table", "sql.mysql", true, true); 9 | 10 | // remove signature 11 | found = found.substring(0, found.indexOf("\n\n--")); 12 | 13 | String expected = "SELECT\n" + 14 | " *\n" + 15 | "FROM\n" + 16 | " my_table"; 17 | assert expected.equalsIgnoreCase(found); 18 | } 19 | 20 | @Test(expected = Exception.class) 21 | public void compileWithError() throws Exception { 22 | PrqlCompiler.toSql("from table | filter id >> 1", "sql.mysql", true, true); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /prqlc/bindings/java/java/src/test/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/prqlc/bindings/java/java/src/test/resources/.gitkeep -------------------------------------------------------------------------------- /prqlc/bindings/php/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.php] 4 | indent_size = 4 5 | indent_style = space 6 | -------------------------------------------------------------------------------- /prqlc/bindings/php/.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | lib/ 3 | -------------------------------------------------------------------------------- /prqlc/bindings/php/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "prql/compiler", 3 | "description": "PRQL compiler bindings.", 4 | "keywords": [ 5 | "prql", 6 | "sql" 7 | ], 8 | "homepage": "https://prql-lang.org/", 9 | "type": "library", 10 | "license": "Apache-2.0", 11 | "autoload": { 12 | "psr-4": { 13 | "Prql\\Compiler\\": "src/" 14 | } 15 | }, 16 | "autoload-dev": { 17 | "psr-4": { 18 | "Prql\\Tests\\": "tests/" 19 | } 20 | }, 21 | "authors": [ 22 | { 23 | "name": "Jonathan" 24 | } 25 | ], 26 | "support": { 27 | "issues": "https://github.com/PRQL/prql/issues", 28 | "source": "https://github.com/PRQL/prql", 29 | "docs": "https://prql-lang.org/book/" 30 | }, 31 | "require": { 32 | "php": "^8.1", 33 | "ext-ffi": "*" 34 | }, 35 | "require-dev": { 36 | "phpunit/phpunit": "^10", 37 | "squizlabs/php_codesniffer": "^3.7" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /prqlc/bindings/php/phpstan.neon: -------------------------------------------------------------------------------- 1 | parameters: 2 | level: 9 3 | paths: 4 | - src 5 | - tests 6 | ignoreErrors: 7 | # Since PHPStan doesn't know about the existence of the functions in libprql, 8 | # it complains since they get dynamically invoked on the FFI object instance 9 | # without being statically defined, so they're unknown. 10 | - '#Call to an undefined method FFI::compile\(\)\.#' 11 | - '#Call to an undefined method FFI::prql_to_pl\(\)\.#' 12 | - '#Call to an undefined method FFI::pl_to_rq\(\)\.#' 13 | - '#Call to an undefined method FFI::rq_to_sql\(\)\.#' 14 | - '#Cannot access property \$format on FFI\\CData\|null\.#' 15 | - '#Cannot access property \$signature_comment on FFI\\CData\|null\.#' 16 | - '#Cannot access property \$target on FFI\\CData\|null\.#' 17 | -------------------------------------------------------------------------------- /prqlc/bindings/php/src/MessageKind.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | public array $messages; 21 | } 22 | -------------------------------------------------------------------------------- /prqlc/bindings/php/src/SourceLocation.php: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include "prqlc.hpp" 5 | 6 | using namespace prqlc; 7 | 8 | void print_result(CompileResult res) { 9 | if (strcmp(res.output, "") == 0) { 10 | std::cout << "Output: \n\n"; 11 | } else { 12 | std::cout << "Output:\n\n" << res.output; 13 | } 14 | } 15 | 16 | int main() { 17 | const auto prql_query = "from albums | select {album_id, title} | take 3"; 18 | 19 | CompileResult res = compile(prql_query, nullptr); 20 | print_result(res); 21 | result_destroy(res); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /prqlc/bindings/prqlc-c/examples/minimal-zig/.gitignore: -------------------------------------------------------------------------------- 1 | zig-cache/ 2 | zig-out/ 3 | c/ 4 | -------------------------------------------------------------------------------- /prqlc/bindings/prqlc-c/examples/minimal-zig/README.md: -------------------------------------------------------------------------------- 1 | # Basic Zig example 2 | 3 | A minimal example for using prql-lib with Zig. 4 | 5 | Run with `task zig` from the root of the repo. 6 | -------------------------------------------------------------------------------- /prqlc/bindings/prqlc-python/Taskfile.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | vars: 4 | build_dir: "../../../target/python" 5 | venv_dir: "../../../target/venv" 6 | 7 | tasks: 8 | build: 9 | desc: Build 10 | vars: 11 | profile: "dev" 12 | cmds: 13 | - cmd: | 14 | maturin build \ 15 | --profile={{.profile}} \ 16 | --out={{.build_dir}} 17 | 18 | init-venv: 19 | status: 20 | - test -d {{.venv_dir}} 21 | cmds: 22 | - python3 -m venv {{.venv_dir}} 23 | 24 | test: 25 | desc: A fast test used for feedback during compiler development 26 | deps: [init-venv] 27 | cmds: 28 | - cmd: | 29 | source {{.venv_dir}}/bin/activate 30 | python3 -m pip install .[dev] 31 | - cmd: | 32 | source {{.venv_dir}}/bin/activate 33 | python3 -m pytest 34 | -------------------------------------------------------------------------------- /prqlc/bindings/prqlc-python/build.rs: -------------------------------------------------------------------------------- 1 | // From https://pyo3.rs/v0.14.5/building_and_distribution.html#macos 2 | // Note the alternative static option with `config.toml` has an problem in https://github.com/PRQL/prql/issues/411. 3 | 4 | fn main() { 5 | pyo3_build_config::add_extension_module_link_args(); 6 | } 7 | -------------------------------------------------------------------------------- /prqlc/bindings/prqlc-python/python/prqlc/__init__.py: -------------------------------------------------------------------------------- 1 | # ruff: noqa: F403, F405 2 | # 3 | # This is the default module init provided automatically by Maturin. 4 | from .prqlc import * 5 | 6 | __doc__ = prqlc.__doc__ 7 | if hasattr(prqlc, "__all__"): 8 | __all__ = prqlc.__all__ 9 | -------------------------------------------------------------------------------- /prqlc/bindings/prqlc-python/python/prqlc/__init__.pyi: -------------------------------------------------------------------------------- 1 | from typing import List, Optional 2 | 3 | class CompileOptions: 4 | def __init__( 5 | self, 6 | *, 7 | format: bool = True, 8 | target: str = "sql.any", 9 | signature_comment: bool = True, 10 | ) -> None: ... 11 | 12 | def compile(prql_query: str, options: Optional[CompileOptions] = None) -> str: ... 13 | def prql_to_pl(prql_query: str) -> str: ... 14 | def pl_to_rq(pl_json: str) -> str: ... 15 | def pl_to_prql(pl_json: str) -> str: ... 16 | def rq_to_sql(rq_json: str) -> str: ... 17 | def get_targets() -> List[str]: ... 18 | 19 | __version__: str 20 | -------------------------------------------------------------------------------- /prqlc/bindings/prqlc-python/python/prqlc/debug.pyi: -------------------------------------------------------------------------------- 1 | def prql_lineage(prql_query: str) -> str: ... 2 | def pl_to_lineage(pl_json: str) -> str: ... 3 | -------------------------------------------------------------------------------- /prqlc/bindings/prqlc-python/python/prqlc/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/prqlc/bindings/prqlc-python/python/prqlc/py.typed -------------------------------------------------------------------------------- /prqlc/prqlc-macros/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | description = "Macros for PRQL compilation at build time" 3 | name = "prqlc-macros" 4 | 5 | edition.workspace = true 6 | license.workspace = true 7 | repository.workspace = true 8 | rust-version.workspace = true 9 | version.workspace = true 10 | 11 | [lib] 12 | bench = false 13 | doctest = false 14 | proc-macro = true 15 | test = false 16 | 17 | [dependencies] 18 | prqlc = {path = "../prqlc", default-features = false, version = "0.13.5" } 19 | syn = "2.0.101" 20 | 21 | [package.metadata.release] 22 | tag-name = "{{version}}" 23 | tag-prefix = "" 24 | -------------------------------------------------------------------------------- /prqlc/prqlc-parser/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod error; 2 | pub mod generic; 3 | pub mod lexer; 4 | pub mod parser; 5 | pub mod span; 6 | #[cfg(test)] 7 | pub(crate) mod test; 8 | -------------------------------------------------------------------------------- /prqlc/prqlc-parser/src/parser/pr/mod.rs: -------------------------------------------------------------------------------- 1 | //! PR, or "Parser Representation" is an AST representation of parsed PRQL. It 2 | //! takes LR tokens and converts them into a more structured form which 3 | //! understands expressions, such as tuples & functions. 4 | 5 | pub use expr::*; 6 | pub use ident::*; 7 | pub use ops::*; 8 | pub use stmt::*; 9 | pub use types::*; 10 | 11 | // re-export Literal from LR, since it's encapsulated in TyKind 12 | pub use crate::lexer::lr::Literal; 13 | pub use crate::span::Span; 14 | 15 | mod expr; 16 | mod ident; 17 | mod ops; 18 | mod stmt; 19 | mod types; 20 | -------------------------------------------------------------------------------- /prqlc/prqlc/build.rs: -------------------------------------------------------------------------------- 1 | use std::error::Error; 2 | // gix failing on https://github.com/rustyhorde/vergen/issues/359, and `git2` 3 | // fails on `aarch64` so we're using `gitcl`. Switch to `gitx` when that bug is 4 | // fixed. 5 | use vergen_gitcl::{Emitter, GitclBuilder as GitBuilder}; 6 | 7 | pub fn main() -> Result<(), Box> { 8 | let git = GitBuilder::default().describe(true, true, None).build()?; 9 | Emitter::default().add_instructions(&git)?.emit()?; 10 | Ok(()) 11 | } 12 | -------------------------------------------------------------------------------- /prqlc/prqlc/examples/compile-files/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "compile-files" 3 | publish = false 4 | 5 | edition.workspace = true 6 | license.workspace = true 7 | repository.workspace = true 8 | rust-version.workspace = true 9 | version.workspace = true 10 | 11 | [[bin]] 12 | bench = false 13 | doc = false 14 | doctest = false 15 | name = "compile-files" 16 | test = false 17 | 18 | [build-dependencies] 19 | prqlc = {path = '../../../prqlc', default-features = false} 20 | -------------------------------------------------------------------------------- /prqlc/prqlc/examples/compile-files/README.md: -------------------------------------------------------------------------------- 1 | # Compile-time example 2 | 3 | `compile-files` is an example of using `prqlc` to compile PRQL to SQL at compile 4 | time in a Rust crate. 5 | -------------------------------------------------------------------------------- /prqlc/prqlc/examples/compile-files/queries/query1.prql: -------------------------------------------------------------------------------- 1 | from albums 2 | select {title, artist_id} 3 | join artists (==artist_id) 4 | -------------------------------------------------------------------------------- /prqlc/prqlc/examples/compile-files/queries/variables.prql: -------------------------------------------------------------------------------- 1 | from employees 2 | filter country == "USA" # Each line transforms the previous result. 3 | derive { # This adds columns / variables. 4 | gross_salary = salary + payroll_tax, 5 | gross_cost = gross_salary + benefits_cost # Variables can use other variables. 6 | } 7 | filter gross_cost > 0 8 | group {title, country} ( # For each group use a nested pipeline 9 | aggregate { # Aggregate each group to a single row 10 | average salary, 11 | average gross_salary, 12 | sum salary, 13 | sum gross_salary, 14 | average gross_cost, 15 | sum_gross_cost = sum gross_cost, 16 | ct = count salary, 17 | } 18 | ) 19 | sort sum_gross_cost 20 | filter ct > 200 21 | take 20 22 | -------------------------------------------------------------------------------- /prqlc/prqlc/examples/compile-files/src/main.rs: -------------------------------------------------------------------------------- 1 | // a helper macro 2 | #[macro_export] 3 | macro_rules! include_query { 4 | ($filename:expr) => { 5 | include_str!(concat!(env!("OUT_DIR"), "/", $filename)) 6 | }; 7 | } 8 | 9 | fn main() { 10 | // queries are accessible under their original filename 11 | let compiler_query: &str = include_query!("query1.prql"); 12 | 13 | println!("{compiler_query}"); 14 | } 15 | -------------------------------------------------------------------------------- /prqlc/prqlc/src/debug/mod.rs: -------------------------------------------------------------------------------- 1 | mod log; 2 | mod messages; 3 | mod render_html; 4 | 5 | pub use crate::debug::log::*; 6 | pub use messages::MessageLogger; 7 | pub use render_html::render_log_to_html; 8 | -------------------------------------------------------------------------------- /prqlc/prqlc/src/ir/mod.rs: -------------------------------------------------------------------------------- 1 | //! Intermediate Representations of Abstract Syntax Tree 2 | //! 3 | pub use prqlc_parser::span::Span; 4 | 5 | pub mod decl; 6 | pub mod generic; 7 | pub mod pl; 8 | pub mod rq; 9 | -------------------------------------------------------------------------------- /prqlc/prqlc/src/ir/pl/utils.rs: -------------------------------------------------------------------------------- 1 | use super::{Expr, ExprKind, FuncCall}; 2 | use crate::pr::Ident; 3 | 4 | pub fn maybe_binop(left: Option, op_name: &[&str], right: Option) -> Option { 5 | match (left, right) { 6 | (Some(left), Some(right)) => Some(new_binop(left, op_name, right)), 7 | (left, right) => left.or(right), 8 | } 9 | } 10 | 11 | pub fn new_binop(left: Expr, op_name: &[&str], right: Expr) -> Expr { 12 | Expr::new(ExprKind::FuncCall(FuncCall { 13 | name: Box::new(Expr::new(Ident::from_path(op_name.to_vec()))), 14 | args: vec![left, right], 15 | named_args: Default::default(), 16 | })) 17 | } 18 | -------------------------------------------------------------------------------- /prqlc/prqlc/src/ir/rq/utils.rs: -------------------------------------------------------------------------------- 1 | use super::Expr; 2 | use super::ExprKind; 3 | 4 | pub fn new_binop(left: Expr, operator_name: &str, right: Expr) -> Expr { 5 | Expr { 6 | kind: ExprKind::Operator { 7 | name: operator_name.to_string(), 8 | args: vec![left, right], 9 | }, 10 | span: None, 11 | } 12 | } 13 | 14 | pub fn maybe_binop(left: Option, operator_name: &str, right: Option) -> Option { 15 | match (left, right) { 16 | (Some(left), Some(right)) => Some(Expr { 17 | kind: ExprKind::Operator { 18 | name: operator_name.to_string(), 19 | args: vec![left, right], 20 | }, 21 | span: None, 22 | }), 23 | (left, right) => left.or(right), 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /prqlc/prqlc/src/main.rs: -------------------------------------------------------------------------------- 1 | #[cfg(all(not(target_family = "wasm"), feature = "cli"))] 2 | mod cli; 3 | 4 | #[cfg(all(not(target_family = "wasm"), feature = "cli"))] 5 | fn main() -> color_eyre::eyre::Result<()> { 6 | cli::main() 7 | } 8 | 9 | #[cfg(any(target_family = "wasm", not(feature = "cli")))] 10 | fn main() { 11 | panic!("Crate is not built with the `cli` feature enabled, or was built for a wasm target."); 12 | } 13 | -------------------------------------------------------------------------------- /prqlc/prqlc/src/semantic/resolver/snapshots/prqlc__semantic__resolver__test__frames_and_names-2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/src/semantic/resolver/mod.rs 3 | expression: "resolve_lineage(r#\"\n from table_1\n join customers (==customer_no)\n \"#).unwrap()" 4 | --- 5 | columns: 6 | - All: 7 | input_id: 116 8 | except: [] 9 | - All: 10 | input_id: 113 11 | except: [] 12 | inputs: 13 | - id: 116 14 | name: table_1 15 | table: 16 | - default_db 17 | - table_1 18 | - id: 113 19 | name: customers 20 | table: 21 | - default_db 22 | - customers 23 | -------------------------------------------------------------------------------- /prqlc/prqlc/src/semantic/resolver/snapshots/prqlc__semantic__resolver__test__frames_and_names.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/src/semantic/resolver/mod.rs 3 | expression: "resolve_lineage(r#\"\n from orders\n select {customer_no, gross, tax, gross - tax}\n take 20\n \"#).unwrap()" 4 | --- 5 | columns: 6 | - Single: 7 | name: 8 | - orders 9 | - customer_no 10 | target_id: 120 11 | target_name: ~ 12 | - Single: 13 | name: 14 | - orders 15 | - gross 16 | target_id: 121 17 | target_name: ~ 18 | - Single: 19 | name: 20 | - orders 21 | - tax 22 | target_id: 122 23 | target_name: ~ 24 | - Single: 25 | name: ~ 26 | target_id: 123 27 | target_name: ~ 28 | inputs: 29 | - id: 118 30 | name: orders 31 | table: 32 | - default_db 33 | - orders 34 | -------------------------------------------------------------------------------- /prqlc/prqlc/src/semantic/resolver/snapshots/prqlc__semantic__resolver__test__functions_1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/src/semantic/resolver/mod.rs 3 | expression: "resolve_derive(r#\"\n let subtract = a b -> a - b\n\n from employees\n derive {\n net_salary = subtract gross_salary tax\n }\n \"#).unwrap()" 4 | --- 5 | - RqOperator: 6 | name: std.sub 7 | args: 8 | - Ident: 9 | - this 10 | - employees 11 | - gross_salary 12 | span: "1:128-140" 13 | - Ident: 14 | - this 15 | - employees 16 | - tax 17 | span: "1:141-144" 18 | span: "1:119-144" 19 | alias: net_salary 20 | -------------------------------------------------------------------------------- /prqlc/prqlc/src/semantic/resolver/snapshots/prqlc__semantic__resolver__test__functions_pipeline.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/src/semantic/resolver/mod.rs 3 | expression: "resolve_derive(r#\"\n from a\n derive one = (foo | sum)\n \"#).unwrap()" 4 | --- 5 | - RqOperator: 6 | name: std.sum 7 | args: 8 | - Ident: 9 | - this 10 | - a 11 | - foo 12 | span: "1:46-49" 13 | ty: 14 | kind: 15 | Array: ~ 16 | span: "0:1699-1701" 17 | name: array 18 | span: "1:52-55" 19 | alias: one 20 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/data/chinook/genres.csv: -------------------------------------------------------------------------------- 1 | genre_id,name 2 | 1,Rock 3 | 2,Jazz 4 | 3,Metal 5 | 4,Alternative & Punk 6 | 5,Rock And Roll 7 | 6,Blues 8 | 7,Latin 9 | 8,Reggae 10 | 9,Pop 11 | 10,Soundtrack 12 | 11,Bossa Nova 13 | 12,Easy Listening 14 | 13,Heavy Metal 15 | 14,R&B/Soul 16 | 15,Electronica/Dance 17 | 16,World 18 | 17,Hip Hop/Rap 19 | 18,Science Fiction 20 | 19,TV Shows 21 | 20,Sci Fi & Fantasy 22 | 21,Drama 23 | 22,Comedy 24 | 23,Alternative 25 | 24,Classical 26 | 25,Opera 27 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/data/chinook/media_types.csv: -------------------------------------------------------------------------------- 1 | media_type_id,name 2 | 1,MPEG audio file 3 | 2,Protected AAC audio file 4 | 3,Protected MPEG-4 video file 5 | 4,Purchased AAC audio file 6 | 5,AAC audio file 7 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/data/chinook/playlists.csv: -------------------------------------------------------------------------------- 1 | playlist_id,name 2 | 1,Music 3 | 2,Movies 4 | 3,TV Shows 5 | 4,Audiobooks 6 | 5,90’s Music 7 | 6,Audiobooks 8 | 7,Movies 9 | 8,Music 10 | 9,Music Videos 11 | 10,TV Shows 12 | 11,Brazilian Music 13 | 12,Classical 14 | 13,Classical 101 - Deep Cuts 15 | 14,Classical 101 - Next Steps 16 | 15,Classical 101 - The Basics 17 | 16,Grunge 18 | 17,Heavy Metal Classic 19 | 18,On-The-Go 1 20 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/dbs/dockerfiles/glaredb.Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1.4 2 | 3 | # TODO: switch to `curlimages/curl` 4 | # glaredb binary releases are not compatible with alpine 5 | # So we can't use here now 6 | # https://github.com/GlareDB/glaredb/issues/1912 7 | FROM --platform=linux/amd64 docker.io/library/buildpack-deps:stable 8 | 9 | RUN < 0 10 | select a = -a 11 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/queries/group_all.prql: -------------------------------------------------------------------------------- 1 | # mssql:test 2 | from a=albums 3 | take 10 4 | join tracks (==album_id) 5 | group {a.album_id, a.title} (aggregate price = (sum tracks.unit_price | math.round 2)) 6 | sort album_id 7 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/queries/group_sort.prql: -------------------------------------------------------------------------------- 1 | # mssql:test 2 | from tracks 3 | derive d = album_id + 1 4 | group d ( 5 | aggregate { 6 | n1 = (track_id | sum), 7 | } 8 | ) 9 | sort d 10 | take 10 11 | select { d1 = d, n1 } 12 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/queries/group_sort_limit_take.prql: -------------------------------------------------------------------------------- 1 | # Compute the 3 longest songs for each genre and sort by genre 2 | # mssql:test 3 | from tracks 4 | select {genre_id,milliseconds} 5 | group {genre_id} ( 6 | sort {-milliseconds} 7 | take 3 8 | ) 9 | join genres (==genre_id) 10 | select {name, milliseconds} 11 | sort {+name,-milliseconds} 12 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/queries/loop_01.prql: -------------------------------------------------------------------------------- 1 | # clickhouse:skip (DB::Exception: Syntax error) 2 | # glaredb:skip (DataFusion does not support recursive CTEs https://github.com/apache/arrow-datafusion/issues/462) 3 | from [{n = 1}] 4 | select n = n - 2 5 | loop (filter n < 4 | select n = n + 1) 6 | select n = n * 2 7 | sort n 8 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/queries/pipelines.prql: -------------------------------------------------------------------------------- 1 | # sqlite:skip (Only works on Sqlite implementations which have the extension 2 | # installed 3 | # https://stackoverflow.com/questions/24037982/how-to-use-regexp-in-sqlite) 4 | 5 | from tracks 6 | 7 | filter (name ~= "Love") 8 | filter ((milliseconds / 1000 / 60) | in 3..4) 9 | sort track_id 10 | take 1..15 11 | select {name, composer} 12 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/queries/read_csv.prql: -------------------------------------------------------------------------------- 1 | # sqlite:skip 2 | # postgres:skip 3 | # mysql:skip 4 | from (read_csv "data_file_root/media_types.csv") 5 | sort media_type_id 6 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/queries/set_ops_remove.prql: -------------------------------------------------------------------------------- 1 | # mssql:test 2 | let distinct = rel -> (from t = _param.rel | group {t.*} (take 1)) 3 | 4 | from_text format:json '{ "columns": ["a"], "data": [[1], [2], [2], [3]] }' 5 | distinct 6 | remove (from_text format:json '{ "columns": ["a"], "data": [[1], [2]] }') 7 | sort a 8 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/queries/sort.prql: -------------------------------------------------------------------------------- 1 | # mssql:test 2 | from e=employees 3 | filter first_name != "Mitchell" 4 | sort {first_name, last_name} 5 | 6 | # joining may use HashMerge, which can undo ORDER BY 7 | join manager=employees side:left (e.reports_to == manager.employee_id) 8 | 9 | select {e.first_name, e.last_name, manager.first_name} 10 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/queries/sort_2.prql: -------------------------------------------------------------------------------- 1 | from albums 2 | select { AA=album_id, artist_id } 3 | sort AA 4 | filter AA >= 25 5 | join artists (==artist_id) 6 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/queries/sort_3.prql: -------------------------------------------------------------------------------- 1 | from [{track_id=0, album_id=1, genre_id=2}] 2 | select { AA=track_id, album_id, genre_id } 3 | sort AA 4 | join side:left [{album_id=1, album_title="Songs"}] (==album_id) 5 | select { AA, AT = album_title ?? "unknown", genre_id } 6 | filter AA < 25 7 | join side:left [{genre_id=1, genre_title="Rock"}] (==genre_id) 8 | select { AA, AT, GT = genre_title ?? "unknown" } 9 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/queries/switch.prql: -------------------------------------------------------------------------------- 1 | # glaredb:skip (May be a bag of String type conversion for Postgres Client) 2 | # mssql:test 3 | from tracks 4 | sort milliseconds 5 | select display = case [ 6 | composer != null => composer, 7 | genre_id < 17 => 'no composer', 8 | true => f'unknown composer' 9 | ] 10 | take 10 11 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/queries/take.prql: -------------------------------------------------------------------------------- 1 | # mssql:test 2 | from tracks 3 | sort {+track_id} 4 | take 3..5 5 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/queries/text_module.prql: -------------------------------------------------------------------------------- 1 | # mssql:test 2 | # glaredb:skip — TODO: started raising an error on 2024-05-20; see `window.prql` 3 | # for more details 4 | from albums 5 | select { 6 | title, 7 | title_and_spaces = f" {title} ", 8 | low = (title | text.lower), 9 | up = (title | text.upper), 10 | ltrimmed = (title | text.ltrim), 11 | rtrimmed = (title | text.rtrim), 12 | trimmed = (title | text.trim), 13 | len = (title | text.length), 14 | subs = (title | text.extract 2 5), 15 | replace = (title | text.replace "al" "PIKA"), 16 | } 17 | sort {title} 18 | filter (title | text.starts_with "Black") || (title | text.contains "Sabbath") || (title | text.ends_with "os") 19 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/queries/window.prql: -------------------------------------------------------------------------------- 1 | # clickhouse:skip problems with DISTINCT ON 2 | # glaredb:skip — TODO: started raising an error on 2024-05-20, from https://github.com/PRQL/prql/actions/runs/9154902656/job/25198160283: 3 | # ERROR: This feature is not implemented: Unsupported ast node in sqltorel: 4 | # Substring { expr: Identifier(Ident { value: "title", quote_style: None }), 5 | # substring_from: Some(Value(Number("2", false))), substring_for: 6 | # Some(Value(Number("5", false))), special: true } 7 | from tracks 8 | group genre_id ( 9 | sort milliseconds 10 | derive { 11 | num = row_number this, 12 | total = count this, 13 | last_val = last track_id, 14 | } 15 | take 10 16 | ) 17 | sort {genre_id, milliseconds} 18 | select {track_id, genre_id, num, total, last_val} 19 | filter genre_id >= 22 20 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__compile__aggregation.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mysql:skip\n# clickhouse:skip\n# glaredb:skip (the string_agg function is not supported)\nfrom tracks\nfilter genre_id == 100\nderive empty_name = name == ''\naggregate {sum track_id, concat_array name, all empty_name, any empty_name}\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/aggregation.prql 5 | --- 6 | SELECT 7 | COALESCE(SUM(track_id), 0), 8 | COALESCE(STRING_AGG(name, ''), ''), 9 | COALESCE(BOOL_AND(name = ''), TRUE), 10 | COALESCE(BOOL_OR(name = ''), FALSE) 11 | FROM 12 | tracks 13 | WHERE 14 | genre_id = 100 15 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__compile__cast.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom tracks\nsort {-bytes}\nselect {\n name,\n bin = ((album_id | as REAL) * 99)\n}\ntake 20\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/cast.prql 5 | --- 6 | WITH table_0 AS ( 7 | SELECT 8 | name, 9 | CAST(album_id AS REAL) * 99 AS bin, 10 | bytes 11 | FROM 12 | tracks 13 | ORDER BY 14 | bytes DESC 15 | LIMIT 16 | 20 17 | ) 18 | SELECT 19 | name, 20 | bin 21 | FROM 22 | table_0 23 | ORDER BY 24 | bytes DESC 25 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__compile__constants_only.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "from genres\ntake 10\nfilter true\ntake 20\nfilter true\nselect d = 10\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/constants_only.prql 5 | --- 6 | WITH table_1 AS ( 7 | SELECT 8 | NULL 9 | FROM 10 | genres 11 | LIMIT 12 | 10 13 | ), table_0 AS ( 14 | SELECT 15 | NULL 16 | FROM 17 | table_1 18 | WHERE 19 | true 20 | LIMIT 21 | 20 22 | ) 23 | SELECT 24 | 10 AS d 25 | FROM 26 | table_0 27 | WHERE 28 | true 29 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__compile__distinct.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom tracks\nselect {album_id, genre_id}\ngroup tracks.* (take 1)\nsort tracks.*\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/distinct.prql 5 | --- 6 | WITH table_0 AS ( 7 | SELECT 8 | DISTINCT album_id, 9 | genre_id 10 | FROM 11 | tracks 12 | ) 13 | SELECT 14 | album_id, 15 | genre_id 16 | FROM 17 | table_0 18 | ORDER BY 19 | album_id, 20 | genre_id 21 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__compile__distinct_on.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom tracks\nselect {genre_id, media_type_id, album_id}\ngroup {genre_id, media_type_id} (sort {-album_id} | take 1)\nsort {-genre_id, media_type_id}\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/distinct_on.prql 5 | --- 6 | WITH table_0 AS ( 7 | SELECT 8 | genre_id, 9 | media_type_id, 10 | album_id, 11 | ROW_NUMBER() OVER ( 12 | PARTITION BY genre_id, 13 | media_type_id 14 | ORDER BY 15 | album_id DESC 16 | ) AS _expr_0 17 | FROM 18 | tracks 19 | ) 20 | SELECT 21 | genre_id, 22 | media_type_id, 23 | album_id 24 | FROM 25 | table_0 26 | WHERE 27 | _expr_0 <= 1 28 | ORDER BY 29 | genre_id DESC, 30 | media_type_id 31 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__compile__genre_counts.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# clickhouse:skip (ClickHouse prefers aliases to column names https://github.com/PRQL/prql/issues/2827)\n# mssql:test\nlet genre_count = (\n from genres\n aggregate {a = count name}\n)\n\nfrom genre_count\nfilter a > 0\nselect a = -a\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/genre_counts.prql 5 | --- 6 | WITH genre_count AS ( 7 | SELECT 8 | COUNT(*) AS a 9 | FROM 10 | genres 11 | ) 12 | SELECT 13 | - a AS a 14 | FROM 15 | genre_count 16 | WHERE 17 | a > 0 18 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__compile__group_all.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom a=albums\ntake 10\njoin tracks (==album_id)\ngroup {a.album_id, a.title} (aggregate price = (sum tracks.unit_price | math.round 2))\nsort album_id\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/group_all.prql 5 | --- 6 | WITH table_0 AS ( 7 | SELECT 8 | album_id, 9 | title 10 | FROM 11 | albums AS a 12 | LIMIT 13 | 10 14 | ) 15 | SELECT 16 | table_0.album_id, 17 | table_0.title, 18 | ROUND(COALESCE(SUM(tracks.unit_price), 0), 2) AS price 19 | FROM 20 | table_0 21 | INNER JOIN tracks ON table_0.album_id = tracks.album_id 22 | GROUP BY 23 | table_0.album_id, 24 | table_0.title 25 | ORDER BY 26 | table_0.album_id 27 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__compile__group_sort.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom tracks\nderive d = album_id + 1\ngroup d (\n aggregate {\n n1 = (track_id | sum),\n }\n)\nsort d\ntake 10\nselect { d1 = d, n1 }\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/group_sort.prql 5 | --- 6 | WITH table_0 AS ( 7 | SELECT 8 | COALESCE(SUM(track_id), 0) AS n1, 9 | album_id + 1 AS _expr_0 10 | FROM 11 | tracks 12 | GROUP BY 13 | album_id + 1 14 | ), 15 | table_1 AS ( 16 | SELECT 17 | _expr_0 AS d1, 18 | n1, 19 | _expr_0 20 | FROM 21 | table_0 22 | ORDER BY 23 | _expr_0 24 | LIMIT 25 | 10 26 | ) 27 | SELECT 28 | d1, 29 | n1 30 | FROM 31 | table_1 32 | ORDER BY 33 | _expr_0 34 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__compile__loop_01.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# clickhouse:skip (DB::Exception: Syntax error)\n# glaredb:skip (DataFusion does not support recursive CTEs https://github.com/apache/arrow-datafusion/issues/462)\nfrom [{n = 1}]\nselect n = n - 2\nloop (filter n < 4 | select n = n + 1)\nselect n = n * 2\nsort n\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/loop_01.prql 5 | --- 6 | WITH RECURSIVE table_0 AS ( 7 | SELECT 8 | 1 AS n 9 | ), 10 | table_1 AS ( 11 | SELECT 12 | n - 2 AS _expr_0 13 | FROM 14 | table_0 15 | UNION 16 | ALL 17 | SELECT 18 | _expr_0 + 1 19 | FROM 20 | table_1 21 | WHERE 22 | _expr_0 < 4 23 | ) 24 | SELECT 25 | _expr_0 * 2 AS n 26 | FROM 27 | table_1 AS table_2 28 | ORDER BY 29 | n 30 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__compile__pipelines.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# sqlite:skip (Only works on Sqlite implementations which have the extension\n# installed\n# https://stackoverflow.com/questions/24037982/how-to-use-regexp-in-sqlite)\n\nfrom tracks\n\nfilter (name ~= \"Love\")\nfilter ((milliseconds / 1000 / 60) | in 3..4)\nsort track_id\ntake 1..15\nselect {name, composer}\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/pipelines.prql 5 | --- 6 | WITH table_0 AS ( 7 | SELECT 8 | name, 9 | composer, 10 | track_id 11 | FROM 12 | tracks 13 | WHERE 14 | REGEXP(name, 'Love') 15 | AND milliseconds / 1000 / 60 BETWEEN 3 AND 4 16 | ORDER BY 17 | track_id 18 | LIMIT 19 | 15 20 | ) 21 | SELECT 22 | name, 23 | composer 24 | FROM 25 | table_0 26 | ORDER BY 27 | track_id 28 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__compile__read_csv.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# sqlite:skip\n# postgres:skip\n# mysql:skip\nfrom (read_csv \"data_file_root/media_types.csv\")\nsort media_type_id\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/read_csv.prql 5 | --- 6 | WITH table_0 AS ( 7 | SELECT 8 | * 9 | FROM 10 | read_csv('data_file_root/media_types.csv') 11 | ) 12 | SELECT 13 | * 14 | FROM 15 | table_0 16 | ORDER BY 17 | media_type_id 18 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__compile__sort_2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "from albums\nselect { AA=album_id, artist_id }\nsort AA\nfilter AA >= 25\njoin artists (==artist_id)\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/sort_2.prql 5 | --- 6 | WITH table_1 AS ( 7 | SELECT 8 | album_id AS "AA", 9 | artist_id 10 | FROM 11 | albums 12 | ), 13 | table_0 AS ( 14 | SELECT 15 | "AA", 16 | artist_id 17 | FROM 18 | table_1 19 | WHERE 20 | "AA" >= 25 21 | ) 22 | SELECT 23 | table_0."AA", 24 | table_0.artist_id, 25 | artists.* 26 | FROM 27 | table_0 28 | INNER JOIN artists ON table_0.artist_id = artists.artist_id 29 | ORDER BY 30 | table_0."AA" 31 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__compile__switch.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# glaredb:skip (May be a bag of String type conversion for Postgres Client)\n# mssql:test\nfrom tracks\nsort milliseconds\nselect display = case [\n composer != null => composer,\n genre_id < 17 => 'no composer',\n true => f'unknown composer'\n]\ntake 10\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/switch.prql 5 | --- 6 | WITH table_0 AS ( 7 | SELECT 8 | CASE 9 | WHEN composer IS NOT NULL THEN composer 10 | WHEN genre_id < 17 THEN 'no composer' 11 | ELSE 'unknown composer' 12 | END AS display, 13 | milliseconds 14 | FROM 15 | tracks 16 | ORDER BY 17 | milliseconds 18 | LIMIT 19 | 10 20 | ) 21 | SELECT 22 | display 23 | FROM 24 | table_0 25 | ORDER BY 26 | milliseconds 27 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__compile__take.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom tracks\nsort {+track_id}\ntake 3..5\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/take.prql 5 | --- 6 | SELECT 7 | * 8 | FROM 9 | tracks 10 | ORDER BY 11 | track_id 12 | LIMIT 13 | 3 OFFSET 2 14 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__fmt__aggregation.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mysql:skip\n# clickhouse:skip\n# glaredb:skip (the string_agg function is not supported)\nfrom tracks\nfilter genre_id == 100\nderive empty_name = name == ''\naggregate {sum track_id, concat_array name, all empty_name, any empty_name}\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/aggregation.prql 5 | --- 6 | from tracks 7 | filter genre_id == 100 8 | derive empty_name = name == "" 9 | aggregate { 10 | sum track_id, 11 | concat_array name, 12 | all empty_name, 13 | any empty_name, 14 | } 15 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__fmt__cast.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom tracks\nsort {-bytes}\nselect {\n name,\n bin = ((album_id | as REAL) * 99)\n}\ntake 20\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/cast.prql 5 | --- 6 | from tracks 7 | sort {-bytes} 8 | select {name, bin = (album_id | as REAL) * 99} 9 | take 20 10 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__fmt__constants_only.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "from genres\ntake 10\nfilter true\ntake 20\nfilter true\nselect d = 10\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/constants_only.prql 5 | --- 6 | from genres 7 | take 10 8 | filter true 9 | take 20 10 | filter true 11 | select d = 10 12 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__fmt__distinct.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom tracks\nselect {album_id, genre_id}\ngroup tracks.* (take 1)\nsort tracks.*\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/distinct.prql 5 | --- 6 | from tracks 7 | select {album_id, genre_id} 8 | group tracks.`*` (take 1) 9 | sort tracks.`*` 10 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__fmt__distinct_on.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom tracks\nselect {genre_id, media_type_id, album_id}\ngroup {genre_id, media_type_id} (sort {-album_id} | take 1)\nsort {-genre_id, media_type_id}\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/distinct_on.prql 5 | --- 6 | from tracks 7 | select {genre_id, media_type_id, album_id} 8 | group {genre_id, media_type_id} ( 9 | sort {-album_id} 10 | take 1 11 | ) 12 | sort {-genre_id, media_type_id} 13 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__fmt__genre_counts.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# clickhouse:skip (ClickHouse prefers aliases to column names https://github.com/PRQL/prql/issues/2827)\n# mssql:test\nlet genre_count = (\n from genres\n aggregate {a = count name}\n)\n\nfrom genre_count\nfilter a > 0\nselect a = -a\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/genre_counts.prql 5 | --- 6 | let genre_count = ( 7 | from genres 8 | aggregate {a = count name} 9 | ) 10 | 11 | from genre_count 12 | filter a > 0 13 | select a = -a 14 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__fmt__group_all.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom a=albums\ntake 10\njoin tracks (==album_id)\ngroup {a.album_id, a.title} (aggregate price = (sum tracks.unit_price | math.round 2))\nsort album_id\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/group_all.prql 5 | --- 6 | from a = albums 7 | take 10 8 | join tracks (==album_id) 9 | group {a.album_id, a.title} (aggregate price = ( 10 | sum tracks.unit_price 11 | math.round 2 12 | )) 13 | sort album_id 14 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__fmt__group_sort.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom tracks\nderive d = album_id + 1\ngroup d (\n aggregate {\n n1 = (track_id | sum),\n }\n)\nsort d\ntake 10\nselect { d1 = d, n1 }\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/group_sort.prql 5 | --- 6 | from tracks 7 | derive d = album_id + 1 8 | group d (aggregate {n1 = (track_id | sum)}) 9 | sort d 10 | take 10 11 | select {d1 = d, n1} 12 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__fmt__group_sort_limit_take.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# Compute the 3 longest songs for each genre and sort by genre\n# mssql:test\nfrom tracks\nselect {genre_id,milliseconds}\ngroup {genre_id} (\n sort {-milliseconds}\n take 3\n)\njoin genres (==genre_id)\nselect {name, milliseconds}\nsort {+name,-milliseconds}\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/group_sort_limit_take.prql 5 | --- 6 | from tracks 7 | select {genre_id, milliseconds} 8 | group {genre_id} (sort {-milliseconds} | take 3) 9 | join genres (==genre_id) 10 | select {name, milliseconds} 11 | sort {+name, -milliseconds} 12 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__fmt__loop_01.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# clickhouse:skip (DB::Exception: Syntax error)\n# glaredb:skip (DataFusion does not support recursive CTEs https://github.com/apache/arrow-datafusion/issues/462)\nfrom [{n = 1}]\nselect n = n - 2\nloop (filter n < 4 | select n = n + 1)\nselect n = n * 2\nsort n\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/loop_01.prql 5 | --- 6 | from [{n = 1}] 7 | select n = n - 2 8 | loop (filter n < 4 | select n = n + 1) 9 | select n = n * 2 10 | sort n 11 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__fmt__pipelines.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# sqlite:skip (Only works on Sqlite implementations which have the extension\n# installed\n# https://stackoverflow.com/questions/24037982/how-to-use-regexp-in-sqlite)\n\nfrom tracks\n\nfilter (name ~= \"Love\")\nfilter ((milliseconds / 1000 / 60) | in 3..4)\nsort track_id\ntake 1..15\nselect {name, composer}\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/pipelines.prql 5 | --- 6 | from tracks 7 | filter name ~= "Love" 8 | filter (milliseconds / 1000 / 60 | in 3..4) 9 | sort track_id 10 | take 1..15 11 | select {name, composer} 12 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__fmt__read_csv.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# sqlite:skip\n# postgres:skip\n# mysql:skip\nfrom (read_csv \"data_file_root/media_types.csv\")\nsort media_type_id\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/read_csv.prql 5 | --- 6 | from (read_csv "data_file_root/media_types.csv") 7 | sort media_type_id 8 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__fmt__set_ops_remove.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nlet distinct = rel -> (from t = _param.rel | group {t.*} (take 1))\n\nfrom_text format:json '{ \"columns\": [\"a\"], \"data\": [[1], [2], [2], [3]] }'\ndistinct\nremove (from_text format:json '{ \"columns\": [\"a\"], \"data\": [[1], [2]] }')\nsort a\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/set_ops_remove.prql 5 | --- 6 | let distinct = func rel -> ( 7 | from t = _param.rel 8 | group {t.`*`} (take 1) 9 | ) 10 | 11 | from_text format:json '{ "columns": ["a"], "data": [[1], [2], [2], [3]] }' 12 | distinct 13 | remove (from_text format:json '{ "columns": ["a"], "data": [[1], [2]] }') 14 | sort a 15 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__fmt__sort.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom e=employees\nfilter first_name != \"Mitchell\"\nsort {first_name, last_name}\n\n# joining may use HashMerge, which can undo ORDER BY\njoin manager=employees side:left (e.reports_to == manager.employee_id)\n\nselect {e.first_name, e.last_name, manager.first_name}\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/sort.prql 5 | --- 6 | from e = employees 7 | filter first_name != "Mitchell" 8 | sort {first_name, last_name} 9 | join side:left manager = employees e.reports_to == manager.employee_id 10 | select {e.first_name, e.last_name, manager.first_name} 11 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__fmt__sort_2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "from albums\nselect { AA=album_id, artist_id }\nsort AA\nfilter AA >= 25\njoin artists (==artist_id)\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/sort_2.prql 5 | --- 6 | from albums 7 | select {AA = album_id, artist_id} 8 | sort AA 9 | filter AA >= 25 10 | join artists (==artist_id) 11 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__fmt__switch.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# glaredb:skip (May be a bag of String type conversion for Postgres Client)\n# mssql:test\nfrom tracks\nsort milliseconds\nselect display = case [\n composer != null => composer,\n genre_id < 17 => 'no composer',\n true => f'unknown composer'\n]\ntake 10\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/switch.prql 5 | --- 6 | from tracks 7 | sort milliseconds 8 | select display = case [ 9 | composer != null => composer, 10 | genre_id < 17 => "no composer", 11 | true => f"unknown composer", 12 | ] 13 | take 10 14 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__fmt__take.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom tracks\nsort {+track_id}\ntake 3..5\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/take.prql 5 | --- 6 | from tracks 7 | sort {+track_id} 8 | take 3..5 9 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__lex__read_csv.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: tokens 4 | input_file: prqlc/prqlc/tests/integration/queries/read_csv.prql 5 | --- 6 | Tokens( 7 | [ 8 | 0..0: Start, 9 | 0..13: Comment(" sqlite:skip"), 10 | 13..14: NewLine, 11 | 14..29: Comment(" postgres:skip"), 12 | 29..30: NewLine, 13 | 30..42: Comment(" mysql:skip"), 14 | 42..43: NewLine, 15 | 43..47: Ident("from"), 16 | 48..49: Control('('), 17 | 49..57: Ident("read_csv"), 18 | 58..90: Literal(String("data_file_root/media_types.csv")), 19 | 90..91: Control(')'), 20 | 91..92: NewLine, 21 | 92..96: Ident("sort"), 22 | 97..110: Ident("media_type_id"), 23 | 110..111: NewLine, 24 | ], 25 | ) 26 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__lex__take.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: tokens 4 | input_file: prqlc/prqlc/tests/integration/queries/take.prql 5 | --- 6 | Tokens( 7 | [ 8 | 0..0: Start, 9 | 0..12: Comment(" mssql:test"), 10 | 12..13: NewLine, 11 | 13..17: Ident("from"), 12 | 18..24: Ident("tracks"), 13 | 24..25: NewLine, 14 | 25..29: Ident("sort"), 15 | 30..31: Control('{'), 16 | 31..32: Control('+'), 17 | 32..40: Ident("track_id"), 18 | 40..41: Control('}'), 19 | 41..42: NewLine, 20 | 42..46: Ident("take"), 21 | 47..48: Literal(Integer(3)), 22 | 48..50: Range { bind_left: true, bind_right: true }, 23 | 50..51: Literal(Integer(5)), 24 | 51..52: NewLine, 25 | ], 26 | ) 27 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__results__aggregation.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:skip\n# mysql:skip\n# clickhouse:skip\n# glaredb:skip (the string_agg function is not supported)\nfrom tracks\nfilter genre_id == 100\nderive empty_name = name == ''\naggregate {sum track_id, concat_array name, all empty_name, any empty_name}\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/aggregation.prql 5 | --- 6 | 0,,1,0 7 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__results__constants_only.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "from genres\ntake 10\nfilter true\ntake 20\nfilter true\nselect d = 10\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/constants_only.prql 5 | --- 6 | 10 7 | 10 8 | 10 9 | 10 10 | 10 11 | 10 12 | 10 13 | 10 14 | 10 15 | 10 16 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__results__distinct_on.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom tracks\nselect {genre_id, media_type_id, album_id}\ngroup {genre_id, media_type_id} (sort {-album_id} | take 1)\nsort {-genre_id, media_type_id}\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/distinct_on.prql 5 | --- 6 | 25,2,317 7 | 24,2,346 8 | 24,4,342 9 | 24,5,268 10 | 23,2,323 11 | 23,3,271 12 | 23,4,260 13 | 22,3,251 14 | 21,3,261 15 | 20,3,253 16 | 19,3,261 17 | 18,3,227 18 | 17,1,258 19 | 16,1,161 20 | 16,5,263 21 | 15,1,259 22 | 15,5,264 23 | 14,1,146 24 | 14,2,321 25 | 13,1,102 26 | 12,1,83 27 | 11,1,52 28 | 10,1,176 29 | 10,2,347 30 | 9,1,29 31 | 9,2,322 32 | 8,1,241 33 | 7,1,248 34 | 7,5,266 35 | 6,1,210 36 | 5,1,12 37 | 4,1,225 38 | 3,1,207 39 | 2,1,204 40 | 2,5,267 41 | 1,1,246 42 | 1,2,257 43 | 1,5,265 44 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__results__genre_counts.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# clickhouse:skip (ClickHouse prefers aliases to column names https://github.com/PRQL/prql/issues/2827)\n# mssql:test\nlet genre_count = (\n from genres\n aggregate {a = count name}\n)\n\nfrom genre_count\nfilter a > 0\nselect a = -a\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/genre_counts.prql 5 | --- 6 | -25 7 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__results__group_all.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom a=albums\ntake 10\njoin tracks (==album_id)\ngroup {a.album_id, a.title} (aggregate price = (sum tracks.unit_price | math.round 2))\nsort album_id\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/group_all.prql 5 | --- 6 | 1,For Those About To Rock We Salute You,9.9 7 | 2,Balls to the Wall,0.99 8 | 3,Restless and Wild,2.97 9 | 4,Let There Be Rock,7.92 10 | 5,Big Ones,14.85 11 | 6,Jagged Little Pill,12.87 12 | 7,Facelift,11.88 13 | 8,Warner 25 Anos,13.86 14 | 9,Plays Metallica By Four Cellos,7.92 15 | 10,Audioslave,13.86 16 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__results__group_sort.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom tracks\nderive d = album_id + 1\ngroup d (\n aggregate {\n n1 = (track_id | sum),\n }\n)\nsort d\ntake 10\nselect { d1 = d, n1 }\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/group_sort.prql 5 | --- 6 | 2,91 7 | 3,2 8 | 4,12 9 | 5,148 10 | 6,450 11 | 7,572 12 | 8,678 13 | 9,973 14 | 10,644 15 | 11,1281 16 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__results__loop_01.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# clickhouse:skip (DB::Exception: Syntax error)\n# glaredb:skip (DataFusion does not support recursive CTEs https://github.com/apache/arrow-datafusion/issues/462)\nfrom [{n = 1}]\nselect n = n - 2\nloop (filter n < 4 | select n = n + 1)\nselect n = n * 2\nsort n\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/loop_01.prql 5 | --- 6 | -2 7 | 0 8 | 2 9 | 4 10 | 6 11 | 8 12 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__results__read_csv.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# sqlite:skip\n# postgres:skip\n# mysql:skip\nfrom (read_csv \"data_file_root/media_types.csv\")\nsort media_type_id\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/read_csv.prql 5 | --- 6 | 1,MPEG audio file 7 | 2,Protected AAC audio file 8 | 3,Protected MPEG-4 video file 9 | 4,Purchased AAC audio file 10 | 5,AAC audio file 11 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__results__set_ops_remove.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nlet distinct = rel -> (from t = _param.rel | group {t.*} (take 1))\n\nfrom_text format:json '{ \"columns\": [\"a\"], \"data\": [[1], [2], [2], [3]] }'\ndistinct\nremove (from_text format:json '{ \"columns\": [\"a\"], \"data\": [[1], [2]] }')\nsort a\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/set_ops_remove.prql 5 | --- 6 | 3 7 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__results__sort.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom e=employees\nfilter first_name != \"Mitchell\"\nsort {first_name, last_name}\n\n# joining may use HashMerge, which can undo ORDER BY\njoin manager=employees side:left (e.reports_to == manager.employee_id)\n\nselect {e.first_name, e.last_name, manager.first_name}\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/sort.prql 5 | --- 6 | Andrew,Adams,Michael 7 | Jane,Peacock,Nancy 8 | Laura,Callahan,Michael 9 | Margaret,Park,Nancy 10 | Michael,Mitchell,Andrew 11 | Nancy,Edwards,Andrew 12 | Robert,King,Michael 13 | Steve,Johnson,Nancy 14 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__results__sort_3.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "from [{track_id=0, album_id=1, genre_id=2}]\nselect { AA=track_id, album_id, genre_id }\nsort AA\njoin side:left [{album_id=1, album_title=\"Songs\"}] (==album_id)\nselect { AA, AT = album_title ?? \"unknown\", genre_id }\nfilter AA < 25\njoin side:left [{genre_id=1, genre_title=\"Rock\"}] (==genre_id)\nselect { AA, AT, GT = genre_title ?? \"unknown\" }\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/sort_3.prql 5 | --- 6 | 0,Songs,unknown 7 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__results__switch.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# glaredb:skip (May be a bag of String type conversion for Postgres Client)\n# mssql:test\nfrom tracks\nsort milliseconds\nselect display = case [\n composer != null => composer,\n genre_id < 17 => 'no composer',\n true => f'unknown composer'\n]\ntake 10\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/switch.prql 5 | --- 6 | Samuel Rosa 7 | no composer 8 | no composer 9 | no composer 10 | L. Muggerud 11 | no composer 12 | L. Muggerud 13 | unknown composer 14 | Gilberto Gil 15 | Chico Science 16 | -------------------------------------------------------------------------------- /prqlc/prqlc/tests/integration/snapshots/integration__queries__results__take.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: prqlc/prqlc/tests/integration/queries.rs 3 | expression: "# mssql:test\nfrom tracks\nsort {+track_id}\ntake 3..5\n" 4 | input_file: prqlc/prqlc/tests/integration/queries/take.prql 5 | --- 6 | 3,Fast As a Shark,3,2,1,F. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman,230619,3990994,0.99 7 | 4,Restless and Wild,3,2,1,F. Baltes, R.A. Smith-Diesel, S. Kaufman, U. Dirkscneider & W. Hoffman,252051,4331779,0.99 8 | 5,Princess of the Dawn,3,2,1,Deaffy & R.A. Smith-Diesel,375418,6290521,0.99 9 | -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | # Generally run 1 behind latest 3 | channel = "1.86.0" 4 | components = ["rustfmt", "clippy"] 5 | # We want two targets: wasm32, and the default target for the platform, which we 6 | # don't list here. (i.e. we use each platform to test each platform) 7 | targets = ["wasm32-unknown-unknown"] 8 | -------------------------------------------------------------------------------- /web/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | 3 | # the old build dir 4 | book/book 5 | -------------------------------------------------------------------------------- /web/book/README.md: -------------------------------------------------------------------------------- 1 | # PRQL language book 2 | 3 | These docs serve as a language book, for users of the language. They should be 4 | friendly & accessible, at a minimum to those who understand basic SQL. 5 | 6 | ## Running 7 | 8 | Install all required PRQL dev tools with: 9 | 10 | ```sh 11 | task setup-dev 12 | ``` 13 | 14 | ...or for the precise cargo command, run `cargo install --locked mdbook`. For 15 | the complete build, add any `mdbook` crates listed in the `Taskfile.yaml`. 16 | 17 | And then to build & serve locally[^1]: 18 | 19 | ```sh 20 | task web:run-book 21 | ``` 22 | 23 | [^1]: ...which is equivalent to: 24 | 25 | ```sh 26 | cd book 27 | mdbook serve 28 | ``` 29 | -------------------------------------------------------------------------------- /web/book/book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | description = "Modern language for transforming data — a simple, powerful, pipelined SQL replacement" 3 | language = "en" 4 | multilingual = false 5 | title = "PRQL language book" 6 | 7 | [output.html] 8 | additional-css = ["comparison-table.css", "mdbook-admonish.css", "./mdbook-admonish.css"] 9 | additional-js = ["highlight-prql.js"] 10 | git-repository-url = "https://github.com/PRQL/prql" 11 | 12 | [preprocessor.prql] 13 | # This is required because mdbook-prql isn't necessarily installed; maybe 14 | # there's a better way. 15 | # 16 | command = "cargo run --bin mdbook-prql" 17 | 18 | [preprocessor.admonish] 19 | assets_version = "3.0.0" # do not edit: managed by `mdbook-admonish install` 20 | command = "mdbook-admonish" 21 | 22 | [preprocessor.footnote] 23 | # Seems to be required for footnotes to show properly. 24 | after = ["admonish"] 25 | -------------------------------------------------------------------------------- /web/book/comparison-table.css: -------------------------------------------------------------------------------- 1 | /* Styling for Tables */ 2 | 3 | .comparison { 4 | display: flex; 5 | flex-wrap: wrap; 6 | gap: 1rem; 7 | width: 100%; 8 | padding-bottom: 3rem; 9 | } 10 | .comparison > div { 11 | flex: 1 0 0; 12 | display: flex; 13 | flex-direction: column; 14 | padding-bottom: 0.5rem; 15 | } 16 | .comparison h4 { 17 | margin: 0; 18 | } 19 | .comparison pre { 20 | margin: 0; 21 | flex-grow: 1; 22 | } 23 | .comparison code { 24 | padding: 0.5rem; 25 | min-height: calc(100% - 1rem); 26 | } 27 | -------------------------------------------------------------------------------- /web/book/src/main.rs: -------------------------------------------------------------------------------- 1 | // We don't need to run this with wasm, and the features that `mdbook` uses of 2 | // `clap`'s don't support wasm. 3 | #[cfg(not(target_family = "wasm"))] 4 | fn main() { 5 | use mdbook_preprocessor_boilerplate::run; 6 | use mdbook_prql::ComparisonPreprocessor; 7 | run( 8 | ComparisonPreprocessor, 9 | "Create comparison examples between PRQL & SQL", 10 | ); 11 | } 12 | 13 | #[cfg(target_family = "wasm")] 14 | fn main() -> ! { 15 | panic!("Not used as a binary in wasm (but it seems cargo insists we have a `main` function).") 16 | } 17 | -------------------------------------------------------------------------------- /web/book/src/project/bindings/dotnet.md: -------------------------------------------------------------------------------- 1 | {{#include ../../../../../prqlc/bindings/dotnet/README.md}} 2 | -------------------------------------------------------------------------------- /web/book/src/project/bindings/elixir.md: -------------------------------------------------------------------------------- 1 | {{#include ../../../../../prqlc/bindings/elixir/README.md}} 2 | -------------------------------------------------------------------------------- /web/book/src/project/bindings/java.md: -------------------------------------------------------------------------------- 1 | {{#include ../../../../../prqlc/bindings/java/README.md}} 2 | -------------------------------------------------------------------------------- /web/book/src/project/bindings/javascript.md: -------------------------------------------------------------------------------- 1 | {{#include ../../../../../prqlc/bindings/js/README.md}} 2 | -------------------------------------------------------------------------------- /web/book/src/project/bindings/php.md: -------------------------------------------------------------------------------- 1 | {{#include ../../../../../prqlc/bindings/php/README.md}} 2 | -------------------------------------------------------------------------------- /web/book/src/project/bindings/python.md: -------------------------------------------------------------------------------- 1 | {{#include ../../../../../prqlc/bindings/prqlc-python/README.md}} 2 | -------------------------------------------------------------------------------- /web/book/src/project/bindings/r.md: -------------------------------------------------------------------------------- 1 | # R (prqlr) 2 | 3 | R bindings for `prqlc`. 4 | 5 | `prqlr` also includes `knitr` (R Markdown and Quarto) integration, which allows 6 | us to easily create documents with the PRQL conversion results embedded in. 7 | 8 | Check out for more context. 9 | 10 | ```admonish note 11 | `prqlr` is generously maintained by [@eitsupi](https://github.com/eitsupi) in the 12 | [PRQL/prqlc-r](https://github.com/PRQL/prqlc-r) repo. 13 | ``` 14 | 15 | ## Installation 16 | 17 | ```r 18 | install.packages("prqlr") 19 | ``` 20 | -------------------------------------------------------------------------------- /web/book/src/project/bindings/rust.md: -------------------------------------------------------------------------------- 1 | Please check the documentation of the 2 | [prqlc crate](https://docs.rs/prqlc/latest/prqlc/). 3 | -------------------------------------------------------------------------------- /web/book/src/project/changelog.md: -------------------------------------------------------------------------------- 1 | {{#include ../../../../CHANGELOG.md}} 2 | -------------------------------------------------------------------------------- /web/book/src/project/contributing/fortnightly-dev-call.ics: -------------------------------------------------------------------------------- 1 | BEGIN:VCALENDAR 2 | PRODID:-//Apple Inc.//macOS 12.6.1//EN 3 | VERSION:2.0 4 | BEGIN:VEVENT 5 | DTSTAMP:20240107T160200 6 | UID:dev-call.prql-lang.org 7 | DTSTART;TZID=America/New_York:20240107T133000 8 | DTEND;TZID=America/New_York:20240107T140000 9 | RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=1SU,3SU;UNTIL=20250331 10 | DESCRIPTION:Discord #dev-voice-channel\nhttps://discord.gg/2RUBzz3R3J\n1730Z on 1st & 3rd Sunday 11 | LOCATION:https://discord.gg/2RUBzz3R3J\n1730Z 12 | SEQUENCE:6 13 | STATUS:CONFIRMED 14 | SUMMARY:PRQL Fortnightly Dev Call 15 | TRANSP:TRANSPARENT 16 | END:VEVENT 17 | END:VCALENDAR 18 | -------------------------------------------------------------------------------- /web/book/src/project/integrations/README.md: -------------------------------------------------------------------------------- 1 | # Integrations 2 | 3 | PRQL is building integrations with lots of external tools, including: 4 | 5 | - [`prqlc` CLI](./prqlc-cli.md) - Rust compiler for the command line 6 | - [ClickHouse](./clickhouse.md) 7 | - [Jupyter](./jupyter.md) 8 | - [DuckDB](./duckdb.md) 9 | - [QStudio](./qstudio.md) 10 | - [Prefect](./prefect.md) 11 | - [VS Code](./vscode.md) 12 | - [PostgreSQL](./postgresql.md) 13 | - [Databend](./databend.md) 14 | - [Rill](./rill.md) 15 | - [Syntax highlighting](./syntax-highlighting.md) for many popular tools. 16 | -------------------------------------------------------------------------------- /web/book/src/project/integrations/clickhouse.md: -------------------------------------------------------------------------------- 1 | # ClickHouse 2 | 3 | PRQL works natively in ClickHouse. Check out the 4 | [ClickHouse docs](https://clickhouse.com/docs/en/guides/developer/alternative-query-languages) 5 | for more details. 6 | -------------------------------------------------------------------------------- /web/book/src/project/integrations/databend.md: -------------------------------------------------------------------------------- 1 | # Databend 2 | 3 | Databend natively supports PRQL. For more details see the 4 | [databend docs](https://www.databend.com/blog/2024-04-03-databend-integrates-prql/). 5 | -------------------------------------------------------------------------------- /web/book/src/project/integrations/duckdb.md: -------------------------------------------------------------------------------- 1 | # DuckDB 2 | 3 | There's a [DuckDB](https://duckdb.org/) community extension by 4 | **[@ywelsch](https://github.com/ywelsch)** at the DuckDB Community Extension 5 | Repository. 6 | 7 | ```sql 8 | INSTALL prql FROM community; 9 | LOAD prql; 10 | -- Once the extension is loaded, you can write PRQL queries 11 | from (read_csv 'https://raw.githubusercontent.com/PRQL/prql/0.8.0/prql-compiler/tests/integration/data/chinook/invoices.csv') 12 | filter invoice_date >= @2009-02-01 13 | take 5; 14 | ``` 15 | 16 | Check out the 17 | [extension's documentation](https://community-extensions.duckdb.org/extensions/prql.html) 18 | for more details. 19 | -------------------------------------------------------------------------------- /web/book/src/project/integrations/prefect.md: -------------------------------------------------------------------------------- 1 | # Prefect 2 | 3 | Because [Prefect](https://www.prefect.io/) is in native Python, it's extremely 4 | easy to integrate with PRQL. 5 | 6 | With a Postgres Task, replace: 7 | 8 | ```python 9 | PostgresExecute.run(..., query=sql) 10 | ``` 11 | 12 | ...with... 13 | 14 | ```python 15 | PostgresExecute.run(..., query=prql_python.compile(prql)) 16 | ``` 17 | 18 | We're big fans of Prefect, and if there is anything that would make the 19 | integration easier, please open an issue. 20 | -------------------------------------------------------------------------------- /web/book/src/project/integrations/prqlc-cli.md: -------------------------------------------------------------------------------- 1 | {{#include ../../../../../prqlc/prqlc/README.md}} 2 | -------------------------------------------------------------------------------- /web/book/src/project/integrations/rill.md: -------------------------------------------------------------------------------- 1 | # Rill 2 | 3 | PRQL has had some work to integrate with Rill. See the 4 | [Rill issues](https://github.com/PRQL/prql/issues?q=is%3Aissue+rill) for more 5 | details. 6 | -------------------------------------------------------------------------------- /web/book/src/project/integrations/syntax-highlighting.md: -------------------------------------------------------------------------------- 1 | {{#include ../../../../../grammars/README.md}} 2 | 3 | --- 4 | 5 | Since the [Elm](https://elm-lang.org/) language coincidentally provides syntax 6 | highlighting suitable for PRQL, it may look better to mark PRQL code as Elm when 7 | the above definition files are not available. 8 | 9 | For example, the following Markdown code block will be nicely highlighted on 10 | GitHub, Pandoc, and other Markdown renderers: 11 | 12 | ````markdown 13 | ```elm 14 | from employees 15 | filter start_date > @2021-01-01 16 | ``` 17 | ```` 18 | 19 | We hope that in the future these renderers will recognize PRQL code blocks and 20 | have syntax highlighting applied, and we are tracking these with several issues. 21 | 22 | - GitHub (Linguist): 23 | - Pandoc (Kate): 24 | -------------------------------------------------------------------------------- /web/book/src/project/integrations/vscode.md: -------------------------------------------------------------------------------- 1 | # Visual Studio Code extension 2 | 3 | PRQL has a Visual Studio Code extension that compiles a PRQL query in a VS Code 4 | editor and displays the resulting SQL code in a second pane on the side. This is 5 | very handy for editing, saving, and reusing PRQL queries in VS Code. 6 | 7 | To install the VS Code extension, open VS Code and type 8 | Ctrl-Shift-P 9 | (Cmd-Shift-P on a Mac) and type `PRQL`. Install 10 | the extension as usual. 11 | 12 | [Repo for the PRQL VS Code extension](https://github.com/PRQL/prql-vscode) 13 | 14 | [Extension on VS Marketplace](https://marketplace.visualstudio.com/items?itemName=PRQL-lang.prql-vscode) 15 | -------------------------------------------------------------------------------- /web/book/src/reference/data/README.md: -------------------------------------------------------------------------------- 1 | # Importing data 2 | -------------------------------------------------------------------------------- /web/book/src/reference/data/from.md: -------------------------------------------------------------------------------- 1 | # From 2 | 3 | Specifies a data source. 4 | 5 | ```prql 6 | from artists 7 | ``` 8 | 9 | To introduce an alias, use an assign expression: 10 | 11 | ```prql 12 | from e = employees 13 | select e.first_name 14 | ``` 15 | 16 | Table names containing spaces or special characters 17 | [need to be contained within backticks](../syntax/keywords.md#quoting): 18 | 19 | ```prql 20 | from `artist tracks` 21 | ``` 22 | 23 | `default_db.tablename` can be used if the table name matches a function from the 24 | standard library. 25 | 26 | ```admonish note 27 | We realize this is an awkward workaround. Track & 👍 [#3271](https://github.com/PRQL/prql/issues/3271) for resolving this. 28 | ``` 29 | 30 | ```prql 31 | default_db.group # in place of `from group` 32 | take 1 33 | ``` 34 | -------------------------------------------------------------------------------- /web/book/src/reference/declarations/README.md: -------------------------------------------------------------------------------- 1 | # Declarations 2 | -------------------------------------------------------------------------------- /web/book/src/reference/spec/README.md: -------------------------------------------------------------------------------- 1 | # Specification 2 | 3 | This chapter explains PRQL's semantics: how expressions are interpreted and 4 | their meaning. It's intended for advanced users and compiler contributors. 5 | -------------------------------------------------------------------------------- /web/book/src/reference/stdlib/transforms/derive.md: -------------------------------------------------------------------------------- 1 | # Derive 2 | 3 | Computes one or more new columns. 4 | 5 | ```prql no-eval 6 | derive { 7 | name = expression, 8 | # or 9 | column, 10 | } 11 | ``` 12 | 13 | ## Examples 14 | 15 | ```prql 16 | from employees 17 | derive gross_salary = salary + payroll_tax 18 | ``` 19 | 20 | ```prql 21 | from employees 22 | derive { 23 | gross_salary = salary + payroll_tax, 24 | gross_cost = gross_salary + benefits_cost 25 | } 26 | ``` 27 | -------------------------------------------------------------------------------- /web/book/src/reference/stdlib/transforms/filter.md: -------------------------------------------------------------------------------- 1 | # Filter 2 | 3 | Picks rows based on their values. 4 | 5 | ```prql no-eval 6 | filter boolean_expression 7 | ``` 8 | 9 | ## Examples 10 | 11 | ```prql 12 | from employees 13 | filter age > 25 14 | ``` 15 | 16 | ```prql 17 | from employees 18 | filter (age > 25 || department != "IT") 19 | ``` 20 | 21 | ```prql 22 | from employees 23 | filter (department | in ["IT", "HR"]) 24 | ``` 25 | 26 | ```prql 27 | from employees 28 | filter (age | in 25..40) 29 | ``` 30 | -------------------------------------------------------------------------------- /web/book/src/reference/stdlib/transforms/take.md: -------------------------------------------------------------------------------- 1 | # Take 2 | 3 | Picks rows based on their position. 4 | 5 | ```prql no-eval 6 | take (n|range) 7 | ``` 8 | 9 | See [Ranges](../../syntax/ranges.md) for more details on how ranges work. 10 | 11 | ## Examples 12 | 13 | ```prql 14 | from employees 15 | take 10 16 | ``` 17 | 18 | ```prql 19 | from orders 20 | sort {-value, created_at} 21 | take 101..110 22 | ``` 23 | -------------------------------------------------------------------------------- /web/book/src/reference/syntax/arrays.md: -------------------------------------------------------------------------------- 1 | # Arrays 2 | 3 | Array is a container type, composed of multiple items. All items must be of the 4 | same type. Number of fields can be vary. 5 | 6 | ```admonish warning 7 | This page is a stub. 8 | ``` 9 | -------------------------------------------------------------------------------- /web/book/src/reference/syntax/case.md: -------------------------------------------------------------------------------- 1 | # Case 2 | 3 | Search for the first condition that evaluates to `true` and return its 4 | associated value. If none of the conditions match, `null` is returned. 5 | 6 | ```prql 7 | from employees 8 | derive distance = case [ 9 | city == "Calgary" => 0, 10 | city == "Edmonton" => 300, 11 | ] 12 | ``` 13 | 14 | To set a default, a `true` condition can be used: 15 | 16 | ```prql 17 | from employees 18 | derive distance = case [ 19 | city == "Calgary" => 0, 20 | city == "Edmonton" => 300, 21 | true => "Unknown", 22 | ] 23 | ``` 24 | -------------------------------------------------------------------------------- /web/book/src/reference/syntax/comments.md: -------------------------------------------------------------------------------- 1 | # Comments 2 | 3 | Character `#` denotes a comment until the end of the line. 4 | 5 | ```prql 6 | from employees # Comment 1 7 | # Comment 2 8 | aggregate {average salary} 9 | ``` 10 | 11 | There's no distinct multiline comment syntax. 12 | -------------------------------------------------------------------------------- /web/book/src/reference/syntax/parameters.md: -------------------------------------------------------------------------------- 1 | # Parameters 2 | 3 | Parameter is a placeholder for a value provided after the compilation of the 4 | query. 5 | 6 | It uses the following syntax: `$id`, where `id` is an arbitrary alpha numeric 7 | string. 8 | 9 | Most database engines only support numeric positional parameter ids (i.e `$3`). 10 | 11 | ```prql 12 | from employees 13 | filter id == $1 14 | ``` 15 | -------------------------------------------------------------------------------- /web/book/src/reference/syntax/r-strings.md: -------------------------------------------------------------------------------- 1 | # R-strings 2 | 3 | R-strings handle escape characters without special treatment: 4 | 5 | ```prql 6 | from artists 7 | derive normal_string = "\\\t" # two characters - \ and tab (\t) 8 | derive raw_string = r"\\\t" # four characters - \, \, \, and t 9 | ``` 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/README.md: -------------------------------------------------------------------------------- 1 | # PRQL documentation tests 2 | 3 | This directory contains tests for PRQL documentation (website, book and README). 4 | -------------------------------------------------------------------------------- /web/book/tests/documentation/main.rs: -------------------------------------------------------------------------------- 1 | #![cfg(not(target_family = "wasm"))] 2 | 3 | /// As well as the examples in the book, we also test the examples in the 4 | /// website & README in this integration test binary. 5 | mod book; 6 | mod readme; 7 | mod website; 8 | 9 | use ::prqlc::Options; 10 | 11 | fn compile(prql: &str) -> Result { 12 | prqlc::compile( 13 | prql, 14 | &Options::default() 15 | .no_signature() 16 | .with_display(prqlc::DisplayOptions::Plain), 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /web/book/tests/documentation/readme.rs: -------------------------------------------------------------------------------- 1 | use regex::Regex; 2 | 3 | use super::compile; 4 | 5 | #[test] 6 | fn test_readme_examples() { 7 | let contents = include_str!("../../../../README.md"); 8 | // Similar to code at https://github.com/PRQL/prql/blob/65706a115a84997c608eaeda38b1aef1240fcec3/web/book/tests/snapshot.rs#L152, but specialized for the Readme. 9 | let re = Regex::new(r"(?s)```(elm|prql)\r?\n(?P.+?)\r?\n```").unwrap(); 10 | assert_ne!(re.find_iter(contents).count(), 0); 11 | re.captures_iter(contents).for_each(|capture| { 12 | compile(&capture["prql"]).unwrap(); 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__README__prql-language-book__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from tracks\nfilter artist == \"Bob Marley\" # Each line transforms the previous result\naggregate { # `aggregate` reduces each column to a value\n plays = sum plays,\n longest = max length,\n shortest = min length, # Trailing commas are allowed\n}\n" 4 | --- 5 | SELECT 6 | COALESCE(SUM(plays), 0) AS plays, 7 | MAX(length) AS longest, 8 | MIN(length) AS shortest 9 | FROM 10 | tracks 11 | WHERE 12 | artist = 'Bob Marley' 13 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__project__target__examples__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.postgres\n\nfrom employees\nsort age\ntake 10\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | employees 9 | ORDER BY 10 | age 11 | LIMIT 12 | 10 13 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__project__target__examples__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.mssql\n\nfrom employees\nsort age\ntake 10\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | employees 9 | ORDER BY 10 | age OFFSET 0 ROWS 11 | FETCH FIRST 12 | 10 ROWS ONLY 13 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__project__target__version__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql version:\"0.13.4\"\n\nfrom employees\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | employees 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__project__target__version__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "[{version = prql.version}]\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | '0.13.5' AS version 8 | ) 9 | SELECT 10 | version 11 | FROM 12 | table_0 13 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__data__from__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from artists\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | artists 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__data__from__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from e = employees\nselect e.first_name\n" 4 | --- 5 | SELECT 6 | first_name 7 | FROM 8 | employees AS e 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__data__from__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from `artist tracks`\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | "artist tracks" 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__data__from__3.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "default_db.group # in place of `from group`\ntake 1\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | "group" 9 | LIMIT 10 | 1 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__data__read-files__reading-files__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.duckdb\n\nfrom (read_parquet \"artists.parquet\")\njoin (read_csv \"albums.csv\") (==track_id)\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | * 8 | FROM 9 | read_parquet('artists.parquet') 10 | ), 11 | table_1 AS ( 12 | SELECT 13 | * 14 | FROM 15 | read_csv_auto('albums.csv') 16 | ) 17 | SELECT 18 | table_0.*, 19 | table_1.* 20 | FROM 21 | table_0 22 | INNER JOIN table_1 ON table_0.track_id = table_1.track_id 23 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__data__read-files__reading-files__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from `artists.parquet`\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | "artists.parquet" 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__data__relation-literals__array-literals__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from [\n {a=5, b=false},\n {a=6, b=true},\n]\nfilter b == true\nselect a\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | 5 AS a, 8 | false AS b 9 | UNION 10 | ALL 11 | SELECT 12 | 6 AS a, 13 | true AS b 14 | ) 15 | SELECT 16 | a 17 | FROM 18 | table_0 19 | WHERE 20 | b = true 21 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__data__relation-literals__array-literals__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "let my_artists = [\n {artist=\"Miles Davis\"},\n {artist=\"Marvin Gaye\"},\n {artist=\"James Brown\"},\n]\n\nfrom artists\njoin my_artists (==artist)\njoin albums (==artist_id)\nselect {artists.artist_id, albums.title}\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | 'Miles Davis' AS artist 8 | UNION 9 | ALL 10 | SELECT 11 | 'Marvin Gaye' AS artist 12 | UNION 13 | ALL 14 | SELECT 15 | 'James Brown' AS artist 16 | ), 17 | my_artists AS ( 18 | SELECT 19 | artist 20 | FROM 21 | table_0 22 | ) 23 | SELECT 24 | artists.artist_id, 25 | albums.title 26 | FROM 27 | artists 28 | INNER JOIN my_artists ON artists.artist = my_artists.artist 29 | INNER JOIN albums ON artists.artist_id = albums.artist_id 30 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__data__relation-literals__array-literals__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from_text \"\"\"\na,b,c\n1,2,3\n4,5,6\n\"\"\"\nderive {\n d = b + c,\n answer = 20 * 2 + 2,\n}\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | '1' AS a, 8 | '2' AS b, 9 | '3' AS c 10 | UNION 11 | ALL 12 | SELECT 13 | '4' AS a, 14 | '5' AS b, 15 | '6' AS c 16 | ) 17 | SELECT 18 | a, 19 | b, 20 | c, 21 | b + c AS d, 22 | 20 * 2 + 2 AS answer 23 | FROM 24 | table_0 25 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__data__relation-literals__array-literals__3.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from_text format:json \"\"\"\n[\n {\"a\": 1, \"m\": \"5\"},\n {\"a\": 4, \"n\": \"6\"}\n]\n\"\"\"\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | 1 AS a, 8 | '5' AS m 9 | UNION 10 | ALL 11 | SELECT 12 | 4 AS a, 13 | NULL AS m 14 | ) 15 | SELECT 16 | a, 17 | m 18 | FROM 19 | table_0 20 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__data__relation-literals__array-literals__4.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from_text format:json \"\"\"\n{\n \"columns\": [\"a\", \"b\", \"c\"],\n \"data\": [\n [1, \"x\", false],\n [4, \"y\", null]\n ]\n}\n\"\"\"\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | 1 AS a, 8 | 'x' AS b, 9 | false AS c 10 | UNION 11 | ALL 12 | SELECT 13 | 4 AS a, 14 | 'y' AS b, 15 | NULL AS c 16 | ) 17 | SELECT 18 | a, 19 | b, 20 | c 21 | FROM 22 | table_0 23 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__declarations__functions__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "let fahrenheit_to_celsius = temp -> (temp - 32) / 1.8\n\nfrom cities\nderive temp_c = (fahrenheit_to_celsius temp_f)\n" 4 | --- 5 | SELECT 6 | *, 7 | (temp_f - 32) / 1.8 AS temp_c 8 | FROM 9 | cities 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__declarations__functions__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "let interp = low:0 high x -> (x - low) / (high - low)\n\nfrom students\nderive {\n sat_proportion_1 = (interp 1600 sat_score),\n sat_proportion_2 = (interp low:0 1600 sat_score),\n}\n" 4 | --- 5 | SELECT 6 | *, 7 | (sat_score - 0) / (1600 - 0) AS sat_proportion_1, 8 | (sat_score - 0) / (1600 - 0) AS sat_proportion_2 9 | FROM 10 | students 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__declarations__functions__late-binding__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "let cost_share = cost -> cost / cost_total\n\nfrom costs\nselect {materials, labor, overhead, cost_total}\nderive {\n materials_share = (cost_share materials),\n labor_share = (cost_share labor),\n overhead_share = (cost_share overhead),\n}\n" 4 | --- 5 | SELECT 6 | materials, 7 | labor, 8 | overhead, 9 | cost_total, 10 | materials / cost_total AS materials_share, 11 | labor / cost_total AS labor_share, 12 | overhead / cost_total AS overhead_share 13 | FROM 14 | costs 15 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__declarations__functions__piping-values-into-functions__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "let interp = low:0 high x -> (x - low) / (high - low)\n\nfrom students\nderive {\n sat_proportion_1 = (sat_score | interp 1600),\n sat_proportion_2 = (sat_score | interp low:0 1600),\n}\n" 4 | --- 5 | SELECT 6 | *, 7 | (sat_score - 0) / (1600 - 0) AS sat_proportion_1, 8 | (sat_score - 0) / (1600 - 0) AS sat_proportion_2 9 | FROM 10 | students 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__declarations__functions__piping-values-into-functions__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "let fahrenheit_to_celsius = temp -> (temp - 32) / 1.8\n\nfrom cities\nderive temp_c = (temp_f | fahrenheit_to_celsius)\n" 4 | --- 5 | SELECT 6 | *, 7 | (temp_f - 32) / 1.8 AS temp_c 8 | FROM 9 | cities 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__declarations__functions__piping-values-into-functions__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "let fahrenheit_to_celsius = temp -> (temp - 32) / 1.8\nlet interp = low:0 high x -> (x - low) / (high - low)\n\nfrom kettles\nderive boiling_proportion = (temp_c | fahrenheit_to_celsius | interp 100)\n" 4 | --- 5 | SELECT 6 | *, 7 | ((temp_c - 32) / 1.8 - 0) / (100 - 0) AS boiling_proportion 8 | FROM 9 | kettles 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__declarations__variables__variables--__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "let top_50 = (\n from employees\n sort salary\n take 50\n aggregate {total_salary = sum salary}\n)\n\nfrom top_50 # Starts a new pipeline\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | salary 8 | FROM 9 | employees 10 | ORDER BY 11 | salary 12 | LIMIT 13 | 50 14 | ), top_50 AS ( 15 | SELECT 16 | COALESCE(SUM(salary), 0) AS total_salary 17 | FROM 18 | table_0 19 | ) 20 | SELECT 21 | total_salary 22 | FROM 23 | top_50 24 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__declarations__variables__variables--__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\ntake 50\ninto first_50\n\nfrom first_50\n" 4 | --- 5 | WITH first_50 AS ( 6 | SELECT 7 | * 8 | FROM 9 | employees 10 | LIMIT 11 | 50 12 | ) 13 | SELECT 14 | * 15 | FROM 16 | first_50 17 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__declarations__variables__variables--__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "let grouping = s\"\"\"\n SELECT SUM(a)\n FROM tbl\n GROUP BY\n GROUPING SETS\n ((b, c, d), (d), (b, d))\n\"\"\"\n\nfrom grouping\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | SUM(a) 8 | FROM 9 | tbl 10 | GROUP BY 11 | GROUPING SETS ((b, c, d), (d), (b, d)) 12 | ) 13 | SELECT 14 | * 15 | FROM 16 | table_0 17 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__spec__name-resolution__translating-to-sql__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nselect first_name\n" 4 | --- 5 | SELECT 6 | first_name 7 | FROM 8 | employees 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__spec__name-resolution__translating-to-sql__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nderive {first_name, dept_id}\njoin d=departments (==dept_id)\nselect {first_name, d.title}\n" 4 | --- 5 | SELECT 6 | employees.first_name, 7 | d.title 8 | FROM 9 | employees 10 | INNER JOIN departments AS d ON employees.dept_id = d.dept_id 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__spec__null__null-handling__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nfilter first_name == null\nfilter null != last_name\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | employees 9 | WHERE 10 | first_name IS NULL 11 | AND last_name IS NOT NULL 12 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__README__standard-library__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nderive {\n gross_salary = (salary + payroll_tax | as int),\n gross_salary_rounded = (gross_salary | math.round 0),\n time = s\"NOW()\", # an s-string, given no `now` function exists in PRQL\n}\n" 4 | --- 5 | SELECT 6 | *, 7 | CAST(salary + payroll_tax AS int) AS gross_salary, 8 | ROUND(CAST(salary + payroll_tax AS int), 0) AS gross_salary_rounded, 9 | NOW() AS time 10 | FROM 11 | employees 12 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__README__standard-library__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.sqlite\n\nfrom [{x = 13, y = 5}]\nselect {\n quotient = x / y,\n int_quotient = x // y,\n}\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | 13 AS x, 8 | 5 AS y 9 | ) 10 | SELECT 11 | (x * 1.0 / y) AS quotient, 12 | ROUND(ABS(x / y) - 0.5) * SIGN(x) * SIGN(y) AS int_quotient 13 | FROM 14 | table_0 15 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__README__standard-library__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.mysql\n\nfrom [{x = 13, y = 5}]\nselect {\n quotient = x / y,\n int_quotient = x // y,\n}\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | 13 AS x, 8 | 5 AS y 9 | ) 10 | SELECT 11 | (x / y) AS quotient, 12 | (x DIV y) AS int_quotient 13 | FROM 14 | table_0 15 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__date__date-functions__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.duckdb\n\nfrom invoices\nselect (invoice_date | date.to_text \"%d/%m/%Y\")\n\n" 4 | --- 5 | SELECT 6 | strftime(invoice_date, '%d/%m/%Y') 7 | FROM 8 | invoices 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__date__date-functions__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.postgres\n\nfrom invoices\nselect (invoice_date | date.to_text \"%d/%m/%Y\")\n\n" 4 | --- 5 | SELECT 6 | TO_CHAR(invoice_date, 'DD/MM/YYYY') 7 | FROM 8 | invoices 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__date__date-functions__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.mysql\n\nfrom invoices\nselect (invoice_date | date.to_text \"%d/%m/%Y\")\n\n" 4 | --- 5 | SELECT 6 | DATE_FORMAT(invoice_date, '%d/%m/%Y') 7 | FROM 8 | invoices 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__distinct__how-do-i-remove-duplicates__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nselect department\ngroup employees.* (\n take 1\n)\n" 4 | --- 5 | SELECT 6 | DISTINCT department 7 | FROM 8 | employees 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__distinct__how-do-i-remove-duplicates__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\ngroup employees.* (take 1)\n" 4 | --- 5 | SELECT 6 | DISTINCT * 7 | FROM 8 | employees 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__distinct__remove-duplicates-from-each-group__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "# youngest employee from each department\nfrom employees\ngroup department (\n sort age\n take 1\n)\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | *, 8 | ROW_NUMBER() OVER ( 9 | PARTITION BY department 10 | ORDER BY 11 | age 12 | ) AS _expr_0 13 | FROM 14 | employees 15 | ) 16 | SELECT 17 | * 18 | FROM 19 | table_0 20 | WHERE 21 | _expr_0 <= 1 22 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__distinct__remove-duplicates-from-each-group__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\ngroup {first_name, last_name} (take 1)\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | *, 8 | ROW_NUMBER() OVER (PARTITION BY first_name, last_name) AS _expr_0 9 | FROM 10 | employees 11 | ) 12 | SELECT 13 | * 14 | FROM 15 | table_0 16 | WHERE 17 | _expr_0 <= 1 18 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__math__example__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nselect age_squared = (age | math.pow 2)\n" 4 | --- 5 | SELECT 6 | POW(age, 2) AS age_squared 7 | FROM 8 | employees 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__text__example__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nselect {\n (last_name | text.lower | text.starts_with(\"a\")),\n (title | text.replace \"manager\" \"chief\"),\n}\n" 4 | --- 5 | SELECT 6 | LOWER(last_name) LIKE CONCAT('a', '%'), 7 | REPLACE(title, 'manager', 'chief') 8 | FROM 9 | employees 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__aggregate__aggregate-is-required__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nderive {avg_sal = average salary}\n" 4 | --- 5 | SELECT 6 | *, 7 | AVG(salary) OVER () AS avg_sal 8 | FROM 9 | employees 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__aggregate__examples__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\naggregate {\n average salary,\n ct = count salary\n}\n" 4 | --- 5 | SELECT 6 | AVG(salary), 7 | COUNT(*) AS ct 8 | FROM 9 | employees 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__aggregate__examples__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\ngroup {title, country} (\n aggregate {\n average salary,\n ct = count salary,\n }\n)\n" 4 | --- 5 | SELECT 6 | title, 7 | country, 8 | AVG(salary), 9 | COUNT(*) AS ct 10 | FROM 11 | employees 12 | GROUP BY 13 | title, 14 | country 15 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__append__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees_1\nappend employees_2\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | employees_1 9 | UNION 10 | ALL 11 | SELECT 12 | * 13 | FROM 14 | employees_2 15 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__append__intersection__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees_1\nintersect employees_2\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | employees_1 AS t 9 | INTERSECT 10 | ALL 11 | SELECT 12 | * 13 | FROM 14 | employees_2 AS b 15 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__append__remove__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees_1\nremove employees_2\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | employees_1 AS t 9 | EXCEPT 10 | ALL 11 | SELECT 12 | * 13 | FROM 14 | employees_2 AS b 15 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__derive__examples__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nderive gross_salary = salary + payroll_tax\n" 4 | --- 5 | SELECT 6 | *, 7 | salary + payroll_tax AS gross_salary 8 | FROM 9 | employees 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__derive__examples__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nderive {\n gross_salary = salary + payroll_tax,\n gross_cost = gross_salary + benefits_cost\n}\n" 4 | --- 5 | SELECT 6 | *, 7 | salary + payroll_tax AS gross_salary, 8 | salary + payroll_tax + benefits_cost AS gross_cost 9 | FROM 10 | employees 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__filter__examples__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nfilter age > 25\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | employees 9 | WHERE 10 | age > 25 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__filter__examples__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nfilter (age > 25 || department != \"IT\")\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | employees 9 | WHERE 10 | age > 25 11 | OR department <> 'IT' 12 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__filter__examples__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nfilter (department | in [\"IT\", \"HR\"])\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | employees 9 | WHERE 10 | department IN ('IT', 'HR') 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__filter__examples__3.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nfilter (age | in 25..40)\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | employees 9 | WHERE 10 | age BETWEEN 25 AND 40 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__group__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\ngroup {title, country} (\n aggregate {\n average salary,\n ct = count salary\n }\n)\n" 4 | --- 5 | SELECT 6 | title, 7 | country, 8 | AVG(salary), 9 | COUNT(*) AS ct 10 | FROM 11 | employees 12 | GROUP BY 13 | title, 14 | country 15 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__group__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nsort join_date\ntake 1\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | employees 9 | ORDER BY 10 | join_date 11 | LIMIT 12 | 1 13 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__group__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\ngroup role (\n sort join_date # taken from above\n take 1\n)\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | *, 8 | ROW_NUMBER() OVER ( 9 | PARTITION BY role 10 | ORDER BY 11 | join_date 12 | ) AS _expr_0 13 | FROM 14 | employees 15 | ) 16 | SELECT 17 | * 18 | FROM 19 | table_0 20 | WHERE 21 | _expr_0 <= 1 22 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__join__examples__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\njoin side:left positions (employees.id==positions.employee_id)\n" 4 | --- 5 | SELECT 6 | employees.*, 7 | positions.* 8 | FROM 9 | employees 10 | LEFT OUTER JOIN positions ON employees.id = positions.employee_id 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__join__examples__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\njoin side:left p=positions (employees.id==p.employee_id)\n" 4 | --- 5 | SELECT 6 | employees.*, 7 | p.* 8 | FROM 9 | employees 10 | LEFT OUTER JOIN positions AS p ON employees.id = p.employee_id 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__join__examples__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from tracks\njoin side:left artists (\n # This adds a `country` condition, as an alternative to filtering\n artists.id==tracks.artist_id && artists.country=='UK'\n)\n" 4 | --- 5 | SELECT 6 | tracks.*, 7 | artists.* 8 | FROM 9 | tracks 10 | LEFT OUTER JOIN artists ON artists.id = tracks.artist_id 11 | AND artists.country = 'UK' 12 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__join__examples__3.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from tracks\njoin side:inner artists (\n this.id==that.artist_id\n)\n" 4 | --- 5 | SELECT 6 | tracks.*, 7 | artists.* 8 | FROM 9 | tracks 10 | INNER JOIN artists ON tracks.id = artists.artist_id 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__join__examples__4.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\njoin positions (==emp_no)\n" 4 | --- 5 | SELECT 6 | employees.*, 7 | positions.* 8 | FROM 9 | employees 10 | INNER JOIN positions ON employees.emp_no = positions.emp_no 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__loop__examples__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from [{n = 1}]\nloop (\n filter n<4\n select n = n+1\n)\n\n# returns [1, 2, 3, 4]\n" 4 | --- 5 | WITH RECURSIVE table_0 AS ( 6 | SELECT 7 | 1 AS n 8 | ), 9 | table_1 AS ( 10 | SELECT 11 | n 12 | FROM 13 | table_0 14 | UNION 15 | ALL 16 | SELECT 17 | n + 1 18 | FROM 19 | table_1 20 | WHERE 21 | n < 4 22 | ) 23 | SELECT 24 | n 25 | FROM 26 | table_1 AS table_2 27 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__select__examples__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nselect name = f\"{first_name} {last_name}\"\n" 4 | --- 5 | SELECT 6 | CONCAT(first_name, ' ', last_name) AS name 7 | FROM 8 | employees 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__select__examples__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nselect {\n name = f\"{first_name} {last_name}\",\n age_eoy = dob - @2022-12-31,\n}\n" 4 | --- 5 | SELECT 6 | CONCAT(first_name, ' ', last_name) AS name, 7 | dob - DATE '2022-12-31' AS age_eoy 8 | FROM 9 | employees 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__select__examples__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nselect first_name\n" 4 | --- 5 | SELECT 6 | first_name 7 | FROM 8 | employees 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__select__examples__3.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from e=employees\nselect {e.first_name, e.last_name}\n" 4 | --- 5 | SELECT 6 | first_name, 7 | last_name 8 | FROM 9 | employees AS e 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__select__excluding-columns__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.bigquery\nfrom tracks\nselect !{milliseconds, bytes}\n" 4 | --- 5 | SELECT 6 | * EXCEPT (milliseconds, bytes) 7 | FROM 8 | tracks 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__select__excluding-columns__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from tracks\nselect {track_id, title, composer, bytes}\nselect !{title, composer}\n" 4 | --- 5 | SELECT 6 | track_id, 7 | bytes 8 | FROM 9 | tracks 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__select__excluding-columns__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from artists\nderive nick = name\nselect !{artists.*}\n" 4 | --- 5 | SELECT 6 | name AS nick 7 | FROM 8 | artists 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__select__excluding-columns__3.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.bigquery\nfrom tracks\nselect !is_compilation\n" 4 | --- 5 | SELECT 6 | NOT is_compilation 7 | FROM 8 | tracks 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__sort__examples__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nsort age\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | employees 9 | ORDER BY 10 | age 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__sort__examples__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nsort {-age}\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | employees 9 | ORDER BY 10 | age DESC 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__sort__examples__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nsort {age, -tenure, +salary}\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | employees 9 | ORDER BY 10 | age, 11 | tenure DESC, 12 | salary 13 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__sort__examples__3.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nsort {s\"substr({first_name}, 2, 5)\"}\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | *, 8 | substr(first_name, 2, 5) AS _expr_0 9 | FROM 10 | employees 11 | ) 12 | SELECT 13 | * 14 | FROM 15 | table_0 16 | ORDER BY 17 | _expr_0 18 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__sort__ordering-guarantees__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nsort tenure\njoin locations (==employee_id)\n" 4 | --- 5 | SELECT 6 | employees.*, 7 | locations.* 8 | FROM 9 | employees 10 | INNER JOIN locations ON employees.employee_id = locations.employee_id 11 | ORDER BY 12 | employees.tenure 13 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__take__examples__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\ntake 10\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | employees 9 | LIMIT 10 | 10 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__take__examples__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from orders\nsort {-value, created_at}\ntake 101..110\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | orders 9 | ORDER BY 10 | value DESC, 11 | created_at 12 | LIMIT 13 | 10 OFFSET 100 14 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__window__example__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\ngroup employee_id (\n sort month\n window rolling:12 (\n derive {trail_12_m_comp = sum paycheck}\n )\n)\n" 4 | --- 5 | SELECT 6 | *, 7 | SUM(paycheck) OVER ( 8 | PARTITION BY employee_id 9 | ORDER BY 10 | month ROWS BETWEEN 11 PRECEDING AND CURRENT ROW 11 | ) AS trail_12_m_comp 12 | FROM 13 | employees 14 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__window__example__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from orders\nsort day\nwindow rows:-3..3 (\n derive {centered_weekly_average = average value}\n)\ngroup {order_month} (\n sort day\n window expanding:true (\n derive {monthly_running_total = sum value}\n )\n)\n" 4 | --- 5 | SELECT 6 | *, 7 | AVG(value) OVER ( 8 | ORDER BY 9 | day ROWS BETWEEN 3 PRECEDING AND 3 FOLLOWING 10 | ) AS centered_weekly_average, 11 | SUM(value) OVER ( 12 | PARTITION BY order_month 13 | ORDER BY 14 | day ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 15 | ) AS monthly_running_total 16 | FROM 17 | orders 18 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__window__window-functions-as-first-class-citizens__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nfilter salary < (average salary)\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | *, 8 | AVG(salary) OVER () AS _expr_0 9 | FROM 10 | employees 11 | ) 12 | SELECT 13 | * 14 | FROM 15 | table_0 16 | WHERE 17 | salary < _expr_0 18 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__window__windowing-by-default__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nsort age\nderive {rnk = rank age}\n" 4 | --- 5 | SELECT 6 | *, 7 | RANK() OVER ( 8 | ORDER BY 9 | age 10 | ) AS rnk 11 | FROM 12 | employees 13 | ORDER BY 14 | age 15 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__stdlib__transforms__window__windowing-by-default__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\ngroup department (\n sort age\n derive {rnk = rank age}\n)\n" 4 | --- 5 | SELECT 6 | *, 7 | RANK() OVER ( 8 | PARTITION BY department 9 | ORDER BY 10 | age 11 | ) AS rnk 12 | FROM 13 | employees 14 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__case__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nderive distance = case [\n city == \"Calgary\" => 0,\n city == \"Edmonton\" => 300,\n]\n" 4 | --- 5 | SELECT 6 | *, 7 | CASE 8 | WHEN city = 'Calgary' THEN 0 9 | WHEN city = 'Edmonton' THEN 300 10 | ELSE NULL 11 | END AS distance 12 | FROM 13 | employees 14 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__case__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nderive distance = case [\n city == \"Calgary\" => 0,\n city == \"Edmonton\" => 300,\n true => \"Unknown\",\n]\n" 4 | --- 5 | SELECT 6 | *, 7 | CASE 8 | WHEN city = 'Calgary' THEN 0 9 | WHEN city = 'Edmonton' THEN 300 10 | ELSE 'Unknown' 11 | END AS distance 12 | FROM 13 | employees 14 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__comments__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees # Comment 1\n# Comment 2\naggregate {average salary}\n" 4 | --- 5 | SELECT 6 | AVG(salary) 7 | FROM 8 | employees 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__f-strings__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nselect full_name = f\"{first_name} {last_name}\"\n" 4 | --- 5 | SELECT 6 | CONCAT(first_name, ' ', last_name) AS full_name 7 | FROM 8 | employees 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__f-strings__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from web\nselect url = f\"http{tls}://www.{domain}.{tld}/{page}\"\n" 4 | --- 5 | SELECT 6 | CONCAT( 7 | 'http', 8 | tls, 9 | '://www.', 10 | domain, 11 | '.', 12 | tld, 13 | '/', 14 | page 15 | ) AS url 16 | FROM 17 | web 18 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__f-strings__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from tracks\nselect length_str = f\"{length_seconds / 60} minutes\"\n" 4 | --- 5 | Error: 6 | ╭─[ :2:38 ] 7 | │ 8 | 2 │ select length_str = f"{length_seconds / 60} minutes" 9 | │ ┬ 10 | │ ╰── interpolated string expected one of ".", ":" or "}", but found " " 11 | ───╯ 12 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__keywords__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "std.from my_table\nstd.select {from = my_table.a, take = my_table.b}\nstd.take 3\n" 4 | --- 5 | SELECT 6 | a AS "from", 7 | b AS take 8 | FROM 9 | my_table 10 | LIMIT 11 | 3 12 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__keywords__identifiers--keywords__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from invoices\naggregate (\n count this\n)\n" 4 | --- 5 | SELECT 6 | COUNT(*) 7 | FROM 8 | invoices 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__keywords__identifiers--keywords__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from invoices\njoin tracks (this.track_id==that.id)\n" 4 | --- 5 | SELECT 6 | invoices.*, 7 | tracks.* 8 | FROM 9 | invoices 10 | INNER JOIN tracks ON invoices.track_id = tracks.id 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__keywords__identifiers--keywords__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from invoices\nderive t = time\n" 4 | --- 5 | Error: 6 | ╭─[ :2:12 ] 7 | │ 8 | 2 │ derive t = time 9 | │ ──┬─ 10 | │ ╰─── expected a value, but found a type 11 | ───╯ 12 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__keywords__identifiers--keywords__3.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from invoices\nderive t = this.time\n" 4 | --- 5 | SELECT 6 | *, 7 | time AS t 8 | FROM 9 | invoices 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__keywords__quoting__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.mysql\nfrom employees\nselect `first name`\n" 4 | --- 5 | SELECT 6 | `first name` 7 | FROM 8 | employees 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__keywords__quoting__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.postgres\nfrom employees\nselect `first name`\n" 4 | --- 5 | SELECT 6 | "first name" 7 | FROM 8 | employees 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__keywords__quoting__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.bigquery\n\nfrom `project-foo.dataset.table`\njoin `project-bar.dataset.table` (==col_bax)\n" 4 | --- 5 | SELECT 6 | `project-foo.dataset.table`.*, 7 | `project-bar.dataset.table`.* 8 | FROM 9 | `project-foo.dataset.table` 10 | INNER JOIN `project-bar.dataset.table` ON `project-foo.dataset.table`.col_bax = `project-bar.dataset.table`.col_bax 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__keywords__schemas--database-names__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from my_database.chinook.albums\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | my_database.chinook.albums 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__literals__dates__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nderive age_at_year_end = (@2022-12-31 - dob)\n" 4 | --- 5 | SELECT 6 | *, 7 | DATE '2022-12-31' - dob AS age_at_year_end 8 | FROM 9 | employees 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__literals__durations__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from projects\nderive first_check_in = start + 10days\n" 4 | --- 5 | SELECT 6 | *, 7 | "start" + INTERVAL 10 DAY AS first_check_in 8 | FROM 9 | projects 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__literals__numbers__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from numbers\nselect {\n small = 1.000_000_1,\n big = 5_000_000,\n huge = 5e9,\n binary = 0x0011,\n hex = 0x80,\n octal = 0o777,\n}\n" 4 | --- 5 | SELECT 6 | 1.0000001 AS small, 7 | 5000000 AS big, 8 | 5000000000.0 AS huge, 9 | 17 AS "binary", 10 | 128 AS hex, 11 | 511 AS octal 12 | FROM 13 | numbers 14 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__literals__times__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from orders\nderive should_have_shipped_today = (order_time < @08:30)\n" 4 | --- 5 | SELECT 6 | *, 7 | order_time < TIME '08:30' AS should_have_shipped_today 8 | FROM 9 | orders 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__literals__timestamps__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from commits\nderive first_prql_commit = @2020-01-01T13:19:55-08:00\nderive first_prql_commit_utc = @2020-01-02T21:19:55Z\n" 4 | --- 5 | SELECT 6 | *, 7 | TIMESTAMP '2020-01-01T13:19:55-0800' AS first_prql_commit, 8 | TIMESTAMP '2020-01-02T21:19:55Z' AS first_prql_commit_utc 9 | FROM 10 | commits 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__operators__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from foo\nselect {\n circumference = diameter * 3.14159,\n area = (diameter / 2) ** 2,\n color,\n}\nfilter circumference > 10 && color != \"red\"\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | diameter * 3.14159 AS circumference, 8 | POW(diameter / 2, 2) AS area, 9 | color 10 | FROM 11 | foo 12 | ) 13 | SELECT 14 | circumference, 15 | area, 16 | color 17 | FROM 18 | table_0 19 | WHERE 20 | circumference > 10 21 | AND color <> 'red' 22 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__operators__coalesce__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from orders\nderive amount ?? 0\n" 4 | --- 5 | SELECT 6 | *, 7 | COALESCE(amount, 0) 8 | FROM 9 | orders 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__operators__division-and-integer-division__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.sqlite\n\nfrom [\n {a = 5, b = 2},\n {a = 5, b = -2},\n]\nselect {\n div_out = a / b,\n int_div_out = a // b,\n}\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | 5 AS a, 8 | 2 AS b 9 | UNION 10 | ALL 11 | SELECT 12 | 5 AS a, 13 | -2 AS b 14 | ) 15 | SELECT 16 | (a * 1.0 / b) AS div_out, 17 | ROUND(ABS(a / b) - 0.5) * SIGN(a) * SIGN(b) AS int_div_out 18 | FROM 19 | table_0 20 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__operators__parentheses__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nderive total_distance = sum distance\n" 4 | --- 5 | Error: 6 | ╭─[ :2:29 ] 7 | │ 8 | 2 │ derive total_distance = sum distance 9 | │ ────┬─── 10 | │ ╰───── Unknown name `distance` 11 | ───╯ 12 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__operators__parentheses__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nderive other_distance = (sum distance)\n" 4 | --- 5 | SELECT 6 | *, 7 | SUM(distance) OVER () AS other_distance 8 | FROM 9 | employees 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__operators__regex-expressions__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from tracks\nfilter (name ~= \"Love\")\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | tracks 9 | WHERE 10 | REGEXP(name, 'Love') 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__operators__regex-expressions__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.duckdb\n\nfrom artists\nfilter (name ~= \"Love.*You\")\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | artists 9 | WHERE 10 | REGEXP_MATCHES(name, 'Love.*You') 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__operators__regex-expressions__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.bigquery\n\nfrom tracks\nfilter (name ~= \"\\\\bLove\\\\b\")\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | tracks 9 | WHERE 10 | REGEXP_CONTAINS(name, '\bLove\b') 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__operators__regex-expressions__3.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.postgres\n\nfrom tracks\nfilter (name ~= \"\\\\(I Can't Help\\\\) Falling\")\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | tracks 9 | WHERE 10 | name ~ '\(I Can''t Help\) Falling' 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__operators__regex-expressions__4.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.mysql\n\nfrom tracks\nfilter (name ~= \"With You\")\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | tracks 9 | WHERE 10 | REGEXP_LIKE(name, 'With You', 'c') 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__operators__regex-expressions__5.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "prql target:sql.sqlite\n\nfrom tracks\nfilter (name ~= \"But Why Isn't Your Syntax More Similar\\\\?\")\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | tracks 9 | WHERE 10 | name REGEXP 'But Why Isn''t Your Syntax More Similar\?' 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__operators__wrapping-lines__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from artists\nselect is_europe =\n\\ country == \"DE\"\n\\ || country == \"FR\"\n\\ || country == \"ES\"\n" 4 | --- 5 | SELECT 6 | country = 'DE' 7 | OR country = 'FR' 8 | OR country = 'ES' AS is_europe 9 | FROM 10 | artists 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__operators__wrapping-lines__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from tracks\n# This would be a really long line without being able to split it:\nselect listening_time_years = (spotify_plays + apple_music_plays + pandora_plays)\n# We can toggle between lines when developing:\n# \\ * length_seconds\n\\ * length_s\n# min hour day year\n\\ / 60 / 60 / 24 / 365\n" 4 | --- 5 | SELECT 6 | ( 7 | spotify_plays + apple_music_plays + pandora_plays 8 | ) * length_s / 60 / 60 / 24 / 365 AS listening_time_years 9 | FROM 10 | tracks 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__parameters__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nfilter id == $1\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | employees 9 | WHERE 10 | id = $1 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__pipes__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nfilter department == \"Product\"\nselect {first_name, last_name}\n" 4 | --- 5 | SELECT 6 | first_name, 7 | last_name 8 | FROM 9 | employees 10 | WHERE 11 | department = 'Product' 12 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__pipes__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees | filter department == \"Product\" | select {first_name, last_name}\n" 4 | --- 5 | SELECT 6 | first_name, 7 | last_name 8 | FROM 9 | employees 10 | WHERE 11 | department = 'Product' 12 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__pipes__ceci-nest-pas-une-pipe__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "[\n {a=2} # No pipe from line break before & after this list item\n]\nderive {\n c = 2 * a, # No pipe from line break before & after this tuple item\n}\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | 2 AS a 8 | ) 9 | SELECT 10 | a, 11 | 2 * a AS c 12 | FROM 13 | table_0 14 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__pipes__ceci-nest-pas-une-pipe__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "let b =\n \\ 3 # No pipe from line break within this line wrap\n\n# No pipe from line break before this `from` statement\n\nfrom y\nderive a = b\n" 4 | --- 5 | SELECT 6 | *, 7 | 3 AS a 8 | FROM 9 | y 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__pipes__inner-transforms__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\ngroup {title, country} (\n aggregate {\n average salary,\n ct = count salary,\n }\n)\n" 4 | --- 5 | SELECT 6 | title, 7 | country, 8 | AVG(salary), 9 | COUNT(*) AS ct 10 | FROM 11 | employees 12 | GROUP BY 13 | title, 14 | country 15 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__r-strings__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from artists\nderive normal_string = \"\\\\\\t\" # two characters - \\ and tab (\\t)\nderive raw_string = r\"\\\\\\t\" # four characters - \\, \\, \\, and t\n" 4 | --- 5 | SELECT 6 | *, 7 | '\ ' AS normal_string, 8 | '\\\t' AS raw_string 9 | FROM 10 | artists 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__ranges__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from events\nfilter (created_at | in @1776-07-04..@1787-09-17)\nfilter (magnitude | in 50..100)\nderive is_northern = (latitude | in 0..)\n" 4 | --- 5 | SELECT 6 | *, 7 | latitude >= 0 AS is_northern 8 | FROM 9 | events 10 | WHERE 11 | created_at BETWEEN DATE '1776-07-04' AND DATE '1787-09-17' 12 | AND magnitude BETWEEN 50 AND 100 13 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__ranges__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from orders\nsort {-value, created_at}\ntake 101..110\n" 4 | --- 5 | SELECT 6 | * 7 | FROM 8 | orders 9 | ORDER BY 10 | value DESC, 11 | created_at 12 | LIMIT 13 | 10 OFFSET 100 14 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__s-strings__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from my_table\nselect db_version = s\"version()\"\n" 4 | --- 5 | SELECT 6 | version() AS db_version 7 | FROM 8 | my_table 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__s-strings__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\naggregate {average salary}\n" 4 | --- 5 | SELECT 6 | AVG(salary) 7 | FROM 8 | employees 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__s-strings__2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from de=dept_emp\njoin s=salaries side:left (s.emp_no == de.emp_no && s\"\"\"\n ({s.from_date}, {s.to_date})\n OVERLAPS\n ({de.from_date}, {de.to_date})\n\"\"\")\n" 4 | --- 5 | SELECT 6 | de.*, 7 | s.* 8 | FROM 9 | dept_emp AS de 10 | LEFT OUTER JOIN salaries AS s ON s.emp_no = de.emp_no 11 | AND (s.from_date, s.to_date) OVERLAPS (de.from_date, de.to_date) 12 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__s-strings__3.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from s\"SELECT DISTINCT ON first_name, id, age FROM employees ORDER BY age ASC\"\njoin s = s\"SELECT * FROM salaries\" (==id)\n" 4 | --- 5 | WITH table_0 AS ( 6 | SELECT 7 | DISTINCT ON first_name, 8 | id, 9 | age 10 | FROM 11 | employees 12 | ORDER BY 13 | age ASC 14 | ), 15 | table_1 AS ( 16 | SELECT 17 | * 18 | FROM 19 | salaries 20 | ) 21 | SELECT 22 | table_0.*, 23 | table_1.* 24 | FROM 25 | table_0 26 | INNER JOIN table_1 ON table_0.id = table_1.id 27 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__s-strings__braces__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nderive {\n has_valid_title = s\"regexp_contains(title, '([a-z0-9]*-){{2,}}')\"\n}\n" 4 | --- 5 | SELECT 6 | *, 7 | regexp_contains(title, '([a-z0-9]*-){2,}') AS has_valid_title 8 | FROM 9 | employees 10 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__s-strings__precedence-within-s-strings__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nderive {\n gross_salary = salary + benefits,\n daily_rate = s\"{gross_salary} / 365\"\n}\n" 4 | --- 5 | SELECT 6 | *, 7 | salary + benefits AS gross_salary, 8 | salary + benefits / 365 AS daily_rate 9 | FROM 10 | employees 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__s-strings__precedence-within-s-strings__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nderive {\n gross_salary = salary + benefits,\n daily_rate = s\"({gross_salary}) / 365\"\n}\n" 4 | --- 5 | SELECT 6 | *, 7 | salary + benefits AS gross_salary, 8 | (salary + benefits) / 365 AS daily_rate 9 | FROM 10 | employees 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__strings__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from artists\nderive {\n single = 'hello world',\n double = \"hello world\",\n double_triple = \"\"\"hello world\"\"\",\n}\n" 4 | --- 5 | SELECT 6 | *, 7 | 'hello world' AS single, 8 | 'hello world' AS double, 9 | 'hello world' AS double_triple 10 | FROM 11 | artists 12 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__strings__quoting-and-escape-characters__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from artists\nselect {\n other = '\"hello world\"',\n escaped = \"\\\"hello world\\\"\",\n triple = \"\"\"I said \"hello world\"!\"\"\",\n}\n" 4 | --- 5 | SELECT 6 | '"hello world"' AS other, 7 | '"hello world"' AS escaped, 8 | 'I said "hello world"!' AS triple 9 | FROM 10 | artists 11 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__strings__quoting-and-escape-characters__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from artists\nderive escapes = \"\\tXYZ\\n \\\\ \" # tab (\\t), \"XYZ\", newline (\\n), \" \", \\, \" \"\nderive world = \"\\u{0048}\\u{0065}\\u{006C}\\u{006C}\\u{006F}\" # \"Hello\"\nderive hex = \"\\x48\\x65\\x6C\\x6C\\x6F\" # \"Hello\"\nderive turtle = \"\\u{01F422}\" # \"🐢\"\n" 4 | --- 5 | SELECT 6 | *, 7 | ' XYZ 8 | \ ' AS escapes, 9 | 'Hello' AS world, 10 | 'Hello' AS hex, 11 | '🐢' AS turtle 12 | FROM 13 | artists 14 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__tuples__0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nselect {first_name}\n" 4 | --- 5 | SELECT 6 | first_name 7 | FROM 8 | employees 9 | -------------------------------------------------------------------------------- /web/book/tests/documentation/snapshots/documentation__book__reference__syntax__tuples__1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: web/book/tests/documentation/book.rs 3 | expression: "from employees\nselect first_name\n" 4 | --- 5 | SELECT 6 | first_name 7 | FROM 8 | employees 9 | -------------------------------------------------------------------------------- /web/book/theme/head.hbs: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /web/playground/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | "eslint:recommended", 6 | "plugin:react/recommended", 7 | "plugin:react/jsx-runtime", 8 | "plugin:react-hooks/recommended", 9 | ], 10 | ignorePatterns: ["dist", ".eslintrc.cjs"], 11 | parserOptions: { ecmaVersion: "latest", sourceType: "module" }, 12 | settings: { react: { version: "18.2" } }, 13 | plugins: ["react-refresh"], 14 | rules: { 15 | "react-refresh/only-export-components": [ 16 | "warn", 17 | { allowConstantExport: true }, 18 | ], 19 | }, 20 | }; 21 | -------------------------------------------------------------------------------- /web/playground/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # data 9 | /public/data 10 | 11 | # testing 12 | /coverage 13 | 14 | # production 15 | /build 16 | 17 | # misc 18 | .DS_Store 19 | .env.local 20 | .env.development.local 21 | .env.test.local 22 | .env.production.local 23 | 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | book.json 29 | -------------------------------------------------------------------------------- /web/playground/README.md: -------------------------------------------------------------------------------- 1 | # PRQL Playground 2 | 3 | A fast-feedback compiler from PRQL to SQL, hosted at 4 | 5 | 6 | To run locally, 7 | [set up a development environment](https://prql-lang.org/book/project/contributing/development.html), 8 | and then run: 9 | 10 | ```sh 11 | task web:run-playground 12 | ``` 13 | 14 | ...or use the commands which that command calls from 15 | [our Taskfile](../Taskfile.yaml). 16 | -------------------------------------------------------------------------------- /web/playground/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/playground/public/favicon.ico -------------------------------------------------------------------------------- /web/playground/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "background_color": "#ffffff", 3 | "display": "standalone", 4 | "icons": [ 5 | { 6 | "sizes": "64x64 32x32 24x24 16x16", 7 | "src": "favicon.ico", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "sizes": "192x192", 12 | "src": "icon192.png", 13 | "type": "image/png" 14 | } 15 | ], 16 | "name": "PRQL Playground", 17 | "short_name": "PRQL Playground", 18 | "start_url": ".", 19 | "theme_color": "#222222" 20 | } 21 | -------------------------------------------------------------------------------- /web/playground/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /web/playground/src/app/App.css: -------------------------------------------------------------------------------- 1 | .main { 2 | height: 100%; 3 | display: flex; 4 | } 5 | .main > * { 6 | flex-grow: 1; 7 | } 8 | .sidebar { 9 | flex: 0 0 200px; 10 | } 11 | -------------------------------------------------------------------------------- /web/playground/src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import "./index.css"; 4 | import "./highlight.css"; 5 | import App from "./app/App"; 6 | import reportWebVitals from "./reportWebVitals"; 7 | 8 | const root = ReactDOM.createRoot(document.getElementById("root")); 9 | root.render( 10 | 11 | 12 | , 13 | ); 14 | 15 | // If you want to start measuring performance in your app, pass a function 16 | // to log results (for example: reportWebVitals(console.log)) 17 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 18 | reportWebVitals(); 19 | -------------------------------------------------------------------------------- /web/playground/src/output/Output.css: -------------------------------------------------------------------------------- 1 | .tab-content.arrow { 2 | padding: 1.5rem; 3 | overflow-x: scroll; 4 | } 5 | 6 | .arrow table { 7 | border-collapse: collapse; 8 | } 9 | 10 | .arrow table td, 11 | .arrow table th { 12 | min-width: 2rem; 13 | padding: 2px 0.5rem; 14 | text-align: right; 15 | } 16 | 17 | .arrow table thead { 18 | border-bottom: 1px solid #444; 19 | } 20 | 21 | .arrow table tbody tr:not(:first-child) td { 22 | border-top: 1px solid #444; 23 | } 24 | 25 | /* .arrow table tbody tr:nth-child(2n) td { 26 | background-color: #333; 27 | } */ 28 | -------------------------------------------------------------------------------- /web/playground/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = (onPerfEntry) => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /web/playground/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import "@testing-library/jest-dom"; 6 | -------------------------------------------------------------------------------- /web/playground/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import react from "@vitejs/plugin-react"; 3 | import wasm from "vite-plugin-wasm"; 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | build: { 8 | target: "esnext", 9 | }, 10 | base: "/playground/playground", 11 | plugins: [react(), wasm()], 12 | }); 13 | -------------------------------------------------------------------------------- /web/prql-codemirror-demo/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /web/prql-codemirror-demo/README.md: -------------------------------------------------------------------------------- 1 | # CodeMirror with PRQL demo 2 | 3 | This is a demo of CodeMirror with PRQL. We don't have any published `lang-prql` 4 | or `prql-lezer` package yet. 5 | 6 | ## Instructions 7 | 8 | Build `prql-lezer` then copy the files from `/grammars/prql-lezer/dist/` to 9 | `src/lang-prql/prql-lezer/`. 10 | 11 | ``` 12 | mkdir src/lang-prql/prql-lezer 13 | cd ../../grammars/prql-lezer/ 14 | npm run build 15 | cp dist/* ../../web/prql-codemirror-demo/src/lang-prql/prql-lezer/ 16 | cd ../../web/prql-codemirror-demo/ 17 | npm run dev 18 | ``` 19 | -------------------------------------------------------------------------------- /web/prql-codemirror-demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | CodeMirror with PRQL 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /web/prql-codemirror-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "prql-codemirror-demo", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "typescript": "^5.3.2", 13 | "vite": "^6.2.7" 14 | }, 15 | "dependencies": { 16 | "@codemirror/autocomplete": "^6.11.0", 17 | "@codemirror/commands": "^6.3.0", 18 | "@codemirror/language": "^6.9.2", 19 | "@codemirror/lint": "^6.4.2", 20 | "@codemirror/search": "^6.5.4", 21 | "@codemirror/theme-one-dark": "^6.1.2", 22 | "@codemirror/view": "^6.22.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /web/prql-codemirror-demo/src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | color-scheme: light dark; 3 | color: rgba(255, 255, 255, 0.87); 4 | background-color: #242424; 5 | } 6 | 7 | .cm-editor { 8 | max-height: 400px; 9 | border: 1px solid silver; 10 | } 11 | -------------------------------------------------------------------------------- /web/prql-codemirror-demo/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /web/prql-codemirror-demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true 21 | }, 22 | "include": ["src"] 23 | } 24 | -------------------------------------------------------------------------------- /web/website/.gitignore: -------------------------------------------------------------------------------- 1 | public/ 2 | 3 | .hugo_build.lock 4 | -------------------------------------------------------------------------------- /web/website/README.md: -------------------------------------------------------------------------------- 1 | # PRQL Website 2 | 3 | A [hugo](https://gohugo.io/) website with PRQL theme, which uses minimal 4 | [water.css](https://watercss.kognise.dev/) styling. 5 | 6 | Serve: 7 | 8 | ```sh 9 | cd website 10 | hugo server 11 | ``` 12 | 13 | To add pages, just add files in `content/` directory. 14 | -------------------------------------------------------------------------------- /web/website/archetypes/default.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "{{ replace .Name "-" " " | title }}" 3 | date: {{ .Date }} 4 | draft: true 5 | --- 6 | -------------------------------------------------------------------------------- /web/website/content/playground.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Playground" 3 | layout: big_iframe 4 | --- 5 | 6 | 7 | -------------------------------------------------------------------------------- /web/website/content/posts/2023-01-28-format-pretty-reports/query_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/content/posts/2023-01-28-format-pretty-reports/query_result.png -------------------------------------------------------------------------------- /web/website/content/posts/2023-02-02-one-year/7cpDySb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/content/posts/2023-02-02-one-year/7cpDySb.png -------------------------------------------------------------------------------- /web/website/content/posts/2023-02-02-one-year/FQ9QSOo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/content/posts/2023-02-02-one-year/FQ9QSOo.png -------------------------------------------------------------------------------- /web/website/content/posts/2023-02-02-one-year/GXLvoXn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/content/posts/2023-02-02-one-year/GXLvoXn.png -------------------------------------------------------------------------------- /web/website/content/posts/2023-02-02-one-year/URpCf29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/content/posts/2023-02-02-one-year/URpCf29.png -------------------------------------------------------------------------------- /web/website/content/posts/2023-02-02-one-year/ncVXken.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/content/posts/2023-02-02-one-year/ncVXken.png -------------------------------------------------------------------------------- /web/website/data/examples/basic.yaml: -------------------------------------------------------------------------------- 1 | label: Basic example 2 | prql: | 3 | from employees 4 | select {id, first_name, age} 5 | sort age 6 | take 10 7 | sql: | 8 | SELECT 9 | id, 10 | first_name, 11 | age 12 | FROM 13 | employees 14 | ORDER BY 15 | age 16 | LIMIT 17 | 10 18 | -------------------------------------------------------------------------------- /web/website/data/examples/dialects.yaml: -------------------------------------------------------------------------------- 1 | label: Dialects 2 | prql: | 3 | prql target:sql.mssql # Will generate TOP rather than LIMIT 4 | 5 | from employees 6 | sort age 7 | take 10 8 | sql: | 9 | SELECT 10 | * 11 | FROM 12 | employees 13 | ORDER BY 14 | age OFFSET 0 ROWS 15 | FETCH 16 | FIRST 10 ROWS ONLY 17 | -------------------------------------------------------------------------------- /web/website/data/examples/expressions.yaml: -------------------------------------------------------------------------------- 1 | label: Expressions 2 | prql: | 3 | from track_plays 4 | derive { 5 | finished = started - unfinished, 6 | fin_share = finished / started, # Use previous definitions 7 | fin_ratio = fin_share / (1-fin_share), # BTW, hanging commas are optional! 8 | } 9 | 10 | sql: | 11 | SELECT 12 | *, 13 | started - unfinished AS finished, 14 | (started - unfinished) / started AS fin_share, 15 | (started - unfinished) / started / (1 - (started - unfinished) / started) 16 | AS fin_ratio 17 | FROM 18 | track_plays 19 | -------------------------------------------------------------------------------- /web/website/data/examples/f-strings.yaml: -------------------------------------------------------------------------------- 1 | label: F-strings 2 | prql: | 3 | from web 4 | # Just like Python 5 | select url = f"https://www.{domain}.{tld}/{page}" 6 | sql: | 7 | SELECT 8 | CONCAT('https://www.', domain, '.', tld, '/', page) AS url 9 | FROM 10 | web 11 | -------------------------------------------------------------------------------- /web/website/data/examples/friendly-syntax.yaml: -------------------------------------------------------------------------------- 1 | label: Friendly syntax 2 | prql: | 3 | from track_plays 4 | filter plays > 10_000 # Readable numbers 5 | filter (length | in 60..240) # Ranges with `..` 6 | filter recorded > @2008-01-01 # Simple date literals 7 | filter released - recorded < 180days # Nice interval literals 8 | sort {-length} # Concise order direction 9 | 10 | sql: | 11 | SELECT 12 | * 13 | FROM 14 | track_plays 15 | WHERE 16 | plays > 10000 17 | AND length BETWEEN 60 AND 240 18 | AND recorded > DATE '2008-01-01' 19 | AND released - recorded < INTERVAL 180 DAY 20 | ORDER BY 21 | length DESC 22 | -------------------------------------------------------------------------------- /web/website/data/examples/functions.yaml: -------------------------------------------------------------------------------- 1 | label: Functions 2 | prql: | 3 | let celsius_to_fahrenheit = temp -> temp * 9/5 + 32 4 | 5 | from weather 6 | select temp_f = (celsius_to_fahrenheit temp_c) 7 | sql: | 8 | SELECT 9 | temp_c * 9 / 5 + 32 AS temp_f 10 | FROM 11 | weather 12 | -------------------------------------------------------------------------------- /web/website/data/examples/hero.yaml: -------------------------------------------------------------------------------- 1 | prql: | 2 | from invoices 3 | filter invoice_date >= @1970-01-16 4 | derive { 5 | transaction_fees = 0.8, 6 | income = total - transaction_fees 7 | } 8 | filter income > 1 9 | group customer_id ( 10 | aggregate { 11 | average total, 12 | sum_income = sum income, 13 | ct = count total, 14 | } 15 | ) 16 | sort {-sum_income} 17 | take 10 18 | join c=customers (==customer_id) 19 | derive name = f"{c.last_name}, {c.first_name}" 20 | select { 21 | c.customer_id, name, sum_income 22 | } 23 | derive db_version = s"version()" 24 | -------------------------------------------------------------------------------- /web/website/data/examples/joins.yaml: -------------------------------------------------------------------------------- 1 | label: Joins 2 | prql: | 3 | from employees 4 | join b=benefits (==employee_id) 5 | join side:left p=positions (p.id==employees.employee_id) 6 | select {employees.employee_id, p.role, b.vision_coverage} 7 | sql: | 8 | SELECT 9 | employees.employee_id, 10 | p.role, 11 | b.vision_coverage 12 | FROM 13 | employees 14 | INNER JOIN benefits AS b ON employees.employee_id = b.employee_id 15 | LEFT OUTER JOIN positions AS p ON p.id = employees.employee_id 16 | -------------------------------------------------------------------------------- /web/website/data/examples/null-handling.yaml: -------------------------------------------------------------------------------- 1 | label: Null handling 2 | prql: | 3 | from users 4 | filter last_login != null 5 | filter deleted_at == null 6 | derive channel = channel ?? "unknown" 7 | sql: | 8 | SELECT 9 | *, 10 | COALESCE(channel, 'unknown') AS channel 11 | FROM 12 | users 13 | WHERE 14 | last_login IS NOT NULL 15 | AND deleted_at IS NULL 16 | -------------------------------------------------------------------------------- /web/website/data/examples/orthogonal.yaml: -------------------------------------------------------------------------------- 1 | label: Orthogonality 2 | prql: | 3 | from employees 4 | # `filter` before aggregations... 5 | filter start_date > @2021-01-01 6 | group country ( 7 | aggregate {max_salary = max salary} 8 | ) 9 | # ...and `filter` after aggregations! 10 | filter max_salary > 100_000 11 | sql: | 12 | SELECT 13 | country, 14 | MAX(salary) AS max_salary 15 | FROM 16 | employees 17 | WHERE 18 | start_date > DATE '2021-01-01' 19 | GROUP BY 20 | country 21 | HAVING 22 | MAX(salary) > 100000 23 | -------------------------------------------------------------------------------- /web/website/data/examples/s-strings.yaml: -------------------------------------------------------------------------------- 1 | label: S-strings 2 | prql: | 3 | # There's no `version` in PRQL, but s-strings 4 | # let us embed SQL as an escape hatch: 5 | from x 6 | derive db_version = s"version()" 7 | sql: | 8 | SELECT 9 | *, 10 | version() AS db_version 11 | FROM x 12 | -------------------------------------------------------------------------------- /web/website/data/examples/top-n.yaml: -------------------------------------------------------------------------------- 1 | label: Top N by group 2 | prql: | 3 | # Most recent employee in each role 4 | # Quite difficult in SQL... 5 | from employees 6 | group role ( 7 | sort join_date 8 | take 1 9 | ) 10 | sql: | 11 | WITH table_0 AS ( 12 | SELECT 13 | *, 14 | ROW_NUMBER() OVER ( 15 | PARTITION BY role 16 | ORDER BY 17 | join_date 18 | ) AS _expr_0 19 | FROM 20 | employees 21 | ) 22 | SELECT 23 | * 24 | FROM 25 | table_0 26 | WHERE 27 | _expr_0 <= 1 28 | -------------------------------------------------------------------------------- /web/website/data/examples/windows.yaml: -------------------------------------------------------------------------------- 1 | label: Windows 2 | prql: | 3 | from employees 4 | group employee_id ( 5 | sort month 6 | window rolling:12 ( 7 | derive {trail_12_m_comp = sum paycheck} 8 | ) 9 | ) 10 | sql: | 11 | SELECT 12 | *, 13 | SUM(paycheck) OVER ( 14 | PARTITION BY employee_id 15 | ORDER BY 16 | month ROWS BETWEEN 11 PRECEDING AND CURRENT ROW 17 | ) AS trail_12_m_comp 18 | FROM 19 | employees 20 | -------------------------------------------------------------------------------- /web/website/static/CNAME: -------------------------------------------------------------------------------- 1 | prql-lang.org 2 | -------------------------------------------------------------------------------- /web/website/static/img/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/static/img/apple-touch-icon.png -------------------------------------------------------------------------------- /web/website/static/img/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/static/img/favicon-16x16.png -------------------------------------------------------------------------------- /web/website/static/img/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/static/img/favicon-32x32.png -------------------------------------------------------------------------------- /web/website/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/static/img/favicon.ico -------------------------------------------------------------------------------- /web/website/themes/prql-theme/archetypes/default.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "{{ replace .Name "-" " " | title }}" 3 | date: {{ .Date }} 4 | draft: true 5 | --- 6 | -------------------------------------------------------------------------------- /web/website/themes/prql-theme/layouts/404.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
3 |

Not found

4 | 5 |

This page does not exist.

6 |
7 | {{ end }} 8 | -------------------------------------------------------------------------------- /web/website/themes/prql-theme/layouts/_default/_markup/render-link.html: -------------------------------------------------------------------------------- 1 | {{/* 2 | 3 | Formats external links with an icon, and opens in a new tab. 4 | 5 | Note that it's important not to have a blank line at the end; so we exclude this 6 | file from prettier / pre-commit's fixer 7 | 8 | */}} 9 | {{ $is_external := strings.HasPrefix .Destination "http" }} 10 | 19 | {{ .Text | safeHTML }} 20 | {{- if $is_external -}} 21 | 22 | {{- end -}} 23 | -------------------------------------------------------------------------------- /web/website/themes/prql-theme/layouts/_default/baseof.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ partial "head.html" . }} 4 | 5 | 6 | 7 | {{ partial "header.html" . }} 8 | 9 | 10 |
11 | {{- block "main" . }}{{- end }} 12 | 13 | {{- block "footer" . }} 14 | {{ partial "footer.html" . }} 15 | {{- end }} 16 |
17 | 18 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /web/website/themes/prql-theme/layouts/_default/big_iframe.html: -------------------------------------------------------------------------------- 1 | {{ define "footer" }} 2 | 3 | {{ end }} 4 | {{ define "main" }} 5 |
6 | {{ .Content }} 7 |
8 | {{ end }} 9 | -------------------------------------------------------------------------------- /web/website/themes/prql-theme/layouts/_default/list.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
3 |

{{ .Title }}

4 | 5 | {{ if .Content }} 6 |
{{ .Content }}
7 | {{ end }} 8 | 9 | {{ range .Pages }} 10 |

11 |
12 | 15 |
16 | {{ .Title }} 17 |

18 | {{ end }} 19 | 20 |
21 | {{ end }} 22 | -------------------------------------------------------------------------------- /web/website/themes/prql-theme/layouts/_default/single.html: -------------------------------------------------------------------------------- 1 | {{ define "main" }} 2 |
3 |
4 | {{ if not .Params.no_head }} 5 |

{{ .Title }}

6 | {{ if .Date }} 7 | 10 | {{ end }} 11 | {{ end }} 12 | 13 | {{ .Content }} 14 |
15 |
16 | {{ end }} 17 | -------------------------------------------------------------------------------- /web/website/themes/prql-theme/layouts/shortcodes/cite.html: -------------------------------------------------------------------------------- 1 | {{ .Inner }} 2 | -------------------------------------------------------------------------------- /web/website/themes/prql-theme/layouts/shortcodes/columns.html: -------------------------------------------------------------------------------- 1 |
2 | {{ range split .Inner "<--->" }} 3 |
{{ . | $.Page.RenderString }}
4 | {{ end }} 5 |
6 | -------------------------------------------------------------------------------- /web/website/themes/prql-theme/layouts/shortcodes/faq.html: -------------------------------------------------------------------------------- 1 |
2 |

{{ (.Get 0) | markdownify }}

3 | {{ .Inner | markdownify }} 4 |
5 | -------------------------------------------------------------------------------- /web/website/themes/prql-theme/layouts/shortcodes/link.html: -------------------------------------------------------------------------------- 1 | {{/* Compile a link as markdown so it runs the `render-link` template */}} 2 | {{ print "[" (.Get "label") "]" "(" .Get "link" ")" | markdownify }} 3 | -------------------------------------------------------------------------------- /web/website/themes/prql-theme/static/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/themes/prql-theme/static/apple-touch-icon.png -------------------------------------------------------------------------------- /web/website/themes/prql-theme/static/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/themes/prql-theme/static/favicon-16x16.png -------------------------------------------------------------------------------- /web/website/themes/prql-theme/static/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/themes/prql-theme/static/favicon-32x32.png -------------------------------------------------------------------------------- /web/website/themes/prql-theme/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/themes/prql-theme/static/favicon.ico -------------------------------------------------------------------------------- /web/website/themes/prql-theme/static/fonts/boxicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/themes/prql-theme/static/fonts/boxicons.eot -------------------------------------------------------------------------------- /web/website/themes/prql-theme/static/fonts/boxicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/themes/prql-theme/static/fonts/boxicons.ttf -------------------------------------------------------------------------------- /web/website/themes/prql-theme/static/fonts/boxicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/themes/prql-theme/static/fonts/boxicons.woff -------------------------------------------------------------------------------- /web/website/themes/prql-theme/static/fonts/boxicons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/themes/prql-theme/static/fonts/boxicons.woff2 -------------------------------------------------------------------------------- /web/website/themes/prql-theme/static/fonts/inter-extra-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/themes/prql-theme/static/fonts/inter-extra-bold.woff2 -------------------------------------------------------------------------------- /web/website/themes/prql-theme/static/fonts/inter-extra-nold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PRQL/prql/20ce2d6d856ac96f61406c9fe5a60f98ac647786/web/website/themes/prql-theme/static/fonts/inter-extra-nold.woff -------------------------------------------------------------------------------- /web/website/themes/prql-theme/theme.toml: -------------------------------------------------------------------------------- 1 | # theme.toml template for a Hugo theme 2 | # See https://github.com/gohugoio/hugoThemes#themetoml for an example 3 | 4 | license = "Apache 2.0" 5 | min_version = "0.41.0" 6 | name = "PRQL Theme" 7 | --------------------------------------------------------------------------------