如何判断PostgreSQL中列的默认值是常量还是表达式
在PostgreSQL中如何判断列的默认值是常量还是表达式?
示例表
CREATE TABLE IF NOT EXISTS default_test ( id serial primary key, name varchar(255) NOT NULL, father_name varchar(255) DEFAULT 'NULL', -- 常量 nn2 varchar(255) DEFAULT ('NULL'), -- 常量 nn3 varchar(255) DEFAULT (null), -- 常量 nn4 varchar(255) DEFAULT 'the default value', -- 常量 last_name varchar(255) NULL, -- 常量(无默认值归为常量范畴) dt timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 表达式 dt2 timestamp NOT NULL DEFAULT '2011-11-11 00:00:00', -- 常量 ts timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP /*ON UPDATE CURRENT_TIMESTAMP*/, -- 表达式 ts2 timestamp NOT NULL DEFAULT '2011-11-11 00:00:00', -- 常量 date_col date DEFAULT (CURRENT_DATE + INTERVAL '2 YEAR'), -- 表达式 i INT DEFAULT -1, -- 常量 c VARCHAR(10) DEFAULT '', -- 常量 price DOUBLE precision DEFAULT 0.00, -- 常量 -- 字面量默认值 i2 INT DEFAULT 0, -- 常量 i3 INT DEFAULT 3, -- 常量 pi_val FLOAT DEFAULT 3.14, -- 常量 f FLOAT DEFAULT 3.14, -- 常量 d DATE DEFAULT (CURRENT_DATE + INTERVAL '1 YEAR'), -- 表达式 p POINT DEFAULT (Point(0,0)), -- 表达式 j JSON DEFAULT '{"a":"b"}' -- 常量 )
PostgreSQL中的判断方法
PostgreSQL没有直接标记表达式默认值的系统字段,需通过解析默认值定义来区分,以下是两种可行方法:
方法1:查询系统目录表
通过pg_attribute和pg_attrdef系统表,结合pg_get_expr函数解析默认值内容:
SELECT att.attname AS column_name, pg_get_expr(def.adbin, def.adrelid) AS default_definition, CASE WHEN def.adbin IS NULL THEN '无默认值(常量范畴)' -- 识别包含函数、运算符或动态关键字的表达式 WHEN def.adbin::text LIKE '%Func%' OR def.adbin::text LIKE '%Op%' OR def.adbin::text LIKE '%Current%' THEN '表达式' ELSE '常量' END AS default_type FROM pg_attribute att LEFT JOIN pg_attrdef def ON att.attrelid = def.adrelid AND att.attnum = def.adnum WHERE att.attrelid = 'default_test'::regclass AND att.attnum > 0 AND NOT att.attisdropped ORDER BY att.attnum;
方法2:结合information_schema查询
通过information_schema.columns获取默认值文本,判断其格式特征:
SELECT column_name, column_default, CASE WHEN column_default IS NULL THEN '无默认值(常量范畴)' -- 排除带引号的字面量,识别带括号的函数/运算表达式 WHEN column_default LIKE '%(%' AND column_default NOT LIKE '''%''' THEN '表达式' WHEN column_default IN ('NULL', 'null') THEN '常量' ELSE '常量' END AS default_type FROM information_schema.columns WHERE table_name = 'default_test' ORDER BY ordinal_position;
判断逻辑说明:固定字面量(字符串、数字、指定日期等)属于常量;包含函数调用(如CURRENT_TIMESTAMP)、运算逻辑(如CURRENT_DATE + INTERVAL '2 YEAR')或自定义函数(如Point(0,0))的属于表达式。
MySQL中的类似实现
在MySQL中,带有表达式默认值的列会在INFORMATION_SCHEMA.COLUMNS表的Extra字段中标记为DEFAULT_GENERATED,可直接通过该标识区分常量与表达式默认值。
内容的提问来源于stack exchange,提问作者Sohel Ahmed Mesaniya
相关产品推荐
相关产品推荐

