0

I am trying to run the below query in a stored procedure and its not working. We tried to print the query using NOTICE and we saw E gets appended to the regex and thats the reason the query doesnt show any output.

Not working

select order,version from mytable
where substring(version  from quote_literal('[0-9]+\.[0-9]{1}'))
IN ('6.2') and order= 'ABC';

But the same query if i run from pgadmin query tool, it works fine.

Working

select order,version  from mytable
where substring(version from '[0-9]+\.[0-9]{1}')
IN ('6.2') and order= 'ABC';

My requirement is to form the reqex dynamically in the stored procedure. Please guide on how to achieve this.

Below is the line of code in my stored procedure,

sql_query = sql_query || ' AND substring(version from ' || quote_literal( '[0-9]+\.[0-9]{1}' ) || ') IN (' || quote_literal(compatibleVersions) || ')';
raise notice 'Value: %', sql_query;                                        
EXECUTE sql_query  INTO query_result ;

and from notice i am getting the below output,

AND substring(version from E'[0-9]+\\.[0-9]{1}') IN ('{6.2}')

My requirement is to make this regex work.

I narrowed down to this query,

working

select substring(version from '[0-9]+\.[0-9]{1}') from mytable ;

not working

select substring(version from quote_literal('[0-9]+\.[0-9]{1}')) from mytable ;

Now i think its easy to fix it. You can try at your end also running this above queries.

7
  • 1
    quote_literal() is only needed in dynamic SQL. You don't need it in static SQL. So just use the working version. Commented Mar 14, 2019 at 14:53
  • Thanks for the reply. i intended to form the query dynamically inside the stored procedure by appending dynamic where conditions. Commented Mar 14, 2019 at 14:56
  • If I see that correctly, [0-9]{1} is the same as [0-9]. Also, you can use \d as a shorthand for [0-9]. See this link in Table 9-17. Commented Mar 14, 2019 at 14:58
  • 1
    What's wrong with using a string constant that starts with E? I guess you should show some of the failing code. Commented Mar 14, 2019 at 14:59
  • edit your question. Do not post code in comments. Commented Mar 14, 2019 at 15:13

2 Answers 2

1

Since your problem is not really the extended string literal syntax using E, but the string representation of the array in the IN list, your PL/pgSQL should look somewhat like this:

sql_query = sql_query ||
            ' AND substring(version from ' || quote_literal( '[0-9]+\.[0-9]{1}' ) ||
                ') IN (' || (SELECT string_agg(quote_literal(x), ', ')
                             FROM unnest(compatibleVersions
                            ) AS x(x)) || ')';
Sign up to request clarification or add additional context in comments.

Comments

0

quote_literal should be used in situations where u want to dynamically construct queries. In such situation quote_literal will be replaced by E in the final constructed query.

right way to use

select * from config_support_module where substring(firmware from '[0-9]+\.[0-9]{1}') IN ('6.2');


select * from config_support_module where substring(firmware from E'[0-9]+\.[0-9]{1}') IN ('6.2') ;

wrong usage of quote_literal in static queries

select * from config_support_module where substring(firmware from quote_literal('[0-9]+\.[0-9]{1}')) IN ('6.2') ;
 This doesnt give you any errors/output.

quote_literal usage in dynamic queries

sql_query = sql_query || ' AND substring(version from ' || quote_literal( '[0-9]+\.[0-9]{1}' ) || ') ... .. ...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.