Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Operator ~<~ in Postgres

(Originally part of this question, but it was bit irrelevant, so I decided to make it a question of its own.)

I cannot find what the operator ~<~ is. The Postgres manual only mentions ~ and similar operators here, but no sign of ~<~.

When fiddling in the psql console, I found out that these commands give the same results:

SELECT * FROM test ORDER BY name USING ~<~;
SELECT * FROM test ORDER BY name COLLATE "C";

And these gives the reverse ordering:

SELECT * FROM test ORDER BY name USING ~>~;
SELECT * FROM test ORDER BY name COLLATE "C" DESC;

Also some info on the tilde operators:

\do ~*~
                                    List of operators
  Schema   | Name | Left arg type | Right arg type | Result type |       Description       
------------+------+---------------+----------------+-------------+-------------------------
pg_catalog | ~<=~ | character     | character      | boolean     | less than or equal
pg_catalog | ~<=~ | text          | text           | boolean     | less than or equal
pg_catalog | ~<~  | character     | character      | boolean     | less than
pg_catalog | ~<~  | text          | text           | boolean     | less than
pg_catalog | ~>=~ | character     | character      | boolean     | greater than or equal
pg_catalog | ~>=~ | text          | text           | boolean     | greater than or equal
pg_catalog | ~>~  | character     | character      | boolean     | greater than
pg_catalog | ~>~  | text          | text           | boolean     | greater than
pg_catalog | ~~   | bytea         | bytea          | boolean     | matches LIKE expression
pg_catalog | ~~   | character     | text           | boolean     | matches LIKE expression
pg_catalog | ~~   | name          | text           | boolean     | matches LIKE expression
pg_catalog | ~~   | text          | text           | boolean     | matches LIKE expression
(12 rows)

The 3rd and 4th rows is the operator I'm looking for, but the description is a bit insufficient for me.

like image 626
Vojtech Sokol Avatar asked Mar 04 '16 23:03

Vojtech Sokol


1 Answers

~>=~, ~<=~, ~>~ and ~<~ are text pattern (or varchar, basically the same) operators, the counterparts of their respective siblings >=, <=, >and <. They sort character data strictly by their byte values, ignoring rules of any collation setting (as opposed to their siblings). This makes them faster, but also invalid for most languages / countries.

The "C" locale is effectively the same as no locale, meaning no collation rules. That explains why ORDER BY name USING ~<~ and ORDER BY name COLLATE "C" end up doing the same. The latter syntax variant should be preferred: more standard, less error-prone.

Detailed explanation in the last chapter of this related answer on dba.SE:

  • Pattern matching with LIKE, SIMILAR TO or regular expressions in PostgreSQL

Note that ~~ / ~~* are Postgres operators for LIKE / ILIKE and barely related to the above. Similarly, !~~ / !~~* for NOT LIKE / NOT IILKE. (Use standard LIKE notation instead of these "internal" operators.)

Related:

  • ~~ Operator In Postgres
  • Symfony2 Doctrine - ILIKE clause for PostgreSQL?
  • Find rows where text array contains value similar to input
like image 63
Erwin Brandstetter Avatar answered Sep 25 '22 01:09

Erwin Brandstetter