4

Code :

CREATE FUNCTION square_num(num integer)
 RETURNS INTEGER AS $$

BEGIN

 IF (num<0) THEN
 RETURN 0;
 END IF;

 RETURN num*num;

END; $$
LANGUAGE PLPGSQL;

The above code created a function in the database postgres and schema public. How can I create a function in a particular database and it's schema? Thanks.

10
  • You have a schema for a database, without specifing a schema you will use 'public' schema provided by postgres. I suggest to create a specific schema for your database owner and create your funciton. In the end alter your function with the scheama created to the owner of the database understand? Commented Dec 28, 2017 at 12:10
  • you mean alter my function's owner to the schema of the particular database?? Is there no way I can specify the database name while creating the function?? Commented Dec 28, 2017 at 12:13
  • Each function belongs to a schema Commented Dec 28, 2017 at 12:17
  • okay so there is no way I can specify the schema of a particular database. Only altering the function's owner is a way? Commented Dec 28, 2017 at 12:18
  • You can alter the schema doing ALTER FUNCTION square_num(num) SET SCHEMA your_schema_name; Commented Dec 28, 2017 at 12:22

1 Answer 1

10

The above code created a function in the database postgres and schema public.

No. It creates function in the database you are connected to in a first existing schema from search_path.

Example:

-bash-4.2$ psql t
psql (10.1)
Type "help" for help.

t=# create table tt();
CREATE TABLE
t=# select table_catalog,table_schema from information_schema.tables where table_name = 'tt';
 table_catalog | table_schema
---------------+--------------
 t             | public
(1 row)

I defined database name t on connection, so relation is created in database t. I don't have schema postgres,so $user was skipped, next "default" schema is public:

t=# show search_path;
   search_path
-----------------
 "$user", public
(1 row)

so now:

t=# create schema postgres;
CREATE SCHEMA
t=# create table tt();
CREATE TABLE

see - no error that relation already exists, because:

t=# select table_catalog,table_schema from information_schema.tables where table_name = 'tt';
 table_catalog | table_schema
---------------+--------------
 t             | public
 t             | postgres
(2 rows)

function creation follows same rules, I used table as shorter syntax...

reading: https://www.postgresql.org/docs/current/static/ddl-schemas.html#DDL-SCHEMAS-PATH

The first schema in the search path that exists is the default location for creating new objects.

finally answering

How can I create a function in a particular database and it's schema?

connect to needed database and either explicitely specify schema name:

CREATE FUNCTION my_schema.square_num(...and so on

or adjust search_path to meet your needs

update for sake of clarity I used schema name postgres to comply with original post. both using postgres database and creating postgres schema can be confusing for new users. There is nothing special (or system) about the default postgres database (that can be recreated any time from template), neither the name postgres gives any special attributes to schema. I only used it for OP to easier reproduce the example (as clearly from the fact that he connect to postgres database, user probably did not specify database name, connecting as OS user postgres). Thus to demonstrate how search_path first value $user was picked up, I used same name as username ...

Sign up to request clarification or add additional context in comments.

5 Comments

I am just speechless for this answer. A very crystal-clear explanation. Thanks a lot. You clarified some more questions with your answer. just one edit in the answer - The second time you create the table it's ii(), change it to tt.
Personally I would choose a different name for the newly created schema. postgres might confuse novice users.(because they could think it is somehow special or reserved or akeyword, which it is not in this case)
I have chosen it as seen that OP connects as postgres user, so it would be clear that $user is postgres users schema
I do think that connecting as user=postgres is a bad habit (for new users). Also, the decouping of system<-->postgres usernames should be stipulated, IMO.
I totally support such opinion. But will keep from overwriting the whole post, as it would loose its laconic outfit. I'll update it with NB instead. Thank you for your notice

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.