diff --git a/server/config/parameters_list.go b/server/config/parameters_list.go index 48d7b88755..9c004c1cbc 100644 --- a/server/config/parameters_list.go +++ b/server/config/parameters_list.go @@ -1361,6 +1361,17 @@ var postgresConfigParameters = map[string]sql.SystemVariable{ ResetVal: int64(1), Scope: GetPgsqlScope(PsqlScopeSession), }, + "force_parallel_mode": &Parameter{ + Name: "force_parallel_mode", + Default: "off", + Category: "Developer Options", + ShortDesc: "Forces use of parallel query facilities.", + Context: ParameterContextUser, + Type: types.NewSystemEnumType("force_parallel_mode", "off", "on", "regress"), + Source: ParameterSourceDefault, + ResetVal: "off", + Scope: GetPgsqlScope(PsqlScopeSession), + }, "from_collapse_limit": &Parameter{ Name: "from_collapse_limit", Default: int64(8), @@ -1827,6 +1838,28 @@ var postgresConfigParameters = map[string]sql.SystemVariable{ ResetVal: "FILE:/usr/local/etc/postgresql/krb5.keytab", Scope: GetPgsqlScope(PsqlScopeSession), }, + "lc_collate": &Parameter{ + Name: "lc_collate", + Default: "en_US.UTF-8", + Category: "Preset Options", + ShortDesc: "Shows the collation order locale.", + Context: ParameterContextInternal, + Type: types.NewSystemStringType("lc_collate"), + Source: ParameterSourceDefault, + ResetVal: "en_US.UTF-8", + Scope: GetPgsqlScope(PsqlScopeSession), + }, + "lc_ctype": &Parameter{ + Name: "lc_ctype", + Default: "en_US.UTF-8", + Category: "Preset Options", + ShortDesc: "Shows the character classification and case conversion locale.", + Context: ParameterContextInternal, + Type: types.NewSystemStringType("lc_ctype"), + Source: ParameterSourceDefault, + ResetVal: "en_US.UTF-8", + Scope: GetPgsqlScope(PsqlScopeSession), + }, "lc_messages": &Parameter{ Name: "lc_messages", Default: "en_US.UTF-8", @@ -2787,6 +2820,17 @@ var postgresConfigParameters = map[string]sql.SystemVariable{ ResetVal: "", Scope: GetPgsqlScope(PsqlScopeSession), }, + "promote_trigger_file": &Parameter{ + Name: "promote_trigger_file", + Default: "", + Category: "Replication / Standby Servers", + ShortDesc: "Specifies a file name whose presence ends recovery in the standby.", + Context: ParameterContextSighup, + Type: types.NewSystemStringType("promote_trigger_file"), + Source: ParameterSourceDefault, + ResetVal: "", + Scope: GetPgsqlScope(PsqlScopeSession), + }, "quote_all_identifiers": &Parameter{ Name: "quote_all_identifiers", Default: int8(0), @@ -2997,6 +3041,17 @@ var postgresConfigParameters = map[string]sql.SystemVariable{ ResetVal: "", Scope: GetPgsqlScope(PsqlScopeSession), }, + "restrict_nonsystem_relation_kind": &Parameter{ + Name: "restrict_nonsystem_relation_kind", + Default: "", + Category: "Client Connection Defaults / Statement Behavior", + ShortDesc: "Prohibits access to non-system relations of specified kinds.", + Context: ParameterContextUser, + Type: types.NewSystemStringType("restrict_nonsystem_relation_kind"), + Source: ParameterSourceDefault, + ResetVal: "", + Scope: GetPgsqlScope(PsqlScopeSession), + }, "row_security": &Parameter{ Name: "row_security", Default: int8(1), @@ -3909,6 +3964,18 @@ var postgresConfigParameters = map[string]sql.SystemVariable{ ResetVal: int64(2), Scope: GetPgsqlScope(PsqlScopeSession), }, + "vacuum_defer_cleanup_age": &Parameter{ + Name: "vacuum_defer_cleanup_age", + Default: int64(0), + Category: "Replication / Primary Server", + ShortDesc: "Number of transactions by which VACUUM and HOT cleanup should be deferred, if any.", + Context: ParameterContextSighup, + Type: types.NewSystemIntType("vacuum_defer_cleanup_age", 0, 1073741823, false), + Source: ParameterSourceDefault, + // min: 0 , max: 1000000 + ResetVal: int64(0), + Scope: GetPgsqlScope(PsqlScopeSession), + }, "vacuum_failsafe_age": &Parameter{ Name: "vacuum_failsafe_age", Default: int64(1600000000), diff --git a/server/functions/aclexplode.go b/server/functions/aclexplode.go new file mode 100644 index 0000000000..839c5cdac0 --- /dev/null +++ b/server/functions/aclexplode.go @@ -0,0 +1,50 @@ +// Copyright 2026 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" +) + +// initAclexplode registers the functions to the catalog. +func initAclexplode() { + framework.RegisterFunction(aclexplode) // TODO: This breaks pgAdmin 4 because of the unsupported aclitem[] type +} + +// aclexplodeName is the name for aclexplode function. +const aclexplodeName = "aclexplode" + +// aclexplode represents the PostgreSQL function of the same name, taking the same parameters. +var aclexplode = framework.Function1{ + Name: aclexplodeName, + Return: pgtypes.Record, // SETOF record + Parameters: [1]*pgtypes.DoltgresType{pgtypes.TextArray}, // TODO: type aclitem[] + Strict: true, + Callable: func(ctx *sql.Context, _ [2]*pgtypes.DoltgresType, val any) (any, error) { + return nil, nil + }, + OutParams: aclexplodeOutArgs, +} + +// aclexplodeOutArgs is the schema for aclexplode table function. Each column is OUT argument. +var aclexplodeOutArgs = sql.Schema{ + {Name: "grantor", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: aclexplodeName}, + {Name: "grantee", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: aclexplodeName}, + {Name: "privilege_type", Type: pgtypes.Text, Default: nil, Nullable: false, Source: aclexplodeName}, + {Name: "is_grantable", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: aclexplodeName}, +} diff --git a/server/functions/has_table_privilege.go b/server/functions/has_table_privilege.go new file mode 100644 index 0000000000..dd99c435f6 --- /dev/null +++ b/server/functions/has_table_privilege.go @@ -0,0 +1,104 @@ +// Copyright 2026 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" +) + +// initHasTablePrivilege registers the functions to the catalog. +func initHasTablePrivilege() { + framework.RegisterFunction(has_table_privilege_name_text_text) + framework.RegisterFunction(has_table_privilege_name_oid_text) + framework.RegisterFunction(has_table_privilege_oid_text_text) + framework.RegisterFunction(has_table_privilege_oid_oid_text) + framework.RegisterFunction(has_table_privilege_text_text) + framework.RegisterFunction(has_table_privilege_oid_text) +} + +// has_table_privilege_name_text_text represents the PostgreSQL function of the same name, taking the same parameters. +var has_table_privilege_name_text_text = framework.Function3{ + Name: "has_table_privilege", + Return: pgtypes.Bool, + Parameters: [3]*pgtypes.DoltgresType{pgtypes.Name, pgtypes.Text, pgtypes.Text}, + Strict: true, + Callable: func(ctx *sql.Context, _ [4]*pgtypes.DoltgresType, val1, val2, val3 any) (any, error) { + // TODO does user have privilege for schema + return true, nil + }, +} + +// has_table_privilege_name_oid_text represents the PostgreSQL function of the same name, taking the same parameters. +var has_table_privilege_name_oid_text = framework.Function3{ + Name: "has_table_privilege", + Return: pgtypes.Bool, + Parameters: [3]*pgtypes.DoltgresType{pgtypes.Name, pgtypes.Oid, pgtypes.Text}, + Strict: true, + Callable: func(ctx *sql.Context, _ [4]*pgtypes.DoltgresType, val1, val2, val3 any) (any, error) { + // TODO does user have privilege for schema + return true, nil + }, +} + +// has_table_privilege_oid_text_text represents the PostgreSQL function of the same name, taking the same parameters. +var has_table_privilege_oid_text_text = framework.Function3{ + Name: "has_table_privilege", + Return: pgtypes.Bool, + Parameters: [3]*pgtypes.DoltgresType{pgtypes.Oid, pgtypes.Text, pgtypes.Text}, + Strict: true, + Callable: func(ctx *sql.Context, _ [4]*pgtypes.DoltgresType, val1, val2, val3 any) (any, error) { + // TODO does user have privilege for schema + return true, nil + }, +} + +// has_table_privilege_oid_oid_text represents the PostgreSQL function of the same name, taking the same parameters. +var has_table_privilege_oid_oid_text = framework.Function3{ + Name: "has_table_privilege", + Return: pgtypes.Bool, + Parameters: [3]*pgtypes.DoltgresType{pgtypes.Oid, pgtypes.Oid, pgtypes.Text}, + Strict: true, + Callable: func(ctx *sql.Context, _ [4]*pgtypes.DoltgresType, val1, val2, val3 any) (any, error) { + // TODO does user have privilege for schema + return true, nil + }, +} + +// has_table_privilege_text_text represents the PostgreSQL function of the same name, taking the same parameters. +var has_table_privilege_text_text = framework.Function2{ + Name: "has_table_privilege", + Return: pgtypes.Bool, + Parameters: [2]*pgtypes.DoltgresType{pgtypes.Text, pgtypes.Text}, + Strict: true, + Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1, val2 any) (any, error) { + // TODO does current user have privilege for schema + return true, nil + }, +} + +// has_table_privilege_oid_text represents the PostgreSQL function of the same name, taking the same parameters. +var has_table_privilege_oid_text = framework.Function2{ + Name: "has_table_privilege", + Return: pgtypes.Bool, + Parameters: [2]*pgtypes.DoltgresType{pgtypes.Oid, pgtypes.Text}, + Strict: true, + Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1, val2 any) (any, error) { + // TODO does current user have privilege for schema + return true, nil + }, +} diff --git a/server/functions/init.go b/server/functions/init.go index 3f2a2fb445..8cbd0ee73a 100644 --- a/server/functions/init.go +++ b/server/functions/init.go @@ -73,6 +73,7 @@ func initTypeFunctions() { func Init() { initTypeFunctions() initAbs() + initAclexplode() initAcos() initAcosd() initAcosh() @@ -125,6 +126,7 @@ func Init() { initGetdatabaseencoding() initHasDatabasePrivilege() initHasSchemaPrivilege() + initHasTablePrivilege() initInitcap() initLcm() initLeft() @@ -145,6 +147,7 @@ func Init() { initOctetLength() initPgAvailableExtensionVersions() initPgBackendPid() + initPgBlockingPids() initPgCharToEncoding() initPgCollationIsVisible() initPgConversionIsVisible() @@ -158,6 +161,7 @@ func Init() { initPgGetFunctionResult() initPgGetFunctionSqlbody() initPgGetIndexDef() + initPgGetKeywords() initPgGetPartKeyDef() initPgGetRuledef() initPgGetTriggerDef() diff --git a/server/functions/pg_blocking_pids.go b/server/functions/pg_blocking_pids.go new file mode 100644 index 0000000000..c25a0e1a82 --- /dev/null +++ b/server/functions/pg_blocking_pids.go @@ -0,0 +1,39 @@ +// Copyright 2026 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" +) + +// initPgBlockingPids registers the functions to the catalog. +func initPgBlockingPids() { + framework.RegisterFunction(pg_blocking_pids) +} + +// pg_blocking_pids represents the PostgreSQL system catalog information function. +var pg_blocking_pids = framework.Function1{ + Name: "pg_blocking_pids", + Return: pgtypes.Int32Array, + Parameters: [1]*pgtypes.DoltgresType{pgtypes.Int32}, + Strict: true, + Callable: func(ctx *sql.Context, _ [2]*pgtypes.DoltgresType, val any) (any, error) { + // TODO + return nil, nil + }, +} diff --git a/server/functions/pg_get_keywords.go b/server/functions/pg_get_keywords.go new file mode 100644 index 0000000000..c80236ecd7 --- /dev/null +++ b/server/functions/pg_get_keywords.go @@ -0,0 +1,133 @@ +// Copyright 2026 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 ( + "io" + + "github.com/dolthub/go-mysql-server/sql" + + "github.com/dolthub/doltgresql/postgres/parser/lex" + "github.com/dolthub/doltgresql/server/functions/framework" + pgtypes "github.com/dolthub/doltgresql/server/types" +) + +// initPgGetKeywords registers the functions to the catalog. +func initPgGetKeywords() { + framework.RegisterFunction(pg_get_keywords) +} + +// pgGetKeywordsName is the name for pg_get_keywords function. +const pgGetKeywordsName = "pg_get_keywords" + +// pg_get_keywords represents the PostgreSQL system catalog information function. +var pg_get_keywords = framework.Function0{ + Name: pgGetKeywordsName, + Return: pgtypes.Text, + IsNonDeterministic: true, + Strict: true, + Callable: func(ctx *sql.Context) (any, error) { + i := 0 + count := len(lex.KeywordNames) + return pgtypes.NewSetReturningFunctionRowIter(func(ctx *sql.Context) (sql.Row, error) { + defer func() { i++ }() + + if i >= count { + return nil, io.EOF + } + + keyword := lex.KeywordNames[i] + catCode := lex.KeywordsCategories[keyword] + catDesc := "" + switch catCode { + case "U": + catDesc = "unreserved" + case "R": + catDesc = "reserved" + case "T": + catDesc = "reserved (can be function or type name)" + case "C": + catDesc = "unreserved (cannot be function or type name)" + } + _, ok := keywordsRequiresAs[keyword] + bareLabel := !ok + bareDesc := "can be bare label" + if !bareLabel { + bareDesc = "requires AS" + } + + return sql.Row{ + keyword, // word + catCode, // catcode + bareLabel, // barelabel + catDesc, // catdesc + bareDesc, // baredesc + }, nil + }), nil + }, + OutParams: pgGetKeywordsOutArgs, +} + +// pgGetKeywordsOutArgs is the schema for pg_get_keywords table function. Each column is OUT argument. +var pgGetKeywordsOutArgs = sql.Schema{ + {Name: "word", Type: pgtypes.Text, Default: nil, Nullable: false, Source: pgGetKeywordsName}, + {Name: "catcode", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: pgGetKeywordsName}, + {Name: "barelabel", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: pgGetKeywordsName}, + {Name: "catdesc", Type: pgtypes.Text, Default: nil, Nullable: false, Source: pgGetKeywordsName}, + {Name: "baredesc", Type: pgtypes.Text, Default: nil, Nullable: false, Source: pgGetKeywordsName}, +} + +// keywordsRequiresAs is a list of keywords that requires AS (cannot be bare label). +var keywordsRequiresAs = map[string]struct{}{ + "array": {}, + "as": {}, + "char": {}, + "character": {}, + "create": {}, + "day": {}, + "except": {}, + "fetch": {}, + "filter": {}, + "for": {}, + "from": {}, + "grant": {}, + "group": {}, + "having": {}, + "hour": {}, + "intersect": {}, + "into": {}, + "isnull": {}, + "limit": {}, + "minute": {}, + "month": {}, + "notnull": {}, + "offset": {}, + "on": {}, + "order": {}, + "over": {}, + "overlaps": {}, + "precision": {}, + "returning": {}, + "second": {}, + "to": {}, + "union": {}, + "varying": {}, + "where": {}, + "window": {}, + "with": {}, + "within": {}, + "without": {}, + "year": {}, +}