Thread: Using regexp_matches in the WHERE clause

Using regexp_matches in the WHERE clause

From
Thomas Kellerer
Date:
Hi,

I stumbled over this question on Stackoverflow
   http://stackoverflow.com/questions/13564369/postgresql-using-column-data-as-pattern-for-regexp-match

And my initial reaction was, that this should be possible using regexp_matches.

So I tried:
   SELECT *   FROM some_table   WHERE regexp_matches(somecol, 'foobar') is not null;

However that resulted in: ERROR: argument of WHERE must not return a set

Hmm, even though an array is not a set I can partly see what the problem is
(although given the really cool array implementation in PostgreSQL I was a bit surprised).


So I though, if I convert this to an integer, it should work:
  SELECT *  FROM some_table  WHERE array_length(regexp_matches(somecol, 'foobar'), 1) > 0

but that still results in the same error.

But array_length() clearly returns an integer, so why does it still throw this error?


I'm using 9.2.1

Regards
Thomas





Re: Using regexp_matches in the WHERE clause

From
Willem Leenen
Date:
 
Sounds to me like this:
 
http://joecelkothesqlapprentice.blogspot.nl/2007/12/using-where-clause-parameter.html
 

 
> To: pgsql-sql@postgresql.org
> From: spam_eater@gmx.net
> Subject: [SQL] Using regexp_matches in the WHERE clause
> Date: Mon, 26 Nov 2012 13:13:06 +0100
>
> Hi,
>
> I stumbled over this question on Stackoverflow
>
> http://stackoverflow.com/questions/13564369/postgresql-using-column-data-as-pattern-for-regexp-match
>
> And my initial reaction was, that this should be possible using regexp_matches.
>
> So I tried:
>
> SELECT *
> FROM some_table
> WHERE regexp_matches(somecol, 'foobar') is not null;
>
> However that resulted in: ERROR: argument of WHERE must not return a set
>
> Hmm, even though an array is not a set I can partly see what the problem is
> (although given the really cool array implementation in PostgreSQL I was a bit surprised).
>
>
> So I though, if I convert this to an integer, it should work:
>
> SELECT *
> FROM some_table
> WHERE array_length(regexp_matches(somecol, 'foobar'), 1) > 0
>
> but that still results in the same error.
>
> But array_length() clearly returns an integer, so why does it still throw this error?
>
>
> I'm using 9.2.1
>
> Regards
> Thomas
>
>
>
>
> --
> Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-sql

Re: Using regexp_matches in the WHERE clause

From
Thomas Kellerer
Date:
>  > So I tried:
>  >
>  > SELECT *
>  > FROM some_table
>  > WHERE regexp_matches(somecol, 'foobar') is not null;
>  >
>  > However that resulted in: ERROR: argument of WHERE must not return a set
>  >
>  > Hmm, even though an array is not a set I can partly see what the problem is
>  > (although given the really cool array implementation in PostgreSQL I was a bit surprised).
>  >
>  >
>  > So I though, if I convert this to an integer, it should work:
>  >
>  > SELECT *
>  > FROM some_table
>  > WHERE array_length(regexp_matches(somecol, 'foobar'), 1) > 0
>  >
>  > but that still results in the same error.
>  >
>  > But array_length() clearly returns an integer, so why does it still throw this error?
>  >
>  >
>  > I'm using 9.2.1
>  >

> Sounds to me like this:
>
> http://joecelkothesqlapprentice.blogspot.nl/2007/12/using-where-clause-parameter.html
>

Thanks, but my question is not related to the underlying problem.

My question is: why I cannot use regexp_matches() in the WHERE clause, even when the result is clearly an integer
value?

Regards
Thomas






Re: Using regexp_matches in the WHERE clause

From
Pavel Stehule
Date:
Hello

2012/11/27 Thomas Kellerer <spam_eater@gmx.net>:
>>  > So I tried:
>>  >
>>  > SELECT *
>>  > FROM some_table
>>  > WHERE regexp_matches(somecol, 'foobar') is not null;
>>  >
>>  > However that resulted in: ERROR: argument of WHERE must not return a
>> set
>>  >
>>  > Hmm, even though an array is not a set I can partly see what the
>> problem is
>>  > (although given the really cool array implementation in PostgreSQL I
>> was a bit surprised).
>>  >
>>  >
>>  > So I though, if I convert this to an integer, it should work:
>>  >
>>  > SELECT *
>>  > FROM some_table
>>  > WHERE array_length(regexp_matches(somecol, 'foobar'), 1) > 0
>>  >
>>  > but that still results in the same error.
>>  >
>>  > But array_length() clearly returns an integer, so why does it still
>> throw this error?
>>  >
>>  >
>>  > I'm using 9.2.1
>>  >
>
>
>> Sounds to me like this:
>>
>>
>> http://joecelkothesqlapprentice.blogspot.nl/2007/12/using-where-clause-parameter.html
>>
>
> Thanks, but my question is not related to the underlying problem.
>
> My question is: why I cannot use regexp_matches() in the WHERE clause, even
> when the result is clearly an integer value?
>

use a ~ operator instead

postgres=# select * from o where a ~ 'e';  a
--------pavelzdenek
(2 rows)


postgres=# select * from o where a ~ 'k$';  a
--------zdenek
(1 row)

you can use regexp_matches, but it is not effective probably

postgres=# select * from o where exists (select * from
regexp_matches(o.a,'ne'));  a
--------zdenek
(1 row)

Regards

Pavel Stehule


>
> Regards
> Thomas
>
>
>
>
>
> --
> Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-sql



Re: Using regexp_matches in the WHERE clause

From
Thomas Kellerer
Date:
Pavel Stehule, 27.11.2012 13:26:
>> My question is: why I cannot use regexp_matches() in the WHERE clause, even
>> when the result is clearly an integer value?
>>
>
> use a ~ operator instead
>

So that means, regexp_matches cannot be used as an expression in the WHERE clause?

Regards
Thomas






Re: Using regexp_matches in the WHERE clause

From
Pavel Stehule
Date:
2012/11/27 Thomas Kellerer <spam_eater@gmx.net>:
> Pavel Stehule, 27.11.2012 13:26:
>
>>> My question is: why I cannot use regexp_matches() in the WHERE clause,
>>> even
>>> when the result is clearly an integer value?
>>>
>>
>> use a ~ operator instead
>>
>
> So that means, regexp_matches cannot be used as an expression in the WHERE

should not be used - it is designed to return matched values, no for
returning true or false,

you can do some obscure
postgres=# select * from o where array(select
(regexp_matches(a,'ne'))[1]) <> '{}'::text[];  a
--------zdenek
(1 row)

but it is not recommended.

Regards

Pavel

> clause?
>
>
> Regards
> Thomas
>
>
>
>
>
> --
> Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-sql



Re: Using regexp_matches in the WHERE clause

From
David Johnston
Date:
On Nov 26, 2012, at 7:13, Thomas Kellerer <spam_eater@gmx.net> wrote:

>
> So I tried:
>
>   SELECT *
>   FROM some_table
>   WHERE regexp_matches(somecol, 'foobar') is not null;
>
> However that resulted in: ERROR: argument of WHERE must not return a set
>
> Hmm, even though an array is not a set I can partly see what the problem is
> (although given the really cool array implementation in PostgreSQL I was a bit surprised).
>

regex_matches returns a set because you can supply the "g" option to capture all matches and each separate match
returnsits own record.  Even though only one record is ever returned without the "g" option the function itself is the
sameand still is defined to return a set. 

David J.


Re: Using regexp_matches in the WHERE clause

From
spulatkan
Date:
I noticed that regexp_matches already returns the rows which matches the
regular expression

now when I make a full table select query


but if I make a search with regexp_matches, it only returns rows that
matches regular expression


on pgadmin the column type is shown as text[] thus I also do not understand
why array_length on where condition does not work for this.



But maybe as it was pointed out, the return type is setof text[], that the
result could have been like this (one row of data may result in multiple
rows)


If you have a regular expression that may end in one or more elements in the
text[] then you may use inner query


ps: last query is pointless as it will return 2 elements for each row (that
matches the regular expression), but there may be a regular expression that
may return one or more elements for each row



--
View this message in context:
http://postgresql.1045698.n5.nabble.com/Using-regexp-matches-in-the-WHERE-clause-tp5733684p5768923.html
Sent from the PostgreSQL - sql mailing list archive at Nabble.com.



Re: Using regexp_matches in the WHERE clause

From
David Johnston
Date:
spulatkan wrote
> so following is enough to get the rows that matches regular expression

> 

This is bad form even if it works.  If the only point of the expression is
to filter rows it should appear in the WHERE clause.  The fact that
regexp_matches(...) behaves in this way at all is, IMO, a flaw of the
implementation.


> on pgadmin the column type is shown as text[] thus I also do not
> understand why array_length on where condition does not work for this.

> 

This works because the array_length formula is applied once to each "row" of
the returned set.  

As mentioned before it makes absolutely no sense to evaluate a set-returning
function within the WHERE clause and so attempting to do so causes a fatal
exception.  For my usage I've simply written a wrapper function that
implements the same basic API as regexp_matches but that returns a scalar
"text[]" instead of a "setof text[]".  It makes coding these kinds of
queries easier if you know/understand the fact that your matching will never
cause more than 1 row to be returned.  If zero rows are returned I return an
empty array and the normal 1-row case returns the matching array.

David J.






--
View this message in context:
http://postgresql.1045698.n5.nabble.com/Using-regexp-matches-in-the-WHERE-clause-tp5733684p5768926.html
Sent from the PostgreSQL - sql mailing list archive at Nabble.com.