EDB*Plus的client_encoding问题

磨砺技术珠矶,践行数据之道,追求卓越价值

回到上一级页面:PostgreSQL内部结构与源代码研究索引页    回到顶级页面:PostgreSQL索引页

[作者 高健@博客园  [email protected]] 

 

我的PPAS下,edb数据库的Encoding是 UTF8:

edb=# \l List of databases Name |    Owner     | Encoding |   Collate   |    Ctype    | Access privileges       
-----------+--------------+----------+-------------+-------------+-------------- -----------------
 edb       | enterprisedb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | postgres | enterprisedb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | template0 | enterprisedb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/enterprisedb +
           |              |          |             |             | enterprisedb=CTc/enterprisedb template1 | enterprisedb | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/enterprisedb +
           |              |          |             |             | enterprisedb=CTc/enterprisedb (4 rows) edb=# 。

而我在postgresql.conf里面去设置 client_encoding,无论如何也无法生效。

client_encoding = sql_ascii             # actually, defaults to database # encoding

重新启动后也不行:

edb=# show client_encoding; client_encoding -----------------
 UTF8 (1 row) edb=# 

也就是说,client_encoding的值,就算是设置了,也未必起作用。

查看社区版PostgreSQL的源代码作参考,看看是为何:

当我用psql连接到数据库时,CheckMyDatabase函数就会被执行。

我注意到其中的这一段:

    /* If we have no other source of client_encoding, use server encoding */ SetConfigOption("client_encoding", GetDatabaseEncodingName(), PGC_BACKEND, PGC_S_DYNAMIC_DEFAULT); 

在准备client_encoding的时候,它用了 GetDatabaseEncodingName()函数,来返回数据库的Encoding名称。

可以认为,其实postgresql.conf里的 client_encoding的设定是没有用处的,因为内部运算的时候直接拿来了所连接的数据库的Encoding。也可以说,client_encoding是一个历史遗留问题,是PostgreSQL的开发者的失误造成的!

/* * CheckMyDatabase -- fetch information from the pg_database entry for our DB */                                    
static void CheckMyDatabase(const char *name, bool am_superuser) {  HeapTuple tup; Form_pg_database dbform; char       *collate; char       *ctype; /* Fetch our pg_database row normally, via syscache */ tup = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for database %u", MyDatabaseId); dbform = (Form_pg_database) GETSTRUCT(tup); /* This recheck is strictly paranoia */                                
    if (strcmp(name, NameStr(dbform->datname)) != 0) ereport(FATAL, (errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("database \"%s\" has disappeared from pg_database", name), errdetail("Database OID %u now seems to belong to \"%s\".", MyDatabaseId, NameStr(dbform->datname)))); /* * Check permissions to connect to the database. * These checks are not enforced when in standalone mode, so that there is * a way to recover from disabling all access to all databases, for * example "UPDATE pg_database SET datallowconn = false;". * * We do not enforce them for autovacuum worker processes either. */                                
    if (IsUnderPostmaster && !IsAutoVacuumWorkerProcess()) { /* * Check that the database is currently allowing connections. */                            
        if (!dbform->datallowconn) ereport(FATAL, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("database \"%s\" is not currently accepting connections", name))); /* * Check privilege to connect to the database. (The am_superuser test * is redundant, but since we have the flag, might as well check it * and save a few cycles.) */                            
        if (!am_superuser && pg_database_aclcheck(MyDatabaseId, GetUserId(), ACL_CONNECT) != ACLCHECK_OK) ereport(FATAL, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied for database \"%s\"", name), errdetail("User does not have CONNECT privilege."))); /* * Check connection limit for this database. * * There is a race condition here --- we create our PGPROC before * checking for other PGPROCs. If two backends did this at about the * same time, they might both think they were over the limit, while * ideally one should succeed and one fail. Getting that to work * exactly seems more trouble than it is worth, however; instead we * just document that the connection limit is approximate. */                            
        if (dbform->datconnlimit >= 0 &&                            
            !am_superuser && CountDBBackends(MyDatabaseId) > dbform->datconnlimit) ereport(FATAL, (errcode(ERRCODE_TOO_MANY_CONNECTIONS), errmsg("too many connections for database \"%s\"", name))); } /* * OK, we're golden. Next to-do item is to save the encoding info out of * the pg_database tuple. */ SetDatabaseEncoding(dbform->encoding); /* Record it as a GUC internal option, too */ SetConfigOption("server_encoding", GetDatabaseEncodingName(), PGC_INTERNAL, PGC_S_OVERRIDE); /* If we have no other source of client_encoding, use server encoding */ SetConfigOption("client_encoding", GetDatabaseEncodingName(), PGC_BACKEND, PGC_S_DYNAMIC_DEFAULT); /* assign locale variables */ collate = NameStr(dbform->datcollate); ctype = NameStr(dbform->datctype); if (pg_perm_setlocale(LC_COLLATE, collate) == NULL) ereport(FATAL, (errmsg("database locale is incompatible with operating system"), errdetail("The database was initialized with LC_COLLATE \"%s\", "                        
                       " which is not recognized by setlocale().", collate), errhint("Recreate the database with another locale or install the missing locale."))); if (pg_perm_setlocale(LC_CTYPE, ctype) == NULL) ereport(FATAL, (errmsg("database locale is incompatible with operating system"), errdetail("The database was initialized with LC_CTYPE \"%s\", "                        
                       " which is not recognized by setlocale().", ctype), errhint("Recreate the database with another locale or install the missing locale."))); /* Make the locale settings visible as GUC variables, too */ SetConfigOption("lc_collate", collate, PGC_INTERNAL, PGC_S_OVERRIDE); SetConfigOption("lc_ctype", ctype, PGC_INTERNAL, PGC_S_OVERRIDE); /* Use the right encoding in translated messages */ #ifdef ENABLE_NLS pg_bind_textdomain_codeset(textdomain(NULL)); #endif                                 ReleaseSysCache(tup);  } 

 

 

[作者 高健@博客园  [email protected] 

回到上一级页面:PostgreSQL内部结构与源代码研究索引页    回到顶级页面:PostgreSQL索引页

磨砺技术珠矶,践行数据之道,追求卓越价值

你可能感兴趣的:(encoding)