Skip to main content
format, clarify
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k

"stringexpression is either null or empty"

So toTo check for: "stringexpression is either null or empty" this, use:

Works for any any charactercharacter type including char(n).   
The manual about comparison operators.

Or use your original expression without trim(), which iswould be costly noise for char(n) (see below), or incorrect for other character types: strings consisting of only spaces would pass as empty string.

"stringexpression is neither null nor empty"

Asserting the opposite is even simpler: "stringexpression is neither null nor empty":

About char(n)

Either way, document your exact intention in an added comment if there is room for ambiguity.

About char(n)

This is about theThe data type char(n), is short for: character(n). ( 
char / character are short for char(1) / character(1).
bpchar is an internal alias of character. (Think "blank-padded character".) Its
This data type is supported for historical reasons and for compatibility with the SQL standard, but its use is discouraged in Postgresdiscouraged in Postgres:

So to check for: "stringexpression is either null or empty":

Works for any character type including char(n).  The manual about comparison operators.

Or use your original expression without trim(), which is costly noise for char(n) (see below), or incorrect for other character types: strings consisting of only spaces would pass as empty string.

Asserting the opposite is even simpler: "stringexpression is neither null nor empty":

About char(n)

This is about the data type char(n), short for: character(n). (char / character are short for char(1) / character(1).) Its use is discouraged in Postgres:

"stringexpression is either null or empty"

To check for this, use:

Works for any character type including char(n). 
The manual about comparison operators.

Or use your original expression without trim(), which would be costly noise for char(n) (see below), or incorrect for other character types: strings consisting of only spaces would pass as empty string.

"stringexpression is neither null nor empty"

Asserting the opposite is simpler:

Either way, document your exact intention in an added comment if there is room for ambiguity.

About char(n)

The data type char(n) is short for character(n). 
char / character are short for char(1) / character(1).
bpchar is an internal alias of character. (Think "blank-padded character".)
This data type is supported for historical reasons and for compatibility with the SQL standard, but its use is discouraged in Postgres:

markup, format
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k

TRUEtrue   .. for '' (or for any string consisting of only spaces with the data type char(n))
NULLnull   .. for NULLnull
FALSEfalse .. for anything else

So to check for: "stringexpression is either NULLnull or empty":

Asserting the opposite is even simpler: "stringexpression is neither NULLnull nor empty":

SELECT stringexpression 
     , stringexpression = ''                   AS base_test
     , (stringexpression = '')  IS NOT FALSE   AS test1
     , (stringexpression <> '') IS NOT TRUE    AS test2
     , coalesce(stringexpression, '') = ''     AS coalesce1
     , coalesce(stringexpression, '  ') = '  ' AS coalesce2
     , coalesce(stringexpression, '') = '  '   AS coalesce3
FROM  (
   VALUES
     ('foo'::char(5))
   , ('')
   , ('   ')                -- not different from '' in char(n)
   , (NULL)
   ) sub(stringexpression);
SELECT stringexpression 
     , stringexpression = ''                   AS base_test
     , (stringexpression = '')  IS NOT FALSE   AS test1
     , (stringexpression <> '') IS NOT TRUE    AS test2
     , coalesce(stringexpression, '') = ''     AS coalesce1
     , coalesce(stringexpression, '  ') = '  ' AS coalesce2
     , coalesce(stringexpression, '') = '  '   AS coalesce3
FROM  (
   VALUES
     ('foo'::char(5))
   , ('')
   , ('   ')                -- not different from '' in char(n)
   , (null)
   ) sub(stringexpression);
SELECT stringexpression 
     , stringexpression = ''                   AS base_test
     , (stringexpression = '')  IS NOT FALSE   AS test1
     , (stringexpression <> '') IS NOT TRUE    AS test2
     , coalesce(stringexpression, '') = ''     AS coalesce1
     , coalesce(stringexpression, '  ') = '  ' AS coalesce2
     , coalesce(stringexpression, '') = '  '   AS coalesce3
FROM  (
   VALUES
     ('foo'::text)
   , ('')
   , ('   ')                -- different from '' in a sane character types
   , (NULLnull)
   ) sub(stringexpression);

TRUE   .. for '' (or for any string consisting of only spaces with the data type char(n))
NULL   .. for NULL
FALSE .. for anything else

So to check for: "stringexpression is either NULL or empty":

Asserting the opposite is even simpler: "stringexpression is neither NULL nor empty":

SELECT stringexpression 
     , stringexpression = ''                   AS base_test
     , (stringexpression = '')  IS NOT FALSE   AS test1
     , (stringexpression <> '') IS NOT TRUE    AS test2
     , coalesce(stringexpression, '') = ''     AS coalesce1
     , coalesce(stringexpression, '  ') = '  ' AS coalesce2
     , coalesce(stringexpression, '') = '  '   AS coalesce3
FROM  (
   VALUES
     ('foo'::char(5))
   , ('')
   , ('   ')                -- not different from '' in char(n)
   , (NULL)
   ) sub(stringexpression);
SELECT stringexpression 
     , stringexpression = ''                   AS base_test
     , (stringexpression = '')  IS NOT FALSE   AS test1
     , (stringexpression <> '') IS NOT TRUE    AS test2
     , coalesce(stringexpression, '') = ''     AS coalesce1
     , coalesce(stringexpression, '  ') = '  ' AS coalesce2
     , coalesce(stringexpression, '') = '  '   AS coalesce3
FROM  (
   VALUES
     ('foo'::text)
   , ('')
   , ('   ')                -- different from '' in a sane character types
   , (NULL)
   ) sub(stringexpression);

true   .. for '' (or for any string consisting of only spaces with the data type char(n))
null   .. for null
false .. for anything else

So to check for: "stringexpression is either null or empty":

Asserting the opposite is even simpler: "stringexpression is neither null nor empty":

SELECT stringexpression 
     , stringexpression = ''                   AS base_test
     , (stringexpression = '')  IS NOT FALSE   AS test1
     , (stringexpression <> '') IS NOT TRUE    AS test2
     , coalesce(stringexpression, '') = ''     AS coalesce1
     , coalesce(stringexpression, '  ') = '  ' AS coalesce2
     , coalesce(stringexpression, '') = '  '   AS coalesce3
FROM  (
   VALUES
     ('foo'::char(5))
   , ('')
   , ('   ')                -- not different from '' in char(n)
   , (null)
   ) sub(stringexpression);
SELECT stringexpression 
     , stringexpression = ''                   AS base_test
     , (stringexpression = '')  IS NOT FALSE   AS test1
     , (stringexpression <> '') IS NOT TRUE    AS test2
     , coalesce(stringexpression, '') = ''     AS coalesce1
     , coalesce(stringexpression, '  ') = '  ' AS coalesce2
     , coalesce(stringexpression, '') = '  '   AS coalesce3
FROM  (
   VALUES
     ('foo'::text)
   , ('')
   , ('   ')                -- different from '' in sane character types
   , (null)
   ) sub(stringexpression);
clarify, denoise, add quote: char(n) discouraged; update markup, links, fiddle
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k

TRUE   .. for '' (or for any string consisting of only spaces with the data type char(n))
NULL   .. for NULL
FALSE .. for anythinganything else

Works for any character type including the obsolescent char(n) which is hardly ever useful.
   The manual about comparison operators.

OrOr use theyour original expression you already had, just without the trim()trim(), which would be uselessis costly noise for char(n)  (see below), or it would include strings consisting of only spaces in the testincorrect for other character types: strings consisting of only spaces would pass as empty string.

Asserting the opposite is even simpler: "stringexpression is neither NULL nor empty" is even simpler:

About char(n)

###About char(n) Do not confuse this data type with other character types like varchar(n), varchar, text or "char" (with quotes), which are all useful data types. This is about the outdated data type with very limited usefulness: char(n), short for: character(n). Also, (char and/ character are short for char(1) / character(1).) Its use is discouraged in Postgres:

In most situations text or character varying should be used instead.

Do not confuse char(n) with other, useful, character types varchar(n), varchar, text or "char" (same thingwith double-quotes).

In char(n) (unlike other string types!) an empty string is not different from any other string consisting of only spaces. All of these are folded to n spaces in char(n) per definition of the type. It follows logically that this worksthe above expressions work for char(n) as well:

coalesce(stringexpression, '') = ''

Just - just as much as these (which wouldn't work for other character types):

###Demo

Demo

SELECT ''::char(5) = ''::char(5)     AS eq1
      , ''::char(5) = '  '::char(5)   AS eq2
      , ''::char(5) = '    '::char(5) AS eq3;
eq1 | eq2 | eq3
----+-----+----
t   | t   | t  

Result:

 eq1 | eq2 | eq3
 ----+-----+----
 t   | t   | t
SELECT stringexpression 
      , stringexpression = ''                    AS simple_testbase_test
      , (stringexpression = '')  IS NOT FALSE    AS test1
      , (stringexpression <> '') IS NOT TRUE     AS test2
      , coalesce(stringexpression, '') = ''      AS test_coalesce1coalesce1
      , coalesce(stringexpression, '  ') = '  '  AS test_coalesce2coalesce2
      , coalesce(stringexpression, '') = '  '    AS test_coalesce3coalesce3
FROM  (
   VALUES
     ('foo'::char(5))
   , ('')
   , (NULL)
   , ('   ')                -- not different from '' in char(n)
   , (NULL)
   ) sub(stringexpression);
 stringexpression | simple_test | test1 | test2 | test_coalesce1 | test_coalesce2 | test_coalesce3
------------------+-------------+-------+-------+----------------+----------------+----------------
 foo              | f           | f     | f     | f              | f              | f
                  | t           | t     | t     | t              | t              | t
                  |             | t     | t     | t              | t              | t
                  | t           | t     | t     | t              | t              | t

Result:


 stringexpression | base_test | test1 | test2 | coalesce1 | coalesce2 | coalesce3 
------------------+-----------+-------+-------+-----------+-----------+-----------
 foo              | f         | f     | f     | f         | f         | f
                  | t         | t     | t     | t         | t         | t
                  | t         | t     | t     | t         | t         | t
 null             | null      | t     | t     | t         | t         | t

Test for "null or empty string" with text:

SELECT stringexpression 
      , stringexpression = ''                    AS simple_testbase_test
      , (stringexpression = '')  IS NOT FALSE    AS test1
      , (stringexpression <> '') IS NOT TRUE     AS test2
      , coalesce(stringexpression, '') = ''      AS test_coalesce1coalesce1
      , coalesce(stringexpression, '  ') = '  '  AS test_coalesce2coalesce2
      , coalesce(stringexpression, '') = '  '    AS test_coalesce3coalesce3
FROM  (
   VALUES
     ('foo'::text)
   , ('')
   , (NULL)
   , ('   ')                -- different from '' in a sane character typetypes
 like text , (NULL)
   ) sub(stringexpression);
 stringexpression | simple_test | test1 | test2 | test_coalesce1 | test_coalesce2 | test_coalesce3
------------------+-------------+-------+-------+----------------+----------------+----------------
 foo              | f           | f     | f     | f              | f              | f
                  | t           | t     | t     | t              | f              | f
                  |             | t     | t     | t              | t              | f
                  | f           | f     | f     | f              | f              | f

Result:


 stringexpression | base_test | test1 | test2 | coalesce1 | coalesce2 | coalesce3 
------------------+-----------+-------+-------+-----------+-----------+-----------
 foo              | f         | f     | f     | f         | f         | f
                  | t         | t     | t     | t         | f         | f
                  | f         | f     | f     | f         | f         | f
 null             | null      | t     | t     | t         | t         | f

dbfiddle heredb<>fiddle here
Old Old SQL Fiddlesqlfiddle

TRUE   .. for '' (or for any string consisting of only spaces with the data type char(n))
NULL   .. for NULL
FALSE .. for anything else

Works for any character type including the obsolescent char(n) which is hardly ever useful.
 The manual about comparison operators.

Or use the expression you already had, just without the trim() which would be useless for char(n)(see below), or it would include strings consisting of only spaces in the test for other character types:

Asserting the opposite: "stringexpression is neither NULL nor empty" is even simpler:

###About char(n) Do not confuse this data type with other character types like varchar(n), varchar, text or "char" (with quotes), which are all useful data types. This is about the outdated data type with very limited usefulness: char(n), short for: character(n). Also, char and character are short for char(1) / character(1) (same thing).

In char(n) (unlike other string types!) an empty string is not different from any other string consisting of only spaces. All of these are folded to n spaces in char(n) per definition of the type. It follows logically that this works for char(n) as well:

coalesce(stringexpression, '') = ''

Just as much as these (which wouldn't work for other character types):

###Demo

SELECT ''::char(5) = ''::char(5)     AS eq1
      ,''::char(5) = '  '::char(5)   AS eq2
      ,''::char(5) = '    '::char(5) AS eq3;
eq1 | eq2 | eq3
----+-----+----
t   | t   | t  
SELECT stringexpression 
      ,stringexpression = ''                    AS simple_test
      ,(stringexpression = '')  IS NOT FALSE    AS test1
      ,(stringexpression <> '') IS NOT TRUE     AS test2
      ,coalesce(stringexpression, '') = ''      AS test_coalesce1
      ,coalesce(stringexpression, '  ') = '  '  AS test_coalesce2
      ,coalesce(stringexpression, '') = '  '    AS test_coalesce3
FROM  (
   VALUES
     ('foo'::char(5))
   , ('')
   , (NULL)
   , ('   ')                -- not different from '' in char(n)
   ) sub(stringexpression);
 stringexpression | simple_test | test1 | test2 | test_coalesce1 | test_coalesce2 | test_coalesce3
------------------+-------------+-------+-------+----------------+----------------+----------------
 foo              | f           | f     | f     | f              | f              | f
                  | t           | t     | t     | t              | t              | t
                  |             | t     | t     | t              | t              | t
                  | t           | t     | t     | t              | t              | t

Test for "null or empty string" with text

SELECT stringexpression 
      ,stringexpression = ''                    AS simple_test
      ,(stringexpression = '')  IS NOT FALSE    AS test1
      ,(stringexpression <> '') IS NOT TRUE     AS test2
      ,coalesce(stringexpression, '') = ''      AS test_coalesce1
      ,coalesce(stringexpression, '  ') = '  '  AS test_coalesce2
      ,coalesce(stringexpression, '') = '  '    AS test_coalesce3
FROM  (
   VALUES
     ('foo'::text)
   , ('')
   , (NULL)
   , ('   ')                -- different from '' in a sane character type like text
   ) sub(stringexpression);
 stringexpression | simple_test | test1 | test2 | test_coalesce1 | test_coalesce2 | test_coalesce3
------------------+-------------+-------+-------+----------------+----------------+----------------
 foo              | f           | f     | f     | f              | f              | f
                  | t           | t     | t     | t              | f              | f
                  |             | t     | t     | t              | t              | f
                  | f           | f     | f     | f              | f              | f

dbfiddle here
Old SQL Fiddle

TRUE   .. for '' (or for any string consisting of only spaces with the data type char(n))
NULL   .. for NULL
FALSE .. for anything else

Works for any character type including char(n).  The manual about comparison operators.

Or use your original expression without trim(), which is costly noise for char(n)  (see below), or incorrect for other character types: strings consisting of only spaces would pass as empty string.

Asserting the opposite is even simpler: "stringexpression is neither NULL nor empty":

About char(n)

This is about the data type char(n), short for: character(n). (char / character are short for char(1) / character(1).) Its use is discouraged in Postgres:

In most situations text or character varying should be used instead.

Do not confuse char(n) with other, useful, character types varchar(n), varchar, text or "char" (with double-quotes).

In char(n) an empty string is not different from any other string consisting of only spaces. All of these are folded to n spaces in char(n) per definition of the type. It follows logically that the above expressions work for char(n) as well - just as much as these (which wouldn't work for other character types):

Demo

SELECT ''::char(5) = ''::char(5)     AS eq1
     , ''::char(5) = '  '::char(5)   AS eq2
     , ''::char(5) = '    '::char(5) AS eq3;

Result:

 eq1 | eq2 | eq3
 ----+-----+----
 t   | t   | t
SELECT stringexpression 
     , stringexpression = ''                   AS base_test
     , (stringexpression = '')  IS NOT FALSE   AS test1
     , (stringexpression <> '') IS NOT TRUE    AS test2
     , coalesce(stringexpression, '') = ''     AS coalesce1
     , coalesce(stringexpression, '  ') = '  ' AS coalesce2
     , coalesce(stringexpression, '') = '  '   AS coalesce3
FROM  (
   VALUES
     ('foo'::char(5))
   , ('')
   , ('   ')                -- not different from '' in char(n)
   , (NULL)
   ) sub(stringexpression);

Result:


 stringexpression | base_test | test1 | test2 | coalesce1 | coalesce2 | coalesce3 
------------------+-----------+-------+-------+-----------+-----------+-----------
 foo              | f         | f     | f     | f         | f         | f
                  | t         | t     | t     | t         | t         | t
                  | t         | t     | t     | t         | t         | t
 null             | null      | t     | t     | t         | t         | t

Test for "null or empty string" with text:

SELECT stringexpression 
     , stringexpression = ''                   AS base_test
     , (stringexpression = '')  IS NOT FALSE   AS test1
     , (stringexpression <> '') IS NOT TRUE    AS test2
     , coalesce(stringexpression, '') = ''     AS coalesce1
     , coalesce(stringexpression, '  ') = '  ' AS coalesce2
     , coalesce(stringexpression, '') = '  '   AS coalesce3
FROM  (
   VALUES
     ('foo'::text)
   , ('')
   , ('   ')                -- different from '' in a sane character types
   , (NULL)
   ) sub(stringexpression);

Result:


 stringexpression | base_test | test1 | test2 | coalesce1 | coalesce2 | coalesce3 
------------------+-----------+-------+-------+-----------+-----------+-----------
 foo              | f         | f     | f     | f         | f         | f
                  | t         | t     | t     | t         | f         | f
                  | f         | f     | f     | f         | f         | f
 null             | null      | t     | t     | t         | t         | f

db<>fiddle here
Old sqlfiddle

links
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k
Loading
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link
URL Rewriter Bot
URL Rewriter Bot
Loading
clarify
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k
Loading
deleted 12 characters in body
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k
Loading
clarify trim, update fiddle, include demo
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k
Loading
clarify
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k
Loading
fix format
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k
Loading
clarify, links
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k
Loading
clean up
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k
Loading
clarify the addendum
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k
Loading
include feedback, expand fiddle, add more
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k
Loading
typo, clarify wording
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k
Loading
reduce the rant, typos
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k
Loading
clarify empty string in char(n)
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k
Loading
add link to manual
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k
Loading
Source Link
Erwin Brandstetter
  • 641.3k
  • 155
  • 1.1k
  • 1.3k
Loading