प्रकार संशोधक के साथ डेटा प्रकारों के लिए आश्चर्यजनक परिणाम


11

इस प्रश्न के लिए एक पुनरावर्ती CTE समाधान पर चर्चा करते समय:

@ypercube एक आश्चर्यजनक अपवाद के कारण ठोकर खा गया, जो हमें प्रकार संशोधक की जांच की ओर ले जाता है। हमें आश्चर्यजनक व्यवहार मिला।

1. टाइप कास्ट कुछ संदर्भों में टाइप संशोधक को बनाए रखता है

यहां तक ​​कि जब नहीं करने का निर्देश दिया। सबसे बुनियादी उदाहरण:

SELECT 'vc8'::varchar(8)::varchar

एक उम्मीद कर सकता है varchar(कोई संशोधक), कम से कम मैं करूँगा। लेकिन परिणाम varchar(8)(संशोधक के साथ) है। नीचे फिडल में कई संबंधित मामले।

2. ऐरे कॉनटेनेशन कुछ संदर्भों में टाइप संशोधक खो देता है

आवश्यकता के बिना, इसलिए यह विपरीत दिशा में गलतियां करता है:

SELECT ARRAY['vc8']::varchar(8)[]
     , ARRAY['vc8']::varchar(8)[] || 'vc8'::varchar(8)

1 अभिव्यक्ति varchar(8)[]उम्मीद के मुताबिक पैदावार देती है।
लेकिन दूसरा, एक दूसरे varchar(8)को समेटने के बाद, बस varchar[](कोई संशोधक) को पानी पिलाया जाता है । इसी तरह का व्यवहार array_append(), नीचे दिए गए लेख में उदाहरण।

यह सब ज्यादातर संदर्भों में मायने नहीं रखता है। पोस्टग्रेट्स डेटा नहीं खोते हैं, और जब एक कॉलम को सौंपा जाता है, तो मान वैसे भी सही प्रकार के लिए मजबूर होता है। हालांकि , विपरीत दिशाओं में गलत तरीके से निष्कर्ष निकालना एक आश्चर्यजनक अपवाद है:

3. पुनरावर्ती CTE ठीक मिलान करने के लिए डेटा प्रकारों की मांग करता है

इस सरलीकृत तालिका को देखते हुए:

CREATE TABLE a (
  vc8  varchar(8)  -- with modifier
, vc   varchar     -- without  
);
INSERT INTO a VALUES  ('a',  'a'), ('bb', 'bb');

जबकि यह rCTE varcharकॉलम के लिए काम करता है vc, यह varchar(8)कॉलम के लिए विफल रहता है vc8:

WITH RECURSIVE cte AS (
   (
   SELECT ARRAY[vc8] AS arr  -- produces varchar(8)[]
   FROM   a
   ORDER  BY vc8
   LIMIT 1
   )

   UNION ALL
   (
   SELECT a.vc8 || c.arr  -- produces varchar[] !!
   FROM   cte c
   JOIN   a ON a.vc8 > c.arr[1]
   ORDER  BY vc8
   LIMIT 1
   )
   )
TABLE  cte;
त्रुटि: पुनरावर्ती क्वेरी "cte" कॉलम 1 में गैर-पुनरावर्ती शब्द के प्रकार (8) [] अलग-अलग प्रकार के होते हैं लेकिन चरित्र भिन्न होते हैं [] समग्र  
संकेत: गैर-पुनरावर्ती शब्द के आउटपुट को सही प्रकार से कास्ट करें। पद: 103

एक त्वरित समाधान करने के लिए डाली जाएगी text

एक सादे UNIONक्वेरी एक ही समस्या का प्रदर्शन नहीं करती है: यह बिना संशोधक के प्रकार के लिए बसती है, जिसे सभी जानकारी को संरक्षित करने की गारंटी है। लेकिन rCTE अधिक picky है।

इसके अलावा, आप / के max(vc8)बजाय आमतौर पर उपयोग किए जाने वाले समस्याओं के साथ नहीं चलेंगे , क्योंकि और दोस्त तुरंत दूर (या संबंधित आधार प्रकार के बिना एम्पलीफायर) के लिए व्यवस्थित होते हैं।ORDER BYLIMIT 1max()text

एसक्यूएल फिडल 3 चीजों का प्रदर्शन:

  1. उदाहरणों की श्रेणी में आश्चर्यजनक परिणाम शामिल हैं।
  2. एक साधारण आरसीटीई जो varcharबिना संशोधक के साथ काम करता है ।
  3. समान आरसीटीई varchar(n)(संशोधक के साथ) के लिए एक अपवाद बढ़ा ।

Fg pg 9.3 के लिए है। मुझे वही परिणाम स्थानीय रूप से pg 9.4.4 के लिए मिलता है।

मैंने मॉडिफ़ायर सहित सटीक डेटा प्रकार दिखाने में सक्षम होने के लिए डेमो एक्सप्रेशन से तालिकाओं का निर्माण किया। जबकि pgAdmin इस जानकारी को बॉक्स से बाहर दिखाता है यह sqlfiddle से उपलब्ध नहीं है। उल्लेखनीय रूप से, यह psql(!) में भी उपलब्ध नहीं है । यह psql में कमी के रूप में जाना जाता है और इससे पहले कि pgsql-hackers पर एक संभावित समाधान पर चर्चा की गई है - लेकिन अभी तक इसे लागू नहीं किया गया है। यह एक कारण हो सकता है कि समस्या का पता नहीं चला है और अभी तक तय नहीं किया गया है।

SQL स्तर पर, आप pg_typeof()टाइप करने के लिए उपयोग कर सकते हैं (लेकिन संशोधक नहीं)।

प्रशन

एक साथ, 3 मुद्दे गड़बड़ करते हैं।
सटीक होने के लिए, अंक 1 सीधे शामिल नहीं है, लेकिन यह गैर-पुनरावर्ती शब्द में एक डाली के साथ उचित रूप से स्पष्ट फिक्स को बर्बाद कर देता है: ARRAY[vc8]::varchar[]या इसी तरह, जो भ्रम में जोड़ता है।
इनमें से कौन सी वस्तु बग, एक गड़बड़ या सिर्फ यह है कि इसे कैसे माना जाता है?
क्या मुझे कुछ याद आ रहा है या हमें बग की सूचना देनी चाहिए?


यह निश्चित रूप से संदिग्ध लगता है। मुझे संदेह है कि मौजूदा संघ प्रश्नों के लिए पिछड़ी संगतता एक भूमिका निभा सकती है।
क्रेग रिंगर

@ क्रैगरिंगर: मैं यह नहीं देखता कि सरणी सुगमता बिना आवश्यकता के संशोधक को क्यों गिराती है और अनुरोध के बावजूद कलाकार नहीं करता है। न ही क्यों आरसीटीई को सरल UNIONप्रश्नों की तुलना में अधिक सख्त (कम स्मार्ट) होना है । क्या ऐसा हो सकता है कि हमें एक साथ तीन स्वतंत्र छोटे कीड़े मिले ? (इस तरह के महीनों और महीनों के बाद ऐसा नहीं लगता है।) आप में से कौन सा लगता है कि इसे बग के रूप में दर्ज किया जाना चाहिए?
एरविन ब्रैंडस्टैटर

जवाबों:


1

इस की वजह से है संबंध गुण (में परिभाषित किया गया pg_classऔर pg_attribute, या एक का उपयोग करके डायनामिक परिभाषित selectबयान) संशोधक समर्थन (के माध्यम से pg_attribute.atttypmod), जबकि समारोह मापदंडों नहीं है। कार्यों के माध्यम से संसाधित होने पर संशोधक खो जाते हैं, और चूंकि सभी ऑपरेटरों को कार्यों के माध्यम से नियंत्रित किया जाता है, जब ऑपरेटरों द्वारा भी संसाधित किया जाता है, तो संशोधक खो जाते हैं।

आउटपुट मानों के साथ फ़ंक्शंस, या रिकॉर्ड के सेट, या समकक्ष returns table(...)भी परिभाषा में शामिल किसी भी संशोधक को बनाए रखने में असमर्थ हैं। हालाँकि, तालिकाएँ return setof <type>(वास्तव में, संभवतया टाइपकास्ट) को बनाए रखेंगी, जिसमें किसी भी संशोधक को परिभाषित किया typeगया है pg_attribute

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.