I've been trying to add stored generated column with this command
ALTER TABLE mtn_order
ADD COLUMN textsearchable_index_col tsvector
GENERATED ALWAYS AS (to_tsvector('english', coalesce(descr, '') || ' ' || coalesce(descrrep, ''))) STORED;
But I get error:
ERROR: syntax error at or near "("
LINE 3: GENERATED ALWAYS AS (to_tsvector('english', coalesce(descr, ...
^
What am i doing wrong?
UPDATE:
Had to upgrade to version 12
Related
I am trying to create an index for text search in Postgres, but I keep getting an error when I create generated tsvector column.
ERROR: generation expression is not immutable
SQL state: 42P17
I have a text "title" column and text[] "authors" column. I am trying to combine the two to create a tsvector column
Here is the code that's getting the error
ALTER TABLE book
ADD COLUMN tscol tsvector
GENERATED ALWAYS AS (to_tsvector(title || ' ' || immutable_array_to_string(coalesce(authors, '{}'), ' '))) STORED;
Code for immutable_array_to_string function:
CREATE OR REPLACE FUNCTION immutable_array_to_string(text[], text)
RETURNS text as $$ SELECT array_to_string($1, $2); $$
LANGUAGE sql IMMUTABLE;
You are calling to_tsvector without a regconfig, so the default one is used. In such case, the function is only stable. If you want it to be immutable, you must pass the regconfig.
to_tsvector('english',title || ' ' || immutable_array_to_string(coalesce(authors, '{}'), ' '))
PS: you can call \df+ to_tsvector to see the volatility of the function with different signatures.
Error:
19:20:44.737 [info] execute "ALTER TABLE listings\n ADD COLUMN search_tsvector tsvector\n GENERATED ALWAYS AS (to_tsvector('spanish', coalesce(title, '') || ' ' || coalesce(description, ''))) STORED;"
** (Postgrex.Error) ERROR 42601 (syntax_error) syntax error at or near "("
query: ALTER TABLE listings
ADD COLUMN search_tsvector tsvector
GENERATED ALWAYS AS (to_tsvector('spanish', coalesce(title, '') || ' ' || coalesce(description, ''))) STORED;
This query runs fine locally on my Postgres 12, but in my server where I can only use Postgres 11 it doesn't run successfully.
Can someone assist?
Postgres 11 did not have generated columns, except for identity columns:
https://www.postgresql.org/docs/current/ddl-generated-columns.html
in my postgres 9.3 database, I have the following combination of function and a trigger to implement soft delete functionality:
ALTER TABLE "LIBN02"."trigger_test_1"
ADD COLUMN delete_ind integer
CREATE OR REPLACE FUNCTION trigger_test_1_soft_delete()
RETURNS trigger AS $$
DECLARE
command text := ' SET delete_ind = 1 WHERE uuid_col = $1';
BEGIN
EXECUTE 'UPDATE ' || "LIBN02"."trigger_test_1" || command USING OLD.uuid_col;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER test_1_soft_delete_trigger
BEFORE DELETE ON "LIBN02"."trigger_test_1"
FOR EACH ROW EXECUTE PROCEDURE trigger_test_1_soft_delete();
After all of the above is done, I run the following delete statement:
DELETE FROM "LIBN02"."trigger_test_1"
I get the following error:
ERROR: missing FROM-clause entry for table "LIBN02"
LINE 1: SELECT 'UPDATE ' || "LIBN02"."trigger_test_1" || command
^
QUERY: SELECT 'UPDATE ' || "LIBN02"."trigger_test_1" || command
CONTEXT: PL/pgSQL function trigger_test_1_soft_delete() line 5 at EXECUTE
********** Error **********
ERROR: missing FROM-clause entry for table "LIBN02"
SQL state: 42P01
Context: PL/pgSQL function trigger_test_1_soft_delete() line 5 at EXECUTE
What should I change in order for this to work?
The error you are receiving is because "LIBN02"."trigger_test_1" is not a string (these are quoted with single quotes), but an identifier. You should use
EXECUTE 'UPDATE "' || TG_TABLE_SCHEMA || '"."' || TG_TABLE_NAME || '" ' || command
USING OLD.uuid_col;
You could also add AND NOT deleted to the WHERE clause to avoid unnecessary churn.
I am building a trigger function in plpgsql for my partitioned table and I've got all of my logic working, but am having trouble inserting the actual record into my table.
I have to reference my specific table by a variable reference, so that (as far as I understand) forces me to use an EXECUTE command, as so:
EXECUTE 'INSERT INTO ' || tablename || ' VALUES ' || NEW.*;
However, this does not handle unpacking the record stored in NEW in a way that Postgres' INSERT function can understand. It converts the record into a string while preserving all of the double quotes within. I.e. the above turns into the following upon execution:
INSERT INTO cfs_hgt_05152016_05202016
VALUES ("2016-05-16 00:00:00","2016-05-12 06:00:00",HGT,"1000 mb",9,-71,-38.5371)
The problem with this is Postgres thinks these values are now columns due to the double quotes.
COPY cfs_hgt_master, line 1: ""2016-05-16 00:00:00","2016-05-12 06:00:00","HGT","1000 mb",9,-71,-38.5371"
ERROR: column "2016-05-16 00:00:00" does not exist
I tried to remedy this by the following:
record_text := regexp_replace(NEW.*, '"', '\'', 'gi');
EXECUTE 'INSERT INTO ' || tablename || ' VALUES ' || record_text;
But escaping the single quote like that produces an error:
psql:cfs_hgt_trigger_function.sql:36: ERROR: unterminated quoted string at or near "' || record_text;
LINE 30: ... EXECUTE 'INSERT INTO ' || tablename || ' VALUES ' || recor...
^
Could someone help me figure out how to either properly escape that single quote, or suggest an alternative means of accomplishing my task?
Don't convert values to their text representation at all. Pass values with the USING clause of EXECUTE.
And escape table names properly. You can use format() for this:
EXECUTE format('INSERT INTO %I SELECT $1.*', tablename)
USING NEW;
Details:
INSERT with dynamic table name in trigger function
How to pass NEW.* to EXECUTE in trigger function
I am trying to test if pgrouting works fine or not. To do so I have created a table containing the following attributes.
Columns:
gid |
length |
the_geom |
source |
target
Now my problem is that when I try to execute the assign_vertex_id function it is giving me the following error;
PL/pgSQL function "assign_vertex_id" line 15 at EXECUTE statement
ERROR: query string argument of EXECUTE is null
CONTEXT: PL/pgSQL function "assign_vertex_id" line 32 at EXECUTE statement
********** Error **********
ERROR: query string argument of EXECUTE is null
SQL state: 22004
Context: PL/pgSQL function "assign_vertex_id" line 32 at EXECUTE statement
Any suggestions what does this mean?
assign_vertex_id() is defined as part of PGrouting in routing_topology.sql. (Running \df+ assign_vertex_id would also give you the current source.) Line 32's EXECUTE statement is:
EXECUTE 'update ' || quote_ident(geom_table) ||
' SET source = ' || source_id ||
', target = ' || target_id ||
' WHERE ' || quote_ident(gid_cname) || ' = ' || _r.id;
The error is that EXECUTE is being called with a NULL argument. How? Well, the SQL || operator means concatenate, and concatenating NULL to a string results in NULL:
=> select ('string' || null) is null;
?column?
----------
t
(1 row)
My guess is the gid column of the underlying table (_r.id here) contains NULLs, although I suppose it could be source/target_id too. Fix it, then add a constraint to prevent that going forward:
ALTER TABLE whatever ALTER COLUMN gid SET NOT NULL;
Are you using Postgis 2.0 and have a table with Multilinestrings?
The function ST_StartPoint() and ST_EndPoint() does not work on Multilinestrings anymore(http://postgis.refractions.net/docs/ST_StartPoint.html) in Postgis 2.0. So it will most likely fail there.
You need to convert your Multilinestrings to Linestrings. More info about that here: