แปลง enum เป็นสตริงโดยไม่เปลี่ยนรูป

Oct 04 2020

วิธีปกติในการแปลงค่า enum เป็นสตริงใน PostgreSQL คือการแคสต์ (ด้วย::text) หรือเพียงแค่อาศัยการแปลงโดยนัยเมื่อกล่าวว่าเชื่อมต่อกับสตริงอื่น:

testdb=# CREATE TYPE color AS ENUM ('red', 'green', 'blue');
CREATE TYPE
testdb=# CREATE TABLE object (id serial, name text, color color);
CREATE TABLE
testdb=# INSERT INTO object (name, color) VALUES ('table', 'red'), ('chair', 'green');
INSERT 0 2
testdb=# SELECT name || color FROM object;
  ?column?  
------------
 tablered
 chairgreen
(2 rows)

อย่างไรก็ตามมีสิ่งที่จับได้: การแปลงดังกล่าวดูเหมือนจะไม่ถือว่าไม่เปลี่ยนรูปโดย Postgres ด้วยเหตุนี้คุณจะได้รับข้อผิดพลาดหากคุณพยายามใช้ในสถานที่ที่คาดว่านิพจน์ไม่เปลี่ยนรูปเช่นในนิยามของGENERATEDคอลัมน์ :

testdb=# ALTER TABLE object ADD COLUMN namecolor text GENERATED ALWAYS AS (name || color) STORED;
ERROR:  generation expression is not immutable
testdb=# ALTER TABLE object ADD COLUMN colorastext text GENERATED ALWAYS AS (color::text) STORED;
ERROR:  generation expression is not immutable

สิ่งนี้ดูเหมือนไม่ง่ายและไม่สะดวกเนื่องจากฉันต้องการที่จะสามารถเชื่อมต่อค่า enum เข้ากับสตริงในคอลัมน์ที่คำนวณได้

ดังนั้นฉันมีสองคำถาม:

  1. เหตุใด Postgres จึงพิจารณาแปลง enum เป็นสตริงให้ไม่เปลี่ยนรูป พฤติกรรมนี้เป็นจุดบกพร่องหรือไม่?
  2. มีวิธีแก้ปัญหาที่จะช่วยให้ฉันโน้มน้าว Postgres ได้หรือไม่ว่าการเปลี่ยนใจเลื่อมใสนั้นไม่เปลี่ยนรูป (และมีความเสี่ยงใดบ้างที่ฉันควรระวัง)

คำตอบ

2 LaurenzAlbe Oct 05 2020 at 12:46
  1. มันเป็นไปได้ที่จะเปลี่ยนชื่อรายการ enum IMMUTABLEเพื่อให้นักแสดงที่ไม่ได้เป็น

  2. ถ้าคุณแน่ใจว่าคุณจะไม่เปลี่ยนชื่อค่า enum IMMUTABLEเขียนฟังก์ชั่นแปลงของคุณเองที่ใช้หล่อภายในและป้ายฟังก์ชั่น จากนั้น PostgreSQL จะเชื่อถือป้ายกำกับนั้นและขึ้นอยู่กับคุณที่จะปฏิบัติตามสัญญา