इस प्रश्न के लिए एक पुनरावर्ती 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 BY
LIMIT 1
max()
text
एसक्यूएल फिडल 3 चीजों का प्रदर्शन:
- उदाहरणों की श्रेणी में आश्चर्यजनक परिणाम शामिल हैं।
- एक साधारण आरसीटीई जो
varchar
बिना संशोधक के साथ काम करता है । - समान आरसीटीई
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
प्रश्नों की तुलना में अधिक सख्त (कम स्मार्ट) होना है । क्या ऐसा हो सकता है कि हमें एक साथ तीन स्वतंत्र छोटे कीड़े मिले ? (इस तरह के महीनों और महीनों के बाद ऐसा नहीं लगता है।) आप में से कौन सा लगता है कि इसे बग के रूप में दर्ज किया जाना चाहिए?