← Back to Overview

src/backend/executor/execExprInterp.c

Coverage: 87/89 lines (97.8%)
Total Lines
89
modified
Covered
87
97.8%
Uncovered
2
2.2%
Keyboard navigation
ExecInterpExpr() lines 472-2311
Modified Lines Coverage: 8/8 lines (100.0%)
LineHitsSourceCommit
472 - ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) -
473 - { -
474 - ExprEvalStep *op; -
475 - TupleTableSlot *resultslot; -
476 - TupleTableSlot *innerslot; -
477 - TupleTableSlot *outerslot; -
478 - TupleTableSlot *scanslot; -
479 - TupleTableSlot *oldslot; -
480 - TupleTableSlot *newslot; -
481 - -
482 - /* -
483 - * This array has to be in the same order as enum ExprEvalOp. -
484 - */ -
485 - #if defined(EEO_USE_COMPUTED_GOTO) -
486 - static const void *const dispatch_table[] = { -
487 - &&CASE_EEOP_DONE_RETURN, -
488 - &&CASE_EEOP_DONE_NO_RETURN, -
489 - &&CASE_EEOP_INNER_FETCHSOME, -
490 - &&CASE_EEOP_OUTER_FETCHSOME, -
491 - &&CASE_EEOP_SCAN_FETCHSOME, -
492 - &&CASE_EEOP_OLD_FETCHSOME, -
493 - &&CASE_EEOP_NEW_FETCHSOME, -
494 - &&CASE_EEOP_INNER_VAR, -
495 - &&CASE_EEOP_OUTER_VAR, -
496 - &&CASE_EEOP_SCAN_VAR, -
497 - &&CASE_EEOP_OLD_VAR, -
498 - &&CASE_EEOP_NEW_VAR, -
499 - &&CASE_EEOP_INNER_SYSVAR, -
500 - &&CASE_EEOP_OUTER_SYSVAR, -
501 - &&CASE_EEOP_SCAN_SYSVAR, -
502 - &&CASE_EEOP_OLD_SYSVAR, -
503 - &&CASE_EEOP_NEW_SYSVAR, -
504 - &&CASE_EEOP_WHOLEROW, -
505 - &&CASE_EEOP_ASSIGN_INNER_VAR, -
506 - &&CASE_EEOP_ASSIGN_OUTER_VAR, -
507 - &&CASE_EEOP_ASSIGN_SCAN_VAR, -
508 - &&CASE_EEOP_ASSIGN_OLD_VAR, -
509 - &&CASE_EEOP_ASSIGN_NEW_VAR, -
510 - &&CASE_EEOP_ASSIGN_TMP, -
511 - &&CASE_EEOP_ASSIGN_TMP_MAKE_RO, -
512 - &&CASE_EEOP_CONST, -
513 - &&CASE_EEOP_FUNCEXPR, -
514 - &&CASE_EEOP_FUNCEXPR_STRICT, -
515 - &&CASE_EEOP_FUNCEXPR_STRICT_1, -
516 - &&CASE_EEOP_FUNCEXPR_STRICT_2, -
517 - &&CASE_EEOP_FUNCEXPR_FUSAGE, -
518 - &&CASE_EEOP_FUNCEXPR_STRICT_FUSAGE, -
519 - &&CASE_EEOP_BOOL_AND_STEP_FIRST, -
520 - &&CASE_EEOP_BOOL_AND_STEP, -
521 - &&CASE_EEOP_BOOL_AND_STEP_LAST, -
522 - &&CASE_EEOP_BOOL_OR_STEP_FIRST, -
523 - &&CASE_EEOP_BOOL_OR_STEP, -
524 - &&CASE_EEOP_BOOL_OR_STEP_LAST, -
525 - &&CASE_EEOP_BOOL_NOT_STEP, -
526 - &&CASE_EEOP_QUAL, -
527 - &&CASE_EEOP_JUMP, -
528 - &&CASE_EEOP_JUMP_IF_NULL, -
529 - &&CASE_EEOP_JUMP_IF_NOT_NULL, -
530 - &&CASE_EEOP_JUMP_IF_NOT_TRUE, -
531 - &&CASE_EEOP_NULLTEST_ISNULL, -
532 - &&CASE_EEOP_NULLTEST_ISNOTNULL, -
533 - &&CASE_EEOP_NULLTEST_ROWISNULL, -
534 - &&CASE_EEOP_NULLTEST_ROWISNOTNULL, -
535 - &&CASE_EEOP_BOOLTEST_IS_TRUE, -
536 - &&CASE_EEOP_BOOLTEST_IS_NOT_TRUE, -
537 - &&CASE_EEOP_BOOLTEST_IS_FALSE, -
538 - &&CASE_EEOP_BOOLTEST_IS_NOT_FALSE, -
539 - &&CASE_EEOP_PARAM_EXEC, -
540 - &&CASE_EEOP_PARAM_EXTERN, -
541 - &&CASE_EEOP_PARAM_CALLBACK, -
542 - &&CASE_EEOP_PARAM_SET, -
543 - &&CASE_EEOP_CASE_TESTVAL, -
544 - &&CASE_EEOP_CASE_TESTVAL_EXT, -
545 - &&CASE_EEOP_MAKE_READONLY, -
546 - &&CASE_EEOP_IOCOERCE, -
547 - &&CASE_EEOP_IOCOERCE_SAFE, -
548 - &&CASE_EEOP_DISTINCT, -
549 - &&CASE_EEOP_NOT_DISTINCT, -
550 - &&CASE_EEOP_NULLIF, -
551 - &&CASE_EEOP_SQLVALUEFUNCTION, -
552 - &&CASE_EEOP_CURRENTOFEXPR, -
553 - &&CASE_EEOP_NEXTVALUEEXPR, -
554 - &&CASE_EEOP_RETURNINGEXPR, -
555 - &&CASE_EEOP_ARRAYEXPR, -
556 - &&CASE_EEOP_ARRAYCOERCE, -
557 - &&CASE_EEOP_ROW, -
558 - &&CASE_EEOP_ROWCOMPARE_STEP, -
559 - &&CASE_EEOP_ROWCOMPARE_FINAL, -
560 - &&CASE_EEOP_MINMAX, -
561 - &&CASE_EEOP_FIELDSELECT, -
562 - &&CASE_EEOP_FIELDSTORE_DEFORM, -
563 - &&CASE_EEOP_FIELDSTORE_FORM, -
564 - &&CASE_EEOP_SBSREF_SUBSCRIPTS, -
565 - &&CASE_EEOP_SBSREF_OLD, -
566 - &&CASE_EEOP_SBSREF_ASSIGN, -
567 - &&CASE_EEOP_SBSREF_FETCH, -
568 - &&CASE_EEOP_DOMAIN_TESTVAL, -
569 - &&CASE_EEOP_DOMAIN_TESTVAL_EXT, -
570 - &&CASE_EEOP_DOMAIN_NOTNULL, -
571 - &&CASE_EEOP_DOMAIN_CHECK, -
572 - &&CASE_EEOP_HASHDATUM_SET_INITVAL, -
573 - &&CASE_EEOP_HASHDATUM_FIRST, -
574 - &&CASE_EEOP_HASHDATUM_FIRST_STRICT, -
575 - &&CASE_EEOP_HASHDATUM_NEXT32, -
576 - &&CASE_EEOP_HASHDATUM_NEXT32_STRICT, -
577 - &&CASE_EEOP_CONVERT_ROWTYPE, -
578 - &&CASE_EEOP_SCALARARRAYOP, -
579 - &&CASE_EEOP_HASHED_SCALARARRAYOP, -
580 - &&CASE_EEOP_XMLEXPR, -
581 - &&CASE_EEOP_JSON_CONSTRUCTOR, -
582 - &&CASE_EEOP_IS_JSON, -
583 - &&CASE_EEOP_JSONEXPR_PATH, -
584 - &&CASE_EEOP_JSONEXPR_COERCION, -
585 - &&CASE_EEOP_JSONEXPR_COERCION_FINISH, -
586 - &&CASE_EEOP_AGGREF, -
587 - &&CASE_EEOP_GROUPING_FUNC, -
588 - &&CASE_EEOP_WINDOW_FUNC, -
589 - &&CASE_EEOP_MERGE_SUPPORT_FUNC, -
590 - &&CASE_EEOP_SUBPLAN, -
591 - &&CASE_EEOP_RPR_NAV_SET, 24cfb8dRow pattern recognition patch (executor and commands).
592 - &&CASE_EEOP_RPR_NAV_RESTORE, 24cfb8dRow pattern recognition patch (executor and commands).
593 - &&CASE_EEOP_AGG_STRICT_DESERIALIZE, -
594 - &&CASE_EEOP_AGG_DESERIALIZE, -
595 - &&CASE_EEOP_AGG_STRICT_INPUT_CHECK_ARGS, -
596 - &&CASE_EEOP_AGG_STRICT_INPUT_CHECK_ARGS_1, -
597 - &&CASE_EEOP_AGG_STRICT_INPUT_CHECK_NULLS, -
598 - &&CASE_EEOP_AGG_PLAIN_PERGROUP_NULLCHECK, -
599 - &&CASE_EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL, -
600 - &&CASE_EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL, -
601 - &&CASE_EEOP_AGG_PLAIN_TRANS_BYVAL, -
602 - &&CASE_EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF, -
603 - &&CASE_EEOP_AGG_PLAIN_TRANS_STRICT_BYREF, -
604 - &&CASE_EEOP_AGG_PLAIN_TRANS_BYREF, -
605 - &&CASE_EEOP_AGG_PRESORTED_DISTINCT_SINGLE, -
606 - &&CASE_EEOP_AGG_PRESORTED_DISTINCT_MULTI, -
607 - &&CASE_EEOP_AGG_ORDERED_TRANS_DATUM, -
608 - &&CASE_EEOP_AGG_ORDERED_TRANS_TUPLE, -
609 - &&CASE_EEOP_LAST -
610 - }; -
611 - -
612 - StaticAssertDecl(lengthof(dispatch_table) == EEOP_LAST + 1, -
613 - "dispatch_table out of whack with ExprEvalOp"); -
614 - -
615 - if (unlikely(state == NULL)) -
616 - return PointerGetDatum(dispatch_table); -
617 - #else -
618 - Assert(state != NULL); -
619 - #endif /* EEO_USE_COMPUTED_GOTO */ -
620 - -
621 - /* setup state */ -
622 - op = state->steps; -
623 - resultslot = state->resultslot; -
624 - innerslot = econtext->ecxt_innertuple; -
625 - outerslot = econtext->ecxt_outertuple; -
626 - scanslot = econtext->ecxt_scantuple; -
627 - oldslot = econtext->ecxt_oldtuple; -
628 - newslot = econtext->ecxt_newtuple; -
629 - -
630 - #if defined(EEO_USE_COMPUTED_GOTO) -
631 - EEO_DISPATCH(); -
632 - #endif -
633 - -
634 - EEO_SWITCH() -
635 - { -
636 - EEO_CASE(EEOP_DONE_RETURN) -
637 - { -
638 - *isnull = state->resnull; -
639 - return state->resvalue; -
640 - } -
641 - -
642 - EEO_CASE(EEOP_DONE_NO_RETURN) -
643 - { -
644 - Assert(isnull == NULL); -
645 - return (Datum) 0; -
646 - } -
647 - -
648 - EEO_CASE(EEOP_INNER_FETCHSOME) -
649 - { -
650 - CheckOpSlotCompatibility(op, innerslot); -
651 - -
652 - slot_getsomeattrs(innerslot, op->d.fetch.last_var); -
653 - -
654 - EEO_NEXT(); -
655 - } -
656 - -
657 - EEO_CASE(EEOP_OUTER_FETCHSOME) -
658 - { -
659 - CheckOpSlotCompatibility(op, outerslot); -
660 - -
661 - slot_getsomeattrs(outerslot, op->d.fetch.last_var); -
662 - -
663 - EEO_NEXT(); -
664 - } -
665 - -
666 - EEO_CASE(EEOP_SCAN_FETCHSOME) -
667 - { -
668 - CheckOpSlotCompatibility(op, scanslot); -
669 - -
670 - slot_getsomeattrs(scanslot, op->d.fetch.last_var); -
671 - -
672 - EEO_NEXT(); -
673 - } -
674 - -
675 - EEO_CASE(EEOP_OLD_FETCHSOME) -
676 - { -
677 - CheckOpSlotCompatibility(op, oldslot); -
678 - -
679 - slot_getsomeattrs(oldslot, op->d.fetch.last_var); -
680 - -
681 - EEO_NEXT(); -
682 - } -
683 - -
684 - EEO_CASE(EEOP_NEW_FETCHSOME) -
685 - { -
686 - CheckOpSlotCompatibility(op, newslot); -
687 - -
688 - slot_getsomeattrs(newslot, op->d.fetch.last_var); -
689 - -
690 - EEO_NEXT(); -
691 - } -
692 - -
693 - EEO_CASE(EEOP_INNER_VAR) -
694 - { -
695 - int attnum = op->d.var.attnum; -
696 - -
697 - /* -
698 - * Since we already extracted all referenced columns from the -
699 - * tuple with a FETCHSOME step, we can just grab the value -
700 - * directly out of the slot's decomposed-data arrays. But let's -
701 - * have an Assert to check that that did happen. -
702 - */ -
703 - Assert(attnum >= 0 && attnum < innerslot->tts_nvalid); -
704 - *op->resvalue = innerslot->tts_values[attnum]; -
705 - *op->resnull = innerslot->tts_isnull[attnum]; -
706 - -
707 - EEO_NEXT(); -
708 - } -
709 - -
710 - EEO_CASE(EEOP_OUTER_VAR) -
711 - { -
712 - int attnum = op->d.var.attnum; -
713 - -
714 - /* See EEOP_INNER_VAR comments */ -
715 - -
716 - Assert(attnum >= 0 && attnum < outerslot->tts_nvalid); -
717 - *op->resvalue = outerslot->tts_values[attnum]; -
718 - *op->resnull = outerslot->tts_isnull[attnum]; -
719 - -
720 - EEO_NEXT(); -
721 - } -
722 - -
723 - EEO_CASE(EEOP_SCAN_VAR) -
724 - { -
725 - int attnum = op->d.var.attnum; -
726 - -
727 - /* See EEOP_INNER_VAR comments */ -
728 - -
729 - Assert(attnum >= 0 && attnum < scanslot->tts_nvalid); -
730 - *op->resvalue = scanslot->tts_values[attnum]; -
731 - *op->resnull = scanslot->tts_isnull[attnum]; -
732 - -
733 - EEO_NEXT(); -
734 - } -
735 - -
736 - EEO_CASE(EEOP_OLD_VAR) -
737 - { -
738 - int attnum = op->d.var.attnum; -
739 - -
740 - /* See EEOP_INNER_VAR comments */ -
741 - -
742 - Assert(attnum >= 0 && attnum < oldslot->tts_nvalid); -
743 - *op->resvalue = oldslot->tts_values[attnum]; -
744 - *op->resnull = oldslot->tts_isnull[attnum]; -
745 - -
746 - EEO_NEXT(); -
747 - } -
748 - -
749 - EEO_CASE(EEOP_NEW_VAR) -
750 - { -
751 - int attnum = op->d.var.attnum; -
752 - -
753 - /* See EEOP_INNER_VAR comments */ -
754 - -
755 - Assert(attnum >= 0 && attnum < newslot->tts_nvalid); -
756 - *op->resvalue = newslot->tts_values[attnum]; -
757 - *op->resnull = newslot->tts_isnull[attnum]; -
758 - -
759 - EEO_NEXT(); -
760 - } -
761 - -
762 - EEO_CASE(EEOP_INNER_SYSVAR) -
763 - { -
764 - ExecEvalSysVar(state, op, econtext, innerslot); -
765 - EEO_NEXT(); -
766 - } -
767 - -
768 - EEO_CASE(EEOP_OUTER_SYSVAR) -
769 - { -
770 - ExecEvalSysVar(state, op, econtext, outerslot); -
771 - EEO_NEXT(); -
772 - } -
773 - -
774 - EEO_CASE(EEOP_SCAN_SYSVAR) -
775 - { -
776 - ExecEvalSysVar(state, op, econtext, scanslot); -
777 - EEO_NEXT(); -
778 - } -
779 - -
780 - EEO_CASE(EEOP_OLD_SYSVAR) -
781 - { -
782 - ExecEvalSysVar(state, op, econtext, oldslot); -
783 - EEO_NEXT(); -
784 - } -
785 - -
786 - EEO_CASE(EEOP_NEW_SYSVAR) -
787 - { -
788 - ExecEvalSysVar(state, op, econtext, newslot); -
789 - EEO_NEXT(); -
790 - } -
791 - -
792 - EEO_CASE(EEOP_WHOLEROW) -
793 - { -
794 - /* too complex for an inline implementation */ -
795 - ExecEvalWholeRowVar(state, op, econtext); -
796 - -
797 - EEO_NEXT(); -
798 - } -
799 - -
800 - EEO_CASE(EEOP_ASSIGN_INNER_VAR) -
801 - { -
802 - int resultnum = op->d.assign_var.resultnum; -
803 - int attnum = op->d.assign_var.attnum; -
804 - -
805 - /* -
806 - * We do not need CheckVarSlotCompatibility here; that was taken -
807 - * care of at compilation time. But see EEOP_INNER_VAR comments. -
808 - */ -
809 - Assert(attnum >= 0 && attnum < innerslot->tts_nvalid); -
810 - Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts); -
811 - resultslot->tts_values[resultnum] = innerslot->tts_values[attnum]; -
812 - resultslot->tts_isnull[resultnum] = innerslot->tts_isnull[attnum]; -
813 - -
814 - EEO_NEXT(); -
815 - } -
816 - -
817 - EEO_CASE(EEOP_ASSIGN_OUTER_VAR) -
818 - { -
819 - int resultnum = op->d.assign_var.resultnum; -
820 - int attnum = op->d.assign_var.attnum; -
821 - -
822 - /* -
823 - * We do not need CheckVarSlotCompatibility here; that was taken -
824 - * care of at compilation time. But see EEOP_INNER_VAR comments. -
825 - */ -
826 - Assert(attnum >= 0 && attnum < outerslot->tts_nvalid); -
827 - Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts); -
828 - resultslot->tts_values[resultnum] = outerslot->tts_values[attnum]; -
829 - resultslot->tts_isnull[resultnum] = outerslot->tts_isnull[attnum]; -
830 - -
831 - EEO_NEXT(); -
832 - } -
833 - -
834 - EEO_CASE(EEOP_ASSIGN_SCAN_VAR) -
835 - { -
836 - int resultnum = op->d.assign_var.resultnum; -
837 - int attnum = op->d.assign_var.attnum; -
838 - -
839 - /* -
840 - * We do not need CheckVarSlotCompatibility here; that was taken -
841 - * care of at compilation time. But see EEOP_INNER_VAR comments. -
842 - */ -
843 - Assert(attnum >= 0 && attnum < scanslot->tts_nvalid); -
844 - Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts); -
845 - resultslot->tts_values[resultnum] = scanslot->tts_values[attnum]; -
846 - resultslot->tts_isnull[resultnum] = scanslot->tts_isnull[attnum]; -
847 - -
848 - EEO_NEXT(); -
849 - } -
850 - -
851 - EEO_CASE(EEOP_ASSIGN_OLD_VAR) -
852 - { -
853 - int resultnum = op->d.assign_var.resultnum; -
854 - int attnum = op->d.assign_var.attnum; -
855 - -
856 - /* -
857 - * We do not need CheckVarSlotCompatibility here; that was taken -
858 - * care of at compilation time. But see EEOP_INNER_VAR comments. -
859 - */ -
860 - Assert(attnum >= 0 && attnum < oldslot->tts_nvalid); -
861 - Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts); -
862 - resultslot->tts_values[resultnum] = oldslot->tts_values[attnum]; -
863 - resultslot->tts_isnull[resultnum] = oldslot->tts_isnull[attnum]; -
864 - -
865 - EEO_NEXT(); -
866 - } -
867 - -
868 - EEO_CASE(EEOP_ASSIGN_NEW_VAR) -
869 - { -
870 - int resultnum = op->d.assign_var.resultnum; -
871 - int attnum = op->d.assign_var.attnum; -
872 - -
873 - /* -
874 - * We do not need CheckVarSlotCompatibility here; that was taken -
875 - * care of at compilation time. But see EEOP_INNER_VAR comments. -
876 - */ -
877 - Assert(attnum >= 0 && attnum < newslot->tts_nvalid); -
878 - Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts); -
879 - resultslot->tts_values[resultnum] = newslot->tts_values[attnum]; -
880 - resultslot->tts_isnull[resultnum] = newslot->tts_isnull[attnum]; -
881 - -
882 - EEO_NEXT(); -
883 - } -
884 - -
885 - EEO_CASE(EEOP_ASSIGN_TMP) -
886 - { -
887 - int resultnum = op->d.assign_tmp.resultnum; -
888 - -
889 - Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts); -
890 - resultslot->tts_values[resultnum] = state->resvalue; -
891 - resultslot->tts_isnull[resultnum] = state->resnull; -
892 - -
893 - EEO_NEXT(); -
894 - } -
895 - -
896 - EEO_CASE(EEOP_ASSIGN_TMP_MAKE_RO) -
897 - { -
898 - int resultnum = op->d.assign_tmp.resultnum; -
899 - -
900 - Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts); -
901 - resultslot->tts_isnull[resultnum] = state->resnull; -
902 - if (!resultslot->tts_isnull[resultnum]) -
903 - resultslot->tts_values[resultnum] = -
904 - MakeExpandedObjectReadOnlyInternal(state->resvalue); -
905 - else -
906 - resultslot->tts_values[resultnum] = state->resvalue; -
907 - -
908 - EEO_NEXT(); -
909 - } -
910 - -
911 - EEO_CASE(EEOP_CONST) -
912 - { -
913 - *op->resnull = op->d.constval.isnull; -
914 - *op->resvalue = op->d.constval.value; -
915 - -
916 - EEO_NEXT(); -
917 - } -
918 - -
919 - /* -
920 - * Function-call implementations. Arguments have previously been -
921 - * evaluated directly into fcinfo->args. -
922 - * -
923 - * As both STRICT checks and function-usage are noticeable performance -
924 - * wise, and function calls are a very hot-path (they also back -
925 - * operators!), it's worth having so many separate opcodes. -
926 - * -
927 - * Note: the reason for using a temporary variable "d", here and in -
928 - * other places, is that some compilers think "*op->resvalue = f();" -
929 - * requires them to evaluate op->resvalue into a register before -
930 - * calling f(), just in case f() is able to modify op->resvalue -
931 - * somehow. The extra line of code can save a useless register spill -
932 - * and reload across the function call. -
933 - */ -
934 - EEO_CASE(EEOP_FUNCEXPR) -
935 - { -
936 - FunctionCallInfo fcinfo = op->d.func.fcinfo_data; -
937 - Datum d; -
938 - -
939 - fcinfo->isnull = false; -
940 - d = op->d.func.fn_addr(fcinfo); -
941 - *op->resvalue = d; -
942 - *op->resnull = fcinfo->isnull; -
943 - -
944 - EEO_NEXT(); -
945 - } -
946 - -
947 - /* strict function call with more than two arguments */ -
948 - EEO_CASE(EEOP_FUNCEXPR_STRICT) -
949 - { -
950 - FunctionCallInfo fcinfo = op->d.func.fcinfo_data; -
951 - NullableDatum *args = fcinfo->args; -
952 - int nargs = op->d.func.nargs; -
953 - Datum d; -
954 - -
955 - Assert(nargs > 2); -
956 - -
957 - /* strict function, so check for NULL args */ -
958 - for (int argno = 0; argno < nargs; argno++) -
959 - { -
960 - if (args[argno].isnull) -
961 - { -
962 - *op->resnull = true; -
963 - goto strictfail; -
964 - } -
965 - } -
966 - fcinfo->isnull = false; -
967 - d = op->d.func.fn_addr(fcinfo); -
968 - *op->resvalue = d; -
969 - *op->resnull = fcinfo->isnull; -
970 - -
971 - strictfail: -
972 - EEO_NEXT(); -
973 - } -
974 - -
975 - /* strict function call with one argument */ -
976 - EEO_CASE(EEOP_FUNCEXPR_STRICT_1) -
977 - { -
978 - FunctionCallInfo fcinfo = op->d.func.fcinfo_data; -
979 - NullableDatum *args = fcinfo->args; -
980 - -
981 - Assert(op->d.func.nargs == 1); -
982 - -
983 - /* strict function, so check for NULL args */ -
984 - if (args[0].isnull) -
985 - *op->resnull = true; -
986 - else -
987 - { -
988 - Datum d; -
989 - -
990 - fcinfo->isnull = false; -
991 - d = op->d.func.fn_addr(fcinfo); -
992 - *op->resvalue = d; -
993 - *op->resnull = fcinfo->isnull; -
994 - } -
995 - -
996 - EEO_NEXT(); -
997 - } -
998 - -
999 - /* strict function call with two arguments */ -
1000 - EEO_CASE(EEOP_FUNCEXPR_STRICT_2) -
1001 - { -
1002 - FunctionCallInfo fcinfo = op->d.func.fcinfo_data; -
1003 - NullableDatum *args = fcinfo->args; -
1004 - -
1005 - Assert(op->d.func.nargs == 2); -
1006 - -
1007 - /* strict function, so check for NULL args */ -
1008 - if (args[0].isnull || args[1].isnull) -
1009 - *op->resnull = true; -
1010 - else -
1011 - { -
1012 - Datum d; -
1013 - -
1014 - fcinfo->isnull = false; -
1015 - d = op->d.func.fn_addr(fcinfo); -
1016 - *op->resvalue = d; -
1017 - *op->resnull = fcinfo->isnull; -
1018 - } -
1019 - -
1020 - EEO_NEXT(); -
1021 - } -
1022 - -
1023 - EEO_CASE(EEOP_FUNCEXPR_FUSAGE) -
1024 - { -
1025 - /* not common enough to inline */ -
1026 - ExecEvalFuncExprFusage(state, op, econtext); -
1027 - -
1028 - EEO_NEXT(); -
1029 - } -
1030 - -
1031 - EEO_CASE(EEOP_FUNCEXPR_STRICT_FUSAGE) -
1032 - { -
1033 - /* not common enough to inline */ -
1034 - ExecEvalFuncExprStrictFusage(state, op, econtext); -
1035 - -
1036 - EEO_NEXT(); -
1037 - } -
1038 - -
1039 - /* -
1040 - * If any of its clauses is FALSE, an AND's result is FALSE regardless -
1041 - * of the states of the rest of the clauses, so we can stop evaluating -
1042 - * and return FALSE immediately. If none are FALSE and one or more is -
1043 - * NULL, we return NULL; otherwise we return TRUE. This makes sense -
1044 - * when you interpret NULL as "don't know": perhaps one of the "don't -
1045 - * knows" would have been FALSE if we'd known its value. Only when -
1046 - * all the inputs are known to be TRUE can we state confidently that -
1047 - * the AND's result is TRUE. -
1048 - */ -
1049 - EEO_CASE(EEOP_BOOL_AND_STEP_FIRST) -
1050 - { -
1051 - *op->d.boolexpr.anynull = false; -
1052 - -
1053 - /* -
1054 - * EEOP_BOOL_AND_STEP_FIRST resets anynull, otherwise it's the -
1055 - * same as EEOP_BOOL_AND_STEP - so fall through to that. -
1056 - */ -
1057 - -
1058 - /* FALL THROUGH */ -
1059 - } -
1060 - -
1061 - EEO_CASE(EEOP_BOOL_AND_STEP) -
1062 - { -
1063 - if (*op->resnull) -
1064 - { -
1065 - *op->d.boolexpr.anynull = true; -
1066 - } -
1067 - else if (!DatumGetBool(*op->resvalue)) -
1068 - { -
1069 - /* result is already set to FALSE, need not change it */ -
1070 - /* bail out early */ -
1071 - EEO_JUMP(op->d.boolexpr.jumpdone); -
1072 - } -
1073 - -
1074 - EEO_NEXT(); -
1075 - } -
1076 - -
1077 - EEO_CASE(EEOP_BOOL_AND_STEP_LAST) -
1078 - { -
1079 - if (*op->resnull) -
1080 - { -
1081 - /* result is already set to NULL, need not change it */ -
1082 - } -
1083 - else if (!DatumGetBool(*op->resvalue)) -
1084 - { -
1085 - /* result is already set to FALSE, need not change it */ -
1086 - -
1087 - /* -
1088 - * No point jumping early to jumpdone - would be same target -
1089 - * (as this is the last argument to the AND expression), -
1090 - * except more expensive. -
1091 - */ -
1092 - } -
1093 - else if (*op->d.boolexpr.anynull) -
1094 - { -
1095 - *op->resvalue = (Datum) 0; -
1096 - *op->resnull = true; -
1097 - } -
1098 - else -
1099 - { -
1100 - /* result is already set to TRUE, need not change it */ -
1101 - } -
1102 - -
1103 - EEO_NEXT(); -
1104 - } -
1105 - -
1106 - /* -
1107 - * If any of its clauses is TRUE, an OR's result is TRUE regardless of -
1108 - * the states of the rest of the clauses, so we can stop evaluating -
1109 - * and return TRUE immediately. If none are TRUE and one or more is -
1110 - * NULL, we return NULL; otherwise we return FALSE. This makes sense -
1111 - * when you interpret NULL as "don't know": perhaps one of the "don't -
1112 - * knows" would have been TRUE if we'd known its value. Only when all -
1113 - * the inputs are known to be FALSE can we state confidently that the -
1114 - * OR's result is FALSE. -
1115 - */ -
1116 - EEO_CASE(EEOP_BOOL_OR_STEP_FIRST) -
1117 - { -
1118 - *op->d.boolexpr.anynull = false; -
1119 - -
1120 - /* -
1121 - * EEOP_BOOL_OR_STEP_FIRST resets anynull, otherwise it's the same -
1122 - * as EEOP_BOOL_OR_STEP - so fall through to that. -
1123 - */ -
1124 - -
1125 - /* FALL THROUGH */ -
1126 - } -
1127 - -
1128 - EEO_CASE(EEOP_BOOL_OR_STEP) -
1129 - { -
1130 - if (*op->resnull) -
1131 - { -
1132 - *op->d.boolexpr.anynull = true; -
1133 - } -
1134 - else if (DatumGetBool(*op->resvalue)) -
1135 - { -
1136 - /* result is already set to TRUE, need not change it */ -
1137 - /* bail out early */ -
1138 - EEO_JUMP(op->d.boolexpr.jumpdone); -
1139 - } -
1140 - -
1141 - EEO_NEXT(); -
1142 - } -
1143 - -
1144 - EEO_CASE(EEOP_BOOL_OR_STEP_LAST) -
1145 - { -
1146 - if (*op->resnull) -
1147 - { -
1148 - /* result is already set to NULL, need not change it */ -
1149 - } -
1150 - else if (DatumGetBool(*op->resvalue)) -
1151 - { -
1152 - /* result is already set to TRUE, need not change it */ -
1153 - -
1154 - /* -
1155 - * No point jumping to jumpdone - would be same target (as -
1156 - * this is the last argument to the AND expression), except -
1157 - * more expensive. -
1158 - */ -
1159 - } -
1160 - else if (*op->d.boolexpr.anynull) -
1161 - { -
1162 - *op->resvalue = (Datum) 0; -
1163 - *op->resnull = true; -
1164 - } -
1165 - else -
1166 - { -
1167 - /* result is already set to FALSE, need not change it */ -
1168 - } -
1169 - -
1170 - EEO_NEXT(); -
1171 - } -
1172 - -
1173 - EEO_CASE(EEOP_BOOL_NOT_STEP) -
1174 - { -
1175 - /* -
1176 - * Evaluation of 'not' is simple... if expr is false, then return -
1177 - * 'true' and vice versa. It's safe to do this even on a -
1178 - * nominally null value, so we ignore resnull; that means that -
1179 - * NULL in produces NULL out, which is what we want. -
1180 - */ -
1181 - *op->resvalue = BoolGetDatum(!DatumGetBool(*op->resvalue)); -
1182 - -
1183 - EEO_NEXT(); -
1184 - } -
1185 - -
1186 - EEO_CASE(EEOP_QUAL) -
1187 - { -
1188 - /* simplified version of BOOL_AND_STEP for use by ExecQual() */ -
1189 - -
1190 - /* If argument (also result) is false or null ... */ -
1191 - if (*op->resnull || -
1192 - !DatumGetBool(*op->resvalue)) -
1193 - { -
1194 - /* ... bail out early, returning FALSE */ -
1195 - *op->resnull = false; -
1196 - *op->resvalue = BoolGetDatum(false); -
1197 - EEO_JUMP(op->d.qualexpr.jumpdone); -
1198 - } -
1199 - -
1200 - /* -
1201 - * Otherwise, leave the TRUE value in place, in case this is the -
1202 - * last qual. Then, TRUE is the correct answer. -
1203 - */ -
1204 - -
1205 - EEO_NEXT(); -
1206 - } -
1207 - -
1208 - EEO_CASE(EEOP_JUMP) -
1209 - { -
1210 - /* Unconditionally jump to target step */ -
1211 - EEO_JUMP(op->d.jump.jumpdone); -
1212 - } -
1213 - -
1214 - EEO_CASE(EEOP_JUMP_IF_NULL) -
1215 - { -
1216 - /* Transfer control if current result is null */ -
1217 - if (*op->resnull) -
1218 - EEO_JUMP(op->d.jump.jumpdone); -
1219 - -
1220 - EEO_NEXT(); -
1221 - } -
1222 - -
1223 - EEO_CASE(EEOP_JUMP_IF_NOT_NULL) -
1224 - { -
1225 - /* Transfer control if current result is non-null */ -
1226 - if (!*op->resnull) -
1227 - EEO_JUMP(op->d.jump.jumpdone); -
1228 - -
1229 - EEO_NEXT(); -
1230 - } -
1231 - -
1232 - EEO_CASE(EEOP_JUMP_IF_NOT_TRUE) -
1233 - { -
1234 - /* Transfer control if current result is null or false */ -
1235 - if (*op->resnull || !DatumGetBool(*op->resvalue)) -
1236 - EEO_JUMP(op->d.jump.jumpdone); -
1237 - -
1238 - EEO_NEXT(); -
1239 - } -
1240 - -
1241 - EEO_CASE(EEOP_NULLTEST_ISNULL) -
1242 - { -
1243 - *op->resvalue = BoolGetDatum(*op->resnull); -
1244 - *op->resnull = false; -
1245 - -
1246 - EEO_NEXT(); -
1247 - } -
1248 - -
1249 - EEO_CASE(EEOP_NULLTEST_ISNOTNULL) -
1250 - { -
1251 - *op->resvalue = BoolGetDatum(!*op->resnull); -
1252 - *op->resnull = false; -
1253 - -
1254 - EEO_NEXT(); -
1255 - } -
1256 - -
1257 - EEO_CASE(EEOP_NULLTEST_ROWISNULL) -
1258 - { -
1259 - /* out of line implementation: too large */ -
1260 - ExecEvalRowNull(state, op, econtext); -
1261 - -
1262 - EEO_NEXT(); -
1263 - } -
1264 - -
1265 - EEO_CASE(EEOP_NULLTEST_ROWISNOTNULL) -
1266 - { -
1267 - /* out of line implementation: too large */ -
1268 - ExecEvalRowNotNull(state, op, econtext); -
1269 - -
1270 - EEO_NEXT(); -
1271 - } -
1272 - -
1273 - /* BooleanTest implementations for all booltesttypes */ -
1274 - -
1275 - EEO_CASE(EEOP_BOOLTEST_IS_TRUE) -
1276 - { -
1277 - if (*op->resnull) -
1278 - { -
1279 - *op->resvalue = BoolGetDatum(false); -
1280 - *op->resnull = false; -
1281 - } -
1282 - /* else, input value is the correct output as well */ -
1283 - -
1284 - EEO_NEXT(); -
1285 - } -
1286 - -
1287 - EEO_CASE(EEOP_BOOLTEST_IS_NOT_TRUE) -
1288 - { -
1289 - if (*op->resnull) -
1290 - { -
1291 - *op->resvalue = BoolGetDatum(true); -
1292 - *op->resnull = false; -
1293 - } -
1294 - else -
1295 - *op->resvalue = BoolGetDatum(!DatumGetBool(*op->resvalue)); -
1296 - -
1297 - EEO_NEXT(); -
1298 - } -
1299 - -
1300 - EEO_CASE(EEOP_BOOLTEST_IS_FALSE) -
1301 - { -
1302 - if (*op->resnull) -
1303 - { -
1304 - *op->resvalue = BoolGetDatum(false); -
1305 - *op->resnull = false; -
1306 - } -
1307 - else -
1308 - *op->resvalue = BoolGetDatum(!DatumGetBool(*op->resvalue)); -
1309 - -
1310 - EEO_NEXT(); -
1311 - } -
1312 - -
1313 - EEO_CASE(EEOP_BOOLTEST_IS_NOT_FALSE) -
1314 - { -
1315 - if (*op->resnull) -
1316 - { -
1317 - *op->resvalue = BoolGetDatum(true); -
1318 - *op->resnull = false; -
1319 - } -
1320 - /* else, input value is the correct output as well */ -
1321 - -
1322 - EEO_NEXT(); -
1323 - } -
1324 - -
1325 - EEO_CASE(EEOP_PARAM_EXEC) -
1326 - { -
1327 - /* out of line implementation: too large */ -
1328 - ExecEvalParamExec(state, op, econtext); -
1329 - -
1330 - EEO_NEXT(); -
1331 - } -
1332 - -
1333 - EEO_CASE(EEOP_PARAM_EXTERN) -
1334 - { -
1335 - /* out of line implementation: too large */ -
1336 - ExecEvalParamExtern(state, op, econtext); -
1337 - EEO_NEXT(); -
1338 - } -
1339 - -
1340 - EEO_CASE(EEOP_PARAM_CALLBACK) -
1341 - { -
1342 - /* allow an extension module to supply a PARAM_EXTERN value */ -
1343 - op->d.cparam.paramfunc(state, op, econtext); -
1344 - EEO_NEXT(); -
1345 - } -
1346 - -
1347 - EEO_CASE(EEOP_PARAM_SET) -
1348 - { -
1349 - /* out of line, unlikely to matter performance-wise */ -
1350 - ExecEvalParamSet(state, op, econtext); -
1351 - EEO_NEXT(); -
1352 - } -
1353 - -
1354 - EEO_CASE(EEOP_CASE_TESTVAL) -
1355 - { -
1356 - *op->resvalue = *op->d.casetest.value; -
1357 - *op->resnull = *op->d.casetest.isnull; -
1358 - -
1359 - EEO_NEXT(); -
1360 - } -
1361 - -
1362 - EEO_CASE(EEOP_CASE_TESTVAL_EXT) -
1363 - { -
1364 - *op->resvalue = econtext->caseValue_datum; -
1365 - *op->resnull = econtext->caseValue_isNull; -
1366 - -
1367 - EEO_NEXT(); -
1368 - } -
1369 - -
1370 - EEO_CASE(EEOP_MAKE_READONLY) -
1371 - { -
1372 - /* -
1373 - * Force a varlena value that might be read multiple times to R/O -
1374 - */ -
1375 - if (!*op->d.make_readonly.isnull) -
1376 - *op->resvalue = -
1377 - MakeExpandedObjectReadOnlyInternal(*op->d.make_readonly.value); -
1378 - *op->resnull = *op->d.make_readonly.isnull; -
1379 - -
1380 - EEO_NEXT(); -
1381 - } -
1382 - -
1383 - EEO_CASE(EEOP_IOCOERCE) -
1384 - { -
1385 - /* -
1386 - * Evaluate a CoerceViaIO node. This can be quite a hot path, so -
1387 - * inline as much work as possible. The source value is in our -
1388 - * result variable. -
1389 - * -
1390 - * Also look at ExecEvalCoerceViaIOSafe() if you change anything -
1391 - * here. -
1392 - */ -
1393 - char *str; -
1394 - -
1395 - /* call output function (similar to OutputFunctionCall) */ -
1396 - if (*op->resnull) -
1397 - { -
1398 - /* output functions are not called on nulls */ -
1399 - str = NULL; -
1400 - } -
1401 - else -
1402 - { -
1403 - FunctionCallInfo fcinfo_out; -
1404 - -
1405 - fcinfo_out = op->d.iocoerce.fcinfo_data_out; -
1406 - fcinfo_out->args[0].value = *op->resvalue; -
1407 - fcinfo_out->args[0].isnull = false; -
1408 - -
1409 - fcinfo_out->isnull = false; -
1410 - str = DatumGetCString(FunctionCallInvoke(fcinfo_out)); -
1411 - -
1412 - /* OutputFunctionCall assumes result isn't null */ -
1413 - Assert(!fcinfo_out->isnull); -
1414 - } -
1415 - -
1416 - /* call input function (similar to InputFunctionCall) */ -
1417 - if (!op->d.iocoerce.finfo_in->fn_strict || str != NULL) -
1418 - { -
1419 - FunctionCallInfo fcinfo_in; -
1420 - Datum d; -
1421 - -
1422 - fcinfo_in = op->d.iocoerce.fcinfo_data_in; -
1423 - fcinfo_in->args[0].value = PointerGetDatum(str); -
1424 - fcinfo_in->args[0].isnull = *op->resnull; -
1425 - /* second and third arguments are already set up */ -
1426 - -
1427 - fcinfo_in->isnull = false; -
1428 - d = FunctionCallInvoke(fcinfo_in); -
1429 - *op->resvalue = d; -
1430 - -
1431 - /* Should get null result if and only if str is NULL */ -
1432 - if (str == NULL) -
1433 - { -
1434 - Assert(*op->resnull); -
1435 - Assert(fcinfo_in->isnull); -
1436 - } -
1437 - else -
1438 - { -
1439 - Assert(!*op->resnull); -
1440 - Assert(!fcinfo_in->isnull); -
1441 - } -
1442 - } -
1443 - -
1444 - EEO_NEXT(); -
1445 - } -
1446 - -
1447 - EEO_CASE(EEOP_IOCOERCE_SAFE) -
1448 - { -
1449 - ExecEvalCoerceViaIOSafe(state, op); -
1450 - EEO_NEXT(); -
1451 - } -
1452 - -
1453 - EEO_CASE(EEOP_DISTINCT) -
1454 - { -
1455 - /* -
1456 - * IS DISTINCT FROM must evaluate arguments (already done into -
1457 - * fcinfo->args) to determine whether they are NULL; if either is -
1458 - * NULL then the result is determined. If neither is NULL, then -
1459 - * proceed to evaluate the comparison function, which is just the -
1460 - * type's standard equality operator. We need not care whether -
1461 - * that function is strict. Because the handling of nulls is -
1462 - * different, we can't just reuse EEOP_FUNCEXPR. -
1463 - */ -
1464 - FunctionCallInfo fcinfo = op->d.func.fcinfo_data; -
1465 - -
1466 - /* check function arguments for NULLness */ -
1467 - if (fcinfo->args[0].isnull && fcinfo->args[1].isnull) -
1468 - { -
1469 - /* Both NULL? Then is not distinct... */ -
1470 - *op->resvalue = BoolGetDatum(false); -
1471 - *op->resnull = false; -
1472 - } -
1473 - else if (fcinfo->args[0].isnull || fcinfo->args[1].isnull) -
1474 - { -
1475 - /* Only one is NULL? Then is distinct... */ -
1476 - *op->resvalue = BoolGetDatum(true); -
1477 - *op->resnull = false; -
1478 - } -
1479 - else -
1480 - { -
1481 - /* Neither null, so apply the equality function */ -
1482 - Datum eqresult; -
1483 - -
1484 - fcinfo->isnull = false; -
1485 - eqresult = op->d.func.fn_addr(fcinfo); -
1486 - /* Must invert result of "="; safe to do even if null */ -
1487 - *op->resvalue = BoolGetDatum(!DatumGetBool(eqresult)); -
1488 - *op->resnull = fcinfo->isnull; -
1489 - } -
1490 - -
1491 - EEO_NEXT(); -
1492 - } -
1493 - -
1494 - /* see EEOP_DISTINCT for comments, this is just inverted */ -
1495 - EEO_CASE(EEOP_NOT_DISTINCT) -
1496 - { -
1497 - FunctionCallInfo fcinfo = op->d.func.fcinfo_data; -
1498 - -
1499 - if (fcinfo->args[0].isnull && fcinfo->args[1].isnull) -
1500 - { -
1501 - *op->resvalue = BoolGetDatum(true); -
1502 - *op->resnull = false; -
1503 - } -
1504 - else if (fcinfo->args[0].isnull || fcinfo->args[1].isnull) -
1505 - { -
1506 - *op->resvalue = BoolGetDatum(false); -
1507 - *op->resnull = false; -
1508 - } -
1509 - else -
1510 - { -
1511 - Datum eqresult; -
1512 - -
1513 - fcinfo->isnull = false; -
1514 - eqresult = op->d.func.fn_addr(fcinfo); -
1515 - *op->resvalue = eqresult; -
1516 - *op->resnull = fcinfo->isnull; -
1517 - } -
1518 - -
1519 - EEO_NEXT(); -
1520 - } -
1521 - -
1522 - EEO_CASE(EEOP_NULLIF) -
1523 - { -
1524 - /* -
1525 - * The arguments are already evaluated into fcinfo->args. -
1526 - */ -
1527 - FunctionCallInfo fcinfo = op->d.func.fcinfo_data; -
1528 - Datum save_arg0 = fcinfo->args[0].value; -
1529 - -
1530 - /* if either argument is NULL they can't be equal */ -
1531 - if (!fcinfo->args[0].isnull && !fcinfo->args[1].isnull) -
1532 - { -
1533 - Datum result; -
1534 - -
1535 - /* -
1536 - * If first argument is of varlena type, it might be an -
1537 - * expanded datum. We need to ensure that the value passed to -
1538 - * the comparison function is a read-only pointer. However, -
1539 - * if we end by returning the first argument, that will be the -
1540 - * original read-write pointer if it was read-write. -
1541 - */ -
1542 - if (op->d.func.make_ro) -
1543 - fcinfo->args[0].value = -
1544 - MakeExpandedObjectReadOnlyInternal(save_arg0); -
1545 - -
1546 - fcinfo->isnull = false; -
1547 - result = op->d.func.fn_addr(fcinfo); -
1548 - -
1549 - /* if the arguments are equal return null */ -
1550 - if (!fcinfo->isnull && DatumGetBool(result)) -
1551 - { -
1552 - *op->resvalue = (Datum) 0; -
1553 - *op->resnull = true; -
1554 - -
1555 - EEO_NEXT(); -
1556 - } -
1557 - } -
1558 - -
1559 - /* Arguments aren't equal, so return the first one */ -
1560 - *op->resvalue = save_arg0; -
1561 - *op->resnull = fcinfo->args[0].isnull; -
1562 - -
1563 - EEO_NEXT(); -
1564 - } -
1565 - -
1566 - EEO_CASE(EEOP_SQLVALUEFUNCTION) -
1567 - { -
1568 - /* -
1569 - * Doesn't seem worthwhile to have an inline implementation -
1570 - * efficiency-wise. -
1571 - */ -
1572 - ExecEvalSQLValueFunction(state, op); -
1573 - -
1574 - EEO_NEXT(); -
1575 - } -
1576 - -
1577 - EEO_CASE(EEOP_CURRENTOFEXPR) -
1578 - { -
1579 - /* error invocation uses space, and shouldn't ever occur */ -
1580 - ExecEvalCurrentOfExpr(state, op); -
1581 - -
1582 - EEO_NEXT(); -
1583 - } -
1584 - -
1585 - EEO_CASE(EEOP_NEXTVALUEEXPR) -
1586 - { -
1587 - /* -
1588 - * Doesn't seem worthwhile to have an inline implementation -
1589 - * efficiency-wise. -
1590 - */ -
1591 - ExecEvalNextValueExpr(state, op); -
1592 - -
1593 - EEO_NEXT(); -
1594 - } -
1595 - -
1596 - EEO_CASE(EEOP_RETURNINGEXPR) -
1597 - { -
1598 - /* -
1599 - * The next op actually evaluates the expression. If the OLD/NEW -
1600 - * row doesn't exist, skip that and return NULL. -
1601 - */ -
1602 - if (state->flags & op->d.returningexpr.nullflag) -
1603 - { -
1604 - *op->resvalue = (Datum) 0; -
1605 - *op->resnull = true; -
1606 - -
1607 - EEO_JUMP(op->d.returningexpr.jumpdone); -
1608 - } -
1609 - -
1610 - EEO_NEXT(); -
1611 - } -
1612 - -
1613 - EEO_CASE(EEOP_ARRAYEXPR) -
1614 - { -
1615 - /* too complex for an inline implementation */ -
1616 - ExecEvalArrayExpr(state, op); -
1617 - -
1618 - EEO_NEXT(); -
1619 - } -
1620 - -
1621 - EEO_CASE(EEOP_ARRAYCOERCE) -
1622 - { -
1623 - /* too complex for an inline implementation */ -
1624 - ExecEvalArrayCoerce(state, op, econtext); -
1625 - -
1626 - EEO_NEXT(); -
1627 - } -
1628 - -
1629 - EEO_CASE(EEOP_ROW) -
1630 - { -
1631 - /* too complex for an inline implementation */ -
1632 - ExecEvalRow(state, op); -
1633 - -
1634 - EEO_NEXT(); -
1635 - } -
1636 - -
1637 - EEO_CASE(EEOP_ROWCOMPARE_STEP) -
1638 - { -
1639 - FunctionCallInfo fcinfo = op->d.rowcompare_step.fcinfo_data; -
1640 - Datum d; -
1641 - -
1642 - /* force NULL result if strict fn and NULL input */ -
1643 - if (op->d.rowcompare_step.finfo->fn_strict && -
1644 - (fcinfo->args[0].isnull || fcinfo->args[1].isnull)) -
1645 - { -
1646 - *op->resnull = true; -
1647 - EEO_JUMP(op->d.rowcompare_step.jumpnull); -
1648 - } -
1649 - -
1650 - /* Apply comparison function */ -
1651 - fcinfo->isnull = false; -
1652 - d = op->d.rowcompare_step.fn_addr(fcinfo); -
1653 - *op->resvalue = d; -
1654 - -
1655 - /* force NULL result if NULL function result */ -
1656 - if (fcinfo->isnull) -
1657 - { -
1658 - *op->resnull = true; -
1659 - EEO_JUMP(op->d.rowcompare_step.jumpnull); -
1660 - } -
1661 - *op->resnull = false; -
1662 - -
1663 - /* If unequal, no need to compare remaining columns */ -
1664 - if (DatumGetInt32(*op->resvalue) != 0) -
1665 - { -
1666 - EEO_JUMP(op->d.rowcompare_step.jumpdone); -
1667 - } -
1668 - -
1669 - EEO_NEXT(); -
1670 - } -
1671 - -
1672 - EEO_CASE(EEOP_ROWCOMPARE_FINAL) -
1673 - { -
1674 - int32 cmpresult = DatumGetInt32(*op->resvalue); -
1675 - CompareType cmptype = op->d.rowcompare_final.cmptype; -
1676 - -
1677 - *op->resnull = false; -
1678 - switch (cmptype) -
1679 - { -
1680 - /* EQ and NE cases aren't allowed here */ -
1681 - case COMPARE_LT: -
1682 - *op->resvalue = BoolGetDatum(cmpresult < 0); -
1683 - break; -
1684 - case COMPARE_LE: -
1685 - *op->resvalue = BoolGetDatum(cmpresult <= 0); -
1686 - break; -
1687 - case COMPARE_GE: -
1688 - *op->resvalue = BoolGetDatum(cmpresult >= 0); -
1689 - break; -
1690 - case COMPARE_GT: -
1691 - *op->resvalue = BoolGetDatum(cmpresult > 0); -
1692 - break; -
1693 - default: -
1694 - Assert(false); -
1695 - break; -
1696 - } -
1697 - -
1698 - EEO_NEXT(); -
1699 - } -
1700 - -
1701 - EEO_CASE(EEOP_MINMAX) -
1702 - { -
1703 - /* too complex for an inline implementation */ -
1704 - ExecEvalMinMax(state, op); -
1705 - -
1706 - EEO_NEXT(); -
1707 - } -
1708 - -
1709 - EEO_CASE(EEOP_FIELDSELECT) -
1710 - { -
1711 - /* too complex for an inline implementation */ -
1712 - ExecEvalFieldSelect(state, op, econtext); -
1713 - -
1714 - EEO_NEXT(); -
1715 - } -
1716 - -
1717 - EEO_CASE(EEOP_FIELDSTORE_DEFORM) -
1718 - { -
1719 - /* too complex for an inline implementation */ -
1720 - ExecEvalFieldStoreDeForm(state, op, econtext); -
1721 - -
1722 - EEO_NEXT(); -
1723 - } -
1724 - -
1725 - EEO_CASE(EEOP_FIELDSTORE_FORM) -
1726 - { -
1727 - /* too complex for an inline implementation */ -
1728 - ExecEvalFieldStoreForm(state, op, econtext); -
1729 - -
1730 - EEO_NEXT(); -
1731 - } -
1732 - -
1733 - EEO_CASE(EEOP_SBSREF_SUBSCRIPTS) -
1734 - { -
1735 - /* Precheck SubscriptingRef subscript(s) */ -
1736 - if (op->d.sbsref_subscript.subscriptfunc(state, op, econtext)) -
1737 - { -
1738 - EEO_NEXT(); -
1739 - } -
1740 - else -
1741 - { -
1742 - /* Subscript is null, short-circuit SubscriptingRef to NULL */ -
1743 - EEO_JUMP(op->d.sbsref_subscript.jumpdone); -
1744 - } -
1745 - } -
1746 - -
1747 - EEO_CASE(EEOP_SBSREF_OLD) -
1748 - EEO_CASE(EEOP_SBSREF_ASSIGN) -
1749 - EEO_CASE(EEOP_SBSREF_FETCH) -
1750 - { -
1751 - /* Perform a SubscriptingRef fetch or assignment */ -
1752 - op->d.sbsref.subscriptfunc(state, op, econtext); -
1753 - -
1754 - EEO_NEXT(); -
1755 - } -
1756 - -
1757 - EEO_CASE(EEOP_CONVERT_ROWTYPE) -
1758 - { -
1759 - /* too complex for an inline implementation */ -
1760 - ExecEvalConvertRowtype(state, op, econtext); -
1761 - -
1762 - EEO_NEXT(); -
1763 - } -
1764 - -
1765 - EEO_CASE(EEOP_SCALARARRAYOP) -
1766 - { -
1767 - /* too complex for an inline implementation */ -
1768 - ExecEvalScalarArrayOp(state, op); -
1769 - -
1770 - EEO_NEXT(); -
1771 - } -
1772 - -
1773 - EEO_CASE(EEOP_HASHED_SCALARARRAYOP) -
1774 - { -
1775 - /* too complex for an inline implementation */ -
1776 - ExecEvalHashedScalarArrayOp(state, op, econtext); -
1777 - -
1778 - EEO_NEXT(); -
1779 - } -
1780 - -
1781 - EEO_CASE(EEOP_DOMAIN_TESTVAL) -
1782 - { -
1783 - *op->resvalue = *op->d.casetest.value; -
1784 - *op->resnull = *op->d.casetest.isnull; -
1785 - -
1786 - EEO_NEXT(); -
1787 - } -
1788 - -
1789 - EEO_CASE(EEOP_DOMAIN_TESTVAL_EXT) -
1790 - { -
1791 - *op->resvalue = econtext->domainValue_datum; -
1792 - *op->resnull = econtext->domainValue_isNull; -
1793 - -
1794 - EEO_NEXT(); -
1795 - } -
1796 - -
1797 - EEO_CASE(EEOP_DOMAIN_NOTNULL) -
1798 - { -
1799 - /* too complex for an inline implementation */ -
1800 - ExecEvalConstraintNotNull(state, op); -
1801 - -
1802 - EEO_NEXT(); -
1803 - } -
1804 - -
1805 - EEO_CASE(EEOP_DOMAIN_CHECK) -
1806 - { -
1807 - /* too complex for an inline implementation */ -
1808 - ExecEvalConstraintCheck(state, op); -
1809 - -
1810 - EEO_NEXT(); -
1811 - } -
1812 - -
1813 - EEO_CASE(EEOP_HASHDATUM_SET_INITVAL) -
1814 - { -
1815 - *op->resvalue = op->d.hashdatum_initvalue.init_value; -
1816 - *op->resnull = false; -
1817 - -
1818 - EEO_NEXT(); -
1819 - } -
1820 - -
1821 - EEO_CASE(EEOP_HASHDATUM_FIRST) -
1822 - { -
1823 - FunctionCallInfo fcinfo = op->d.hashdatum.fcinfo_data; -
1824 - -
1825 - /* -
1826 - * Save the Datum on non-null inputs, otherwise store 0 so that -
1827 - * subsequent NEXT32 operations combine with an initialized value. -
1828 - */ -
1829 - if (!fcinfo->args[0].isnull) -
1830 - *op->resvalue = op->d.hashdatum.fn_addr(fcinfo); -
1831 - else -
1832 - *op->resvalue = (Datum) 0; -
1833 - -
1834 - *op->resnull = false; -
1835 - -
1836 - EEO_NEXT(); -
1837 - } -
1838 - -
1839 - EEO_CASE(EEOP_HASHDATUM_FIRST_STRICT) -
1840 - { -
1841 - FunctionCallInfo fcinfo = op->d.hashdatum.fcinfo_data; -
1842 - -
1843 - if (fcinfo->args[0].isnull) -
1844 - { -
1845 - /* -
1846 - * With strict we have the expression return NULL instead of -
1847 - * ignoring NULL input values. We've nothing more to do after -
1848 - * finding a NULL. -
1849 - */ -
1850 - *op->resnull = true; -
1851 - *op->resvalue = (Datum) 0; -
1852 - EEO_JUMP(op->d.hashdatum.jumpdone); -
1853 - } -
1854 - -
1855 - /* execute the hash function and save the resulting value */ -
1856 - *op->resvalue = op->d.hashdatum.fn_addr(fcinfo); -
1857 - *op->resnull = false; -
1858 - -
1859 - EEO_NEXT(); -
1860 - } -
1861 - -
1862 - EEO_CASE(EEOP_HASHDATUM_NEXT32) -
1863 - { -
1864 - FunctionCallInfo fcinfo = op->d.hashdatum.fcinfo_data; -
1865 - uint32 existinghash; -
1866 - -
1867 - existinghash = DatumGetUInt32(op->d.hashdatum.iresult->value); -
1868 - /* combine successive hash values by rotating */ -
1869 - existinghash = pg_rotate_left32(existinghash, 1); -
1870 - -
1871 - /* leave the hash value alone on NULL inputs */ -
1872 - if (!fcinfo->args[0].isnull) -
1873 - { -
1874 - uint32 hashvalue; -
1875 - -
1876 - /* execute hash func and combine with previous hash value */ -
1877 - hashvalue = DatumGetUInt32(op->d.hashdatum.fn_addr(fcinfo)); -
1878 - existinghash = existinghash ^ hashvalue; -
1879 - } -
1880 - -
1881 - *op->resvalue = UInt32GetDatum(existinghash); -
1882 - *op->resnull = false; -
1883 - -
1884 - EEO_NEXT(); -
1885 - } -
1886 - -
1887 - EEO_CASE(EEOP_HASHDATUM_NEXT32_STRICT) -
1888 - { -
1889 - FunctionCallInfo fcinfo = op->d.hashdatum.fcinfo_data; -
1890 - -
1891 - if (fcinfo->args[0].isnull) -
1892 - { -
1893 - /* -
1894 - * With strict we have the expression return NULL instead of -
1895 - * ignoring NULL input values. We've nothing more to do after -
1896 - * finding a NULL. -
1897 - */ -
1898 - *op->resnull = true; -
1899 - *op->resvalue = (Datum) 0; -
1900 - EEO_JUMP(op->d.hashdatum.jumpdone); -
1901 - } -
1902 - else -
1903 - { -
1904 - uint32 existinghash; -
1905 - uint32 hashvalue; -
1906 - -
1907 - existinghash = DatumGetUInt32(op->d.hashdatum.iresult->value); -
1908 - /* combine successive hash values by rotating */ -
1909 - existinghash = pg_rotate_left32(existinghash, 1); -
1910 - -
1911 - /* execute hash func and combine with previous hash value */ -
1912 - hashvalue = DatumGetUInt32(op->d.hashdatum.fn_addr(fcinfo)); -
1913 - *op->resvalue = UInt32GetDatum(existinghash ^ hashvalue); -
1914 - *op->resnull = false; -
1915 - } -
1916 - -
1917 - EEO_NEXT(); -
1918 - } -
1919 - -
1920 - EEO_CASE(EEOP_XMLEXPR) -
1921 - { -
1922 - /* too complex for an inline implementation */ -
1923 - ExecEvalXmlExpr(state, op); -
1924 - -
1925 - EEO_NEXT(); -
1926 - } -
1927 - -
1928 - EEO_CASE(EEOP_JSON_CONSTRUCTOR) -
1929 - { -
1930 - /* too complex for an inline implementation */ -
1931 - ExecEvalJsonConstructor(state, op, econtext); -
1932 - EEO_NEXT(); -
1933 - } -
1934 - -
1935 - EEO_CASE(EEOP_IS_JSON) -
1936 - { -
1937 - /* too complex for an inline implementation */ -
1938 - ExecEvalJsonIsPredicate(state, op); -
1939 - -
1940 - EEO_NEXT(); -
1941 - } -
1942 - -
1943 - EEO_CASE(EEOP_JSONEXPR_PATH) -
1944 - { -
1945 - /* too complex for an inline implementation */ -
1946 - EEO_JUMP(ExecEvalJsonExprPath(state, op, econtext)); -
1947 - } -
1948 - -
1949 - EEO_CASE(EEOP_JSONEXPR_COERCION) -
1950 - { -
1951 - /* too complex for an inline implementation */ -
1952 - ExecEvalJsonCoercion(state, op, econtext); -
1953 - -
1954 - EEO_NEXT(); -
1955 - } -
1956 - -
1957 - EEO_CASE(EEOP_JSONEXPR_COERCION_FINISH) -
1958 - { -
1959 - /* too complex for an inline implementation */ -
1960 - ExecEvalJsonCoercionFinish(state, op); -
1961 - -
1962 - EEO_NEXT(); -
1963 - } -
1964 - -
1965 - EEO_CASE(EEOP_AGGREF) -
1966 - { -
1967 - /* -
1968 - * Returns a Datum whose value is the precomputed aggregate value -
1969 - * found in the given expression context. -
1970 - */ -
1971 - int aggno = op->d.aggref.aggno; -
1972 - -
1973 - Assert(econtext->ecxt_aggvalues != NULL); -
1974 - -
1975 - *op->resvalue = econtext->ecxt_aggvalues[aggno]; -
1976 - *op->resnull = econtext->ecxt_aggnulls[aggno]; -
1977 - -
1978 - EEO_NEXT(); -
1979 - } -
1980 - -
1981 - EEO_CASE(EEOP_GROUPING_FUNC) -
1982 - { -
1983 - /* too complex/uncommon for an inline implementation */ -
1984 - ExecEvalGroupingFunc(state, op); -
1985 - -
1986 - EEO_NEXT(); -
1987 - } -
1988 - -
1989 - EEO_CASE(EEOP_WINDOW_FUNC) -
1990 - { -
1991 - /* -
1992 - * Like Aggref, just return a precomputed value from the econtext. -
1993 - */ -
1994 - WindowFuncExprState *wfunc = op->d.window_func.wfstate; -
1995 - -
1996 - Assert(econtext->ecxt_aggvalues != NULL); -
1997 - -
1998 - *op->resvalue = econtext->ecxt_aggvalues[wfunc->wfuncno]; -
1999 - *op->resnull = econtext->ecxt_aggnulls[wfunc->wfuncno]; -
2000 - -
2001 - EEO_NEXT(); -
2002 - } -
2003 - -
2004 - EEO_CASE(EEOP_MERGE_SUPPORT_FUNC) -
2005 - { -
2006 - /* too complex/uncommon for an inline implementation */ -
2007 - ExecEvalMergeSupportFunc(state, op, econtext); -
2008 - -
2009 - EEO_NEXT(); -
2010 - } -
2011 - -
2012 - EEO_CASE(EEOP_SUBPLAN) -
2013 - { -
2014 - /* too complex for an inline implementation */ -
2015 - ExecEvalSubPlan(state, op, econtext); -
2016 - -
2017 - EEO_NEXT(); -
2018 - } -
2019 - -
2020 - /* RPR navigation: swap slot to target row */ 24cfb8dRow pattern recognition patch (executor and commands).
2021 176296 EEO_CASE(EEOP_RPR_NAV_SET) 24cfb8dRow pattern recognition patch (executor and commands).
2022 - { 24cfb8dRow pattern recognition patch (executor and commands).
2023 176296 ExecEvalRPRNavSet(state, op, econtext); 24cfb8dRow pattern recognition patch (executor and commands).
2024 176232 outerslot = econtext->ecxt_outertuple; 24cfb8dRow pattern recognition patch (executor and commands).
2025 - 24cfb8dRow pattern recognition patch (executor and commands).
2026 176232 EEO_NEXT(); 24cfb8dRow pattern recognition patch (executor and commands).
2027 - } 24cfb8dRow pattern recognition patch (executor and commands).
2028 - 24cfb8dRow pattern recognition patch (executor and commands).
2029 - /* RPR navigation: restore slot to original row */ 24cfb8dRow pattern recognition patch (executor and commands).
2030 176232 EEO_CASE(EEOP_RPR_NAV_RESTORE) 24cfb8dRow pattern recognition patch (executor and commands).
2031 - { 24cfb8dRow pattern recognition patch (executor and commands).
2032 176232 ExecEvalRPRNavRestore(state, op, econtext); 24cfb8dRow pattern recognition patch (executor and commands).
2033 176232 outerslot = econtext->ecxt_outertuple; 24cfb8dRow pattern recognition patch (executor and commands).
2034 - 24cfb8dRow pattern recognition patch (executor and commands).
2035 176232 EEO_NEXT(); 24cfb8dRow pattern recognition patch (executor and commands).
2036 - } 24cfb8dRow pattern recognition patch (executor and commands).
2037 - 24cfb8dRow pattern recognition patch (executor and commands).
2038 - /* evaluate a strict aggregate deserialization function */ -
2039 - EEO_CASE(EEOP_AGG_STRICT_DESERIALIZE) -
2040 - { -
2041 - /* Don't call a strict deserialization function with NULL input */ -
2042 - if (op->d.agg_deserialize.fcinfo_data->args[0].isnull) -
2043 - EEO_JUMP(op->d.agg_deserialize.jumpnull); -
2044 - -
2045 - /* fallthrough */ -
2046 - } -
2047 - -
2048 - /* evaluate aggregate deserialization function (non-strict portion) */ -
2049 - EEO_CASE(EEOP_AGG_DESERIALIZE) -
2050 - { -
2051 - FunctionCallInfo fcinfo = op->d.agg_deserialize.fcinfo_data; -
2052 - AggState *aggstate = castNode(AggState, state->parent); -
2053 - MemoryContext oldContext; -
2054 - -
2055 - /* -
2056 - * We run the deserialization functions in per-input-tuple memory -
2057 - * context. -
2058 - */ -
2059 - oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory); -
2060 - fcinfo->isnull = false; -
2061 - *op->resvalue = FunctionCallInvoke(fcinfo); -
2062 - *op->resnull = fcinfo->isnull; -
2063 - MemoryContextSwitchTo(oldContext); -
2064 - -
2065 - EEO_NEXT(); -
2066 - } -
2067 - -
2068 - /* -
2069 - * Check that a strict aggregate transition / combination function's -
2070 - * input is not NULL. -
2071 - */ -
2072 - -
2073 - /* when checking more than one argument */ -
2074 - EEO_CASE(EEOP_AGG_STRICT_INPUT_CHECK_ARGS) -
2075 - { -
2076 - NullableDatum *args = op->d.agg_strict_input_check.args; -
2077 - int nargs = op->d.agg_strict_input_check.nargs; -
2078 - -
2079 - Assert(nargs > 1); -
2080 - -
2081 - for (int argno = 0; argno < nargs; argno++) -
2082 - { -
2083 - if (args[argno].isnull) -
2084 - EEO_JUMP(op->d.agg_strict_input_check.jumpnull); -
2085 - } -
2086 - EEO_NEXT(); -
2087 - } -
2088 - -
2089 - /* special case for just one argument */ -
2090 - EEO_CASE(EEOP_AGG_STRICT_INPUT_CHECK_ARGS_1) -
2091 - { -
2092 - NullableDatum *args = op->d.agg_strict_input_check.args; -
2093 - PG_USED_FOR_ASSERTS_ONLY int nargs = op->d.agg_strict_input_check.nargs; -
2094 - -
2095 - Assert(nargs == 1); -
2096 - -
2097 - if (args[0].isnull) -
2098 - EEO_JUMP(op->d.agg_strict_input_check.jumpnull); -
2099 - EEO_NEXT(); -
2100 - } -
2101 - -
2102 - EEO_CASE(EEOP_AGG_STRICT_INPUT_CHECK_NULLS) -
2103 - { -
2104 - bool *nulls = op->d.agg_strict_input_check.nulls; -
2105 - int nargs = op->d.agg_strict_input_check.nargs; -
2106 - -
2107 - for (int argno = 0; argno < nargs; argno++) -
2108 - { -
2109 - if (nulls[argno]) -
2110 - EEO_JUMP(op->d.agg_strict_input_check.jumpnull); -
2111 - } -
2112 - EEO_NEXT(); -
2113 - } -
2114 - -
2115 - /* -
2116 - * Check for a NULL pointer to the per-group states. -
2117 - */ -
2118 - -
2119 - EEO_CASE(EEOP_AGG_PLAIN_PERGROUP_NULLCHECK) -
2120 - { -
2121 - AggState *aggstate = castNode(AggState, state->parent); -
2122 - AggStatePerGroup pergroup_allaggs = -
2123 - aggstate->all_pergroups[op->d.agg_plain_pergroup_nullcheck.setoff]; -
2124 - -
2125 - if (pergroup_allaggs == NULL) -
2126 - EEO_JUMP(op->d.agg_plain_pergroup_nullcheck.jumpnull); -
2127 - -
2128 - EEO_NEXT(); -
2129 - } -
2130 - -
2131 - /* -
2132 - * Different types of aggregate transition functions are implemented -
2133 - * as different types of steps, to avoid incurring unnecessary -
2134 - * overhead. There's a step type for each valid combination of having -
2135 - * a by value / by reference transition type, [not] needing to the -
2136 - * initialize the transition value for the first row in a group from -
2137 - * input, and [not] strict transition function. -
2138 - * -
2139 - * Could optimize further by splitting off by-reference for -
2140 - * fixed-length types, but currently that doesn't seem worth it. -
2141 - */ -
2142 - -
2143 - EEO_CASE(EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL) -
2144 - { -
2145 - AggState *aggstate = castNode(AggState, state->parent); -
2146 - AggStatePerTrans pertrans = op->d.agg_trans.pertrans; -
2147 - AggStatePerGroup pergroup = -
2148 - &aggstate->all_pergroups[op->d.agg_trans.setoff][op->d.agg_trans.transno]; -
2149 - -
2150 - Assert(pertrans->transtypeByVal); -
2151 - -
2152 - if (pergroup->noTransValue) -
2153 - { -
2154 - /* If transValue has not yet been initialized, do so now. */ -
2155 - ExecAggInitGroup(aggstate, pertrans, pergroup, -
2156 - op->d.agg_trans.aggcontext); -
2157 - /* copied trans value from input, done this round */ -
2158 - } -
2159 - else if (likely(!pergroup->transValueIsNull)) -
2160 - { -
2161 - /* invoke transition function, unless prevented by strictness */ -
2162 - ExecAggPlainTransByVal(aggstate, pertrans, pergroup, -
2163 - op->d.agg_trans.aggcontext, -
2164 - op->d.agg_trans.setno); -
2165 - } -
2166 - -
2167 - EEO_NEXT(); -
2168 - } -
2169 - -
2170 - /* see comments above EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL */ -
2171 - EEO_CASE(EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL) -
2172 - { -
2173 - AggState *aggstate = castNode(AggState, state->parent); -
2174 - AggStatePerTrans pertrans = op->d.agg_trans.pertrans; -
2175 - AggStatePerGroup pergroup = -
2176 - &aggstate->all_pergroups[op->d.agg_trans.setoff][op->d.agg_trans.transno]; -
2177 - -
2178 - Assert(pertrans->transtypeByVal); -
2179 - -
2180 - if (likely(!pergroup->transValueIsNull)) -
2181 - ExecAggPlainTransByVal(aggstate, pertrans, pergroup, -
2182 - op->d.agg_trans.aggcontext, -
2183 - op->d.agg_trans.setno); -
2184 - -
2185 - EEO_NEXT(); -
2186 - } -
2187 - -
2188 - /* see comments above EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL */ -
2189 - EEO_CASE(EEOP_AGG_PLAIN_TRANS_BYVAL) -
2190 - { -
2191 - AggState *aggstate = castNode(AggState, state->parent); -
2192 - AggStatePerTrans pertrans = op->d.agg_trans.pertrans; -
2193 - AggStatePerGroup pergroup = -
2194 - &aggstate->all_pergroups[op->d.agg_trans.setoff][op->d.agg_trans.transno]; -
2195 - -
2196 - Assert(pertrans->transtypeByVal); -
2197 - -
2198 - ExecAggPlainTransByVal(aggstate, pertrans, pergroup, -
2199 - op->d.agg_trans.aggcontext, -
2200 - op->d.agg_trans.setno); -
2201 - -
2202 - EEO_NEXT(); -
2203 - } -
2204 - -
2205 - /* see comments above EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL */ -
2206 - EEO_CASE(EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF) -
2207 - { -
2208 - AggState *aggstate = castNode(AggState, state->parent); -
2209 - AggStatePerTrans pertrans = op->d.agg_trans.pertrans; -
2210 - AggStatePerGroup pergroup = -
2211 - &aggstate->all_pergroups[op->d.agg_trans.setoff][op->d.agg_trans.transno]; -
2212 - -
2213 - Assert(!pertrans->transtypeByVal); -
2214 - -
2215 - if (pergroup->noTransValue) -
2216 - ExecAggInitGroup(aggstate, pertrans, pergroup, -
2217 - op->d.agg_trans.aggcontext); -
2218 - else if (likely(!pergroup->transValueIsNull)) -
2219 - ExecAggPlainTransByRef(aggstate, pertrans, pergroup, -
2220 - op->d.agg_trans.aggcontext, -
2221 - op->d.agg_trans.setno); -
2222 - -
2223 - EEO_NEXT(); -
2224 - } -
2225 - -
2226 - /* see comments above EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL */ -
2227 - EEO_CASE(EEOP_AGG_PLAIN_TRANS_STRICT_BYREF) -
2228 - { -
2229 - AggState *aggstate = castNode(AggState, state->parent); -
2230 - AggStatePerTrans pertrans = op->d.agg_trans.pertrans; -
2231 - AggStatePerGroup pergroup = -
2232 - &aggstate->all_pergroups[op->d.agg_trans.setoff][op->d.agg_trans.transno]; -
2233 - -
2234 - Assert(!pertrans->transtypeByVal); -
2235 - -
2236 - if (likely(!pergroup->transValueIsNull)) -
2237 - ExecAggPlainTransByRef(aggstate, pertrans, pergroup, -
2238 - op->d.agg_trans.aggcontext, -
2239 - op->d.agg_trans.setno); -
2240 - EEO_NEXT(); -
2241 - } -
2242 - -
2243 - /* see comments above EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL */ -
2244 - EEO_CASE(EEOP_AGG_PLAIN_TRANS_BYREF) -
2245 - { -
2246 - AggState *aggstate = castNode(AggState, state->parent); -
2247 - AggStatePerTrans pertrans = op->d.agg_trans.pertrans; -
2248 - AggStatePerGroup pergroup = -
2249 - &aggstate->all_pergroups[op->d.agg_trans.setoff][op->d.agg_trans.transno]; -
2250 - -
2251 - Assert(!pertrans->transtypeByVal); -
2252 - -
2253 - ExecAggPlainTransByRef(aggstate, pertrans, pergroup, -
2254 - op->d.agg_trans.aggcontext, -
2255 - op->d.agg_trans.setno); -
2256 - -
2257 - EEO_NEXT(); -
2258 - } -
2259 - -
2260 - EEO_CASE(EEOP_AGG_PRESORTED_DISTINCT_SINGLE) -
2261 - { -
2262 - AggStatePerTrans pertrans = op->d.agg_presorted_distinctcheck.pertrans; -
2263 - AggState *aggstate = castNode(AggState, state->parent); -
2264 - -
2265 - if (ExecEvalPreOrderedDistinctSingle(aggstate, pertrans)) -
2266 - EEO_NEXT(); -
2267 - else -
2268 - EEO_JUMP(op->d.agg_presorted_distinctcheck.jumpdistinct); -
2269 - } -
2270 - -
2271 - EEO_CASE(EEOP_AGG_PRESORTED_DISTINCT_MULTI) -
2272 - { -
2273 - AggState *aggstate = castNode(AggState, state->parent); -
2274 - AggStatePerTrans pertrans = op->d.agg_presorted_distinctcheck.pertrans; -
2275 - -
2276 - if (ExecEvalPreOrderedDistinctMulti(aggstate, pertrans)) -
2277 - EEO_NEXT(); -
2278 - else -
2279 - EEO_JUMP(op->d.agg_presorted_distinctcheck.jumpdistinct); -
2280 - } -
2281 - -
2282 - /* process single-column ordered aggregate datum */ -
2283 - EEO_CASE(EEOP_AGG_ORDERED_TRANS_DATUM) -
2284 - { -
2285 - /* too complex for an inline implementation */ -
2286 - ExecEvalAggOrderedTransDatum(state, op, econtext); -
2287 - -
2288 - EEO_NEXT(); -
2289 - } -
2290 - -
2291 - /* process multi-column ordered aggregate tuple */ -
2292 - EEO_CASE(EEOP_AGG_ORDERED_TRANS_TUPLE) -
2293 - { -
2294 - /* too complex for an inline implementation */ -
2295 - ExecEvalAggOrderedTransTuple(state, op, econtext); -
2296 - -
2297 - EEO_NEXT(); -
2298 - } -
2299 - -
2300 - EEO_CASE(EEOP_LAST) -
2301 - { -
2302 - /* unreachable */ -
2303 - Assert(false); -
2304 - goto out_error; -
2305 - } -
2306 - } -
2307 - -
2308 - out_error: -
2309 - pg_unreachable(); -
2310 - return (Datum) 0; -
2311 - } -
rpr_nav_get_compound_offset() lines 6021-6040
Modified Lines Coverage: 9/9 lines (100.0%)
LineHitsSourceCommit
6021 9788 rpr_nav_get_compound_offset(ExprEvalStep *op) 24cfb8dRow pattern recognition patch (executor and commands).
6022 - { 24cfb8dRow pattern recognition patch (executor and commands).
6023 9788 int64 val; 24cfb8dRow pattern recognition patch (executor and commands).
6024 - 24cfb8dRow pattern recognition patch (executor and commands).
6025 9788 Assert(op->d.rpr_nav.offset_value != NULL); 24cfb8dRow pattern recognition patch (executor and commands).
6026 - 24cfb8dRow pattern recognition patch (executor and commands).
6027 9788 if (op->d.rpr_nav.offset_isnull[1]) 24cfb8dRow pattern recognition patch (executor and commands).
6028 4 ereport(ERROR, 24cfb8dRow pattern recognition patch (executor and commands).
6029 - errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), 24cfb8dRow pattern recognition patch (executor and commands).
6030 - errmsg("row pattern navigation offset must not be null")); 24cfb8dRow pattern recognition patch (executor and commands).
6031 - 24cfb8dRow pattern recognition patch (executor and commands).
6032 9784 val = DatumGetInt64(op->d.rpr_nav.offset_value[1]); 24cfb8dRow pattern recognition patch (executor and commands).
6033 - 24cfb8dRow pattern recognition patch (executor and commands).
6034 9784 if (val < 0) 24cfb8dRow pattern recognition patch (executor and commands).
6035 4 ereport(ERROR, 24cfb8dRow pattern recognition patch (executor and commands).
6036 - errcode(ERRCODE_INVALID_PARAMETER_VALUE), 24cfb8dRow pattern recognition patch (executor and commands).
6037 - errmsg("row pattern navigation offset must not be negative")); 24cfb8dRow pattern recognition patch (executor and commands).
6038 - 24cfb8dRow pattern recognition patch (executor and commands).
6039 9780 return val; 24cfb8dRow pattern recognition patch (executor and commands).
6040 - } 24cfb8dRow pattern recognition patch (executor and commands).
ExecEvalRPRNavSet() lines 6053-6235
Modified Lines Coverage: 59/61 lines (96.7%)
LineHitsSourceCommit
6053 984292 ExecEvalRPRNavSet(ExprState *state, ExprEvalStep *op, ExprContext *econtext) 24cfb8dRow pattern recognition patch (executor and commands).
6054 - { 24cfb8dRow pattern recognition patch (executor and commands).
6055 984292 WindowAggState *winstate = op->d.rpr_nav.winstate; 24cfb8dRow pattern recognition patch (executor and commands).
6056 984292 int64 offset; 24cfb8dRow pattern recognition patch (executor and commands).
6057 984292 int64 target_pos; 24cfb8dRow pattern recognition patch (executor and commands).
6058 984292 TupleTableSlot *target_slot; 24cfb8dRow pattern recognition patch (executor and commands).
6059 - 24cfb8dRow pattern recognition patch (executor and commands).
6060 - /* Save current slot for later restore */ 24cfb8dRow pattern recognition patch (executor and commands).
6061 984292 winstate->nav_saved_outertuple = econtext->ecxt_outertuple; 24cfb8dRow pattern recognition patch (executor and commands).
6062 - 24cfb8dRow pattern recognition patch (executor and commands).
6063 - /* 24cfb8dRow pattern recognition patch (executor and commands).
6064 - * Determine the inner offset. NULL or negative offsets are errors per 24cfb8dRow pattern recognition patch (executor and commands).
6065 - * the SQL standard. 24cfb8dRow pattern recognition patch (executor and commands).
6066 - * 24cfb8dRow pattern recognition patch (executor and commands).
6067 - * Default offset when offset_arg is NULL: PREV/NEXT: 1 (standard 5.6.2) 24cfb8dRow pattern recognition patch (executor and commands).
6068 - * FIRST/LAST and compound: 0 for inner, 1 for outer 24cfb8dRow pattern recognition patch (executor and commands).
6069 - */ 24cfb8dRow pattern recognition patch (executor and commands).
6070 984292 if (op->d.rpr_nav.offset_value != NULL) 24cfb8dRow pattern recognition patch (executor and commands).
6071 - { 24cfb8dRow pattern recognition patch (executor and commands).
6072 16100 if (*op->d.rpr_nav.offset_isnull) 24cfb8dRow pattern recognition patch (executor and commands).
6073 28 ereport(ERROR, 24cfb8dRow pattern recognition patch (executor and commands).
6074 - errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), 24cfb8dRow pattern recognition patch (executor and commands).
6075 - errmsg("row pattern navigation offset must not be null")); 24cfb8dRow pattern recognition patch (executor and commands).
6076 - 24cfb8dRow pattern recognition patch (executor and commands).
6077 16072 offset = DatumGetInt64(*op->d.rpr_nav.offset_value); 24cfb8dRow pattern recognition patch (executor and commands).
6078 - 24cfb8dRow pattern recognition patch (executor and commands).
6079 16072 if (offset < 0) 24cfb8dRow pattern recognition patch (executor and commands).
6080 28 ereport(ERROR, 24cfb8dRow pattern recognition patch (executor and commands).
6081 - errcode(ERRCODE_INVALID_PARAMETER_VALUE), 24cfb8dRow pattern recognition patch (executor and commands).
6082 - errmsg("row pattern navigation offset must not be negative")); 24cfb8dRow pattern recognition patch (executor and commands).
6083 - } 24cfb8dRow pattern recognition patch (executor and commands).
6084 - else 24cfb8dRow pattern recognition patch (executor and commands).
6085 - { 24cfb8dRow pattern recognition patch (executor and commands).
6086 - /* Default offset: 1 for simple PREV/NEXT, 0 otherwise */ 24cfb8dRow pattern recognition patch (executor and commands).
6087 968192 if (op->d.rpr_nav.kind == RPR_NAV_PREV || 24cfb8dRow pattern recognition patch (executor and commands).
6088 - op->d.rpr_nav.kind == RPR_NAV_NEXT) 24cfb8dRow pattern recognition patch (executor and commands).
6089 - offset = 1; 24cfb8dRow pattern recognition patch (executor and commands).
6090 - else 24cfb8dRow pattern recognition patch (executor and commands).
6091 944 offset = 0; 24cfb8dRow pattern recognition patch (executor and commands).
6092 - } 24cfb8dRow pattern recognition patch (executor and commands).
6093 - 24cfb8dRow pattern recognition patch (executor and commands).
6094 - /* 24cfb8dRow pattern recognition patch (executor and commands).
6095 - * Calculate target position based on navigation direction. On overflow, 24cfb8dRow pattern recognition patch (executor and commands).
6096 - * use -1 so that ExecRPRNavGetSlot treats it as out of range. 24cfb8dRow pattern recognition patch (executor and commands).
6097 - */ 24cfb8dRow pattern recognition patch (executor and commands).
6098 984236 switch (op->d.rpr_nav.kind) 24cfb8dRow pattern recognition patch (executor and commands).
6099 - { 24cfb8dRow pattern recognition patch (executor and commands).
6100 972220 case RPR_NAV_PREV: 24cfb8dRow pattern recognition patch (executor and commands).
6101 - 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6102 - /* 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6103 - * currentpos and offset are both non-negative, so the subtraction 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6104 - * cannot underflow; assert the invariant rather than guarding an 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6105 - * unreachable overflow. 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6106 - */ 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6107 972220 Assert(!pg_sub_s64_overflow(winstate->currentpos, offset, &target_pos)); 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6108 972220 target_pos = winstate->currentpos - offset; 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6109 972220 break; 24cfb8dRow pattern recognition patch (executor and commands).
6110 596 case RPR_NAV_NEXT: 24cfb8dRow pattern recognition patch (executor and commands).
6111 596 if (pg_add_s64_overflow(winstate->currentpos, offset, &target_pos)) 24cfb8dRow pattern recognition patch (executor and commands).
6112 20 target_pos = -1; 24cfb8dRow pattern recognition patch (executor and commands).
6113 - break; 24cfb8dRow pattern recognition patch (executor and commands).
6114 668 case RPR_NAV_FIRST: 24cfb8dRow pattern recognition patch (executor and commands).
6115 - /* FIRST: offset from match_start, clamped to currentpos */ 24cfb8dRow pattern recognition patch (executor and commands).
6116 668 if (pg_add_s64_overflow(winstate->nav_match_start, offset, &target_pos)) 24cfb8dRow pattern recognition patch (executor and commands).
6117 - target_pos = -1; 24cfb8dRow pattern recognition patch (executor and commands).
6118 668 else if (target_pos > winstate->currentpos) 24cfb8dRow pattern recognition patch (executor and commands).
6119 108 target_pos = -1; /* beyond current match range */ 24cfb8dRow pattern recognition patch (executor and commands).
6120 - break; 24cfb8dRow pattern recognition patch (executor and commands).
6121 620 case RPR_NAV_LAST: 24cfb8dRow pattern recognition patch (executor and commands).
6122 - /* LAST: offset backward from currentpos, clamped to match_start */ 24cfb8dRow pattern recognition patch (executor and commands).
6123 620 if (pg_sub_s64_overflow(winstate->currentpos, offset, &target_pos)) 24cfb8dRow pattern recognition patch (executor and commands).
6124 - target_pos = -1; 24cfb8dRow pattern recognition patch (executor and commands).
6125 620 else if (target_pos < winstate->nav_match_start) 24cfb8dRow pattern recognition patch (executor and commands).
6126 108 target_pos = -1; /* before match_start */ 24cfb8dRow pattern recognition patch (executor and commands).
6127 - break; 24cfb8dRow pattern recognition patch (executor and commands).
6128 - 24cfb8dRow pattern recognition patch (executor and commands).
6129 9888 case RPR_NAV_PREV_FIRST: 24cfb8dRow pattern recognition patch (executor and commands).
6130 - case RPR_NAV_NEXT_FIRST: 24cfb8dRow pattern recognition patch (executor and commands).
6131 - { 24cfb8dRow pattern recognition patch (executor and commands).
6132 9888 int64 compound_offset; 24cfb8dRow pattern recognition patch (executor and commands).
6133 9888 int64 inner_pos; 24cfb8dRow pattern recognition patch (executor and commands).
6134 - 24cfb8dRow pattern recognition patch (executor and commands).
6135 - /* Inner: match_start + offset */ 24cfb8dRow pattern recognition patch (executor and commands).
6136 9888 if (pg_add_s64_overflow(winstate->nav_match_start, offset, &inner_pos)) 24cfb8dRow pattern recognition patch (executor and commands).
6137 - { 24cfb8dRow pattern recognition patch (executor and commands).
6138 - target_pos = -1; 24cfb8dRow pattern recognition patch (executor and commands).
6139 984228 break; 24cfb8dRow pattern recognition patch (executor and commands).
6140 - } 24cfb8dRow pattern recognition patch (executor and commands).
6141 9888 if (inner_pos > winstate->currentpos || inner_pos < 0) 24cfb8dRow pattern recognition patch (executor and commands).
6142 - { 24cfb8dRow pattern recognition patch (executor and commands).
6143 - target_pos = -1; 24cfb8dRow pattern recognition patch (executor and commands).
6144 - break; 24cfb8dRow pattern recognition patch (executor and commands).
6145 - } 24cfb8dRow pattern recognition patch (executor and commands).
6146 - 24cfb8dRow pattern recognition patch (executor and commands).
6147 - /* Outer offset */ 24cfb8dRow pattern recognition patch (executor and commands).
6148 9692 compound_offset = rpr_nav_get_compound_offset(op); 24cfb8dRow pattern recognition patch (executor and commands).
6149 - 24cfb8dRow pattern recognition patch (executor and commands).
6150 - /* Apply outer: PREV subtracts, NEXT adds */ 24cfb8dRow pattern recognition patch (executor and commands).
6151 9688 if (op->d.rpr_nav.kind == RPR_NAV_PREV_FIRST) 24cfb8dRow pattern recognition patch (executor and commands).
6152 - { 24cfb8dRow pattern recognition patch (executor and commands).
6153 - /* 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6154 - * inner_pos is in [0, currentpos] and compound_offset is 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6155 - * non-negative, so this cannot underflow. 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6156 - */ 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6157 9564 Assert(!pg_sub_s64_overflow(inner_pos, compound_offset, &target_pos)); 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6158 9564 target_pos = inner_pos - compound_offset; 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6159 - } 24cfb8dRow pattern recognition patch (executor and commands).
6160 - else 24cfb8dRow pattern recognition patch (executor and commands).
6161 - { 24cfb8dRow pattern recognition patch (executor and commands).
6162 124 if (pg_add_s64_overflow(inner_pos, compound_offset, &target_pos)) 24cfb8dRow pattern recognition patch (executor and commands).
6163 20 target_pos = -1; 24cfb8dRow pattern recognition patch (executor and commands).
6164 - } 24cfb8dRow pattern recognition patch (executor and commands).
6165 - } 24cfb8dRow pattern recognition patch (executor and commands).
6166 - break; 24cfb8dRow pattern recognition patch (executor and commands).
6167 - 24cfb8dRow pattern recognition patch (executor and commands).
6168 244 case RPR_NAV_PREV_LAST: 24cfb8dRow pattern recognition patch (executor and commands).
6169 - case RPR_NAV_NEXT_LAST: 24cfb8dRow pattern recognition patch (executor and commands).
6170 - { 24cfb8dRow pattern recognition patch (executor and commands).
6171 244 int64 compound_offset; 24cfb8dRow pattern recognition patch (executor and commands).
6172 244 int64 inner_pos; 24cfb8dRow pattern recognition patch (executor and commands).
6173 - 24cfb8dRow pattern recognition patch (executor and commands).
6174 - /* Inner: currentpos - offset */ 24cfb8dRow pattern recognition patch (executor and commands).
6175 244 if (pg_sub_s64_overflow(winstate->currentpos, offset, &inner_pos)) 24cfb8dRow pattern recognition patch (executor and commands).
6176 - { 24cfb8dRow pattern recognition patch (executor and commands).
6177 - target_pos = -1; 24cfb8dRow pattern recognition patch (executor and commands).
6178 984228 break; 24cfb8dRow pattern recognition patch (executor and commands).
6179 - } 24cfb8dRow pattern recognition patch (executor and commands).
6180 244 if (inner_pos < winstate->nav_match_start) 24cfb8dRow pattern recognition patch (executor and commands).
6181 - { 24cfb8dRow pattern recognition patch (executor and commands).
6182 - target_pos = -1; 24cfb8dRow pattern recognition patch (executor and commands).
6183 - break; 24cfb8dRow pattern recognition patch (executor and commands).
6184 - } 24cfb8dRow pattern recognition patch (executor and commands).
6185 - 24cfb8dRow pattern recognition patch (executor and commands).
6186 - /* Outer offset */ 24cfb8dRow pattern recognition patch (executor and commands).
6187 96 compound_offset = rpr_nav_get_compound_offset(op); 24cfb8dRow pattern recognition patch (executor and commands).
6188 - 24cfb8dRow pattern recognition patch (executor and commands).
6189 - /* Apply outer: PREV subtracts, NEXT adds */ 24cfb8dRow pattern recognition patch (executor and commands).
6190 92 if (op->d.rpr_nav.kind == RPR_NAV_PREV_LAST) 24cfb8dRow pattern recognition patch (executor and commands).
6191 - { 24cfb8dRow pattern recognition patch (executor and commands).
6192 - /* 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6193 - * inner_pos is in [nav_match_start, currentpos] (>= 0) 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6194 - * and compound_offset is non-negative, so this cannot 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6195 - * underflow. 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6196 - */ 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6197 24 Assert(!pg_sub_s64_overflow(inner_pos, compound_offset, &target_pos)); 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6198 24 target_pos = inner_pos - compound_offset; 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
6199 - } 24cfb8dRow pattern recognition patch (executor and commands).
6200 - else 24cfb8dRow pattern recognition patch (executor and commands).
6201 - { 24cfb8dRow pattern recognition patch (executor and commands).
6202 68 if (pg_add_s64_overflow(inner_pos, compound_offset, &target_pos)) 24cfb8dRow pattern recognition patch (executor and commands).
6203 20 target_pos = -1; 24cfb8dRow pattern recognition patch (executor and commands).
6204 - } 24cfb8dRow pattern recognition patch (executor and commands).
6205 - } 24cfb8dRow pattern recognition patch (executor and commands).
6206 - break; 24cfb8dRow pattern recognition patch (executor and commands).
6207 0 default: 24cfb8dRow pattern recognition patch (executor and commands).
6208 0 elog(ERROR, "unrecognized RPR navigation kind: %d", 24cfb8dRow pattern recognition patch (executor and commands).
6209 - op->d.rpr_nav.kind); 24cfb8dRow pattern recognition patch (executor and commands).
6210 - break; 24cfb8dRow pattern recognition patch (executor and commands).
6211 - } 24cfb8dRow pattern recognition patch (executor and commands).
6212 - 24cfb8dRow pattern recognition patch (executor and commands).
6213 - /* 24cfb8dRow pattern recognition patch (executor and commands).
6214 - * Slot swap elision: if target_pos is the current row, skip the 24cfb8dRow pattern recognition patch (executor and commands).
6215 - * tuplestore fetch and slot swap entirely. This benefits LAST(expr), 24cfb8dRow pattern recognition patch (executor and commands).
6216 - * PREV(expr, 0), NEXT(expr, 0), and similar cases. 24cfb8dRow pattern recognition patch (executor and commands).
6217 - * 24cfb8dRow pattern recognition patch (executor and commands).
6218 - * We must still set nav_saved_outertuple (done above) so that 24cfb8dRow pattern recognition patch (executor and commands).
6219 - * EEOP_RPR_NAV_RESTORE is a harmless no-op. 24cfb8dRow pattern recognition patch (executor and commands).
6220 - */ 24cfb8dRow pattern recognition patch (executor and commands).
6221 984228 if (target_pos == winstate->currentpos) 24cfb8dRow pattern recognition patch (executor and commands).
6222 984228 return; 24cfb8dRow pattern recognition patch (executor and commands).
6223 - 24cfb8dRow pattern recognition patch (executor and commands).
6224 - /* Fetch target row slot (returns nav_null_slot if out of range) */ 24cfb8dRow pattern recognition patch (executor and commands).
6225 983356 target_slot = ExecRPRNavGetSlot(winstate, target_pos); 24cfb8dRow pattern recognition patch (executor and commands).
6226 - 24cfb8dRow pattern recognition patch (executor and commands).
6227 - /* 24cfb8dRow pattern recognition patch (executor and commands).
6228 - * Update econtext to point to the target slot. Also decompress the new 24cfb8dRow pattern recognition patch (executor and commands).
6229 - * slot's attributes since FETCHSOME already ran for the original slot. 24cfb8dRow pattern recognition patch (executor and commands).
6230 - * The caller (interpreter or JIT) is responsible for updating any local 24cfb8dRow pattern recognition patch (executor and commands).
6231 - * slot cache (e.g. outerslot) from econtext after we return. 24cfb8dRow pattern recognition patch (executor and commands).
6232 - */ 24cfb8dRow pattern recognition patch (executor and commands).
6233 983356 slot_getallattrs(target_slot); 24cfb8dRow pattern recognition patch (executor and commands).
6234 983356 econtext->ecxt_outertuple = target_slot; 24cfb8dRow pattern recognition patch (executor and commands).
6235 - } 24cfb8dRow pattern recognition patch (executor and commands).
ExecEvalRPRNavRestore() lines 6253-6272
Modified Lines Coverage: 11/11 lines (100.0%)
LineHitsSourceCommit
6253 984228 ExecEvalRPRNavRestore(ExprState *state, ExprEvalStep *op, 24cfb8dRow pattern recognition patch (executor and commands).
6254 - ExprContext *econtext) 24cfb8dRow pattern recognition patch (executor and commands).
6255 - { 24cfb8dRow pattern recognition patch (executor and commands).
6256 984228 WindowAggState *winstate = op->d.rpr_nav.winstate; 24cfb8dRow pattern recognition patch (executor and commands).
6257 - 24cfb8dRow pattern recognition patch (executor and commands).
6258 984228 econtext->ecxt_outertuple = winstate->nav_saved_outertuple; 24cfb8dRow pattern recognition patch (executor and commands).
6259 - 24cfb8dRow pattern recognition patch (executor and commands).
6260 - /* Stabilize pass-by-ref result against nav_slot re-fetch */ 24cfb8dRow pattern recognition patch (executor and commands).
6261 984228 if (!op->d.rpr_nav.resulttypbyval && 24cfb8dRow pattern recognition patch (executor and commands).
6262 144616 !*op->resnull) 24cfb8dRow pattern recognition patch (executor and commands).
6263 - { 24cfb8dRow pattern recognition patch (executor and commands).
6264 130120 MemoryContext oldContext; 24cfb8dRow pattern recognition patch (executor and commands).
6265 - 24cfb8dRow pattern recognition patch (executor and commands).
6266 130120 oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory); 24cfb8dRow pattern recognition patch (executor and commands).
6267 260240 *op->resvalue = datumCopy(*op->resvalue, 24cfb8dRow pattern recognition patch (executor and commands).
6268 - false, 24cfb8dRow pattern recognition patch (executor and commands).
6269 130120 op->d.rpr_nav.resulttyplen); 24cfb8dRow pattern recognition patch (executor and commands).
6270 130120 MemoryContextSwitchTo(oldContext); 24cfb8dRow pattern recognition patch (executor and commands).
6271 - } 24cfb8dRow pattern recognition patch (executor and commands).
6272 984228 } 24cfb8dRow pattern recognition patch (executor and commands).