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

Commit04a4821

Browse files
committed
Attached is a patch implementing factorial(), returning numeric. Points
to note:1) arttype is numeric. I thought this was the best way of allowingarbitarily large factorials, even though factorial(2^63) is a largenumber. Happy to change to integers if this is overkill.2) since we're accepting numeric arguments, the patch tests for floats.If a numeric is passed with non-zero decimal portion, an error is raisedsince (from memory) they are undefined.Gavin Sherry
1 parentaf03663 commit04a4821

File tree

9 files changed

+74
-100
lines changed

9 files changed

+74
-100
lines changed

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

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.58 2003/11/29 19:51:58 pgsql Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.59 2003/12/01 21:52:37 momjian Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -26,7 +26,7 @@
2626
* intpl, intmi, int4mul, intdiv
2727
*
2828
*Arithmetic operators:
29-
* intmod, int4fac
29+
* intmod
3030
*/
3131

3232
#include"postgres.h"
@@ -849,40 +849,6 @@ int42mod(PG_FUNCTION_ARGS)
849849
PG_RETURN_INT32(arg1 %arg2);
850850
}
851851

852-
/* int[24]fac()
853-
* Factorial
854-
*/
855-
Datum
856-
int4fac(PG_FUNCTION_ARGS)
857-
{
858-
int32arg1=PG_GETARG_INT32(0);
859-
int32result;
860-
861-
if (arg1==0)
862-
result=1;
863-
elseif (arg1<0)
864-
result=0;
865-
else
866-
for (result=1;arg1>0;--arg1)
867-
result *=arg1;
868-
PG_RETURN_INT32(result);
869-
}
870-
871-
Datum
872-
int2fac(PG_FUNCTION_ARGS)
873-
{
874-
int16arg1=PG_GETARG_INT16(0);
875-
int32result;
876-
877-
if (arg1==0)
878-
result=1;
879-
elseif (arg1<0)
880-
result=0;
881-
else
882-
for (result=1;arg1>0;--arg1)
883-
result *=arg1;
884-
PG_RETURN_INT32(result);
885-
}
886852

887853
/* int[24]abs()
888854
* Absolute value

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

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.49 2003/11/29 19:51:58 pgsql Exp $
10+
* $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.50 2003/12/01 21:52:37 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -561,26 +561,6 @@ int8mod(PG_FUNCTION_ARGS)
561561
PG_RETURN_INT64(result);
562562
}
563563

564-
/* int8fac()
565-
* Factorial
566-
*/
567-
Datum
568-
int8fac(PG_FUNCTION_ARGS)
569-
{
570-
int64arg1=PG_GETARG_INT64(0);
571-
int64result;
572-
int64i;
573-
574-
if (arg1==0)
575-
result=1;
576-
elseif (arg1<1)
577-
result=0;
578-
else
579-
for (i=arg1,result=1;i>0;--i)
580-
result *=i;
581-
582-
PG_RETURN_INT64(result);
583-
}
584564

585565
Datum
586566
int8inc(PG_FUNCTION_ARGS)

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

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* Copyright (c) 1998-2003, PostgreSQL Global Development Group
1515
*
1616
* IDENTIFICATION
17-
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.68 2003/11/29 19:51:59 pgsql Exp $
17+
* $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.69 2003/12/01 21:52:37 momjian Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -1288,6 +1288,55 @@ numeric_larger(PG_FUNCTION_ARGS)
12881288
* ----------------------------------------------------------------------
12891289
*/
12901290

1291+
/*
1292+
* numeric_fac()
1293+
* Computer factorial
1294+
*/
1295+
1296+
Datum
1297+
numeric_fac(PG_FUNCTION_ARGS)
1298+
{
1299+
1300+
int64num=PG_GETARG_INT64(0);
1301+
NumericVarcount;
1302+
NumericVarfact;
1303+
NumericVarzerovar;
1304+
NumericVarresult;
1305+
Numericres;
1306+
1307+
if(num<1) {
1308+
res=make_result(&const_one);
1309+
PG_RETURN_NUMERIC(res);
1310+
}
1311+
1312+
1313+
init_var(&fact);
1314+
init_var(&count);
1315+
init_var(&result);
1316+
init_var(&zerovar);
1317+
zero_var(&zerovar);
1318+
1319+
int8_to_numericvar((int64)num,&result);
1320+
set_var_from_var(&const_one,&count);
1321+
1322+
for(num=num-1;num>0;num--) {
1323+
set_var_from_var(&result,&count);
1324+
1325+
int8_to_numericvar((int64)num,&fact);
1326+
1327+
mul_var(&count,&fact,&result,count.dscale+fact.dscale);
1328+
}
1329+
1330+
res=make_result(&count);
1331+
1332+
free_var(&count);
1333+
free_var(&fact);
1334+
free_var(&result);
1335+
free_var(&zerovar);
1336+
1337+
PG_RETURN_NUMERIC(res);
1338+
}
1339+
12911340

12921341
/*
12931342
* numeric_sqrt() -

‎src/include/catalog/pg_operator.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
11-
* $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.122 2003/11/29 22:40:58 pgsql Exp $
11+
* $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.123 2003/12/01 21:52:37 momjian Exp $
1212
*
1313
* NOTES
1414
* the genbki.sh script reads this file and generates .bki
@@ -122,12 +122,12 @@ DATA(insert OID = 375 ( "||" PGNSP PGUID b f 2277 2277 22770 0 0 0 0 0 arra
122122

123123
DATA(insertOID=352 ("="PGNSPPGUIDbt28281635200000xideqeqseleqjoinsel ));
124124
DATA(insertOID=353 ("="PGNSPPGUIDbf282316000000xideqint4eqseleqjoinsel ));
125+
DATA(insertOID=388 ("!"PGNSPPGUIDrf2001700000000numeric_fac-- ));
126+
DATA(insertOID=389 ("!!"PGNSPPGUIDlf0201700000000numeric_fac-- ));
125127
DATA(insertOID=385 ("="PGNSPPGUIDbt29291638500000cideqeqseleqjoinsel ));
126128
DATA(insertOID=386 ("="PGNSPPGUIDbt22221638600000int2vectoreqeqseleqjoinsel ));
127129
DATA(insertOID=387 ("="PGNSPPGUIDbf27271638700000tideqeqseleqjoinsel ));
128130
#defineTIDEqualOperator 387
129-
DATA(insertOID=388 ("!"PGNSPPGUIDrf20020000000int8fac-- ));
130-
DATA(insertOID=389 ("!!"PGNSPPGUIDlf02020000000int8fac-- ));
131131

132132
DATA(insertOID=410 ("="PGNSPPGUIDbt202016410411412412412413int8eqeqseleqjoinsel ));
133133
DATA(insertOID=411 ("<>"PGNSPPGUIDbf2020164114100000int8neneqselneqjoinsel ));
@@ -176,8 +176,6 @@ DATA(insert OID = 511 ( "@" PGNSP PGUID b f 600 60316 0 0 0 0 0 0 on_
176176
DATA(insertOID=512 ("@"PGNSPPGUIDbf6006021675500000on_ppath-- ));
177177
DATA(insertOID=513 ("@@"PGNSPPGUIDlf0603600000000box_center-- ));
178178
DATA(insertOID=514 ("*"PGNSPPGUIDbf23232351400000int4mul-- ));
179-
DATA(insertOID=515 ("!"PGNSPPGUIDrf23023000000int4fac-- ));
180-
DATA(insertOID=516 ("!!"PGNSPPGUIDlf02323000000int4fac-- ));
181179
DATA(insertOID=517 ("<->"PGNSPPGUIDbf60060070151700000point_distance-- ));
182180
DATA(insertOID=518 ("<>"PGNSPPGUIDbf232316518960000int4neneqselneqjoinsel ));
183181
DATA(insertOID=519 ("<>"PGNSPPGUIDbf212116519940000int2neneqselneqjoinsel ));
@@ -507,8 +505,6 @@ DATA(insert OID = 1133 ( ">"PGNSP PGUID b f 701700 16 1122 1134 0 0 0 0 f
507505
DATA(insertOID=1134 ("<="PGNSPPGUIDbf70170016112511330000float84lescalarltselscalarltjoinsel ));
508506
DATA(insertOID=1135 (">="PGNSPPGUIDbf70170016112411320000float84gescalargtselscalargtjoinsel ));
509507

510-
DATA(insertOID=1158 ("!"PGNSPPGUIDrf21023000000int2fac-- ));
511-
DATA(insertOID=1175 ("!!"PGNSPPGUIDlf02123000000int2fac-- ));
512508

513509
/* LIKE hacks by Keith Parks. */
514510
DATA(insertOID=1207 ("~~"PGNSPPGUIDbf192516012080000namelikelikesellikejoinsel ));

‎src/include/catalog/pg_proc.h

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.316 2003/11/29 22:40:58 pgsql Exp $
10+
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.317 2003/12/01 21:52:37 momjian Exp $
1111
*
1212
* NOTES
1313
* The script catalog/genbki.sh reads this file and generates .bki
@@ -208,8 +208,6 @@ DESCR("PostgreSQL version string");
208208

209209
/* OIDS 100 - 199 */
210210

211-
DATA(insertOID=100 (int8facPGNSPPGUID12fftfi120"20"int8fac-_null_ ));
212-
DESCR("factorial");
213211
DATA(insertOID=101 (eqselPGNSPPGUID12fftfs4701"2281 26 2281 23"eqsel-_null_ ));
214212
DESCR("restriction selectivity of = and related operators");
215213
DATA(insertOID=102 (neqselPGNSPPGUID12fftfs4701"2281 26 2281 23"neqsel-_null_ ));
@@ -231,7 +229,7 @@ DATA(insert OID = 109 ( unknownin PGNSP PGUID 12 f f t f i 1 705 "2275"un
231229
DESCR("I/O");
232230
DATA(insertOID=110 (unknownoutPGNSPPGUID12fftfi12275"705"unknownout-_null_ ));
233231
DESCR("I/O");
234-
232+
DATA(insertOID=111 (numeric_facPGNSPPGUID12fftfi11700"20"numeric_fac-_null_ ));
235233
DATA(insertOID=112 (textPGNSPPGUID12fftfi125"23"int4_text-_null_ ));
236234
DESCR("convert int4 to text");
237235
DATA(insertOID=113 (textPGNSPPGUID12fftfi125"21"int2_text-_null_ ));
@@ -294,8 +292,6 @@ DATA(insert OID = 140 ( areajoinsel PGNSP PGUID 12 f f t f s 4 701 "2281 26
294292
DESCR("join selectivity for area-comparison operators");
295293
DATA(insertOID=141 (int4mulPGNSPPGUID12fftfi223"23 23"int4mul-_null_ ));
296294
DESCR("multiply");
297-
DATA(insertOID=142 (int4facPGNSPPGUID12fftfi123"23"int4fac-_null_ ));
298-
DESCR("factorial");
299295
DATA(insertOID=144 (int4nePGNSPPGUID12fftfi216"23 23"int4ne-_null_ ));
300296
DESCR("not equal");
301297
DATA(insertOID=145 (int2nePGNSPPGUID12fftfi216"21 21"int2ne-_null_ ));
@@ -571,9 +567,6 @@ DESCR("Current date and time - increments during transactions");
571567
DATA(insertOID=275 (isfinitePGNSPPGUID12fftfi116"702"abstime_finite-_null_ ));
572568
DESCR("finite abstime?");
573569

574-
DATA(insertOID=276 (int2facPGNSPPGUID12fftfi123"21"int2fac-_null_ ));
575-
DESCR("factorial");
576-
577570
DATA(insertOID=277 (inter_slPGNSPPGUID12fftfi216"601 628"inter_sl-_null_ ));
578571
DESCR("intersect?");
579572
DATA(insertOID=278 (inter_lbPGNSPPGUID12fftfi216"628 603"inter_lb-_null_ ));
@@ -1758,11 +1751,7 @@ DATA(insert OID = 1390 ( isfinite PGNSP PGUID 12 f f t f i 1 16 "1186" inte
17581751
DESCR("finite interval?");
17591752

17601753

1761-
DATA(insertOID=1391 (factorialPGNSPPGUID12fftfi123"21"int2fac-_null_ ));
1762-
DESCR("factorial");
1763-
DATA(insertOID=1392 (factorialPGNSPPGUID12fftfi123"23"int4fac-_null_ ));
1764-
DESCR("factorial");
1765-
DATA(insertOID=1393 (factorialPGNSPPGUID12fftfi120"20"int8fac-_null_ ));
1754+
DATA(insertOID=1376 (factorialPGNSPPGUID12fftfi11700"20"numeric_fac-_null_ ));
17661755
DESCR("factorial");
17671756
DATA(insertOID=1394 (absPGNSPPGUID12fftfi1700"700"float4abs-_null_ ));
17681757
DESCR("absolute value");

‎src/include/utils/builtins.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.230 2003/11/29 22:41:15 pgsql Exp $
10+
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.231 2003/12/01 21:52:38 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -159,8 +159,6 @@ extern Datum int4mod(PG_FUNCTION_ARGS);
159159
externDatumint2mod(PG_FUNCTION_ARGS);
160160
externDatumint24mod(PG_FUNCTION_ARGS);
161161
externDatumint42mod(PG_FUNCTION_ARGS);
162-
externDatumint4fac(PG_FUNCTION_ARGS);
163-
externDatumint2fac(PG_FUNCTION_ARGS);
164162
externDatumint2larger(PG_FUNCTION_ARGS);
165163
externDatumint2smaller(PG_FUNCTION_ARGS);
166164
externDatumint4larger(PG_FUNCTION_ARGS);
@@ -720,6 +718,7 @@ extern Datum numeric_mod(PG_FUNCTION_ARGS);
720718
externDatumnumeric_inc(PG_FUNCTION_ARGS);
721719
externDatumnumeric_smaller(PG_FUNCTION_ARGS);
722720
externDatumnumeric_larger(PG_FUNCTION_ARGS);
721+
externDatumnumeric_fac(PG_FUNCTION_ARGS);
723722
externDatumnumeric_sqrt(PG_FUNCTION_ARGS);
724723
externDatumnumeric_exp(PG_FUNCTION_ARGS);
725724
externDatumnumeric_ln(PG_FUNCTION_ARGS);

‎src/include/utils/int8.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/utils/int8.h,v 1.39 2003/11/29 22:41:15 pgsql Exp $
10+
* $PostgreSQL: pgsql/src/include/utils/int8.h,v 1.40 2003/12/01 21:52:38 momjian Exp $
1111
*
1212
* NOTES
1313
* These data types are supported on all 64-bit architectures, and may
@@ -72,7 +72,6 @@ extern Datum int8mi(PG_FUNCTION_ARGS);
7272
externDatumint8mul(PG_FUNCTION_ARGS);
7373
externDatumint8div(PG_FUNCTION_ARGS);
7474
externDatumint8abs(PG_FUNCTION_ARGS);
75-
externDatumint8fac(PG_FUNCTION_ARGS);
7675
externDatumint8mod(PG_FUNCTION_ARGS);
7776
externDatumint8inc(PG_FUNCTION_ARGS);
7877
externDatumint8larger(PG_FUNCTION_ARGS);

‎src/test/regress/expected/create_operator.out

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,17 @@ CREATE OPERATOR <% (
1515
negator = >=%
1616
);
1717
CREATE OPERATOR @#@ (
18-
rightarg =int4,-- left unary
19-
procedure =int4fac
18+
rightarg =int8,-- left unary
19+
procedure =numeric_fac
2020
);
2121
CREATE OPERATOR #@# (
22-
leftarg =int4,-- right unary
23-
procedure =int4fac
22+
leftarg =int8,-- right unary
23+
procedure =numeric_fac
2424
);
2525
CREATE OPERATOR #%# (
26-
leftarg =int4,-- right unary
27-
procedure =int4fac
26+
leftarg =int8,-- right unary
27+
procedure =numeric_fac
2828
);
2929
-- Test comments
3030
COMMENT ON OPERATOR ###### (int4, NONE) IS 'bad right unary';
3131
ERROR: operator does not exist: integer ######
32-
COMMENT ON OPERATOR #%# (int4, NONE) IS 'right unary';
33-
COMMENT ON OPERATOR #%# (int4, NONE) IS NULL;

‎src/test/regress/sql/create_operator.sql

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,21 @@ CREATE OPERATOR <% (
1818
);
1919

2020
CREATE OPERATOR @#@ (
21-
rightarg=int4,-- left unary
22-
procedure=int4fac
21+
rightarg=int8,-- left unary
22+
procedure=numeric_fac
2323
);
2424

2525
CREATE OPERATOR#@# (
26-
leftarg=int4,-- right unary
27-
procedure=int4fac
26+
leftarg=int8,-- right unary
27+
procedure=numeric_fac
2828
);
2929

3030
CREATE OPERATOR#%# (
31-
leftarg=int4,-- right unary
32-
procedure=int4fac
31+
leftarg=int8,-- right unary
32+
procedure=numeric_fac
3333
);
3434

3535
-- Test comments
3636
COMMENT ON OPERATOR ###### (int4, NONE) IS'bad right unary';
37-
COMMENT ON OPERATOR #%# (int4, NONE) IS'right unary';
38-
COMMENT ON OPERATOR #%# (int4, NONE) ISNULL;
3937

4038

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp