Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc138979

Browse files
committed
Add transform functions for various temporal typmod coercisions.
This enables ALTER TABLE to skip table and index rebuilds in some cases.Noah Misch, with trivial changes by me.
1 parent1a01560 commitc138979

File tree

8 files changed

+150
-6
lines changed

8 files changed

+150
-6
lines changed

‎src/backend/utils/adt/date.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,17 @@ timetypmodout(PG_FUNCTION_ARGS)
12101210
}
12111211

12121212

1213+
/* time_transform()
1214+
* Flatten calls to time_scale() and timetz_scale() that solely represent
1215+
* increases in allowed precision.
1216+
*/
1217+
Datum
1218+
time_transform(PG_FUNCTION_ARGS)
1219+
{
1220+
PG_RETURN_POINTER(TemporalTransform(MAX_TIME_PRECISION,
1221+
(Node*)PG_GETARG_POINTER(0)));
1222+
}
1223+
12131224
/* time_scale()
12141225
* Adjust time type for specified scale factor.
12151226
* Used by PostgreSQL type system to stuff columns.

‎src/backend/utils/adt/datetime.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include"catalog/pg_type.h"
2424
#include"funcapi.h"
2525
#include"miscadmin.h"
26+
#include"nodes/nodeFuncs.h"
27+
#include"parser/parse_clause.h"
2628
#include"utils/builtins.h"
2729
#include"utils/date.h"
2830
#include"utils/datetime.h"
@@ -4141,6 +4143,39 @@ CheckDateTokenTables(void)
41414143
returnok;
41424144
}
41434145

4146+
/*
4147+
* Helper for temporal protransform functions. Types time, timetz, timestamp
4148+
* and timestamptz each have a range of allowed precisions. An unspecified
4149+
* precision is rigorously equivalent to the highest specifiable precision.
4150+
*/
4151+
Node*
4152+
TemporalTransform(int32max_precis,Node*node)
4153+
{
4154+
FuncExpr*expr= (FuncExpr*)node;
4155+
Node*typmod;
4156+
Node*ret=NULL;
4157+
4158+
if (!IsA(expr,FuncExpr))
4159+
returnret;
4160+
4161+
Assert(list_length(expr->args)==2);
4162+
typmod=lsecond(expr->args);
4163+
4164+
if (IsA(typmod,Const))
4165+
{
4166+
Node*source=linitial(expr->args);
4167+
int32old_precis=exprTypmod(source);
4168+
int32new_precis=DatumGetInt32(((Const*)typmod)->constvalue);
4169+
4170+
if (new_precis==-1||
4171+
new_precis==max_precis||
4172+
(old_precis!=-1&&new_precis >=old_precis))
4173+
ret=relabel_to_typmod(source,new_precis);
4174+
}
4175+
4176+
returnret;
4177+
}
4178+
41444179
/*
41454180
* This function gets called during timezone config file load or reload
41464181
* to create the final array of timezone tokens. The argument array

‎src/backend/utils/adt/timestamp.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include"funcapi.h"
2828
#include"libpq/pqformat.h"
2929
#include"miscadmin.h"
30+
#include"nodes/nodeFuncs.h"
31+
#include"parser/parse_clause.h"
3032
#include"parser/scansup.h"
3133
#include"utils/array.h"
3234
#include"utils/builtins.h"
@@ -308,6 +310,21 @@ timestamptypmodout(PG_FUNCTION_ARGS)
308310
}
309311

310312

313+
/* timestamp_transform()
314+
* Flatten calls to timestamp_scale() and timestamptz_scale() that solely
315+
* represent increases in allowed precision.
316+
*/
317+
Datum
318+
timestamp_transform(PG_FUNCTION_ARGS)
319+
{
320+
/*
321+
* timestamp_scale throws an error when the typmod is out of range, but we
322+
* can't get there from a cast: our typmodin will have caught it already.
323+
*/
324+
PG_RETURN_POINTER(TemporalTransform(MAX_TIMESTAMP_PRECISION,
325+
(Node*)PG_GETARG_POINTER(0)));
326+
}
327+
311328
/* timestamp_scale()
312329
* Adjust time type for specified scale factor.
313330
* Used by PostgreSQL type system to stuff columns.
@@ -745,6 +762,18 @@ interval_send(PG_FUNCTION_ARGS)
745762
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
746763
}
747764

765+
/*
766+
* The interval typmod stores a "range" in its high 16 bits and a "precision"
767+
* in its low 16 bits. Both contribute to defining the resolution of the
768+
* type. Range addresses resolution granules larger than one second, and
769+
* precision specifies resolution below one second. This representation can
770+
* express all SQL standard resolutions, but we implement them all in terms of
771+
* truncating rightward from some position. Range is a bitmap of permitted
772+
* fields, but only the temporally-smallest such field is significant to our
773+
* calculations. Precision is a count of sub-second decimal places to retain.
774+
* Setting all bits (INTERVAL_FULL_PRECISION) gives the same truncation
775+
* semantics as choosing MAX_INTERVAL_PRECISION.
776+
*/
748777
Datum
749778
intervaltypmodin(PG_FUNCTION_ARGS)
750779
{
@@ -901,6 +930,63 @@ intervaltypmodout(PG_FUNCTION_ARGS)
901930
}
902931

903932

933+
/* interval_transform()
934+
* Flatten superfluous calls to interval_scale(). The interval typmod is
935+
* complex to permit accepting and regurgitating all SQL standard variations.
936+
* For truncation purposes, it boils down to a single, simple granularity.
937+
*/
938+
Datum
939+
interval_transform(PG_FUNCTION_ARGS)
940+
{
941+
FuncExpr*expr= (FuncExpr*)PG_GETARG_POINTER(0);
942+
Node*typmod;
943+
Node*ret=NULL;
944+
945+
if (!IsA(expr,FuncExpr))
946+
PG_RETURN_POINTER(ret);
947+
948+
Assert(list_length(expr->args)==2);
949+
typmod=lsecond(expr->args);
950+
951+
if (IsA(typmod,Const))
952+
{
953+
Node*source=linitial(expr->args);
954+
int32old_typmod=exprTypmod(source);
955+
int32new_typmod=DatumGetInt32(((Const*)typmod)->constvalue);
956+
intold_range;
957+
intold_precis;
958+
intnew_range=INTERVAL_RANGE(new_typmod);
959+
intnew_precis=INTERVAL_PRECISION(new_typmod);
960+
intnew_range_fls;
961+
962+
if (old_typmod==-1)
963+
{
964+
old_range=INTERVAL_FULL_RANGE;
965+
old_precis=INTERVAL_FULL_PRECISION;
966+
}
967+
else
968+
{
969+
old_range=INTERVAL_RANGE(old_typmod);
970+
old_precis=INTERVAL_PRECISION(old_typmod);
971+
}
972+
973+
/*
974+
* Temporally-smaller fields occupy higher positions in the range
975+
* bitmap. Since only the temporally-smallest bit matters for length
976+
* coercion purposes, we compare the last-set bits in the ranges.
977+
*/
978+
new_range_fls=fls(new_range);
979+
if (new_typmod==-1||
980+
((new_range_fls >=SECOND||
981+
new_range_fls >=fls(old_range))&&
982+
(new_precis >=MAX_INTERVAL_PRECISION||
983+
new_precis >=old_precis)))
984+
ret=relabel_to_typmod(source,new_typmod);
985+
}
986+
987+
PG_RETURN_POINTER(ret);
988+
}
989+
904990
/* interval_scale()
905991
* Adjust interval type for specified fields.
906992
* Used by PostgreSQL type system to stuff columns.

‎src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/*yyyymmddN */
56-
#defineCATALOG_VERSION_NO201202072
56+
#defineCATALOG_VERSION_NO201202081
5757

5858
#endif

‎src/include/catalog/pg_proc.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,7 +1257,9 @@ DESCR("date difference preserving months and years");
12571257

12581258
/* OIDS 1200 - 1299 */
12591259

1260-
DATA(insertOID=1200 (intervalPGNSPPGUID121000ffftfi201186"1186 23"_null__null__null__null_interval_scale_null__null__null_ ));
1260+
DATA(insertOID=3918 (interval_transformPGNSPPGUID121000ffftfi102281"2281"_null__null__null__null_interval_transform_null__null__null_ ));
1261+
DESCR("transform an interval length coercion");
1262+
DATA(insertOID=1200 (intervalPGNSPPGUID121003918ffftfi201186"1186 23"_null__null__null__null_interval_scale_null__null__null_ ));
12611263
DESCR("adjust interval precision");
12621264

12631265
DATA(insertOID=1215 (obj_descriptionPGNSPPGUID14100000ffftfs2025"26 19"_null__null__null__null_"select description from pg_catalog.pg_description where objoid = $1 and classoid = (select oid from pg_catalog.pg_class where relname = $2 and relnamespace = PGNSP) and objsubid = 0"_null__null__null_ ));
@@ -2732,19 +2734,23 @@ DATA(insert OID = 1953 ( byteane PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 16
27322734
DATA(insertOID=1954 (byteacmpPGNSPPGUID121000ffftfi2023"17 17"_null__null__null__null_byteacmp_null__null__null_ ));
27332735
DESCR("less-equal-greater");
27342736

2735-
DATA(insertOID=1961 (timestampPGNSPPGUID121000ffftfi201114"1114 23"_null__null__null__null_timestamp_scale_null__null__null_ ));
2737+
DATA(insertOID=3917 (timestamp_transformPGNSPPGUID121000ffftfi102281"2281"_null__null__null__null_timestamp_transform_null__null__null_ ));
2738+
DESCR("transform a timestamp length coercion");
2739+
DATA(insertOID=1961 (timestampPGNSPPGUID121003917ffftfi201114"1114 23"_null__null__null__null_timestamp_scale_null__null__null_ ));
27362740
DESCR("adjust timestamp precision");
27372741

27382742
DATA(insertOID=1965 (oidlargerPGNSPPGUID121000ffftfi2026"26 26"_null__null__null__null_oidlarger_null__null__null_ ));
27392743
DESCR("larger of two");
27402744
DATA(insertOID=1966 (oidsmallerPGNSPPGUID121000ffftfi2026"26 26"_null__null__null__null_oidsmaller_null__null__null_ ));
27412745
DESCR("smaller of two");
27422746

2743-
DATA(insertOID=1967 (timestamptzPGNSPPGUID121000ffftfi201184"1184 23"_null__null__null__null_timestamptz_scale_null__null__null_ ));
2747+
DATA(insertOID=1967 (timestamptzPGNSPPGUID121003917ffftfi201184"1184 23"_null__null__null__null_timestamptz_scale_null__null__null_ ));
27442748
DESCR("adjust timestamptz precision");
2745-
DATA(insertOID=1968 (timePGNSPPGUID121000ffftfi201083"1083 23"_null__null__null__null_time_scale_null__null__null_ ));
2749+
DATA(insertOID=3944 (time_transformPGNSPPGUID121000ffftfi102281"2281"_null__null__null__null_time_transform_null__null__null_ ));
2750+
DESCR("transform a time length coercion");
2751+
DATA(insertOID=1968 (timePGNSPPGUID121003944ffftfi201083"1083 23"_null__null__null__null_time_scale_null__null__null_ ));
27462752
DESCR("adjust time precision");
2747-
DATA(insertOID=1969 (timetzPGNSPPGUID121000ffftfi201266"1266 23"_null__null__null__null_timetz_scale_null__null__null_ ));
2753+
DATA(insertOID=1969 (timetzPGNSPPGUID121003944ffftfi201266"1266 23"_null__null__null__null_timetz_scale_null__null__null_ ));
27482754
DESCR("adjust time with time zone precision");
27492755

27502756
DATA(insertOID=2003 (textanycatPGNSPPGUID141000ffftfv2025"25 2776"_null__null__null__null_"select $1 || $2::pg_catalog.text"_null__null__null_ ));

‎src/include/utils/date.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ extern Datum time_recv(PG_FUNCTION_ARGS);
154154
externDatumtime_send(PG_FUNCTION_ARGS);
155155
externDatumtimetypmodin(PG_FUNCTION_ARGS);
156156
externDatumtimetypmodout(PG_FUNCTION_ARGS);
157+
externDatumtime_transform(PG_FUNCTION_ARGS);
157158
externDatumtime_scale(PG_FUNCTION_ARGS);
158159
externDatumtime_eq(PG_FUNCTION_ARGS);
159160
externDatumtime_ne(PG_FUNCTION_ARGS);

‎src/include/utils/datetime.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#ifndefDATETIME_H
1717
#defineDATETIME_H
1818

19+
#include"nodes/nodes.h"
1920
#include"utils/timestamp.h"
2021

2122
/* this struct is declared in utils/tzparser.h: */
@@ -298,6 +299,8 @@ extern intDecodeUnits(int field, char *lowtoken, int *val);
298299

299300
externintj2day(intjd);
300301

302+
externNode*TemporalTransform(int32max_precis,Node*node);
303+
301304
externboolCheckDateTokenTables(void);
302305

303306
externvoidConvertTimeZoneAbbrevs(TimeZoneAbbrevTable*tbl,

‎src/include/utils/timestamp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ extern Datum timestamp_recv(PG_FUNCTION_ARGS);
100100
externDatumtimestamp_send(PG_FUNCTION_ARGS);
101101
externDatumtimestamptypmodin(PG_FUNCTION_ARGS);
102102
externDatumtimestamptypmodout(PG_FUNCTION_ARGS);
103+
externDatumtimestamp_transform(PG_FUNCTION_ARGS);
103104
externDatumtimestamp_scale(PG_FUNCTION_ARGS);
104105
externDatumtimestamp_eq(PG_FUNCTION_ARGS);
105106
externDatumtimestamp_ne(PG_FUNCTION_ARGS);
@@ -136,6 +137,7 @@ extern Datum interval_recv(PG_FUNCTION_ARGS);
136137
externDatuminterval_send(PG_FUNCTION_ARGS);
137138
externDatumintervaltypmodin(PG_FUNCTION_ARGS);
138139
externDatumintervaltypmodout(PG_FUNCTION_ARGS);
140+
externDatuminterval_transform(PG_FUNCTION_ARGS);
139141
externDatuminterval_scale(PG_FUNCTION_ARGS);
140142
externDatuminterval_eq(PG_FUNCTION_ARGS);
141143
externDatuminterval_ne(PG_FUNCTION_ARGS);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp