Skip to content

add fors plpgsql statement#2472

Merged
jennifersp merged 7 commits intomainfrom
jennifer/fixes
Mar 24, 2026
Merged

add fors plpgsql statement#2472
jennifersp merged 7 commits intomainfrom
jennifer/fixes

Conversation

@jennifersp
Copy link
Copy Markdown
Contributor

No description provided.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 18, 2026

Main PR
covering_index_scan_postgres 1034.64/s 1026.93/s -0.8%
index_join_postgres 151.69/s 152.05/s +0.2%
index_join_scan_postgres 189.57/s 190.24/s +0.3%
index_scan_postgres 11.68/s 11.64/s -0.4%
oltp_point_select 2384.23/s 2383.08/s -0.1%
oltp_read_only 1746.72/s 1742.95/s -0.3%
select_random_points 120.45/s 122.26/s +1.5%
select_random_ranges 803.60/s 780.72/s -2.9%
table_scan_postgres 11.39/s 11.38/s -0.1%
types_table_scan_postgres 5.14/s 5.09/s -1.0%

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 18, 2026

Main PR
Total 42090 42090
Successful 17783 17820
Failures 24307 24270
Partial Successes1 5573 5572
Main PR
Successful 42.2499% 42.3378%
Failures 57.7501% 57.6622%

${\color{red}Regressions (1)}$

random

QUERY:          (SELECT unique1 AS random
  FROM onek ORDER BY random() LIMIT 1)
INTERSECT
(SELECT unique1 AS random
  FROM onek ORDER BY random() LIMIT 1)
INTERSECT
(SELECT unique1 AS random
  FROM onek ORDER BY random() LIMIT 1);
RECEIVED ERROR: expected row count 0 but received 1

${\color{lightgreen}Progressions (33)}$

alter_table

QUERY: create function xtrig()
  returns trigger language plpgsql
as $$
  declare
    r record;
  begin
    for r in select * from old loop
      raise info 'a=%, b=%', r.a, r.b;
    end loop;
    return NULL;
  end;
$$;

create_function_sql

QUERY: CREATE FUNCTION voidtest3(a int) RETURNS VOID LANGUAGE SQL AS
$$ INSERT INTO sometable VALUES(a + 1) $$;
QUERY: CREATE FUNCTION voidtest4(a int) RETURNS VOID LANGUAGE SQL AS
$$ INSERT INTO sometable VALUES(a - 1) RETURNING f1 $$;
QUERY: TABLE sometable;

create_procedure

QUERY: CREATE PROCEDURE ptest1(x text)
LANGUAGE SQL
AS $$
INSERT INTO cp_test VALUES (1, x);
$$;
QUERY: CALL ptest1('xy' || 'zzy');
QUERY: CALL ptest1(substring(random()::numeric(20,15)::text, 1, 1));
QUERY: SELECT * FROM cp_test ORDER BY b COLLATE "C";
QUERY: CALL ptest7(least('a', 'b'), 'a');
QUERY: DROP PROCEDURE ptest1;

incremental_sort

QUERY: create or replace function explain_analyze_inc_sort_nodes_without_memory(query text)
returns jsonb language plpgsql
as
$$
declare
  nodes jsonb := '[]'::jsonb;
  node jsonb;
  group_key text;
  space_key text;
begin
  for node in select * from jsonb_array_elements(explain_analyze_inc_sort_nodes(query)) t loop
    for group_key in select unnest(array['Full-sort Groups', 'Pre-sorted Groups']::text[]) t loop
      for space_key in select unnest(array['Sort Space Memory', 'Sort Space Disk']::text[]) t loop
        node := jsonb_set(node, array[group_key, space_key, 'Average Sort Space Used'], '"NN"', false);
        node := jsonb_set(node, array[group_key, space_key, 'Peak Sort Space Used'], '"NN"', false);
      end loop;
    end loop;
    nodes := nodes || node;
  end loop;
  return nodes;
end;
$$;
QUERY: create or replace function explain_analyze_inc_sort_nodes_verify_invariants(query text)
returns bool language plpgsql
as
$$
declare
  node jsonb;
  group_stats jsonb;
  group_key text;
  space_key text;
begin
  for node in select * from jsonb_array_elements(explain_analyze_inc_sort_nodes(query)) t loop
    for group_key in select unnest(array['Full-sort Groups', 'Pre-sorted Groups']::text[]) t loop
      group_stats := node->group_key;
      for space_key in select unnest(array['Sort Space Memory', 'Sort Space Disk']::text[]) t loop
        if (group_stats->space_key->'Peak Sort Space Used')::bigint < (group_stats->space_key->'Peak Sort Space Used')::bigint then
          raise exception '% has invalid max space < average space', group_key;
        end if;
      end loop;
    end loop;
  end loop;
  return true;
end;
$$;

insert_conflict

QUERY: create or replace function parted_conflict_update_func() returns trigger as $$
declare
    r record;
begin
 for r in select * from inserted loop
	raise notice 'a = %, b = %, c = %', r.a, r.b, r.c;
 end loop;
 return new;
end;
$$ language plpgsql;
QUERY: drop function parted_conflict_update_func();

join_hash

QUERY: create or replace function find_hash(node json)
returns json language plpgsql
as
$$
declare
  x json;
  child json;
begin
  if node->>'Node Type' = 'Hash' then
    return node;
  else
    for child in select json_array_elements(node->'Plans')
    loop
      x := find_hash(child);
      if x is not null then
        return x;
      end if;
    end loop;
    return null;
  end if;
end;
$$;

plancache

QUERY: create function cachebug() returns void as $$
declare r int;
begin
  drop table if exists temptable cascade;
  create temp table temptable as select * from generate_series(1,3) as f1;
  create temp view vv as select * from temptable;
  for r in select * from vv loop
    raise notice '%', r;
  end loop;
end$$ language plpgsql;

plpgsql

QUERY: select error2('public.stuffs');

polymorphism

QUERY: select dfunc('Hi');

rangefuncs

QUERY: create function insert_tt(text) returns int as
$$ insert into tt(data) values($1) returning f1 $$
language sql;
QUERY: create or replace function insert_tt(text) returns int as
$$ insert into tt(data) values($1),($1||$1) returning f1 $$
language sql;
QUERY: create or replace function insert_tt2(text,text) returns setof int as
$$ insert into tt(data) values($1),($2) returning f1 $$
language sql;
QUERY: create function testrngfunc() returns record as $$
  insert into rngfunc values (1,2) returning *;
$$ language sql;
QUERY: create function testrngfunc() returns setof record as $$
  insert into rngfunc values (1,2), (3,4) returning *;
$$ language sql;
QUERY: create or replace function testrngfunc() returns setof rngfunc_type as $$
  select 1, 2 union select 3, 4 order by 1;
$$ language sql immutable;
QUERY: create or replace function rngfuncbar() returns setof text as
$$ select 'foo'::varchar union all select 'bar'::varchar ; $$
language sql stable;
QUERY: select rngfuncbar();

select

QUERY: create function sillysrf(int) returns setof int as
  'values (1),(10),(2),($1)' language sql immutable;
QUERY: select sillysrf(42);
QUERY: drop function sillysrf(int);

select_into

QUERY: CREATE FUNCTION make_table() RETURNS VOID
AS $$
  CREATE TABLE created_table AS SELECT * FROM int8_tbl;
$$ LANGUAGE SQL;

select_parallel

QUERY: create function sp_test_func() returns setof text as
$$ select 'foo'::varchar union all select 'bar'::varchar $$
language sql stable;

vacuum

QUERY: CREATE FUNCTION do_analyze() RETURNS VOID VOLATILE LANGUAGE SQL
	AS 'ANALYZE pg_am';
QUERY: CREATE FUNCTION wrap_do_analyze(c INT) RETURNS INT IMMUTABLE LANGUAGE SQL
	AS 'SELECT $1 FROM do_analyze()';

Footnotes

  1. These are tests that we're marking as Successful, however they do not match the expected output in some way. This is due to small differences, such as different wording on the error messages, or the column names being incorrect while the data itself is correct.

@jennifersp jennifersp requested a review from Hydrocharged March 19, 2026 23:04
Copy link
Copy Markdown
Collaborator

@Hydrocharged Hydrocharged left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Comment thread server/expression/any.go Outdated
Comment thread server/functions/framework/sql_function.go Outdated
Comment thread testing/go/create_function_plpgsql_test.go
@jennifersp jennifersp enabled auto-merge (squash) March 24, 2026 04:38
@jennifersp jennifersp merged commit 2e722e9 into main Mar 24, 2026
17 checks passed
@jennifersp jennifersp deleted the jennifer/fixes branch March 24, 2026 05:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants