Skip to content

Conversation

@zachmu
Copy link
Member

@zachmu zachmu commented Apr 10, 2025

This PR adds a couple compatibility features for commands issued by psql:

  • Support for the operator(...) syntax for built-in postgres operators
  • Support for collation expressions, currently ignored

These two things get us to near 100% coverage for psql commands without special casing. The last piece is the array(select ...) syntax.

Relies on dolthub/go-mysql-server#2931

@zachmu zachmu requested a review from Hydrocharged April 10, 2025 00:33
@github-actions
Copy link
Contributor

github-actions bot commented Apr 10, 2025

Main PR
covering_index_scan_postgres 338.43/s 338.74/s 0.0%
index_join_postgres 154.32/s 151.81/s -1.7%
index_join_scan_postgres 184.20/s 184.51/s +0.1%
index_scan_postgres 12.66/s 12.56/s -0.8%
oltp_point_select 2637.21/s 2622.89/s -0.6%
oltp_read_only 1830.35/s 1812.53/s -1.0%
select_random_points 114.64/s 114.95/s +0.2%
select_random_ranges 130.33/s 125.59/s -3.7%
table_scan_postgres 12.09/s 11.73/s -3.0%
types_table_scan_postgres 5.54/s 5.43/s -2.0%

@github-actions
Copy link
Contributor

github-actions bot commented Apr 10, 2025

Main PR
Total 42090 42090
Successful 15578 15696
Failures 26512 26394
Partial Successes1 5208 5231
Main PR
Successful 37.0112% 37.2915%
Failures 62.9888% 62.7085%

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

aggregates

QUERY: SELECT var_pop(1.0::float8), var_samp(2.0::float8);
QUERY: SELECT stddev_pop(3.0::float8), stddev_samp(4.0::float8);
QUERY: SELECT sum(x::float8), avg(x::float8), var_pop(x::float8)
FROM (VALUES ('1'), ('infinity')) v(x);
QUERY: SELECT sum(x::float8), avg(x::float8), var_pop(x::float8)
FROM (VALUES ('infinity'), ('1')) v(x);
QUERY: SELECT sum(x::float8), avg(x::float8), var_pop(x::float8)
FROM (VALUES ('infinity'), ('infinity')) v(x);
QUERY: SELECT sum(x::float8), avg(x::float8), var_pop(x::float8)
FROM (VALUES ('-infinity'), ('infinity')) v(x);
QUERY: SELECT sum(x::float8), avg(x::float8), var_pop(x::float8)
FROM (VALUES ('-infinity'), ('-infinity')) v(x);
QUERY: SELECT avg(x::float8), var_pop(x::float8)
FROM (VALUES (100000003), (100000004), (100000006), (100000007)) v(x);
QUERY: SELECT avg(x::float8), var_pop(x::float8)
FROM (VALUES (7000000000005), (7000000000007)) v(x);

collate

QUERY: SELECT 'bbc' COLLATE "C" > 'Abc' COLLATE "C" AS "true";
QUERY: SELECT 'bbc' COLLATE "POSIX" < 'Abc' COLLATE "POSIX" AS "false";
QUERY: SELECT a, b, a < b as lt FROM
  (VALUES ('a', 'B'), ('A', 'b' COLLATE "C")) v(a,b);
QUERY: INSERT INTO vctable VALUES ('foo' COLLATE "C");
QUERY: CREATE VIEW collate_on_int AS
SELECT c1+1 AS c1p FROM
  (SELECT ('4' COLLATE "C")::INT AS c1) ss;

collate.icu.utf8

QUERY: SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc';
QUERY: SELECT * FROM collate_test1 WHERE b >= 'bbc' COLLATE "C";
QUERY: SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "C";
QUERY: SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C";
QUERY: SELECT 'bbc' COLLATE "sv-x-icu" > 'äbc' COLLATE "sv-x-icu" AS "false";
QUERY: SELECT a, lower(x COLLATE "C"), lower(y COLLATE "C") FROM collate_test10;
QUERY: SELECT b,
       b ~ '^[[:alpha:]]+$' AS is_alpha,
       b ~ '^[[:upper:]]+$' AS is_upper,
       b ~ '^[[:lower:]]+$' AS is_lower,
       b ~ '^[[:digit:]]+$' AS is_digit,
       b ~ '^[[:alnum:]]+$' AS is_alnum,
       b ~ '^[[:graph:]]+$' AS is_graph,
       b ~ '^[[:print:]]+$' AS is_print,
       b ~ '^[[:punct:]]+$' AS is_punct,
       b ~ '^[[:space:]]+$' AS is_space
FROM collate_test6;
QUERY: /* not run by default because it requires tr_TR system locale
-- to_char

SET lc_time TO 'tr_TR';
SELECT to_char(date '2010-04-01', 'DD TMMON YYYY');
SELECT to_char(date '2010-04-01', 'DD TMMON YYYY' COLLATE "tr-x-icu");
*/
-- backwards parsing
CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc';
QUERY: CREATE VIEW collview3 AS SELECT a, lower((x || x) COLLATE "C") FROM collate_test10;
QUERY: CREATE VIEW collate_dep_test3 AS SELECT text 'foo' COLLATE test0 AS foo;
QUERY: SELECT 'ὀδυσσεύς' = 'ὈΔΥΣΣΕΎΣ' COLLATE case_sensitive;
QUERY: SELECT * FROM test4 WHERE b = 'Cote' COLLATE ignore_accents;

infinite_recurse

QUERY: SELECT version() ~ 'powerpc64[^,]*-linux-gnu'
       AS skip_test 

psql

QUERY: SELECT amname AS "Name",
  CASE amtype WHEN 'i' THEN 'Index' WHEN 't' THEN 'Table' END AS "Type"
FROM pg_catalog.pg_am
WHERE amname OPERATOR(pg_catalog.~) '^(foo)$' COLLATE pg_catalog.default
ORDER BY 1;
QUERY: SELECT amname AS "Name",
  CASE amtype WHEN 'i' THEN 'Index' WHEN 't' THEN 'Table' END AS "Type"
FROM pg_catalog.pg_am
WHERE amname OPERATOR(pg_catalog.~) '^(foo)$' COLLATE pg_catalog.default
ORDER BY 1;
QUERY: SELECT amname AS "Name",
  CASE amtype WHEN 'i' THEN 'Index' WHEN 't' THEN 'Table' END AS "Type",
  amhandler AS "Handler",
  pg_catalog.obj_description(oid, 'pg_am') AS "Description"
FROM pg_catalog.pg_am
WHERE amname OPERATOR(pg_catalog.~) '^(foo)$' COLLATE pg_catalog.default
ORDER BY 1;
QUERY: SELECT amname AS "Name",
  CASE amtype WHEN 'i' THEN 'Index' WHEN 't' THEN 'Table' END AS "Type"
FROM pg_catalog.pg_am
WHERE amname OPERATOR(pg_catalog.~) E'^(no\\.such\\.access\\.method)$' COLLATE pg_catalog.default
ORDER BY 1;
QUERY: SELECT n.nspname as "Schema",
  c.relname as "Name",
  CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'm' THEN 'materialized view' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 't' THEN 'TOAST table' WHEN 'f' THEN 'foreign table' WHEN 'p' THEN 'partitioned table' WHEN 'I' THEN 'partitioned index' END as "Type",
  pg_catalog.pg_get_userbyid(c.relowner) as "Owner"
FROM pg_catalog.pg_class c
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('r','p','t','s','')
  AND c.relname OPERATOR(pg_catalog.~) E'^(no\\.such\\.table\\.relation)$' COLLATE pg_catalog.default
  AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 1,2;
QUERY: SELECT spcname AS "Name",
  pg_catalog.pg_get_userbyid(spcowner) AS "Owner",
  pg_catalog.pg_tablespace_location(oid) AS "Location"
FROM pg_catalog.pg_tablespace
WHERE spcname OPERATOR(pg_catalog.~) E'^(no\\.such\\.tablespace)$' COLLATE pg_catalog.default
ORDER BY 1;
QUERY: SELECT pg_catalog.pg_get_userbyid(d.defaclrole) AS "Owner",
  n.nspname AS "Schema",
  CASE d.defaclobjtype WHEN 'r' THEN 'table' WHEN 'S' THEN 'sequence' WHEN 'f' THEN 'function' WHEN 'T' THEN 'type' WHEN 'n' THEN 'schema' END AS "Type",
  pg_catalog.array_to_string(d.defaclacl, E'\n') AS "Access privileges"
FROM pg_catalog.pg_default_acl d
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = d.defaclnamespace
WHERE (n.nspname OPERATOR(pg_catalog.~) E'^(no\\.such\\.default\\.access\\.privilege)$' COLLATE pg_catalog.default
        OR pg_catalog.pg_get_userbyid(d.defaclrole) OPERATOR(pg_catalog.~) E'^(no\\.such\\.default\\.access\\.privilege)$' COLLATE pg_catalog.default)
ORDER BY 1, 2, 3;
QUERY: SELECT n.nspname as "Schema",
  c.relname as "Name",
  CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'm' THEN 'materialized view' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 't' THEN 'TOAST table' WHEN 'f' THEN 'foreign table' WHEN 'p' THEN 'partitioned table' WHEN 'I' THEN 'partitioned index' END as "Type",
  pg_catalog.pg_get_userbyid(c.relowner) as "Owner",
  c2.relname as "Table"
FROM pg_catalog.pg_class c
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
     LEFT JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid
     LEFT JOIN pg_catalog.pg_class c2 ON i.indrelid = c2.oid
WHERE c.relkind IN ('i','I','s','')
  AND c.relname OPERATOR(pg_catalog.~) E'^(no\\.such\\.index\\.relation)$' COLLATE pg_catalog.default
  AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 1,2;
QUERY: SELECT n.nspname as "Schema",
  c.relname as "Name",
  CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'm' THEN 'materialized view' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 't' THEN 'TOAST table' WHEN 'f' THEN 'foreign table' WHEN 'p' THEN 'partitioned table' WHEN 'I' THEN 'partitioned index' END as "Type",
  pg_catalog.pg_get_userbyid(c.relowner) as "Owner"
FROM pg_catalog.pg_class c
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('m','s','')
  AND c.relname OPERATOR(pg_catalog.~) E'^(no\\.such\\.materialized\\.view)$' COLLATE pg_catalog.default
  AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 1,2;
QUERY: SELECT n.nspname as "Schema",
  c.relname as "Name",
  CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'm' THEN 'materialized view' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 't' THEN 'TOAST table' WHEN 'f' THEN 'foreign table' WHEN 'p' THEN 'partitioned table' WHEN 'I' THEN 'partitioned index' END as "Type",
  pg_catalog.pg_get_userbyid(c.relowner) as "Owner"
FROM pg_catalog.pg_class c
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('S','s','')
  AND c.relname OPERATOR(pg_catalog.~) E'^(no\\.such\\.relation)$' COLLATE pg_catalog.default
  AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 1,2;
QUERY: SELECT n.nspname as "Schema",
  c.relname as "Name",
  CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'm' THEN 'materialized view' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 't' THEN 'TOAST table' WHEN 'f' THEN 'foreign table' WHEN 'p' THEN 'partitioned table' WHEN 'I' THEN 'partitioned index' END as "Type",
  pg_catalog.pg_get_userbyid(c.relowner) as "Owner"
FROM pg_catalog.pg_class c
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('r','p','t','s','')
  AND c.relname OPERATOR(pg_catalog.~) E'^(no\\.such\\.relation)$' COLLATE pg_catalog.default
  AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 1,2;
QUERY: SELECT n.nspname as "Schema",
  c.relname as "Name",
  CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'm' THEN 'materialized view' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 't' THEN 'TOAST table' WHEN 'f' THEN 'foreign table' WHEN 'p' THEN 'partitioned table' WHEN 'I' THEN 'partitioned index' END as "Type",
  pg_catalog.pg_get_userbyid(c.relowner) as "Owner"
FROM pg_catalog.pg_class c
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('v','s','')
  AND c.relname OPERATOR(pg_catalog.~) E'^(no\\.such\\.relation)$' COLLATE pg_catalog.default
  AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 1,2;
QUERY: SELECT s.srvname AS "Name",
  pg_catalog.pg_get_userbyid(s.srvowner) AS "Owner",
  f.fdwname AS "Foreign-data wrapper"
FROM pg_catalog.pg_foreign_server s
     JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid=s.srvfdw
WHERE s.srvname OPERATOR(pg_catalog.~) E'^(no\\.such\\.foreign\\.server)$' COLLATE pg_catalog.default
ORDER BY 1;

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
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.

Overall looks fine, not as bad as I expected it to be. However, if we can I would like to move the portion that I reference in the comment below.

@zachmu zachmu enabled auto-merge April 11, 2025 17:51
@zachmu zachmu merged commit 2719d33 into main Apr 11, 2025
14 checks passed
@zachmu zachmu deleted the zachmu/psql branch April 11, 2025 18:36
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