From 42db162914c522ebadf856d2b663667c6ae2322e Mon Sep 17 00:00:00 2001 From: Benjamin Maurer Date: Thu, 21 Aug 2025 14:16:28 +0200 Subject: [PATCH 1/9] Fix response media type for plaintext. --- frameworks/Haskell/postgrest/src/plaintext.sql | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frameworks/Haskell/postgrest/src/plaintext.sql b/frameworks/Haskell/postgrest/src/plaintext.sql index ed9dbda1784..a894aa1f472 100644 --- a/frameworks/Haskell/postgrest/src/plaintext.sql +++ b/frameworks/Haskell/postgrest/src/plaintext.sql @@ -1,3 +1,5 @@ -create function plaintext() returns text as $$ +create domain "text/plain" text; + +create function plaintext() returns "text/plain" as $$ SELECT 'Hello, World!'; -$$ language sql volatile; \ No newline at end of file +$$ language sql volatile; From 6b9e18556692912954f1f4cd757629e358082baf Mon Sep 17 00:00:00 2001 From: Benjamin Maurer Date: Thu, 21 Aug 2025 14:47:15 +0200 Subject: [PATCH 2/9] raw-media-types option was removed. --- frameworks/Haskell/postgrest/postgrest.conf | 1 - frameworks/Haskell/postgrest/postgrest.dockerfile | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/frameworks/Haskell/postgrest/postgrest.conf b/frameworks/Haskell/postgrest/postgrest.conf index 688ef63d886..eaf7acfddac 100644 --- a/frameworks/Haskell/postgrest/postgrest.conf +++ b/frameworks/Haskell/postgrest/postgrest.conf @@ -16,4 +16,3 @@ role-claim-key = "$(PGRST_ROLE_CLAIM_KEY)" max-rows = "$(PGRST_MAX_ROWS)" pre-request = "$(PGRST_PRE_REQUEST)" root-spec = "$(PGRST_ROOT_SPEC)" -raw-media-types = "$(PGRST_RAW_MEDIA_TYPES)" \ No newline at end of file diff --git a/frameworks/Haskell/postgrest/postgrest.dockerfile b/frameworks/Haskell/postgrest/postgrest.dockerfile index fb5f224e9bd..fb25374ce37 100644 --- a/frameworks/Haskell/postgrest/postgrest.dockerfile +++ b/frameworks/Haskell/postgrest/postgrest.dockerfile @@ -23,12 +23,10 @@ ENV PGRST_MAX_ROWS= ENV PGRST_PRE_REQUEST= ENV PGRST_ROLE_CLAIM_KEY=.role ENV PGRST_ROOT_SPEC= -ENV PGRST_RAW_MEDIA_TYPES= ENV PGRST_DB_URI=postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_world ENV PGRST_DB_SCHEMA=public ENV PGRST_DB_ANON_ROLE=benchmarkdbuser -ENV PGRST_RAW_MEDIA_TYPES="text/html, text/plain" ENV PGRST_DB_POOL=64 RUN mkdir /app COPY src /app @@ -37,4 +35,4 @@ WORKDIR /app EXPOSE 3000 -ENTRYPOINT [ "/app/entrypoint.sh" ] \ No newline at end of file +ENTRYPOINT [ "/app/entrypoint.sh" ] From 29ad9e41cf0a384aa3ccc223fac9ba223921a508 Mon Sep 17 00:00:00 2001 From: Benjamin Maurer Date: Thu, 21 Aug 2025 14:55:35 +0200 Subject: [PATCH 3/9] Rename json route, as json is a reserved keyword. --- frameworks/Haskell/postgrest/README.md | 2 +- frameworks/Haskell/postgrest/benchmark_config.json | 2 +- frameworks/Haskell/postgrest/src/json.sql | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frameworks/Haskell/postgrest/README.md b/frameworks/Haskell/postgrest/README.md index 385ebf7b6ab..3409eb6405d 100755 --- a/frameworks/Haskell/postgrest/README.md +++ b/frameworks/Haskell/postgrest/README.md @@ -17,7 +17,7 @@ The tests were run with: ## Test URLs ### JSON -http://localhost:3000/rpc/json +http://localhost:3000/rpc/jsonser ### PLAINTEXT diff --git a/frameworks/Haskell/postgrest/benchmark_config.json b/frameworks/Haskell/postgrest/benchmark_config.json index be82b4771a8..8d324533f37 100755 --- a/frameworks/Haskell/postgrest/benchmark_config.json +++ b/frameworks/Haskell/postgrest/benchmark_config.json @@ -3,7 +3,7 @@ "tests": [ { "default": { - "json_url": "/rpc/json", + "json_url": "/rpc/jsonser", "plaintext_url": "/rpc/plaintext", "db_url": "/rpc/db", "query_url": "/rpc/queries?queries=", diff --git a/frameworks/Haskell/postgrest/src/json.sql b/frameworks/Haskell/postgrest/src/json.sql index 69f468887f8..28e92dcf66e 100644 --- a/frameworks/Haskell/postgrest/src/json.sql +++ b/frameworks/Haskell/postgrest/src/json.sql @@ -1,3 +1,3 @@ -create function json() returns json as $$ +create function jsonser() returns json as $$ SELECT json_build_object('message', 'Hello, World!'); -$$ language sql volatile; \ No newline at end of file +$$ language sql volatile; From fa129f0c9a0814d161d35605f37794d74d62e4c3 Mon Sep 17 00:00:00 2001 From: Benjamin Maurer Date: Thu, 21 Aug 2025 16:46:22 +0200 Subject: [PATCH 4/9] Use stricter stability modifiers. --- frameworks/Haskell/postgrest/src/fortunes.sql | 6 +++--- frameworks/Haskell/postgrest/src/json.sql | 2 +- frameworks/Haskell/postgrest/src/plaintext.sql | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frameworks/Haskell/postgrest/src/fortunes.sql b/frameworks/Haskell/postgrest/src/fortunes.sql index 5d4444b9529..47db4009ea1 100644 --- a/frameworks/Haskell/postgrest/src/fortunes.sql +++ b/frameworks/Haskell/postgrest/src/fortunes.sql @@ -1,8 +1,8 @@ CREATE TYPE fortune_t AS (id int, message text); create or replace function fortune_template(f fortune_t) returns text as $$ - SELECT format('%s%s', $1.id, regexp_replace($1.message, '<', '<','g')); -$$ language sql volatile; + SELECT format('%s%s', $1.id, regexp_replace($1.message, '<', '<','g')); +$$ language sql stable; create or replace function fortunes_template(fortunes fortune_t[]) returns text as $$ WITH header AS ( @@ -11,7 +11,7 @@ WITH header AS ( ), footer AS ( SELECT 2,'' as html ), fortunes AS ( - SELECT unnest as fortune from unnest($1) + SELECT unnest as fortune from unnest($1) ), additional AS ( SELECT (-1, 'Additional fortune added at request time.')::fortune_t as f ), all_fortunes AS ( diff --git a/frameworks/Haskell/postgrest/src/json.sql b/frameworks/Haskell/postgrest/src/json.sql index 28e92dcf66e..5df9168e372 100644 --- a/frameworks/Haskell/postgrest/src/json.sql +++ b/frameworks/Haskell/postgrest/src/json.sql @@ -1,3 +1,3 @@ create function jsonser() returns json as $$ SELECT json_build_object('message', 'Hello, World!'); -$$ language sql volatile; +$$ language sql immutable; diff --git a/frameworks/Haskell/postgrest/src/plaintext.sql b/frameworks/Haskell/postgrest/src/plaintext.sql index a894aa1f472..77fd5d76bfd 100644 --- a/frameworks/Haskell/postgrest/src/plaintext.sql +++ b/frameworks/Haskell/postgrest/src/plaintext.sql @@ -2,4 +2,4 @@ create domain "text/plain" text; create function plaintext() returns "text/plain" as $$ SELECT 'Hello, World!'; -$$ language sql volatile; +$$ language sql immutable; From 7c953c8b81b9768d29e8ae4d703a6c16f4cea6f9 Mon Sep 17 00:00:00 2001 From: Benjamin Maurer Date: Thu, 21 Aug 2025 16:49:04 +0200 Subject: [PATCH 5/9] Rename update path according to wiki --- frameworks/Haskell/postgrest/README.md | 2 +- frameworks/Haskell/postgrest/src/update.sql | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) mode change 100755 => 100644 frameworks/Haskell/postgrest/README.md diff --git a/frameworks/Haskell/postgrest/README.md b/frameworks/Haskell/postgrest/README.md old mode 100755 new mode 100644 index 3409eb6405d..fd207092295 --- a/frameworks/Haskell/postgrest/README.md +++ b/frameworks/Haskell/postgrest/README.md @@ -37,7 +37,7 @@ http://localhost:8080/cached_query?queries= ### UPDATE Not Implemented -http://localhost:3000/rpc/update?queries= +http://localhost:3000/rpc/updates?queries= ### FORTUNES diff --git a/frameworks/Haskell/postgrest/src/update.sql b/frameworks/Haskell/postgrest/src/update.sql index 541e2a507cc..71aededfe44 100644 --- a/frameworks/Haskell/postgrest/src/update.sql +++ b/frameworks/Haskell/postgrest/src/update.sql @@ -1,4 +1,4 @@ -create or replace function update(queries text default '') returns jsonb as $$ +create or replace function updates(queries text default '') returns jsonb as $$ DECLARE r "World"%ROWTYPE; j jsonb := jsonb_build_array(); @@ -6,11 +6,10 @@ DECLARE rnd_id int; count int; BEGIN - SET TRANSACTION READ WRITE; IF queries ~ '^[1-9]\d{0,2}$' THEN count := CAST(queries as int); - ELSE - count := 1; + ELSE + count := 1; END IF; IF count > 500 THEN count := 500; From 6f10c2db7312ec6e49f32d86db3057585b88a742 Mon Sep 17 00:00:00 2001 From: Benjamin Maurer Date: Thu, 21 Aug 2025 16:49:20 +0200 Subject: [PATCH 6/9] Minor improvement to docker-compose file. --- frameworks/Haskell/postgrest/docker-compose.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frameworks/Haskell/postgrest/docker-compose.yml b/frameworks/Haskell/postgrest/docker-compose.yml index 8b8b2a03e0f..eca0e4bbfb8 100644 --- a/frameworks/Haskell/postgrest/docker-compose.yml +++ b/frameworks/Haskell/postgrest/docker-compose.yml @@ -1,4 +1,3 @@ -version: '3' services: tfb-database: build: @@ -13,4 +12,6 @@ services: dockerfile: postgrest.dockerfile context: . ports: - - 3030:3000 \ No newline at end of file + - 3030:3000 + depends_on: + - tfb-database From 3ad10a38f13f754808a2e080610f716bfdc08a57 Mon Sep 17 00:00:00 2001 From: Benjamin Maurer Date: Fri, 22 Aug 2025 11:25:55 +0200 Subject: [PATCH 7/9] Minor changes. --- frameworks/Haskell/postgrest/README.md | 13 ++++++++++--- frameworks/Haskell/postgrest/src/plaintext.sql | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/frameworks/Haskell/postgrest/README.md b/frameworks/Haskell/postgrest/README.md index fd207092295..90dd62acf81 100644 --- a/frameworks/Haskell/postgrest/README.md +++ b/frameworks/Haskell/postgrest/README.md @@ -7,7 +7,7 @@ * [DB](src/db.sql) * [QUERY](src/query.sql) * [CACHED QUERY] Not Implemented -* [UPDATE] Not Implemented +* [UPDATE](src/update.sql) * [FORTUNES](src/fortunes.sql) ## Important Libraries @@ -31,14 +31,21 @@ http://localhost:3000/rpc/db http://localhost:3000/rpc/query?queries= -### CACHED QUERY Not Implemented +### CACHED QUERY - Not Implemented http://localhost:8080/cached_query?queries= -### UPDATE Not Implemented +### UPDATE - Not Working http://localhost:3000/rpc/updates?queries= +Technically, this is implemented (maybe not correctly though). +However, the benchmark issues this as a GET request. +PostgREST sets the transaction to READ ONLY for GET requests, +as they are supposed to be idempotent. +Hence this results in an error. Calling the endpoint with POST +works though. + ### FORTUNES http://localhost:3000/rpc/fortunes.html diff --git a/frameworks/Haskell/postgrest/src/plaintext.sql b/frameworks/Haskell/postgrest/src/plaintext.sql index 77fd5d76bfd..b5be0003fcc 100644 --- a/frameworks/Haskell/postgrest/src/plaintext.sql +++ b/frameworks/Haskell/postgrest/src/plaintext.sql @@ -1,4 +1,4 @@ -create domain "text/plain" text; +create domain "text/plain" as text; create function plaintext() returns "text/plain" as $$ SELECT 'Hello, World!'; From d197ee3437e531b45f5c84dbb3763e24730a788f Mon Sep 17 00:00:00 2001 From: Benjamin Maurer Date: Fri, 22 Aug 2025 11:26:09 +0200 Subject: [PATCH 8/9] Fix fortunes benchmark. --- .../Haskell/postgrest/benchmark_config.json | 2 +- frameworks/Haskell/postgrest/config.toml | 1 + frameworks/Haskell/postgrest/src/fortunes.sql | 47 ++++++------------- 3 files changed, 17 insertions(+), 33 deletions(-) diff --git a/frameworks/Haskell/postgrest/benchmark_config.json b/frameworks/Haskell/postgrest/benchmark_config.json index 8d324533f37..228ee2f5be0 100755 --- a/frameworks/Haskell/postgrest/benchmark_config.json +++ b/frameworks/Haskell/postgrest/benchmark_config.json @@ -7,7 +7,7 @@ "plaintext_url": "/rpc/plaintext", "db_url": "/rpc/db", "query_url": "/rpc/queries?queries=", - "fortunes_url": "/rpc/fortunes.html", + "fortune_url": "/rpc/fortunes", "port": 3000, "approach": "Realistic", "classification": "Micro", diff --git a/frameworks/Haskell/postgrest/config.toml b/frameworks/Haskell/postgrest/config.toml index b98dcecc8ed..a5606004603 100644 --- a/frameworks/Haskell/postgrest/config.toml +++ b/frameworks/Haskell/postgrest/config.toml @@ -6,6 +6,7 @@ urls.plaintext = "/rpc/plaintext" urls.json = "/rpc/json" urls.db = "/rpc/db" urls.query = "/rpc/queries?queries=" +urls.fortune = "/rpc/fortunes" approach = "Realistic" classification = "Micro" database = "postgres" diff --git a/frameworks/Haskell/postgrest/src/fortunes.sql b/frameworks/Haskell/postgrest/src/fortunes.sql index 47db4009ea1..ec2241e0829 100644 --- a/frameworks/Haskell/postgrest/src/fortunes.sql +++ b/frameworks/Haskell/postgrest/src/fortunes.sql @@ -1,35 +1,18 @@ -CREATE TYPE fortune_t AS (id int, message text); +create domain "text/html" as text; -create or replace function fortune_template(f fortune_t) returns text as $$ - SELECT format('%s%s', $1.id, regexp_replace($1.message, '<', '<','g')); -$$ language sql stable; +create or replace function sanitize_html(text) returns text as $$ + select replace(replace(replace(replace(replace($1, '&', '&'), '"', '"'),'>', '>'),'<', '<'), '''', ''') +$$ language sql immutable; -create or replace function fortunes_template(fortunes fortune_t[]) returns text as $$ -WITH header AS ( - SELECT 0 as id,' -Fortunes' as html -), footer AS ( - SELECT 2,'
idmessage
' as html -), fortunes AS ( - SELECT unnest as fortune from unnest($1) -), additional AS ( - SELECT (-1, 'Additional fortune added at request time.')::fortune_t as f -), all_fortunes AS ( - SELECT * from (SELECT * FROM fortunes UNION ALL SELECT * from additional) p ORDER BY (fortune).message -), fortunes_html AS ( - SELECT 1,string_agg(fortune_template(fortune), '') from all_fortunes -), html AS ( - SELECT * FROM header UNION SELECT * FROM fortunes_html UNION SELECT * from footer ORDER BY id -) -SELECT string_agg(html,'') from html; -$$ language sql volatile; +create or replace function fortune_template("Fortune") returns text as $$ + SELECT format('%s%s', $1.id, sanitize_html($1.message)); +$$ language sql immutable; + +create or replace function fortunes() returns "text/html" as $$ + select set_config('response.headers', '[{"Content-Type": "text/html; charset=utf-8"}]', true); -create or replace function "fortunes.html"() returns bytea as $$ -DECLARE - fortunes fortune_t[]; -BEGIN - SET LOCAL "response.headers" = '[{"Content-Type": "text/html"}]'; - SELECT array_agg(CAST((id,message) AS fortune_t)) FROM "Fortunes" INTO fortunes; - RETURN convert_to(fortunes_template(fortunes), 'UTF8'); -END -$$ language plpgsql volatile; + select 'Fortunes' + || string_agg(fortune_template(f), NULL order by f.message collate unicode asc) + || '
idmessage
' + from (select * from "Fortune" union all select 0, 'Additional fortune added at request time.') f; +$$ language sql volatile; From 2da83a7ebd80baced920185dfcbbabc51a90daaf Mon Sep 17 00:00:00 2001 From: Benjamin Maurer Date: Sat, 6 Sep 2025 12:36:06 +0200 Subject: [PATCH 9/9] Add clarifying comment for content-type. --- frameworks/Haskell/postgrest/src/fortunes.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frameworks/Haskell/postgrest/src/fortunes.sql b/frameworks/Haskell/postgrest/src/fortunes.sql index ec2241e0829..f8de4591c8c 100644 --- a/frameworks/Haskell/postgrest/src/fortunes.sql +++ b/frameworks/Haskell/postgrest/src/fortunes.sql @@ -9,6 +9,8 @@ create or replace function fortune_template("Fortune") returns text as $$ $$ language sql immutable; create or replace function fortunes() returns "text/html" as $$ + -- This is only necessary bc. of the benchmark: The domain gives us content-type: text/html, + -- but the benchmark explicitly tests for the charset in the content-type. select set_config('response.headers', '[{"Content-Type": "text/html; charset=utf-8"}]', true); select 'Fortunes'
idmessage