Cannot drop function in postgres - postgresql

I have function that I wrote as part of a trigger, but cannot drop the function with DROP FUNCTION aft_delete();. Why is this the case?
myname=# \df
List of functions
Schema | Name | Result data type | Argument data types | Type
--------+------------+------------------+---------------------+---------
public | aft_delete | trigger | | trigger
(1 row)
myname=# DROP FUNCTION aft_delete();
ERROR: could not find tuple for trigger 34119

You might need to use the CASCADE keyword to drop the dependent trigger (assuming that is what you want).
https://www.postgresql.org/docs/current/static/sql-dropfunction.html

Related

pgr_dijkstra returns an empty set

I'm trying to write a function that is able to find the shortest way between two points using pgr_dijkstra function. I'm following this guide. With data provided in the guide everything works fine. But when I try to apply the same steps (build a topology using pgr_createTopology and then test it with pgr_dijkstra) to another data set, pgr_dijkstra returns an empty result. I've also noticed that the guide's data set has a LineString geometry column, while I have a MultiLineString geometry column. What could be the reason?
My table's structure:
Table "public.roads"
Column | Type | Collation | Nullable | Default
--------+--------------------------------+-----------+----------+------------------------------------
id | integer | | not null | nextval('roads_gid_seq'::regclass)
geom | geometry(MultiLineString,4326) | | |
source | integer | | |
target | integer | | |
Indexes:
"roads_pkey" PRIMARY KEY, btree (id)
"roads_geom_idx" gist (geom)
"roads_source_idx" btree (source)
"roads_target_idx" btree (target)
Topology creation query:
SELECT pgr_createTopology('roads', 0.00001, 'geom', 'id');
Shortest way test:
SELECT seq, node, edge, cost as cost, agg_cost, geom
FROM pgr_dijkstra(
'SELECT id, source, target, st_length(geom, true) AS cost FROM roads',
-- Some random points
1, 200
) AS pt
JOIN roads rd ON pt.edge = rd.id;
The problem was actually related to geometry data types. The function doesn't work properly with MultiLineString, though it doesn't produce any errors. So, I've converted MultiLineString to LineString and now everything seems to be OK.

Recursive postgres query to view

I have the following table which models a very simple hierarchical data structure with each element pointing to its parent:
Table "public.device_groups"
Column | Type | Modifiers
--------------+------------------------+---------------------------------------------------------------
dg_id | integer | not null default nextval('device_groups_dg_id_seq'::regclass)
dg_name | character varying(100) |
dg_parent_id | integer |
I want to query the recursive list of subgroups of a specific group.
I constructed the following recursive query which works fine:
WITH RECURSIVE r(dg_parent_id, dg_id, dg_name) AS (
SELECT dg_parent_id, dg_id, dg_name FROM device_groups WHERE dg_id=1
UNION ALL
SELECT dg.dg_parent_id, dg.dg_id, dg.dg_name
FROM r pr, device_groups dg
WHERE dg.dg_parent_id = pr.dg_id
)
SELECT dg_id, dg_name
FROM r;
I now want to turn this into a view where I can choose which group I want to drill down for using a WHERE clause. This means I want to be able to do:
SELECT * FROM device_groups_recursive WHERE dg_id = 1;
And get all the (recursive) subgroups of the group with id 1
I was able to write a function (by wrapping the query from above), but I would like to have a view instead of the function.
Side-Node: I know of the shortcoming of an adjacency list representation, I cannot change it currently.

When aliasing a function, I do not see composite types

I create table gs:
foo=>create table gs as select generate_subscripts('{{1,2,3},{4,5,6}}'::integer[],2);
I alias the table and the column:
foo=> select s.a from gs s(a);
a
---
1
2
3
(3 rows)
If I only alias the table, I see composite types:
foo=> select s from gs s;
s
-----
(1)
(2)
(3)
(3 rows)
But when I only alias a function as if it was a table, I do not see composite types, but it is as if I had aliased a table and column:
foo=> select s from generate_subscripts('{{1,2,3},{4,5,6}}'::integer[],2) s;
s
---
1
2
3
(3 rows)
I do not understand why I do not see composite types instead.
Set returning functions (or table functions, SRF) are treated differently than actual relations (tables, views, etc.). Especially, when they return only one column (a base type):
If no table_alias is specified, the function name is used as the table name; in the case of a ROWS FROM() construct, the first function's name is used.
If column aliases are not supplied, then for a function returning a base data type, the column name is also the same as the function name. For a function returning a composite type, the result columns get the names of the individual attributes of the type.
What is not covered though, is the case, when you supply a table alias, but not a column alias (for a single-columned SRF). In that case, the column alias will be the same as the table alias, so you can't access the function's row-type (composite type) explicitly (its reference is hidden by the column alias).
select s from generate_subscripts('{{1,2,3},{4,5,6}}'::integer[],2) s;
-- "s" is both a column alias and a table alias here, so:
select s.s from generate_subscripts('{{1,2,3},{4,5,6}}'::integer[],2) s;
-- is also valid
More intriguing however, is that when you use an explicit table alias and an explicit column alias for a single-columned SRF, the table alias also becomes a column alias (its type will be the base type, not a row-type -- composite type).
select s, a from generate_subscripts('{{1,2,3},{4,5,6}}'::integer[],2) s(a);
+---+---+
| s | a |
+---+---+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+---+---+
I'm not sure though if it's a bug, or just an undocumented "feature".
http://rextester.com/VJOBI47962

Is it possible in PL/pgSQL to evaluate a string as an expression, not a statement?

I have two database tables:
# \d table_1
Table "public.table_1"
Column | Type | Modifiers
------------+---------+-----------
id | integer |
value | integer |
date_one | date |
date_two | date |
date_three | date |
# \d table_2
Table "public.table_2"
Column | Type | Modifiers
------------+---------+-----------
id | integer |
table_1_id | integer |
selector | text |
The values in table_2.selector can be one of one, two, or three, and are used to select one of the date columns in table_1.
My first implementation used a CASE:
SELECT value
FROM table_1
INNER JOIN table_2 ON table_2.table_1_id = table_1.id
WHERE CASE table_2.selector
WHEN 'one' THEN
table_1.date_one
WHEN 'two' THEN
table_1.date_two
WHEN 'three' THEN
table_1.date_three
ELSE
table_1.date_one
END BETWEEN ? AND ?
The values for selector are such that I could identify the column of interest as eval(date_#{table_2.selector}), if PL/pgSQL allows evaluation of strings as expressions.
The closest I've been able to find is EXECUTE string, which evaluates entire statements. Is there a way to evaluate expressions?
In the plpgsql function you can dynamically create any expression. This does not apply, however, in the case you described. The query must be explicitly defined before it is executed, while the choice of the field occurs while the query is executed.
Your query is the best approach. You may try to use a function, but it will not bring any benefits as the essence of the issue will remain unchanged.

Show query result column types (PostgreSQL)

Is there a way to easily get the column types of a query result? I read the psql documentation, but I don't think it supports that. Ideally, I'd be able to get something like:
columna : text | columnb : integer
----------------+-------------------
oh hai | 42
Is there a way I can get this information without coding something up?
It is possible to get any SELECT query result column type.
Example
Given the following query and result, let's answer the question *"What is the column type of all_ids?"*
SELECT array_agg(distinct "id") "all_ids" FROM "auth_user";
all_ids
--------------------------------------------
{30,461577687337538580,471090357619135524}
(1 row)
We need a mechanism to unveil the type of "all_ids".
On the postgres mailing list archives I found reference to a native pg function called pg_typeof.
Example usage:
SELECT pg_typeof(array_agg(distinct "id")) "all_ids" FROM "auth_user";
Output:
all_ids
----------
bigint[]
(1 row)
Cheers!
It is definitely possible with \gdesc command(psql 11):
\gdesc
Shows the description (that is, the column names and data types) of the result of the current query buffer. The query is not actually
executed; however, if it contains some type of syntax error, that
error will be reported in the normal way.
If the current query buffer is empty, the most recently sent query is described instead.
For example:
$ SELECT * FROM pg_database \gdesc
COLUMN | TYPE
---------------+-----------
datname | name
datdba | oid
encoding | INTEGER
datcollate | name
datctype | name
datistemplate | BOOLEAN
datallowconn | BOOLEAN
datconnlimit | INTEGER
datlastsysoid | oid
datfrozenxid | xid
datminmxid | xid
dattablespace | oid
datacl | aclitem[]
I don't think you can print exactly what you have in the sample, unless you write a stored procedure for it.
One way to do it (two "selects"):
create table my_table as select ...
\d my_table
select * from my_table