To stop reading the whole problem, my main question is:
Is there a function in PostgreSQL to escape regular expression characters in a string?
I researched the documentation, but could not find such a function.
Here is the complete problem:
In a PostgreSQL database, I have a column with unique names. I also have a process that periodically inserts names into this field, and to prevent duplication, if it needs to enter a name that already exists, it adds a space and parentheses with the quantity to the end.
i.e. name, name (1), name (2), name (3), etc.
In its current form, I use the following code to find the following number to add to the series (written in plpgsql):
var_name_id := 1; SELECT CAST(substring(a.name from E'\\((\\d+)\\)$') AS int) INTO var_last_name_id FROM my_table.names a WHERE a.name LIKE var_name || ' (%)' ORDER BY CAST(substring(a.name from E'\\((\\d+)\\)$') AS int) DESC LIMIT 1; IF var_last_name_id IS NOT NULL THEN var_name_id = var_last_name_id + 1; END IF; var_new_name := var_name || ' (' || var_name_id || ')';
( var_name contains the name I'm trying to insert.)
So far this works, but the problem is the WHERE statement:
WHERE a.name LIKE var_name || ' (%)'
This check does not verify that the % question is a number, and does not take into account several parentheses, as in something like "Name ((1))", and if in any case there was a cast exception, be thrown.
The WHERE statement should really be something like:
WHERE a.r1_name ~* var_name || E' \\(\\d+\\)'
But var_name may contain var_name characters, which leads to the question above: is there a function in PostgreSQL that escapes regex characters in a string, so I could do something like:
WHERE a.r1_name ~* regex_escape(var_name) || E' \\(\\d+\\)'
Any suggestions are welcome, including a possible rework of my solution with duplicate names.