From ae9821f1eb7fbd2d808381b6d24fa405f3d91828 Mon Sep 17 00:00:00 2001 From: Taylor Bantle Date: Mon, 15 Jul 2024 15:16:52 -0700 Subject: [PATCH 1/5] Add obj_description function --- server/functions/init.go | 1 + server/functions/obj_description.go | 42 +++++++++++++++++++++++++++ testing/go/functions_test.go | 12 ++++++++ testing/go/information_schema_test.go | 13 +++++++-- 4 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 server/functions/obj_description.go diff --git a/server/functions/init.go b/server/functions/init.go index 4907100adb..17075f2de8 100644 --- a/server/functions/init.go +++ b/server/functions/init.go @@ -64,6 +64,7 @@ func Init() { initMinScale() initMod() initNextVal() + initObjDescription() initOctetLength() initPi() initPower() diff --git a/server/functions/obj_description.go b/server/functions/obj_description.go new file mode 100644 index 0000000000..79aba73896 --- /dev/null +++ b/server/functions/obj_description.go @@ -0,0 +1,42 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import ( + "github.com/dolthub/go-mysql-server/sql" + + "github.com/dolthub/doltgresql/server/functions/framework" + pgtypes "github.com/dolthub/doltgresql/server/types" +) + +// initObjDescription registers the functions to the catalog. +func initObjDescription() { + framework.RegisterFunction(obj_description) +} + +// obj_description represents the PostgreSQL function of the same name, taking the same parameters. +var obj_description = framework.Function2{ + Name: "obj_description", + Return: pgtypes.Text, + Parameters: [2]pgtypes.DoltgresType{pgtypes.Oid, pgtypes.Name}, + IsNonDeterministic: true, + Strict: true, + Callable: func(ctx *sql.Context, _ [3]pgtypes.DoltgresType, val1 any, val2 any) (any, error) { + // TODO: When we support comments this should return the comment for a + // database object specified by its OID and the name of the containing + // system catalog. + return "", nil + }, +} diff --git a/testing/go/functions_test.go b/testing/go/functions_test.go index d929448476..23d392d838 100644 --- a/testing/go/functions_test.go +++ b/testing/go/functions_test.go @@ -434,5 +434,17 @@ func TestSystemInformationFunctions(t *testing.T) { }, }, }, + { + Name: "obj_description", + Assertions: []ScriptTestAssertion{ + { + Query: `SELECT obj_description(100, 'pg_class');`, + Cols: []string{"obj_description"}, + Expected: []sql.Row{ + {""}, + }, + }, + }, + }, }) } diff --git a/testing/go/information_schema_test.go b/testing/go/information_schema_test.go index c0fa51663f..e6589dbaca 100644 --- a/testing/go/information_schema_test.go +++ b/testing/go/information_schema_test.go @@ -34,13 +34,15 @@ func TestInfoSchemaTables(t *testing.T) { { Name: "information_schema.tables", SetUpScript: []string{ - "create table test_table (id int)", + "create schema test_schema;", + "SET search_path TO test_schema;", + "create table test_table (id int);", }, Assertions: []ScriptTestAssertion{ { Query: `SELECT DISTINCT table_schema FROM information_schema.tables order by table_schema;`, Expected: []sql.Row{ - {"information_schema"}, {"pg_catalog"}, {"public"}, + {"information_schema"}, {"pg_catalog"}, {"test_schema"}, }, }, { @@ -48,7 +50,7 @@ func TestInfoSchemaTables(t *testing.T) { Expected: []sql.Row{ {"postgres", "information_schema"}, {"postgres", "pg_catalog"}, - {"postgres", "public"}, + {"postgres", "test_schema"}, }, }, { @@ -56,6 +58,11 @@ func TestInfoSchemaTables(t *testing.T) { Query: "SELECT * FROM PG_catalog.pg_AGGREGATE ORDER BY aggfnoid;", Expected: []sql.Row{}, }, + { + Skip: true, // TODO: regclass failing here + Query: `SELECT "table_schema", "table_name", ('"' || "table_schema" || '"."' || "table_name" || '"')::regclass AS table_oid FROM "information_schema"."tables" WHERE ("table_schema" = 'test_schema' AND "table_name" = 'test_table');`, + Expected: []sql.Row{{"test_schema", "test_table", ""}}, + }, }, }, }) From f06f41cee9e7c2fd7cbc37b6051fa470749ce6eb Mon Sep 17 00:00:00 2001 From: Taylor Bantle Date: Mon, 15 Jul 2024 16:12:55 -0700 Subject: [PATCH 2/5] Add col_description function --- server/functions/col_description.go | 41 +++++++++++++++++++++++++++++ server/functions/init.go | 1 + testing/go/functions_test.go | 12 +++++++++ 3 files changed, 54 insertions(+) create mode 100644 server/functions/col_description.go diff --git a/server/functions/col_description.go b/server/functions/col_description.go new file mode 100644 index 0000000000..b4618ac088 --- /dev/null +++ b/server/functions/col_description.go @@ -0,0 +1,41 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import ( + "github.com/dolthub/go-mysql-server/sql" + + "github.com/dolthub/doltgresql/server/functions/framework" + pgtypes "github.com/dolthub/doltgresql/server/types" +) + +// initColDescription registers the functions to the catalog. +func initColDescription() { + framework.RegisterFunction(col_description) +} + +// col_description represents the PostgreSQL function of the same name, taking the same parameters. +var col_description = framework.Function2{ + Name: "col_description", + Return: pgtypes.Text, + Parameters: [2]pgtypes.DoltgresType{pgtypes.Oid, pgtypes.Int32}, + IsNonDeterministic: true, + Strict: true, + Callable: func(ctx *sql.Context, _ [3]pgtypes.DoltgresType, val1 any, val2 any) (any, error) { + // TODO: When we support comments this should return the comment for a table + // column, which is specified by the OID of its table and its column number + return "", nil + }, +} diff --git a/server/functions/init.go b/server/functions/init.go index 17075f2de8..9b4f96b687 100644 --- a/server/functions/init.go +++ b/server/functions/init.go @@ -36,6 +36,7 @@ func Init() { initCeil() initCharLength() initChr() + initColDescription() initCos() initCosd() initCosh() diff --git a/testing/go/functions_test.go b/testing/go/functions_test.go index 23d392d838..a78c009f81 100644 --- a/testing/go/functions_test.go +++ b/testing/go/functions_test.go @@ -434,6 +434,18 @@ func TestSystemInformationFunctions(t *testing.T) { }, }, }, + { + Name: "col_description", + Assertions: []ScriptTestAssertion{ + { + Query: `SELECT col_description(100, 1);`, + Cols: []string{"col_description"}, + Expected: []sql.Row{ + {""}, + }, + }, + }, + }, { Name: "obj_description", Assertions: []ScriptTestAssertion{ From a042dfdc1fab7234a0624b7944c0897ca0024839 Mon Sep 17 00:00:00 2001 From: Taylor Bantle Date: Mon, 15 Jul 2024 16:16:47 -0700 Subject: [PATCH 3/5] Add shobj_description function --- server/functions/init.go | 1 + server/functions/shobj_description.go | 42 +++++++++++++++++++++++++++ testing/go/functions_test.go | 12 ++++++++ 3 files changed, 55 insertions(+) create mode 100644 server/functions/shobj_description.go diff --git a/server/functions/init.go b/server/functions/init.go index 9b4f96b687..d7ed12bdd0 100644 --- a/server/functions/init.go +++ b/server/functions/init.go @@ -80,6 +80,7 @@ func Init() { initRtrim() initScale() initSetVal() + initShobjDescription() initSign() initSin() initSind() diff --git a/server/functions/shobj_description.go b/server/functions/shobj_description.go new file mode 100644 index 0000000000..1b2f355a2b --- /dev/null +++ b/server/functions/shobj_description.go @@ -0,0 +1,42 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import ( + "github.com/dolthub/go-mysql-server/sql" + + "github.com/dolthub/doltgresql/server/functions/framework" + pgtypes "github.com/dolthub/doltgresql/server/types" +) + +// initShobjDescription registers the functions to the catalog. +func initShobjDescription() { + framework.RegisterFunction(shobj_description) +} + +// shobj_description represents the PostgreSQL function of the same name, taking the same parameters. +var shobj_description = framework.Function2{ + Name: "shobj_description", + Return: pgtypes.Text, + Parameters: [2]pgtypes.DoltgresType{pgtypes.Oid, pgtypes.Name}, + IsNonDeterministic: true, + Strict: true, + Callable: func(ctx *sql.Context, _ [3]pgtypes.DoltgresType, val1 any, val2 any) (any, error) { + // TODO: When we support comments this should return the comment for a + // shared database object specified by its OID and the name of the + // containing system catalog. + return "", nil + }, +} diff --git a/testing/go/functions_test.go b/testing/go/functions_test.go index a78c009f81..f5a8ce071a 100644 --- a/testing/go/functions_test.go +++ b/testing/go/functions_test.go @@ -458,5 +458,17 @@ func TestSystemInformationFunctions(t *testing.T) { }, }, }, + { + Name: "shobj_description", + Assertions: []ScriptTestAssertion{ + { + Query: `SELECT shobj_description(100, 'pg_class');`, + Cols: []string{"shobj_description"}, + Expected: []sql.Row{ + {""}, + }, + }, + }, + }, }) } From c3a6941001c48ec01bd0c4414c3b180460cc88db Mon Sep 17 00:00:00 2001 From: Taylor Bantle Date: Tue, 16 Jul 2024 10:29:15 -0700 Subject: [PATCH 4/5] Remove test --- testing/go/information_schema_test.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/testing/go/information_schema_test.go b/testing/go/information_schema_test.go index e6589dbaca..a4dc0e13af 100644 --- a/testing/go/information_schema_test.go +++ b/testing/go/information_schema_test.go @@ -58,11 +58,6 @@ func TestInfoSchemaTables(t *testing.T) { Query: "SELECT * FROM PG_catalog.pg_AGGREGATE ORDER BY aggfnoid;", Expected: []sql.Row{}, }, - { - Skip: true, // TODO: regclass failing here - Query: `SELECT "table_schema", "table_name", ('"' || "table_schema" || '"."' || "table_name" || '"')::regclass AS table_oid FROM "information_schema"."tables" WHERE ("table_schema" = 'test_schema' AND "table_name" = 'test_table');`, - Expected: []sql.Row{{"test_schema", "test_table", ""}}, - }, }, }, }) From a107d5c466b6283c36943eb1dfd1a52cecb1a4d2 Mon Sep 17 00:00:00 2001 From: Taylor Bantle Date: Tue, 16 Jul 2024 12:10:36 -0700 Subject: [PATCH 5/5] Fix tests --- testing/go/functions_test.go | 57 +++++++++++++++++++++++++++ testing/go/information_schema_test.go | 47 +++++++++++++++++++--- 2 files changed, 99 insertions(+), 5 deletions(-) diff --git a/testing/go/functions_test.go b/testing/go/functions_test.go index f5a8ce071a..2df499fbfe 100644 --- a/testing/go/functions_test.go +++ b/testing/go/functions_test.go @@ -444,6 +444,27 @@ func TestSystemInformationFunctions(t *testing.T) { {""}, }, }, + { + Query: `SELECT col_description('not_a_table'::regclass, 1);`, + ExpectedErr: `relation "not_a_table" does not exist`, + }, + { + Query: `CREATE TABLE test_table (id INT);`, + Expected: []sql.Row{}, + }, + { + Skip: true, // TODO: Implement column comments + Query: `COMMENT ON COLUMN test_table.id IS 'This is col id';`, + Expected: []sql.Row{}, + }, + { + Skip: true, // TODO: Implement column object comments + Query: `SELECT col_description('test_table'::regclass, 1);`, + Cols: []string{"col_description"}, + Expected: []sql.Row{ + {"This is col id"}, + }, + }, }, }, { @@ -456,6 +477,18 @@ func TestSystemInformationFunctions(t *testing.T) { {""}, }, }, + { + Query: `SELECT obj_description('does-not-exist'::regproc, 'pg_class');`, + ExpectedErr: `function "does-not-exist" does not exist`, + }, + { + Skip: true, // TODO: Implement database object comments + Query: `SELECT obj_description('sinh'::regproc, 'pg_proc');`, + Cols: []string{"col_description"}, + Expected: []sql.Row{ + {"hyperbolic sine"}, + }, + }, }, }, { @@ -468,6 +501,30 @@ func TestSystemInformationFunctions(t *testing.T) { {""}, }, }, + { + Query: `SELECT shobj_description('does-not-exist'::regproc, 'pg_class');`, + ExpectedErr: `function "does-not-exist" does not exist`, + }, + { + Skip: true, // TODO: Implement tablespaces + Query: `CREATE TABLESPACE tblspc_2 LOCATION '/';`, + Expected: []sql.Row{}, + }, + { + Skip: true, // TODO: Implement shared database object comments + Query: `COMMENT ON TABLESPACE tblspc_2 IS 'Store a few of the things';`, + Expected: []sql.Row{}, + }, + { + Skip: true, // TODO: Implement shared database object comments + Query: `SELECT shobj_description( + (SELECT oid FROM pg_tablespace WHERE spcname = 'tblspc_2'), + 'pg_tablespace');`, + Cols: []string{"shobj_description"}, + Expected: []sql.Row{ + {"Store a few of the things"}, + }, + }, }, }, }) diff --git a/testing/go/information_schema_test.go b/testing/go/information_schema_test.go index a4dc0e13af..3d2f802f53 100644 --- a/testing/go/information_schema_test.go +++ b/testing/go/information_schema_test.go @@ -34,15 +34,13 @@ func TestInfoSchemaTables(t *testing.T) { { Name: "information_schema.tables", SetUpScript: []string{ - "create schema test_schema;", - "SET search_path TO test_schema;", - "create table test_table (id int);", + "create table test_table (id int)", }, Assertions: []ScriptTestAssertion{ { Query: `SELECT DISTINCT table_schema FROM information_schema.tables order by table_schema;`, Expected: []sql.Row{ - {"information_schema"}, {"pg_catalog"}, {"test_schema"}, + {"information_schema"}, {"pg_catalog"}, {"public"}, }, }, { @@ -50,12 +48,51 @@ func TestInfoSchemaTables(t *testing.T) { Expected: []sql.Row{ {"postgres", "information_schema"}, {"postgres", "pg_catalog"}, + {"postgres", "public"}, + }, + }, + { + Query: `SELECT table_catalog, table_schema, table_name FROM information_schema.tables WHERE table_schema='public';`, + Expected: []sql.Row{ + {"postgres", "public", "test_table"}, + }, + }, + { + Query: `CREATE SCHEMA test_schema;`, + Expected: []sql.Row{}, + }, + { + Query: `SET SEARCH_PATH TO test_schema;`, + Expected: []sql.Row{}, + }, + { + Query: `CREATE TABLE test_table2 (id INT);`, + Expected: []sql.Row{}, + }, + { + Query: `SELECT DISTINCT table_schema FROM information_schema.tables order by table_schema;`, + Expected: []sql.Row{ + {"information_schema"}, {"pg_catalog"}, {"public"}, {"test_schema"}, + }, + }, + { + Query: `SELECT table_catalog, table_schema FROM information_schema.tables group by table_catalog, table_schema order by table_schema;`, + Expected: []sql.Row{ + {"postgres", "information_schema"}, + {"postgres", "pg_catalog"}, + {"postgres", "public"}, {"postgres", "test_schema"}, }, }, + { + Query: `SELECT table_catalog, table_schema, table_name FROM information_schema.tables WHERE table_schema='test_schema';`, + Expected: []sql.Row{ + {"postgres", "test_schema", "test_table2"}, + }, + }, { Skip: true, // TODO: need ENUM type for table_type column - Query: "SELECT * FROM PG_catalog.pg_AGGREGATE ORDER BY aggfnoid;", + Query: "SELECT * FROM information_schema.tables ORDER BY table_name;", Expected: []sql.Row{}, }, },