web-dev-qa-db-ja.com

空でない配列を選択するにはどうすればよいですか?

なぜこれがそんなにトリッキーなのですか、nullや空の文字列と等しくないように設定されたトークンは何ですか?

SELECT lexemes
FROM ts_debug('This is a title')
WHERE alias = 'asciiword';

 lexemes 
---------
 {}
 {}
 {}
 {titl}
(4 rows)

わかりました。それで、私は{}

SELECT lexemes
FROM ts_debug('This is a title')
WHERE alias = 'asciiword'
  AND lexemes <> '{}'
  AND lexemes <> ARRAY[]::text[]
  AND lexemes IS NOT NULL
  AND lexemes <> ARRAY[' ']
  AND lexemes <> ARRAY[null]::text[];

これらのほとんどが機能しないことはわかっていました。ですが、なぜか完全に混乱しています<> '{}'は機能しません<> ARRAY[]::text;。どうすればこれを除外できますか?

3
Evan Carroll

その理由は、その列の空の文字列が配列の次元[1:0]を持っているためです。通常はNULLです。見る:

SELECT lexemes, array_dims(lexemes) FROM ts_debug('a title');

 lexemes | array_dims
---------+------------
 {}      | [1:0]  -- !!
         |
 {titl}  | [1:1]

空の配列は通常、配列の次元としてNULLを持ちます。

SELECT '{}'::text[] AS test, array_dims('{}'::text[]);

 test    | array_dims
---------+------------
 {}      | <NULL>

したがって、比較lexemes = '{}'::text[]FALSEを返します。私にはバグのようです。バージョン8.4〜10ベータ版をテストしました。それはすべてのバージョンにあります。

回避策として、allを空にするには奇数ケース(およびNULL)を含む配列:

SELECT *
FROM   ts_debug('This is a title')
WHERE  cardinality(lexemes) > 0;

または、テキスト表現を比較します。

...
AND    lexemes::text <> '{}';

バグレポート#14826を提出しました

4