How does PostgreSQL compare strings? I'm running Postgresql 9.6 on Ubuntu 16.04. The collation order is en_ZA.UTF-8. I'm puzzled by how Postgres compares strings:

test=&gt; select 'b' &gt; 'B';
 ?column? 
----------
  f

test=&gt; select 'ba' &gt; 'B';
?column? 
----------
  t

test=&gt; select 'b' = 'B';
?column? 
----------
  f

test=&gt; select 'ba' &gt; 'C';
 ?column?  
----------
 f


The response to the second query doesn't make sense to me.
That's just how your locale defines sort order. Obviously  upper case letters act as tiebreakers if the string is otherwise identical - then they sort after lower case equivalents. But 'ba' still sorts after 'B' (and 'BA' sorts after 'b').

Compare to results without collation rules:

SELECT   'b' &gt; 'B'
      , 'ba' &gt; 'B'
      , 'ba' &gt; 'C'
      , 'b'  &gt; 'B' COLLATE "C"
      , 'ba' &gt; 'B' COLLATE "C"
      , 'ba' &gt; 'C' COLLATE "C";



 ?column? | ?column? | ?column? | ?column? | ?column? | ?column?
----------+----------+----------+----------+----------+----------
 f        | t        | f        | t        | t        | t



(My current collation setting German_Germany.1252 happens to behave just like your en_ZA.UTF-8.)