如何检测在Postgresql中默认值是常量还是表达式

huangapple go评论61阅读模式
英文:

How to detect if default value is constant or expression in 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 '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"}'  -- 常数
)

MySQL中的类似部分

请参阅https://dev.mysql.com/doc/refman/8.0/en/data-type-defaults.html

具有默认表达式的列在Information Schema中的Extra列中具有DEFAULT_GENERATED

https://dev.mysql.com/doc/refman/8.0/en/information-schema-columns-table.html

英文:

In Postgresql, how can I know default value is constant or expression?

Example:

CREATE TABLE  IF NOT EXISTS default_test  (
  id  serial primary key,
  name varchar(255) NOT NULL,
  father_name varchar(255) DEFAULT 'NULL', -- CONSTANT
  nn2 varchar(255) DEFAULT ('NULL'), -- CONSTANT
  nn3 varchar(255) DEFAULT (null), -- CONSTANT
  nn4 varchar(255) DEFAULT 'the default value', -- CONSTANT
  last_name varchar(255) NULL, -- CONSTANT
  dt timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, -- EXPRESSION
  dt2 timestamp NOT NULL DEFAULT '2011-11-11 00:00:00', -- CONSTANT
  ts timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP /*ON UPDATE CURRENT_TIMESTAMP*/,  -- EXPRESSION
  ts2 timestamp NOT NULL DEFAULT '2011-11-11 00:00:00',  -- CONSTANT
  date_col date DEFAULT (CURRENT_DATE + INTERVAL '2 YEAR'), -- EXPRESSION
   i     INT DEFAULT -1, -- CONSTANT
   c     VARCHAR(10) DEFAULT '', -- CONSTANT
   price DOUBLE precision DEFAULT 0.00, -- CONSTANT

   -- literal defaults
   i2 INT         DEFAULT 0, -- CONSTANT
   i3 INT         DEFAULT 3, -- CONSTANT
   pi_val FLOAT         DEFAULT 3.14, -- CONSTANT

   --
   f FLOAT       DEFAULT 3.14, -- CONSTANT
   d DATE        DEFAULT (CURRENT_DATE + INTERVAL '1 YEAR'), -- EXPRESSION
   p POINT       DEFAULT (Point(0,0)), -- EXPRESSION
   j JSON        DEFAULT '{"a":"b"}'  -- CONSTANT


   
)

Similar part in MySQL

See https://dev.mysql.com/doc/refman/8.0/en/data-type-defaults.html

Column with default expression have DEFAULT_GENERATED in Extra column in Information Schema

https://dev.mysql.com/doc/refman/8.0/en/information-schema-columns-table.html

答案1

得分: 1

你可以从pg_catalog中的attdef字段中获取adbin字段中的信息。

例如,如果你有以下SQL代码:

create table table1(
	w_def_expr text default current_user,
	w_def_cons text default 'hi',
	wo_def     text
);

你可以使用以下查询获取该信息:

select adrelid, tab.relname, attname, pg_get_expr(adbin, 0) expr, 
       split_part(substr(adbin,2),' ',1) expr_type
  from pg_attribute col
       inner join pg_class tab on col.attrelid = tab.oid
	   inner join pg_attrdef def on col.attrelid = def.adrelid and col.attnum = def.adnum
  where tab.relname='table1'

获取类似于以下内容:

如何检测在Postgresql中默认值是常量还是表达式

adbin中获取信息的方式并不是标准的,未来可能会发生变化。我没有找到更好的方法。

这里可以看到2017年的一个回答,说明这是不可能的。

英文:

Yo can get that info in adbin field from attdef in the pg_catalog

If you have for example:

create table table1(
	w_def_expr text default current_user,
	w_def_cons text default 'hi',
	wo_def     text
);

You can get that info with this query:

select adrelid, tab.relname, attname, pg_get_expr(adbin, 0) expr, 
       split_part(substr(adbin,2),' ',1) expr_type
  from pg_attribute col
       inner join pg_class tab on col.attrelid = tab.oid
	   inner join pg_attrdef def on col.attrelid = def.adrelid and col.attnum = def.adnum
  where tab.relname='table1';

Getting something like:

如何检测在Postgresql中默认值是常量还是表达式

The way of getting info in adbin is not standar and can be change in the future.
I didn't find a way to do it better.

Here you can se an answer from 2017 saying that is not possible

huangapple
  • 本文由 发表于 2023年2月18日 22:25:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/75493980.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定