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

Commit3cc0800

Browse files
committed
Add a transform function for numeric typmod coercisions.
This enables ALTER TABLE to skip table and index rebuilds when a columnis changed to an unconstrained numeric, or when the scale is unchangedand the precision does not decrease.Noah Misch, with a few stylistic changes and a fix for an OIDcollision by me.
1 parentaf7914c commit3cc0800

File tree

4 files changed

+53
-2
lines changed

4 files changed

+53
-2
lines changed

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include"catalog/pg_type.h"
3131
#include"libpq/pqformat.h"
3232
#include"miscadmin.h"
33+
#include"nodes/nodeFuncs.h"
34+
#include"parser/parse_clause.h"
3335
#include"utils/array.h"
3436
#include"utils/builtins.h"
3537
#include"utils/int8.h"
@@ -712,6 +714,52 @@ numeric_send(PG_FUNCTION_ARGS)
712714
}
713715

714716

717+
/*
718+
* numeric_transform() -
719+
*
720+
* Flatten calls to our length coercion function that solely represent
721+
* increases in allowable precision. Scale changes mutate every datum, so
722+
* they are unoptimizable. Some values, e.g. 1E-1001, can only fit into an
723+
* unconstrained numeric, so a change from an unconstrained numeric to any
724+
* constrained numeric is also unoptimizable.
725+
*/
726+
Datum
727+
numeric_transform(PG_FUNCTION_ARGS)
728+
{
729+
FuncExpr*expr= (FuncExpr*)PG_GETARG_POINTER(0);
730+
Node*typmod;
731+
Node*ret=NULL;
732+
733+
if (!IsA(expr,FuncExpr))
734+
PG_RETURN_POINTER(ret);
735+
736+
Assert(list_length(expr->args)==2);
737+
typmod=lsecond(expr->args);
738+
739+
if (IsA(typmod,Const))
740+
{
741+
Node*source=linitial(expr->args);
742+
int32old_typmod=exprTypmod(source);
743+
int32new_typmod=DatumGetInt32(((Const*)typmod)->constvalue);
744+
int32old_scale= (old_typmod-VARHDRSZ)&0xffff;
745+
int32new_scale= (new_typmod-VARHDRSZ)&0xffff;
746+
int32old_precision= (old_typmod-VARHDRSZ) >>16&0xffff;
747+
int32new_precision= (new_typmod-VARHDRSZ) >>16&0xffff;
748+
749+
/*
750+
* If new_typmod < VARHDRSZ, the destination is unconstrained; that's
751+
* always OK. If old_typmod >= VARHDRSZ, the source is constained.
752+
* and we're OK if the scale is unchanged and the precison is not
753+
* decreasing. See further nodes in function header comment.
754+
*/
755+
if (new_typmod<VARHDRSZ|| (old_typmod >=VARHDRSZ&&
756+
new_scale==old_scale&&new_precision >=old_precision))
757+
ret=relabel_to_typmod(source,new_typmod);
758+
}
759+
760+
PG_RETURN_POINTER(ret);
761+
}
762+
715763
/*
716764
* numeric() -
717765
*

‎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_NO201201311
56+
#defineCATALOG_VERSION_NO201202071
5757

5858
#endif

‎src/include/catalog/pg_proc.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2142,8 +2142,10 @@ DATA(insert OID = 2917 ( numerictypmodinPGNSP PGUID 12 1 0 0 0 f f f t f i 1
21422142
DESCR("I/O typmod");
21432143
DATA(insertOID=2918 (numerictypmodoutPGNSPPGUID121000ffftfi102275"23"_null__null__null__null_numerictypmodout_null__null__null_ ));
21442144
DESCR("I/O typmod");
2145-
DATA(insertOID=1703 (numericPGNSPPGUID121000ffftfi201700"1700 23"_null__null__null__null_numeric_null__null__null_ ));
2145+
DATA(insertOID=1703 (numericPGNSPPGUID121003157ffftfi201700"1700 23"_null__null__null__null_numeric_null__null__null_ ));
21462146
DESCR("adjust numeric to typmod precision/scale");
2147+
DATA(insertOID=3157 (numeric_transformPGNSPPGUID121000ffftfi102281"2281"_null__null__null__null_numeric_transform_null__null__null_ ));
2148+
DESCR("transform a numeric length coercion");
21472149
DATA(insertOID=1704 (numeric_absPGNSPPGUID121000ffftfi101700"1700"_null__null__null__null_numeric_abs_null__null__null_ ));
21482150
DATA(insertOID=1705 (absPGNSPPGUID121000ffftfi101700"1700"_null__null__null__null_numeric_abs_null__null__null_ ));
21492151
DESCR("absolute value");

‎src/include/utils/builtins.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,7 @@ extern Datum numeric_recv(PG_FUNCTION_ARGS);
913913
externDatumnumeric_send(PG_FUNCTION_ARGS);
914914
externDatumnumerictypmodin(PG_FUNCTION_ARGS);
915915
externDatumnumerictypmodout(PG_FUNCTION_ARGS);
916+
externDatumnumeric_transform(PG_FUNCTION_ARGS);
916917
externDatumnumeric (PG_FUNCTION_ARGS);
917918
externDatumnumeric_abs(PG_FUNCTION_ARGS);
918919
externDatumnumeric_uminus(PG_FUNCTION_ARGS);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp