postgres function takes parameter bytea while calling insted of varchar - postgresql

ERROR: function dharani.fn_generate_ror_1b_citizen(bytea, character varying) does not exist at character 15
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
STATEMENT: select * from dharani.fn_generate_ror_1b_citizen($1,$2)
ERROR: function dharani.fn_generate_pahani_citizen(bytea, bytea, character varying) does not exist at character 15
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
STATEMENT: select * from dharani.fn_generate_pahani_citizen($1,$2,$3)

You have to supply function arguments of the appropriate type, if necessary using type casts as the hint says.
SQL is a typed language, and PostgreSQL uses function overloading, so it is essential the data types are resolved properly. The exact rules how this is done are in the documentation.

Related

replace special characters in a column in postgresql using pgadmin

I am trying to replace a column with these characters --> "{,
I tried using both replace and regex_replace, I am getting the following error.
update mytable
set address = replace(address, ',','_');
this is the error I get.
ERROR: function replace(character varying[], unknown, unknown) does not exist
LINE 1: select replace(address,',','_') from mytable.
^
HINT: No function matches the given name and argument types.
You might need to add explicit type casts.
SQL state: 42883
Character: 8

Postgresql Nested functions

I'm trying to nest functions in postgresql, trying to extract a directory name (actually the third one) from a path.
My starting SQL code was :
SELECT "Path", regexp_matches("Path", '^([^/]*/){3}.*') FROM ...
Since the returned value of my regex is delimited by curly brace and double-quote (when containing spaces), I'm trying to remove theses delimiters by nesting functions :
SELECT "Path", right(regexp_matches("Path", '^([^/]*/){3}.*'),2) FROM
But I've the following error :
ERROR: function right(text[], integer) does not exist
LINE 2: SELECT "Path", right(regexp_matches("Path", '^([^/]*/){3}.*'...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
État SQL :42883
Caractère :17
I don't know how to format the expression in order to be accepted...
Of course, if someone can give me a way to get exactly the nth field of a string separated by slashes, I would be happy !

Postgres encode() function doesn't work with a function as an argument

I'm trying to use Postgresql encode() function and put some other functions as it's arguments. I get errors, and I can't understand why.
I am using Postgres 9.6.14 on Windows.
This works fine and returns 698d51a19d8a121ce581499d7b701668
select md5('111');
This also works fine and returns some value
select encode('698d51a19d8a121ce581499d7b701668', 'base64');
But this one, which combines the first 2, doesn't work and returns "ERROR: function encode(text, unknown) does not exist"
select encode(md5('111'), 'base64');
This also doesn't work and returns the same error
select encode(concat('1', '11'), 'base64');
I thought that there is a rule which prevents to use one function inside another, but the following one works fine and returns the same value as the first request here, as expected.
select md5(concat('1', '11'))
So what's the issue with requests number 3 and 4 and encode() function overall?
Look at the definition of encode:
\df encode
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+--------+------------------+---------------------+------
pg_catalog | encode | text | bytea, text | func
(1 row)
The first argument has to be bytea, that is a binary byte string.
Your first two queries work because string literals are of type unknown, which can be cast to bytea implicitly.
In the queries that do not work, you are using the functions md5 and concat, which both have text as a result type. Now there is no implicit cast between text and bytea, hence the error message.
To make that work, you have to introduce an explicit type cast:
select encode(CAST(md5('111') AS bytea), 'base64');

Inconsistent PostgreSQL behavior with strings and network functions

PostgreSQL's inet functions generally accept strings in correct inet form:
mydb=# select network('10.1.2.3/24');
network
-------------
10.1.2.0/24
(1 row)
However, if string concatenation is used to construct the string, the same function will fail:
mydb=# select network('10.1.2.3' || '/24');
ERROR: function network(text) does not exist
LINE 1: select network('10.1.2.3' || '/24');
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
even though the two strings appear to be equivalent:
mydb=# select '10.1.2.3/24';
?column?
-------------
10.1.2.3/24
(1 row)
mydb=# select '10.1.2.3' || '/24';
?column?
-------------
10.1.2.3/24
(1 row)
You can work around this by casting the concatenated string to inet:
mydb=# select network(('10.1.2.3' || '/24')::inet);
network
-------------
10.1.2.0/24
(1 row)
Can anyone describe this behavior in a way that will help me understand why it happens? Is there implicit casting of whole strings that doesn't affect concatenated strings?
Strictly speaking, a quoted literal in PostgreSQL (e.g. '10.1.2.3/24') is not a string, it is a literal of some type to be determined by the parser.
You can tell the parser what type it is using SQL-standard prefix notation (inet '10.1.2.3/24') or Postgres suffix-cast notation ('10.1.2.3/24'::inet). These are not type-casts, they are the input specification for the particular type. If you don't specify the type, the parser will try to guess at its type based on context, and fall back to the pseudo-type unknown.
When you run network('10.1.2.3/24'), the literal is deduced to be of type inet, because there is only one function called network, and that is the type it expects. The value is never of type text, so no cast is needed.
But when you write network('10.1.2.3' || '/24'), the || operator needs to be resolved first; to do this, Postgres determines (correctly) that the literals '10.1.2.3' and '/24' should be treated as type text, and the result of concatenating them is also text. It then looks for a function called network() which takes a text parameter and doesn't find one; it has no automatic cast configured text to inet, so it fails with a type-checking error.
You can actually see this in action by creating a new function called network that takes a float parameter:
create function network(float) returns text language sql as $$ select 'test'::text; $$
Running select network('10.1.2.3/24') with this function in scope will give you an error "Could not choose a best candidate function", because Postgres doesn't know whether inet or float is the type you intended with your literal '10.1.2.3/24'. (If you create a function network(text), it will be preferred over both; not because the literal is of type text, just because it is considered a "better candidate".)
Conversely, if you specify Select network(text '10.1.2.3/24'), you will get a type error, not an implicit cast.
There seems to be an implicit type cast to inet before applying the network function. This doesn't work when you are explicitly creating a text object by concatenating. You should add an explicit inet type cast:
db=# select network(('10.1.2.3'||'/24')::inet);
network
-------------
10.1.2.0/24
(1 row)

How do i get nextval without advancing the cursor?

How do i get nextval without advancing the cursor in PostgreSQL?
This doesn't work:
pgdb=# SELECT curval('schemas.category_category_id_seq');
ERROR: function curval(unknown) does not exist
LINE 1: SELECT curval('schemas.category_category_id_seq');
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
PostgreSQL's nextval() function is safe. But currval()+1 isn't.
From what I can tell, your function name is just wrong. It is "currval". See https://dba.stackexchange.com/questions/3281/how-do-i-use-currval-in-postgresql-to-get-the-last-inserted-id
BTW, if you can assume your sequence just increments by one, you can do:
select currval('schemas.category_category_id_seq') + 1;