มีอะไรใหม่ใน Postgres 19: เจาะลึกเวอร์ชันเบต้า
(snowflake.com)- รีลีสเบต้าที่บรรจุการปรับปรุงอย่างกว้างขวางในทุกด้าน ตั้งแต่
REPACK CONCURRENTLYที่ฝังมาในคอร์สำหรับฐานข้อมูลโปรดักชันขนาดใหญ่ ไปจนถึงคิวรีกราฟคุณสมบัติด้วย SQL, logical replication, VACUUM และประสิทธิภาพ - รองรับการ ผสาน·แยก พาร์ทิชัน และการซิงก์ค่าซีเควนซ์ ทำให้การเปลี่ยนแปลงการออกแบบและการย้ายข้อมูลระหว่างใช้งานจริงง่ายขึ้นมาก
- autovacuum นำ parallel worker และระบบคะแนนลำดับความสำคัญมาใช้ ช่วยเพิ่ม throughput และการมองเห็นของงานบำรุงรักษา
- การนำ SQL/PGQ มาใช้ทำให้สามารถคิวรีข้อมูลที่มีอยู่ในรูปแบบกราฟได้ โดยไม่ต้องทิ้งโมเดลเชิงสัมพันธ์
- จุดสำคัญไม่ใช่ฟีเจอร์พาดหัวเพียงอย่างเดียว แต่คือ ความครอบคลุม (breadth) โดยพัฒนาพร้อมกันทั้งด้านแอปพลิเคชัน การปฏิบัติการ ประสิทธิภาพ และความสามารถในการขยาย
มี REPACK มาให้ในตัว
- ในสภาพแวดล้อมที่เดินระบบมานาน มักเกิดสถานการณ์ซ้ำ ๆ ที่ต้องการกู้คืนพื้นที่จาก table bloat, เขียนตารางใหม่ หรือจัดระเบียบข้อมูลใหม่ โดยหลีกเลี่ยงการล็อกที่มากับ
VACUUM FULLหรือCLUSTER- มี ecosystem ของส่วนขยายที่แก้ปัญหานี้อยู่แล้ว โดยเฉพาะ
pg_repackที่ช่วยเติมเต็มช่องว่างนี้มาโดยตลอด
- มี ecosystem ของส่วนขยายที่แก้ปัญหานี้อยู่แล้ว โดยเฉพาะ
- Postgres 19 นำคำสั่ง
REPACKเข้ามาไว้ในคอร์ พร้อมรองรับREPACK CONCURRENTLY- คาดว่าจะเป็นฟีเจอร์ที่ผู้ใช้โปรดักชันให้ความสนใจมากกว่าที่ผู้อ่าน release notes โดยทั่วไปอาจคาดไว้
เพิ่มความใช้งานได้จริงของ partitioning
- Postgres 19 เพิ่มการรองรับการ ผสาน·แยก พาร์ทิชัน
- กลยุทธ์ partitioning มักถูกเลือกจากข้อมูลที่ยังไม่สมบูรณ์ และเมื่อ workload, ระยะเวลาเก็บรักษา หรืออัตราการเติบโตของข้อมูลเปลี่ยนไป ก็อาจเกิดปัญหาบางพาร์ทิชันใหญ่เกินไปหรือเล็กเกินไป
- การแยกและผสานได้ช่วยให้มีทางปรับแบบออกแบบไปตามเวลา โดยไม่ต้องสร้างใหม่ทั้งหมดตั้งแต่ต้น
- ผสานพาร์ทิชัน Q1 และ Q2 เป็นพาร์ทิชันเดียว:
ALTER TABLE customer_orders MERGE PARTITIONS (orders_2026_q1, orders_2026_q2) INTO orders_2026_h1; - มีตัวอย่าง
SPLIT PARTITIONสำหรับแยกพาร์ทิชัน Q3 เป็นรายเดือน
- ผสานพาร์ทิชัน Q1 และ Q2 เป็นพาร์ทิชันเดียว:
logical replication เติบโตเต็มที่ขึ้น
- logical replication มีประโยชน์ต่อ migration, upgrade, ระบบรายงาน, การย้ายข้อมูล, การทำ replication แบบเลือกบางส่วน, high availability และ workflow ด้านปฏิบัติการ
- การปรับปรุงที่สำคัญที่สุดคือ การซิงก์ค่าซีเควนซ์ ทำให้ subscriber ตรงกับ publisher ได้ดียิ่งขึ้น
- เมื่อ replication โดยไม่มีสถานะของซีเควนซ์ ข้อมูลจะถูกย้ายไป แต่หลัง cutover อาจเกิดปัญหา ID ถัดไปที่สร้างขึ้นไม่ตรงกัน
- เพิ่มการรองรับ
ALL SEQUENCESใน publication, การรายงานข้อผิดพลาดของการซิงก์ซีเควนซ์ และปรับปรุงพฤติกรรมการรีเฟรช subscription ที่เกี่ยวกับซีเควนซ์
- ใน publication สามารถใช้คำสั่ง
EXCEPTเพื่อ publish ตารางทั้งหมดแต่ยกเว้นบางตารางได้ - เมื่อจำเป็น
wal_level = replicaจะเปิดใช้ logical replication โดยอัตโนมัติ และเพิ่มeffective_wal_levelใหม่เพื่อรายงานพฤติกรรมจริง ช่วยลดการตั้งค่าผิดพลาดและเพิ่มการมองเห็น
autovacuum ฉลาดขึ้นและมองเห็นได้ชัดขึ้น
- autovacuum สามารถใช้ parallel vacuum worker ได้ และควบคุมได้ทั้งระดับ global และรายตาราง
- ตัวอย่างการตั้งค่าระดับ global:
ALTER SYSTEM SET autovacuum_max_parallel_workers = 4;
- ตัวอย่างการตั้งค่าระดับ global:
- เพิ่ม ระบบคะแนน ใหม่เพื่อควบคุมลำดับที่ตารางจะถูก vacuum ทำให้ตัดสินลำดับความสำคัญได้ดีขึ้นว่าตารางใดเร่งด่วนที่สุด
- ตัวอย่างการปรับน้ำหนักรายตาราง: ความเร่งด่วนของ vacuum ที่อิงจาก insert เป็น 3.0 และความเร่งด่วนของ vacuum ปกติจาก update/delete เป็น 0.5
- มุมมอง
pg_stat_autovacuum_scoresใหม่ช่วยให้เห็นกระบวนการตัดสินใจ- เพิ่ม observability ของการบำรุงรักษาด้วยรายละเอียดในมุมมองความคืบหน้าของ vacuum/วิเคราะห์, การใช้หน่วยความจำและ parallelism ใน
VACUUM VERBOSEกับ log ของ autovacuum และเพิ่มlog_autoanalyze_min_durationแยกต่างหาก
- เพิ่ม observability ของการบำรุงรักษาด้วยรายละเอียดในมุมมองความคืบหน้าของ vacuum/วิเคราะห์, การใช้หน่วยความจำและ parallelism ใน
นำคิวรีกราฟคุณสมบัติด้วย SQL มาใช้
- เพิ่ม SQL/PGQ (SQL property graph queries)
- ระบุ workload ที่โมเดล vertex/edge มีประโยชน์ เช่น การตรวจจับการฉ้อโกง, recommendation, network analysis, permission graph, supply chain และผังองค์กร
- ตัวอย่างการนิยาม property graph: ระบุ VERTEX TABLES และ EDGE TABLES ด้วย
CREATE PROPERTY GRAPH store_graph
- เป็นการเพิ่มอีกวิธีหนึ่งในการคิวรีข้อมูลที่มีอยู่แล้ว โดยไม่ต้องทิ้งโมเดลเชิงสัมพันธ์
- เป็นแนวทางเดียวกับที่ JSONB, full-text search และ extension ไม่ได้บังคับให้เปลี่ยนสถาปัตยกรรมเดิม
- จากมุมมองนักพัฒนา สามารถใช้คิวรีแบบกราฟได้โดยไม่ต้องเพิ่ม datastore แยกต่างหาก, เส้นทางการซิงก์, พื้นผิวการปฏิบัติการ หรือสิ่งที่ต้องดีบักตอนตีสอง
COPY มีประโยชน์มากขึ้น
COPY FROMรองรับการข้าม header หลายบรรทัด- มีประโยชน์ต่อการประมวลผล CSV จาก vendor, เครื่องมือภายใน หรือ export ที่มีบรรทัด metadata เพิ่มเติมด้านบน
- เพิ่ม
ON_ERROR SET_NULLให้กับCOPY FROMเพื่อกำหนดค่าที่ป้อนผิดให้เป็น null เป็นทางเลือกระหว่าง “โหลดทั้งหมดล้มเหลว” กับ “ต้องทำความสะอาดข้อมูลล่วงหน้า”- มีตัวอย่างการโหลดไฟล์ที่คอลัมน์ price มีค่า 'N/A' และ 'MISSING' ปะปนอยู่
COPY TOสามารถส่งออกเป็นรูปแบบ JSON รวมถึง JSON array เดี่ยวได้ และสามารถส่งออกตารางพาร์ทิชันโดยตรงได้ด้วย (ก่อนหน้านี้ต้องใช้COPY (SELECT ...))- ตัวอย่างการส่งออกตารางเป็น JSON array ที่ถูกต้อง:
WITH (FORMAT JSON, ARRAY true)
- ตัวอย่างการส่งออกตารางเป็น JSON array ที่ถูกต้อง:
ปรับปรุงความสะดวกของ SQL
GROUP BY ALLจะ group expression ในรายการเป้าหมายที่ไม่ใช่ aggregate และไม่ใช่ window โดยอัตโนมัติ ทำให้เขียน exploratory SQL และคิวรีรายงานได้สะอาดขึ้น- เพิ่มการรองรับ
IGNORE NULLS·RESPECT NULLSใน window function สำหรับlead,lag,first_value,last_value,nth_value - เพิ่ม
INSERT ... ON CONFLICT DO SELECT ... RETURNINGเพื่อคืนแถวที่ชนกันใน upsert ได้โดยตรงยิ่งขึ้น - เพิ่ม
UPDATE·DELETE FOR PORTION OFเพื่อรองรับงานเกี่ยวกับเวลา (temporal) ต่อเนื่อง รวมถึงฟังก์ชันเวลาRANDOM()ที่ขยายเพิ่ม
การปรับปรุงประสิทธิภาพทั่วทั้งระบบ
- มีการปรับปรุงจำนวนมากใน planner และ executor เช่น anti-join, semi-join, constant folding, incremental sort ใน append path, การประมวลผล aggregate ก่อน join, การคำนวณ join selectivity และสถิติของฟังก์ชัน
- Postgres พัฒนาไปในทิศทางที่รู้จักรูปแบบของคิวรีทั่วไปได้ดีขึ้น และลดงานที่ไม่จำเป็น
- การประมวลผล aggregate บางส่วนทำก่อน join เพื่อลดจำนวนแถวที่ต้องประมวลผล
- กรณี
NOT INและLEFT JOINมากขึ้นถูกแปลงเป็น anti-join ที่มีประสิทธิภาพ - เพิ่มการมองเห็นของ Memoize ใน
EXPLAIN, ปรับปรุงประสิทธิภาพการ sort ด้วย radix sort, เร่งการตรวจสอบข้อจำกัด foreign key และใช้คำสั่ง SIMD กับอินพุต text/CSV ของCOPY FROM
- ในหลายกรณี เพียงอัปเกรดก็ได้พฤติกรรมที่ดีขึ้นโดยไม่ต้องเปลี่ยนโค้ดแอปพลิเคชัน
ทำไม Postgres 19 จึงสำคัญ
- สิ่งที่โดดเด่นไม่ใช่ฟีเจอร์เดี่ยว แต่คือ ความครอบคลุม (breadth)
- สำหรับนักพัฒนาแอปพลิเคชัน: คิวรีกราฟ, ไวยากรณ์ SQL ที่ดีขึ้น, การปรับปรุง window function, พฤติกรรม upsert ที่ดีขึ้น
- สำหรับผู้ดูแลระบบ:
REPACK CONCURRENTLY, autovacuum ที่ดีขึ้น, monitoring ที่ปรับปรุง, การเปลี่ยน checksum แบบออนไลน์, การมองเห็น replication ที่มากขึ้น - สำหรับผู้ใช้ที่เน้นประสิทธิภาพ: การปรับปรุง planner, การปรับปรุง SIMD, การมองเห็น asynchronous I/O, การตรวจสอบ foreign key ที่เร็วขึ้น, การ sort ที่ดีขึ้น
- สำหรับผู้ใช้ที่สร้างระบบบน Postgres: hook ใหม่, โมดูล planner advice, การปรับปรุง extension, การค้นสถิติ FDW และการลงทุนต่อเนื่องใน ecosystem ของ extension
- ไม่ได้พัฒนาเพื่อ workload หรือ persona เดียว แต่ก้าวหน้าไปพร้อมกันในฐานะฐานข้อมูลและแพลตฟอร์มสำหรับแอปพลิเคชัน การปฏิบัติการ การวิเคราะห์ และการขยายต่อ
- ยังไม่ใช่ GA ดังนั้นตอนนี้คือเวลาทดสอบ — รันแอปพลิเคชัน, ทดสอบ migration, ตรวจสอบ extension, ตรวจ query plan สำคัญ และตรวจ workflow ของ logical replication กับการบำรุงรักษา
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
เคยใช้ Postgres, Oracle, MS SQL Server, MySQL ในโปรเจกต์จริง และแม้จะไม่ได้ใช้ SQLite แบบลึกมาก แต่ก็รู้ว่าเป็นตัวเลือกที่ยอดเยี่ยม
ช่วงนี้ถ้าเลือกเพื่อตัวเอง จะหลีกเลี่ยง Oracle และ MySQL/MariaDB เสมอ
Postgres ยอดเยี่ยม แต่ก็อยากให้มีการเชื่อมต่อที่เบา และ materialized view ที่อัปเดตแบบซิงโครนัส แม้ connection pooler จะช่วยให้สถานการณ์ดีขึ้น แต่การใช้หน่วยความจำต่อการเชื่อมต่อพร้อมกันหนึ่งรายการก็ยังสูงผิดปกติอยู่ดี และฟีเจอร์แบบ indexed view ของ SQL Server ทำให้สามารถทำ implementation ที่สง่างาม เรียบง่าย และถูกต้องเสมอสำหรับสถานการณ์ข้อมูลที่ซับซ้อนได้
SQL Server อาจแพง แต่ในหลายกรณีก็คุ้มค่ากับราคา และถ้าเลือก data store อย่างรอบคอบ ก็ลดปัญหาปวดหัวในอนาคตได้มาก
ถ้าจะใช้ตัวฟรี ก็ยากที่จะเอาชนะ SQLite ได้ และตอนนี้มันรองรับ use case ส่วนใหญ่ได้แล้ว แต่ในด้าน backup, replication และเครื่องมือ จะเริ่มไปไม่ไหว ถ้าต้องรับผิดชอบ system availability และ disaster recovery ก็ไม่ลังเลที่จะจ่ายเงินเพื่อลดความเสี่ยง
ถ้าจะจ่ายแม้แต่นิดเดียว ก็ไปให้สุดเลย developer experience รอบ ๆ MSSQL นั้นไม่มีใครเทียบได้ และคิดว่า SQL project ของ SSMS กับ Visual Studio ดีกว่าพวก Entity Framework ในปัจจุบันมาก เมื่อรวมกับเครื่องมือ third-party อย่าง RedGate ก็สามารถแทนที่แพ็กเกจ consulting มูลค่าหลายล้านดอลลาร์ได้
คงไม่เสนอให้ตั้ง Oracle หรือ DB2 server ใหม่ แต่ถ้ามีอยู่แล้ว ก็คงจะคัดค้านจนถึงที่สุดต่อการ refactor เพื่อเอามันออก ฐานข้อมูลแบบนี้มักมีเรื่องเล่าขนหัวลุกมหาศาลติดมาด้วย และถ้าไม่มีทางเลือกอื่นนอกจากพยายามสร้าง side effect แปลก ๆ เหล่านั้นขึ้นใหม่บน engine ตัวใหม่ ธุรกิจก็อาจเสียหายได้
ในฐานะ DBA ถ้าเคยทำงาน DBA หนัก ๆ มามาก จะเห็นว่า Postgres อยู่คนละระดับกับ SQL Server Postgres เป็น native บน Linux และเป็นโอเพนซอร์ส จึงมีความยืดหยุ่น การสังเกตภายในระบบ และความสามารถในการปฏิบัติการที่เทียบกับ SQL Server ไม่ได้เลย
ในภูมิทัศน์เทคโนโลยีปัจจุบัน มองว่า SQL Server ตายไปแล้วในทางปฏิบัติ บริษัทที่ใช้ก็มีแต่หน่วยงาน legacy ที่ยึด Windows เป็นศูนย์กลาง และที่แบบนั้นก็กำลังลดลงเรื่อย ๆ
ถ้ามีตัวเลือกอัปเดตแบบหน่วงเวลาด้วยก็คงดี เป็นวิธีที่ประมวลผลหลายอัปเดตรวมกันโดยพิจารณาเฉพาะเรคคอร์ดที่เปลี่ยนไปหลังการ refresh ครั้งล่าสุด แต่ไม่ค่อยแน่ใจว่า Oracle ทำทางเทคนิคอย่างไร ฟีเจอร์นี้น่าจะเป็นการเพิ่มที่ยอดเยี่ยมเมื่อเทียบกับฐานข้อมูล OLTP โอเพนซอร์สแทบทั้งหมด
โปรเจกต์ OrioleDB ก็น่าสนใจมากจริง ๆ: https://github.com/orioledb/orioledb/releases
หลายปีก่อนเคยลำบากพอสมควรกับ vacuum เพราะมีการ insert/delete แบบสุ่มอย่างต่อเนื่องจำนวนมากในที่คล้าย ๆ temporary table แก้ด้วยการสะสมการเปลี่ยนแปลงไว้ใน RAM มากขึ้นแล้วค่อย flush ลง table เพื่อเพิ่มจำนวนแถวที่เปลี่ยนต่อ page แต่ก็ลำบากมากกว่าจะหาสมดุลที่ดีได้
ในฐานะคนที่ใช้ Postgres ในสายวิทยาศาสตร์มานานกว่า 15 ปี เริ่มกังวลแล้วที่ PostgreSQL ไม่มี column-oriented storage
เมื่อ dataset ใหญ่ขึ้นเรื่อย ๆ ข้อจำกัดของ storage ใน PG ก็ยิ่งรู้สึกชัดขึ้น ส่วนขยายหลายตัวอย่าง cetus อาจให้ฟีเจอร์นี้ได้ แต่ก็ต้องพึ่งว่าส่วนขยายนั้นจะยังได้รับการสนับสนุนต่อไปหรือไม่ และยังเพิ่มความซับซ้อนด้วย
ตอนแรกคิดว่าถ้าใช้ table ของ Postgres เป็น storage และใช้ executor ของ Postgres overhead ในตัวมันเองน่าจะสูงเกินไป จึงคิดว่าถ้าทำให้ performance ใกล้เคียง Timescale ได้ก็คงเจ๋งมากแล้ว ไม่ได้คิดว่าจะเข้าใกล้ฐานข้อมูลสำหรับ analytics โดยเฉพาะได้
แต่เมื่อโปรเจกต์เดินหน้า performance ก็ดีขึ้นเรื่อย ๆ และตอนนี้ก็สนับสนุนแนวทางทำ งาน analytics ด้วย Postgres + extension อย่างชัดเจน
คล้ายกับกังวลว่า Apple ไม่ขายเครื่องซักผ้า
ทุกวันนี้หลายบริษัทก็ใช้ key-value database หรือ document store ร่วมกับ relational database ในแอปหลักด้วย
ไม่รู้ว่าทำไมถึงไม่มีการพูดถึงว่า PostgreSQL 19 จะนำการรองรับ native application-time temporal data ตามมาตรฐาน SQL:2011 เข้ามา: https://www.depesz.com/2026/04/02/waiting-for-postgresql-19-...
_archive: https://www.postgresql.org/docs/current/tcn.htmlถ้าสิ่งนี้กลายเป็น native ได้ ก็น่าจะยอดเยี่ยมจริง ๆ เหมือนการใช้งาน PostgreSQL ส่วนใหญ่
https://news.ycombinator.com/item?id=48413655
ผมตัดสินไม่ได้ว่าบทความนี้ใช้สำนวนที่ถูก oversample ในชุดข้อมูลฝึก LLM หรือว่ามีการใช้ AI เยอะเพื่อขัดเกลางานเขียน เอนเอียงไปทางอย่างหลัง
ผมมองว่าการที่ Claude เขียนประโยคอย่าง “ในฐานะคนที่ทำ X มานาน” เป็น alignment failure อย่างหนึ่ง LLM ไม่ควรเขียนราวกับว่ามีประสบการณ์ส่วนตัว ถึงในข้อมูลฝึกอาจมีมนุษย์พูดแบบนั้น และแม้จะเป็นลำดับโทเค็นที่ดูเป็นไปได้ทางสถิติ ผมก็คิดว่า LLM ไม่ควรอ้างประสบการณ์ชีวิตที่ตัวมันเองไม่มี
ผมชอบ การปรับปรุง COPY และ logical replication ตอนนี้ผมสำรองฐานข้อมูล PG ไปยังอินสแตนซ์ Databasus แบบ sidecar ซึ่งหนักกว่าแบ็กเอนด์ทั้งหมด + DB + Caddy เสียอีก
ข้างล่างคือการบ่นเรื่องสไตล์การเขียนแบบ LLM
ถ้าต้องอ่านประโยคอย่าง “เท่านี้ก็ชัดแล้ว: ผู้ใช้มีความต้องการจริง และ ecosystem ก็เข้ามาเติมช่องว่างนั้น”, “มันดูเรียบง่าย แต่แก้ปัญหาการปฏิบัติงานจริง”, “มันไม่ได้เปลี่ยนโลก แต่ทำให้เวิร์กโฟลว์ข้อมูลในชีวิตประจำวันดีขึ้น” Orwell ถ้ายังมีชีวิตอยู่ตอนนี้คงประกาศว่าตัวเองไม่รู้ภาษาอังกฤษ แล้วไปเรียน Klingon แทนแล้ว
ฟีเจอร์ฐานข้อมูลกราฟดูน่าสนใจ แต่ไวยากรณ์
GRAPH_TABLEนี่แย่มากSELECT customer_name FROM GRAPH_TABLE (myshop MATCH (c IS customers)-[IS customer_orders]->(o IS orders WHERE o.ordered_when = current_date) COLUMNS (c.name AS customer_name));มันทำให้นึกถึง neo4j ซึ่งผมไม่คิดว่าในปี 2026 จะเป็นสิ่งที่เครื่องมือจริงจังควรลอกมาแบบนั้น
สุดท้ายสิ่งที่อยากรู้คือความเร็ว row-level security เป็นฟีเจอร์ที่มีประโยชน์มาก แต่การจะสร้างของจริงจังบน implementation ของ Postgres นั้นดูบ้าบิ่น เพราะ planner จะเละเทะและต้อง match ทีละแถวจนทำให้ประสิทธิภาพพัง
มันคือ SQL/PGQ ซึ่งสืบทอดมาจากภาษา Cypher ของ Neo4J และตอนนี้เป็นส่วนหนึ่งของมาตรฐาน SQL แล้ว
อยากให้ PostgreSQL มี block compression เพิ่มเข้ามานอกเหนือจาก row compression ด้วย row compression อย่างเดียวให้ผลจำกัดเกินไป
จะวางข้อมูลไว้ใน ZFS pool แล้วเปิด block compression ก็ได้ แต่ถ้ารองรับแบบ native ก็จะลดภาระการตั้งค่า และอาจให้ประสิทธิภาพดีกว่า
GROUP BY ALL พอมาคิดดูแล้วก็สมเหตุสมผลมาก แต่น่าสนใจที่ก่อนหน้านี้ไม่เคยนึกถึงเลย
จากมุมมองที่ใกล้กับ DevOps อยากให้ PostgreSQL รองรับ in-place upgrade ระหว่างเวอร์ชันหลักที่ต่อเนื่องกันเสียที
ดิสโทรส่วนใหญ่จัดการความยุ่งยากของการรันเวอร์ชันเก่ากับเวอร์ชันใหม่พร้อมกันเพื่อ
pg_upgradeได้ แต่ถ้าใช้ Docker การอัปเกรดไปเวอร์ชันหลักใหม่เป็นเรื่องเจ็บปวดจริง ๆดีใจที่มี GROUP BY ALL เท่าที่ผมรู้เป็นแนวคิดที่ DuckDB นำเข้ามา
ในเอกสาร DuckDB ก็ระบุว่าฟีเจอร์หลายอย่างเริ่มจาก DuckDB และฟีเจอร์อย่าง
GROUP BY ALLก็ถูกระบบอื่นนำไปใช้ในภายหลังhttps://duckdb.org/docs/lts/sql/dialect/friendly_sql