The simplest user-defined function in Postgresql - amazon-redshift

I am wondering if there is a better way to write a test function in Postgresql 8. The following sniped code works fine under AWS Redshift in my tests so maybe someone can share a shorter implementation in the aforementioned AWS service.
-- The simplest function that I wrote in Postgresql
CREATE FUNCTION TEST_FUNCTION()
RETURNS INTEGER
STABLE
AS $$
return 1
$$ LANGUAGE plpythonu;
-- Testing the simplest function
SELECT TEST_FUNCTION();
-- Dropping the simplest function out
DROP FUNCTION TEST_FUNCTION();

Related

Any way to make Postgres stricter when creating functions?

We started to use Postgres much more recently, having moved from SQL Server. I've noticed that Postgres parser/compiler allows creation of functions that (it seems to me) can be rejected at creation time.
One example of what I'm talking about is select statements in plpgsql blocks:
create or replace function test() returns void as $$
begin
select * from pg_database;
end;
$$ language plpgsql;
This function fails at runtime with "query has no destination for result data". Why would this error not be caught at function creation time? Is there any case when using select without 'return' in plpgsql block is allowed?
The other type of errors that are not always caught at compile time is type mismatch errors between a declared return type and actual type of the value. These are caught in simple cases, but start to make it to runtime in more complicated functions. I suspect there's some limitations in Postgres type inference/analysis, is there any additional information on this available?
tldr: Is there any way to make Postgres parser/compiler fail more on function creation?
Is there any way to make Postgres parser/compiler fail more on function creation?
That's the purpose of the plpgsql_check extension. It won't prevent the function to be created, though.
test=# create extension plpgsql_check;
CREATE EXTENSION
test=# create or replace function test() returns void as $$
begin
select * from pg_database;
end;
$$ language plpgsql;
test=# select * from plpgsql_check_function('test');
plpgsql_check_function
----------------------------------------------------------------------
error:42601:3:SQL statement:query has no destination for result data

From SQL Server to Postgres

I'm new to Postgresql; I have only used SQL Server before so I'm trying to migrate an ASP.NET MVC application to ASP.NET Core 3.0 and replace SQL Server with PostgreSQL in the process, and move to Ubuntu.
Can anyone tell what's wrong with my query here?
CREATE OR REPLACE PROCEDURE officekit.testsp (mode CHARACTER)
LANGUAGE plpgsql AS $plpgsql$
BEGIN
IF mode = 'test' THEN
SELECT a,b,c,d FROM testSchema.test;
END IF;
COMMIT;
END;
$plpgsql$;
In your code almost every line is not good.
First if you want to write stored procedures in Postgres, please start with the documentation. The concept of stored procedures in MSSQL is significantly different to that in Oracle, DB2, and certainly different to that in Postgres. PLpgSQL in Postgres is similar to Oracle's PL/SQL. The best thing to do, is to forget all that you know about stored procedures and start from scratch.
The errors:
procedures in Postgres cannot return data - only functions can do this - in your example you probably need a table function.
CREATE OR REPLACE FUNCTION officekit.testsp(mode text)
RETURNS TABLE(a text, b text, c text)
AS $$
BEGIN
IF mode = 'test' THEN
RETURN QUERY SELECT test.a, test.b, test.c FROM test;
END IF;
END;
$$ LANGUAGE plpgsql;
Personally I don't like this style of programming. Functions should not just wrap queries. A lot of significant performance problems and architecture issues arise from the bad use of this possibility, but it depends on context.
Why is commit there? This code doesn't make any change in the database. There is no reason to call commit.

How to use DO in postgres

I am attempting to get a better understanding of the DO command in postgreSQL 9.1
I have following code block,
DO
$do$
BEGIN
IF 1=1 THEN
SELECT 'foo';
ELSE
SELECT 'bar';
END IF;
END
$do$
However it returns the following error:
[42601] ERROR: query has no destination for result data Hint: If you want to discard the results of a SELECT, use PERFORM instead. Where: PL/pgSQL function "inline_code_block" line 4 at SQL statement
PostgreSQL DO command creates and executes some specific short life function. This function has not any interface, and then it cannot to return any output other then changes data in tables and some debug output.
Your example has more than one issues:
Only PostgreSQL table functions can returns some tabular data. But the mechanism is significantly different than MSSQL. PostgreSQL user's should to use RETURN NEXT or RETURN QUERY commands.
CREATE OR REPLACE FUNCTION foo(a int)
RETURNS TABLE(b int, c int) AS $$
BEGIN
RETURN QUERY SELECT i, i + 1 FROM generate_series(1,a) g(i);
END;
$$ LANGUAGE plpgsql;
SELECT * FROM foo(10);
DO anonymous functions are not table functions - so no output is allowed.
PostgreSQL 9.1 is not supported version, please upgrade
If you have some experience only from MSSQL, then forget it. A concept of stored procedures of PostgreSQL is very similar to Oracle or DB2, and it is significantly different to MSSQL does. T-SQL integrates procedural and SQL constructs to one set. Oracle, PostgreSQL, ... procedural functionality can embedded SQL, but procedural functionality is not integrated to SQL.
Please, read PostgreSQL PLpgSQL documentation for better imagine about this technology.

Loading Postgres functions with dependencies

I'm using quite a few Postgres functions (both sql and pl/pgsql) in a particular application. Some of the sql functions depend on other sql functions, e.g.
create or replace function my_function ()
returns table (a text, b text) as
$$
select * from my_other_function();
$$
language sql;
For my_function to load properly, my_other_function has to be loaded first, else I get a my_other_function does not exist error. To manage this, I have been manually ensuring that my_other_function does get loaded first, but it would be nice not to have to do that.
In other words, is there a way to load all of my functions without regard to order and somehow check that all the necessary dependencies are available (function objects) after the fact?
I'm using Postgres 9.6.
You can use SETcheck_function_bodies= false; prior creating your functions to suppress the error.

How to execute a python script form a stored procedure in PostgreSql?

I want to execute a python script form a stored procedure in PostgreSql
I want something like this:
CREATE TRIGGER executePython
AFTER INSERT ON mytable
FOR EACH ROW
BEGIN
SYSTEM('python MyApp');
END;
Anyone can help me, please?
Are you able to install extensions? If so, you can use the the PL/Python extension
CREATE FUNCTION callMyApp()
RETURNS VOID
AS $$
import subprocess
subprocess.call(['/usr/bin/python', '/path/to/MyApp'])
$$ LANGUAGE plpythonu;
CREATE TRIGGER executePython
AFTER INSERT ON messages
FOR EACH ROW EXECUTE PROCEDURE callMyApp();
Note that this will run as the postgres user, so there may be permission issues.
There's also an extension called PL/SH, which might be of use, but doesn't appear to be an official package.
CREATE FUNCTION executePython()
RETURNS VOID
AS $$
#!/bin/sh
python /path/to/MyApp
$$
LANGUAGE plsh;
This blog post might be of interest to you, as well.
Also, this is nearly a duplicate of this thread entitled Run a shell script when a database record is written to postgres.
(Note: I haven't tested any of this code.)