Postgres Database Exception - postgresql

Exception (Database Exception) 'yii\db\Exception' with message
SQLSTATE[42601]: Syntax error: 7
ERROR: a column definition list is required for functions returning "record"

If you have a function that is defined as RETURNS [SETOF] record, you have to specify a column list when you call it. This is because the return type has to be known at query parse time.
An example:
SELECT * FROM myfun() AS myfun(a integer, b text);

Related

Why a query for a certain data type can also output other data type?

While going through the documentation (data-types) of Apache AGE, I ran into some interesting queries that demonstrated the input/output format of data types.
Such as: -
SELECT *
FROM cypher('graph_name', $$
RETURN 1
$$) AS (int_result agtype);
Which as expected outputs
int_result
1
(1 row)
However, if the query is modified to
SELECT *
FROM cypher('graph_name', $$
RETURN 1.4
$$) AS (int_result agtype);
It still outputs
int_result
1.4
(1 row)
The behavior is also noticed in boolean datatype in which you can enter any numeric value, and it outputs it as it is, for an instance
SELECT *
FROM cypher('graph_name', $$
RETURN 1.5
$$) AS (boolean_result agtype);
Will output
boolean_result
1.5
(1 row)
It is also interesting to note that any other input (except numeric, true, or false), for example 't' gives an error for the same boolean query.
SELECT *
FROM cypher('graph_name', $$
RETURN t
$$) AS (boolean_result agtype);
Will output
ERROR: could not find rte for t
I was expecting similar behavior for other inputs that did not match the data types, however, they proceeded just fine. What may be the developmental reason for such behavior?
The confusion here is that in (int_result agtype), int_result is not the data type, but instead just the name of the column that will be displayed in the result. The data type itself is agtype, which is handled internally. AGE itself sets the correct data type for agtype.
SELECT *
FROM cypher('graph_name', $$
RETURN t
$$) AS (boolean_result agtype);
For this case, it gives an error because it expects to return a variable named 't'. However, since no 't' was declared in the cypher query, it throws an error.
This behavior can seem unexpected but is because of fact that Apache Age supports dynamic typing of data. This mean that the system infers the data type of the value returned by the cypher query and maps it to an appropriate AGE data type.
In case of the first query where value returned by the Cypher query is integer Literal “1”. Which AGE maps to an integer Data type and in second query the value returned by the Cypher is a floating point literal “1.4”.
For more information here
#Apache-AGE
#Postgres

How to insert JSONB data from dependent table

I'm trying to insert data into a JSONB field based on a dependent table.
Essentially I want to do this (ignore why this is just an example query):
insert into myschema.teams (team_name, params)
select users.team_name, '{"team_name": teams.team_id, "user_name": users.username }'
from myschema.users
where users.team_name is not null;
As written I'm getting these errors:
ERROR: invalid input syntax for type json
LINE 2: ... '{"team_name...
^
DETAIL: Token "teams" is invalid.
CONTEXT: JSON data, line 1: {"team_name": teams...
You are using a string literal that doesn't contain valid JSON. There is no interpolation going on - you need use the jsonb_build_object function to create the JSONB value from dynamic values. (You could also do string concatenation and the cast from text to json, but please don't).
insert into myschema.teams (team_name, params)
select users.team_name, jsonb_build_object('team_name', teams.team_name, 'user_name', users.username)
from myschema.users
where users.team_name is not null;

Postgresql pass function parameter with casting

I created two functions. The first function, getProductOrder, is getting token whose type is character varying. The second function is getOrderTechnicalDetails whose function parameter is character varying.
For example When I call getProductOrder with quotation marks that is working nothing problem the function
Worked example
select
(select row_to_json(getOrderTechnicalDetails('991964b80d4f41a416b48ac99bdc07ad')) as techDetails),
o.*
from
(select * from getProductOrder(null, '54e91016-46d0-11e7-912d-001dd8b72237', null, 9181, 1::smallint)) o
But I have to use dynamic parameter here problem is casting problem function can't determine casting.
When I execute this query I get syntax error. How can I solve this problem?
Query
select
(select row_to_json(getOrderTechnicalDetails(o.token::character varying)) as techDetails),
o.*
from
(select * from getProductOrder(null, '54e6341-46d0-11e7-912d-001dd8b72237', null, 9181, 1::smallint)) o
Error
ERROR: invalid input syntax for integer: "-"
SQL state: 22P02
Context: SQL function "getordertechnicaldetails" statement 1

How to embed a function returning a string in a Q query?

I'm using Q.f to format column fields from integer to float with 4 digits precision:
fmt_price:{[val] .Q.f[4;](val*0.0001)}
select fmt_price[price] from mytable
The fmt_price works well at the q prompt, but if I embed the function in a query I get this error:
An error occurred during execution of the query. The server sent the
response: `type
The fmt_price call works if I return a float or integer variable, rather than the result of Q.f.
You need to do an each over the list. Currently you are passing a list of values to .Q.f, when it expects an atom. Something like the following is what you need:
fmt_price:{[val] .Q.f[4;] each (val*0.0001)}

Use function result as columns in query with PostgreSQL

I'm using PostgreSQL 9.1 and let's say I have a type in PostgreSQL like:
CREATE TYPE sticker AS (
customer_id integer,
customer_machine_id integer,
);
and I have a plpgsql named get_sticker that returns the type sticker...
I can do this fine:
select get_sticker(a_value), * from foo_bar;
But, this returns the result in a tuple (which totally makes sense). But, how can I convert (basically unpack) to columns?
It seems like it would be something like the following, but it fails.
select get_sticker(a_value).*, * from foo_bar; -- <<<< FAIL
Error message:
ERROR: syntax error at or near "."
SQL state: 42601
You need an extra set of parentheses:
select (get_sticker(a_value)).*, * from foo_bar;