Header And Logo

PostgreSQL
| The world's most advanced open source database.

int8.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * int8.c
00004  *    Internal 64-bit integer operations
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  * IDENTIFICATION
00010  *    src/backend/utils/adt/int8.c
00011  *
00012  *-------------------------------------------------------------------------
00013  */
00014 #include "postgres.h"
00015 
00016 #include <ctype.h>
00017 #include <limits.h>
00018 #include <math.h>
00019 
00020 #include "funcapi.h"
00021 #include "libpq/pqformat.h"
00022 #include "utils/int8.h"
00023 #include "utils/builtins.h"
00024 
00025 
00026 #define MAXINT8LEN      25
00027 
00028 #define SAMESIGN(a,b)   (((a) < 0) == ((b) < 0))
00029 
00030 typedef struct
00031 {
00032     int64       current;
00033     int64       finish;
00034     int64       step;
00035 } generate_series_fctx;
00036 
00037 
00038 /***********************************************************************
00039  **
00040  **     Routines for 64-bit integers.
00041  **
00042  ***********************************************************************/
00043 
00044 /*----------------------------------------------------------
00045  * Formatting and conversion routines.
00046  *---------------------------------------------------------*/
00047 
00048 /*
00049  * scanint8 --- try to parse a string into an int8.
00050  *
00051  * If errorOK is false, ereport a useful error message if the string is bad.
00052  * If errorOK is true, just return "false" for bad input.
00053  */
00054 bool
00055 scanint8(const char *str, bool errorOK, int64 *result)
00056 {
00057     const char *ptr = str;
00058     int64       tmp = 0;
00059     int         sign = 1;
00060 
00061     /*
00062      * Do our own scan, rather than relying on sscanf which might be broken
00063      * for long long.
00064      */
00065 
00066     /* skip leading spaces */
00067     while (*ptr && isspace((unsigned char) *ptr))
00068         ptr++;
00069 
00070     /* handle sign */
00071     if (*ptr == '-')
00072     {
00073         ptr++;
00074 
00075         /*
00076          * Do an explicit check for INT64_MIN.  Ugly though this is, it's
00077          * cleaner than trying to get the loop below to handle it portably.
00078          */
00079         if (strncmp(ptr, "9223372036854775808", 19) == 0)
00080         {
00081             tmp = -INT64CONST(0x7fffffffffffffff) - 1;
00082             ptr += 19;
00083             goto gotdigits;
00084         }
00085         sign = -1;
00086     }
00087     else if (*ptr == '+')
00088         ptr++;
00089 
00090     /* require at least one digit */
00091     if (!isdigit((unsigned char) *ptr))
00092     {
00093         if (errorOK)
00094             return false;
00095         else
00096             ereport(ERROR,
00097                     (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
00098                      errmsg("invalid input syntax for integer: \"%s\"",
00099                             str)));
00100     }
00101 
00102     /* process digits */
00103     while (*ptr && isdigit((unsigned char) *ptr))
00104     {
00105         int64       newtmp = tmp * 10 + (*ptr++ - '0');
00106 
00107         if ((newtmp / 10) != tmp)       /* overflow? */
00108         {
00109             if (errorOK)
00110                 return false;
00111             else
00112                 ereport(ERROR,
00113                         (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00114                        errmsg("value \"%s\" is out of range for type bigint",
00115                               str)));
00116         }
00117         tmp = newtmp;
00118     }
00119 
00120 gotdigits:
00121 
00122     /* allow trailing whitespace, but not other trailing chars */
00123     while (*ptr != '\0' && isspace((unsigned char) *ptr))
00124         ptr++;
00125 
00126     if (*ptr != '\0')
00127     {
00128         if (errorOK)
00129             return false;
00130         else
00131             ereport(ERROR,
00132                     (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
00133                      errmsg("invalid input syntax for integer: \"%s\"",
00134                             str)));
00135     }
00136 
00137     *result = (sign < 0) ? -tmp : tmp;
00138 
00139     return true;
00140 }
00141 
00142 /* int8in()
00143  */
00144 Datum
00145 int8in(PG_FUNCTION_ARGS)
00146 {
00147     char       *str = PG_GETARG_CSTRING(0);
00148     int64       result;
00149 
00150     (void) scanint8(str, false, &result);
00151     PG_RETURN_INT64(result);
00152 }
00153 
00154 
00155 /* int8out()
00156  */
00157 Datum
00158 int8out(PG_FUNCTION_ARGS)
00159 {
00160     int64       val = PG_GETARG_INT64(0);
00161     char        buf[MAXINT8LEN + 1];
00162     char       *result;
00163 
00164     pg_lltoa(val, buf);
00165     result = pstrdup(buf);
00166     PG_RETURN_CSTRING(result);
00167 }
00168 
00169 /*
00170  *      int8recv            - converts external binary format to int8
00171  */
00172 Datum
00173 int8recv(PG_FUNCTION_ARGS)
00174 {
00175     StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
00176 
00177     PG_RETURN_INT64(pq_getmsgint64(buf));
00178 }
00179 
00180 /*
00181  *      int8send            - converts int8 to binary format
00182  */
00183 Datum
00184 int8send(PG_FUNCTION_ARGS)
00185 {
00186     int64       arg1 = PG_GETARG_INT64(0);
00187     StringInfoData buf;
00188 
00189     pq_begintypsend(&buf);
00190     pq_sendint64(&buf, arg1);
00191     PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
00192 }
00193 
00194 
00195 /*----------------------------------------------------------
00196  *  Relational operators for int8s, including cross-data-type comparisons.
00197  *---------------------------------------------------------*/
00198 
00199 /* int8relop()
00200  * Is val1 relop val2?
00201  */
00202 Datum
00203 int8eq(PG_FUNCTION_ARGS)
00204 {
00205     int64       val1 = PG_GETARG_INT64(0);
00206     int64       val2 = PG_GETARG_INT64(1);
00207 
00208     PG_RETURN_BOOL(val1 == val2);
00209 }
00210 
00211 Datum
00212 int8ne(PG_FUNCTION_ARGS)
00213 {
00214     int64       val1 = PG_GETARG_INT64(0);
00215     int64       val2 = PG_GETARG_INT64(1);
00216 
00217     PG_RETURN_BOOL(val1 != val2);
00218 }
00219 
00220 Datum
00221 int8lt(PG_FUNCTION_ARGS)
00222 {
00223     int64       val1 = PG_GETARG_INT64(0);
00224     int64       val2 = PG_GETARG_INT64(1);
00225 
00226     PG_RETURN_BOOL(val1 < val2);
00227 }
00228 
00229 Datum
00230 int8gt(PG_FUNCTION_ARGS)
00231 {
00232     int64       val1 = PG_GETARG_INT64(0);
00233     int64       val2 = PG_GETARG_INT64(1);
00234 
00235     PG_RETURN_BOOL(val1 > val2);
00236 }
00237 
00238 Datum
00239 int8le(PG_FUNCTION_ARGS)
00240 {
00241     int64       val1 = PG_GETARG_INT64(0);
00242     int64       val2 = PG_GETARG_INT64(1);
00243 
00244     PG_RETURN_BOOL(val1 <= val2);
00245 }
00246 
00247 Datum
00248 int8ge(PG_FUNCTION_ARGS)
00249 {
00250     int64       val1 = PG_GETARG_INT64(0);
00251     int64       val2 = PG_GETARG_INT64(1);
00252 
00253     PG_RETURN_BOOL(val1 >= val2);
00254 }
00255 
00256 /* int84relop()
00257  * Is 64-bit val1 relop 32-bit val2?
00258  */
00259 Datum
00260 int84eq(PG_FUNCTION_ARGS)
00261 {
00262     int64       val1 = PG_GETARG_INT64(0);
00263     int32       val2 = PG_GETARG_INT32(1);
00264 
00265     PG_RETURN_BOOL(val1 == val2);
00266 }
00267 
00268 Datum
00269 int84ne(PG_FUNCTION_ARGS)
00270 {
00271     int64       val1 = PG_GETARG_INT64(0);
00272     int32       val2 = PG_GETARG_INT32(1);
00273 
00274     PG_RETURN_BOOL(val1 != val2);
00275 }
00276 
00277 Datum
00278 int84lt(PG_FUNCTION_ARGS)
00279 {
00280     int64       val1 = PG_GETARG_INT64(0);
00281     int32       val2 = PG_GETARG_INT32(1);
00282 
00283     PG_RETURN_BOOL(val1 < val2);
00284 }
00285 
00286 Datum
00287 int84gt(PG_FUNCTION_ARGS)
00288 {
00289     int64       val1 = PG_GETARG_INT64(0);
00290     int32       val2 = PG_GETARG_INT32(1);
00291 
00292     PG_RETURN_BOOL(val1 > val2);
00293 }
00294 
00295 Datum
00296 int84le(PG_FUNCTION_ARGS)
00297 {
00298     int64       val1 = PG_GETARG_INT64(0);
00299     int32       val2 = PG_GETARG_INT32(1);
00300 
00301     PG_RETURN_BOOL(val1 <= val2);
00302 }
00303 
00304 Datum
00305 int84ge(PG_FUNCTION_ARGS)
00306 {
00307     int64       val1 = PG_GETARG_INT64(0);
00308     int32       val2 = PG_GETARG_INT32(1);
00309 
00310     PG_RETURN_BOOL(val1 >= val2);
00311 }
00312 
00313 /* int48relop()
00314  * Is 32-bit val1 relop 64-bit val2?
00315  */
00316 Datum
00317 int48eq(PG_FUNCTION_ARGS)
00318 {
00319     int32       val1 = PG_GETARG_INT32(0);
00320     int64       val2 = PG_GETARG_INT64(1);
00321 
00322     PG_RETURN_BOOL(val1 == val2);
00323 }
00324 
00325 Datum
00326 int48ne(PG_FUNCTION_ARGS)
00327 {
00328     int32       val1 = PG_GETARG_INT32(0);
00329     int64       val2 = PG_GETARG_INT64(1);
00330 
00331     PG_RETURN_BOOL(val1 != val2);
00332 }
00333 
00334 Datum
00335 int48lt(PG_FUNCTION_ARGS)
00336 {
00337     int32       val1 = PG_GETARG_INT32(0);
00338     int64       val2 = PG_GETARG_INT64(1);
00339 
00340     PG_RETURN_BOOL(val1 < val2);
00341 }
00342 
00343 Datum
00344 int48gt(PG_FUNCTION_ARGS)
00345 {
00346     int32       val1 = PG_GETARG_INT32(0);
00347     int64       val2 = PG_GETARG_INT64(1);
00348 
00349     PG_RETURN_BOOL(val1 > val2);
00350 }
00351 
00352 Datum
00353 int48le(PG_FUNCTION_ARGS)
00354 {
00355     int32       val1 = PG_GETARG_INT32(0);
00356     int64       val2 = PG_GETARG_INT64(1);
00357 
00358     PG_RETURN_BOOL(val1 <= val2);
00359 }
00360 
00361 Datum
00362 int48ge(PG_FUNCTION_ARGS)
00363 {
00364     int32       val1 = PG_GETARG_INT32(0);
00365     int64       val2 = PG_GETARG_INT64(1);
00366 
00367     PG_RETURN_BOOL(val1 >= val2);
00368 }
00369 
00370 /* int82relop()
00371  * Is 64-bit val1 relop 16-bit val2?
00372  */
00373 Datum
00374 int82eq(PG_FUNCTION_ARGS)
00375 {
00376     int64       val1 = PG_GETARG_INT64(0);
00377     int16       val2 = PG_GETARG_INT16(1);
00378 
00379     PG_RETURN_BOOL(val1 == val2);
00380 }
00381 
00382 Datum
00383 int82ne(PG_FUNCTION_ARGS)
00384 {
00385     int64       val1 = PG_GETARG_INT64(0);
00386     int16       val2 = PG_GETARG_INT16(1);
00387 
00388     PG_RETURN_BOOL(val1 != val2);
00389 }
00390 
00391 Datum
00392 int82lt(PG_FUNCTION_ARGS)
00393 {
00394     int64       val1 = PG_GETARG_INT64(0);
00395     int16       val2 = PG_GETARG_INT16(1);
00396 
00397     PG_RETURN_BOOL(val1 < val2);
00398 }
00399 
00400 Datum
00401 int82gt(PG_FUNCTION_ARGS)
00402 {
00403     int64       val1 = PG_GETARG_INT64(0);
00404     int16       val2 = PG_GETARG_INT16(1);
00405 
00406     PG_RETURN_BOOL(val1 > val2);
00407 }
00408 
00409 Datum
00410 int82le(PG_FUNCTION_ARGS)
00411 {
00412     int64       val1 = PG_GETARG_INT64(0);
00413     int16       val2 = PG_GETARG_INT16(1);
00414 
00415     PG_RETURN_BOOL(val1 <= val2);
00416 }
00417 
00418 Datum
00419 int82ge(PG_FUNCTION_ARGS)
00420 {
00421     int64       val1 = PG_GETARG_INT64(0);
00422     int16       val2 = PG_GETARG_INT16(1);
00423 
00424     PG_RETURN_BOOL(val1 >= val2);
00425 }
00426 
00427 /* int28relop()
00428  * Is 16-bit val1 relop 64-bit val2?
00429  */
00430 Datum
00431 int28eq(PG_FUNCTION_ARGS)
00432 {
00433     int16       val1 = PG_GETARG_INT16(0);
00434     int64       val2 = PG_GETARG_INT64(1);
00435 
00436     PG_RETURN_BOOL(val1 == val2);
00437 }
00438 
00439 Datum
00440 int28ne(PG_FUNCTION_ARGS)
00441 {
00442     int16       val1 = PG_GETARG_INT16(0);
00443     int64       val2 = PG_GETARG_INT64(1);
00444 
00445     PG_RETURN_BOOL(val1 != val2);
00446 }
00447 
00448 Datum
00449 int28lt(PG_FUNCTION_ARGS)
00450 {
00451     int16       val1 = PG_GETARG_INT16(0);
00452     int64       val2 = PG_GETARG_INT64(1);
00453 
00454     PG_RETURN_BOOL(val1 < val2);
00455 }
00456 
00457 Datum
00458 int28gt(PG_FUNCTION_ARGS)
00459 {
00460     int16       val1 = PG_GETARG_INT16(0);
00461     int64       val2 = PG_GETARG_INT64(1);
00462 
00463     PG_RETURN_BOOL(val1 > val2);
00464 }
00465 
00466 Datum
00467 int28le(PG_FUNCTION_ARGS)
00468 {
00469     int16       val1 = PG_GETARG_INT16(0);
00470     int64       val2 = PG_GETARG_INT64(1);
00471 
00472     PG_RETURN_BOOL(val1 <= val2);
00473 }
00474 
00475 Datum
00476 int28ge(PG_FUNCTION_ARGS)
00477 {
00478     int16       val1 = PG_GETARG_INT16(0);
00479     int64       val2 = PG_GETARG_INT64(1);
00480 
00481     PG_RETURN_BOOL(val1 >= val2);
00482 }
00483 
00484 
00485 /*----------------------------------------------------------
00486  *  Arithmetic operators on 64-bit integers.
00487  *---------------------------------------------------------*/
00488 
00489 Datum
00490 int8um(PG_FUNCTION_ARGS)
00491 {
00492     int64       arg = PG_GETARG_INT64(0);
00493     int64       result;
00494 
00495     result = -arg;
00496     /* overflow check (needed for INT64_MIN) */
00497     if (arg != 0 && SAMESIGN(result, arg))
00498         ereport(ERROR,
00499                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00500                  errmsg("bigint out of range")));
00501     PG_RETURN_INT64(result);
00502 }
00503 
00504 Datum
00505 int8up(PG_FUNCTION_ARGS)
00506 {
00507     int64       arg = PG_GETARG_INT64(0);
00508 
00509     PG_RETURN_INT64(arg);
00510 }
00511 
00512 Datum
00513 int8pl(PG_FUNCTION_ARGS)
00514 {
00515     int64       arg1 = PG_GETARG_INT64(0);
00516     int64       arg2 = PG_GETARG_INT64(1);
00517     int64       result;
00518 
00519     result = arg1 + arg2;
00520 
00521     /*
00522      * Overflow check.  If the inputs are of different signs then their sum
00523      * cannot overflow.  If the inputs are of the same sign, their sum had
00524      * better be that sign too.
00525      */
00526     if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
00527         ereport(ERROR,
00528                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00529                  errmsg("bigint out of range")));
00530     PG_RETURN_INT64(result);
00531 }
00532 
00533 Datum
00534 int8mi(PG_FUNCTION_ARGS)
00535 {
00536     int64       arg1 = PG_GETARG_INT64(0);
00537     int64       arg2 = PG_GETARG_INT64(1);
00538     int64       result;
00539 
00540     result = arg1 - arg2;
00541 
00542     /*
00543      * Overflow check.  If the inputs are of the same sign then their
00544      * difference cannot overflow.  If they are of different signs then the
00545      * result should be of the same sign as the first input.
00546      */
00547     if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
00548         ereport(ERROR,
00549                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00550                  errmsg("bigint out of range")));
00551     PG_RETURN_INT64(result);
00552 }
00553 
00554 Datum
00555 int8mul(PG_FUNCTION_ARGS)
00556 {
00557     int64       arg1 = PG_GETARG_INT64(0);
00558     int64       arg2 = PG_GETARG_INT64(1);
00559     int64       result;
00560 
00561     result = arg1 * arg2;
00562 
00563     /*
00564      * Overflow check.  We basically check to see if result / arg2 gives arg1
00565      * again.  There are two cases where this fails: arg2 = 0 (which cannot
00566      * overflow) and arg1 = INT64_MIN, arg2 = -1 (where the division itself
00567      * will overflow and thus incorrectly match).
00568      *
00569      * Since the division is likely much more expensive than the actual
00570      * multiplication, we'd like to skip it where possible.  The best bang for
00571      * the buck seems to be to check whether both inputs are in the int32
00572      * range; if so, no overflow is possible.
00573      */
00574     if (arg1 != (int64) ((int32) arg1) || arg2 != (int64) ((int32) arg2))
00575     {
00576         if (arg2 != 0 &&
00577             ((arg2 == -1 && arg1 < 0 && result < 0) ||
00578              result / arg2 != arg1))
00579             ereport(ERROR,
00580                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00581                      errmsg("bigint out of range")));
00582     }
00583     PG_RETURN_INT64(result);
00584 }
00585 
00586 Datum
00587 int8div(PG_FUNCTION_ARGS)
00588 {
00589     int64       arg1 = PG_GETARG_INT64(0);
00590     int64       arg2 = PG_GETARG_INT64(1);
00591     int64       result;
00592 
00593     if (arg2 == 0)
00594     {
00595         ereport(ERROR,
00596                 (errcode(ERRCODE_DIVISION_BY_ZERO),
00597                  errmsg("division by zero")));
00598         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
00599         PG_RETURN_NULL();
00600     }
00601 
00602     /*
00603      * INT64_MIN / -1 is problematic, since the result can't be represented on
00604      * a two's-complement machine.  Some machines produce INT64_MIN, some
00605      * produce zero, some throw an exception.  We can dodge the problem by
00606      * recognizing that division by -1 is the same as negation.
00607      */
00608     if (arg2 == -1)
00609     {
00610         result = -arg1;
00611         /* overflow check (needed for INT64_MIN) */
00612         if (arg1 != 0 && SAMESIGN(result, arg1))
00613             ereport(ERROR,
00614                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00615                      errmsg("bigint out of range")));
00616         PG_RETURN_INT64(result);
00617     }
00618 
00619     /* No overflow is possible */
00620 
00621     result = arg1 / arg2;
00622 
00623     PG_RETURN_INT64(result);
00624 }
00625 
00626 /* int8abs()
00627  * Absolute value
00628  */
00629 Datum
00630 int8abs(PG_FUNCTION_ARGS)
00631 {
00632     int64       arg1 = PG_GETARG_INT64(0);
00633     int64       result;
00634 
00635     result = (arg1 < 0) ? -arg1 : arg1;
00636     /* overflow check (needed for INT64_MIN) */
00637     if (result < 0)
00638         ereport(ERROR,
00639                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00640                  errmsg("bigint out of range")));
00641     PG_RETURN_INT64(result);
00642 }
00643 
00644 /* int8mod()
00645  * Modulo operation.
00646  */
00647 Datum
00648 int8mod(PG_FUNCTION_ARGS)
00649 {
00650     int64       arg1 = PG_GETARG_INT64(0);
00651     int64       arg2 = PG_GETARG_INT64(1);
00652 
00653     if (arg2 == 0)
00654     {
00655         ereport(ERROR,
00656                 (errcode(ERRCODE_DIVISION_BY_ZERO),
00657                  errmsg("division by zero")));
00658         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
00659         PG_RETURN_NULL();
00660     }
00661 
00662     /*
00663      * Some machines throw a floating-point exception for INT64_MIN % -1,
00664      * which is a bit silly since the correct answer is perfectly
00665      * well-defined, namely zero.
00666      */
00667     if (arg2 == -1)
00668         PG_RETURN_INT64(0);
00669 
00670     /* No overflow is possible */
00671 
00672     PG_RETURN_INT64(arg1 % arg2);
00673 }
00674 
00675 
00676 Datum
00677 int8inc(PG_FUNCTION_ARGS)
00678 {
00679     /*
00680      * When int8 is pass-by-reference, we provide this special case to avoid
00681      * palloc overhead for COUNT(): when called as an aggregate, we know that
00682      * the argument is modifiable local storage, so just update it in-place.
00683      * (If int8 is pass-by-value, then of course this is useless as well as
00684      * incorrect, so just ifdef it out.)
00685      */
00686 #ifndef USE_FLOAT8_BYVAL        /* controls int8 too */
00687     if (AggCheckCallContext(fcinfo, NULL))
00688     {
00689         int64      *arg = (int64 *) PG_GETARG_POINTER(0);
00690         int64       result;
00691 
00692         result = *arg + 1;
00693         /* Overflow check */
00694         if (result < 0 && *arg > 0)
00695             ereport(ERROR,
00696                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00697                      errmsg("bigint out of range")));
00698 
00699         *arg = result;
00700         PG_RETURN_POINTER(arg);
00701     }
00702     else
00703 #endif
00704     {
00705         /* Not called as an aggregate, so just do it the dumb way */
00706         int64       arg = PG_GETARG_INT64(0);
00707         int64       result;
00708 
00709         result = arg + 1;
00710         /* Overflow check */
00711         if (result < 0 && arg > 0)
00712             ereport(ERROR,
00713                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00714                      errmsg("bigint out of range")));
00715 
00716         PG_RETURN_INT64(result);
00717     }
00718 }
00719 
00720 /*
00721  * These functions are exactly like int8inc but are used for aggregates that
00722  * count only non-null values.  Since the functions are declared strict,
00723  * the null checks happen before we ever get here, and all we need do is
00724  * increment the state value.  We could actually make these pg_proc entries
00725  * point right at int8inc, but then the opr_sanity regression test would
00726  * complain about mismatched entries for a built-in function.
00727  */
00728 
00729 Datum
00730 int8inc_any(PG_FUNCTION_ARGS)
00731 {
00732     return int8inc(fcinfo);
00733 }
00734 
00735 Datum
00736 int8inc_float8_float8(PG_FUNCTION_ARGS)
00737 {
00738     return int8inc(fcinfo);
00739 }
00740 
00741 
00742 Datum
00743 int8larger(PG_FUNCTION_ARGS)
00744 {
00745     int64       arg1 = PG_GETARG_INT64(0);
00746     int64       arg2 = PG_GETARG_INT64(1);
00747     int64       result;
00748 
00749     result = ((arg1 > arg2) ? arg1 : arg2);
00750 
00751     PG_RETURN_INT64(result);
00752 }
00753 
00754 Datum
00755 int8smaller(PG_FUNCTION_ARGS)
00756 {
00757     int64       arg1 = PG_GETARG_INT64(0);
00758     int64       arg2 = PG_GETARG_INT64(1);
00759     int64       result;
00760 
00761     result = ((arg1 < arg2) ? arg1 : arg2);
00762 
00763     PG_RETURN_INT64(result);
00764 }
00765 
00766 Datum
00767 int84pl(PG_FUNCTION_ARGS)
00768 {
00769     int64       arg1 = PG_GETARG_INT64(0);
00770     int32       arg2 = PG_GETARG_INT32(1);
00771     int64       result;
00772 
00773     result = arg1 + arg2;
00774 
00775     /*
00776      * Overflow check.  If the inputs are of different signs then their sum
00777      * cannot overflow.  If the inputs are of the same sign, their sum had
00778      * better be that sign too.
00779      */
00780     if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
00781         ereport(ERROR,
00782                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00783                  errmsg("bigint out of range")));
00784     PG_RETURN_INT64(result);
00785 }
00786 
00787 Datum
00788 int84mi(PG_FUNCTION_ARGS)
00789 {
00790     int64       arg1 = PG_GETARG_INT64(0);
00791     int32       arg2 = PG_GETARG_INT32(1);
00792     int64       result;
00793 
00794     result = arg1 - arg2;
00795 
00796     /*
00797      * Overflow check.  If the inputs are of the same sign then their
00798      * difference cannot overflow.  If they are of different signs then the
00799      * result should be of the same sign as the first input.
00800      */
00801     if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
00802         ereport(ERROR,
00803                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00804                  errmsg("bigint out of range")));
00805     PG_RETURN_INT64(result);
00806 }
00807 
00808 Datum
00809 int84mul(PG_FUNCTION_ARGS)
00810 {
00811     int64       arg1 = PG_GETARG_INT64(0);
00812     int32       arg2 = PG_GETARG_INT32(1);
00813     int64       result;
00814 
00815     result = arg1 * arg2;
00816 
00817     /*
00818      * Overflow check.  We basically check to see if result / arg1 gives arg2
00819      * again.  There is one case where this fails: arg1 = 0 (which cannot
00820      * overflow).
00821      *
00822      * Since the division is likely much more expensive than the actual
00823      * multiplication, we'd like to skip it where possible.  The best bang for
00824      * the buck seems to be to check whether both inputs are in the int32
00825      * range; if so, no overflow is possible.
00826      */
00827     if (arg1 != (int64) ((int32) arg1) &&
00828         result / arg1 != arg2)
00829         ereport(ERROR,
00830                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00831                  errmsg("bigint out of range")));
00832     PG_RETURN_INT64(result);
00833 }
00834 
00835 Datum
00836 int84div(PG_FUNCTION_ARGS)
00837 {
00838     int64       arg1 = PG_GETARG_INT64(0);
00839     int32       arg2 = PG_GETARG_INT32(1);
00840     int64       result;
00841 
00842     if (arg2 == 0)
00843     {
00844         ereport(ERROR,
00845                 (errcode(ERRCODE_DIVISION_BY_ZERO),
00846                  errmsg("division by zero")));
00847         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
00848         PG_RETURN_NULL();
00849     }
00850 
00851     /*
00852      * INT64_MIN / -1 is problematic, since the result can't be represented on
00853      * a two's-complement machine.  Some machines produce INT64_MIN, some
00854      * produce zero, some throw an exception.  We can dodge the problem by
00855      * recognizing that division by -1 is the same as negation.
00856      */
00857     if (arg2 == -1)
00858     {
00859         result = -arg1;
00860         /* overflow check (needed for INT64_MIN) */
00861         if (arg1 != 0 && SAMESIGN(result, arg1))
00862             ereport(ERROR,
00863                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00864                      errmsg("bigint out of range")));
00865         PG_RETURN_INT64(result);
00866     }
00867 
00868     /* No overflow is possible */
00869 
00870     result = arg1 / arg2;
00871 
00872     PG_RETURN_INT64(result);
00873 }
00874 
00875 Datum
00876 int48pl(PG_FUNCTION_ARGS)
00877 {
00878     int32       arg1 = PG_GETARG_INT32(0);
00879     int64       arg2 = PG_GETARG_INT64(1);
00880     int64       result;
00881 
00882     result = arg1 + arg2;
00883 
00884     /*
00885      * Overflow check.  If the inputs are of different signs then their sum
00886      * cannot overflow.  If the inputs are of the same sign, their sum had
00887      * better be that sign too.
00888      */
00889     if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
00890         ereport(ERROR,
00891                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00892                  errmsg("bigint out of range")));
00893     PG_RETURN_INT64(result);
00894 }
00895 
00896 Datum
00897 int48mi(PG_FUNCTION_ARGS)
00898 {
00899     int32       arg1 = PG_GETARG_INT32(0);
00900     int64       arg2 = PG_GETARG_INT64(1);
00901     int64       result;
00902 
00903     result = arg1 - arg2;
00904 
00905     /*
00906      * Overflow check.  If the inputs are of the same sign then their
00907      * difference cannot overflow.  If they are of different signs then the
00908      * result should be of the same sign as the first input.
00909      */
00910     if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
00911         ereport(ERROR,
00912                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00913                  errmsg("bigint out of range")));
00914     PG_RETURN_INT64(result);
00915 }
00916 
00917 Datum
00918 int48mul(PG_FUNCTION_ARGS)
00919 {
00920     int32       arg1 = PG_GETARG_INT32(0);
00921     int64       arg2 = PG_GETARG_INT64(1);
00922     int64       result;
00923 
00924     result = arg1 * arg2;
00925 
00926     /*
00927      * Overflow check.  We basically check to see if result / arg2 gives arg1
00928      * again.  There is one case where this fails: arg2 = 0 (which cannot
00929      * overflow).
00930      *
00931      * Since the division is likely much more expensive than the actual
00932      * multiplication, we'd like to skip it where possible.  The best bang for
00933      * the buck seems to be to check whether both inputs are in the int32
00934      * range; if so, no overflow is possible.
00935      */
00936     if (arg2 != (int64) ((int32) arg2) &&
00937         result / arg2 != arg1)
00938         ereport(ERROR,
00939                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00940                  errmsg("bigint out of range")));
00941     PG_RETURN_INT64(result);
00942 }
00943 
00944 Datum
00945 int48div(PG_FUNCTION_ARGS)
00946 {
00947     int32       arg1 = PG_GETARG_INT32(0);
00948     int64       arg2 = PG_GETARG_INT64(1);
00949 
00950     if (arg2 == 0)
00951     {
00952         ereport(ERROR,
00953                 (errcode(ERRCODE_DIVISION_BY_ZERO),
00954                  errmsg("division by zero")));
00955         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
00956         PG_RETURN_NULL();
00957     }
00958 
00959     /* No overflow is possible */
00960     PG_RETURN_INT64((int64) arg1 / arg2);
00961 }
00962 
00963 Datum
00964 int82pl(PG_FUNCTION_ARGS)
00965 {
00966     int64       arg1 = PG_GETARG_INT64(0);
00967     int16       arg2 = PG_GETARG_INT16(1);
00968     int64       result;
00969 
00970     result = arg1 + arg2;
00971 
00972     /*
00973      * Overflow check.  If the inputs are of different signs then their sum
00974      * cannot overflow.  If the inputs are of the same sign, their sum had
00975      * better be that sign too.
00976      */
00977     if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
00978         ereport(ERROR,
00979                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
00980                  errmsg("bigint out of range")));
00981     PG_RETURN_INT64(result);
00982 }
00983 
00984 Datum
00985 int82mi(PG_FUNCTION_ARGS)
00986 {
00987     int64       arg1 = PG_GETARG_INT64(0);
00988     int16       arg2 = PG_GETARG_INT16(1);
00989     int64       result;
00990 
00991     result = arg1 - arg2;
00992 
00993     /*
00994      * Overflow check.  If the inputs are of the same sign then their
00995      * difference cannot overflow.  If they are of different signs then the
00996      * result should be of the same sign as the first input.
00997      */
00998     if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
00999         ereport(ERROR,
01000                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
01001                  errmsg("bigint out of range")));
01002     PG_RETURN_INT64(result);
01003 }
01004 
01005 Datum
01006 int82mul(PG_FUNCTION_ARGS)
01007 {
01008     int64       arg1 = PG_GETARG_INT64(0);
01009     int16       arg2 = PG_GETARG_INT16(1);
01010     int64       result;
01011 
01012     result = arg1 * arg2;
01013 
01014     /*
01015      * Overflow check.  We basically check to see if result / arg1 gives arg2
01016      * again.  There is one case where this fails: arg1 = 0 (which cannot
01017      * overflow).
01018      *
01019      * Since the division is likely much more expensive than the actual
01020      * multiplication, we'd like to skip it where possible.  The best bang for
01021      * the buck seems to be to check whether both inputs are in the int32
01022      * range; if so, no overflow is possible.
01023      */
01024     if (arg1 != (int64) ((int32) arg1) &&
01025         result / arg1 != arg2)
01026         ereport(ERROR,
01027                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
01028                  errmsg("bigint out of range")));
01029     PG_RETURN_INT64(result);
01030 }
01031 
01032 Datum
01033 int82div(PG_FUNCTION_ARGS)
01034 {
01035     int64       arg1 = PG_GETARG_INT64(0);
01036     int16       arg2 = PG_GETARG_INT16(1);
01037     int64       result;
01038 
01039     if (arg2 == 0)
01040     {
01041         ereport(ERROR,
01042                 (errcode(ERRCODE_DIVISION_BY_ZERO),
01043                  errmsg("division by zero")));
01044         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
01045         PG_RETURN_NULL();
01046     }
01047 
01048     /*
01049      * INT64_MIN / -1 is problematic, since the result can't be represented on
01050      * a two's-complement machine.  Some machines produce INT64_MIN, some
01051      * produce zero, some throw an exception.  We can dodge the problem by
01052      * recognizing that division by -1 is the same as negation.
01053      */
01054     if (arg2 == -1)
01055     {
01056         result = -arg1;
01057         /* overflow check (needed for INT64_MIN) */
01058         if (arg1 != 0 && SAMESIGN(result, arg1))
01059             ereport(ERROR,
01060                     (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
01061                      errmsg("bigint out of range")));
01062         PG_RETURN_INT64(result);
01063     }
01064 
01065     /* No overflow is possible */
01066 
01067     result = arg1 / arg2;
01068 
01069     PG_RETURN_INT64(result);
01070 }
01071 
01072 Datum
01073 int28pl(PG_FUNCTION_ARGS)
01074 {
01075     int16       arg1 = PG_GETARG_INT16(0);
01076     int64       arg2 = PG_GETARG_INT64(1);
01077     int64       result;
01078 
01079     result = arg1 + arg2;
01080 
01081     /*
01082      * Overflow check.  If the inputs are of different signs then their sum
01083      * cannot overflow.  If the inputs are of the same sign, their sum had
01084      * better be that sign too.
01085      */
01086     if (SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
01087         ereport(ERROR,
01088                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
01089                  errmsg("bigint out of range")));
01090     PG_RETURN_INT64(result);
01091 }
01092 
01093 Datum
01094 int28mi(PG_FUNCTION_ARGS)
01095 {
01096     int16       arg1 = PG_GETARG_INT16(0);
01097     int64       arg2 = PG_GETARG_INT64(1);
01098     int64       result;
01099 
01100     result = arg1 - arg2;
01101 
01102     /*
01103      * Overflow check.  If the inputs are of the same sign then their
01104      * difference cannot overflow.  If they are of different signs then the
01105      * result should be of the same sign as the first input.
01106      */
01107     if (!SAMESIGN(arg1, arg2) && !SAMESIGN(result, arg1))
01108         ereport(ERROR,
01109                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
01110                  errmsg("bigint out of range")));
01111     PG_RETURN_INT64(result);
01112 }
01113 
01114 Datum
01115 int28mul(PG_FUNCTION_ARGS)
01116 {
01117     int16       arg1 = PG_GETARG_INT16(0);
01118     int64       arg2 = PG_GETARG_INT64(1);
01119     int64       result;
01120 
01121     result = arg1 * arg2;
01122 
01123     /*
01124      * Overflow check.  We basically check to see if result / arg2 gives arg1
01125      * again.  There is one case where this fails: arg2 = 0 (which cannot
01126      * overflow).
01127      *
01128      * Since the division is likely much more expensive than the actual
01129      * multiplication, we'd like to skip it where possible.  The best bang for
01130      * the buck seems to be to check whether both inputs are in the int32
01131      * range; if so, no overflow is possible.
01132      */
01133     if (arg2 != (int64) ((int32) arg2) &&
01134         result / arg2 != arg1)
01135         ereport(ERROR,
01136                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
01137                  errmsg("bigint out of range")));
01138     PG_RETURN_INT64(result);
01139 }
01140 
01141 Datum
01142 int28div(PG_FUNCTION_ARGS)
01143 {
01144     int16       arg1 = PG_GETARG_INT16(0);
01145     int64       arg2 = PG_GETARG_INT64(1);
01146 
01147     if (arg2 == 0)
01148     {
01149         ereport(ERROR,
01150                 (errcode(ERRCODE_DIVISION_BY_ZERO),
01151                  errmsg("division by zero")));
01152         /* ensure compiler realizes we mustn't reach the division (gcc bug) */
01153         PG_RETURN_NULL();
01154     }
01155 
01156     /* No overflow is possible */
01157     PG_RETURN_INT64((int64) arg1 / arg2);
01158 }
01159 
01160 /* Binary arithmetics
01161  *
01162  *      int8and     - returns arg1 & arg2
01163  *      int8or      - returns arg1 | arg2
01164  *      int8xor     - returns arg1 # arg2
01165  *      int8not     - returns ~arg1
01166  *      int8shl     - returns arg1 << arg2
01167  *      int8shr     - returns arg1 >> arg2
01168  */
01169 
01170 Datum
01171 int8and(PG_FUNCTION_ARGS)
01172 {
01173     int64       arg1 = PG_GETARG_INT64(0);
01174     int64       arg2 = PG_GETARG_INT64(1);
01175 
01176     PG_RETURN_INT64(arg1 & arg2);
01177 }
01178 
01179 Datum
01180 int8or(PG_FUNCTION_ARGS)
01181 {
01182     int64       arg1 = PG_GETARG_INT64(0);
01183     int64       arg2 = PG_GETARG_INT64(1);
01184 
01185     PG_RETURN_INT64(arg1 | arg2);
01186 }
01187 
01188 Datum
01189 int8xor(PG_FUNCTION_ARGS)
01190 {
01191     int64       arg1 = PG_GETARG_INT64(0);
01192     int64       arg2 = PG_GETARG_INT64(1);
01193 
01194     PG_RETURN_INT64(arg1 ^ arg2);
01195 }
01196 
01197 Datum
01198 int8not(PG_FUNCTION_ARGS)
01199 {
01200     int64       arg1 = PG_GETARG_INT64(0);
01201 
01202     PG_RETURN_INT64(~arg1);
01203 }
01204 
01205 Datum
01206 int8shl(PG_FUNCTION_ARGS)
01207 {
01208     int64       arg1 = PG_GETARG_INT64(0);
01209     int32       arg2 = PG_GETARG_INT32(1);
01210 
01211     PG_RETURN_INT64(arg1 << arg2);
01212 }
01213 
01214 Datum
01215 int8shr(PG_FUNCTION_ARGS)
01216 {
01217     int64       arg1 = PG_GETARG_INT64(0);
01218     int32       arg2 = PG_GETARG_INT32(1);
01219 
01220     PG_RETURN_INT64(arg1 >> arg2);
01221 }
01222 
01223 /*----------------------------------------------------------
01224  *  Conversion operators.
01225  *---------------------------------------------------------*/
01226 
01227 Datum
01228 int48(PG_FUNCTION_ARGS)
01229 {
01230     int32       arg = PG_GETARG_INT32(0);
01231 
01232     PG_RETURN_INT64((int64) arg);
01233 }
01234 
01235 Datum
01236 int84(PG_FUNCTION_ARGS)
01237 {
01238     int64       arg = PG_GETARG_INT64(0);
01239     int32       result;
01240 
01241     result = (int32) arg;
01242 
01243     /* Test for overflow by reverse-conversion. */
01244     if ((int64) result != arg)
01245         ereport(ERROR,
01246                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
01247                  errmsg("integer out of range")));
01248 
01249     PG_RETURN_INT32(result);
01250 }
01251 
01252 Datum
01253 int28(PG_FUNCTION_ARGS)
01254 {
01255     int16       arg = PG_GETARG_INT16(0);
01256 
01257     PG_RETURN_INT64((int64) arg);
01258 }
01259 
01260 Datum
01261 int82(PG_FUNCTION_ARGS)
01262 {
01263     int64       arg = PG_GETARG_INT64(0);
01264     int16       result;
01265 
01266     result = (int16) arg;
01267 
01268     /* Test for overflow by reverse-conversion. */
01269     if ((int64) result != arg)
01270         ereport(ERROR,
01271                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
01272                  errmsg("smallint out of range")));
01273 
01274     PG_RETURN_INT16(result);
01275 }
01276 
01277 Datum
01278 i8tod(PG_FUNCTION_ARGS)
01279 {
01280     int64       arg = PG_GETARG_INT64(0);
01281     float8      result;
01282 
01283     result = arg;
01284 
01285     PG_RETURN_FLOAT8(result);
01286 }
01287 
01288 /* dtoi8()
01289  * Convert float8 to 8-byte integer.
01290  */
01291 Datum
01292 dtoi8(PG_FUNCTION_ARGS)
01293 {
01294     float8      arg = PG_GETARG_FLOAT8(0);
01295     int64       result;
01296 
01297     /* Round arg to nearest integer (but it's still in float form) */
01298     arg = rint(arg);
01299 
01300     /*
01301      * Does it fit in an int64?  Avoid assuming that we have handy constants
01302      * defined for the range boundaries, instead test for overflow by
01303      * reverse-conversion.
01304      */
01305     result = (int64) arg;
01306 
01307     if ((float8) result != arg)
01308         ereport(ERROR,
01309                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
01310                  errmsg("bigint out of range")));
01311 
01312     PG_RETURN_INT64(result);
01313 }
01314 
01315 Datum
01316 i8tof(PG_FUNCTION_ARGS)
01317 {
01318     int64       arg = PG_GETARG_INT64(0);
01319     float4      result;
01320 
01321     result = arg;
01322 
01323     PG_RETURN_FLOAT4(result);
01324 }
01325 
01326 /* ftoi8()
01327  * Convert float4 to 8-byte integer.
01328  */
01329 Datum
01330 ftoi8(PG_FUNCTION_ARGS)
01331 {
01332     float4      arg = PG_GETARG_FLOAT4(0);
01333     int64       result;
01334     float8      darg;
01335 
01336     /* Round arg to nearest integer (but it's still in float form) */
01337     darg = rint(arg);
01338 
01339     /*
01340      * Does it fit in an int64?  Avoid assuming that we have handy constants
01341      * defined for the range boundaries, instead test for overflow by
01342      * reverse-conversion.
01343      */
01344     result = (int64) darg;
01345 
01346     if ((float8) result != darg)
01347         ereport(ERROR,
01348                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
01349                  errmsg("bigint out of range")));
01350 
01351     PG_RETURN_INT64(result);
01352 }
01353 
01354 Datum
01355 i8tooid(PG_FUNCTION_ARGS)
01356 {
01357     int64       arg = PG_GETARG_INT64(0);
01358     Oid         result;
01359 
01360     result = (Oid) arg;
01361 
01362     /* Test for overflow by reverse-conversion. */
01363     if ((int64) result != arg)
01364         ereport(ERROR,
01365                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
01366                  errmsg("OID out of range")));
01367 
01368     PG_RETURN_OID(result);
01369 }
01370 
01371 Datum
01372 oidtoi8(PG_FUNCTION_ARGS)
01373 {
01374     Oid         arg = PG_GETARG_OID(0);
01375 
01376     PG_RETURN_INT64((int64) arg);
01377 }
01378 
01379 /*
01380  * non-persistent numeric series generator
01381  */
01382 Datum
01383 generate_series_int8(PG_FUNCTION_ARGS)
01384 {
01385     return generate_series_step_int8(fcinfo);
01386 }
01387 
01388 Datum
01389 generate_series_step_int8(PG_FUNCTION_ARGS)
01390 {
01391     FuncCallContext *funcctx;
01392     generate_series_fctx *fctx;
01393     int64       result;
01394     MemoryContext oldcontext;
01395 
01396     /* stuff done only on the first call of the function */
01397     if (SRF_IS_FIRSTCALL())
01398     {
01399         int64       start = PG_GETARG_INT64(0);
01400         int64       finish = PG_GETARG_INT64(1);
01401         int64       step = 1;
01402 
01403         /* see if we were given an explicit step size */
01404         if (PG_NARGS() == 3)
01405             step = PG_GETARG_INT64(2);
01406         if (step == 0)
01407             ereport(ERROR,
01408                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
01409                      errmsg("step size cannot equal zero")));
01410 
01411         /* create a function context for cross-call persistence */
01412         funcctx = SRF_FIRSTCALL_INIT();
01413 
01414         /*
01415          * switch to memory context appropriate for multiple function calls
01416          */
01417         oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
01418 
01419         /* allocate memory for user context */
01420         fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx));
01421 
01422         /*
01423          * Use fctx to keep state from call to call. Seed current with the
01424          * original start value
01425          */
01426         fctx->current = start;
01427         fctx->finish = finish;
01428         fctx->step = step;
01429 
01430         funcctx->user_fctx = fctx;
01431         MemoryContextSwitchTo(oldcontext);
01432     }
01433 
01434     /* stuff done on every call of the function */
01435     funcctx = SRF_PERCALL_SETUP();
01436 
01437     /*
01438      * get the saved state and use current as the result for this iteration
01439      */
01440     fctx = funcctx->user_fctx;
01441     result = fctx->current;
01442 
01443     if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
01444         (fctx->step < 0 && fctx->current >= fctx->finish))
01445     {
01446         /* increment current in preparation for next iteration */
01447         fctx->current += fctx->step;
01448 
01449         /* if next-value computation overflows, this is the final result */
01450         if (SAMESIGN(result, fctx->step) && !SAMESIGN(result, fctx->current))
01451             fctx->step = 0;
01452 
01453         /* do when there is more left to send */
01454         SRF_RETURN_NEXT(funcctx, Int64GetDatum(result));
01455     }
01456     else
01457         /* do when there is no more left */
01458         SRF_RETURN_DONE(funcctx);
01459 }