Postgres escaping backslash in SIMILAR TO syntax - postgresql

I have table containing 4 lines as follow:
Audit\\subfolder\System2.log
Audit\\subfolder/System1.log
Audit\\System2.log
Audit\\System1.log
Running the following query:
select * from table where file_location SIMILAR TO
'Audit\\[^/]*'
will yield:
Audit\\subfolder\System2.log
Audit\\System2.log
Audit\\System1.log
However running the following query:
select * from table where file_location SIMILAR TO
'Audit\\[^\\]*'
yields me nothing.
What would be the correct way to escape \\ in SIMILAR TO clause?

What would be the correct way to escape \ in SIMILAR TO clause?
Using ESCAPE might be a natural choice:
SELECT *
FROM table1
WHERE file_location SIMILAR TO 'Audit\\[^!\]*' ESCAPE '!'
Here is SQLFiddle demo

Related

POSTGRESQL Dollar Quotes in Where Clause

For people who tried or needed a solution to escape every special character (even $) in a WHERE CLAUSE in POSTGRESQL, here is how it should be use
the documentation can be somehow hard to understand, and there is no proper example of it so here is mine
e.g : if you want to make a request looking as
SELECT
*
FROM
<TableName>
WHERE
<ColumnName> = 'string with ' character';
it will throw an error cause "character'" is outside the string
So here is how it should be written:
SELECT
*
FROM
<TableName>
WHERE
<ColumnName> = $$string with ' character$$;
The WHERE CONDITION will take the string literally; the interface may look broken but the following instruction will still be interpreted as expected.
SELECT
*
FROM
<TableName>
WHERE
<ColumnName> = $$string with ' character$$ AND <OtherColumnName> IS NOT NULL;
This could even be another escaped string with $$.
For details about dollar quoting, look at the documentation.

How to match a backslash with the like operator in Redshift

How can I match a backslash with the like operator in Redshift?
I tried below, but they didn't work…
-- syntax error
select 'a\a' like '\';
-- false
select 'a\a' like '\\';
-- syntax error
select 'a\a' like '\\\';
-- syntax error
select 'a\a' like '\' escape '^';
-- syntax error
select 'a\a' like '^\' escape '^';
Envelope it with %:
select 'a\a' like '%\\%';

How to get output of a sql with additional special characters

Long story...
I am trying to geenrate a crosstab query dynamically and run it as a psql script..
To achieve this, I want the last line of the sql to generated and appended to the top portion of the sql.
The last line of the sql is like this.... "as final_result(symbol character varying,"431" numeric,"432" numeric,"433" numeric);"
Of which, the "431", "432" etc are to be generated dynamically as these are the pivot columns and they change from time to time...
So I wrote a query to output the text as follows....
psql -c "select distinct '"'||runweek||'" numeric ,' from calendar where runweek between current_runweek()-2 and current_runweek() order by 1;" -U USER -d DBNAME > /tmp/gengen.lst
While the sql provides the output, when I run it as a script, because of the special characters (', "", ) it fails.
How should I get it working? My plan was then loop through the "lst" file and build the pivot string, and append that to the top portion of the sql and execute the script... (New to postgres, does not know , dynamic sql generation and execution etc.. but I am comfortable with UNIX scripting..)
If I could somehow get the output as
("431" numeric, "432" numeric....etc) in a single step, if there is a recommendation to achieve this, it will be greatly appreciated.....
Since you're using double quotes around the argument, double quotes inside the argument must be escaped with a backslash:
psql -c "select distinct '\"'||runweek||'\" numeric ,' from calendar where runweek between current_runweek()-2 and current_runweek() order by 1;"
Heredoc can also be used instead of -c. It accepts multi-line formatting so that makes the whole thing more readable.
(psql [arguments] <<EOF
select distinct '"'||runweek||'" numeric ,'
from calendar
where runweek between current_runweek()-2 and current_runweek()
order by 1;
EOF
) > output
By using quote_ident which is specifically meant to produce a quoted identifier from a text value, you don't even need to add the double quotes. The query could be like:
select string_agg( quote_ident(runweek::text), ',' order by runweek)
from calendar
where runweek between current_runweek()-2 and current_runweek();
which also solves the problem that your original query has a stray ',' at the end, whereas this form does not.

Anorm: Escape { for Postgres

I want to execute query like this:
SELECT '{"a":[1,2,3],"b":[4,5,6]}'::json#>>'{a,2}'
But anorm can not prepare the query and raise the parse error.
How to escape the '{' and '}' symbols in SQL text for anorm?
Update:
the solution is a pretty simple (like RTFM:) )
SELECT '{"a":[1,2,3],"b":[4,5,6]}'::json#>>'{a,2}'
should be
SELECT '{"a":[1,2,3],"b":[4,5,6]}'::json->'a'->>2
there are no symbols '{', '}' so Anorm is happy.
You can pass the values as stings which contain curly braces
Look at this example
SELECT '{}'::jsonb;
so I replaced it with binding
SELECT {empty}::jsonb;
And passed this named param on executing the query
NamedParameter("empty", "{}")

PostgreSQL - how to check if my data contains a backslash

SELECT count(*) FROM table WHERE column ilike '%/%';
gives me the number of values containing "/"
How to do the same for "\"?
SELECT count(*)
FROM table
WHERE column ILIKE '%\\\\%';
Excerpt from the docs:
Note that the backslash already has a special meaning in string literals, so to write a pattern constant that contains a backslash you must write two backslashes in an SQL statement (assuming escape string syntax is used, see Section 4.1.2.1). Thus, writing a pattern that actually matches a literal backslash means writing four backslashes in the statement. You can avoid this by selecting a different escape character with ESCAPE; then a backslash is not special to LIKE anymore. (But it is still special to the string literal parser, so you still need two of them.)
Better yet - don't use like, just use standard position:
select count(*) from table where 0 < position( E'\\' in column );
I found on 12.5 I did not need an escape character
# select * from t;
x
-----
a/b
c\d
(2 rows)
# select count(*) from t where 0 < position('/' in x);
count
-------
1
(1 row)
# select count(*) from t where 0 < position('\' in x);
count
-------
1
(1 row)
whereas on 9.6 I did.
Bit strange but there you go.
Usefully,
position(E'/' in x)
worked on both versions.
You need to be careful - E'//' seems to work (i.e. parses) but does not actually find a slash.
You need E'\\\\' because the argument to LIKE is a regex and regex escape char is already \ (e.g ~ E'\\w' would match any string containing a printable char).
See the doc