{"id":13580175,"url":"https://github.com/kaspermarstal/plprql","last_synced_at":"2025-04-06T00:30:50.900Z","repository":{"id":207390898,"uuid":"692249642","full_name":"kaspermarstal/plprql","owner":"kaspermarstal","description":"Use PRQL in PostgreSQL","archived":false,"fork":false,"pushed_at":"2025-03-21T19:50:39.000Z","size":345,"stargazers_count":450,"open_issues_count":1,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-29T07:03:34.117Z","etag":null,"topics":["extension","pgrx","postgresql","prql","sql"],"latest_commit_sha":null,"homepage":"https://prql-lang.org/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kaspermarstal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-15T23:13:05.000Z","updated_at":"2025-03-28T09:38:33.000Z","dependencies_parsed_at":"2024-02-01T22:08:08.716Z","dependency_job_id":"a950c9fd-5e61-46e0-ae11-bd23fc333099","html_url":"https://github.com/kaspermarstal/plprql","commit_stats":null,"previous_names":["kaspermarstal/plprql"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaspermarstal%2Fplprql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaspermarstal%2Fplprql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaspermarstal%2Fplprql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaspermarstal%2Fplprql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kaspermarstal","download_url":"https://codeload.github.com/kaspermarstal/plprql/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247419597,"owners_count":20936009,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["extension","pgrx","postgresql","prql","sql"],"created_at":"2024-08-01T15:01:48.357Z","updated_at":"2025-04-06T00:30:50.890Z","avatar_url":"https://github.com/kaspermarstal.png","language":"Rust","readme":"[![Linux](https://github.com/kaspermarstal/plprql/actions/workflows/ci.yml/badge.svg)](https://github.com/kaspermarstal/plprql/actions/workflows/ci.yml) [![Linux](https://github.com/kaspermarstal/plprql/actions/workflows/package.yml/badge.svg)](https://github.com/kaspermarstal/plprql/actions/workflows/package.yml)\n\n\n# PRQL in PostgreSQL!\n\nPL/PRQL is a PostgreSQL extension that lets you write stored procedures with [PRQL](https://prql-lang.org/). The extension supports PostgreSQL v12-16 on Linux and macOS.\n\n## What is PRQL?\nPRQL (Pipelined Relational Query Language) is an open source query language for data manipulation and analysis that compiles to SQL. PRQL introduces a pipeline concept (similar to Unix pipes) that transforms data line-by-line. The sequential series of transformations reduces the complexity often encountered with nested SQL queries and makes your data manipulation logic easier to read and write. With PL/PRQL you can write Procedural Language (PL) functions (stored procedures) with PRQL instead of the traditional PL/pgSQL and combine the simplicity of PRQL with the power of stored procedures.\n\n## Key features\n- [Write functions with PRQL](#write-functions-with-prql) - Useful for large analytical queries\n- [Compile PRQL queries to SQL queries](#compile-prql-queries-to-sql-queries) - Useful for development and debugging\n- [Execute PRQL queries](#execute-prql-queries) - Useful for prototyping and custom queries in ORMs\n\n### Write functions with PRQL\nPRQL shines when your SQL queries becomes long and complex. You can manage this complexity by porting your most impressive SQL incantations to PRQL functions, which can then be used in dashboards, business logic or other database code. For example:\n\n```sql\ncreate function match_stats(int) returns table(player text, kd_ratio float) as $$\n  from matches\n  filter match_id == $1\n  group player (\n    aggregate {\n      total_kills = sum kills,\n      total_deaths = sum deaths\n    }\n  )\n  filter total_deaths \u003e 0\n  derive kd_ratio = total_kills / total_deaths\n  select { player, kd_ratio }\n$$ language plprql;\n\nselect * from match_stats(1001)\n    \n player  | kd_ratio \n---------+----------\n Player1 |    0.625\n Player2 |      1.6\n(2 rows)\n```\n\n### Compile PRQL queries to SQL queries\nYou can use `prql_to_sql()` to see the SQL statements that PostgreSQL executes under the hood. This function invokes the PRQL compiler and shows you the resulting SQL code. Using the example above:\n\n```sql\nselect prql_to_sql('...'); -- statements above omitted for brevity\n\n prql_to_sql \n-------------\nWITH table_0 AS (\n  SELECT player, COALESCE(SUM(kills), 0) AS _expr_0, COALESCE(SUM(deaths), 0) AS _expr_1\n  FROM matches\n  WHERE match_id = $1\n  GROUP BY player\n)\nSELECT player, _expr_0 / _expr_1 AS kd_ratio\nFROM table_0\nWHERE _expr_1 \u003e 0\n-- Generated by PRQL compiler version:0.11.1 (https://prql-lang.org)\n(1 row)\n```\n\n### Execute PRQL queries\nYou can run PRQL code directly with the `prql` function. This is useful for e.g. custom queries in application code:\n \n```sql\nselect prql('from matches | filter player == ''Player1''') \nas (id int, match_id int, round int, player text, kills int, deaths int) \nlimit 2;\n\n id | match_id | round | player  | kills | deaths \n----+----------+-------+---------+-------+--------\n  1 |     1001 |     1 | Player1 |     4 |      1\n  3 |     1001 |     2 | Player1 |     1 |      7\n(2 rows)\n \n-- Same as above, but returns cursor\nselect prql('from matches | filter player == ''Player1''', 'player1_cursor');\nfetch 2 from player1_cursor;\n```\n\n\nFor more information on the design of the extension, see the [design document](DESIGN.md). \n\nFor more information on PRQL, visit the PRQL [website](https://prql-lang.org/), [playground](https://prql-lang.org/playground/) or [repository](https://github.com/PRQL/prql). \n\n\u003e [!NOTE]\n\u003e\n\u003e PRQL supports `select` statements only. `insert`, `update`, and `delete` statements, and your other database code, will continue to live in vanilla SQL, ORMs, or other database frameworks.\n\n## Getting Started\n\nYou can install the PL/PRQL extension in four ways:\n\n- [Install Deb File](#install-deb-file): Download .deb file from releases page.\n- [Install From Source](#install-from-source): Clone the repository and build the extension on your own machine.\n- [Run Dockerfile](#run-dockerfile): Build a docker image with PostgreSQL and the extension.\n- [Run Shell Script](#run-shell-script): Download and run a shell script builds the extension on your own machine for you.\n\n\nThe instruction assume you use Ubuntu or Debian.\n\n### Install Deb File\nFollow these steps to install PL/PRQL from one of the released deb files:\n\n1. Download the deb file that matches your operating system from the [Releases](https://github.com/kaspermarstal/plprql/releases/) page.\n2. Open a terminal and change to the directory where the `.deb` file was downloaded. Install the package with dpkg, e.g.:\n   \n   ```cmd\n   sudo dpkg -i plprql-0.1.0-postgresql-16-debian-bookworm-amd64.deb\n   ```\n3. If dpkg reports missing dependencies, run the following command to fix them:\n   \n   ```cmd\n   sudo apt-get install -f\n   ```\n   \nThis only requires that you have PostgreSQL installed on beforehand. Replace the major version of PostgreSQL in the deb's filename if needed. Supported versions are 12, 13, 14, 15, and 16.\n\n### Install From Source\nPL/PRQL is built on top of the [pgrx](https://github.com/pgcentralfoundation/pgrx) framework for writing PostgreSQL extensions in Rust. This framework comes with development tools that you need to install. Follow these steps to set up your development environment:\n\n1. Install `cargo`.\n   \n   ```cmd\n   curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y\n   ```\n2. Install `cargo-pgrx`.\n\n    ```cmd\n    cargo install --locked --version=0.11.3 cargo-pgrx\n    ```\n\n    The version of `cargo-pgrx` must match the version of `pgrx` in `plprql/Cargo.toml`. \n\n3. Initialize `pgrx` for your system.\n   ```cmd\n   cargo pgrx init --pg16 \u003cPG16\u003e\n   ```\n   where `\u003cPG16\u003e` is the path to your system installation's `pg_config` tool (typically `/usr/bin/pg_config`). Supported versions are PostgreSQL v12-16. You can also run `cargo pgrx init` and have `pgrx` download, install, and compile PostgreSQL v12-16. These installations are managed by `pgrx` and used for development and testing. Individual `pgrx`-managed installations can be installed using e.g. `cargo pgrx init --pg16 download`. \n\n4. Clone this repository.\n\n    ```cmd\n    git clone https://github.com/kaspermarstal/plprql\n    ```\n   \n5. `cd` into root directory and install the extension to the PostgreSQL specified by\n   the `pg_config` currently on your `$PATH`.\n   ```cmd\n   cd plprql/plprql\n   cargo pgrx install --release\n   ```\n   You can target a specific PostgreSQL installation by providing the path of another `pg_config` using the `-c` flag.\n   \n6. Fire up your system PostgreSQL installation and start writing functions right away! You can also try out PL/PRQL in an installation managed by `pgrx`:\n   ```cmd\n   $ cargo pgrx run pg16\n   psql\u003e create extension plprql;\n   psql\u003e create function match_stats(int) \n         returns table(total_kills real, total_deaths real) as $$\n           from rounds\n           filter match_id == $1\n           aggregate {\n             total_kills = sum kills,\n             total_deaths = sum deaths\n           }\n         $$ language plprql\n   psql\u003e select match_stats(1);\n   ```\n   \n### Run Dockerfile\n\nThe `docker/plprql.Dockerfile` builds the `postgres:16-bookworm` docker image with the extension installed. You run this Dockerfile on your own machine with the following commands:\n\n```cmd\ncurl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/kaspermarstal/plprql/main/docker/plprql.Dockerfile \u003e plprql.Dockerfile\ndocker build --tag 'plprql' . -f plprql.Dockerfile\n```\n\nThe dockerfile downloads a .deb file from the releases page and installs it into the official `postgres:16-bookworm` image.\n\nYou can quickly test that the extension is installed and works as expected:\n\n```cmd\nCONTAINER_ID=$(docker run -d -e POSTGRES_HOST_AUTH_METHOD=trust plprql)\ndocker exec $CONTAINER_ID psql -U postgres -c \"create extension plprql;\"\ndocker exec $CONTAINER_ID psql -U postgres -c \"select prql_to_sql1('from table')\"\n```\n\n### Run Shell Script\nRun the following command to download and execute the shell script in [scripts/install.sh](scripts/install.sh):\n\n```cmd\ncurl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/kaspermarstal/plprql/main/scripts/install.sh | bash\n```\n   \nThis will install the tip of the main branch using `pg_config` on your path.\n\nYou can customize the PostgreSQL installation and/or the PL/PRQL version using the `--pg-config` and `--revision` flags:\n\n```cmd\ncurl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/kaspermarstal/plprql/main/scripts/install.sh \u003e install.sh\nchmod +x ./install.sh\n./install.sh --pg-version /usr/bin/pg_config --revision 186faea\n```\n\nYou need the following packages for the shell script to run:\n\n- A C compiler\n- PostgreSQL and header files\n- Rust, Cargo, and pgrx\n- Utilities for the shell script (curl, wget, gnupg, lsb-release, git, jq)\n\nYou can install these dependencies with the following commands:\n\n```cmd\nsudo apt-get update \u0026\u0026 apt-get upgrade\nsudo apt-get install -y curl wget gnupg lsb-release git build-essential\nsh -c 'echo \"deb https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main\" \u003e /etc/apt/sources.list.d/pgdg.list'\nwget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -\nsudo apt-get update\nsudo apt-get install -y postgresql-16 postgresql-server-dev-16\ncurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y\nsource ~/.bashrc\ncargo install --locked --version=0.11.3 cargo-pgrx\ncargo pgrx init --pg16 $(which pg_config)\n```\n\n### Running Tests \nYou can run tests using `cargo pgrx test pg16`. Unit tests are in the main `plprql` crate while integration tests are in the `plprql-tests` crate. From the root source directory:\n\n```cmd\ncd plprql \u0026\u0026 echo \"\\q\" | cargo pgrx run pg16 \u0026\u0026 cargo test --no-default-features --features pg16\ncd ../plprql-tests \u0026\u0026 echo \"\\q\" | cargo pgrx run pg16 \u0026\u0026 cargo test --no-default-features --features pg16\n```\n\nSupported PostgreSQL versions are `pg12`, `pg13`, `pg14`, `pg15`, and `pg16`.\n\n## License\nApache 2.0 License\n","funding_links":[],"categories":["Rust"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaspermarstal%2Fplprql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkaspermarstal%2Fplprql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaspermarstal%2Fplprql/lists"}