Create Operator In Postgresql - postgresql

Anyone knows how to call self defined operator in postgresql?
I hava the following operator:
CREATE OR REPLACE FUNCTION algo.fun_temp(IN exp BOOLEAN)
RETURNS INTEGER AS $$
BEGIN
RETURN NOT exp;
END;
$$ LANGUAGE plpgsql;
CREATE OPERATOR algo.~
(
PROCEDURE = algo.fun_temp,
RIGHTARG = BOOLEAN
);
And when I try to call this operator with SELECT algo.~ TRUE, the client complains
"ERROR: syntax error at or near "~"
LINE 1: SELECT algo.~ TRUE"
Anyone knows what the problem is? Any help is appreciated.
cheng

The function should return INTEGER, what you wrote returns BOOLEAN:
CREATE OR REPLACE FUNCTION algo.fun_temp(IN exp BOOLEAN)
RETURNS INTEGER AS $$
BEGIN
RETURN (NOT exp)::INTEGER;
END;
$$ LANGUAGE plpgsql;
Then add the schema algo to the search_path:
SET search_path = public, algo;

Related

Postgresql update query syntax error in plpgsql function

I have to create a update procedure, so i created a function and given only below query
CREATE FUNCTION public.testf()
RETURNS boolean
LANGUAGE 'plpgsql'
AS $BODY$begin
update tt pp
set status = 'Ok'
return true;
end;$BODY$;
ALTER FUNCTION public.testf()
OWNER TO postgres;
returns error
ERROR: syntax error at or near "UPDATE" LINE 5: AS $BODY$UPDATE
return type I have given is int4range
What I am doing wrong
Please help
THanks
Pulling out my crystal ball, I see:
You created the function with LANGUAGE plpgsql.
You didn't surround the function body with BEGIN ... END;.
If your function is just a single SQL statement, use LANGUAGE sql.
Else, use the block-centered PL/pgSQL syntax properly.
You are missing an ; to end the UPDATE statement.
CREATE FUNCTION public.testf()
RETURNS boolean
LANGUAGE plpgsql
AS $BODY$
begin
update tt pp
set status = 'Ok'; --<< here
return true;
end;
$BODY$;

"query has no destination for result data" error even after having return in the function

Below is my function, even after having a RETURN statement, but a
query has no destination for result data
error is thrown. Am I missing something?
CREATE OR REPLACE FUNCTION test(ulds character varying)
RETURNS boolean AS
$BODY$
DECLARE
val_result boolean;
BEGIN
select * from regexp_split_to_array('BLK&AAK&AKE', '&');
SET val_result = false;
RETURN val_result;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION test(character varying)
There are more than one issues:
Result of unbind queries is not result of function in Postgres. You need to use INTO clause.
regexp_split_to_array is scalar function, there is not any reason to call this function from SELECT statement. Use SELECT only when you take result of table function, or when you need to read data from relations.
assign statement in plpgsql is based on := symbol. The command SET is used for something different.
the type text is proffered against varchar for function's parameters.
So your code can looks like:
CREATE OR REPLACE FUNCTION test(ulds text)
RETURNS boolean AS $$
DECLARE
result boolean;
target text[];
BEGIN
-- suboptimal, don't do this!!!
SELECT regexp_split_to_array('BLK&AAK&AKE', '&') INTO target;
-- preferred
target := regexp_split_to_array('BLK&AAK&AKE', '&');
result := true;
RETURN result;
END;
$$ LANGUAGE plpgsql;

Rename the column name of a stored function

I've got a postgresql stored procedure, which is returning an integer.
When I call that function, the result is returned with the function name as column name.
For example the name of the function is: "add-person". The column name, when invoking the function, is "add-person".
Is there a way to make the database return the integer with a self-choosen column name? For example "id"?
I think it is pretty easy, but I currently miss the forests for the trees..
Edit:
What i'd missed to tell, is that the return value is a variable, like so:
CREATE OR REPLACE FUNCTION "scheme"."add-person"(arggivenname character varying, argfamilyname character varying) RETURNS integer AS
$BODY$
DECLARE
varResponse integer;
BEGIN
-- Operations before
INSERT INTO "scheme"."table"
(
given_name,
family_name
)
VALUES
(
arggivenname,
argfamilyname
)
RETURNING
"id"
INTO
varResponse;
-- Operations after
RETURN varResponse;
END;
$BODY$
LANGUAGE plpgsql VOLATILE COST 100;
You can us the AS statement for that. That means:
Select add-person() AS yourcolumnname
To have a named column from a function it is necessary to create a type and return that type from the function
create type mytype as (mycolumn integer);
create or replace function ri()
returns mytype as $$
select 1;
$$ language sql;
select * from ri();
mycolumn
----------
1
Edit
Or much simpler without the type creation as in #pozs comment:
create or replace function ri(out mycolumn integer)
as $$
select 1;
$$ language sql;

PGSQL error for If statement in function

I'm trying to create a function for pgsql where I need to return a boolean if an equipment exists in a lecture hall. I'm getting the following error:
"ERROR: return type mismatch in function declared to return boolean"
"DETAIL: Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING."
CREATE FUNCTION hasProjector(int) RETURNS boolean AS $$
DO
$do$
BEGIN
IF EXISTS(SELECT * FROM LectureRoomEquipment WHERE LectureRoomID = $1 AND EquipmentID = 1) THEN
SELECT true AS hasProjector;
ELSE
SELECT false AS hasProjector;
END IF;
END
$do$
$$ LANGUAGE SQL;
Does anyone advise me what i'm doing wrong and how I can fix this? Thank you.
You don't need plpgsql. Do it as plain SQL
create function hasprojector(int) returns boolean as $$
select exists (
select *
from lectureroomequipment
where lectureroomid = $1 and equipmentid = 1
);
$$ language sql;

Assign complex type with UUID field from a function call

I am using PostgreSQL 9.3, working with plpgsql functions:
CREATE TEMP TABLE uuid_inside (
id uuid PRIMARY KEY
);
CREATE FUNCTION uuid_test_func(id uuid)
RETURNS uuid_inside AS
$$
DECLARE
res_uuid_inside uuid_inside;
BEGIN
IF (id = '00000000-0000-0000-0000-000000000001'::uuid) THEN
SELECT uuid_test_func('00000000-0000-0000-0000-000000000000'::uuid)
INTO res_uuid_inside;
RETURN res_uuid_inside;
END IF;
res_uuid_inside.id := id;
RETURN res_uuid_inside;
END;
$$
LANGUAGE plpgsql;
Call:
SELECT uuid_test_func('00000000-0000-0000-0000-000000000001'::uuid);
Message:
ERROR: invalid input syntax for uuid: "(00000000-0000-0000-0000-000000000000)"
SQL-state: 22P02
But this works fine:
SELECT uuid_test_func('00000000-0000-0000-0000-000000000002'::uuid);
The problem is not with recursive function calling - the original code is refering to some other function inside.
Simple function
The recursion in your function seems pointless. This simple sql function does the job (without nesting and without the composite type wrapper):
CREATE FUNCTION uuid_test_func(id uuid)
RETURNS uuid AS
$func$
SELECT CASE WHEN $1 = '00000000-0000-0000-0000-000000000001'::uuid
THEN '00000000-0000-0000-0000-000000000000'::uuid
ELSE $1
END
$func$ LANGUAGE plpgsql;
But that's probably just due to simplification for the demo.
Address problem in original
As for the error message. You are running into a confusing "feature" of PL/pgSQL:
Composite type assignment expects one column per type column. Assigning composite types as a whole is not an option.
This has nothing to do with the UUID type per se.
This modified version would work:
CREATE OR REPLACE FUNCTION uuid_test_func(id uuid)
RETURNS uuid_inside AS
$func$
DECLARE
res_uuid_inside uuid_inside;
BEGIN
IF (id = '00000000-0000-0000-0000-000000000001'::uuid) THEN
SELECT * FROM uuid_test_func('00000000-0000-0000-0000-000000000000'::uuid)
INTO res_uuid_inside.id;
-- INTO res_uuid_inside; -- would work, too - 1st col is assigned
RETURN res_uuid_inside;
END IF;
res_uuid_inside.id := id;
RETURN res_uuid_inside;
END
$func$ LANGUAGE plpgsql;
Closely related question:
Passing array of a composite type to stored procedure
Simpler function
That said, I'd suggest this simplified form (keeping the recursion and the composite result):
CREATE OR REPLACE FUNCTION uuid_test_func(id uuid)
RETURNS uuid_inside AS
$func$
BEGIN
IF (id = '00000000-0000-0000-0000-000000000001'::uuid) THEN
RETURN (SELECT f FROM uuid_test_func('00000000-0000-0000-0000-000000000000'::uuid) f);
ELSE
RETURN row(id)::uuid_inside;
END IF;
END
$func$ LANGUAGE plpgsql;