From e80949372564c126c92aa7d64de483e04c0ef95e Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 16 Apr 2021 18:20:42 -0400 Subject: [PATCH] Split function definitions out of system_views.sql into a new file. Invent system_functions.sql to carry the function definitions that were formerly in system_views.sql. The function definitions were already a quarter of the file and are about to be more, so it seems appropriate to give them their own home. In passing, fix an oversight in dfb75e478: it neglected to call check_input() for system_constraints.sql. Discussion: https://postgr.es/m/3956760.1618529139@sss.pgh.pa.us --- src/backend/catalog/Makefile | 3 +- src/backend/catalog/system_functions.sql | 392 +++++++++++++++++++++++ src/backend/catalog/system_views.sql | 381 +--------------------- src/bin/initdb/initdb.c | 6 + 4 files changed, 401 insertions(+), 381 deletions(-) create mode 100644 src/backend/catalog/system_functions.sql diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile index e36a9602c1..69f9dd51a7 100644 --- a/src/backend/catalog/Makefile +++ b/src/backend/catalog/Makefile @@ -122,6 +122,7 @@ $(top_builddir)/src/include/catalog/header-stamp: bki-stamp install-data: bki-stamp installdirs $(INSTALL_DATA) $(call vpathsearch,postgres.bki) '$(DESTDIR)$(datadir)/postgres.bki' $(INSTALL_DATA) $(call vpathsearch,system_constraints.sql) '$(DESTDIR)$(datadir)/system_constraints.sql' + $(INSTALL_DATA) $(srcdir)/system_functions.sql '$(DESTDIR)$(datadir)/system_functions.sql' $(INSTALL_DATA) $(srcdir)/system_views.sql '$(DESTDIR)$(datadir)/system_views.sql' $(INSTALL_DATA) $(srcdir)/information_schema.sql '$(DESTDIR)$(datadir)/information_schema.sql' $(INSTALL_DATA) $(srcdir)/sql_features.txt '$(DESTDIR)$(datadir)/sql_features.txt' @@ -131,7 +132,7 @@ installdirs: .PHONY: uninstall-data uninstall-data: - rm -f $(addprefix '$(DESTDIR)$(datadir)'/, postgres.bki system_constraints.sql system_views.sql information_schema.sql sql_features.txt) + rm -f $(addprefix '$(DESTDIR)$(datadir)'/, postgres.bki system_constraints.sql system_functions.sql system_views.sql information_schema.sql sql_features.txt) # postgres.bki, system_constraints.sql, and the generated headers are # in the distribution tarball, so they are not cleaned here. diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql new file mode 100644 index 0000000000..d7ac7a926e --- /dev/null +++ b/src/backend/catalog/system_functions.sql @@ -0,0 +1,392 @@ +/* + * PostgreSQL System Functions + * + * Copyright (c) 1996-2021, PostgreSQL Global Development Group + * + * src/backend/catalog/system_functions.sql + * + * This file redefines certain built-in functions that it's impractical + * to fully define in pg_proc.dat. In most cases that's because they use + * SQL-standard function bodies and/or default expressions. The node + * tree representations of those are too unreadable, platform-dependent, + * and changeable to want to deal with them manually. Hence, we put stub + * definitions of such functions into pg_proc.dat and then replace them + * here. The stub definitions would be unnecessary were it not that we'd + * like these functions to have stable OIDs, the same as other built-in + * functions. + * + * This file also takes care of adjusting privileges for those functions + * that should not have the default public-EXECUTE privileges. (However, + * a small number of functions that exist mainly to underlie system views + * are dealt with in system_views.sql, instead.) + * + * Note: this file is read in single-user -j mode, which means that the + * command terminator is semicolon-newline-newline; whenever the backend + * sees that, it stops and executes what it's got. If you write a lot of + * statements without empty lines between, they'll all get quoted to you + * in any error message about one of them, so don't do that. Also, you + * cannot write a semicolon immediately followed by an empty line in a + * string literal (including a function body!) or a multiline comment. + */ + + +CREATE FUNCTION ts_debug(IN config regconfig, IN document text, + OUT alias text, + OUT description text, + OUT token text, + OUT dictionaries regdictionary[], + OUT dictionary regdictionary, + OUT lexemes text[]) +RETURNS SETOF record AS +$$ +SELECT + tt.alias AS alias, + tt.description AS description, + parse.token AS token, + ARRAY ( SELECT m.mapdict::pg_catalog.regdictionary + FROM pg_catalog.pg_ts_config_map AS m + WHERE m.mapcfg = $1 AND m.maptokentype = parse.tokid + ORDER BY m.mapseqno ) + AS dictionaries, + ( SELECT mapdict::pg_catalog.regdictionary + FROM pg_catalog.pg_ts_config_map AS m + WHERE m.mapcfg = $1 AND m.maptokentype = parse.tokid + ORDER BY pg_catalog.ts_lexize(mapdict, parse.token) IS NULL, m.mapseqno + LIMIT 1 + ) AS dictionary, + ( SELECT pg_catalog.ts_lexize(mapdict, parse.token) + FROM pg_catalog.pg_ts_config_map AS m + WHERE m.mapcfg = $1 AND m.maptokentype = parse.tokid + ORDER BY pg_catalog.ts_lexize(mapdict, parse.token) IS NULL, m.mapseqno + LIMIT 1 + ) AS lexemes +FROM pg_catalog.ts_parse( + (SELECT cfgparser FROM pg_catalog.pg_ts_config WHERE oid = $1 ), $2 + ) AS parse, + pg_catalog.ts_token_type( + (SELECT cfgparser FROM pg_catalog.pg_ts_config WHERE oid = $1 ) + ) AS tt +WHERE tt.tokid = parse.tokid +$$ +LANGUAGE SQL STRICT STABLE PARALLEL SAFE; + +COMMENT ON FUNCTION ts_debug(regconfig,text) IS + 'debug function for text search configuration'; + +CREATE FUNCTION ts_debug(IN document text, + OUT alias text, + OUT description text, + OUT token text, + OUT dictionaries regdictionary[], + OUT dictionary regdictionary, + OUT lexemes text[]) +RETURNS SETOF record AS +$$ + SELECT * FROM pg_catalog.ts_debug( pg_catalog.get_current_ts_config(), $1); +$$ +LANGUAGE SQL STRICT STABLE PARALLEL SAFE; + +COMMENT ON FUNCTION ts_debug(text) IS + 'debug function for current text search configuration'; + + +CREATE OR REPLACE FUNCTION + pg_start_backup(label text, fast boolean DEFAULT false, exclusive boolean DEFAULT true) + RETURNS pg_lsn STRICT VOLATILE LANGUAGE internal AS 'pg_start_backup' + PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION pg_stop_backup ( + exclusive boolean, wait_for_archive boolean DEFAULT true, + OUT lsn pg_lsn, OUT labelfile text, OUT spcmapfile text) + RETURNS SETOF record STRICT VOLATILE LANGUAGE internal as 'pg_stop_backup_v2' + PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION + pg_promote(wait boolean DEFAULT true, wait_seconds integer DEFAULT 60) + RETURNS boolean STRICT VOLATILE LANGUAGE INTERNAL AS 'pg_promote' + PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION + pg_terminate_backend(pid integer, timeout int8 DEFAULT 0) + RETURNS boolean STRICT VOLATILE LANGUAGE INTERNAL AS 'pg_terminate_backend' + PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION + pg_wait_for_backend_termination(pid integer, timeout int8 DEFAULT 5000) + RETURNS boolean STRICT VOLATILE LANGUAGE INTERNAL AS 'pg_wait_for_backend_termination' + PARALLEL SAFE; + +-- legacy definition for compatibility with 9.3 +CREATE OR REPLACE FUNCTION + json_populate_record(base anyelement, from_json json, use_json_as_text boolean DEFAULT false) + RETURNS anyelement LANGUAGE internal STABLE AS 'json_populate_record' PARALLEL SAFE; + +-- legacy definition for compatibility with 9.3 +CREATE OR REPLACE FUNCTION + json_populate_recordset(base anyelement, from_json json, use_json_as_text boolean DEFAULT false) + RETURNS SETOF anyelement LANGUAGE internal STABLE ROWS 100 AS 'json_populate_recordset' PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION pg_logical_slot_get_changes( + IN slot_name name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}', + OUT lsn pg_lsn, OUT xid xid, OUT data text) +RETURNS SETOF RECORD +LANGUAGE INTERNAL +VOLATILE ROWS 1000 COST 1000 +AS 'pg_logical_slot_get_changes'; + +CREATE OR REPLACE FUNCTION pg_logical_slot_peek_changes( + IN slot_name name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}', + OUT lsn pg_lsn, OUT xid xid, OUT data text) +RETURNS SETOF RECORD +LANGUAGE INTERNAL +VOLATILE ROWS 1000 COST 1000 +AS 'pg_logical_slot_peek_changes'; + +CREATE OR REPLACE FUNCTION pg_logical_slot_get_binary_changes( + IN slot_name name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}', + OUT lsn pg_lsn, OUT xid xid, OUT data bytea) +RETURNS SETOF RECORD +LANGUAGE INTERNAL +VOLATILE ROWS 1000 COST 1000 +AS 'pg_logical_slot_get_binary_changes'; + +CREATE OR REPLACE FUNCTION pg_logical_slot_peek_binary_changes( + IN slot_name name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}', + OUT lsn pg_lsn, OUT xid xid, OUT data bytea) +RETURNS SETOF RECORD +LANGUAGE INTERNAL +VOLATILE ROWS 1000 COST 1000 +AS 'pg_logical_slot_peek_binary_changes'; + +CREATE OR REPLACE FUNCTION pg_create_physical_replication_slot( + IN slot_name name, IN immediately_reserve boolean DEFAULT false, + IN temporary boolean DEFAULT false, + OUT slot_name name, OUT lsn pg_lsn) +RETURNS RECORD +LANGUAGE INTERNAL +STRICT VOLATILE +AS 'pg_create_physical_replication_slot'; + +CREATE OR REPLACE FUNCTION pg_create_logical_replication_slot( + IN slot_name name, IN plugin name, + IN temporary boolean DEFAULT false, + IN twophase boolean DEFAULT false, + OUT slot_name name, OUT lsn pg_lsn) +RETURNS RECORD +LANGUAGE INTERNAL +STRICT VOLATILE +AS 'pg_create_logical_replication_slot'; + +CREATE OR REPLACE FUNCTION + make_interval(years int4 DEFAULT 0, months int4 DEFAULT 0, weeks int4 DEFAULT 0, + days int4 DEFAULT 0, hours int4 DEFAULT 0, mins int4 DEFAULT 0, + secs double precision DEFAULT 0.0) +RETURNS interval +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'make_interval'; + +CREATE OR REPLACE FUNCTION + jsonb_set(jsonb_in jsonb, path text[] , replacement jsonb, + create_if_missing boolean DEFAULT true) +RETURNS jsonb +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_set'; + +CREATE OR REPLACE FUNCTION + jsonb_set_lax(jsonb_in jsonb, path text[] , replacement jsonb, + create_if_missing boolean DEFAULT true, + null_value_treatment text DEFAULT 'use_json_null') +RETURNS jsonb +LANGUAGE INTERNAL +CALLED ON NULL INPUT IMMUTABLE PARALLEL SAFE +AS 'jsonb_set_lax'; + +CREATE OR REPLACE FUNCTION + parse_ident(str text, strict boolean DEFAULT true) +RETURNS text[] +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'parse_ident'; + +CREATE OR REPLACE FUNCTION + jsonb_insert(jsonb_in jsonb, path text[] , replacement jsonb, + insert_after boolean DEFAULT false) +RETURNS jsonb +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_insert'; + +CREATE OR REPLACE FUNCTION + jsonb_path_exists(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS boolean +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_path_exists'; + +CREATE OR REPLACE FUNCTION + jsonb_path_match(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS boolean +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_path_match'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS SETOF jsonb +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_path_query'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query_array(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS jsonb +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_path_query_array'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query_first(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS jsonb +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_path_query_first'; + +CREATE OR REPLACE FUNCTION + jsonb_path_exists_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS boolean +LANGUAGE INTERNAL +STRICT STABLE PARALLEL SAFE +AS 'jsonb_path_exists_tz'; + +CREATE OR REPLACE FUNCTION + jsonb_path_match_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS boolean +LANGUAGE INTERNAL +STRICT STABLE PARALLEL SAFE +AS 'jsonb_path_match_tz'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS SETOF jsonb +LANGUAGE INTERNAL +STRICT STABLE PARALLEL SAFE +AS 'jsonb_path_query_tz'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query_array_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS jsonb +LANGUAGE INTERNAL +STRICT STABLE PARALLEL SAFE +AS 'jsonb_path_query_array_tz'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query_first_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS jsonb +LANGUAGE INTERNAL +STRICT STABLE PARALLEL SAFE +AS 'jsonb_path_query_first_tz'; + +-- default normalization form is NFC, per SQL standard +CREATE OR REPLACE FUNCTION + "normalize"(text, text DEFAULT 'NFC') +RETURNS text +LANGUAGE internal +STRICT IMMUTABLE PARALLEL SAFE +AS 'unicode_normalize_func'; + +CREATE OR REPLACE FUNCTION + is_normalized(text, text DEFAULT 'NFC') +RETURNS boolean +LANGUAGE internal +STRICT IMMUTABLE PARALLEL SAFE +AS 'unicode_is_normalized'; + +-- +-- The default permissions for functions mean that anyone can execute them. +-- A number of functions shouldn't be executable by just anyone, but rather +-- than use explicit 'superuser()' checks in those functions, we use the GRANT +-- system to REVOKE access to those functions at initdb time. Administrators +-- can later change who can access these functions, or leave them as only +-- available to superuser / cluster owner, if they choose. +-- +REVOKE EXECUTE ON FUNCTION pg_start_backup(text, boolean, boolean) FROM public; +REVOKE EXECUTE ON FUNCTION pg_stop_backup() FROM public; +REVOKE EXECUTE ON FUNCTION pg_stop_backup(boolean, boolean) FROM public; +REVOKE EXECUTE ON FUNCTION pg_create_restore_point(text) FROM public; +REVOKE EXECUTE ON FUNCTION pg_switch_wal() FROM public; +REVOKE EXECUTE ON FUNCTION pg_wal_replay_pause() FROM public; +REVOKE EXECUTE ON FUNCTION pg_wal_replay_resume() FROM public; +REVOKE EXECUTE ON FUNCTION pg_rotate_logfile() FROM public; +REVOKE EXECUTE ON FUNCTION pg_reload_conf() FROM public; +REVOKE EXECUTE ON FUNCTION pg_current_logfile() FROM public; +REVOKE EXECUTE ON FUNCTION pg_current_logfile(text) FROM public; +REVOKE EXECUTE ON FUNCTION pg_promote(boolean, integer) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_stat_reset() FROM public; +REVOKE EXECUTE ON FUNCTION pg_stat_reset_shared(text) FROM public; +REVOKE EXECUTE ON FUNCTION pg_stat_reset_slru(text) FROM public; +REVOKE EXECUTE ON FUNCTION pg_stat_reset_single_table_counters(oid) FROM public; +REVOKE EXECUTE ON FUNCTION pg_stat_reset_single_function_counters(oid) FROM public; +REVOKE EXECUTE ON FUNCTION pg_stat_reset_replication_slot(text) FROM public; + +REVOKE EXECUTE ON FUNCTION lo_import(text) FROM public; +REVOKE EXECUTE ON FUNCTION lo_import(text, oid) FROM public; +REVOKE EXECUTE ON FUNCTION lo_export(oid, text) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_ls_logdir() FROM public; +REVOKE EXECUTE ON FUNCTION pg_ls_waldir() FROM public; +REVOKE EXECUTE ON FUNCTION pg_ls_archive_statusdir() FROM public; +REVOKE EXECUTE ON FUNCTION pg_ls_tmpdir() FROM public; +REVOKE EXECUTE ON FUNCTION pg_ls_tmpdir(oid) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_read_file(text) FROM public; +REVOKE EXECUTE ON FUNCTION pg_read_file(text,bigint,bigint) FROM public; +REVOKE EXECUTE ON FUNCTION pg_read_file(text,bigint,bigint,boolean) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text) FROM public; +REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text,bigint,bigint) FROM public; +REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text,bigint,bigint,boolean) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_replication_origin_advance(text, pg_lsn) FROM public; +REVOKE EXECUTE ON FUNCTION pg_replication_origin_create(text) FROM public; +REVOKE EXECUTE ON FUNCTION pg_replication_origin_drop(text) FROM public; +REVOKE EXECUTE ON FUNCTION pg_replication_origin_oid(text) FROM public; +REVOKE EXECUTE ON FUNCTION pg_replication_origin_progress(text, boolean) FROM public; +REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_is_setup() FROM public; +REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_progress(boolean) FROM public; +REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_reset() FROM public; +REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_setup(text) FROM public; +REVOKE EXECUTE ON FUNCTION pg_replication_origin_xact_reset() FROM public; +REVOKE EXECUTE ON FUNCTION pg_replication_origin_xact_setup(pg_lsn, timestamp with time zone) FROM public; +REVOKE EXECUTE ON FUNCTION pg_show_replication_origin_status() FROM public; + +REVOKE EXECUTE ON FUNCTION pg_stat_file(text) FROM public; +REVOKE EXECUTE ON FUNCTION pg_stat_file(text,boolean) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_ls_dir(text) FROM public; +REVOKE EXECUTE ON FUNCTION pg_ls_dir(text,boolean,boolean) FROM public; + +-- +-- We also set up some things as accessible to standard roles. +-- +GRANT EXECUTE ON FUNCTION pg_ls_logdir() TO pg_monitor; +GRANT EXECUTE ON FUNCTION pg_ls_waldir() TO pg_monitor; +GRANT EXECUTE ON FUNCTION pg_ls_archive_statusdir() TO pg_monitor; +GRANT EXECUTE ON FUNCTION pg_ls_tmpdir() TO pg_monitor; +GRANT EXECUTE ON FUNCTION pg_ls_tmpdir(oid) TO pg_monitor; + +GRANT pg_read_all_settings TO pg_monitor; +GRANT pg_read_all_stats TO pg_monitor; +GRANT pg_stat_scan_tables TO pg_monitor; diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 6d78b33590..e96dd73280 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -164,7 +164,7 @@ CREATE VIEW pg_indexes AS LEFT JOIN pg_tablespace T ON (T.oid = I.reltablespace) WHERE C.relkind IN ('r', 'm', 'p') AND I.relkind IN ('i', 'I'); -CREATE OR REPLACE VIEW pg_sequences AS +CREATE VIEW pg_sequences AS SELECT N.nspname AS schemaname, C.relname AS sequencename, @@ -1268,382 +1268,3 @@ REVOKE ALL ON pg_replication_origin_status FROM public; REVOKE ALL ON pg_subscription FROM public; GRANT SELECT (subdbid, subname, subowner, subenabled, subbinary, substream, subslotname, subpublications) ON pg_subscription TO public; - - --- --- We have a few function definitions in here, too. --- At some point there might be enough to justify breaking them out into --- a separate "system_functions.sql" file. --- - --- Tsearch debug function. Defined here because it'd be pretty unwieldy --- to put it into pg_proc.h - -CREATE FUNCTION ts_debug(IN config regconfig, IN document text, - OUT alias text, - OUT description text, - OUT token text, - OUT dictionaries regdictionary[], - OUT dictionary regdictionary, - OUT lexemes text[]) -RETURNS SETOF record AS -$$ -SELECT - tt.alias AS alias, - tt.description AS description, - parse.token AS token, - ARRAY ( SELECT m.mapdict::pg_catalog.regdictionary - FROM pg_catalog.pg_ts_config_map AS m - WHERE m.mapcfg = $1 AND m.maptokentype = parse.tokid - ORDER BY m.mapseqno ) - AS dictionaries, - ( SELECT mapdict::pg_catalog.regdictionary - FROM pg_catalog.pg_ts_config_map AS m - WHERE m.mapcfg = $1 AND m.maptokentype = parse.tokid - ORDER BY pg_catalog.ts_lexize(mapdict, parse.token) IS NULL, m.mapseqno - LIMIT 1 - ) AS dictionary, - ( SELECT pg_catalog.ts_lexize(mapdict, parse.token) - FROM pg_catalog.pg_ts_config_map AS m - WHERE m.mapcfg = $1 AND m.maptokentype = parse.tokid - ORDER BY pg_catalog.ts_lexize(mapdict, parse.token) IS NULL, m.mapseqno - LIMIT 1 - ) AS lexemes -FROM pg_catalog.ts_parse( - (SELECT cfgparser FROM pg_catalog.pg_ts_config WHERE oid = $1 ), $2 - ) AS parse, - pg_catalog.ts_token_type( - (SELECT cfgparser FROM pg_catalog.pg_ts_config WHERE oid = $1 ) - ) AS tt -WHERE tt.tokid = parse.tokid -$$ -LANGUAGE SQL STRICT STABLE PARALLEL SAFE; - -COMMENT ON FUNCTION ts_debug(regconfig,text) IS - 'debug function for text search configuration'; - -CREATE FUNCTION ts_debug(IN document text, - OUT alias text, - OUT description text, - OUT token text, - OUT dictionaries regdictionary[], - OUT dictionary regdictionary, - OUT lexemes text[]) -RETURNS SETOF record AS -$$ - SELECT * FROM pg_catalog.ts_debug( pg_catalog.get_current_ts_config(), $1); -$$ -LANGUAGE SQL STRICT STABLE PARALLEL SAFE; - -COMMENT ON FUNCTION ts_debug(text) IS - 'debug function for current text search configuration'; - --- --- Redeclare built-in functions that need default values attached to their --- arguments. It's impractical to set those up directly in pg_proc.h because --- of the complexity and platform-dependency of the expression tree --- representation. (Note that internal functions still have to have entries --- in pg_proc.h; we are merely causing their proargnames and proargdefaults --- to get filled in.) --- - -CREATE OR REPLACE FUNCTION - pg_start_backup(label text, fast boolean DEFAULT false, exclusive boolean DEFAULT true) - RETURNS pg_lsn STRICT VOLATILE LANGUAGE internal AS 'pg_start_backup' - PARALLEL RESTRICTED; - -CREATE OR REPLACE FUNCTION pg_stop_backup ( - exclusive boolean, wait_for_archive boolean DEFAULT true, - OUT lsn pg_lsn, OUT labelfile text, OUT spcmapfile text) - RETURNS SETOF record STRICT VOLATILE LANGUAGE internal as 'pg_stop_backup_v2' - PARALLEL RESTRICTED; - -CREATE OR REPLACE FUNCTION - pg_promote(wait boolean DEFAULT true, wait_seconds integer DEFAULT 60) - RETURNS boolean STRICT VOLATILE LANGUAGE INTERNAL AS 'pg_promote' - PARALLEL SAFE; - -CREATE OR REPLACE FUNCTION - pg_terminate_backend(pid integer, timeout int8 DEFAULT 0) - RETURNS boolean STRICT VOLATILE LANGUAGE INTERNAL AS 'pg_terminate_backend' - PARALLEL SAFE; - -CREATE OR REPLACE FUNCTION - pg_wait_for_backend_termination(pid integer, timeout int8 DEFAULT 5000) - RETURNS boolean STRICT VOLATILE LANGUAGE INTERNAL AS 'pg_wait_for_backend_termination' - PARALLEL SAFE; - --- legacy definition for compatibility with 9.3 -CREATE OR REPLACE FUNCTION - json_populate_record(base anyelement, from_json json, use_json_as_text boolean DEFAULT false) - RETURNS anyelement LANGUAGE internal STABLE AS 'json_populate_record' PARALLEL SAFE; - --- legacy definition for compatibility with 9.3 -CREATE OR REPLACE FUNCTION - json_populate_recordset(base anyelement, from_json json, use_json_as_text boolean DEFAULT false) - RETURNS SETOF anyelement LANGUAGE internal STABLE ROWS 100 AS 'json_populate_recordset' PARALLEL SAFE; - -CREATE OR REPLACE FUNCTION pg_logical_slot_get_changes( - IN slot_name name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}', - OUT lsn pg_lsn, OUT xid xid, OUT data text) -RETURNS SETOF RECORD -LANGUAGE INTERNAL -VOLATILE ROWS 1000 COST 1000 -AS 'pg_logical_slot_get_changes'; - -CREATE OR REPLACE FUNCTION pg_logical_slot_peek_changes( - IN slot_name name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}', - OUT lsn pg_lsn, OUT xid xid, OUT data text) -RETURNS SETOF RECORD -LANGUAGE INTERNAL -VOLATILE ROWS 1000 COST 1000 -AS 'pg_logical_slot_peek_changes'; - -CREATE OR REPLACE FUNCTION pg_logical_slot_get_binary_changes( - IN slot_name name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}', - OUT lsn pg_lsn, OUT xid xid, OUT data bytea) -RETURNS SETOF RECORD -LANGUAGE INTERNAL -VOLATILE ROWS 1000 COST 1000 -AS 'pg_logical_slot_get_binary_changes'; - -CREATE OR REPLACE FUNCTION pg_logical_slot_peek_binary_changes( - IN slot_name name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}', - OUT lsn pg_lsn, OUT xid xid, OUT data bytea) -RETURNS SETOF RECORD -LANGUAGE INTERNAL -VOLATILE ROWS 1000 COST 1000 -AS 'pg_logical_slot_peek_binary_changes'; - -CREATE OR REPLACE FUNCTION pg_create_physical_replication_slot( - IN slot_name name, IN immediately_reserve boolean DEFAULT false, - IN temporary boolean DEFAULT false, - OUT slot_name name, OUT lsn pg_lsn) -RETURNS RECORD -LANGUAGE INTERNAL -STRICT VOLATILE -AS 'pg_create_physical_replication_slot'; - -CREATE OR REPLACE FUNCTION pg_create_logical_replication_slot( - IN slot_name name, IN plugin name, - IN temporary boolean DEFAULT false, - IN twophase boolean DEFAULT false, - OUT slot_name name, OUT lsn pg_lsn) -RETURNS RECORD -LANGUAGE INTERNAL -STRICT VOLATILE -AS 'pg_create_logical_replication_slot'; - -CREATE OR REPLACE FUNCTION - make_interval(years int4 DEFAULT 0, months int4 DEFAULT 0, weeks int4 DEFAULT 0, - days int4 DEFAULT 0, hours int4 DEFAULT 0, mins int4 DEFAULT 0, - secs double precision DEFAULT 0.0) -RETURNS interval -LANGUAGE INTERNAL -STRICT IMMUTABLE PARALLEL SAFE -AS 'make_interval'; - -CREATE OR REPLACE FUNCTION - jsonb_set(jsonb_in jsonb, path text[] , replacement jsonb, - create_if_missing boolean DEFAULT true) -RETURNS jsonb -LANGUAGE INTERNAL -STRICT IMMUTABLE PARALLEL SAFE -AS 'jsonb_set'; - -CREATE OR REPLACE FUNCTION - jsonb_set_lax(jsonb_in jsonb, path text[] , replacement jsonb, - create_if_missing boolean DEFAULT true, - null_value_treatment text DEFAULT 'use_json_null') -RETURNS jsonb -LANGUAGE INTERNAL -CALLED ON NULL INPUT IMMUTABLE PARALLEL SAFE -AS 'jsonb_set_lax'; - -CREATE OR REPLACE FUNCTION - parse_ident(str text, strict boolean DEFAULT true) -RETURNS text[] -LANGUAGE INTERNAL -STRICT IMMUTABLE PARALLEL SAFE -AS 'parse_ident'; - -CREATE OR REPLACE FUNCTION - jsonb_insert(jsonb_in jsonb, path text[] , replacement jsonb, - insert_after boolean DEFAULT false) -RETURNS jsonb -LANGUAGE INTERNAL -STRICT IMMUTABLE PARALLEL SAFE -AS 'jsonb_insert'; - -CREATE OR REPLACE FUNCTION - jsonb_path_exists(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', - silent boolean DEFAULT false) -RETURNS boolean -LANGUAGE INTERNAL -STRICT IMMUTABLE PARALLEL SAFE -AS 'jsonb_path_exists'; - -CREATE OR REPLACE FUNCTION - jsonb_path_match(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', - silent boolean DEFAULT false) -RETURNS boolean -LANGUAGE INTERNAL -STRICT IMMUTABLE PARALLEL SAFE -AS 'jsonb_path_match'; - -CREATE OR REPLACE FUNCTION - jsonb_path_query(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', - silent boolean DEFAULT false) -RETURNS SETOF jsonb -LANGUAGE INTERNAL -STRICT IMMUTABLE PARALLEL SAFE -AS 'jsonb_path_query'; - -CREATE OR REPLACE FUNCTION - jsonb_path_query_array(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', - silent boolean DEFAULT false) -RETURNS jsonb -LANGUAGE INTERNAL -STRICT IMMUTABLE PARALLEL SAFE -AS 'jsonb_path_query_array'; - -CREATE OR REPLACE FUNCTION - jsonb_path_query_first(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', - silent boolean DEFAULT false) -RETURNS jsonb -LANGUAGE INTERNAL -STRICT IMMUTABLE PARALLEL SAFE -AS 'jsonb_path_query_first'; - -CREATE OR REPLACE FUNCTION - jsonb_path_exists_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', - silent boolean DEFAULT false) -RETURNS boolean -LANGUAGE INTERNAL -STRICT STABLE PARALLEL SAFE -AS 'jsonb_path_exists_tz'; - -CREATE OR REPLACE FUNCTION - jsonb_path_match_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', - silent boolean DEFAULT false) -RETURNS boolean -LANGUAGE INTERNAL -STRICT STABLE PARALLEL SAFE -AS 'jsonb_path_match_tz'; - -CREATE OR REPLACE FUNCTION - jsonb_path_query_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', - silent boolean DEFAULT false) -RETURNS SETOF jsonb -LANGUAGE INTERNAL -STRICT STABLE PARALLEL SAFE -AS 'jsonb_path_query_tz'; - -CREATE OR REPLACE FUNCTION - jsonb_path_query_array_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', - silent boolean DEFAULT false) -RETURNS jsonb -LANGUAGE INTERNAL -STRICT STABLE PARALLEL SAFE -AS 'jsonb_path_query_array_tz'; - -CREATE OR REPLACE FUNCTION - jsonb_path_query_first_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', - silent boolean DEFAULT false) -RETURNS jsonb -LANGUAGE INTERNAL -STRICT STABLE PARALLEL SAFE -AS 'jsonb_path_query_first_tz'; - --- default normalization form is NFC, per SQL standard -CREATE OR REPLACE FUNCTION - "normalize"(text, text DEFAULT 'NFC') -RETURNS text -LANGUAGE internal -STRICT IMMUTABLE PARALLEL SAFE -AS 'unicode_normalize_func'; - -CREATE OR REPLACE FUNCTION - is_normalized(text, text DEFAULT 'NFC') -RETURNS boolean -LANGUAGE internal -STRICT IMMUTABLE PARALLEL SAFE -AS 'unicode_is_normalized'; - --- --- The default permissions for functions mean that anyone can execute them. --- A number of functions shouldn't be executable by just anyone, but rather --- than use explicit 'superuser()' checks in those functions, we use the GRANT --- system to REVOKE access to those functions at initdb time. Administrators --- can later change who can access these functions, or leave them as only --- available to superuser / cluster owner, if they choose. --- -REVOKE EXECUTE ON FUNCTION pg_start_backup(text, boolean, boolean) FROM public; -REVOKE EXECUTE ON FUNCTION pg_stop_backup() FROM public; -REVOKE EXECUTE ON FUNCTION pg_stop_backup(boolean, boolean) FROM public; -REVOKE EXECUTE ON FUNCTION pg_create_restore_point(text) FROM public; -REVOKE EXECUTE ON FUNCTION pg_switch_wal() FROM public; -REVOKE EXECUTE ON FUNCTION pg_wal_replay_pause() FROM public; -REVOKE EXECUTE ON FUNCTION pg_wal_replay_resume() FROM public; -REVOKE EXECUTE ON FUNCTION pg_rotate_logfile() FROM public; -REVOKE EXECUTE ON FUNCTION pg_reload_conf() FROM public; -REVOKE EXECUTE ON FUNCTION pg_current_logfile() FROM public; -REVOKE EXECUTE ON FUNCTION pg_current_logfile(text) FROM public; -REVOKE EXECUTE ON FUNCTION pg_promote(boolean, integer) FROM public; - -REVOKE EXECUTE ON FUNCTION pg_stat_reset() FROM public; -REVOKE EXECUTE ON FUNCTION pg_stat_reset_shared(text) FROM public; -REVOKE EXECUTE ON FUNCTION pg_stat_reset_slru(text) FROM public; -REVOKE EXECUTE ON FUNCTION pg_stat_reset_single_table_counters(oid) FROM public; -REVOKE EXECUTE ON FUNCTION pg_stat_reset_single_function_counters(oid) FROM public; -REVOKE EXECUTE ON FUNCTION pg_stat_reset_replication_slot(text) FROM public; - -REVOKE EXECUTE ON FUNCTION lo_import(text) FROM public; -REVOKE EXECUTE ON FUNCTION lo_import(text, oid) FROM public; -REVOKE EXECUTE ON FUNCTION lo_export(oid, text) FROM public; - -REVOKE EXECUTE ON FUNCTION pg_ls_logdir() FROM public; -REVOKE EXECUTE ON FUNCTION pg_ls_waldir() FROM public; -REVOKE EXECUTE ON FUNCTION pg_ls_archive_statusdir() FROM public; -REVOKE EXECUTE ON FUNCTION pg_ls_tmpdir() FROM public; -REVOKE EXECUTE ON FUNCTION pg_ls_tmpdir(oid) FROM public; - -REVOKE EXECUTE ON FUNCTION pg_read_file(text) FROM public; -REVOKE EXECUTE ON FUNCTION pg_read_file(text,bigint,bigint) FROM public; -REVOKE EXECUTE ON FUNCTION pg_read_file(text,bigint,bigint,boolean) FROM public; - -REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text) FROM public; -REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text,bigint,bigint) FROM public; -REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text,bigint,bigint,boolean) FROM public; - -REVOKE EXECUTE ON FUNCTION pg_replication_origin_advance(text, pg_lsn) FROM public; -REVOKE EXECUTE ON FUNCTION pg_replication_origin_create(text) FROM public; -REVOKE EXECUTE ON FUNCTION pg_replication_origin_drop(text) FROM public; -REVOKE EXECUTE ON FUNCTION pg_replication_origin_oid(text) FROM public; -REVOKE EXECUTE ON FUNCTION pg_replication_origin_progress(text, boolean) FROM public; -REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_is_setup() FROM public; -REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_progress(boolean) FROM public; -REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_reset() FROM public; -REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_setup(text) FROM public; -REVOKE EXECUTE ON FUNCTION pg_replication_origin_xact_reset() FROM public; -REVOKE EXECUTE ON FUNCTION pg_replication_origin_xact_setup(pg_lsn, timestamp with time zone) FROM public; -REVOKE EXECUTE ON FUNCTION pg_show_replication_origin_status() FROM public; - -REVOKE EXECUTE ON FUNCTION pg_stat_file(text) FROM public; -REVOKE EXECUTE ON FUNCTION pg_stat_file(text,boolean) FROM public; - -REVOKE EXECUTE ON FUNCTION pg_ls_dir(text) FROM public; -REVOKE EXECUTE ON FUNCTION pg_ls_dir(text,boolean,boolean) FROM public; - --- --- We also set up some things as accessible to standard roles. --- -GRANT EXECUTE ON FUNCTION pg_ls_logdir() TO pg_monitor; -GRANT EXECUTE ON FUNCTION pg_ls_waldir() TO pg_monitor; -GRANT EXECUTE ON FUNCTION pg_ls_archive_statusdir() TO pg_monitor; -GRANT EXECUTE ON FUNCTION pg_ls_tmpdir() TO pg_monitor; -GRANT EXECUTE ON FUNCTION pg_ls_tmpdir(oid) TO pg_monitor; - -GRANT pg_read_all_settings TO pg_monitor; -GRANT pg_read_all_stats TO pg_monitor; -GRANT pg_stat_scan_tables TO pg_monitor; diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 4500df6fc8..152d21e88b 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -160,6 +160,7 @@ static char *dictionary_file; static char *info_schema_file; static char *features_file; static char *system_constraints_file; +static char *system_functions_file; static char *system_views_file; static bool success = false; static bool made_new_pgdata = false; @@ -2506,6 +2507,7 @@ setup_data_file_paths(void) set_input(&info_schema_file, "information_schema.sql"); set_input(&features_file, "sql_features.txt"); set_input(&system_constraints_file, "system_constraints.sql"); + set_input(&system_functions_file, "system_functions.sql"); set_input(&system_views_file, "system_views.sql"); if (show_setting || debug) @@ -2532,6 +2534,8 @@ setup_data_file_paths(void) check_input(dictionary_file); check_input(info_schema_file); check_input(features_file); + check_input(system_constraints_file); + check_input(system_functions_file); check_input(system_views_file); } @@ -2869,6 +2873,8 @@ initialize_data_directory(void) setup_run_file(cmdfd, system_constraints_file); + setup_run_file(cmdfd, system_functions_file); + setup_depend(cmdfd); /*