1414 * Copyright (c) 1998-2005, PostgreSQL Global Development Group
1515 *
1616 * IDENTIFICATION
17- * $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.83 2005/04/06 23:56:07 neilc Exp $
17+ * $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.84 2005/06/04 14:12:50 momjian Exp $
1818 *
1919 *-------------------------------------------------------------------------
2020 */
@@ -265,7 +265,7 @@ static void sub_var(NumericVar *var1, NumericVar *var2, NumericVar *result);
265265static void mul_var (NumericVar * var1 ,NumericVar * var2 ,NumericVar * result ,
266266int rscale );
267267static void div_var (NumericVar * var1 ,NumericVar * var2 ,NumericVar * result ,
268- int rscale );
268+ int rscale , bool round );
269269static int select_div_scale (NumericVar * var1 ,NumericVar * var2 );
270270static void mod_var (NumericVar * var1 ,NumericVar * var2 ,NumericVar * result );
271271static void ceil_var (NumericVar * var ,NumericVar * result );
@@ -906,14 +906,14 @@ compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
906906sub_var (& operand_var ,& bound1_var ,& operand_var );
907907sub_var (& bound2_var ,& bound1_var ,& bound2_var );
908908div_var (& operand_var ,& bound2_var ,result_var ,
909- select_div_scale (& operand_var ,& bound2_var ));
909+ select_div_scale (& operand_var ,& bound2_var ), true );
910910}
911911else
912912{
913913sub_var (& bound1_var ,& operand_var ,& operand_var );
914914sub_var (& bound1_var ,& bound2_var ,& bound1_var );
915915div_var (& operand_var ,& bound1_var ,result_var ,
916- select_div_scale (& operand_var ,& bound1_var ));
916+ select_div_scale (& operand_var ,& bound1_var ), true );
917917}
918918
919919mul_var (result_var ,count_var ,result_var ,
@@ -1266,7 +1266,7 @@ numeric_div(PG_FUNCTION_ARGS)
12661266/*
12671267 * Do the divide and return the result
12681268 */
1269- div_var (& arg1 ,& arg2 ,& result ,rscale );
1269+ div_var (& arg1 ,& arg2 ,& result ,rscale , true );
12701270
12711271res = make_result (& result );
12721272
@@ -2246,7 +2246,7 @@ numeric_variance(PG_FUNCTION_ARGS)
22462246{
22472247mul_var (& vN ,& vNminus1 ,& vNminus1 ,0 );/* N * (N - 1) */
22482248rscale = select_div_scale (& vsumX2 ,& vNminus1 );
2249- div_var (& vsumX2 ,& vNminus1 ,& vsumX ,rscale );/* variance */
2249+ div_var (& vsumX2 ,& vNminus1 ,& vsumX ,rscale , true );/* variance */
22502250
22512251res = make_result (& vsumX );
22522252}
@@ -2322,7 +2322,7 @@ numeric_stddev(PG_FUNCTION_ARGS)
23222322{
23232323mul_var (& vN ,& vNminus1 ,& vNminus1 ,0 );/* N * (N - 1) */
23242324rscale = select_div_scale (& vsumX2 ,& vNminus1 );
2325- div_var (& vsumX2 ,& vNminus1 ,& vsumX ,rscale );/* variance */
2325+ div_var (& vsumX2 ,& vNminus1 ,& vsumX ,rscale , true );/* variance */
23262326sqrt_var (& vsumX ,& vsumX ,rscale );/* stddev */
23272327
23282328res = make_result (& vsumX );
@@ -3840,7 +3840,7 @@ mul_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
38403840 */
38413841static void
38423842div_var (NumericVar * var1 ,NumericVar * var2 ,NumericVar * result ,
3843- int rscale )
3843+ int rscale , bool round )
38443844{
38453845int div_ndigits ;
38463846int res_sign ;
@@ -4079,8 +4079,11 @@ div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
40794079result -> sign = res_sign ;
40804080
40814081/* Round to target rscale (and set result->dscale) */
4082- round_var (result ,rscale );
4083-
4082+ if (round )
4083+ round_var (result ,rscale );
4084+ else
4085+ trunc_var (result ,rscale );
4086+
40844087/* Strip leading and trailing zeroes */
40854088strip_var (result );
40864089}
@@ -4178,7 +4181,7 @@ mod_var(NumericVar *var1, NumericVar *var2, NumericVar *result)
41784181 */
41794182rscale = select_div_scale (var1 ,var2 );
41804183
4181- div_var (var1 ,var2 ,& tmp ,rscale );
4184+ div_var (var1 ,var2 ,& tmp ,rscale , false );
41824185
41834186trunc_var (& tmp ,0 );
41844187
@@ -4294,7 +4297,7 @@ sqrt_var(NumericVar *arg, NumericVar *result, int rscale)
42944297
42954298for (;;)
42964299{
4297- div_var (& tmp_arg ,result ,& tmp_val ,local_rscale );
4300+ div_var (& tmp_arg ,result ,& tmp_val ,local_rscale , true );
42984301
42994302add_var (result ,& tmp_val ,result );
43004303mul_var (result ,& const_zero_point_five ,result ,local_rscale );
@@ -4384,7 +4387,7 @@ exp_var(NumericVar *arg, NumericVar *result, int rscale)
43844387
43854388/* Compensate for input sign, and round to requested rscale */
43864389if (xneg )
4387- div_var (& const_one ,result ,result ,rscale );
4390+ div_var (& const_one ,result ,result ,rscale , true );
43884391else
43894392round_var (result ,rscale );
43904393
@@ -4450,7 +4453,7 @@ exp_var_internal(NumericVar *arg, NumericVar *result, int rscale)
44504453add_var (& ni ,& const_one ,& ni );
44514454mul_var (& xpow ,& x ,& xpow ,local_rscale );
44524455mul_var (& ifac ,& ni ,& ifac ,0 );
4453- div_var (& xpow ,& ifac ,& elem ,local_rscale );
4456+ div_var (& xpow ,& ifac ,& elem ,local_rscale , true );
44544457
44554458if (elem .ndigits == 0 )
44564459break ;
@@ -4534,7 +4537,7 @@ ln_var(NumericVar *arg, NumericVar *result, int rscale)
45344537 */
45354538sub_var (& x ,& const_one ,result );
45364539add_var (& x ,& const_one ,& elem );
4537- div_var (result ,& elem ,result ,local_rscale );
4540+ div_var (result ,& elem ,result ,local_rscale , true );
45384541set_var_from_var (result ,& xx );
45394542mul_var (result ,result ,& x ,local_rscale );
45404543
@@ -4544,7 +4547,7 @@ ln_var(NumericVar *arg, NumericVar *result, int rscale)
45444547{
45454548add_var (& ni ,& const_two ,& ni );
45464549mul_var (& xx ,& x ,& xx ,local_rscale );
4547- div_var (& xx ,& ni ,& elem ,local_rscale );
4550+ div_var (& xx ,& ni ,& elem ,local_rscale , true );
45484551
45494552if (elem .ndigits == 0 )
45504553break ;
@@ -4614,7 +4617,7 @@ log_var(NumericVar *base, NumericVar *num, NumericVar *result)
46144617/* Select scale for division result */
46154618rscale = select_div_scale (& ln_num ,& ln_base );
46164619
4617- div_var (& ln_num ,& ln_base ,result ,rscale );
4620+ div_var (& ln_num ,& ln_base ,result ,rscale , true );
46184621
46194622free_var (& ln_num );
46204623free_var (& ln_base );
@@ -4752,7 +4755,7 @@ power_var_int(NumericVar *base, int exp, NumericVar *result, int rscale)
47524755round_var (result ,rscale );
47534756return ;
47544757case -1 :
4755- div_var (& const_one ,base ,result ,rscale );
4758+ div_var (& const_one ,base ,result ,rscale , true );
47564759return ;
47574760case 2 :
47584761mul_var (base ,base ,result ,rscale );
@@ -4790,7 +4793,7 @@ power_var_int(NumericVar *base, int exp, NumericVar *result, int rscale)
47904793
47914794/* Compensate for input sign, and round to requested rscale */
47924795if (neg )
4793- div_var (& const_one ,result ,result ,rscale );
4796+ div_var (& const_one ,result ,result ,rscale , true );
47944797else
47954798round_var (result ,rscale );
47964799}