由 MySQL 的 ON UPDATE CURRENT_TIMESTAMP 带来的启发,AntDB 是否可以实现 UPDATE 时自动更新字段值。
PostgreSQL之时间戳自动更新
CREATE TABLE ts (
id int,
value int DEFAULT 0,
tt timestamp DEFAULT current_timestamp
);
postgres=# \d ts
Table "public.ts"
Column | Type | Modifiers
--------+-----------------------------+---------------
id | integer |
value | integer | default 0
tt | timestamp without time zone | default now()
postgres=# select adrelid::regclass, adnum, pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = 'ts'::regclass ;
adrelid | adnum | pg_get_expr
---------+-------+-------------
ts | 2 | 0
ts | 3 | now()
(2 rows)
新增 ColDefaultWhen 规则,对 default expression 修饰,表示 default expression 的生效时机。
DEFAULT b_expr ColDefaultWhen
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_DEFAULT;
n->location = @1;
n->raw_expr = makeDefaultExpr($3, $2, @2);
n->cooked_expr = NULL;
$$ = (Node *)n;
}
ColDefaultWhen:
ON INSERT { $$ = DEF_ON_INSERT; }
| ON UPDATE { $$ = DEF_ON_UPDATE; }
| ON INSERT OR UPDATE { $$ = DEF_ON_INSERT | DEF_ON_UPDATE; }
| { $$ = DEF_ON_INSERT; }
;
/*
* Default Expression
*/
typedef struct DefaultExpr
{
NodeTag type;
int16 def_when; /* when to set default expression */
Node *def_expr; /* default expression */
int location; /* token location, or -1 if unknown */
} DefaultExpr;
CREATE TABLE ts (
id int,
value int DEFAULT 0 ON INSERT DEFAULT 999 ON UPDATE,
tt timestamp DEFAULT current_timestamp ON INSERT OR UPDATE
);
postgres=# \d ts
Table "public.ts"
Column | Type | Modifiers
--------+-----------------------------+----------------------------------------
id | integer |
value | integer | default (0) ON INSERT, (999) ON UPDATE
tt | timestamp without time zone | default (now()) ON INSERT OR UPDATE
postgres=# select adrelid::regclass, adnum, pg_get_expr(adbin, adrelid) from pg_attrdef where adrelid = 'ts'::regclass;
adrelid | adnum | pg_get_expr
---------+-------+--------------------------------
ts | 2 | (0) ON INSERT, (999) ON UPDATE
ts | 3 | (now()) ON INSERT OR UPDATE
(2 rows)
postgres=# insert into ts values(1, default, default);
INSERT 0 1
postgres=# insert into ts(id) values(2);
INSERT 0 1
postgres=# insert into ts(id, value) values(3, 1);
INSERT 0 1
postgres=# insert into ts default values;
INSERT 0 1
postgres=# insert into ts values(4,1,now());
INSERT 0 1
postgres=# select * from ts where id = 3;
id | value | tt
----+-------+----------------------------
3 | 1 | 2018-03-06 14:38:52.51784
(1 row)
postgres=# update ts set value = id+1 where id = 3;
UPDATE 1
postgres=# select * from ts order by 1;
id | value | tt
----+-------+----------------------------
3 | 4 | 2018-03-06 14:41:29.099994
(1 row)
由上述结果看到,更新 value 时,tt 字段的值自动更新。
postgres=# \d ts
Table "public.ts"
Column | Type | Modifiers
--------+-----------------------------+----------------------------------------
id | integer |
value | integer | default (0) ON INSERT, (999) ON UPDATE
tt | timestamp without time zone | default (now()) ON INSERT OR UPDATE
postgres=# alter table ts alter COLUMN value drop default on update;
ALTER TABLE
postgres=# \d ts
Table "public.ts"
Column | Type | Modifiers
--------+-----------------------------+-------------------------------------
id | integer |
value | integer | default (0) ON INSERT
tt | timestamp without time zone | default (now()) ON INSERT OR UPDATE
postgres=# alter table ts alter COLUMN tt drop default on update;
ALTER TABLE
postgres=# \d ts
Table "public.ts"
Column | Type | Modifiers
--------+-----------------------------+---------------------------
id | integer |
value | integer | default (0) ON INSERT
tt | timestamp without time zone | default (now()) ON INSERT
postgres=# alter table ts alter COLUMN tt set default current_timestamp on update;
ALTER TABLE
postgres=# \d ts
Table "public.ts"
Column | Type | Modifiers
--------+-----------------------------+----------------------------------------------
id | integer |
value | integer | default (0) ON INSERT
tt | timestamp without time zone | default (now()) ON INSERT, (now()) ON UPDATE
postgres=# alter table ts alter COLUMN value set default 999 on update;
ALTER TABLE
postgres=# \d ts
Table "public.ts"
Column | Type | Modifiers
--------+-----------------------------+----------------------------------------------
id | integer |
value | integer | default (0) ON INSERT, (999) ON UPDATE
tt | timestamp without time zone | default (now()) ON INSERT, (now()) ON UPDATE
postgres=# alter table ts alter COLUMN value set data type float4;
ALTER TABLE
postgres=# \d ts
Table "public.ts"
Column | Type | Modifiers
--------+-----------------------------+----------------------------------------------
id | integer |
value | real | default (0) ON INSERT, (999) ON UPDATE
tt | timestamp without time zone | default (now()) ON INSERT, (now()) ON UPDATE
default_on_update.patch