1

我创建了一个名称中带有 unicode 字符的表(专门用 unicode 测试表名)。它很好地创建了表,但是我检测表是否存在的方法坏了!

这是有问题的交互:

caribou_test=# select table_name from information_schema.tables where table_schema = 'public';
 table_name  
-------------
...
 pinkpink1
(16 rows)

caribou_test=# select table_name from information_schema.tables where table_schema = 'public' and table_name = 'pinkƒpink1';
 table_name 
------------
(0 rows)

caribou_test=# select table_name from information_schema.tables where table_schema = 'public' and table_name = 'pinkpink1';
 table_name 
------------
(0 rows)

caribou_test=# select * from pinkƒpink1;
 id | position | env_id | locked |         created_at         |       updated_at        | status_id | status_position | i1l0  |  f∆   |  growth555   
----+----------+--------+--------+----------------------------+-------------------------+-----------+-----------------+-------+-------+--------------
  1 |        0 |      1 | f      | 2013-06-27 14:50:34.228136 | 2013-06-27 14:50:34.227 |         1 |               0 | YELLL | 55555 | 1.3333388822
(1 row)

表名是pinkƒpink1(测试数据)。如您所见,当我从 information_schema.tables 中选择表名时,它显示时没有 ƒ,但我无法选择表名!但我仍然可以直接向该表发出选择。这里发生了什么?

编辑:为@craig-ringer 提供所需的信息:

caribou_test=# SELECT current_setting('server_encoding') AS server_encoding, current_setting('client_encoding') AS client_encoding, version();
 server_encoding | client_encoding |                                                                    version                                                                     
-----------------+-----------------+------------------------------------------------------------------------------------------------------------------------------------------------
 UTF8            | UTF8            | PostgreSQL 9.2.2 on x86_64-apple-darwin12.2.1, compiled by Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn), 64-bit

caribou_test=# SELECT * FROM pg_class WHERE relname = 'pinkƑpink1';
--->  (0 rows)

caribou_test=# SELECT upper('ƒ') = 'Ƒ', lower('Ƒ') = 'ƒ';
 ?column? | ?column? 
----------+----------
 t        | t
(1 row)

caribou_test=# WITH chars(rowid, thechar) AS (VALUES (1,'ƒ'),(2,'Ƒ'),(3,upper('ƒ')),(4,lower('Ƒ'))) SELECT rowid, thechar, convert_to(thechar, 'utf-8') from chars;
 rowid | thechar | convert_to 
-------+---------+------------
     1 | ƒ       | \xc692
     2 | Ƒ       | \xc691
     3 | Ƒ       | \xc691
     4 | ƒ       | \xc692
4

2 回答 2

4

它看起来像一个错误,可能在regclass或与之相关的东西:

# create table pinkƒpink1 (id serial);
NOTICE:  CREATE TABLE will create implicit sequence "pink?pink1_id_seq" for serial column "pink?pink1.id"
CREATE TABLE
# select 'pinkƒpink1'::name;
    name    
------------
 pinkƒpink1
(1 row)

# select 'pinkƒpink1'::regclass;
  regclass   
-------------
 "pinkpink1"
(1 row)

# select relname from pg_class where oid = 'pinkƒpink1'::regclass;
  relname  
-----------
 pinkpink1

# select relname from pg_class where relname = 'pinkƒpink1'::name;
 relname 
---------
(0 rows)

# select relname from pg_class where relname = 'pinkpink1';
 relname 
---------
(0 rows)

(我的系统是 OSX Lion,一切都是 utf8,以防万一。)


对于解决方法,您可以将其转换::regclass为上面所做的(找到表的那个)。请注意,::regclass如果表不存在,则转换为将产生错误,因此请相应地编写代码。


根据克雷格的要求:

# SELECT current_setting('server_encoding') AS server_encoding, current_setting('client_encoding') AS client_encoding, version();
 server_encoding | client_encoding |                                                              version                                                              
-----------------+-----------------+-----------------------------------------------------------------------------------------------------------------------------------
 UTF8            | UTF8            | PostgreSQL 9.2.4 on x86_64-apple-darwin11.4.2, compiled by Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn), 64-bit
(1 row)

根据欧文的说法:

# SELECT name, setting FROM pg_settings WHERE  name IN ('lc_collate','lc_ctype','client_encoding','server_encoding');
      name       |   setting   
-----------------+-------------
 client_encoding | UTF8
 lc_collate      | en_US.UTF-8
 lc_ctype        | en_US.UTF-8
 server_encoding | UTF8
(4 rows)
于 2013-06-27T22:02:48.463 回答
1

我使用 Postgres 9.1.9 在本地测试了您的案例,它可以正常工作。

SQLfiddle与 Postgres 9.2.4 相同。它只是工作。

它一定是你的问题中没有的东西......

操作系统?

似乎可以在 OSX 上重现。

为了帮助调试,您应该提供更多信息。

  • 服务器编码、客户端编码、区域设置:

    SELECT name, setting
    FROM   pg_settings
    WHERE  name IN ('lc_collate','lc_ctype','client_encoding','server_encoding')
    
  • 哪个客户?你如何连接?

ƒ是小写Ƒ。Postgres 依赖于底层操作系统的语言环境设置。当您查询信息架构或目录表时,您需要提供一个准确的字符串(区分大小写!)。但是,当您在 SQL 语句中使用没有双引号的标识符时,它首先被转换为小写。如果您的语言环境出于某种原因认为它必须转换ƒ为一些小写等效项,这将解释我们所看到的一切。

要排除(或验证)这一点,请尝试使用和不使用双引号的测试:

CREATE TEMP TABLE "pinkƒpink1" (id int);
CREATE TEMP TABLE pinkƒpink1 (id int);

在我在 Debian Linux 下的测试中,两者都导致相同的表名,所以我无法执行第二个命令。我怀疑,您的情况有所不同,这可以解释整个问题。

于 2013-06-27T22:02:59.020 回答