varchar(N)
. द्वारा लगाई गई लंबाई सीमा प्रकार और गणना length
. द्वारा की जाती है फ़ंक्शन वर्णों में है, बाइट्स में नहीं। तो 'abcdef'::char(3)
'abc'
. में छोटा कर दिया गया है लेकिन 'a€cdef'::char(3)
'a€c'
. में छोटा कर दिया गया है , यूटीएफ -8 के रूप में एन्कोड किए गए डेटाबेस के संदर्भ में भी, जहां 'a€c'
5 बाइट्स का उपयोग करके एन्कोड किया गया है।
यदि डंप फ़ाइल को पुनर्स्थापित करने से शिकायत की जाती है कि 'Mér'
varchar(3)
. में नहीं जाएगा कॉलम, जो बताता है कि आप SQL_ASCII डेटाबेस में UTF-8 एन्कोडेड डंप फ़ाइल को पुनर्स्थापित कर रहे थे।
उदाहरण के लिए, मैंने इसे UTF-8 डेटाबेस में किया था:
create schema so4249745;
create table so4249745.t(key varchar(3) primary key);
insert into so4249745.t values('Mér');
और फिर इसे डंप किया और इसे SQL_ASCII डेटाबेस में लोड करने का प्रयास किया:
pg_dump -f dump.sql --schema=so4249745 --table=t
createdb -E SQL_ASCII -T template0 enctest
psql -f dump.sql enctest
और निश्चित रूप से पर्याप्त:
psql:dump.sql:34: ERROR: value too long for type character varying(3)
CONTEXT: COPY t, line 1, column key: "Mér"
इसके विपरीत, यदि मैं डेटाबेस को एन्कोडिंग LATIN1 या UTF8 के रूप में बनाता हूं, तो यह ठीक लोड होता है।
यह समस्या बहु-बाइट वर्ण एन्कोडिंग वाले डेटाबेस को डंप करने और SQL_ASCII डेटाबेस में पुनर्स्थापित करने का प्रयास करने के संयोजन के कारण आती है। SQL_ASCII का उपयोग करना मूल रूप से क्लाइंट डेटा के सर्वर डेटा में ट्रांसकोडिंग को अक्षम करता है और प्रति वर्ण एक बाइट ग्रहण करता है, जिससे ग्राहकों को सही वर्ण मानचित्र का उपयोग करने की ज़िम्मेदारी लेने के लिए छोड़ दिया जाता है। चूंकि डंप फ़ाइल में यूटीएफ -8 के रूप में संग्रहीत स्ट्रिंग है, जो कि चार बाइट्स है, इसलिए SQL_ASCII डेटाबेस इसे चार वर्णों के रूप में देखता है, और इसलिए इसे बाधा का उल्लंघन करने के रूप में मानता है। और यह उस मान को प्रिंट करता है, जिसे मेरा टर्मिनल फिर तीन वर्णों के रूप में पुन:संयोजित करता है।