Skip to content

Conversation

@Hydrocharged
Copy link
Collaborator

Direction of the Doltgres-side of changes for adding tables as types (which includes GMS changes since we do not support tables being treated as values for parameters outside of aggregate/window functions).

In general, table types are not serialized within the type collection, only the resulting type ID (created based on the table ID) is serialized in locations that need to reference the type. The table type is currently constructed every time we need to fetch it from the type collection. Inside the type collection, we first check if a given type ID is contained in the map. If not, then we check the root (obtained from the context) for a matching table name and construct the table type.

@Hydrocharged Hydrocharged requested a review from zachmu November 11, 2025 14:12
@github-actions
Copy link
Contributor

github-actions bot commented Nov 11, 2025

Main PR
covering_index_scan_postgres 347.37/s 331.40/s -4.6%
index_join_postgres 157.69/s 153.68/s -2.6%
index_join_scan_postgres 188.94/s 193.38/s +2.3%
index_scan_postgres 11.89/s 11.68/s -1.8%
oltp_point_select 2201.49/s ${\color{lightgreen}2478.94/s}$ ${\color{lightgreen}+12.6\%}$
oltp_read_only 1712.24/s 1809.48/s +5.6%
select_random_points 118.73/s 120.16/s +1.2%
select_random_ranges 131.01/s 128.76/s -1.8%
table_scan_postgres 11.21/s 11.21/s 0.0%
types_table_scan_postgres 5.25/s 5.21/s -0.8%

@github-actions
Copy link
Contributor

Main PR
Total 42090 42090
Successful 17231 17271
Failures 24859 24819
Partial Successes1 5592 5593
Main PR
Successful 40.9385% 41.0335%
Failures 59.0615% 58.9665%

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

alter_table

QUERY: create table at_tab2 (x int, y at_tab1);
QUERY: drop table at_tab2;
QUERY: create table at_tab2 (x int, y text, check((x,y)::at_tab1 = (1,'42')::at_tab1));
QUERY: drop table at_tab1, at_tab2;
QUERY: create table at_tab1 (a int, b text) partition by list(a);
QUERY: create table at_tab2 (x int, y at_tab1);
QUERY: drop table at_tab1, at_tab2;
QUERY: create temp table recur2 (f1 int, f2 recur1);

arrays

QUERY: create temp table t1 (f1 int8_tbl[]);

copy2

QUERY: create function check_con_function(check_con_tbl) returns bool as $$
begin
  raise notice 'input = %', row_to_json($1);
  return $1.f1 > 0;
end $$ language plpgsql immutable;

inherit

QUERY: select NULL::derived::base;

join

QUERY: create function mki8(bigint, bigint) returns int8_tbl as
$$select row($1,$2)::int8_tbl$$ language sql;
QUERY: create function mki4(int) returns int4_tbl as
$$select row($1)::int4_tbl$$ language sql;
QUERY: drop function mki8(bigint, bigint);
QUERY: drop function mki4(int);

misc

QUERY: CREATE FUNCTION hobby_construct(text, text)
   RETURNS hobbies_r
   AS 'select $1 as name, $2 as hobby'
   LANGUAGE SQL;
QUERY: CREATE FUNCTION hobby_construct_named(name text, hobby text)
   RETURNS hobbies_r
   AS 'select name, hobby'
   LANGUAGE SQL;
QUERY: CREATE FUNCTION equipment_named_ambiguous_2b(hobby text)
   RETURNS setof equipment_r
   AS 'select * from equipment_r where equipment_r.hobby = hobby'
   LANGUAGE SQL;

rangefuncs

QUERY: CREATE FUNCTION rngfunct(int) returns setof rngfunc2 as 'SELECT * FROM rngfunc2 WHERE rngfuncid = $1 ORDER BY f2;' LANGUAGE SQL;
QUERY: CREATE FUNCTION getrngfunc4(int) RETURNS rngfunc AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL;
QUERY: CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc4(1);
QUERY: CREATE FUNCTION getrngfunc5(int) RETURNS setof rngfunc AS 'SELECT * FROM rngfunc WHERE rngfuncid = $1;' LANGUAGE SQL;
QUERY: CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc5(1);
QUERY: CREATE FUNCTION getrngfunc9(int) RETURNS rngfunc AS 'DECLARE rngfunctup rngfunc%ROWTYPE; BEGIN SELECT * into rngfunctup FROM rngfunc WHERE rngfuncid = $1; RETURN rngfunctup; END;' LANGUAGE plpgsql;
QUERY: CREATE VIEW vw_getrngfunc AS SELECT * FROM getrngfunc9(1);
QUERY: DROP FUNCTION getrngfunc4(int);
QUERY: DROP FUNCTION getrngfunc5(int);
QUERY: DROP FUNCTION getrngfunc9(int);
QUERY: DROP FUNCTION rngfunct(int);
QUERY: create or replace function get_first_user() returns users as
$$ SELECT * FROM users ORDER BY userid LIMIT 1; $$
language sql stable;
QUERY: create or replace function get_users() returns setof users as
$$ SELECT * FROM users ORDER BY userid; $$
language sql stable;
QUERY: drop function get_first_user();
QUERY: drop function get_users();

rowsecurity

QUERY: create function rls_f () returns setof rls_t
  stable language sql
  as $$ select * from rls_t $$;
QUERY: DROP FUNCTION rls_f();

rowtypes

QUERY: create temp table people (fn fullname, bd date);

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.

Copy link
Member

@zachmu zachmu left a comment

Choose a reason for hiding this comment

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

Seems like a reasonable path forward for this feature

conflicts.ClearContextValues = ClearContextValues
plpgsql.GetTypesCollectionFromContext = GetTypesCollectionFromContext
id.RegisterListener(sequenceIDListener{}, id.Section_Table)
typecollection.GetSqlTableFromContext = GetSqlTableFromContext
Copy link
Member

Choose a reason for hiding this comment

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

This is less defensible when it's not cross-codebase. Probably need to refactor core a bit to remove the necessity of this. My guess is that these utility methods aren't really part of the core package, and the core and type collection packages could both depend on them in a new home.

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.

3 participants