1 /*------------------------------------------------------------------------- 2 * 3 * int8.c 4 * Internal 64-bit integer operations 5 * 6 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group 7 * Portions Copyright (c) 1994, Regents of the University of California 8 * 9 * IDENTIFICATION 10 * src/backend/utils/adt/int8.c 11 * 12 *------------------------------------------------------------------------- 13 */ 14 #include "postgres.h" 15 16 #include <ctype.h> 17 #include <limits.h> 18 #include <math.h> 19 20 #include "common/int.h" 21 #include "funcapi.h" 22 #include "libpq/pqformat.h" 23 #include "nodes/nodeFuncs.h" 24 #include "nodes/supportnodes.h" 25 #include "optimizer/optimizer.h" 26 #include "utils/int8.h" 27 #include "utils/builtins.h" 28 29 30 #define MAXINT8LEN 25 31 32 typedef struct 33 { 34 int64 current; 35 int64 finish; 36 int64 step; 37 } generate_series_fctx; 38 39 40 /*********************************************************************** 41 ** 42 ** Routines for 64-bit integers. 43 ** 44 ***********************************************************************/ 45 46 /*---------------------------------------------------------- 47 * Formatting and conversion routines. 48 *---------------------------------------------------------*/ 49 50 /* 51 * scanint8 --- try to parse a string into an int8. 52 * 53 * If errorOK is false, ereport a useful error message if the string is bad. 54 * If errorOK is true, just return "false" for bad input. 55 */ 56 bool 57 scanint8(const char *str, bool errorOK, int64 *result) 58 { 59 const char *ptr = str; 60 int64 tmp = 0; 61 bool neg = false; 62 63 /* 64 * Do our own scan, rather than relying on sscanf which might be broken 65 * for long long. 66 * 67 * As INT64_MIN can't be stored as a positive 64 bit integer, accumulate 68 * value as a negative number. 69 */ 70 71 /* skip leading spaces */ 72 while (*ptr && isspace((unsigned char) *ptr)) 73 ptr++; 74 75 /* handle sign */ 76 if (*ptr == '-') 77 { 78 ptr++; 79 neg = true; 80 } 81 else if (*ptr == '+') 82 ptr++; 83 84 /* require at least one digit */ 85 if (unlikely(!isdigit((unsigned char) *ptr))) 86 goto invalid_syntax; 87 88 /* process digits */ 89 while (*ptr && isdigit((unsigned char) *ptr)) 90 { 91 int8 digit = (*ptr++ - '0'); 92 93 if (unlikely(pg_mul_s64_overflow(tmp, 10, &tmp)) || 94 unlikely(pg_sub_s64_overflow(tmp, digit, &tmp))) 95 goto out_of_range; 96 } 97 98 /* allow trailing whitespace, but not other trailing chars */ 99 while (*ptr != '\0' && isspace((unsigned char) *ptr)) 100 ptr++; 101 102 if (unlikely(*ptr != '\0')) 103 goto invalid_syntax; 104 105 if (!neg) 106 { 107 /* could fail if input is most negative number */ 108 if (unlikely(tmp == PG_INT64_MIN)) 109 goto out_of_range; 110 tmp = -tmp; 111 } 112 113 *result = tmp; 114 return true; 115 116 out_of_range: 117 if (!errorOK) 118 ereport(ERROR, 119 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 120 errmsg("value \"%s\" is out of range for type %s", 121 str, "bigint"))); 122 return false; 123 124 invalid_syntax: 125 if (!errorOK) 126 ereport(ERROR, 127 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 128 errmsg("invalid input syntax for type %s: \"%s\"", 129 "bigint", str))); 130 return false; 131 } 132 133 /* int8in() 134 */ 135 Datum 136 int8in(PG_FUNCTION_ARGS) 137 { 138 char *str = PG_GETARG_CSTRING(0); 139 int64 result; 140 141 (void) scanint8(str, false, &result); 142 PG_RETURN_INT64(result); 143 } 144 145 146 /* int8out() 147 */ 148 Datum 149 int8out(PG_FUNCTION_ARGS) 150 { 151 int64 val = PG_GETARG_INT64(0); 152 char buf[MAXINT8LEN + 1]; 153 char *result; 154 155 pg_lltoa(val, buf); 156 result = pstrdup(buf); 157 PG_RETURN_CSTRING(result); 158 } 159 160 /* 161 * int8recv - converts external binary format to int8 162 */ 163 Datum 164 int8recv(PG_FUNCTION_ARGS) 165 { 166 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); 167 168 PG_RETURN_INT64(pq_getmsgint64(buf)); 169 } 170 171 /* 172 * int8send - converts int8 to binary format 173 */ 174 Datum 175 int8send(PG_FUNCTION_ARGS) 176 { 177 int64 arg1 = PG_GETARG_INT64(0); 178 StringInfoData buf; 179 180 pq_begintypsend(&buf); 181 pq_sendint64(&buf, arg1); 182 PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); 183 } 184 185 186 /*---------------------------------------------------------- 187 * Relational operators for int8s, including cross-data-type comparisons. 188 *---------------------------------------------------------*/ 189 190 /* int8relop() 191 * Is val1 relop val2? 192 */ 193 Datum 194 int8eq(PG_FUNCTION_ARGS) 195 { 196 int64 val1 = PG_GETARG_INT64(0); 197 int64 val2 = PG_GETARG_INT64(1); 198 199 PG_RETURN_BOOL(val1 == val2); 200 } 201 202 Datum 203 int8ne(PG_FUNCTION_ARGS) 204 { 205 int64 val1 = PG_GETARG_INT64(0); 206 int64 val2 = PG_GETARG_INT64(1); 207 208 PG_RETURN_BOOL(val1 != val2); 209 } 210 211 Datum 212 int8lt(PG_FUNCTION_ARGS) 213 { 214 int64 val1 = PG_GETARG_INT64(0); 215 int64 val2 = PG_GETARG_INT64(1); 216 217 PG_RETURN_BOOL(val1 < val2); 218 } 219 220 Datum 221 int8gt(PG_FUNCTION_ARGS) 222 { 223 int64 val1 = PG_GETARG_INT64(0); 224 int64 val2 = PG_GETARG_INT64(1); 225 226 PG_RETURN_BOOL(val1 > val2); 227 } 228 229 Datum 230 int8le(PG_FUNCTION_ARGS) 231 { 232 int64 val1 = PG_GETARG_INT64(0); 233 int64 val2 = PG_GETARG_INT64(1); 234 235 PG_RETURN_BOOL(val1 <= val2); 236 } 237 238 Datum 239 int8ge(PG_FUNCTION_ARGS) 240 { 241 int64 val1 = PG_GETARG_INT64(0); 242 int64 val2 = PG_GETARG_INT64(1); 243 244 PG_RETURN_BOOL(val1 >= val2); 245 } 246 247 /* int84relop() 248 * Is 64-bit val1 relop 32-bit val2? 249 */ 250 Datum 251 int84eq(PG_FUNCTION_ARGS) 252 { 253 int64 val1 = PG_GETARG_INT64(0); 254 int32 val2 = PG_GETARG_INT32(1); 255 256 PG_RETURN_BOOL(val1 == val2); 257 } 258 259 Datum 260 int84ne(PG_FUNCTION_ARGS) 261 { 262 int64 val1 = PG_GETARG_INT64(0); 263 int32 val2 = PG_GETARG_INT32(1); 264 265 PG_RETURN_BOOL(val1 != val2); 266 } 267 268 Datum 269 int84lt(PG_FUNCTION_ARGS) 270 { 271 int64 val1 = PG_GETARG_INT64(0); 272 int32 val2 = PG_GETARG_INT32(1); 273 274 PG_RETURN_BOOL(val1 < val2); 275 } 276 277 Datum 278 int84gt(PG_FUNCTION_ARGS) 279 { 280 int64 val1 = PG_GETARG_INT64(0); 281 int32 val2 = PG_GETARG_INT32(1); 282 283 PG_RETURN_BOOL(val1 > val2); 284 } 285 286 Datum 287 int84le(PG_FUNCTION_ARGS) 288 { 289 int64 val1 = PG_GETARG_INT64(0); 290 int32 val2 = PG_GETARG_INT32(1); 291 292 PG_RETURN_BOOL(val1 <= val2); 293 } 294 295 Datum 296 int84ge(PG_FUNCTION_ARGS) 297 { 298 int64 val1 = PG_GETARG_INT64(0); 299 int32 val2 = PG_GETARG_INT32(1); 300 301 PG_RETURN_BOOL(val1 >= val2); 302 } 303 304 /* int48relop() 305 * Is 32-bit val1 relop 64-bit val2? 306 */ 307 Datum 308 int48eq(PG_FUNCTION_ARGS) 309 { 310 int32 val1 = PG_GETARG_INT32(0); 311 int64 val2 = PG_GETARG_INT64(1); 312 313 PG_RETURN_BOOL(val1 == val2); 314 } 315 316 Datum 317 int48ne(PG_FUNCTION_ARGS) 318 { 319 int32 val1 = PG_GETARG_INT32(0); 320 int64 val2 = PG_GETARG_INT64(1); 321 322 PG_RETURN_BOOL(val1 != val2); 323 } 324 325 Datum 326 int48lt(PG_FUNCTION_ARGS) 327 { 328 int32 val1 = PG_GETARG_INT32(0); 329 int64 val2 = PG_GETARG_INT64(1); 330 331 PG_RETURN_BOOL(val1 < val2); 332 } 333 334 Datum 335 int48gt(PG_FUNCTION_ARGS) 336 { 337 int32 val1 = PG_GETARG_INT32(0); 338 int64 val2 = PG_GETARG_INT64(1); 339 340 PG_RETURN_BOOL(val1 > val2); 341 } 342 343 Datum 344 int48le(PG_FUNCTION_ARGS) 345 { 346 int32 val1 = PG_GETARG_INT32(0); 347 int64 val2 = PG_GETARG_INT64(1); 348 349 PG_RETURN_BOOL(val1 <= val2); 350 } 351 352 Datum 353 int48ge(PG_FUNCTION_ARGS) 354 { 355 int32 val1 = PG_GETARG_INT32(0); 356 int64 val2 = PG_GETARG_INT64(1); 357 358 PG_RETURN_BOOL(val1 >= val2); 359 } 360 361 /* int82relop() 362 * Is 64-bit val1 relop 16-bit val2? 363 */ 364 Datum 365 int82eq(PG_FUNCTION_ARGS) 366 { 367 int64 val1 = PG_GETARG_INT64(0); 368 int16 val2 = PG_GETARG_INT16(1); 369 370 PG_RETURN_BOOL(val1 == val2); 371 } 372 373 Datum 374 int82ne(PG_FUNCTION_ARGS) 375 { 376 int64 val1 = PG_GETARG_INT64(0); 377 int16 val2 = PG_GETARG_INT16(1); 378 379 PG_RETURN_BOOL(val1 != val2); 380 } 381 382 Datum 383 int82lt(PG_FUNCTION_ARGS) 384 { 385 int64 val1 = PG_GETARG_INT64(0); 386 int16 val2 = PG_GETARG_INT16(1); 387 388 PG_RETURN_BOOL(val1 < val2); 389 } 390 391 Datum 392 int82gt(PG_FUNCTION_ARGS) 393 { 394 int64 val1 = PG_GETARG_INT64(0); 395 int16 val2 = PG_GETARG_INT16(1); 396 397 PG_RETURN_BOOL(val1 > val2); 398 } 399 400 Datum 401 int82le(PG_FUNCTION_ARGS) 402 { 403 int64 val1 = PG_GETARG_INT64(0); 404 int16 val2 = PG_GETARG_INT16(1); 405 406 PG_RETURN_BOOL(val1 <= val2); 407 } 408 409 Datum 410 int82ge(PG_FUNCTION_ARGS) 411 { 412 int64 val1 = PG_GETARG_INT64(0); 413 int16 val2 = PG_GETARG_INT16(1); 414 415 PG_RETURN_BOOL(val1 >= val2); 416 } 417 418 /* int28relop() 419 * Is 16-bit val1 relop 64-bit val2? 420 */ 421 Datum 422 int28eq(PG_FUNCTION_ARGS) 423 { 424 int16 val1 = PG_GETARG_INT16(0); 425 int64 val2 = PG_GETARG_INT64(1); 426 427 PG_RETURN_BOOL(val1 == val2); 428 } 429 430 Datum 431 int28ne(PG_FUNCTION_ARGS) 432 { 433 int16 val1 = PG_GETARG_INT16(0); 434 int64 val2 = PG_GETARG_INT64(1); 435 436 PG_RETURN_BOOL(val1 != val2); 437 } 438 439 Datum 440 int28lt(PG_FUNCTION_ARGS) 441 { 442 int16 val1 = PG_GETARG_INT16(0); 443 int64 val2 = PG_GETARG_INT64(1); 444 445 PG_RETURN_BOOL(val1 < val2); 446 } 447 448 Datum 449 int28gt(PG_FUNCTION_ARGS) 450 { 451 int16 val1 = PG_GETARG_INT16(0); 452 int64 val2 = PG_GETARG_INT64(1); 453 454 PG_RETURN_BOOL(val1 > val2); 455 } 456 457 Datum 458 int28le(PG_FUNCTION_ARGS) 459 { 460 int16 val1 = PG_GETARG_INT16(0); 461 int64 val2 = PG_GETARG_INT64(1); 462 463 PG_RETURN_BOOL(val1 <= val2); 464 } 465 466 Datum 467 int28ge(PG_FUNCTION_ARGS) 468 { 469 int16 val1 = PG_GETARG_INT16(0); 470 int64 val2 = PG_GETARG_INT64(1); 471 472 PG_RETURN_BOOL(val1 >= val2); 473 } 474 475 /* 476 * in_range support function for int8. 477 * 478 * Note: we needn't supply int8_int4 or int8_int2 variants, as implicit 479 * coercion of the offset value takes care of those scenarios just as well. 480 */ 481 Datum 482 in_range_int8_int8(PG_FUNCTION_ARGS) 483 { 484 int64 val = PG_GETARG_INT64(0); 485 int64 base = PG_GETARG_INT64(1); 486 int64 offset = PG_GETARG_INT64(2); 487 bool sub = PG_GETARG_BOOL(3); 488 bool less = PG_GETARG_BOOL(4); 489 int64 sum; 490 491 if (offset < 0) 492 ereport(ERROR, 493 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), 494 errmsg("invalid preceding or following size in window function"))); 495 496 if (sub) 497 offset = -offset; /* cannot overflow */ 498 499 if (unlikely(pg_add_s64_overflow(base, offset, &sum))) 500 { 501 /* 502 * If sub is false, the true sum is surely more than val, so correct 503 * answer is the same as "less". If sub is true, the true sum is 504 * surely less than val, so the answer is "!less". 505 */ 506 PG_RETURN_BOOL(sub ? !less : less); 507 } 508 509 if (less) 510 PG_RETURN_BOOL(val <= sum); 511 else 512 PG_RETURN_BOOL(val >= sum); 513 } 514 515 516 /*---------------------------------------------------------- 517 * Arithmetic operators on 64-bit integers. 518 *---------------------------------------------------------*/ 519 520 Datum 521 int8um(PG_FUNCTION_ARGS) 522 { 523 int64 arg = PG_GETARG_INT64(0); 524 int64 result; 525 526 if (unlikely(arg == PG_INT64_MIN)) 527 ereport(ERROR, 528 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 529 errmsg("bigint out of range"))); 530 result = -arg; 531 PG_RETURN_INT64(result); 532 } 533 534 Datum 535 int8up(PG_FUNCTION_ARGS) 536 { 537 int64 arg = PG_GETARG_INT64(0); 538 539 PG_RETURN_INT64(arg); 540 } 541 542 Datum 543 int8pl(PG_FUNCTION_ARGS) 544 { 545 int64 arg1 = PG_GETARG_INT64(0); 546 int64 arg2 = PG_GETARG_INT64(1); 547 int64 result; 548 549 if (unlikely(pg_add_s64_overflow(arg1, arg2, &result))) 550 ereport(ERROR, 551 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 552 errmsg("bigint out of range"))); 553 PG_RETURN_INT64(result); 554 } 555 556 Datum 557 int8mi(PG_FUNCTION_ARGS) 558 { 559 int64 arg1 = PG_GETARG_INT64(0); 560 int64 arg2 = PG_GETARG_INT64(1); 561 int64 result; 562 563 if (unlikely(pg_sub_s64_overflow(arg1, arg2, &result))) 564 ereport(ERROR, 565 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 566 errmsg("bigint out of range"))); 567 PG_RETURN_INT64(result); 568 } 569 570 Datum 571 int8mul(PG_FUNCTION_ARGS) 572 { 573 int64 arg1 = PG_GETARG_INT64(0); 574 int64 arg2 = PG_GETARG_INT64(1); 575 int64 result; 576 577 if (unlikely(pg_mul_s64_overflow(arg1, arg2, &result))) 578 ereport(ERROR, 579 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 580 errmsg("bigint out of range"))); 581 PG_RETURN_INT64(result); 582 } 583 584 Datum 585 int8div(PG_FUNCTION_ARGS) 586 { 587 int64 arg1 = PG_GETARG_INT64(0); 588 int64 arg2 = PG_GETARG_INT64(1); 589 int64 result; 590 591 if (arg2 == 0) 592 { 593 ereport(ERROR, 594 (errcode(ERRCODE_DIVISION_BY_ZERO), 595 errmsg("division by zero"))); 596 /* ensure compiler realizes we mustn't reach the division (gcc bug) */ 597 PG_RETURN_NULL(); 598 } 599 600 /* 601 * INT64_MIN / -1 is problematic, since the result can't be represented on 602 * a two's-complement machine. Some machines produce INT64_MIN, some 603 * produce zero, some throw an exception. We can dodge the problem by 604 * recognizing that division by -1 is the same as negation. 605 */ 606 if (arg2 == -1) 607 { 608 if (unlikely(arg1 == PG_INT64_MIN)) 609 ereport(ERROR, 610 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 611 errmsg("bigint out of range"))); 612 result = -arg1; 613 PG_RETURN_INT64(result); 614 } 615 616 /* No overflow is possible */ 617 618 result = arg1 / arg2; 619 620 PG_RETURN_INT64(result); 621 } 622 623 /* int8abs() 624 * Absolute value 625 */ 626 Datum 627 int8abs(PG_FUNCTION_ARGS) 628 { 629 int64 arg1 = PG_GETARG_INT64(0); 630 int64 result; 631 632 if (unlikely(arg1 == PG_INT64_MIN)) 633 ereport(ERROR, 634 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 635 errmsg("bigint out of range"))); 636 result = (arg1 < 0) ? -arg1 : arg1; 637 PG_RETURN_INT64(result); 638 } 639 640 /* int8mod() 641 * Modulo operation. 642 */ 643 Datum 644 int8mod(PG_FUNCTION_ARGS) 645 { 646 int64 arg1 = PG_GETARG_INT64(0); 647 int64 arg2 = PG_GETARG_INT64(1); 648 649 if (unlikely(arg2 == 0)) 650 { 651 ereport(ERROR, 652 (errcode(ERRCODE_DIVISION_BY_ZERO), 653 errmsg("division by zero"))); 654 /* ensure compiler realizes we mustn't reach the division (gcc bug) */ 655 PG_RETURN_NULL(); 656 } 657 658 /* 659 * Some machines throw a floating-point exception for INT64_MIN % -1, 660 * which is a bit silly since the correct answer is perfectly 661 * well-defined, namely zero. 662 */ 663 if (arg2 == -1) 664 PG_RETURN_INT64(0); 665 666 /* No overflow is possible */ 667 668 PG_RETURN_INT64(arg1 % arg2); 669 } 670 671 672 Datum 673 int8inc(PG_FUNCTION_ARGS) 674 { 675 /* 676 * When int8 is pass-by-reference, we provide this special case to avoid 677 * palloc overhead for COUNT(): when called as an aggregate, we know that 678 * the argument is modifiable local storage, so just update it in-place. 679 * (If int8 is pass-by-value, then of course this is useless as well as 680 * incorrect, so just ifdef it out.) 681 */ 682 #ifndef USE_FLOAT8_BYVAL /* controls int8 too */ 683 if (AggCheckCallContext(fcinfo, NULL)) 684 { 685 int64 *arg = (int64 *) PG_GETARG_POINTER(0); 686 687 if (unlikely(pg_add_s64_overflow(*arg, 1, arg))) 688 ereport(ERROR, 689 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 690 errmsg("bigint out of range"))); 691 692 PG_RETURN_POINTER(arg); 693 } 694 else 695 #endif 696 { 697 /* Not called as an aggregate, so just do it the dumb way */ 698 int64 arg = PG_GETARG_INT64(0); 699 int64 result; 700 701 if (unlikely(pg_add_s64_overflow(arg, 1, &result))) 702 ereport(ERROR, 703 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 704 errmsg("bigint out of range"))); 705 706 PG_RETURN_INT64(result); 707 } 708 } 709 710 Datum 711 int8dec(PG_FUNCTION_ARGS) 712 { 713 /* 714 * When int8 is pass-by-reference, we provide this special case to avoid 715 * palloc overhead for COUNT(): when called as an aggregate, we know that 716 * the argument is modifiable local storage, so just update it in-place. 717 * (If int8 is pass-by-value, then of course this is useless as well as 718 * incorrect, so just ifdef it out.) 719 */ 720 #ifndef USE_FLOAT8_BYVAL /* controls int8 too */ 721 if (AggCheckCallContext(fcinfo, NULL)) 722 { 723 int64 *arg = (int64 *) PG_GETARG_POINTER(0); 724 725 if (unlikely(pg_sub_s64_overflow(*arg, 1, arg))) 726 ereport(ERROR, 727 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 728 errmsg("bigint out of range"))); 729 PG_RETURN_POINTER(arg); 730 } 731 else 732 #endif 733 { 734 /* Not called as an aggregate, so just do it the dumb way */ 735 int64 arg = PG_GETARG_INT64(0); 736 int64 result; 737 738 if (unlikely(pg_sub_s64_overflow(arg, 1, &result))) 739 ereport(ERROR, 740 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 741 errmsg("bigint out of range"))); 742 743 PG_RETURN_INT64(result); 744 } 745 } 746 747 748 /* 749 * These functions are exactly like int8inc/int8dec but are used for 750 * aggregates that count only non-null values. Since the functions are 751 * declared strict, the null checks happen before we ever get here, and all we 752 * need do is increment the state value. We could actually make these pg_proc 753 * entries point right at int8inc/int8dec, but then the opr_sanity regression 754 * test would complain about mismatched entries for a built-in function. 755 */ 756 757 Datum 758 int8inc_any(PG_FUNCTION_ARGS) 759 { 760 return int8inc(fcinfo); 761 } 762 763 Datum 764 int8inc_float8_float8(PG_FUNCTION_ARGS) 765 { 766 return int8inc(fcinfo); 767 } 768 769 Datum 770 int8dec_any(PG_FUNCTION_ARGS) 771 { 772 return int8dec(fcinfo); 773 } 774 775 776 Datum 777 int8larger(PG_FUNCTION_ARGS) 778 { 779 int64 arg1 = PG_GETARG_INT64(0); 780 int64 arg2 = PG_GETARG_INT64(1); 781 int64 result; 782 783 result = ((arg1 > arg2) ? arg1 : arg2); 784 785 PG_RETURN_INT64(result); 786 } 787 788 Datum 789 int8smaller(PG_FUNCTION_ARGS) 790 { 791 int64 arg1 = PG_GETARG_INT64(0); 792 int64 arg2 = PG_GETARG_INT64(1); 793 int64 result; 794 795 result = ((arg1 < arg2) ? arg1 : arg2); 796 797 PG_RETURN_INT64(result); 798 } 799 800 Datum 801 int84pl(PG_FUNCTION_ARGS) 802 { 803 int64 arg1 = PG_GETARG_INT64(0); 804 int32 arg2 = PG_GETARG_INT32(1); 805 int64 result; 806 807 if (unlikely(pg_add_s64_overflow(arg1, (int64) arg2, &result))) 808 ereport(ERROR, 809 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 810 errmsg("bigint out of range"))); 811 PG_RETURN_INT64(result); 812 } 813 814 Datum 815 int84mi(PG_FUNCTION_ARGS) 816 { 817 int64 arg1 = PG_GETARG_INT64(0); 818 int32 arg2 = PG_GETARG_INT32(1); 819 int64 result; 820 821 if (unlikely(pg_sub_s64_overflow(arg1, (int64) arg2, &result))) 822 ereport(ERROR, 823 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 824 errmsg("bigint out of range"))); 825 PG_RETURN_INT64(result); 826 } 827 828 Datum 829 int84mul(PG_FUNCTION_ARGS) 830 { 831 int64 arg1 = PG_GETARG_INT64(0); 832 int32 arg2 = PG_GETARG_INT32(1); 833 int64 result; 834 835 if (unlikely(pg_mul_s64_overflow(arg1, (int64) arg2, &result))) 836 ereport(ERROR, 837 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 838 errmsg("bigint out of range"))); 839 PG_RETURN_INT64(result); 840 } 841 842 Datum 843 int84div(PG_FUNCTION_ARGS) 844 { 845 int64 arg1 = PG_GETARG_INT64(0); 846 int32 arg2 = PG_GETARG_INT32(1); 847 int64 result; 848 849 if (arg2 == 0) 850 { 851 ereport(ERROR, 852 (errcode(ERRCODE_DIVISION_BY_ZERO), 853 errmsg("division by zero"))); 854 /* ensure compiler realizes we mustn't reach the division (gcc bug) */ 855 PG_RETURN_NULL(); 856 } 857 858 /* 859 * INT64_MIN / -1 is problematic, since the result can't be represented on 860 * a two's-complement machine. Some machines produce INT64_MIN, some 861 * produce zero, some throw an exception. We can dodge the problem by 862 * recognizing that division by -1 is the same as negation. 863 */ 864 if (arg2 == -1) 865 { 866 if (unlikely(arg1 == PG_INT64_MIN)) 867 ereport(ERROR, 868 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 869 errmsg("bigint out of range"))); 870 result = -arg1; 871 PG_RETURN_INT64(result); 872 } 873 874 /* No overflow is possible */ 875 876 result = arg1 / arg2; 877 878 PG_RETURN_INT64(result); 879 } 880 881 Datum 882 int48pl(PG_FUNCTION_ARGS) 883 { 884 int32 arg1 = PG_GETARG_INT32(0); 885 int64 arg2 = PG_GETARG_INT64(1); 886 int64 result; 887 888 if (unlikely(pg_add_s64_overflow((int64) arg1, arg2, &result))) 889 ereport(ERROR, 890 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 891 errmsg("bigint out of range"))); 892 PG_RETURN_INT64(result); 893 } 894 895 Datum 896 int48mi(PG_FUNCTION_ARGS) 897 { 898 int32 arg1 = PG_GETARG_INT32(0); 899 int64 arg2 = PG_GETARG_INT64(1); 900 int64 result; 901 902 if (unlikely(pg_sub_s64_overflow((int64) arg1, arg2, &result))) 903 ereport(ERROR, 904 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 905 errmsg("bigint out of range"))); 906 PG_RETURN_INT64(result); 907 } 908 909 Datum 910 int48mul(PG_FUNCTION_ARGS) 911 { 912 int32 arg1 = PG_GETARG_INT32(0); 913 int64 arg2 = PG_GETARG_INT64(1); 914 int64 result; 915 916 if (unlikely(pg_mul_s64_overflow((int64) arg1, arg2, &result))) 917 ereport(ERROR, 918 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 919 errmsg("bigint out of range"))); 920 PG_RETURN_INT64(result); 921 } 922 923 Datum 924 int48div(PG_FUNCTION_ARGS) 925 { 926 int32 arg1 = PG_GETARG_INT32(0); 927 int64 arg2 = PG_GETARG_INT64(1); 928 929 if (unlikely(arg2 == 0)) 930 { 931 ereport(ERROR, 932 (errcode(ERRCODE_DIVISION_BY_ZERO), 933 errmsg("division by zero"))); 934 /* ensure compiler realizes we mustn't reach the division (gcc bug) */ 935 PG_RETURN_NULL(); 936 } 937 938 /* No overflow is possible */ 939 PG_RETURN_INT64((int64) arg1 / arg2); 940 } 941 942 Datum 943 int82pl(PG_FUNCTION_ARGS) 944 { 945 int64 arg1 = PG_GETARG_INT64(0); 946 int16 arg2 = PG_GETARG_INT16(1); 947 int64 result; 948 949 if (unlikely(pg_add_s64_overflow(arg1, (int64) arg2, &result))) 950 ereport(ERROR, 951 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 952 errmsg("bigint out of range"))); 953 PG_RETURN_INT64(result); 954 } 955 956 Datum 957 int82mi(PG_FUNCTION_ARGS) 958 { 959 int64 arg1 = PG_GETARG_INT64(0); 960 int16 arg2 = PG_GETARG_INT16(1); 961 int64 result; 962 963 if (unlikely(pg_sub_s64_overflow(arg1, (int64) arg2, &result))) 964 ereport(ERROR, 965 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 966 errmsg("bigint out of range"))); 967 PG_RETURN_INT64(result); 968 } 969 970 Datum 971 int82mul(PG_FUNCTION_ARGS) 972 { 973 int64 arg1 = PG_GETARG_INT64(0); 974 int16 arg2 = PG_GETARG_INT16(1); 975 int64 result; 976 977 if (unlikely(pg_mul_s64_overflow(arg1, (int64) arg2, &result))) 978 ereport(ERROR, 979 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 980 errmsg("bigint out of range"))); 981 PG_RETURN_INT64(result); 982 } 983 984 Datum 985 int82div(PG_FUNCTION_ARGS) 986 { 987 int64 arg1 = PG_GETARG_INT64(0); 988 int16 arg2 = PG_GETARG_INT16(1); 989 int64 result; 990 991 if (unlikely(arg2 == 0)) 992 { 993 ereport(ERROR, 994 (errcode(ERRCODE_DIVISION_BY_ZERO), 995 errmsg("division by zero"))); 996 /* ensure compiler realizes we mustn't reach the division (gcc bug) */ 997 PG_RETURN_NULL(); 998 } 999 1000 /* 1001 * INT64_MIN / -1 is problematic, since the result can't be represented on 1002 * a two's-complement machine. Some machines produce INT64_MIN, some 1003 * produce zero, some throw an exception. We can dodge the problem by 1004 * recognizing that division by -1 is the same as negation. 1005 */ 1006 if (arg2 == -1) 1007 { 1008 if (unlikely(arg1 == PG_INT64_MIN)) 1009 ereport(ERROR, 1010 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 1011 errmsg("bigint out of range"))); 1012 result = -arg1; 1013 PG_RETURN_INT64(result); 1014 } 1015 1016 /* No overflow is possible */ 1017 1018 result = arg1 / arg2; 1019 1020 PG_RETURN_INT64(result); 1021 } 1022 1023 Datum 1024 int28pl(PG_FUNCTION_ARGS) 1025 { 1026 int16 arg1 = PG_GETARG_INT16(0); 1027 int64 arg2 = PG_GETARG_INT64(1); 1028 int64 result; 1029 1030 if (unlikely(pg_add_s64_overflow((int64) arg1, arg2, &result))) 1031 ereport(ERROR, 1032 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 1033 errmsg("bigint out of range"))); 1034 PG_RETURN_INT64(result); 1035 } 1036 1037 Datum 1038 int28mi(PG_FUNCTION_ARGS) 1039 { 1040 int16 arg1 = PG_GETARG_INT16(0); 1041 int64 arg2 = PG_GETARG_INT64(1); 1042 int64 result; 1043 1044 if (unlikely(pg_sub_s64_overflow((int64) arg1, arg2, &result))) 1045 ereport(ERROR, 1046 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 1047 errmsg("bigint out of range"))); 1048 PG_RETURN_INT64(result); 1049 } 1050 1051 Datum 1052 int28mul(PG_FUNCTION_ARGS) 1053 { 1054 int16 arg1 = PG_GETARG_INT16(0); 1055 int64 arg2 = PG_GETARG_INT64(1); 1056 int64 result; 1057 1058 if (unlikely(pg_mul_s64_overflow((int64) arg1, arg2, &result))) 1059 ereport(ERROR, 1060 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 1061 errmsg("bigint out of range"))); 1062 PG_RETURN_INT64(result); 1063 } 1064 1065 Datum 1066 int28div(PG_FUNCTION_ARGS) 1067 { 1068 int16 arg1 = PG_GETARG_INT16(0); 1069 int64 arg2 = PG_GETARG_INT64(1); 1070 1071 if (unlikely(arg2 == 0)) 1072 { 1073 ereport(ERROR, 1074 (errcode(ERRCODE_DIVISION_BY_ZERO), 1075 errmsg("division by zero"))); 1076 /* ensure compiler realizes we mustn't reach the division (gcc bug) */ 1077 PG_RETURN_NULL(); 1078 } 1079 1080 /* No overflow is possible */ 1081 PG_RETURN_INT64((int64) arg1 / arg2); 1082 } 1083 1084 /* Binary arithmetics 1085 * 1086 * int8and - returns arg1 & arg2 1087 * int8or - returns arg1 | arg2 1088 * int8xor - returns arg1 # arg2 1089 * int8not - returns ~arg1 1090 * int8shl - returns arg1 << arg2 1091 * int8shr - returns arg1 >> arg2 1092 */ 1093 1094 Datum 1095 int8and(PG_FUNCTION_ARGS) 1096 { 1097 int64 arg1 = PG_GETARG_INT64(0); 1098 int64 arg2 = PG_GETARG_INT64(1); 1099 1100 PG_RETURN_INT64(arg1 & arg2); 1101 } 1102 1103 Datum 1104 int8or(PG_FUNCTION_ARGS) 1105 { 1106 int64 arg1 = PG_GETARG_INT64(0); 1107 int64 arg2 = PG_GETARG_INT64(1); 1108 1109 PG_RETURN_INT64(arg1 | arg2); 1110 } 1111 1112 Datum 1113 int8xor(PG_FUNCTION_ARGS) 1114 { 1115 int64 arg1 = PG_GETARG_INT64(0); 1116 int64 arg2 = PG_GETARG_INT64(1); 1117 1118 PG_RETURN_INT64(arg1 ^ arg2); 1119 } 1120 1121 Datum 1122 int8not(PG_FUNCTION_ARGS) 1123 { 1124 int64 arg1 = PG_GETARG_INT64(0); 1125 1126 PG_RETURN_INT64(~arg1); 1127 } 1128 1129 Datum 1130 int8shl(PG_FUNCTION_ARGS) 1131 { 1132 int64 arg1 = PG_GETARG_INT64(0); 1133 int32 arg2 = PG_GETARG_INT32(1); 1134 1135 PG_RETURN_INT64(arg1 << arg2); 1136 } 1137 1138 Datum 1139 int8shr(PG_FUNCTION_ARGS) 1140 { 1141 int64 arg1 = PG_GETARG_INT64(0); 1142 int32 arg2 = PG_GETARG_INT32(1); 1143 1144 PG_RETURN_INT64(arg1 >> arg2); 1145 } 1146 1147 /*---------------------------------------------------------- 1148 * Conversion operators. 1149 *---------------------------------------------------------*/ 1150 1151 Datum 1152 int48(PG_FUNCTION_ARGS) 1153 { 1154 int32 arg = PG_GETARG_INT32(0); 1155 1156 PG_RETURN_INT64((int64) arg); 1157 } 1158 1159 Datum 1160 int84(PG_FUNCTION_ARGS) 1161 { 1162 int64 arg = PG_GETARG_INT64(0); 1163 1164 if (unlikely(arg < PG_INT32_MIN) || unlikely(arg > PG_INT32_MAX)) 1165 ereport(ERROR, 1166 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 1167 errmsg("integer out of range"))); 1168 1169 PG_RETURN_INT32((int32) arg); 1170 } 1171 1172 Datum 1173 int28(PG_FUNCTION_ARGS) 1174 { 1175 int16 arg = PG_GETARG_INT16(0); 1176 1177 PG_RETURN_INT64((int64) arg); 1178 } 1179 1180 Datum 1181 int82(PG_FUNCTION_ARGS) 1182 { 1183 int64 arg = PG_GETARG_INT64(0); 1184 1185 if (unlikely(arg < PG_INT16_MIN) || unlikely(arg > PG_INT16_MAX)) 1186 ereport(ERROR, 1187 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 1188 errmsg("smallint out of range"))); 1189 1190 PG_RETURN_INT16((int16) arg); 1191 } 1192 1193 Datum 1194 i8tod(PG_FUNCTION_ARGS) 1195 { 1196 int64 arg = PG_GETARG_INT64(0); 1197 float8 result; 1198 1199 result = arg; 1200 1201 PG_RETURN_FLOAT8(result); 1202 } 1203 1204 /* dtoi8() 1205 * Convert float8 to 8-byte integer. 1206 */ 1207 Datum 1208 dtoi8(PG_FUNCTION_ARGS) 1209 { 1210 float8 num = PG_GETARG_FLOAT8(0); 1211 1212 /* 1213 * Get rid of any fractional part in the input. This is so we don't fail 1214 * on just-out-of-range values that would round into range. Note 1215 * assumption that rint() will pass through a NaN or Inf unchanged. 1216 */ 1217 num = rint(num); 1218 1219 /* Range check */ 1220 if (unlikely(isnan(num) || !FLOAT8_FITS_IN_INT64(num))) 1221 ereport(ERROR, 1222 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 1223 errmsg("bigint out of range"))); 1224 1225 PG_RETURN_INT64((int64) num); 1226 } 1227 1228 Datum 1229 i8tof(PG_FUNCTION_ARGS) 1230 { 1231 int64 arg = PG_GETARG_INT64(0); 1232 float4 result; 1233 1234 result = arg; 1235 1236 PG_RETURN_FLOAT4(result); 1237 } 1238 1239 /* ftoi8() 1240 * Convert float4 to 8-byte integer. 1241 */ 1242 Datum 1243 ftoi8(PG_FUNCTION_ARGS) 1244 { 1245 float4 num = PG_GETARG_FLOAT4(0); 1246 1247 /* 1248 * Get rid of any fractional part in the input. This is so we don't fail 1249 * on just-out-of-range values that would round into range. Note 1250 * assumption that rint() will pass through a NaN or Inf unchanged. 1251 */ 1252 num = rint(num); 1253 1254 /* Range check */ 1255 if (unlikely(isnan(num) || !FLOAT4_FITS_IN_INT64(num))) 1256 ereport(ERROR, 1257 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 1258 errmsg("bigint out of range"))); 1259 1260 PG_RETURN_INT64((int64) num); 1261 } 1262 1263 Datum 1264 i8tooid(PG_FUNCTION_ARGS) 1265 { 1266 int64 arg = PG_GETARG_INT64(0); 1267 1268 if (unlikely(arg < 0) || unlikely(arg > PG_UINT32_MAX)) 1269 ereport(ERROR, 1270 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 1271 errmsg("OID out of range"))); 1272 1273 PG_RETURN_OID((Oid) arg); 1274 } 1275 1276 Datum 1277 oidtoi8(PG_FUNCTION_ARGS) 1278 { 1279 Oid arg = PG_GETARG_OID(0); 1280 1281 PG_RETURN_INT64((int64) arg); 1282 } 1283 1284 /* 1285 * non-persistent numeric series generator 1286 */ 1287 Datum 1288 generate_series_int8(PG_FUNCTION_ARGS) 1289 { 1290 return generate_series_step_int8(fcinfo); 1291 } 1292 1293 Datum 1294 generate_series_step_int8(PG_FUNCTION_ARGS) 1295 { 1296 FuncCallContext *funcctx; 1297 generate_series_fctx *fctx; 1298 int64 result; 1299 MemoryContext oldcontext; 1300 1301 /* stuff done only on the first call of the function */ 1302 if (SRF_IS_FIRSTCALL()) 1303 { 1304 int64 start = PG_GETARG_INT64(0); 1305 int64 finish = PG_GETARG_INT64(1); 1306 int64 step = 1; 1307 1308 /* see if we were given an explicit step size */ 1309 if (PG_NARGS() == 3) 1310 step = PG_GETARG_INT64(2); 1311 if (step == 0) 1312 ereport(ERROR, 1313 (errcode(ERRCODE_INVALID_PARAMETER_VALUE), 1314 errmsg("step size cannot equal zero"))); 1315 1316 /* create a function context for cross-call persistence */ 1317 funcctx = SRF_FIRSTCALL_INIT(); 1318 1319 /* 1320 * switch to memory context appropriate for multiple function calls 1321 */ 1322 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); 1323 1324 /* allocate memory for user context */ 1325 fctx = (generate_series_fctx *) palloc(sizeof(generate_series_fctx)); 1326 1327 /* 1328 * Use fctx to keep state from call to call. Seed current with the 1329 * original start value 1330 */ 1331 fctx->current = start; 1332 fctx->finish = finish; 1333 fctx->step = step; 1334 1335 funcctx->user_fctx = fctx; 1336 MemoryContextSwitchTo(oldcontext); 1337 } 1338 1339 /* stuff done on every call of the function */ 1340 funcctx = SRF_PERCALL_SETUP(); 1341 1342 /* 1343 * get the saved state and use current as the result for this iteration 1344 */ 1345 fctx = funcctx->user_fctx; 1346 result = fctx->current; 1347 1348 if ((fctx->step > 0 && fctx->current <= fctx->finish) || 1349 (fctx->step < 0 && fctx->current >= fctx->finish)) 1350 { 1351 /* 1352 * Increment current in preparation for next iteration. If next-value 1353 * computation overflows, this is the final result. 1354 */ 1355 if (pg_add_s64_overflow(fctx->current, fctx->step, &fctx->current)) 1356 fctx->step = 0; 1357 1358 /* do when there is more left to send */ 1359 SRF_RETURN_NEXT(funcctx, Int64GetDatum(result)); 1360 } 1361 else 1362 /* do when there is no more left */ 1363 SRF_RETURN_DONE(funcctx); 1364 } 1365 1366 /* 1367 * Planner support function for generate_series(int8, int8 [, int8]) 1368 */ 1369 Datum 1370 generate_series_int8_support(PG_FUNCTION_ARGS) 1371 { 1372 Node *rawreq = (Node *) PG_GETARG_POINTER(0); 1373 Node *ret = NULL; 1374 1375 if (IsA(rawreq, SupportRequestRows)) 1376 { 1377 /* Try to estimate the number of rows returned */ 1378 SupportRequestRows *req = (SupportRequestRows *) rawreq; 1379 1380 if (is_funcclause(req->node)) /* be paranoid */ 1381 { 1382 List *args = ((FuncExpr *) req->node)->args; 1383 Node *arg1, 1384 *arg2, 1385 *arg3; 1386 1387 /* We can use estimated argument values here */ 1388 arg1 = estimate_expression_value(req->root, linitial(args)); 1389 arg2 = estimate_expression_value(req->root, lsecond(args)); 1390 if (list_length(args) >= 3) 1391 arg3 = estimate_expression_value(req->root, lthird(args)); 1392 else 1393 arg3 = NULL; 1394 1395 /* 1396 * If any argument is constant NULL, we can safely assume that 1397 * zero rows are returned. Otherwise, if they're all non-NULL 1398 * constants, we can calculate the number of rows that will be 1399 * returned. Use double arithmetic to avoid overflow hazards. 1400 */ 1401 if ((IsA(arg1, Const) && 1402 ((Const *) arg1)->constisnull) || 1403 (IsA(arg2, Const) && 1404 ((Const *) arg2)->constisnull) || 1405 (arg3 != NULL && IsA(arg3, Const) && 1406 ((Const *) arg3)->constisnull)) 1407 { 1408 req->rows = 0; 1409 ret = (Node *) req; 1410 } 1411 else if (IsA(arg1, Const) && 1412 IsA(arg2, Const) && 1413 (arg3 == NULL || IsA(arg3, Const))) 1414 { 1415 double start, 1416 finish, 1417 step; 1418 1419 start = DatumGetInt64(((Const *) arg1)->constvalue); 1420 finish = DatumGetInt64(((Const *) arg2)->constvalue); 1421 step = arg3 ? DatumGetInt64(((Const *) arg3)->constvalue) : 1; 1422 1423 /* This equation works for either sign of step */ 1424 if (step != 0) 1425 { 1426 req->rows = floor((finish - start + step) / step); 1427 ret = (Node *) req; 1428 } 1429 } 1430 } 1431 } 1432 1433 PG_RETURN_POINTER(ret); 1434 } 1435