← Back to Overview

src/backend/executor/nodeWindowAgg.c

Coverage: 451/469 lines (96.2%)
Total Lines
469
modified
Covered
451
96.2%
Uncovered
18
3.8%
Keyboard navigation
eval_windowaggregates() lines 732-1134
Modified Lines Coverage: 14/14 lines (100.0%)
LineHitsSourceCommit
732 - eval_windowaggregates(WindowAggState *winstate) -
733 - { -
734 - WindowStatePerAgg peraggstate; -
735 - int wfuncno, -
736 - numaggs, -
737 - numaggs_restart, -
738 - i; -
739 - int64 aggregatedupto_nonrestarted; -
740 - MemoryContext oldContext; -
741 - ExprContext *econtext; -
742 - WindowObject agg_winobj; -
743 - TupleTableSlot *agg_row_slot; -
744 - TupleTableSlot *temp_slot; -
745 - -
746 - numaggs = winstate->numaggs; -
747 - if (numaggs == 0) -
748 - return; /* nothing to do */ -
749 - -
750 - /* final output execution is in ps_ExprContext */ -
751 - econtext = winstate->ss.ps.ps_ExprContext; -
752 - agg_winobj = winstate->agg_winobj; -
753 - agg_row_slot = winstate->agg_row_slot; -
754 - temp_slot = winstate->temp_slot_1; -
755 - -
756 - /* -
757 - * If the window's frame start clause is UNBOUNDED_PRECEDING and no -
758 - * exclusion clause is specified, then the window frame consists of a -
759 - * contiguous group of rows extending forward from the start of the -
760 - * partition, and rows only enter the frame, never exit it, as the current -
761 - * row advances forward. This makes it possible to use an incremental -
762 - * strategy for evaluating aggregates: we run the transition function for -
763 - * each row added to the frame, and run the final function whenever we -
764 - * need the current aggregate value. This is considerably more efficient -
765 - * than the naive approach of re-running the entire aggregate calculation -
766 - * for each current row. It does assume that the final function doesn't -
767 - * damage the running transition value, but we have the same assumption in -
768 - * nodeAgg.c too (when it rescans an existing hash table). -
769 - * -
770 - * If the frame start does sometimes move, we can still optimize as above -
771 - * whenever successive rows share the same frame head, but if the frame -
772 - * head moves beyond the previous head we try to remove those rows using -
773 - * the aggregate's inverse transition function. This function restores -
774 - * the aggregate's current state to what it would be if the removed row -
775 - * had never been aggregated in the first place. Inverse transition -
776 - * functions may optionally return NULL, indicating that the function was -
777 - * unable to remove the tuple from aggregation. If this happens, or if -
778 - * the aggregate doesn't have an inverse transition function at all, we -
779 - * must perform the aggregation all over again for all tuples within the -
780 - * new frame boundaries. -
781 - * -
782 - * If there's any exclusion clause, then we may have to aggregate over a -
783 - * non-contiguous set of rows, so we punt and recalculate for every row. -
784 - * (For some frame end choices, it might be that the frame is always -
785 - * contiguous anyway, but that's an optimization to investigate later.) -
786 - * -
787 - * In many common cases, multiple rows share the same frame and hence the -
788 - * same aggregate value. (In particular, if there's no ORDER BY in a RANGE -
789 - * window, then all rows are peers and so they all have window frame equal -
790 - * to the whole partition.) We optimize such cases by calculating the -
791 - * aggregate value once when we reach the first row of a peer group, and -
792 - * then returning the saved value for all subsequent rows. -
793 - * -
794 - * 'aggregatedupto' keeps track of the first row that has not yet been -
795 - * accumulated into the aggregate transition values. Whenever we start a -
796 - * new peer group, we accumulate forward to the end of the peer group. -
797 - */ -
798 - -
799 - /* -
800 - * First, update the frame head position. -
801 - * -
802 - * The frame head should never move backwards, and the code below wouldn't -
803 - * cope if it did, so for safety we complain if it does. -
804 - */ -
805 - update_frameheadpos(winstate); -
806 - if (winstate->frameheadpos < winstate->aggregatedbase) -
807 - elog(ERROR, "window frame head moved backward"); -
808 - -
809 - /* -
810 - * If the frame didn't change compared to the previous row, we can re-use -
811 - * the result values that were previously saved at the bottom of this -
812 - * function. Since we don't know the current frame's end yet, this is not -
813 - * possible to check for fully. But if the frame end mode is UNBOUNDED -
814 - * FOLLOWING or CURRENT ROW, no exclusion clause is specified, and the -
815 - * current row lies within the previous row's frame, then the two frames' -
816 - * ends must coincide. Note that on the first row aggregatedbase == -
817 - * aggregatedupto, meaning this test must fail, so we don't need to check -
818 - * the "there was no previous row" case explicitly here. -
819 - */ -
820 - if (winstate->aggregatedbase == winstate->frameheadpos && -
821 - (winstate->frameOptions & (FRAMEOPTION_END_UNBOUNDED_FOLLOWING | -
822 - FRAMEOPTION_END_CURRENT_ROW)) && -
823 - !(winstate->frameOptions & FRAMEOPTION_EXCLUSION) && -
824 - winstate->aggregatedbase <= winstate->currentpos && -
825 - winstate->aggregatedupto > winstate->currentpos) -
826 - { -
827 - for (i = 0; i < numaggs; i++) -
828 - { -
829 - peraggstate = &winstate->peragg[i]; -
830 - wfuncno = peraggstate->wfuncno; -
831 - econtext->ecxt_aggvalues[wfuncno] = peraggstate->resultValue; -
832 - econtext->ecxt_aggnulls[wfuncno] = peraggstate->resultValueIsNull; -
833 - } -
834 - return; -
835 - } -
836 - -
837 - /*---------- -
838 - * Initialize restart flags. -
839 - * -
840 - * We restart the aggregation: -
841 - * - if we're processing the first row in the partition, or -
842 - * - if the frame's head moved and we cannot use an inverse -
843 - * transition function, or -
844 - * - we have an EXCLUSION clause, or -
845 - * - if the new frame doesn't overlap the old one -
846 - * - if RPR (Row Pattern Recognition) is enabled, because the reduced 24cfb8dRow pattern recognition patch (executor and commands).
847 - * frame depends on pattern matching results which can differ entirely 24cfb8dRow pattern recognition patch (executor and commands).
848 - * from row to row, making inverse transition optimization inapplicable 24cfb8dRow pattern recognition patch (executor and commands).
849 - * -
850 - * Note that we don't strictly need to restart in the last case, but if -
851 - * we're going to remove all rows from the aggregation anyway, a restart -
852 - * surely is faster. -
853 - *---------- -
854 - */ -
855 - numaggs_restart = 0; -
856 - for (i = 0; i < numaggs; i++) -
857 - { -
858 - peraggstate = &winstate->peragg[i]; -
859 - if (winstate->currentpos == 0 || -
860 - (winstate->aggregatedbase != winstate->frameheadpos && -
861 - !OidIsValid(peraggstate->invtransfn_oid)) || -
862 - (winstate->frameOptions & FRAMEOPTION_EXCLUSION) || -
863 973920 winstate->aggregatedupto <= winstate->frameheadpos || 24cfb8dRow pattern recognition patch (executor and commands).
864 15864 rpr_is_defined(winstate)) 24cfb8dRow pattern recognition patch (executor and commands).
865 - { -
866 - peraggstate->restart = true; -
867 - numaggs_restart++; -
868 - } -
869 - else -
870 - peraggstate->restart = false; -
871 - } -
872 - -
873 - /* -
874 - * If we have any possibly-moving aggregates, attempt to advance -
875 - * aggregatedbase to match the frame's head by removing input rows that -
876 - * fell off the top of the frame from the aggregations. This can fail, -
877 - * i.e. advance_windowaggregate_base() can return false, in which case -
878 - * we'll restart that aggregate below. -
879 - */ -
880 - while (numaggs_restart < numaggs && -
881 - winstate->aggregatedbase < winstate->frameheadpos) -
882 - { -
883 - /* -
884 - * Fetch the next tuple of those being removed. This should never fail -
885 - * as we should have been here before. -
886 - */ -
887 - if (!window_gettupleslot(agg_winobj, winstate->aggregatedbase, -
888 - temp_slot)) -
889 - elog(ERROR, "could not re-fetch previously fetched frame row"); -
890 - -
891 - /* Set tuple context for evaluation of aggregate arguments */ -
892 - winstate->tmpcontext->ecxt_outertuple = temp_slot; -
893 - -
894 - /* -
895 - * Perform the inverse transition for each aggregate function in the -
896 - * window, unless it has already been marked as needing a restart. -
897 - */ -
898 - for (i = 0; i < numaggs; i++) -
899 - { -
900 - bool ok; -
901 - -
902 - peraggstate = &winstate->peragg[i]; -
903 - if (peraggstate->restart) -
904 - continue; -
905 - -
906 - wfuncno = peraggstate->wfuncno; -
907 - ok = advance_windowaggregate_base(winstate, -
908 - &winstate->perfunc[wfuncno], -
909 - peraggstate); -
910 - if (!ok) -
911 - { -
912 - /* Inverse transition function has failed, must restart */ -
913 - peraggstate->restart = true; -
914 - numaggs_restart++; -
915 - } -
916 - } -
917 - -
918 - /* Reset per-input-tuple context after each tuple */ -
919 - ResetExprContext(winstate->tmpcontext); -
920 - -
921 - /* And advance the aggregated-row state */ -
922 - winstate->aggregatedbase++; -
923 - ExecClearTuple(temp_slot); -
924 - } -
925 - -
926 - /* -
927 - * If we successfully advanced the base rows of all the aggregates, -
928 - * aggregatedbase now equals frameheadpos; but if we failed for any, we -
929 - * must forcibly update aggregatedbase. -
930 - */ -
931 - winstate->aggregatedbase = winstate->frameheadpos; -
932 - -
933 - /* -
934 - * If we created a mark pointer for aggregates, keep it pushed up to frame -
935 - * head, so that tuplestore can discard unnecessary rows. -
936 - */ -
937 - if (agg_winobj->markptr >= 0) -
938 - WinSetMarkPosition(agg_winobj, winstate->frameheadpos); -
939 - -
940 - /* -
941 - * Now restart the aggregates that require it. -
942 - * -
943 - * We assume that aggregates using the shared context always restart if -
944 - * *any* aggregate restarts, and we may thus clean up the shared -
945 - * aggcontext if that is the case. Private aggcontexts are reset by -
946 - * initialize_windowaggregate() if their owning aggregate restarts. If we -
947 - * aren't restarting an aggregate, we need to free any previously saved -
948 - * result for it, else we'll leak memory. -
949 - */ -
950 - if (numaggs_restart > 0) -
951 - MemoryContextReset(winstate->aggcontext); -
952 - for (i = 0; i < numaggs; i++) -
953 - { -
954 - peraggstate = &winstate->peragg[i]; -
955 - -
956 - /* Aggregates using the shared ctx must restart if *any* agg does */ -
957 - Assert(peraggstate->aggcontext != winstate->aggcontext || -
958 - numaggs_restart == 0 || -
959 - peraggstate->restart); -
960 - -
961 - if (peraggstate->restart) -
962 - { -
963 - wfuncno = peraggstate->wfuncno; -
964 - initialize_windowaggregate(winstate, -
965 - &winstate->perfunc[wfuncno], -
966 - peraggstate); -
967 - } -
968 - else if (!peraggstate->resultValueIsNull) -
969 - { -
970 - if (!peraggstate->resulttypeByVal) -
971 - pfree(DatumGetPointer(peraggstate->resultValue)); -
972 - peraggstate->resultValue = (Datum) 0; -
973 - peraggstate->resultValueIsNull = true; -
974 - } -
975 - } -
976 - -
977 - /* -
978 - * Non-restarted aggregates now contain the rows between aggregatedbase -
979 - * (i.e., frameheadpos) and aggregatedupto, while restarted aggregates -
980 - * contain no rows. If there are any restarted aggregates, we must thus -
981 - * begin aggregating anew at frameheadpos, otherwise we may simply -
982 - * continue at aggregatedupto. We must remember the old value of -
983 - * aggregatedupto to know how long to skip advancing non-restarted -
984 - * aggregates. If we modify aggregatedupto, we must also clear -
985 - * agg_row_slot, per the loop invariant below. -
986 - */ -
987 - aggregatedupto_nonrestarted = winstate->aggregatedupto; -
988 - if (numaggs_restart > 0 && -
989 - winstate->aggregatedupto != winstate->frameheadpos) -
990 - { -
991 - winstate->aggregatedupto = winstate->frameheadpos; -
992 - ExecClearTuple(agg_row_slot); -
993 - 24cfb8dRow pattern recognition patch (executor and commands).
994 - /* 24cfb8dRow pattern recognition patch (executor and commands).
995 - * If RPR is defined, we do not use aggregatedupto_nonrestarted. To 24cfb8dRow pattern recognition patch (executor and commands).
996 - * avoid assertion failure below, we reset aggregatedupto_nonrestarted 24cfb8dRow pattern recognition patch (executor and commands).
997 - * to frameheadpos. 24cfb8dRow pattern recognition patch (executor and commands).
998 - */ 24cfb8dRow pattern recognition patch (executor and commands).
999 947771 if (rpr_is_defined(winstate)) 24cfb8dRow pattern recognition patch (executor and commands).
1000 946776 aggregatedupto_nonrestarted = winstate->frameheadpos; 24cfb8dRow pattern recognition patch (executor and commands).
1001 - } -
1002 - -
1003 - /* -
1004 - * Advance until we reach a row not in frame (or end of partition). -
1005 - * -
1006 - * Note the loop invariant: agg_row_slot is either empty or holds the row -
1007 - * at position aggregatedupto. We advance aggregatedupto after processing -
1008 - * a row. -
1009 - */ -
1010 - for (;;) -
1011 - { -
1012 1992792 int64 ret; 24cfb8dRow pattern recognition patch (executor and commands).
1013 - -
1014 - /* Fetch next row if we didn't already */ -
1015 - if (TupIsNull(agg_row_slot)) -
1016 - { -
1017 - if (!window_gettupleslot(agg_winobj, winstate->aggregatedupto, -
1018 - agg_row_slot)) -
1019 - break; /* must be end of partition */ -
1020 - } -
1021 - -
1022 - /* -
1023 - * Exit loop if no more rows can be in frame. Skip aggregation if -
1024 - * current row is not in frame but there might be more in the frame. -
1025 - */ -
1026 - ret = row_is_in_frame(agg_winobj, winstate->aggregatedupto, -
1027 - agg_row_slot, false); -
1028 - if (ret < 0) -
1029 - break; -
1030 - 24cfb8dRow pattern recognition patch (executor and commands).
1031 - if (ret == 0) -
1032 - goto next_tuple; -
1033 - -
1034 1984017 if (rpr_is_defined(winstate)) 24cfb8dRow pattern recognition patch (executor and commands).
1035 - { 24cfb8dRow pattern recognition patch (executor and commands).
1036 - /* 24cfb8dRow pattern recognition patch (executor and commands).
1037 - * If currentpos is already decided but aggregatedupto is not yet 24cfb8dRow pattern recognition patch (executor and commands).
1038 - * determined, we've passed the last reduced frame. 24cfb8dRow pattern recognition patch (executor and commands).
1039 - */ 24cfb8dRow pattern recognition patch (executor and commands).
1040 1866672 if (get_reduced_frame_status(winstate, winstate->currentpos) 24cfb8dRow pattern recognition patch (executor and commands).
1041 1866672 != RF_NOT_DETERMINED && 24cfb8dRow pattern recognition patch (executor and commands).
1042 1866672 get_reduced_frame_status(winstate, winstate->aggregatedupto) 24cfb8dRow pattern recognition patch (executor and commands).
1043 - == RF_NOT_DETERMINED) 24cfb8dRow pattern recognition patch (executor and commands).
1044 - break; 24cfb8dRow pattern recognition patch (executor and commands).
1045 - 24cfb8dRow pattern recognition patch (executor and commands).
1046 - /* 24cfb8dRow pattern recognition patch (executor and commands).
1047 - * Calculate the reduced frame for aggregatedupto. 24cfb8dRow pattern recognition patch (executor and commands).
1048 - */ 24cfb8dRow pattern recognition patch (executor and commands).
1049 1835080 ret = row_is_in_reduced_frame(winstate->agg_winobj, 24cfb8dRow pattern recognition patch (executor and commands).
1050 - winstate->aggregatedupto); 24cfb8dRow pattern recognition patch (executor and commands).
1051 1835080 if (ret == -1) /* unmatched row */ 24cfb8dRow pattern recognition patch (executor and commands).
1052 - break; 24cfb8dRow pattern recognition patch (executor and commands).
1053 - 24cfb8dRow pattern recognition patch (executor and commands).
1054 - /* 24cfb8dRow pattern recognition patch (executor and commands).
1055 - * Check if current row is inside a match but not the head 24cfb8dRow pattern recognition patch (executor and commands).
1056 - * (skipped), and it's the base row for aggregation. 24cfb8dRow pattern recognition patch (executor and commands).
1057 - */ 24cfb8dRow pattern recognition patch (executor and commands).
1058 1746652 if (get_reduced_frame_status(winstate, 24cfb8dRow pattern recognition patch (executor and commands).
1059 1713852 winstate->aggregatedupto) == RF_SKIPPED && 24cfb8dRow pattern recognition patch (executor and commands).
1060 1713852 winstate->aggregatedupto == winstate->aggregatedbase) 24cfb8dRow pattern recognition patch (executor and commands).
1061 - break; 24cfb8dRow pattern recognition patch (executor and commands).
1062 - } 24cfb8dRow pattern recognition patch (executor and commands).
1063 - 24cfb8dRow pattern recognition patch (executor and commands).
1064 - /* Set tuple context for evaluation of aggregate arguments */ -
1065 - winstate->tmpcontext->ecxt_outertuple = agg_row_slot; -
1066 - -
1067 - /* Accumulate row into the aggregates */ -
1068 - for (i = 0; i < numaggs; i++) -
1069 - { -
1070 - peraggstate = &winstate->peragg[i]; -
1071 - -
1072 - /* Non-restarted aggs skip until aggregatedupto_nonrestarted */ -
1073 - if (!peraggstate->restart && -
1074 - winstate->aggregatedupto < aggregatedupto_nonrestarted) -
1075 - continue; -
1076 - -
1077 - wfuncno = peraggstate->wfuncno; -
1078 - advance_windowaggregate(winstate, -
1079 - &winstate->perfunc[wfuncno], -
1080 - peraggstate); -
1081 - } -
1082 - -
1083 - next_tuple: -
1084 - /* Reset per-input-tuple context after each tuple */ -
1085 - ResetExprContext(winstate->tmpcontext); -
1086 - -
1087 - /* And advance the aggregated-row state */ -
1088 - winstate->aggregatedupto++; -
1089 - ExecClearTuple(agg_row_slot); -
1090 - } -
1091 - -
1092 - /* The frame's end is not supposed to move backwards, ever */ -
1093 - Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto); -
1094 - -
1095 - /* -
1096 - * finalize aggregates and fill result/isnull fields. -
1097 - */ -
1098 - for (i = 0; i < numaggs; i++) -
1099 - { -
1100 - Datum *result; -
1101 - bool *isnull; -
1102 - -
1103 - peraggstate = &winstate->peragg[i]; -
1104 - wfuncno = peraggstate->wfuncno; -
1105 - result = &econtext->ecxt_aggvalues[wfuncno]; -
1106 - isnull = &econtext->ecxt_aggnulls[wfuncno]; -
1107 - finalize_windowaggregate(winstate, -
1108 - &winstate->perfunc[wfuncno], -
1109 - peraggstate, -
1110 - result, isnull); -
1111 - -
1112 - /* -
1113 - * save the result in case next row shares the same frame. -
1114 - * -
1115 - * XXX in some framing modes, eg ROWS/END_CURRENT_ROW, we can know in -
1116 - * advance that the next row can't possibly share the same frame. Is -
1117 - * it worth detecting that and skipping this code? -
1118 - */ -
1119 - if (!peraggstate->resulttypeByVal && !*isnull) -
1120 - { -
1121 - oldContext = MemoryContextSwitchTo(peraggstate->aggcontext); -
1122 - peraggstate->resultValue = -
1123 - datumCopy(*result, -
1124 - peraggstate->resulttypeByVal, -
1125 - peraggstate->resulttypeLen); -
1126 - MemoryContextSwitchTo(oldContext); -
1127 - } -
1128 - else -
1129 - { -
1130 - peraggstate->resultValue = *result; -
1131 - } -
1132 - peraggstate->resultValueIsNull = *isnull; -
1133 - } -
1134 - } -
prepare_tuplestore() lines 1198-1321
Modified Lines Coverage: 6/6 lines (100.0%)
LineHitsSourceCommit
1198 - prepare_tuplestore(WindowAggState *winstate) -
1199 - { -
1200 - WindowAgg *node = (WindowAgg *) winstate->ss.ps.plan; -
1201 - int frameOptions = winstate->frameOptions; -
1202 - int numfuncs = winstate->numfuncs; -
1203 - -
1204 - /* we shouldn't be called if this was done already */ -
1205 - Assert(winstate->buffer == NULL); -
1206 - -
1207 - /* Create new tuplestore */ -
1208 - winstate->buffer = tuplestore_begin_heap(false, false, work_mem); -
1209 - -
1210 - /* -
1211 - * Set up read pointers for the tuplestore. The current pointer doesn't -
1212 - * need BACKWARD capability, but the per-window-function read pointers do, -
1213 - * and the aggregate pointer does if we might need to restart aggregation. -
1214 - */ -
1215 - winstate->current_ptr = 0; /* read pointer 0 is pre-allocated */ -
1216 - -
1217 - /* reset default REWIND capability bit for current ptr */ -
1218 - tuplestore_set_eflags(winstate->buffer, 0); -
1219 - -
1220 - /* create read pointers for aggregates, if needed */ -
1221 - if (winstate->numaggs > 0) -
1222 - { -
1223 - WindowObject agg_winobj = winstate->agg_winobj; -
1224 - int readptr_flags = 0; -
1225 - -
1226 - /* -
1227 - * If the frame head is potentially movable, or we have an EXCLUSION -
1228 - * clause, we might need to restart aggregation ... -
1229 - */ -
1230 - if (!(frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING) || -
1231 - (frameOptions & FRAMEOPTION_EXCLUSION)) -
1232 - { -
1233 - /* ... so create a mark pointer to track the frame head */ -
1234 - agg_winobj->markptr = tuplestore_alloc_read_pointer(winstate->buffer, 0); -
1235 - /* and the read pointer will need BACKWARD capability */ -
1236 - readptr_flags |= EXEC_FLAG_BACKWARD; -
1237 - } -
1238 - -
1239 - agg_winobj->readptr = tuplestore_alloc_read_pointer(winstate->buffer, -
1240 - readptr_flags); -
1241 - } -
1242 - -
1243 - /* create mark and read pointers for each real window function */ -
1244 - for (int i = 0; i < numfuncs; i++) -
1245 - { -
1246 - WindowStatePerFunc perfuncstate = &(winstate->perfunc[i]); -
1247 - -
1248 - if (!perfuncstate->plain_agg) -
1249 - { -
1250 - WindowObject winobj = perfuncstate->winobj; -
1251 - -
1252 - winobj->markptr = tuplestore_alloc_read_pointer(winstate->buffer, -
1253 - 0); -
1254 - winobj->readptr = tuplestore_alloc_read_pointer(winstate->buffer, -
1255 - EXEC_FLAG_BACKWARD); -
1256 - } -
1257 - } -
1258 - -
1259 - /* Create read/mark pointers for RPR navigation if needed */ 24cfb8dRow pattern recognition patch (executor and commands).
1260 4053 if (winstate->nav_winobj) 24cfb8dRow pattern recognition patch (executor and commands).
1261 - { 24cfb8dRow pattern recognition patch (executor and commands).
1262 - /* 24cfb8dRow pattern recognition patch (executor and commands).
1263 - * Allocate mark and read pointers for RPR navigation. 24cfb8dRow pattern recognition patch (executor and commands).
1264 - * 24cfb8dRow pattern recognition patch (executor and commands).
1265 - * If navMaxOffsetKind == RPR_NAV_OFFSET_FIXED, we advance the mark 24cfb8dRow pattern recognition patch (executor and commands).
1266 - * based on (currentpos - navMaxOffset) and optionally 24cfb8dRow pattern recognition patch (executor and commands).
1267 - * (nfaContext->matchStartRow + navFirstOffset), allowing 24cfb8dRow pattern recognition patch (executor and commands).
1268 - * tuplestore_trim() to free rows that are no longer reachable. 24cfb8dRow pattern recognition patch (executor and commands).
1269 - * 24cfb8dRow pattern recognition patch (executor and commands).
1270 - * RPR_NAV_OFFSET_NEEDS_EVAL is resolved at executor init; by this 24cfb8dRow pattern recognition patch (executor and commands).
1271 - * point it is either FIXED or RETAIN_ALL. 24cfb8dRow pattern recognition patch (executor and commands).
1272 - */ 24cfb8dRow pattern recognition patch (executor and commands).
1273 4928 winstate->nav_winobj->markptr = 24cfb8dRow pattern recognition patch (executor and commands).
1274 2464 tuplestore_alloc_read_pointer(winstate->buffer, 0); 24cfb8dRow pattern recognition patch (executor and commands).
1275 4928 winstate->nav_winobj->readptr = 24cfb8dRow pattern recognition patch (executor and commands).
1276 2464 tuplestore_alloc_read_pointer(winstate->buffer, 24cfb8dRow pattern recognition patch (executor and commands).
1277 - EXEC_FLAG_BACKWARD); 24cfb8dRow pattern recognition patch (executor and commands).
1278 2464 winstate->nav_winobj->markpos = 0; 24cfb8dRow pattern recognition patch (executor and commands).
1279 - } 24cfb8dRow pattern recognition patch (executor and commands).
1280 - 24cfb8dRow pattern recognition patch (executor and commands).
1281 - /* -
1282 - * If we are in RANGE or GROUPS mode, then determining frame boundaries -
1283 - * requires physical access to the frame endpoint rows, except in certain -
1284 - * degenerate cases. We create read pointers to point to those rows, to -
1285 - * simplify access and ensure that the tuplestore doesn't discard the -
1286 - * endpoint rows prematurely. (Must create pointers in exactly the same -
1287 - * cases that update_frameheadpos and update_frametailpos need them.) -
1288 - */ -
1289 - winstate->framehead_ptr = winstate->frametail_ptr = -1; /* if not used */ -
1290 - -
1291 - if (frameOptions & (FRAMEOPTION_RANGE | FRAMEOPTION_GROUPS)) -
1292 - { -
1293 - if (((frameOptions & FRAMEOPTION_START_CURRENT_ROW) && -
1294 - node->ordNumCols != 0) || -
1295 - (frameOptions & FRAMEOPTION_START_OFFSET)) -
1296 - winstate->framehead_ptr = -
1297 - tuplestore_alloc_read_pointer(winstate->buffer, 0); -
1298 - if (((frameOptions & FRAMEOPTION_END_CURRENT_ROW) && -
1299 - node->ordNumCols != 0) || -
1300 - (frameOptions & FRAMEOPTION_END_OFFSET)) -
1301 - winstate->frametail_ptr = -
1302 - tuplestore_alloc_read_pointer(winstate->buffer, 0); -
1303 - } -
1304 - -
1305 - /* -
1306 - * If we have an exclusion clause that requires knowing the boundaries of -
1307 - * the current row's peer group, we create a read pointer to track the -
1308 - * tail position of the peer group (i.e., first row of the next peer -
1309 - * group). The head position does not require its own pointer because we -
1310 - * maintain that as a side effect of advancing the current row. -
1311 - */ -
1312 - winstate->grouptail_ptr = -1; -
1313 - -
1314 - if ((frameOptions & (FRAMEOPTION_EXCLUDE_GROUP | -
1315 - FRAMEOPTION_EXCLUDE_TIES)) && -
1316 - node->ordNumCols != 0) -
1317 - { -
1318 - winstate->grouptail_ptr = -
1319 - tuplestore_alloc_read_pointer(winstate->buffer, 0); -
1320 - } -
1321 - } -
begin_partition() lines 1328-1435
Modified Lines Coverage: 5/5 lines (100.0%)
LineHitsSourceCommit
1328 - begin_partition(WindowAggState *winstate) -
1329 - { -
1330 - PlanState *outerPlan = outerPlanState(winstate); -
1331 - int numfuncs = winstate->numfuncs; -
1332 - -
1333 - winstate->partition_spooled = false; -
1334 - winstate->framehead_valid = false; -
1335 - winstate->frametail_valid = false; -
1336 - winstate->grouptail_valid = false; -
1337 12707 if (rpr_is_defined(winstate)) 24cfb8dRow pattern recognition patch (executor and commands).
1338 10240 clear_reduced_frame(winstate); 24cfb8dRow pattern recognition patch (executor and commands).
1339 - winstate->spooled_rows = 0; -
1340 - winstate->currentpos = 0; -
1341 - winstate->frameheadpos = 0; -
1342 - winstate->frametailpos = 0; -
1343 - winstate->currentgroup = 0; -
1344 - winstate->frameheadgroup = 0; -
1345 - winstate->frametailgroup = 0; -
1346 - winstate->groupheadpos = 0; -
1347 - winstate->grouptailpos = -1; /* see update_grouptailpos */ -
1348 - ExecClearTuple(winstate->agg_row_slot); -
1349 - if (winstate->framehead_slot) -
1350 - ExecClearTuple(winstate->framehead_slot); -
1351 - if (winstate->frametail_slot) -
1352 - ExecClearTuple(winstate->frametail_slot); -
1353 - -
1354 - /* -
1355 - * If this is the very first partition, we need to fetch the first input -
1356 - * row to store in first_part_slot. -
1357 - */ -
1358 - if (TupIsNull(winstate->first_part_slot)) -
1359 - { -
1360 - TupleTableSlot *outerslot = ExecProcNode(outerPlan); -
1361 - -
1362 - if (!TupIsNull(outerslot)) -
1363 - ExecCopySlot(winstate->first_part_slot, outerslot); -
1364 - else -
1365 - { -
1366 - /* outer plan is empty, so we have nothing to do */ -
1367 - winstate->partition_spooled = true; -
1368 - winstate->more_partitions = false; -
1369 - return; -
1370 - } -
1371 - } -
1372 - -
1373 - /* Create new tuplestore if not done already. */ -
1374 - if (unlikely(winstate->buffer == NULL)) -
1375 - prepare_tuplestore(winstate); -
1376 - -
1377 - winstate->next_partition = false; -
1378 - -
1379 - if (winstate->numaggs > 0) -
1380 - { -
1381 - WindowObject agg_winobj = winstate->agg_winobj; -
1382 - -
1383 - /* reset mark and see positions for aggregate functions */ -
1384 - agg_winobj->markpos = -1; -
1385 - agg_winobj->seekpos = -1; -
1386 - -
1387 - /* Also reset the row counters for aggregates */ -
1388 - winstate->aggregatedbase = 0; -
1389 - winstate->aggregatedupto = 0; -
1390 - } -
1391 - -
1392 - /* reset mark and seek positions for RPR navigation */ 24cfb8dRow pattern recognition patch (executor and commands).
1393 12683 if (winstate->nav_winobj) 24cfb8dRow pattern recognition patch (executor and commands).
1394 - { 24cfb8dRow pattern recognition patch (executor and commands).
1395 10228 winstate->nav_winobj->markpos = -1; 24cfb8dRow pattern recognition patch (executor and commands).
1396 10228 winstate->nav_winobj->seekpos = -1; 24cfb8dRow pattern recognition patch (executor and commands).
1397 - } 24cfb8dRow pattern recognition patch (executor and commands).
1398 - 24cfb8dRow pattern recognition patch (executor and commands).
1399 - /* reset mark and seek positions for each real window function */ -
1400 - for (int i = 0; i < numfuncs; i++) -
1401 - { -
1402 - WindowStatePerFunc perfuncstate = &(winstate->perfunc[i]); -
1403 - -
1404 - if (!perfuncstate->plain_agg) -
1405 - { -
1406 - WindowObject winobj = perfuncstate->winobj; -
1407 - -
1408 - winobj->markpos = -1; -
1409 - winobj->seekpos = -1; -
1410 - -
1411 - /* reset null map */ -
1412 - if (winobj->ignore_nulls == IGNORE_NULLS || -
1413 - winobj->ignore_nulls == PARSER_IGNORE_NULLS) -
1414 - { -
1415 - int numargs = perfuncstate->numArguments; -
1416 - -
1417 - for (int j = 0; j < numargs; j++) -
1418 - { -
1419 - int n = winobj->num_notnull_info[j]; -
1420 - -
1421 - if (n > 0) -
1422 - memset(winobj->notnull_info[j], 0, -
1423 - NN_POS_TO_BYTES(n)); -
1424 - } -
1425 - } -
1426 - } -
1427 - } -
1428 - -
1429 - /* -
1430 - * Store the first tuple into the tuplestore (it's always available now; -
1431 - * we either read it above, or saved it at the end of previous partition) -
1432 - */ -
1433 - tuplestore_puttupleslot(winstate->buffer, winstate->first_part_slot); -
1434 - winstate->spooled_rows++; -
1435 - } -
release_partition() lines 1536-1582
Modified Lines Coverage: 9/9 lines (100.0%)
LineHitsSourceCommit
1536 - release_partition(WindowAggState *winstate) -
1537 - { -
1538 - int i; -
1539 - -
1540 - for (i = 0; i < winstate->numfuncs; i++) -
1541 - { -
1542 - WindowStatePerFunc perfuncstate = &(winstate->perfunc[i]); -
1543 - -
1544 - /* Release any partition-local state of this window function */ -
1545 - if (perfuncstate->winobj) -
1546 - perfuncstate->winobj->localmem = NULL; -
1547 - } -
1548 - -
1549 - /* -
1550 - * Release all partition-local memory (in particular, any partition-local -
1551 - * state that we might have trashed our pointers to in the above loop, and -
1552 - * any aggregate temp data). We don't rely on retail pfree because some -
1553 - * aggregates might have allocated data we don't have direct pointers to. -
1554 - */ -
1555 - MemoryContextReset(winstate->partcontext); -
1556 - MemoryContextReset(winstate->aggcontext); -
1557 - for (i = 0; i < winstate->numaggs; i++) -
1558 - { -
1559 - if (winstate->peragg[i].aggcontext != winstate->aggcontext) -
1560 - MemoryContextReset(winstate->peragg[i].aggcontext); -
1561 - } -
1562 - -
1563 - if (winstate->buffer) -
1564 - tuplestore_clear(winstate->buffer); -
1565 - winstate->partition_spooled = false; -
1566 - winstate->next_partition = true; -
1567 - 24cfb8dRow pattern recognition patch (executor and commands).
1568 - /* Reset RPR match results */ 24cfb8dRow pattern recognition patch (executor and commands).
1569 17357 clear_reduced_frame(winstate); 24cfb8dRow pattern recognition patch (executor and commands).
1570 - 24cfb8dRow pattern recognition patch (executor and commands).
1571 - /* Reset NFA state for new partition */ 24cfb8dRow pattern recognition patch (executor and commands).
1572 17357 winstate->nfaContext = NULL; 24cfb8dRow pattern recognition patch (executor and commands).
1573 17357 winstate->nfaContextTail = NULL; 24cfb8dRow pattern recognition patch (executor and commands).
1574 17357 winstate->nfaContextFree = NULL; 24cfb8dRow pattern recognition patch (executor and commands).
1575 17357 winstate->nfaStateFree = NULL; 24cfb8dRow pattern recognition patch (executor and commands).
1576 17357 winstate->nfaLastProcessedRow = -1; 24cfb8dRow pattern recognition patch (executor and commands).
1577 17357 winstate->nfaStatesActive = 0; 24cfb8dRow pattern recognition patch (executor and commands).
1578 17357 winstate->nfaContextsActive = 0; 24cfb8dRow pattern recognition patch (executor and commands).
1579 - 24cfb8dRow pattern recognition patch (executor and commands).
1580 - /* Invalidate the nav slot position cache for the new partition. */ 24cfb8dRow pattern recognition patch (executor and commands).
1581 17357 winstate->nav_slot_pos = -1; 24cfb8dRow pattern recognition patch (executor and commands).
1582 - } -
calculate_frame_offsets() lines 2311-2390
Modified Lines Coverage: 2/2 lines (100.0%)
LineHitsSourceCommit
2311 - calculate_frame_offsets(PlanState *pstate) -
2312 - { -
2313 - WindowAggState *winstate = castNode(WindowAggState, pstate); -
2314 - ExprContext *econtext; -
2315 - int frameOptions = winstate->frameOptions; -
2316 - Datum value; -
2317 - bool isnull; -
2318 - int16 len; -
2319 - bool byval; -
2320 - -
2321 - /* Ensure we've not been called before for this scan */ -
2322 - Assert(winstate->all_first); -
2323 - -
2324 - econtext = winstate->ss.ps.ps_ExprContext; -
2325 - -
2326 - if (frameOptions & FRAMEOPTION_START_OFFSET) -
2327 - { -
2328 - Assert(winstate->startOffset != NULL); -
2329 - value = ExecEvalExprSwitchContext(winstate->startOffset, -
2330 - econtext, -
2331 - &isnull); -
2332 - if (isnull) -
2333 - ereport(ERROR, -
2334 - (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), -
2335 - errmsg("frame starting offset must not be null"))); -
2336 - /* copy value into query-lifespan context */ -
2337 - get_typlenbyval(exprType((Node *) winstate->startOffset->expr), -
2338 - &len, -
2339 - &byval); -
2340 - winstate->startOffsetValue = datumCopy(value, byval, len); -
2341 - if (frameOptions & (FRAMEOPTION_ROWS | FRAMEOPTION_GROUPS)) -
2342 - { -
2343 - /* value is known to be int8 */ -
2344 - int64 offset = DatumGetInt64(value); -
2345 - -
2346 - if (offset < 0) -
2347 - ereport(ERROR, -
2348 - (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), -
2349 - errmsg("frame starting offset must not be negative"))); -
2350 - } -
2351 - } -
2352 - -
2353 - if (frameOptions & FRAMEOPTION_END_OFFSET) -
2354 - { -
2355 - Assert(winstate->endOffset != NULL); -
2356 - value = ExecEvalExprSwitchContext(winstate->endOffset, -
2357 - econtext, -
2358 - &isnull); -
2359 - if (isnull) -
2360 - ereport(ERROR, -
2361 - (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), -
2362 - errmsg("frame ending offset must not be null"))); -
2363 - /* copy value into query-lifespan context */ -
2364 - get_typlenbyval(exprType((Node *) winstate->endOffset->expr), -
2365 - &len, -
2366 - &byval); -
2367 - winstate->endOffsetValue = datumCopy(value, byval, len); -
2368 - if (frameOptions & (FRAMEOPTION_ROWS | FRAMEOPTION_GROUPS)) -
2369 - { -
2370 - /* value is known to be int8 */ -
2371 - int64 offset = DatumGetInt64(value); -
2372 - -
2373 - if (offset < 0) -
2374 - ereport(ERROR, -
2375 - (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), -
2376 - errmsg("frame ending offset must not be negative"))); -
2377 - 24cfb8dRow pattern recognition patch (executor and commands).
2378 - /* 24cfb8dRow pattern recognition patch (executor and commands).
2379 - * Row pattern recognition forbids a zero-length frame end; 24cfb8dRow pattern recognition patch (executor and commands).
2380 - * checked here so a non-constant offset (e.g. a bind parameter) 24cfb8dRow pattern recognition patch (executor and commands).
2381 - * is caught, not just a literal 0. 24cfb8dRow pattern recognition patch (executor and commands).
2382 - */ 24cfb8dRow pattern recognition patch (executor and commands).
2383 356 if (winstate->rpPattern != NULL && offset == 0) 24cfb8dRow pattern recognition patch (executor and commands).
2384 8 ereport(ERROR, 24cfb8dRow pattern recognition patch (executor and commands).
2385 - errcode(ERRCODE_WINDOWING_ERROR), 24cfb8dRow pattern recognition patch (executor and commands).
2386 - errmsg("frame ending offset must be positive with row pattern recognition")); 24cfb8dRow pattern recognition patch (executor and commands).
2387 - } -
2388 - } -
2389 - winstate->all_first = false; -
2390 - } -
ExecWindowAgg() lines 2402-2680
Modified Lines Coverage: 5/5 lines (100.0%)
LineHitsSourceCommit
2402 - ExecWindowAgg(PlanState *pstate) -
2403 - { -
2404 - WindowAggState *winstate = castNode(WindowAggState, pstate); -
2405 - TupleTableSlot *slot; -
2406 - ExprContext *econtext; -
2407 - int i; -
2408 - int numfuncs; -
2409 - -
2410 - CHECK_FOR_INTERRUPTS(); -
2411 - -
2412 - if (winstate->status == WINDOWAGG_DONE) -
2413 - return NULL; -
2414 - -
2415 - /* -
2416 - * Compute frame offset values, if any, during first call (or after a -
2417 - * rescan). These are assumed to hold constant throughout the scan; if -
2418 - * user gives us a volatile expression, we'll only use its initial value. -
2419 - */ -
2420 - if (unlikely(winstate->all_first)) -
2421 - calculate_frame_offsets(pstate); -
2422 - -
2423 - /* We need to loop as the runCondition or qual may filter out tuples */ -
2424 - for (;;) -
2425 - { -
2426 - if (winstate->next_partition) -
2427 - { -
2428 - /* Initialize for first partition and set current row = 0 */ -
2429 - begin_partition(winstate); -
2430 - /* If there are no input rows, we'll detect that and exit below */ -
2431 - } -
2432 - else -
2433 - { -
2434 - /* Advance current row within partition */ -
2435 - winstate->currentpos++; -
2436 - /* This might mean that the frame moves, too */ -
2437 - winstate->framehead_valid = false; -
2438 - winstate->frametail_valid = false; -
2439 - /* we don't need to invalidate grouptail here; see below */ -
2440 - } -
2441 - -
2442 - /* -
2443 - * Spool all tuples up to and including the current row, if we haven't -
2444 - * already -
2445 - */ -
2446 - spool_tuples(winstate, winstate->currentpos); -
2447 - -
2448 - /* Move to the next partition if we reached the end of this partition */ -
2449 - if (winstate->partition_spooled && -
2450 - winstate->currentpos >= winstate->spooled_rows) -
2451 - { -
2452 - release_partition(winstate); -
2453 - -
2454 - if (winstate->more_partitions) -
2455 - { -
2456 - begin_partition(winstate); -
2457 - Assert(winstate->spooled_rows > 0); -
2458 - -
2459 - /* Come out of pass-through mode when changing partition */ -
2460 - winstate->status = WINDOWAGG_RUN; -
2461 - } -
2462 - else -
2463 - { -
2464 - /* No further partitions? We're done */ -
2465 - winstate->status = WINDOWAGG_DONE; -
2466 - return NULL; -
2467 - } -
2468 - } -
2469 - -
2470 - /* final output execution is in ps_ExprContext */ -
2471 - econtext = winstate->ss.ps.ps_ExprContext; -
2472 - -
2473 - /* Clear the per-output-tuple context for current row */ -
2474 - ResetExprContext(econtext); -
2475 - -
2476 - /* -
2477 - * Read the current row from the tuplestore, and save in -
2478 - * ScanTupleSlot. (We can't rely on the outerplan's output slot -
2479 - * because we may have to read beyond the current row. Also, we have -
2480 - * to actually copy the row out of the tuplestore, since window -
2481 - * function evaluation might cause the tuplestore to dump its state to -
2482 - * disk.) -
2483 - * -
2484 - * In GROUPS mode, or when tracking a group-oriented exclusion clause, -
2485 - * we must also detect entering a new peer group and update associated -
2486 - * state when that happens. We use temp_slot_2 to temporarily hold -
2487 - * the previous row for this purpose. -
2488 - * -
2489 - * Current row must be in the tuplestore, since we spooled it above. -
2490 - */ -
2491 - tuplestore_select_read_pointer(winstate->buffer, winstate->current_ptr); -
2492 - if ((winstate->frameOptions & (FRAMEOPTION_GROUPS | -
2493 - FRAMEOPTION_EXCLUDE_GROUP | -
2494 - FRAMEOPTION_EXCLUDE_TIES)) && -
2495 - winstate->currentpos > 0) -
2496 - { -
2497 - ExecCopySlot(winstate->temp_slot_2, winstate->ss.ss_ScanTupleSlot); -
2498 - if (!tuplestore_gettupleslot(winstate->buffer, true, true, -
2499 - winstate->ss.ss_ScanTupleSlot)) -
2500 - elog(ERROR, "unexpected end of tuplestore"); -
2501 - if (!are_peers(winstate, winstate->temp_slot_2, -
2502 - winstate->ss.ss_ScanTupleSlot)) -
2503 - { -
2504 - winstate->currentgroup++; -
2505 - winstate->groupheadpos = winstate->currentpos; -
2506 - winstate->grouptail_valid = false; -
2507 - } -
2508 - ExecClearTuple(winstate->temp_slot_2); -
2509 - } -
2510 - else -
2511 - { -
2512 - if (!tuplestore_gettupleslot(winstate->buffer, true, true, -
2513 - winstate->ss.ss_ScanTupleSlot)) -
2514 - elog(ERROR, "unexpected end of tuplestore"); -
2515 - } -
2516 - -
2517 - /* don't evaluate the window functions when we're in pass-through mode */ -
2518 - if (winstate->status == WINDOWAGG_RUN) -
2519 - { -
2520 - /* 24cfb8dRow pattern recognition patch (executor and commands).
2521 - * If RPR is defined and skip mode is next row, clear the current 24cfb8dRow pattern recognition patch (executor and commands).
2522 - * match so the next row triggers re-evaluation. 24cfb8dRow pattern recognition patch (executor and commands).
2523 - */ 24cfb8dRow pattern recognition patch (executor and commands).
2524 1592912 if (rpr_is_defined(winstate)) 24cfb8dRow pattern recognition patch (executor and commands).
2525 - { 24cfb8dRow pattern recognition patch (executor and commands).
2526 988964 if (winstate->rpSkipTo == ST_NEXT_ROW) 24cfb8dRow pattern recognition patch (executor and commands).
2527 7536 clear_reduced_frame(winstate); 24cfb8dRow pattern recognition patch (executor and commands).
2528 - 0ed285dDrive RPR row pattern matching once per row
2529 - /* 0ed285dDrive RPR row pattern matching once per row
2530 - * Drive the row pattern match every row, so it tracks the row 0ed285dDrive RPR row pattern matching once per row
2531 - * scan rather than frame access: a window function that skips 0ed285dDrive RPR row pattern matching once per row
2532 - * the frame (e.g. nth_value() with a NULL offset) must not 0ed285dDrive RPR row pattern matching once per row
2533 - * leave the match state behind currentpos. 0ed285dDrive RPR row pattern matching once per row
2534 - */ 0ed285dDrive RPR row pattern matching once per row
2535 988964 Assert(winstate->nav_winobj != NULL); 0ed285dDrive RPR row pattern matching once per row
2536 988964 (void) row_is_in_reduced_frame(winstate->nav_winobj, 0ed285dDrive RPR row pattern matching once per row
2537 - winstate->currentpos); 0ed285dDrive RPR row pattern matching once per row
2538 - } 24cfb8dRow pattern recognition patch (executor and commands).
2539 - 24cfb8dRow pattern recognition patch (executor and commands).
2540 - /* -
2541 - * Evaluate true window functions -
2542 - */ -
2543 - numfuncs = winstate->numfuncs; -
2544 - for (i = 0; i < numfuncs; i++) -
2545 - { -
2546 - WindowStatePerFunc perfuncstate = &(winstate->perfunc[i]); -
2547 - -
2548 - if (perfuncstate->plain_agg) -
2549 - continue; -
2550 - eval_windowfunction(winstate, perfuncstate, -
2551 - &(econtext->ecxt_aggvalues[perfuncstate->wfuncstate->wfuncno]), -
2552 - &(econtext->ecxt_aggnulls[perfuncstate->wfuncstate->wfuncno])); -
2553 - } -
2554 - -
2555 - /* -
2556 - * Evaluate aggregates -
2557 - */ -
2558 - if (winstate->numaggs > 0) -
2559 - eval_windowaggregates(winstate); -
2560 - } -
2561 - -
2562 - /* -
2563 - * If we have created auxiliary read pointers for the frame or group -
2564 - * boundaries, force them to be kept up-to-date, because we don't know -
2565 - * whether the window function(s) will do anything that requires that. -
2566 - * Failing to advance the pointers would result in being unable to -
2567 - * trim data from the tuplestore, which is bad. (If we could know in -
2568 - * advance whether the window functions will use frame boundary info, -
2569 - * we could skip creating these pointers in the first place ... but -
2570 - * unfortunately the window function API doesn't require that.) -
2571 - */ -
2572 - if (winstate->framehead_ptr >= 0) -
2573 - update_frameheadpos(winstate); -
2574 - if (winstate->frametail_ptr >= 0) -
2575 - update_frametailpos(winstate); -
2576 - if (winstate->grouptail_ptr >= 0) -
2577 - update_grouptailpos(winstate); -
2578 - -
2579 - /* -
2580 - * Truncate any no-longer-needed rows from the tuplestore. -
2581 - */ -
2582 - tuplestore_trim(winstate->buffer); -
2583 - -
2584 - /* -
2585 - * Form and return a projection tuple using the windowfunc results and -
2586 - * the current row. Setting ecxt_outertuple arranges that any Vars -
2587 - * will be evaluated with respect to that row. -
2588 - */ -
2589 - econtext->ecxt_outertuple = winstate->ss.ss_ScanTupleSlot; -
2590 - -
2591 - slot = ExecProject(winstate->ss.ps.ps_ProjInfo); -
2592 - -
2593 - if (winstate->status == WINDOWAGG_RUN) -
2594 - { -
2595 - econtext->ecxt_scantuple = slot; -
2596 - -
2597 - /* -
2598 - * Now evaluate the run condition to see if we need to go into -
2599 - * pass-through mode, or maybe stop completely. -
2600 - */ -
2601 - if (!ExecQual(winstate->runcondition, econtext)) -
2602 - { -
2603 - /* -
2604 - * Determine which mode to move into. If there is no -
2605 - * PARTITION BY clause and we're the top-level WindowAgg then -
2606 - * we're done. This tuple and any future tuples cannot -
2607 - * possibly match the runcondition. However, when there is a -
2608 - * PARTITION BY clause or we're not the top-level window we -
2609 - * can't just stop as we need to either process other -
2610 - * partitions or ensure WindowAgg nodes above us receive all -
2611 - * of the tuples they need to process their WindowFuncs. -
2612 - */ -
2613 - if (winstate->use_pass_through) -
2614 - { -
2615 - /* -
2616 - * When switching into a pass-through mode, we'd better -
2617 - * NULLify the aggregate results as these are no longer -
2618 - * updated and NULLifying them avoids the old stale -
2619 - * results lingering. Some of these might be byref types -
2620 - * so we can't have them pointing to free'd memory. The -
2621 - * planner insisted that quals used in the runcondition -
2622 - * are strict, so the top-level WindowAgg will always -
2623 - * filter these NULLs out in the filter clause. -
2624 - */ -
2625 - numfuncs = winstate->numfuncs; -
2626 - for (i = 0; i < numfuncs; i++) -
2627 - { -
2628 - econtext->ecxt_aggvalues[i] = (Datum) 0; -
2629 - econtext->ecxt_aggnulls[i] = true; -
2630 - } -
2631 - -
2632 - /* -
2633 - * STRICT pass-through mode is required for the top window -
2634 - * when there is a PARTITION BY clause. Otherwise we must -
2635 - * ensure we store tuples that don't match the -
2636 - * runcondition so they're available to WindowAggs above. -
2637 - */ -
2638 - if (winstate->top_window) -
2639 - { -
2640 - winstate->status = WINDOWAGG_PASSTHROUGH_STRICT; -
2641 - continue; -
2642 - } -
2643 - else -
2644 - { -
2645 - winstate->status = WINDOWAGG_PASSTHROUGH; -
2646 - } -
2647 - } -
2648 - else -
2649 - { -
2650 - /* -
2651 - * Pass-through not required. We can just return NULL. -
2652 - * Nothing else will match the runcondition. -
2653 - */ -
2654 - winstate->status = WINDOWAGG_DONE; -
2655 - return NULL; -
2656 - } -
2657 - } -
2658 - -
2659 - /* -
2660 - * Filter out any tuples we don't need in the top-level WindowAgg. -
2661 - */ -
2662 - if (!ExecQual(winstate->ss.ps.qual, econtext)) -
2663 - { -
2664 - InstrCountFiltered1(winstate, 1); -
2665 - continue; -
2666 - } -
2667 - -
2668 - break; -
2669 - } -
2670 - -
2671 - /* -
2672 - * When not in WINDOWAGG_RUN mode, we must still return this tuple if -
2673 - * we're anything apart from the top window. -
2674 - */ -
2675 - else if (!winstate->top_window) -
2676 - break; -
2677 - } -
2678 - -
2679 - return slot; -
2680 - } -
ExecInitWindowAgg() lines 2690-3117
Modified Lines Coverage: 58/58 lines (100.0%)
LineHitsSourceCommit
2690 - ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) -
2691 - { -
2692 - WindowAggState *winstate; -
2693 - Plan *outerPlan; -
2694 - ExprContext *econtext; -
2695 - ExprContext *tmpcontext; -
2696 - WindowStatePerFunc perfunc; -
2697 - WindowStatePerAgg peragg; -
2698 - int frameOptions = node->frameOptions; -
2699 - int numfuncs, -
2700 - wfuncno, -
2701 - numaggs, -
2702 - aggno; -
2703 - TupleDesc scanDesc; -
2704 - ListCell *l; -
2705 - -
2706 - /* check for unsupported flags */ -
2707 - Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); -
2708 - -
2709 - /* -
2710 - * create state structure -
2711 - */ -
2712 - winstate = makeNode(WindowAggState); -
2713 - winstate->ss.ps.plan = (Plan *) node; -
2714 - winstate->ss.ps.state = estate; -
2715 - winstate->ss.ps.ExecProcNode = ExecWindowAgg; -
2716 - -
2717 - /* copy frame options to state node for easy access */ -
2718 - winstate->frameOptions = frameOptions; -
2719 - -
2720 - /* -
2721 - * Create expression contexts. We need two, one for per-input-tuple -
2722 - * processing and one for per-output-tuple processing, plus an optional a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2723 - * third for row pattern recognition DEFINE evaluation (built just below a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2724 - * when a DEFINE clause is present). We cheat a little by using a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2725 - * ExecAssignExprContext() to build them all. Each call overwrites a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2726 - * ps_ExprContext, so the last call must establish the output context. a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2727 - */ -
2728 - ExecAssignExprContext(estate, &winstate->ss.ps); -
2729 - tmpcontext = winstate->ss.ps.ps_ExprContext; -
2730 - winstate->tmpcontext = tmpcontext; -
2731 - a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2732 - /* a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2733 - * Row pattern recognition evaluates DEFINE clauses in a third context, a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2734 - * reset before each DEFINE evaluation pass. It must be distinct from a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2735 - * tmpcontext and ps_ExprContext so its reset frees neither input nor a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2736 - * output tuple memory. a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2737 - */ a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2738 5034 if (node->defineClause != NIL) a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2739 - { a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2740 3048 ExecAssignExprContext(estate, &winstate->ss.ps); a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2741 3048 winstate->rprContext = winstate->ss.ps.ps_ExprContext; a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2742 - } a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2743 - a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
2744 - ExecAssignExprContext(estate, &winstate->ss.ps); -
2745 - -
2746 - /* Create long-lived context for storage of partition-local memory etc */ -
2747 - winstate->partcontext = -
2748 - AllocSetContextCreate(CurrentMemoryContext, -
2749 - "WindowAgg Partition", -
2750 - ALLOCSET_DEFAULT_SIZES); -
2751 - -
2752 - /* -
2753 - * Create mid-lived context for aggregate trans values etc. -
2754 - * -
2755 - * Note that moving aggregates each use their own private context, not -
2756 - * this one. -
2757 - */ -
2758 - winstate->aggcontext = -
2759 - AllocSetContextCreate(CurrentMemoryContext, -
2760 - "WindowAgg Aggregates", -
2761 - ALLOCSET_DEFAULT_SIZES); -
2762 - -
2763 - /* Only the top-level WindowAgg may have a qual */ -
2764 - Assert(node->plan.qual == NIL || node->topWindow); -
2765 - -
2766 - /* Initialize the qual */ -
2767 - winstate->ss.ps.qual = ExecInitQual(node->plan.qual, -
2768 - (PlanState *) winstate); -
2769 - -
2770 - /* -
2771 - * Setup the run condition, if we received one from the query planner. -
2772 - * When set, this may allow us to move into pass-through mode so that we -
2773 - * don't have to perform any further evaluation of WindowFuncs in the -
2774 - * current partition or possibly stop returning tuples altogether when all -
2775 - * tuples are in the same partition. -
2776 - */ -
2777 - winstate->runcondition = ExecInitQual(node->runCondition, -
2778 - (PlanState *) winstate); -
2779 - -
2780 - /* -
2781 - * When we're not the top-level WindowAgg node or we are but have a -
2782 - * PARTITION BY clause we must move into one of the WINDOWAGG_PASSTHROUGH* -
2783 - * modes when the runCondition becomes false. -
2784 - */ -
2785 - winstate->use_pass_through = !node->topWindow || node->partNumCols > 0; -
2786 - -
2787 - /* remember if we're the top-window or we are below the top-window */ -
2788 - winstate->top_window = node->topWindow; -
2789 - -
2790 - /* -
2791 - * initialize child nodes -
2792 - */ -
2793 - outerPlan = outerPlan(node); -
2794 - outerPlanState(winstate) = ExecInitNode(outerPlan, estate, eflags); -
2795 - -
2796 - /* -
2797 - * initialize source tuple type (which is also the tuple type that we'll -
2798 - * store in the tuplestore and use in all our working slots). -
2799 - */ -
2800 - ExecCreateScanSlotFromOuterPlan(estate, &winstate->ss, &TTSOpsMinimalTuple); -
2801 - scanDesc = winstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor; -
2802 - -
2803 - /* the outer tuple isn't the child's tuple, but always a minimal tuple */ -
2804 - winstate->ss.ps.outeropsset = true; -
2805 - winstate->ss.ps.outerops = &TTSOpsMinimalTuple; -
2806 - winstate->ss.ps.outeropsfixed = true; -
2807 - -
2808 - /* -
2809 - * tuple table initialization -
2810 - */ -
2811 - winstate->first_part_slot = ExecInitExtraTupleSlot(estate, scanDesc, -
2812 - &TTSOpsMinimalTuple); -
2813 - winstate->agg_row_slot = ExecInitExtraTupleSlot(estate, scanDesc, -
2814 - &TTSOpsMinimalTuple); -
2815 - winstate->temp_slot_1 = ExecInitExtraTupleSlot(estate, scanDesc, -
2816 - &TTSOpsMinimalTuple); -
2817 - winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc, -
2818 - &TTSOpsMinimalTuple); -
2819 - -
2820 5034 if (node->rpPattern != NULL) 24cfb8dRow pattern recognition patch (executor and commands).
2821 - { 24cfb8dRow pattern recognition patch (executor and commands).
2822 3048 winstate->nav_slot = ExecInitExtraTupleSlot(estate, scanDesc, 24cfb8dRow pattern recognition patch (executor and commands).
2823 - &TTSOpsMinimalTuple); 24cfb8dRow pattern recognition patch (executor and commands).
2824 3048 winstate->nav_slot_pos = -1; 24cfb8dRow pattern recognition patch (executor and commands).
2825 - 24cfb8dRow pattern recognition patch (executor and commands).
2826 3048 winstate->nav_null_slot = ExecInitExtraTupleSlot(estate, scanDesc, 24cfb8dRow pattern recognition patch (executor and commands).
2827 - &TTSOpsMinimalTuple); 24cfb8dRow pattern recognition patch (executor and commands).
2828 3048 winstate->nav_null_slot = ExecStoreAllNullTuple(winstate->nav_null_slot); 24cfb8dRow pattern recognition patch (executor and commands).
2829 - 24cfb8dRow pattern recognition patch (executor and commands).
2830 3048 winstate->nav_saved_outertuple = NULL; 24cfb8dRow pattern recognition patch (executor and commands).
2831 3048 winstate->nav_match_start = 0; 24cfb8dRow pattern recognition patch (executor and commands).
2832 - } 24cfb8dRow pattern recognition patch (executor and commands).
2833 - 24cfb8dRow pattern recognition patch (executor and commands).
2834 - /* -
2835 - * create frame head and tail slots only if needed (must create slots in -
2836 - * exactly the same cases that update_frameheadpos and update_frametailpos -
2837 - * need them) -
2838 - */ -
2839 - winstate->framehead_slot = winstate->frametail_slot = NULL; -
2840 - -
2841 - if (frameOptions & (FRAMEOPTION_RANGE | FRAMEOPTION_GROUPS)) -
2842 - { -
2843 - if (((frameOptions & FRAMEOPTION_START_CURRENT_ROW) && -
2844 - node->ordNumCols != 0) || -
2845 - (frameOptions & FRAMEOPTION_START_OFFSET)) -
2846 - winstate->framehead_slot = ExecInitExtraTupleSlot(estate, scanDesc, -
2847 - &TTSOpsMinimalTuple); -
2848 - if (((frameOptions & FRAMEOPTION_END_CURRENT_ROW) && -
2849 - node->ordNumCols != 0) || -
2850 - (frameOptions & FRAMEOPTION_END_OFFSET)) -
2851 - winstate->frametail_slot = ExecInitExtraTupleSlot(estate, scanDesc, -
2852 - &TTSOpsMinimalTuple); -
2853 - } -
2854 - -
2855 - /* -
2856 - * Initialize result slot, type and projection. -
2857 - */ -
2858 - ExecInitResultTupleSlotTL(&winstate->ss.ps, &TTSOpsVirtual); -
2859 - ExecAssignProjectionInfo(&winstate->ss.ps, NULL); -
2860 - -
2861 - /* Set up data for comparing tuples */ -
2862 - if (node->partNumCols > 0) -
2863 - winstate->partEqfunction = -
2864 - execTuplesMatchPrepare(scanDesc, -
2865 - node->partNumCols, -
2866 - node->partColIdx, -
2867 - node->partOperators, -
2868 - node->partCollations, -
2869 - &winstate->ss.ps); -
2870 - -
2871 - if (node->ordNumCols > 0) -
2872 - winstate->ordEqfunction = -
2873 - execTuplesMatchPrepare(scanDesc, -
2874 - node->ordNumCols, -
2875 - node->ordColIdx, -
2876 - node->ordOperators, -
2877 - node->ordCollations, -
2878 - &winstate->ss.ps); -
2879 - -
2880 - /* -
2881 - * WindowAgg nodes use aggvalues and aggnulls as well as Agg nodes. -
2882 - */ -
2883 - numfuncs = winstate->numfuncs; -
2884 - numaggs = winstate->numaggs; -
2885 - econtext = winstate->ss.ps.ps_ExprContext; -
2886 - econtext->ecxt_aggvalues = palloc0_array(Datum, numfuncs); -
2887 - econtext->ecxt_aggnulls = palloc0_array(bool, numfuncs); -
2888 - -
2889 - /* -
2890 - * allocate per-wfunc/per-agg state information. -
2891 - */ -
2892 - perfunc = palloc0_array(WindowStatePerFuncData, numfuncs); -
2893 - peragg = palloc0_array(WindowStatePerAggData, numaggs); -
2894 - winstate->perfunc = perfunc; -
2895 - winstate->peragg = peragg; -
2896 - -
2897 - wfuncno = -1; -
2898 - aggno = -1; -
2899 - foreach(l, winstate->funcs) -
2900 - { -
2901 - WindowFuncExprState *wfuncstate = (WindowFuncExprState *) lfirst(l); -
2902 - WindowFunc *wfunc = wfuncstate->wfunc; -
2903 - WindowStatePerFunc perfuncstate; -
2904 - AclResult aclresult; -
2905 - int i; -
2906 - -
2907 - if (wfunc->winref != node->winref) /* planner screwed up? */ -
2908 - elog(ERROR, "WindowFunc with winref %u assigned to WindowAgg with winref %u", -
2909 - wfunc->winref, node->winref); -
2910 - -
2911 - /* -
2912 - * Look for a previous duplicate window function, which needs the same -
2913 - * ignore_nulls value -
2914 - */ -
2915 - for (i = 0; i <= wfuncno; i++) -
2916 - { -
2917 - if (equal(wfunc, perfunc[i].wfunc) && -
2918 - !contain_volatile_functions((Node *) wfunc)) -
2919 - break; -
2920 - } -
2921 - if (i <= wfuncno && wfunc->ignore_nulls == perfunc[i].ignore_nulls) -
2922 - { -
2923 - /* Found a match to an existing entry, so just mark it */ -
2924 - wfuncstate->wfuncno = i; -
2925 - continue; -
2926 - } -
2927 - -
2928 - /* Nope, so assign a new PerAgg record */ -
2929 - perfuncstate = &perfunc[++wfuncno]; -
2930 - -
2931 - /* Mark WindowFunc state node with assigned index in the result array */ -
2932 - wfuncstate->wfuncno = wfuncno; -
2933 - -
2934 - /* Check permission to call window function */ -
2935 - aclresult = object_aclcheck(ProcedureRelationId, wfunc->winfnoid, GetUserId(), -
2936 - ACL_EXECUTE); -
2937 - if (aclresult != ACLCHECK_OK) -
2938 - aclcheck_error(aclresult, OBJECT_FUNCTION, -
2939 - get_func_name(wfunc->winfnoid)); -
2940 - InvokeFunctionExecuteHook(wfunc->winfnoid); -
2941 - -
2942 - /* Fill in the perfuncstate data */ -
2943 - perfuncstate->wfuncstate = wfuncstate; -
2944 - perfuncstate->wfunc = wfunc; -
2945 - perfuncstate->numArguments = list_length(wfuncstate->args); -
2946 - perfuncstate->winCollation = wfunc->inputcollid; -
2947 - -
2948 - get_typlenbyval(wfunc->wintype, -
2949 - &perfuncstate->resulttypeLen, -
2950 - &perfuncstate->resulttypeByVal); -
2951 - -
2952 - /* -
2953 - * If it's really just a plain aggregate function, we'll emulate the -
2954 - * Agg environment for it. -
2955 - */ -
2956 - perfuncstate->plain_agg = wfunc->winagg; -
2957 - if (wfunc->winagg) -
2958 - { -
2959 - WindowStatePerAgg peraggstate; -
2960 - -
2961 - perfuncstate->aggno = ++aggno; -
2962 - peraggstate = &winstate->peragg[aggno]; -
2963 - initialize_peragg(winstate, wfunc, peraggstate); -
2964 - peraggstate->wfuncno = wfuncno; -
2965 - } -
2966 - else -
2967 - { -
2968 - WindowObject winobj = makeNode(WindowObjectData); -
2969 - -
2970 - winobj->winstate = winstate; -
2971 - winobj->argstates = wfuncstate->args; -
2972 - winobj->localmem = NULL; -
2973 - perfuncstate->winobj = winobj; -
2974 - winobj->ignore_nulls = wfunc->ignore_nulls; -
2975 - init_notnull_info(winobj, perfuncstate); -
2976 - -
2977 - /* It's a real window function, so set up to call it. */ -
2978 - fmgr_info_cxt(wfunc->winfnoid, &perfuncstate->flinfo, -
2979 - econtext->ecxt_per_query_memory); -
2980 - fmgr_info_set_expr((Node *) wfunc, &perfuncstate->flinfo); -
2981 - } -
2982 - } -
2983 - -
2984 - /* Update numfuncs, numaggs to match number of unique functions found */ -
2985 - winstate->numfuncs = wfuncno + 1; -
2986 - winstate->numaggs = aggno + 1; -
2987 - -
2988 - /* Set up WindowObject for aggregates, if needed */ -
2989 - if (winstate->numaggs > 0) -
2990 - { -
2991 - WindowObject agg_winobj = makeNode(WindowObjectData); -
2992 - -
2993 - agg_winobj->winstate = winstate; -
2994 - agg_winobj->argstates = NIL; -
2995 - agg_winobj->localmem = NULL; -
2996 - /* make sure markptr = -1 to invalidate. It may not get used */ -
2997 - agg_winobj->markptr = -1; -
2998 - agg_winobj->readptr = -1; -
2999 - winstate->agg_winobj = agg_winobj; -
3000 - } -
3001 - -
3002 - /* 24cfb8dRow pattern recognition patch (executor and commands).
3003 - * Set up WindowObject for RPR navigation opcodes. This is separate from 24cfb8dRow pattern recognition patch (executor and commands).
3004 - * agg_winobj because it needs its own read pointer to avoid interfering 24cfb8dRow pattern recognition patch (executor and commands).
3005 - * with aggregate processing. 24cfb8dRow pattern recognition patch (executor and commands).
3006 - */ 24cfb8dRow pattern recognition patch (executor and commands).
3007 5034 if (node->rpPattern != NULL) 24cfb8dRow pattern recognition patch (executor and commands).
3008 - { 24cfb8dRow pattern recognition patch (executor and commands).
3009 3048 WindowObject nav_winobj = makeNode(WindowObjectData); 24cfb8dRow pattern recognition patch (executor and commands).
3010 - 24cfb8dRow pattern recognition patch (executor and commands).
3011 3048 nav_winobj->winstate = winstate; 24cfb8dRow pattern recognition patch (executor and commands).
3012 3048 nav_winobj->argstates = NIL; 24cfb8dRow pattern recognition patch (executor and commands).
3013 3048 nav_winobj->localmem = NULL; 24cfb8dRow pattern recognition patch (executor and commands).
3014 3048 nav_winobj->markptr = -1; 24cfb8dRow pattern recognition patch (executor and commands).
3015 3048 nav_winobj->readptr = -1; 24cfb8dRow pattern recognition patch (executor and commands).
3016 3048 winstate->nav_winobj = nav_winobj; 24cfb8dRow pattern recognition patch (executor and commands).
3017 - } 24cfb8dRow pattern recognition patch (executor and commands).
3018 - 24cfb8dRow pattern recognition patch (executor and commands).
3019 - /* Set the status to running */ -
3020 - winstate->status = WINDOWAGG_RUN; -
3021 - -
3022 - /* initialize frame bound offset expressions */ -
3023 - winstate->startOffset = ExecInitExpr((Expr *) node->startOffset, -
3024 - (PlanState *) winstate); -
3025 - winstate->endOffset = ExecInitExpr((Expr *) node->endOffset, -
3026 - (PlanState *) winstate); -
3027 - -
3028 - /* Lookup in_range support functions if needed */ -
3029 - if (OidIsValid(node->startInRangeFunc)) -
3030 - fmgr_info(node->startInRangeFunc, &winstate->startInRangeFunc); -
3031 - if (OidIsValid(node->endInRangeFunc)) -
3032 - fmgr_info(node->endInRangeFunc, &winstate->endInRangeFunc); -
3033 - winstate->inRangeColl = node->inRangeColl; -
3034 - winstate->inRangeAsc = node->inRangeAsc; -
3035 - winstate->inRangeNullsFirst = node->inRangeNullsFirst; -
3036 - -
3037 - /* Set up SKIP TO type */ 24cfb8dRow pattern recognition patch (executor and commands).
3038 5034 winstate->rpSkipTo = node->rpSkipTo; 24cfb8dRow pattern recognition patch (executor and commands).
3039 - /* Set up row pattern recognition PATTERN clause (compiled NFA) */ 24cfb8dRow pattern recognition patch (executor and commands).
3040 5034 winstate->rpPattern = node->rpPattern; 24cfb8dRow pattern recognition patch (executor and commands).
3041 - /* Set up nav offsets for tuplestore trim; resolve any NEEDS_EVAL kinds */ 24cfb8dRow pattern recognition patch (executor and commands).
3042 5034 winstate->navMaxOffsetKind = node->navMaxOffsetKind; 24cfb8dRow pattern recognition patch (executor and commands).
3043 5034 winstate->navMaxOffset = node->navMaxOffset; 24cfb8dRow pattern recognition patch (executor and commands).
3044 5034 winstate->hasFirstNav = node->hasFirstNav; 24cfb8dRow pattern recognition patch (executor and commands).
3045 5034 winstate->navFirstOffsetKind = node->navFirstOffsetKind; 24cfb8dRow pattern recognition patch (executor and commands).
3046 5034 winstate->navFirstOffset = node->navFirstOffset; 24cfb8dRow pattern recognition patch (executor and commands).
3047 5034 eval_define_offsets(winstate, node->defineClause); 24cfb8dRow pattern recognition patch (executor and commands).
3048 - 24cfb8dRow pattern recognition patch (executor and commands).
3049 - /* Copy match_start dependency bitmapset for per-context evaluation */ 24cfb8dRow pattern recognition patch (executor and commands).
3050 5034 winstate->defineMatchStartDependent = bms_copy(node->defineMatchStartDependent); 24cfb8dRow pattern recognition patch (executor and commands).
3051 - 24cfb8dRow pattern recognition patch (executor and commands).
3052 - /* Calculate NFA state size and allocate cycle detection bitmap */ 24cfb8dRow pattern recognition patch (executor and commands).
3053 5034 if (node->rpPattern != NULL) 24cfb8dRow pattern recognition patch (executor and commands).
3054 - { 24cfb8dRow pattern recognition patch (executor and commands).
3055 3048 int nfaVisitedNWords; 24cfb8dRow pattern recognition patch (executor and commands).
3056 - 24cfb8dRow pattern recognition patch (executor and commands).
3057 3048 winstate->nfaStateSize = offsetof(RPRNFAState, counts) + 24cfb8dRow pattern recognition patch (executor and commands).
3058 3048 sizeof(int32) * node->rpPattern->maxDepth; 24cfb8dRow pattern recognition patch (executor and commands).
3059 3048 nfaVisitedNWords = 24cfb8dRow pattern recognition patch (executor and commands).
3060 3048 (node->rpPattern->numElements - 1) / BITS_PER_BITMAPWORD + 1; 24cfb8dRow pattern recognition patch (executor and commands).
3061 3048 winstate->nfaVisitedElems = palloc0(sizeof(bitmapword) * 24cfb8dRow pattern recognition patch (executor and commands).
3062 - nfaVisitedNWords); 24cfb8dRow pattern recognition patch (executor and commands).
3063 - /* High-water mark sentinels: no bits set yet. */ 24cfb8dRow pattern recognition patch (executor and commands).
3064 3048 winstate->nfaVisitedMinWord = PG_INT16_MAX; 24cfb8dRow pattern recognition patch (executor and commands).
3065 3048 winstate->nfaVisitedMaxWord = -1; 24cfb8dRow pattern recognition patch (executor and commands).
3066 - } 24cfb8dRow pattern recognition patch (executor and commands).
3067 - 24cfb8dRow pattern recognition patch (executor and commands).
3068 - /* Set up row pattern recognition DEFINE clause */ 24cfb8dRow pattern recognition patch (executor and commands).
3069 5034 winstate->defineVariableList = NIL; 24cfb8dRow pattern recognition patch (executor and commands).
3070 5034 winstate->defineClauseExprs = NIL; b848408Tidy up row pattern recognition plumbing
3071 - b848408Tidy up row pattern recognition plumbing
3072 - /* b848408Tidy up row pattern recognition plumbing
3073 - * Compile DEFINE clause expressions. PREV/NEXT navigation is handled by b848408Tidy up row pattern recognition plumbing
3074 - * EEOP_RPR_NAV_SET/RESTORE opcodes emitted during ExecInitExpr, so no b848408Tidy up row pattern recognition plumbing
3075 - * varno rewriting is needed here. b848408Tidy up row pattern recognition plumbing
3076 - */ b848408Tidy up row pattern recognition plumbing
3077 12050 foreach_node(TargetEntry, te, node->defineClause) b848408Tidy up row pattern recognition plumbing
3078 - { 24cfb8dRow pattern recognition patch (executor and commands).
3079 7016 char *name = te->resname; b848408Tidy up row pattern recognition plumbing
3080 7016 ExprState *exprstate; b848408Tidy up row pattern recognition plumbing
3081 - b848408Tidy up row pattern recognition plumbing
3082 14032 winstate->defineVariableList = b848408Tidy up row pattern recognition plumbing
3083 7016 lappend(winstate->defineVariableList, b848408Tidy up row pattern recognition plumbing
3084 7016 makeString(pstrdup(name))); b848408Tidy up row pattern recognition plumbing
3085 - b848408Tidy up row pattern recognition plumbing
3086 7016 exprstate = ExecInitExpr(te->expr, (PlanState *) winstate); b848408Tidy up row pattern recognition plumbing
3087 - b848408Tidy up row pattern recognition plumbing
3088 7016 winstate->defineClauseExprs = b848408Tidy up row pattern recognition plumbing
3089 7016 lappend(winstate->defineClauseExprs, exprstate); b848408Tidy up row pattern recognition plumbing
3090 - } 24cfb8dRow pattern recognition patch (executor and commands).
3091 - 24cfb8dRow pattern recognition patch (executor and commands).
3092 - /* Initialize NFA free lists for row pattern matching */ 24cfb8dRow pattern recognition patch (executor and commands).
3093 5034 winstate->nfaContext = NULL; 24cfb8dRow pattern recognition patch (executor and commands).
3094 5034 winstate->nfaContextTail = NULL; 24cfb8dRow pattern recognition patch (executor and commands).
3095 5034 winstate->nfaContextFree = NULL; 24cfb8dRow pattern recognition patch (executor and commands).
3096 5034 winstate->nfaStateFree = NULL; 24cfb8dRow pattern recognition patch (executor and commands).
3097 5034 winstate->nfaLastProcessedRow = -1; 24cfb8dRow pattern recognition patch (executor and commands).
3098 5034 winstate->nfaStatesActive = 0; 24cfb8dRow pattern recognition patch (executor and commands).
3099 5034 winstate->nfaContextsActive = 0; 24cfb8dRow pattern recognition patch (executor and commands).
3100 - 24cfb8dRow pattern recognition patch (executor and commands).
3101 - /* 24cfb8dRow pattern recognition patch (executor and commands).
3102 - * Allocate varMatched array for NFA evaluation. With the new varNames 24cfb8dRow pattern recognition patch (executor and commands).
3103 - * ordering (DEFINE order first), varId == defineIdx for all defined 24cfb8dRow pattern recognition patch (executor and commands).
3104 - * variables, so no mapping is needed. 24cfb8dRow pattern recognition patch (executor and commands).
3105 - */ 24cfb8dRow pattern recognition patch (executor and commands).
3106 5034 if (winstate->defineVariableList != NIL) 4cf9108Further tidy up row pattern recognition plumbing
3107 3048 winstate->nfaVarMatched = palloc0(sizeof(bool) * 24cfb8dRow pattern recognition patch (executor and commands).
3108 3048 list_length(winstate->defineVariableList)); 24cfb8dRow pattern recognition patch (executor and commands).
3109 - else 24cfb8dRow pattern recognition patch (executor and commands).
3110 1986 winstate->nfaVarMatched = NULL; 24cfb8dRow pattern recognition patch (executor and commands).
3111 - winstate->all_first = true; -
3112 - winstate->partition_spooled = false; -
3113 - winstate->more_partitions = false; -
3114 - winstate->next_partition = true; -
3115 - -
3116 - return winstate; -
3117 - } -
ExecRPRNavGetSlot() lines 3126-3152
Modified Lines Coverage: 11/11 lines (100.0%)
LineHitsSourceCommit
3126 983356 ExecRPRNavGetSlot(WindowAggState *winstate, int64 pos) 24cfb8dRow pattern recognition patch (executor and commands).
3127 - { 24cfb8dRow pattern recognition patch (executor and commands).
3128 983356 WindowObject winobj = winstate->nav_winobj; 24cfb8dRow pattern recognition patch (executor and commands).
3129 983356 TupleTableSlot *slot = winstate->nav_slot; 24cfb8dRow pattern recognition patch (executor and commands).
3130 - 24cfb8dRow pattern recognition patch (executor and commands).
3131 983356 if (pos < 0) 24cfb8dRow pattern recognition patch (executor and commands).
3132 22804 return winstate->nav_null_slot; 24cfb8dRow pattern recognition patch (executor and commands).
3133 - 24cfb8dRow pattern recognition patch (executor and commands).
3134 - /* 24cfb8dRow pattern recognition patch (executor and commands).
3135 - * If nav_slot already holds this position, return it without re-fetching. 24cfb8dRow pattern recognition patch (executor and commands).
3136 - * This is critical when multiple PREV/NEXT calls in the same expression 24cfb8dRow pattern recognition patch (executor and commands).
3137 - * navigate to the same row, because re-fetching would free the slot's 24cfb8dRow pattern recognition patch (executor and commands).
3138 - * tuple memory and invalidate any pass-by-ref Datum pointers from earlier 24cfb8dRow pattern recognition patch (executor and commands).
3139 - * navigation results. 24cfb8dRow pattern recognition patch (executor and commands).
3140 - */ 24cfb8dRow pattern recognition patch (executor and commands).
3141 960552 if (winstate->nav_slot_pos == pos) 24cfb8dRow pattern recognition patch (executor and commands).
3142 - return slot; 24cfb8dRow pattern recognition patch (executor and commands).
3143 - 24cfb8dRow pattern recognition patch (executor and commands).
3144 484496 if (!window_gettupleslot(winobj, pos, slot)) 24cfb8dRow pattern recognition patch (executor and commands).
3145 - { 24cfb8dRow pattern recognition patch (executor and commands).
3146 160 winstate->nav_slot_pos = -1; 24cfb8dRow pattern recognition patch (executor and commands).
3147 160 return winstate->nav_null_slot; 24cfb8dRow pattern recognition patch (executor and commands).
3148 - } 24cfb8dRow pattern recognition patch (executor and commands).
3149 - 24cfb8dRow pattern recognition patch (executor and commands).
3150 484336 winstate->nav_slot_pos = pos; 24cfb8dRow pattern recognition patch (executor and commands).
3151 484336 return slot; 24cfb8dRow pattern recognition patch (executor and commands).
3152 - } 24cfb8dRow pattern recognition patch (executor and commands).
ExecReScanWindowAgg() lines 3195-3229
Modified Lines Coverage: 2/2 lines (100.0%)
LineHitsSourceCommit
3195 - ExecReScanWindowAgg(WindowAggState *node) -
3196 - { -
3197 - PlanState *outerPlan = outerPlanState(node); -
3198 - ExprContext *econtext = node->ss.ps.ps_ExprContext; -
3199 - -
3200 - node->status = WINDOWAGG_RUN; -
3201 - node->all_first = true; -
3202 - -
3203 - /* release tuplestore et al */ -
3204 - release_partition(node); -
3205 - -
3206 - /* release all temp tuples, but especially first_part_slot */ -
3207 - ExecClearTuple(node->ss.ss_ScanTupleSlot); -
3208 - ExecClearTuple(node->first_part_slot); -
3209 - ExecClearTuple(node->agg_row_slot); -
3210 - ExecClearTuple(node->temp_slot_1); -
3211 - ExecClearTuple(node->temp_slot_2); -
3212 108 if (node->nav_slot) 24cfb8dRow pattern recognition patch (executor and commands).
3213 56 ExecClearTuple(node->nav_slot); 24cfb8dRow pattern recognition patch (executor and commands).
3214 - if (node->framehead_slot) -
3215 - ExecClearTuple(node->framehead_slot); -
3216 - if (node->frametail_slot) -
3217 - ExecClearTuple(node->frametail_slot); -
3218 - -
3219 - /* Forget current wfunc values */ -
3220 - MemSet(econtext->ecxt_aggvalues, 0, sizeof(Datum) * node->numfuncs); -
3221 - MemSet(econtext->ecxt_aggnulls, 0, sizeof(bool) * node->numfuncs); -
3222 - -
3223 - /* -
3224 - * if chgParam of subnode is not null then plan will be re-scanned by -
3225 - * first ExecProcNode. -
3226 - */ -
3227 - if (outerPlan->chgParam == NULL) -
3228 - ExecReScan(outerPlan); -
3229 - } -
window_gettupleslot() lines 3555-3639
Modified Lines Coverage: 0/1 lines (0.0%)
LineHitsSourceCommit
3555 - window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot) -
3556 - { -
3557 - WindowAggState *winstate = winobj->winstate; -
3558 - MemoryContext oldcontext; -
3559 - -
3560 - /* often called repeatedly in a row */ -
3561 - CHECK_FOR_INTERRUPTS(); -
3562 - -
3563 - /* Don't allow passing -1 to spool_tuples here */ -
3564 - if (pos < 0) -
3565 - return false; -
3566 - -
3567 - /* If necessary, fetch the tuple into the spool */ -
3568 - spool_tuples(winstate, pos); -
3569 - -
3570 - if (pos >= winstate->spooled_rows) -
3571 - return false; -
3572 - -
3573 - if (pos < winobj->markpos) -
3574 0 elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT, 24cfb8dRow pattern recognition patch (executor and commands).
3575 - pos, winobj->markpos); 24cfb8dRow pattern recognition patch (executor and commands).
3576 - -
3577 - oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory); -
3578 - -
3579 - tuplestore_select_read_pointer(winstate->buffer, winobj->readptr); -
3580 - -
3581 - /* -
3582 - * Advance or rewind until we are within one tuple of the one we want. -
3583 - */ -
3584 - if (winobj->seekpos < pos - 1) -
3585 - { -
3586 - if (!tuplestore_skiptuples(winstate->buffer, -
3587 - pos - 1 - winobj->seekpos, -
3588 - true)) -
3589 - elog(ERROR, "unexpected end of tuplestore"); -
3590 - winobj->seekpos = pos - 1; -
3591 - } -
3592 - else if (winobj->seekpos > pos + 1) -
3593 - { -
3594 - if (!tuplestore_skiptuples(winstate->buffer, -
3595 - winobj->seekpos - (pos + 1), -
3596 - false)) -
3597 - elog(ERROR, "unexpected end of tuplestore"); -
3598 - winobj->seekpos = pos + 1; -
3599 - } -
3600 - else if (winobj->seekpos == pos) -
3601 - { -
3602 - /* -
3603 - * There's no API to refetch the tuple at the current position. We -
3604 - * have to move one tuple forward, and then one backward. (We don't -
3605 - * do it the other way because we might try to fetch the row before -
3606 - * our mark, which isn't allowed.) XXX this case could stand to be -
3607 - * optimized. -
3608 - */ -
3609 - tuplestore_advance(winstate->buffer, true); -
3610 - winobj->seekpos++; -
3611 - } -
3612 - -
3613 - /* -
3614 - * Now we should be on the tuple immediately before or after the one we -
3615 - * want, so just fetch forwards or backwards as appropriate. -
3616 - * -
3617 - * Notice that we tell tuplestore_gettupleslot to make a physical copy of -
3618 - * the fetched tuple. This ensures that the slot's contents remain valid -
3619 - * through manipulations of the tuplestore, which some callers depend on. -
3620 - */ -
3621 - if (winobj->seekpos > pos) -
3622 - { -
3623 - if (!tuplestore_gettupleslot(winstate->buffer, false, true, slot)) -
3624 - elog(ERROR, "unexpected end of tuplestore"); -
3625 - winobj->seekpos--; -
3626 - } -
3627 - else -
3628 - { -
3629 - if (!tuplestore_gettupleslot(winstate->buffer, true, true, slot)) -
3630 - elog(ERROR, "unexpected end of tuplestore"); -
3631 - winobj->seekpos++; -
3632 - } -
3633 - -
3634 - Assert(winobj->seekpos == pos); -
3635 - -
3636 - MemoryContextSwitchTo(oldcontext); -
3637 - -
3638 - return true; -
3639 - } -
ignorenulls_getfuncarginframe() lines 3680-3856
Modified Lines Coverage: 15/16 lines (93.8%)
LineHitsSourceCommit
3680 - ignorenulls_getfuncarginframe(WindowObject winobj, int argno, -
3681 - int relpos, int seektype, bool set_mark, -
3682 - bool *isnull, bool *isout) -
3683 - { -
3684 - WindowAggState *winstate; -
3685 - ExprContext *econtext; -
3686 - TupleTableSlot *slot; -
3687 - Datum datum; -
3688 - int64 abs_pos; -
3689 - int64 mark_pos; -
3690 - int notnull_offset; -
3691 - int notnull_relpos; -
3692 - int forward; -
3693 1088 int64 num_reduced_frame; 24cfb8dRow pattern recognition patch (executor and commands).
3694 - -
3695 - Assert(WindowObjectIsValid(winobj)); -
3696 - winstate = winobj->winstate; -
3697 - econtext = winstate->ss.ps.ps_ExprContext; -
3698 - slot = winstate->temp_slot_1; -
3699 - datum = (Datum) 0; -
3700 - notnull_offset = 0; -
3701 - notnull_relpos = abs(relpos); -
3702 - -
3703 - switch (seektype) -
3704 - { -
3705 - case WINDOW_SEEK_CURRENT: -
3706 - elog(ERROR, "WINDOW_SEEK_CURRENT is not supported for WinGetFuncArgInFrame"); -
3707 - abs_pos = mark_pos = 0; /* keep compiler quiet */ -
3708 - break; -
3709 - case WINDOW_SEEK_HEAD: -
3710 - /* rejecting relpos < 0 is easy and simplifies code below */ -
3711 - if (relpos < 0) -
3712 - goto out_of_frame; -
3713 - update_frameheadpos(winstate); -
3714 - abs_pos = winstate->frameheadpos; -
3715 - mark_pos = winstate->frameheadpos; -
3716 - forward = 1; -
3717 - break; -
3718 - case WINDOW_SEEK_TAIL: -
3719 - /* rejecting relpos > 0 is easy and simplifies code below */ -
3720 - if (relpos > 0) -
3721 - goto out_of_frame; -
3722 - 24cfb8dRow pattern recognition patch (executor and commands).
3723 - /* 24cfb8dRow pattern recognition patch (executor and commands).
3724 - * RPR cares about frame head pos. Need to call 24cfb8dRow pattern recognition patch (executor and commands).
3725 - * update_frameheadpos 24cfb8dRow pattern recognition patch (executor and commands).
3726 - */ 24cfb8dRow pattern recognition patch (executor and commands).
3727 308 update_frameheadpos(winstate); 24cfb8dRow pattern recognition patch (executor and commands).
3728 - 24cfb8dRow pattern recognition patch (executor and commands).
3729 - update_frametailpos(winstate); -
3730 - abs_pos = winstate->frametailpos - 1; -
3731 - mark_pos = 0; /* keep compiler quiet */ -
3732 - forward = -1; -
3733 - break; -
3734 - default: -
3735 - elog(ERROR, "unrecognized window seek type: %d", seektype); -
3736 - abs_pos = mark_pos = 0; /* keep compiler quiet */ -
3737 - break; -
3738 - } -
3739 - -
3740 - /* -
3741 - * Get the next nonnull value in the frame, moving forward or backward -
3742 - * until we find a value or reach the frame's end. -
3743 - */ -
3744 - 24cfb8dRow pattern recognition patch (executor and commands).
3745 - /* 24cfb8dRow pattern recognition patch (executor and commands).
3746 - * Check whether current row is in reduced frame. 24cfb8dRow pattern recognition patch (executor and commands).
3747 - */ 24cfb8dRow pattern recognition patch (executor and commands).
3748 1088 num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos); 24cfb8dRow pattern recognition patch (executor and commands).
3749 1088 if (num_reduced_frame < 0) /* unmatched or skipped row */ 24cfb8dRow pattern recognition patch (executor and commands).
3750 320 goto out_of_frame; 24cfb8dRow pattern recognition patch (executor and commands).
3751 768 else if (num_reduced_frame > 0) /* the first row of the reduced frame */ 24cfb8dRow pattern recognition patch (executor and commands).
3752 - { 24cfb8dRow pattern recognition patch (executor and commands).
3753 - /* 24cfb8dRow pattern recognition patch (executor and commands).
3754 - * Early check if row could be out of reduced frame. When RPR is 24cfb8dRow pattern recognition patch (executor and commands).
3755 - * enabled, EXCLUDE clause cannot be specified and the frame is always 24cfb8dRow pattern recognition patch (executor and commands).
3756 - * contiguous. So we can safely perform the following checks. Note, 24cfb8dRow pattern recognition patch (executor and commands).
3757 - * however, it is possible that a row is out of reduced frame if 24cfb8dRow pattern recognition patch (executor and commands).
3758 - * there's a NULL in the middle. So we need to check it in the 24cfb8dRow pattern recognition patch (executor and commands).
3759 - * following do loop. 24cfb8dRow pattern recognition patch (executor and commands).
3760 - */ 24cfb8dRow pattern recognition patch (executor and commands).
3761 88 if (seektype == WINDOW_SEEK_HEAD && relpos >= num_reduced_frame) 24cfb8dRow pattern recognition patch (executor and commands).
3762 16 goto out_of_frame; 24cfb8dRow pattern recognition patch (executor and commands).
3763 72 if (seektype == WINDOW_SEEK_TAIL) 24cfb8dRow pattern recognition patch (executor and commands).
3764 - { 24cfb8dRow pattern recognition patch (executor and commands).
3765 24 if (notnull_relpos >= num_reduced_frame) 24cfb8dRow pattern recognition patch (executor and commands).
3766 0 goto out_of_frame; 24cfb8dRow pattern recognition patch (executor and commands).
3767 - 24cfb8dRow pattern recognition patch (executor and commands).
3768 - /* not out of reduced frame. Set abspos as a starting point */ 24cfb8dRow pattern recognition patch (executor and commands).
3769 24 abs_pos = winstate->frameheadpos + num_reduced_frame - 1; 24cfb8dRow pattern recognition patch (executor and commands).
3770 - } 24cfb8dRow pattern recognition patch (executor and commands).
3771 - } 24cfb8dRow pattern recognition patch (executor and commands).
3772 - 24cfb8dRow pattern recognition patch (executor and commands).
3773 - do -
3774 - { -
3775 - int inframe; -
3776 - int v; -
3777 - -
3778 - /* -
3779 - * Check apparent out of frame case. We need to do this because we -
3780 - * may not call window_gettupleslot before row_is_in_frame, which -
3781 - * supposes abs_pos is never negative. -
3782 - */ -
3783 - if (abs_pos < 0) -
3784 - goto out_of_frame; -
3785 - -
3786 - /* check whether row is in frame */ -
3787 - inframe = row_is_in_frame(winobj, abs_pos, slot, true); -
3788 - if (inframe == -1) -
3789 - goto out_of_frame; -
3790 - else if (inframe == 0) -
3791 - goto advance; -
3792 - -
3793 - if (isout) -
3794 - *isout = false; -
3795 - -
3796 - v = get_notnull_info(winobj, abs_pos, argno); -
3797 - if (v == NN_NULL) /* this row is known to be NULL */ -
3798 - goto advance; -
3799 - -
3800 - else if (v == NN_UNKNOWN) /* need to check NULL or not */ -
3801 - { -
3802 - if (!window_gettupleslot(winobj, abs_pos, slot)) -
3803 - goto out_of_frame; -
3804 - -
3805 - econtext->ecxt_outertuple = slot; -
3806 - datum = ExecEvalExpr( -
3807 - (ExprState *) list_nth(winobj->argstates, -
3808 - argno), econtext, -
3809 - isnull); -
3810 - if (!*isnull) -
3811 - notnull_offset++; -
3812 - -
3813 - /* record the row status */ -
3814 - put_notnull_info(winobj, abs_pos, argno, *isnull); -
3815 - } -
3816 - else /* this row is known to be NOT NULL */ -
3817 - { -
3818 - notnull_offset++; -
3819 - if (notnull_offset > notnull_relpos) -
3820 - { -
3821 - /* to prepare exiting this loop, datum needs to be set */ -
3822 - if (!window_gettupleslot(winobj, abs_pos, slot)) -
3823 - goto out_of_frame; -
3824 - -
3825 - econtext->ecxt_outertuple = slot; -
3826 - datum = ExecEvalExpr( -
3827 - (ExprState *) list_nth -
3828 - (winobj->argstates, argno), -
3829 - econtext, isnull); -
3830 - } -
3831 - } -
3832 - advance: -
3833 - abs_pos += forward; -
3834 1664 if (rpr_is_defined(winstate)) 24cfb8dRow pattern recognition patch (executor and commands).
3835 - { 24cfb8dRow pattern recognition patch (executor and commands).
3836 - /* 24cfb8dRow pattern recognition patch (executor and commands).
3837 - * Check whether we are still in the reduced frame. (also check 24cfb8dRow pattern recognition patch (executor and commands).
3838 - * if we succeeded in getting the target row). 24cfb8dRow pattern recognition patch (executor and commands).
3839 - */ 24cfb8dRow pattern recognition patch (executor and commands).
3840 136 num_reduced_frame--; 24cfb8dRow pattern recognition patch (executor and commands).
3841 136 if (num_reduced_frame <= 0 && notnull_offset <= notnull_relpos) 24cfb8dRow pattern recognition patch (executor and commands).
3842 12 goto out_of_frame; 24cfb8dRow pattern recognition patch (executor and commands).
3843 - } 24cfb8dRow pattern recognition patch (executor and commands).
3844 - } while (notnull_offset <= notnull_relpos); -
3845 - -
3846 - if (set_mark) -
3847 - WinSetMarkPosition(winobj, mark_pos); -
3848 - -
3849 - return datum; -
3850 - -
3851 - out_of_frame: -
3852 - if (isout) -
3853 - *isout = true; -
3854 - *isnull = true; -
3855 - return (Datum) 0; -
3856 - } -
eval_nav_offset_helper() lines 3999-4022
Modified Lines Coverage: 14/14 lines (100.0%)
LineHitsSourceCommit
3999 72 eval_nav_offset_helper(WindowAggState *winstate, Expr *offset_expr, 24cfb8dRow pattern recognition patch (executor and commands).
4000 - int64 defaultOffset) 24cfb8dRow pattern recognition patch (executor and commands).
4001 - { 24cfb8dRow pattern recognition patch (executor and commands).
4002 72 ExprContext *econtext = winstate->ss.ps.ps_ExprContext; 24cfb8dRow pattern recognition patch (executor and commands).
4003 72 ExprState *estate; 24cfb8dRow pattern recognition patch (executor and commands).
4004 72 Datum val; 24cfb8dRow pattern recognition patch (executor and commands).
4005 72 bool isnull; 24cfb8dRow pattern recognition patch (executor and commands).
4006 72 int64 offset; 24cfb8dRow pattern recognition patch (executor and commands).
4007 - 24cfb8dRow pattern recognition patch (executor and commands).
4008 72 if (offset_expr == NULL) 24cfb8dRow pattern recognition patch (executor and commands).
4009 72 return defaultOffset; 24cfb8dRow pattern recognition patch (executor and commands).
4010 - 24cfb8dRow pattern recognition patch (executor and commands).
4011 72 estate = ExecInitExpr(offset_expr, (PlanState *) winstate); 24cfb8dRow pattern recognition patch (executor and commands).
4012 72 val = ExecEvalExprSwitchContext(estate, econtext, &isnull); 24cfb8dRow pattern recognition patch (executor and commands).
4013 - 95b07bcSupport window functions a la SQL:2008.
4014 72 if (isnull) 24cfb8dRow pattern recognition patch (executor and commands).
4015 - return 0; 24cfb8dRow pattern recognition patch (executor and commands).
4016 - 24cfb8dRow pattern recognition patch (executor and commands).
4017 72 offset = DatumGetInt64(val); 24cfb8dRow pattern recognition patch (executor and commands).
4018 72 if (offset < 0) 24cfb8dRow pattern recognition patch (executor and commands).
4019 4 return 0; 24cfb8dRow pattern recognition patch (executor and commands).
4020 - -
4021 - return offset; 24cfb8dRow pattern recognition patch (executor and commands).
4022 - } 24cfb8dRow pattern recognition patch (executor and commands).
DatumGetInt64() lines 4017-4032
Modified Lines Coverage: 3/3 lines (100.0%)
LineHitsSourceCommit
4017 72 offset = DatumGetInt64(val); 24cfb8dRow pattern recognition patch (executor and commands).
4018 72 if (offset < 0) 24cfb8dRow pattern recognition patch (executor and commands).
4019 4 return 0; 24cfb8dRow pattern recognition patch (executor and commands).
4020 - -
4021 - return offset; 24cfb8dRow pattern recognition patch (executor and commands).
4022 - } 24cfb8dRow pattern recognition patch (executor and commands).
4023 - 24cfb8dRow pattern recognition patch (executor and commands).
4024 - typedef struct 24cfb8dRow pattern recognition patch (executor and commands).
4025 - { 24cfb8dRow pattern recognition patch (executor and commands).
4026 - WindowAggState *winstate; 24cfb8dRow pattern recognition patch (executor and commands).
4027 - int64 maxOffset; /* max backward-reach offset across all nav 24cfb8dRow pattern recognition patch (executor and commands).
4028 - * exprs */ 24cfb8dRow pattern recognition patch (executor and commands).
4029 - bool maxOverflow; /* true if backward-reach overflow detected */ 24cfb8dRow pattern recognition patch (executor and commands).
4030 - int64 minFirstOffset; /* min forward-from-match_start offset; may be 24cfb8dRow pattern recognition patch (executor and commands).
4031 - * negative (PREV_FIRST: inner - outer < 0) */ 24cfb8dRow pattern recognition patch (executor and commands).
4032 - } EvalDefineOffsetsContext; 24cfb8dRow pattern recognition patch (executor and commands).
visit_nav_exec() lines 4054-4150
Modified Lines Coverage: 35/35 lines (100.0%)
LineHitsSourceCommit
4054 48 visit_nav_exec(NavTraversal *t, RPRNavExpr *nav) 24cfb8dRow pattern recognition patch (executor and commands).
4055 - { -
4056 48 EvalDefineOffsetsContext *context = (EvalDefineOffsetsContext *) t->data; 24cfb8dRow pattern recognition patch (executor and commands).
4057 - 24cfb8dRow pattern recognition patch (executor and commands).
4058 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4059 - * Parser guarantee (mirrors visit_nav_plan): nav's direct children are 24cfb8dRow pattern recognition patch (executor and commands).
4060 - * never RPRNavExpr -- compound nesting is flattened in place and any 24cfb8dRow pattern recognition patch (executor and commands).
4061 - * other nesting is rejected. Outer-kind dispatch is sufficient. 24cfb8dRow pattern recognition patch (executor and commands).
4062 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4063 48 Assert(nav->arg == NULL || !IsA(nav->arg, RPRNavExpr)); 24cfb8dRow pattern recognition patch (executor and commands).
4064 48 Assert(nav->offset_arg == NULL || !IsA(nav->offset_arg, RPRNavExpr)); 24cfb8dRow pattern recognition patch (executor and commands).
4065 48 Assert(nav->compound_offset_arg == NULL || 24cfb8dRow pattern recognition patch (executor and commands).
4066 - !IsA(nav->compound_offset_arg, RPRNavExpr)); 24cfb8dRow pattern recognition patch (executor and commands).
4067 - 24cfb8dRow pattern recognition patch (executor and commands).
4068 - /* Backward reach: PREV, LAST-with-offset */ 24cfb8dRow pattern recognition patch (executor and commands).
4069 48 if (!context->maxOverflow) 24cfb8dRow pattern recognition patch (executor and commands).
4070 - { -
4071 48 int64 reach = 0; 24cfb8dRow pattern recognition patch (executor and commands).
4072 48 bool gotReach = false; 24cfb8dRow pattern recognition patch (executor and commands).
4073 - -
4074 48 if (nav->kind == RPR_NAV_PREV) 24cfb8dRow pattern recognition patch (executor and commands).
4075 - { 24cfb8dRow pattern recognition patch (executor and commands).
4076 16 reach = eval_nav_offset_helper(context->winstate, 24cfb8dRow pattern recognition patch (executor and commands).
4077 - nav->offset_arg, 1); 24cfb8dRow pattern recognition patch (executor and commands).
4078 - gotReach = true; 24cfb8dRow pattern recognition patch (executor and commands).
4079 - } 24cfb8dRow pattern recognition patch (executor and commands).
4080 32 else if (nav->kind == RPR_NAV_LAST && nav->offset_arg != NULL) 24cfb8dRow pattern recognition patch (executor and commands).
4081 - { 24cfb8dRow pattern recognition patch (executor and commands).
4082 4 reach = eval_nav_offset_helper(context->winstate, 24cfb8dRow pattern recognition patch (executor and commands).
4083 - nav->offset_arg, 0); 24cfb8dRow pattern recognition patch (executor and commands).
4084 - gotReach = true; 24cfb8dRow pattern recognition patch (executor and commands).
4085 - } 24cfb8dRow pattern recognition patch (executor and commands).
4086 28 else if (nav->kind == RPR_NAV_PREV_LAST || 24cfb8dRow pattern recognition patch (executor and commands).
4087 - nav->kind == RPR_NAV_NEXT_LAST) 24cfb8dRow pattern recognition patch (executor and commands).
4088 - { 24cfb8dRow pattern recognition patch (executor and commands).
4089 12 int64 inner = eval_nav_offset_helper(context->winstate, 24cfb8dRow pattern recognition patch (executor and commands).
4090 - nav->offset_arg, 0); 24cfb8dRow pattern recognition patch (executor and commands).
4091 12 int64 outer = eval_nav_offset_helper(context->winstate, 24cfb8dRow pattern recognition patch (executor and commands).
4092 - nav->compound_offset_arg, 1); 24cfb8dRow pattern recognition patch (executor and commands).
4093 - 24cfb8dRow pattern recognition patch (executor and commands).
4094 12 if (nav->kind == RPR_NAV_PREV_LAST) 24cfb8dRow pattern recognition patch (executor and commands).
4095 - { 24cfb8dRow pattern recognition patch (executor and commands).
4096 8 if (pg_add_s64_overflow(inner, outer, &reach)) 24cfb8dRow pattern recognition patch (executor and commands).
4097 8 context->maxOverflow = true; 24cfb8dRow pattern recognition patch (executor and commands).
4098 - else 24cfb8dRow pattern recognition patch (executor and commands).
4099 - gotReach = true; 24cfb8dRow pattern recognition patch (executor and commands).
4100 - } 24cfb8dRow pattern recognition patch (executor and commands).
4101 - else 24cfb8dRow pattern recognition patch (executor and commands).
4102 - { 24cfb8dRow pattern recognition patch (executor and commands).
4103 4 reach = Max(inner - outer, 0); 24cfb8dRow pattern recognition patch (executor and commands).
4104 4 gotReach = true; 24cfb8dRow pattern recognition patch (executor and commands).
4105 - } 24cfb8dRow pattern recognition patch (executor and commands).
4106 - } 24cfb8dRow pattern recognition patch (executor and commands).
4107 - 24cfb8dRow pattern recognition patch (executor and commands).
4108 12 if (gotReach) 24cfb8dRow pattern recognition patch (executor and commands).
4109 24 context->maxOffset = Max(context->maxOffset, reach); 24cfb8dRow pattern recognition patch (executor and commands).
4110 - } 24cfb8dRow pattern recognition patch (executor and commands).
4111 - 24cfb8dRow pattern recognition patch (executor and commands).
4112 - /* Forward reach from match_start: FIRST, compound PREV_FIRST/NEXT_FIRST */ 24cfb8dRow pattern recognition patch (executor and commands).
4113 48 if (nav->kind == RPR_NAV_FIRST) 24cfb8dRow pattern recognition patch (executor and commands).
4114 - { 24cfb8dRow pattern recognition patch (executor and commands).
4115 4 int64 reach; 24cfb8dRow pattern recognition patch (executor and commands).
4116 - 24cfb8dRow pattern recognition patch (executor and commands).
4117 4 reach = eval_nav_offset_helper(context->winstate, 24cfb8dRow pattern recognition patch (executor and commands).
4118 - nav->offset_arg, 0); 24cfb8dRow pattern recognition patch (executor and commands).
4119 4 context->minFirstOffset = Min(context->minFirstOffset, reach); 24cfb8dRow pattern recognition patch (executor and commands).
4120 - } 24cfb8dRow pattern recognition patch (executor and commands).
4121 44 else if (nav->kind == RPR_NAV_PREV_FIRST || 24cfb8dRow pattern recognition patch (executor and commands).
4122 - nav->kind == RPR_NAV_NEXT_FIRST) 24cfb8dRow pattern recognition patch (executor and commands).
4123 - { 24cfb8dRow pattern recognition patch (executor and commands).
4124 12 int64 inner = eval_nav_offset_helper(context->winstate, 24cfb8dRow pattern recognition patch (executor and commands).
4125 - nav->offset_arg, 0); 24cfb8dRow pattern recognition patch (executor and commands).
4126 12 int64 outer = eval_nav_offset_helper(context->winstate, 24cfb8dRow pattern recognition patch (executor and commands).
4127 - nav->compound_offset_arg, 1); 24cfb8dRow pattern recognition patch (executor and commands).
4128 12 int64 reach; 24cfb8dRow pattern recognition patch (executor and commands).
4129 - 24cfb8dRow pattern recognition patch (executor and commands).
4130 12 if (nav->kind == RPR_NAV_PREV_FIRST) 24cfb8dRow pattern recognition patch (executor and commands).
4131 - { 24cfb8dRow pattern recognition patch (executor and commands).
4132 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4133 - * reach = inner - outer. Both are non-negative, so the result >= 24cfb8dRow pattern recognition patch (executor and commands).
4134 - * -PG_INT64_MAX, which cannot underflow int64. 24cfb8dRow pattern recognition patch (executor and commands).
4135 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4136 4 reach = inner - outer; 24cfb8dRow pattern recognition patch (executor and commands).
4137 - } 24cfb8dRow pattern recognition patch (executor and commands).
4138 - else 24cfb8dRow pattern recognition patch (executor and commands).
4139 - { 24cfb8dRow pattern recognition patch (executor and commands).
4140 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4141 - * NEXT_FIRST: reach = inner + outer. This can overflow, but the 24cfb8dRow pattern recognition patch (executor and commands).
4142 - * result is always >= 0, so it never updates minFirstOffset 24cfb8dRow pattern recognition patch (executor and commands).
4143 - * (which tracks the minimum). Clamp to PG_INT64_MAX on overflow. 24cfb8dRow pattern recognition patch (executor and commands).
4144 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4145 8 if (pg_add_s64_overflow(inner, outer, &reach)) 24cfb8dRow pattern recognition patch (executor and commands).
4146 4 reach = PG_INT64_MAX; 24cfb8dRow pattern recognition patch (executor and commands).
4147 - } 24cfb8dRow pattern recognition patch (executor and commands).
4148 12 context->minFirstOffset = Min(context->minFirstOffset, reach); 24cfb8dRow pattern recognition patch (executor and commands).
4149 - } -
4150 - } -
eval_define_offsets() lines 4166-4212
Modified Lines Coverage: 27/27 lines (100.0%)
LineHitsSourceCommit
4166 5034 eval_define_offsets(WindowAggState *winstate, List *defineClause) 24cfb8dRow pattern recognition patch (executor and commands).
4167 - { -
4168 5034 EvalDefineOffsetsContext ctx; 24cfb8dRow pattern recognition patch (executor and commands).
4169 5034 NavTraversal trav; 24cfb8dRow pattern recognition patch (executor and commands).
4170 5034 bool needsMax = (winstate->navMaxOffsetKind == RPR_NAV_OFFSET_NEEDS_EVAL); 24cfb8dRow pattern recognition patch (executor and commands).
4171 5034 bool needsFirst = (winstate->hasFirstNav && 24cfb8dRow pattern recognition patch (executor and commands).
4172 152 winstate->navFirstOffsetKind == RPR_NAV_OFFSET_NEEDS_EVAL); 24cfb8dRow pattern recognition patch (executor and commands).
4173 - 24cfb8dRow pattern recognition patch (executor and commands).
4174 5034 if (!needsMax && !needsFirst) 24cfb8dRow pattern recognition patch (executor and commands).
4175 4986 return; 24cfb8dRow pattern recognition patch (executor and commands).
4176 - 24cfb8dRow pattern recognition patch (executor and commands).
4177 48 ctx.winstate = winstate; 24cfb8dRow pattern recognition patch (executor and commands).
4178 48 ctx.maxOffset = 0; 24cfb8dRow pattern recognition patch (executor and commands).
4179 48 ctx.maxOverflow = false; 24cfb8dRow pattern recognition patch (executor and commands).
4180 48 ctx.minFirstOffset = PG_INT64_MAX; 24cfb8dRow pattern recognition patch (executor and commands).
4181 - 24cfb8dRow pattern recognition patch (executor and commands).
4182 48 trav.visit = visit_nav_exec; 24cfb8dRow pattern recognition patch (executor and commands).
4183 48 trav.data = &ctx; 24cfb8dRow pattern recognition patch (executor and commands).
4184 - 24cfb8dRow pattern recognition patch (executor and commands).
4185 96 foreach_node(TargetEntry, te, defineClause) 24cfb8dRow pattern recognition patch (executor and commands).
4186 - { 24cfb8dRow pattern recognition patch (executor and commands).
4187 48 nav_traversal_walker((Node *) te->expr, &trav); 24cfb8dRow pattern recognition patch (executor and commands).
4188 - } 24cfb8dRow pattern recognition patch (executor and commands).
4189 - 24cfb8dRow pattern recognition patch (executor and commands).
4190 48 if (needsMax) 24cfb8dRow pattern recognition patch (executor and commands).
4191 - { 24cfb8dRow pattern recognition patch (executor and commands).
4192 32 if (ctx.maxOverflow) 24cfb8dRow pattern recognition patch (executor and commands).
4193 - { 24cfb8dRow pattern recognition patch (executor and commands).
4194 8 winstate->navMaxOffsetKind = RPR_NAV_OFFSET_RETAIN_ALL; 24cfb8dRow pattern recognition patch (executor and commands).
4195 8 winstate->navMaxOffset = 0; 24cfb8dRow pattern recognition patch (executor and commands).
4196 - } 24cfb8dRow pattern recognition patch (executor and commands).
4197 - else 24cfb8dRow pattern recognition patch (executor and commands).
4198 - { 24cfb8dRow pattern recognition patch (executor and commands).
4199 24 winstate->navMaxOffsetKind = RPR_NAV_OFFSET_FIXED; 24cfb8dRow pattern recognition patch (executor and commands).
4200 24 winstate->navMaxOffset = ctx.maxOffset; 24cfb8dRow pattern recognition patch (executor and commands).
4201 - } 24cfb8dRow pattern recognition patch (executor and commands).
4202 - } 24cfb8dRow pattern recognition patch (executor and commands).
4203 - 24cfb8dRow pattern recognition patch (executor and commands).
4204 48 if (needsFirst) 24cfb8dRow pattern recognition patch (executor and commands).
4205 - { 24cfb8dRow pattern recognition patch (executor and commands).
4206 16 winstate->navFirstOffsetKind = RPR_NAV_OFFSET_FIXED; 24cfb8dRow pattern recognition patch (executor and commands).
4207 16 if (ctx.minFirstOffset < PG_INT64_MAX) 24cfb8dRow pattern recognition patch (executor and commands).
4208 12 winstate->navFirstOffset = ctx.minFirstOffset; 24cfb8dRow pattern recognition patch (executor and commands).
4209 - else 24cfb8dRow pattern recognition patch (executor and commands).
4210 4 winstate->navFirstOffset = PG_INT64_MAX; 24cfb8dRow pattern recognition patch (executor and commands).
4211 - } 24cfb8dRow pattern recognition patch (executor and commands).
4212 - } -
rpr_is_defined() lines 4219-4222
Modified Lines Coverage: 2/2 lines (100.0%)
LineHitsSourceCommit
4219 8911487 rpr_is_defined(WindowAggState *winstate) 24cfb8dRow pattern recognition patch (executor and commands).
4220 - { -
4221 8911487 return winstate->rpPattern != NULL; 24cfb8dRow pattern recognition patch (executor and commands).
4222 - } -
row_is_in_reduced_frame() lines 4243-4291
Modified Lines Coverage: 18/20 lines (90.0%)
LineHitsSourceCommit
4243 4356552 row_is_in_reduced_frame(WindowObject winobj, int64 pos) 24cfb8dRow pattern recognition patch (executor and commands).
4244 - { -
4245 4356552 WindowAggState *winstate = winobj->winstate; 24cfb8dRow pattern recognition patch (executor and commands).
4246 4356552 int state; 24cfb8dRow pattern recognition patch (executor and commands).
4247 4356552 int64 rtn; 24cfb8dRow pattern recognition patch (executor and commands).
4248 - -
4249 4356552 if (!rpr_is_defined(winstate)) 24cfb8dRow pattern recognition patch (executor and commands).
4250 - { 24cfb8dRow pattern recognition patch (executor and commands).
4251 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4252 - * RPR is not defined. Assume that we are always in the reduced window 24cfb8dRow pattern recognition patch (executor and commands).
4253 - * frame. 24cfb8dRow pattern recognition patch (executor and commands).
4254 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4255 4356488 rtn = 0; 24cfb8dRow pattern recognition patch (executor and commands).
4256 - return rtn; 24cfb8dRow pattern recognition patch (executor and commands).
4257 - } 24cfb8dRow pattern recognition patch (executor and commands).
4258 - 24cfb8dRow pattern recognition patch (executor and commands).
4259 4349836 state = get_reduced_frame_status(winstate, pos); 24cfb8dRow pattern recognition patch (executor and commands).
4260 - 24cfb8dRow pattern recognition patch (executor and commands).
4261 4349836 if (state == RF_NOT_DETERMINED) 24cfb8dRow pattern recognition patch (executor and commands).
4262 - { 24cfb8dRow pattern recognition patch (executor and commands).
4263 130008 update_frameheadpos(winstate); 24cfb8dRow pattern recognition patch (executor and commands).
4264 130008 update_reduced_frame(winobj, pos); 24cfb8dRow pattern recognition patch (executor and commands).
4265 - } 24cfb8dRow pattern recognition patch (executor and commands).
4266 - 24cfb8dRow pattern recognition patch (executor and commands).
4267 4349772 state = get_reduced_frame_status(winstate, pos); 24cfb8dRow pattern recognition patch (executor and commands).
4268 - 24cfb8dRow pattern recognition patch (executor and commands).
4269 4349772 switch (state) 24cfb8dRow pattern recognition patch (executor and commands).
4270 - { 24cfb8dRow pattern recognition patch (executor and commands).
4271 81440 case RF_FRAME_HEAD: 24cfb8dRow pattern recognition patch (executor and commands).
4272 81440 rtn = winstate->rpr_match_length; 24cfb8dRow pattern recognition patch (executor and commands).
4273 81440 break; 24cfb8dRow pattern recognition patch (executor and commands).
4274 - 24cfb8dRow pattern recognition patch (executor and commands).
4275 - case RF_SKIPPED: 24cfb8dRow pattern recognition patch (executor and commands).
4276 - rtn = -2; 24cfb8dRow pattern recognition patch (executor and commands).
4277 - break; 24cfb8dRow pattern recognition patch (executor and commands).
4278 - 24cfb8dRow pattern recognition patch (executor and commands).
4279 469952 case RF_UNMATCHED: 24cfb8dRow pattern recognition patch (executor and commands).
4280 - case RF_EMPTY_MATCH: 24cfb8dRow pattern recognition patch (executor and commands).
4281 469952 rtn = -1; 24cfb8dRow pattern recognition patch (executor and commands).
4282 469952 break; 24cfb8dRow pattern recognition patch (executor and commands).
4283 - 24cfb8dRow pattern recognition patch (executor and commands).
4284 0 default: 24cfb8dRow pattern recognition patch (executor and commands).
4285 0 elog(ERROR, "unrecognized state: %d at: " INT64_FORMAT, 24cfb8dRow pattern recognition patch (executor and commands).
4286 - state, pos); 24cfb8dRow pattern recognition patch (executor and commands).
4287 - break; 24cfb8dRow pattern recognition patch (executor and commands).
4288 - } 24cfb8dRow pattern recognition patch (executor and commands).
4289 - 24cfb8dRow pattern recognition patch (executor and commands).
4290 - return rtn; 24cfb8dRow pattern recognition patch (executor and commands).
4291 - } 24cfb8dRow pattern recognition patch (executor and commands).
clear_reduced_frame() lines 4298-4304
Modified Lines Coverage: 6/6 lines (100.0%)
LineHitsSourceCommit
4298 35133 clear_reduced_frame(WindowAggState *winstate) 24cfb8dRow pattern recognition patch (executor and commands).
4299 - { 24cfb8dRow pattern recognition patch (executor and commands).
4300 35133 winstate->rpr_match_valid = false; 24cfb8dRow pattern recognition patch (executor and commands).
4301 35133 winstate->rpr_match_matched = false; 24cfb8dRow pattern recognition patch (executor and commands).
4302 35133 winstate->rpr_match_start = -1; 24cfb8dRow pattern recognition patch (executor and commands).
4303 35133 winstate->rpr_match_length = 0; 24cfb8dRow pattern recognition patch (executor and commands).
4304 35133 } 24cfb8dRow pattern recognition patch (executor and commands).
get_reduced_frame_status() lines 4327-4364
Modified Lines Coverage: 9/9 lines (100.0%)
LineHitsSourceCommit
4327 14179604 get_reduced_frame_status(WindowAggState *winstate, int64 pos) 24cfb8dRow pattern recognition patch (executor and commands).
4328 - { 24cfb8dRow pattern recognition patch (executor and commands).
4329 14179604 int64 start = winstate->rpr_match_start; 24cfb8dRow pattern recognition patch (executor and commands).
4330 14179604 int64 length = winstate->rpr_match_length; 24cfb8dRow pattern recognition patch (executor and commands).
4331 - 24cfb8dRow pattern recognition patch (executor and commands).
4332 14179604 if (!winstate->rpr_match_valid) 24cfb8dRow pattern recognition patch (executor and commands).
4333 - return RF_NOT_DETERMINED; 24cfb8dRow pattern recognition patch (executor and commands).
4334 - 24cfb8dRow pattern recognition patch (executor and commands).
4335 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4336 - * By here the record is valid and holds one of the three shapes above. 24cfb8dRow pattern recognition patch (executor and commands).
4337 - * 24cfb8dRow pattern recognition patch (executor and commands).
4338 - * The empty match (true, 0) must be classified first: it has length 0, so 24cfb8dRow pattern recognition patch (executor and commands).
4339 - * the range test below would compute start + length == start and reject 24cfb8dRow pattern recognition patch (executor and commands).
4340 - * its own start position as out of range. 24cfb8dRow pattern recognition patch (executor and commands).
4341 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4342 14162336 if (pos == start && winstate->rpr_match_matched && length == 0) 24cfb8dRow pattern recognition patch (executor and commands).
4343 - return RF_EMPTY_MATCH; 24cfb8dRow pattern recognition patch (executor and commands).
4344 - 24cfb8dRow pattern recognition patch (executor and commands).
4345 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4346 - * By here length >= 1 -- the only zero-length record, the empty match, 24cfb8dRow pattern recognition patch (executor and commands).
4347 - * has been handled -- so [start, start + length) is a well-formed range. 24cfb8dRow pattern recognition patch (executor and commands).
4348 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4349 14160124 if (pos < start || pos >= start + length) 24cfb8dRow pattern recognition patch (executor and commands).
4350 - return RF_NOT_DETERMINED; 24cfb8dRow pattern recognition patch (executor and commands).
4351 - 24cfb8dRow pattern recognition patch (executor and commands).
4352 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4353 - * By here pos lies within [start, start + length). An unmatched record 24cfb8dRow pattern recognition patch (executor and commands).
4354 - * is (false, 1), so this returns for its single in-range position. 24cfb8dRow pattern recognition patch (executor and commands).
4355 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4356 14015792 if (!winstate->rpr_match_matched) 24cfb8dRow pattern recognition patch (executor and commands).
4357 - return RF_UNMATCHED; 24cfb8dRow pattern recognition patch (executor and commands).
4358 - 24cfb8dRow pattern recognition patch (executor and commands).
4359 - /* By here the match is real (true, >= 1) and pos is one of its rows. */ 24cfb8dRow pattern recognition patch (executor and commands).
4360 12994464 if (pos == start) 24cfb8dRow pattern recognition patch (executor and commands).
4361 1113388 return RF_FRAME_HEAD; 24cfb8dRow pattern recognition patch (executor and commands).
4362 - 24cfb8dRow pattern recognition patch (executor and commands).
4363 - return RF_SKIPPED; 24cfb8dRow pattern recognition patch (executor and commands).
4364 - } 24cfb8dRow pattern recognition patch (executor and commands).
advance_nav_mark() lines 4380-4419
Modified Lines Coverage: 14/14 lines (100.0%)
LineHitsSourceCommit
4380 988852 advance_nav_mark(WindowAggState *winstate, int64 currentPos) 0ed285dDrive RPR row pattern matching once per row
4381 - { 0ed285dDrive RPR row pattern matching once per row
4382 988852 int64 navmarkpos; 0ed285dDrive RPR row pattern matching once per row
4383 - 0ed285dDrive RPR row pattern matching once per row
4384 - /* No RPR navigation read pointer: nothing to advance */ 0ed285dDrive RPR row pattern matching once per row
4385 988852 if (winstate->nav_winobj == NULL) 0ed285dDrive RPR row pattern matching once per row
4386 - return; 0ed285dDrive RPR row pattern matching once per row
4387 - 0ed285dDrive RPR row pattern matching once per row
4388 - /* RETAIN_ALL disables trim for the backward (PREV/LAST) dimension */ 0ed285dDrive RPR row pattern matching once per row
4389 988852 if (winstate->navMaxOffsetKind == RPR_NAV_OFFSET_RETAIN_ALL) 0ed285dDrive RPR row pattern matching once per row
4390 - return; 0ed285dDrive RPR row pattern matching once per row
4391 - 0ed285dDrive RPR row pattern matching once per row
4392 - /* navMax is FIXED here: NEEDS_EVAL resolved, RETAIN_ALL returned */ 0ed285dDrive RPR row pattern matching once per row
4393 988812 Assert(winstate->navMaxOffsetKind == RPR_NAV_OFFSET_FIXED); 0ed285dDrive RPR row pattern matching once per row
4394 - 0ed285dDrive RPR row pattern matching once per row
4395 988812 if (currentPos > winstate->navMaxOffset) 0ed285dDrive RPR row pattern matching once per row
4396 966380 navmarkpos = currentPos - winstate->navMaxOffset; 0ed285dDrive RPR row pattern matching once per row
4397 - else 0ed285dDrive RPR row pattern matching once per row
4398 - navmarkpos = 0; 0ed285dDrive RPR row pattern matching once per row
4399 - 0ed285dDrive RPR row pattern matching once per row
4400 988812 if (winstate->hasFirstNav && winstate->nfaContext != NULL) 0ed285dDrive RPR row pattern matching once per row
4401 - { 0ed285dDrive RPR row pattern matching once per row
4402 5952 int64 firstreach; 0ed285dDrive RPR row pattern matching once per row
4403 - 0ed285dDrive RPR row pattern matching once per row
4404 - /* navFirst is always FIXED; it never takes RETAIN_ALL */ 0ed285dDrive RPR row pattern matching once per row
4405 5952 Assert(winstate->navFirstOffsetKind == RPR_NAV_OFFSET_FIXED); 0ed285dDrive RPR row pattern matching once per row
4406 - 0ed285dDrive RPR row pattern matching once per row
4407 - /* 0ed285dDrive RPR row pattern matching once per row
4408 - * Head context has the smallest matchStartRow (contexts appended in 0ed285dDrive RPR row pattern matching once per row
4409 - * nondecreasing order), so bounding by it covers every FIRST reach. 0ed285dDrive RPR row pattern matching once per row
4410 - */ 0ed285dDrive RPR row pattern matching once per row
4411 5952 if (!pg_add_s64_overflow(winstate->nfaContext->matchStartRow, 0ed285dDrive RPR row pattern matching once per row
4412 - winstate->navFirstOffset, 0ed285dDrive RPR row pattern matching once per row
4413 - &firstreach)) 0ed285dDrive RPR row pattern matching once per row
4414 5916 navmarkpos = Min(navmarkpos, Max(firstreach, 0)); 0ed285dDrive RPR row pattern matching once per row
4415 - } 0ed285dDrive RPR row pattern matching once per row
4416 - 0ed285dDrive RPR row pattern matching once per row
4417 988812 if (navmarkpos > winstate->nav_winobj->markpos) 0ed285dDrive RPR row pattern matching once per row
4418 970988 WinSetMarkPosition(winstate->nav_winobj, navmarkpos); 0ed285dDrive RPR row pattern matching once per row
4419 - } 0ed285dDrive RPR row pattern matching once per row
advance_reduced_frame_nfa() lines 4430-4501
Modified Lines Coverage: 19/19 lines (100.0%)
LineHitsSourceCommit
4430 99360 advance_reduced_frame_nfa(WindowObject winobj, RPRNFAContext *targetCtx, 0ed285dDrive RPR row pattern matching once per row
4431 - int64 pos, bool hasLimitedFrame, int64 frameOffset) 0ed285dDrive RPR row pattern matching once per row
4432 - { 0ed285dDrive RPR row pattern matching once per row
4433 99360 WindowAggState *winstate = winobj->winstate; 0ed285dDrive RPR row pattern matching once per row
4434 99360 int64 currentPos; 0ed285dDrive RPR row pattern matching once per row
4435 99360 int64 startPos; 0ed285dDrive RPR row pattern matching once per row
4436 - 0ed285dDrive RPR row pattern matching once per row
4437 - /* 0ed285dDrive RPR row pattern matching once per row
4438 - * Determine where to start processing. Usually nfaLastProcessedRow+1 >= 0ed285dDrive RPR row pattern matching once per row
4439 - * pos since contexts are created at currentPos+1 during processing. 0ed285dDrive RPR row pattern matching once per row
4440 - * However, pos can exceed this when rows are skipped (e.g., unmatched 0ed285dDrive RPR row pattern matching once per row
4441 - * rows don't update nfaLastProcessedRow). 0ed285dDrive RPR row pattern matching once per row
4442 - */ 0ed285dDrive RPR row pattern matching once per row
4443 99360 startPos = Max(pos, winstate->nfaLastProcessedRow + 1); 0ed285dDrive RPR row pattern matching once per row
4444 - 0ed285dDrive RPR row pattern matching once per row
4445 - /* 0ed285dDrive RPR row pattern matching once per row
4446 - * Process rows until target context completes or we hit boundaries. Each 0ed285dDrive RPR row pattern matching once per row
4447 - * row evaluation is shared across all active contexts. 0ed285dDrive RPR row pattern matching once per row
4448 - */ 0ed285dDrive RPR row pattern matching once per row
4449 1088212 for (currentPos = startPos; targetCtx->states != NULL; currentPos++) 0ed285dDrive RPR row pattern matching once per row
4450 - { 0ed285dDrive RPR row pattern matching once per row
4451 995264 bool rowExists; 0ed285dDrive RPR row pattern matching once per row
4452 - 0ed285dDrive RPR row pattern matching once per row
4453 - /* 0ed285dDrive RPR row pattern matching once per row
4454 - * Evaluate variables for this row - done only once, shared by all 0ed285dDrive RPR row pattern matching once per row
4455 - * contexts. 0ed285dDrive RPR row pattern matching once per row
4456 - * 0ed285dDrive RPR row pattern matching once per row
4457 - * Set nav_match_start to the head context's matchStartRow for 0ed285dDrive RPR row pattern matching once per row
4458 - * FIRST/LAST navigation. Match_start-dependent variables (FIRST, 0ed285dDrive RPR row pattern matching once per row
4459 - * LAST-with-offset) are re-evaluated per-context in ExecRPRProcessRow 0ed285dDrive RPR row pattern matching once per row
4460 - * when matchStartRow differs. 0ed285dDrive RPR row pattern matching once per row
4461 - */ 0ed285dDrive RPR row pattern matching once per row
4462 995264 winstate->nav_match_start = targetCtx->matchStartRow; 0ed285dDrive RPR row pattern matching once per row
4463 995264 rowExists = nfa_evaluate_row(winobj, currentPos, winstate->nfaVarMatched); 0ed285dDrive RPR row pattern matching once per row
4464 - 0ed285dDrive RPR row pattern matching once per row
4465 - /* No more rows in partition? Finalize all contexts */ 0ed285dDrive RPR row pattern matching once per row
4466 995200 if (!rowExists) 0ed285dDrive RPR row pattern matching once per row
4467 - { 0ed285dDrive RPR row pattern matching once per row
4468 6348 ExecRPRFinalizeAllContexts(winstate, currentPos - 1); 0ed285dDrive RPR row pattern matching once per row
4469 - /* Clean up dead contexts from finalization */ 0ed285dDrive RPR row pattern matching once per row
4470 6348 ExecRPRCleanupDeadContexts(winstate, targetCtx); 0ed285dDrive RPR row pattern matching once per row
4471 6348 break; 0ed285dDrive RPR row pattern matching once per row
4472 - } 0ed285dDrive RPR row pattern matching once per row
4473 - 0ed285dDrive RPR row pattern matching once per row
4474 - /* Update last processed row */ 0ed285dDrive RPR row pattern matching once per row
4475 988852 winstate->nfaLastProcessedRow = currentPos; 0ed285dDrive RPR row pattern matching once per row
4476 - 0ed285dDrive RPR row pattern matching once per row
4477 - /*-------------------------- 0ed285dDrive RPR row pattern matching once per row
4478 - * Process all contexts for this row: 0ed285dDrive RPR row pattern matching once per row
4479 - * 1. Match all (convergence) 0ed285dDrive RPR row pattern matching once per row
4480 - * 2. Absorb redundant 0ed285dDrive RPR row pattern matching once per row
4481 - * 3. Advance all (divergence) 0ed285dDrive RPR row pattern matching once per row
4482 - */ 0ed285dDrive RPR row pattern matching once per row
4483 988852 ExecRPRProcessRow(winstate, currentPos, hasLimitedFrame, frameOffset); 0ed285dDrive RPR row pattern matching once per row
4484 - 0ed285dDrive RPR row pattern matching once per row
4485 - /* 0ed285dDrive RPR row pattern matching once per row
4486 - * Create a new context for the next potential start position. This 0ed285dDrive RPR row pattern matching once per row
4487 - * enables overlapping match detection for SKIP TO NEXT ROW. 0ed285dDrive RPR row pattern matching once per row
4488 - */ 0ed285dDrive RPR row pattern matching once per row
4489 988852 ExecRPRStartContext(winstate, currentPos + 1); 0ed285dDrive RPR row pattern matching once per row
4490 - 0ed285dDrive RPR row pattern matching once per row
4491 - /* 0ed285dDrive RPR row pattern matching once per row
4492 - * Clean up dead contexts (failed with no active states and no match). 0ed285dDrive RPR row pattern matching once per row
4493 - * This removes contexts that failed during processing and counts them 0ed285dDrive RPR row pattern matching once per row
4494 - * appropriately as pruned or mismatched. 0ed285dDrive RPR row pattern matching once per row
4495 - */ 0ed285dDrive RPR row pattern matching once per row
4496 988852 ExecRPRCleanupDeadContexts(winstate, targetCtx); 0ed285dDrive RPR row pattern matching once per row
4497 - 0ed285dDrive RPR row pattern matching once per row
4498 - /* Advance the nav mark to the frontier so trim can free old rows. */ 0ed285dDrive RPR row pattern matching once per row
4499 988852 advance_nav_mark(winstate, currentPos); 0ed285dDrive RPR row pattern matching once per row
4500 - } 0ed285dDrive RPR row pattern matching once per row
4501 99296 } 0ed285dDrive RPR row pattern matching once per row
update_reduced_frame() lines 4518-4631
Modified Lines Coverage: 49/49 lines (100.0%)
LineHitsSourceCommit
4518 130008 update_reduced_frame(WindowObject winobj, int64 pos) 24cfb8dRow pattern recognition patch (executor and commands).
4519 - { 24cfb8dRow pattern recognition patch (executor and commands).
4520 130008 WindowAggState *winstate = winobj->winstate; 24cfb8dRow pattern recognition patch (executor and commands).
4521 130008 RPRNFAContext *targetCtx; 24cfb8dRow pattern recognition patch (executor and commands).
4522 130008 int frameOptions = winstate->frameOptions; 24cfb8dRow pattern recognition patch (executor and commands).
4523 130008 bool hasLimitedFrame; 24cfb8dRow pattern recognition patch (executor and commands).
4524 130008 int64 frameOffset = 0; 24cfb8dRow pattern recognition patch (executor and commands).
4525 130008 int64 matchLen; 24cfb8dRow pattern recognition patch (executor and commands).
4526 - 24cfb8dRow pattern recognition patch (executor and commands).
4527 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4528 - * Check if we have a limited frame (ROWS ... N FOLLOWING). Each context 24cfb8dRow pattern recognition patch (executor and commands).
4529 - * needs its own frame end based on matchStartRow + offset. 24cfb8dRow pattern recognition patch (executor and commands).
4530 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4531 130008 hasLimitedFrame = (frameOptions & FRAMEOPTION_ROWS) && 24cfb8dRow pattern recognition patch (executor and commands).
4532 - !(frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING); 24cfb8dRow pattern recognition patch (executor and commands).
4533 130008 if (hasLimitedFrame) 24cfb8dRow pattern recognition patch (executor and commands).
4534 408 frameOffset = DatumGetInt64(winstate->endOffsetValue); 24cfb8dRow pattern recognition patch (executor and commands).
4535 - 24cfb8dRow pattern recognition patch (executor and commands).
4536 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4537 - * Case 1: pos is before any existing context's start position. This means 24cfb8dRow pattern recognition patch (executor and commands).
4538 - * the position was already processed and determined unmatched. Head is 24cfb8dRow pattern recognition patch (executor and commands).
4539 - * the oldest context (lowest matchStartRow) since contexts are added at 24cfb8dRow pattern recognition patch (executor and commands).
4540 - * tail with increasing positions. 24cfb8dRow pattern recognition patch (executor and commands).
4541 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4542 130008 if (winstate->nfaContext != NULL && 24cfb8dRow pattern recognition patch (executor and commands).
4543 113640 pos < winstate->nfaContext->matchStartRow) 24cfb8dRow pattern recognition patch (executor and commands).
4544 - { 24cfb8dRow pattern recognition patch (executor and commands).
4545 - /* already processed, unmatched */ 24cfb8dRow pattern recognition patch (executor and commands).
4546 23816 winstate->rpr_match_valid = true; 24cfb8dRow pattern recognition patch (executor and commands).
4547 23816 winstate->rpr_match_matched = false; 24cfb8dRow pattern recognition patch (executor and commands).
4548 23816 winstate->rpr_match_start = pos; 24cfb8dRow pattern recognition patch (executor and commands).
4549 23816 winstate->rpr_match_length = 1; 24cfb8dRow pattern recognition patch (executor and commands).
4550 23816 return; 24cfb8dRow pattern recognition patch (executor and commands).
4551 - } 24cfb8dRow pattern recognition patch (executor and commands).
4552 - 24cfb8dRow pattern recognition patch (executor and commands).
4553 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4554 - * Case 2: Find existing context for this pos, or create new one. 24cfb8dRow pattern recognition patch (executor and commands).
4555 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4556 106192 targetCtx = ExecRPRGetHeadContext(winstate, pos); 24cfb8dRow pattern recognition patch (executor and commands).
4557 106192 if (targetCtx == NULL) 24cfb8dRow pattern recognition patch (executor and commands).
4558 - { 24cfb8dRow pattern recognition patch (executor and commands).
4559 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4560 - * No context exists. If pos is already processed, it means this row 24cfb8dRow pattern recognition patch (executor and commands).
4561 - * was already determined to be unmatched or skipped - no need to 24cfb8dRow pattern recognition patch (executor and commands).
4562 - * reprocess. 24cfb8dRow pattern recognition patch (executor and commands).
4563 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4564 16368 if (pos <= winstate->nfaLastProcessedRow) 24cfb8dRow pattern recognition patch (executor and commands).
4565 - { 24cfb8dRow pattern recognition patch (executor and commands).
4566 - /* already processed, unmatched */ 24cfb8dRow pattern recognition patch (executor and commands).
4567 6044 winstate->rpr_match_valid = true; 24cfb8dRow pattern recognition patch (executor and commands).
4568 6044 winstate->rpr_match_matched = false; 24cfb8dRow pattern recognition patch (executor and commands).
4569 6044 winstate->rpr_match_start = pos; 24cfb8dRow pattern recognition patch (executor and commands).
4570 6044 winstate->rpr_match_length = 1; 24cfb8dRow pattern recognition patch (executor and commands).
4571 6044 return; 24cfb8dRow pattern recognition patch (executor and commands).
4572 - } 24cfb8dRow pattern recognition patch (executor and commands).
4573 - /* Not yet processed - create new context and start fresh */ 24cfb8dRow pattern recognition patch (executor and commands).
4574 10324 targetCtx = ExecRPRStartContext(winstate, pos); 24cfb8dRow pattern recognition patch (executor and commands).
4575 - } 24cfb8dRow pattern recognition patch (executor and commands).
4576 89824 else if (targetCtx->states == NULL) 24cfb8dRow pattern recognition patch (executor and commands).
4577 - { 24cfb8dRow pattern recognition patch (executor and commands).
4578 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4579 - * The head context already completed in an earlier call. Reachable 24cfb8dRow pattern recognition patch (executor and commands).
4580 - * under SKIP TO NEXT ROW, where overlapping contexts let one reach 24cfb8dRow pattern recognition patch (executor and commands).
4581 - * FIN -- recording its result -- before the call for its own start 24cfb8dRow pattern recognition patch (executor and commands).
4582 - * row arrives. Register that result. 24cfb8dRow pattern recognition patch (executor and commands).
4583 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4584 788 goto register_result; 24cfb8dRow pattern recognition patch (executor and commands).
4585 - } 24cfb8dRow pattern recognition patch (executor and commands).
4586 - 24cfb8dRow pattern recognition patch (executor and commands).
4587 - /* Drive the NFA forward until pos's match is resolved. */ 0ed285dDrive RPR row pattern matching once per row
4588 99360 advance_reduced_frame_nfa(winobj, targetCtx, pos, hasLimitedFrame, 0ed285dDrive RPR row pattern matching once per row
4589 - frameOffset); 0ed285dDrive RPR row pattern matching once per row
4590 - 24cfb8dRow pattern recognition patch (executor and commands).
4591 100084 register_result: 24cfb8dRow pattern recognition patch (executor and commands).
4592 100084 Assert(pos == targetCtx->matchStartRow); 24cfb8dRow pattern recognition patch (executor and commands).
4593 - 24cfb8dRow pattern recognition patch (executor and commands).
4594 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4595 - * Record match result. 24cfb8dRow pattern recognition patch (executor and commands).
4596 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4597 100084 winstate->rpr_match_valid = true; 24cfb8dRow pattern recognition patch (executor and commands).
4598 100084 winstate->rpr_match_start = targetCtx->matchStartRow; 24cfb8dRow pattern recognition patch (executor and commands).
4599 - 24cfb8dRow pattern recognition patch (executor and commands).
4600 100084 if (targetCtx->matchEndRow < targetCtx->matchStartRow) 24cfb8dRow pattern recognition patch (executor and commands).
4601 - { 24cfb8dRow pattern recognition patch (executor and commands).
4602 63360 matchLen = targetCtx->lastProcessedRow - targetCtx->matchStartRow + 1; 24cfb8dRow pattern recognition patch (executor and commands).
4603 - 24cfb8dRow pattern recognition patch (executor and commands).
4604 63360 if (targetCtx->matchedState != NULL) 24cfb8dRow pattern recognition patch (executor and commands).
4605 - { 24cfb8dRow pattern recognition patch (executor and commands).
4606 - /* Empty match: FIN reached but 0 rows consumed */ 24cfb8dRow pattern recognition patch (executor and commands).
4607 436 winstate->rpr_match_matched = true; 24cfb8dRow pattern recognition patch (executor and commands).
4608 436 winstate->rpr_match_length = 0; 24cfb8dRow pattern recognition patch (executor and commands).
4609 436 ExecRPRRecordContextSuccess(winstate, 0); 24cfb8dRow pattern recognition patch (executor and commands).
4610 - } 24cfb8dRow pattern recognition patch (executor and commands).
4611 - else 24cfb8dRow pattern recognition patch (executor and commands).
4612 - { 24cfb8dRow pattern recognition patch (executor and commands).
4613 - /* No match */ 24cfb8dRow pattern recognition patch (executor and commands).
4614 62924 winstate->rpr_match_matched = false; 24cfb8dRow pattern recognition patch (executor and commands).
4615 62924 winstate->rpr_match_length = 1; 24cfb8dRow pattern recognition patch (executor and commands).
4616 62924 ExecRPRRecordContextFailure(winstate, matchLen); 24cfb8dRow pattern recognition patch (executor and commands).
4617 - } 24cfb8dRow pattern recognition patch (executor and commands).
4618 63360 ExecRPRFreeContext(winstate, targetCtx); 24cfb8dRow pattern recognition patch (executor and commands).
4619 63360 return; 24cfb8dRow pattern recognition patch (executor and commands).
4620 - } 24cfb8dRow pattern recognition patch (executor and commands).
4621 - 24cfb8dRow pattern recognition patch (executor and commands).
4622 - /* Match succeeded */ 24cfb8dRow pattern recognition patch (executor and commands).
4623 36724 matchLen = targetCtx->matchEndRow - targetCtx->matchStartRow + 1; 24cfb8dRow pattern recognition patch (executor and commands).
4624 - 24cfb8dRow pattern recognition patch (executor and commands).
4625 36724 winstate->rpr_match_matched = true; 24cfb8dRow pattern recognition patch (executor and commands).
4626 36724 winstate->rpr_match_length = matchLen; 24cfb8dRow pattern recognition patch (executor and commands).
4627 36724 ExecRPRRecordContextSuccess(winstate, matchLen); 24cfb8dRow pattern recognition patch (executor and commands).
4628 - 24cfb8dRow pattern recognition patch (executor and commands).
4629 - /* Remove the matched context */ 24cfb8dRow pattern recognition patch (executor and commands).
4630 36724 ExecRPRFreeContext(winstate, targetCtx); 24cfb8dRow pattern recognition patch (executor and commands).
4631 - } 24cfb8dRow pattern recognition patch (executor and commands).
nfa_evaluate_row() lines 4646-4689
Modified Lines Coverage: 20/20 lines (100.0%)
LineHitsSourceCommit
4646 995264 nfa_evaluate_row(WindowObject winobj, int64 pos, bool *varMatched) 24cfb8dRow pattern recognition patch (executor and commands).
4647 - { 24cfb8dRow pattern recognition patch (executor and commands).
4648 995264 WindowAggState *winstate = winobj->winstate; 24cfb8dRow pattern recognition patch (executor and commands).
4649 995264 ExprContext *econtext = winstate->rprContext; a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
4650 995264 TupleTableSlot *slot; 24cfb8dRow pattern recognition patch (executor and commands).
4651 995264 int64 saved_pos; 24cfb8dRow pattern recognition patch (executor and commands).
4652 - 24cfb8dRow pattern recognition patch (executor and commands).
4653 - /* Release the previous row's DEFINE evaluation memory */ a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
4654 995264 ResetExprContext(econtext); a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
4655 - a70f1c1Use a dedicated ExprContext for RPR DEFINE clause evaluation
4656 - /* Fetch current row into temp_slot_1 */ 24cfb8dRow pattern recognition patch (executor and commands).
4657 995264 slot = winstate->temp_slot_1; 24cfb8dRow pattern recognition patch (executor and commands).
4658 995264 if (!window_gettupleslot(winobj, pos, slot)) 24cfb8dRow pattern recognition patch (executor and commands).
4659 - return false; /* No row exists */ 24cfb8dRow pattern recognition patch (executor and commands).
4660 - 24cfb8dRow pattern recognition patch (executor and commands).
4661 - /* Set up 1-slot context: only ecxt_outertuple */ 24cfb8dRow pattern recognition patch (executor and commands).
4662 988916 econtext->ecxt_outertuple = slot; 24cfb8dRow pattern recognition patch (executor and commands).
4663 - 24cfb8dRow pattern recognition patch (executor and commands).
4664 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4665 - * Save and set currentpos so that EEOP_RPR_NAV_SET opcodes can calculate 24cfb8dRow pattern recognition patch (executor and commands).
4666 - * target positions (currentpos +/- offset). 24cfb8dRow pattern recognition patch (executor and commands).
4667 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4668 988916 saved_pos = winstate->currentpos; 24cfb8dRow pattern recognition patch (executor and commands).
4669 988916 winstate->currentpos = pos; 24cfb8dRow pattern recognition patch (executor and commands).
4670 - 24cfb8dRow pattern recognition patch (executor and commands).
4671 - /* Invalidate nav_slot cache so PREV/NEXT re-fetch for new row */ 24cfb8dRow pattern recognition patch (executor and commands).
4672 988916 winstate->nav_slot_pos = -1; 24cfb8dRow pattern recognition patch (executor and commands).
4673 - 24cfb8dRow pattern recognition patch (executor and commands).
4674 3336780 foreach_ptr(ExprState, exprState, winstate->defineClauseExprs) b848408Tidy up row pattern recognition plumbing
4675 - { 24cfb8dRow pattern recognition patch (executor and commands).
4676 2347928 int varIdx = foreach_current_index(exprState); 4cf9108Further tidy up row pattern recognition plumbing
4677 2347928 Datum result; 24cfb8dRow pattern recognition patch (executor and commands).
4678 2347928 bool isnull; 24cfb8dRow pattern recognition patch (executor and commands).
4679 - 24cfb8dRow pattern recognition patch (executor and commands).
4680 - /* Evaluate DEFINE expression */ 24cfb8dRow pattern recognition patch (executor and commands).
4681 2347928 result = ExecEvalExpr(exprState, econtext, &isnull); 24cfb8dRow pattern recognition patch (executor and commands).
4682 - 24cfb8dRow pattern recognition patch (executor and commands).
4683 3721940 varMatched[varIdx] = (!isnull && DatumGetBool(result)); 24cfb8dRow pattern recognition patch (executor and commands).
4684 - } 24cfb8dRow pattern recognition patch (executor and commands).
4685 - 24cfb8dRow pattern recognition patch (executor and commands).
4686 988852 winstate->currentpos = saved_pos; 24cfb8dRow pattern recognition patch (executor and commands).
4687 - 24cfb8dRow pattern recognition patch (executor and commands).
4688 988852 return true; /* Row exists */ 24cfb8dRow pattern recognition patch (executor and commands).
4689 - } 24cfb8dRow pattern recognition patch (executor and commands).
WinGetSlotInFrame() lines 4706-4916
Modified Lines Coverage: 87/101 lines (86.1%)
LineHitsSourceCommit
4706 1531520 WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot, 24cfb8dRow pattern recognition patch (executor and commands).
4707 - int relpos, int seektype, bool set_mark, 24cfb8dRow pattern recognition patch (executor and commands).
4708 - bool *isnull, bool *isout) 24cfb8dRow pattern recognition patch (executor and commands).
4709 - { 24cfb8dRow pattern recognition patch (executor and commands).
4710 1531520 WindowAggState *winstate; 24cfb8dRow pattern recognition patch (executor and commands).
4711 1531520 int64 abs_pos; 24cfb8dRow pattern recognition patch (executor and commands).
4712 1531520 int64 mark_pos; 24cfb8dRow pattern recognition patch (executor and commands).
4713 1531520 int64 num_reduced_frame; 24cfb8dRow pattern recognition patch (executor and commands).
4714 - 24cfb8dRow pattern recognition patch (executor and commands).
4715 1531520 Assert(WindowObjectIsValid(winobj)); 24cfb8dRow pattern recognition patch (executor and commands).
4716 1531520 winstate = winobj->winstate; 24cfb8dRow pattern recognition patch (executor and commands).
4717 - 24cfb8dRow pattern recognition patch (executor and commands).
4718 1531520 switch (seektype) 24cfb8dRow pattern recognition patch (executor and commands).
4719 - { 24cfb8dRow pattern recognition patch (executor and commands).
4720 0 case WINDOW_SEEK_CURRENT: 24cfb8dRow pattern recognition patch (executor and commands).
4721 0 elog(ERROR, "WINDOW_SEEK_CURRENT is not supported for WinGetFuncArgInFrame"); 24cfb8dRow pattern recognition patch (executor and commands).
4722 - abs_pos = mark_pos = 0; /* keep compiler quiet */ 24cfb8dRow pattern recognition patch (executor and commands).
4723 - break; 24cfb8dRow pattern recognition patch (executor and commands).
4724 969816 case WINDOW_SEEK_HEAD: 24cfb8dRow pattern recognition patch (executor and commands).
4725 - /* rejecting relpos < 0 is easy and simplifies code below */ 24cfb8dRow pattern recognition patch (executor and commands).
4726 969816 if (relpos < 0) 24cfb8dRow pattern recognition patch (executor and commands).
4727 0 goto out_of_frame; 24cfb8dRow pattern recognition patch (executor and commands).
4728 969816 update_frameheadpos(winstate); 24cfb8dRow pattern recognition patch (executor and commands).
4729 969788 abs_pos = winstate->frameheadpos + relpos; 24cfb8dRow pattern recognition patch (executor and commands).
4730 969788 mark_pos = abs_pos; 24cfb8dRow pattern recognition patch (executor and commands).
4731 - 24cfb8dRow pattern recognition patch (executor and commands).
4732 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4733 - * Account for exclusion option if one is active, but advance only 24cfb8dRow pattern recognition patch (executor and commands).
4734 - * abs_pos not mark_pos. This prevents changes of the current 24cfb8dRow pattern recognition patch (executor and commands).
4735 - * row's peer group from resulting in trying to fetch a row before 24cfb8dRow pattern recognition patch (executor and commands).
4736 - * some previous mark position. 24cfb8dRow pattern recognition patch (executor and commands).
4737 - * 24cfb8dRow pattern recognition patch (executor and commands).
4738 - * Note that in some corner cases such as current row being 24cfb8dRow pattern recognition patch (executor and commands).
4739 - * outside frame, these calculations are theoretically too simple, 24cfb8dRow pattern recognition patch (executor and commands).
4740 - * but it doesn't matter because we'll end up deciding the row is 24cfb8dRow pattern recognition patch (executor and commands).
4741 - * out of frame. We do not attempt to avoid fetching rows past 24cfb8dRow pattern recognition patch (executor and commands).
4742 - * end of frame; that would happen in some cases anyway. 24cfb8dRow pattern recognition patch (executor and commands).
4743 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4744 969788 switch (winstate->frameOptions & FRAMEOPTION_EXCLUSION) 24cfb8dRow pattern recognition patch (executor and commands).
4745 - { 24cfb8dRow pattern recognition patch (executor and commands).
4746 - case 0: 24cfb8dRow pattern recognition patch (executor and commands).
4747 - /* no adjustment needed */ 24cfb8dRow pattern recognition patch (executor and commands).
4748 - break; 24cfb8dRow pattern recognition patch (executor and commands).
4749 160 case FRAMEOPTION_EXCLUDE_CURRENT_ROW: 24cfb8dRow pattern recognition patch (executor and commands).
4750 160 if (abs_pos >= winstate->currentpos && 24cfb8dRow pattern recognition patch (executor and commands).
4751 - winstate->currentpos >= winstate->frameheadpos) 24cfb8dRow pattern recognition patch (executor and commands).
4752 44 abs_pos++; 24cfb8dRow pattern recognition patch (executor and commands).
4753 - break; 24cfb8dRow pattern recognition patch (executor and commands).
4754 80 case FRAMEOPTION_EXCLUDE_GROUP: 24cfb8dRow pattern recognition patch (executor and commands).
4755 80 update_grouptailpos(winstate); 24cfb8dRow pattern recognition patch (executor and commands).
4756 80 if (abs_pos >= winstate->groupheadpos && 24cfb8dRow pattern recognition patch (executor and commands).
4757 48 winstate->grouptailpos > winstate->frameheadpos) 24cfb8dRow pattern recognition patch (executor and commands).
4758 - { 24cfb8dRow pattern recognition patch (executor and commands).
4759 48 int64 overlapstart = Max(winstate->groupheadpos, 24cfb8dRow pattern recognition patch (executor and commands).
4760 - winstate->frameheadpos); 24cfb8dRow pattern recognition patch (executor and commands).
4761 - 24cfb8dRow pattern recognition patch (executor and commands).
4762 48 abs_pos += winstate->grouptailpos - overlapstart; 24cfb8dRow pattern recognition patch (executor and commands).
4763 - } 24cfb8dRow pattern recognition patch (executor and commands).
4764 - break; 24cfb8dRow pattern recognition patch (executor and commands).
4765 240 case FRAMEOPTION_EXCLUDE_TIES: 24cfb8dRow pattern recognition patch (executor and commands).
4766 240 update_grouptailpos(winstate); 24cfb8dRow pattern recognition patch (executor and commands).
4767 240 if (abs_pos >= winstate->groupheadpos && 24cfb8dRow pattern recognition patch (executor and commands).
4768 176 winstate->grouptailpos > winstate->frameheadpos) 24cfb8dRow pattern recognition patch (executor and commands).
4769 - { 24cfb8dRow pattern recognition patch (executor and commands).
4770 96 int64 overlapstart = Max(winstate->groupheadpos, 24cfb8dRow pattern recognition patch (executor and commands).
4771 - winstate->frameheadpos); 24cfb8dRow pattern recognition patch (executor and commands).
4772 - 24cfb8dRow pattern recognition patch (executor and commands).
4773 96 if (abs_pos == overlapstart) 24cfb8dRow pattern recognition patch (executor and commands).
4774 56 abs_pos = winstate->currentpos; 24cfb8dRow pattern recognition patch (executor and commands).
4775 - else 24cfb8dRow pattern recognition patch (executor and commands).
4776 40 abs_pos += winstate->grouptailpos - overlapstart - 1; 24cfb8dRow pattern recognition patch (executor and commands).
4777 - } 24cfb8dRow pattern recognition patch (executor and commands).
4778 - break; 24cfb8dRow pattern recognition patch (executor and commands).
4779 0 default: 24cfb8dRow pattern recognition patch (executor and commands).
4780 0 elog(ERROR, "unrecognized frame option state: 0x%x", 24cfb8dRow pattern recognition patch (executor and commands).
4781 - winstate->frameOptions); 24cfb8dRow pattern recognition patch (executor and commands).
4782 - break; 24cfb8dRow pattern recognition patch (executor and commands).
4783 - } 24cfb8dRow pattern recognition patch (executor and commands).
4784 969788 num_reduced_frame = row_is_in_reduced_frame(winobj, 24cfb8dRow pattern recognition patch (executor and commands).
4785 - winstate->frameheadpos); 24cfb8dRow pattern recognition patch (executor and commands).
4786 969788 if (num_reduced_frame < 0) 24cfb8dRow pattern recognition patch (executor and commands).
4787 960732 goto out_of_frame; 24cfb8dRow pattern recognition patch (executor and commands).
4788 9056 else if (num_reduced_frame > 0) 24cfb8dRow pattern recognition patch (executor and commands).
4789 6064 if (relpos >= num_reduced_frame) 24cfb8dRow pattern recognition patch (executor and commands).
4790 16 goto out_of_frame; 24cfb8dRow pattern recognition patch (executor and commands).
4791 - break; 24cfb8dRow pattern recognition patch (executor and commands).
4792 561704 case WINDOW_SEEK_TAIL: 24cfb8dRow pattern recognition patch (executor and commands).
4793 - /* rejecting relpos > 0 is easy and simplifies code below */ 24cfb8dRow pattern recognition patch (executor and commands).
4794 561704 if (relpos > 0) 24cfb8dRow pattern recognition patch (executor and commands).
4795 0 goto out_of_frame; 24cfb8dRow pattern recognition patch (executor and commands).
4796 - 24cfb8dRow pattern recognition patch (executor and commands).
4797 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4798 - * RPR cares about frame head pos. Need to call 24cfb8dRow pattern recognition patch (executor and commands).
4799 - * update_frameheadpos 24cfb8dRow pattern recognition patch (executor and commands).
4800 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4801 561704 update_frameheadpos(winstate); 24cfb8dRow pattern recognition patch (executor and commands).
4802 - 24cfb8dRow pattern recognition patch (executor and commands).
4803 561704 update_frametailpos(winstate); 24cfb8dRow pattern recognition patch (executor and commands).
4804 561700 abs_pos = winstate->frametailpos - 1 + relpos; 24cfb8dRow pattern recognition patch (executor and commands).
4805 - 24cfb8dRow pattern recognition patch (executor and commands).
4806 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4807 - * Account for exclusion option if one is active. If there is no 24cfb8dRow pattern recognition patch (executor and commands).
4808 - * exclusion, we can safely set the mark at the accessed row. But 24cfb8dRow pattern recognition patch (executor and commands).
4809 - * if there is, we can only mark the frame start, because we can't 24cfb8dRow pattern recognition patch (executor and commands).
4810 - * be sure how far back in the frame the exclusion might cause us 24cfb8dRow pattern recognition patch (executor and commands).
4811 - * to fetch in future. Furthermore, we have to actually check 24cfb8dRow pattern recognition patch (executor and commands).
4812 - * against frameheadpos here, since it's unsafe to try to fetch a 24cfb8dRow pattern recognition patch (executor and commands).
4813 - * row before frame start if the mark might be there already. 24cfb8dRow pattern recognition patch (executor and commands).
4814 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4815 561700 switch (winstate->frameOptions & FRAMEOPTION_EXCLUSION) 24cfb8dRow pattern recognition patch (executor and commands).
4816 - { 24cfb8dRow pattern recognition patch (executor and commands).
4817 - case 0: 24cfb8dRow pattern recognition patch (executor and commands).
4818 - /* no adjustment needed */ 24cfb8dRow pattern recognition patch (executor and commands).
4819 - mark_pos = abs_pos; 24cfb8dRow pattern recognition patch (executor and commands).
4820 - break; 24cfb8dRow pattern recognition patch (executor and commands).
4821 120 case FRAMEOPTION_EXCLUDE_CURRENT_ROW: 24cfb8dRow pattern recognition patch (executor and commands).
4822 120 if (abs_pos <= winstate->currentpos && 24cfb8dRow pattern recognition patch (executor and commands).
4823 - winstate->currentpos < winstate->frametailpos) 24cfb8dRow pattern recognition patch (executor and commands).
4824 12 abs_pos--; 24cfb8dRow pattern recognition patch (executor and commands).
4825 120 update_frameheadpos(winstate); 24cfb8dRow pattern recognition patch (executor and commands).
4826 120 if (abs_pos < winstate->frameheadpos) 24cfb8dRow pattern recognition patch (executor and commands).
4827 8 goto out_of_frame; 24cfb8dRow pattern recognition patch (executor and commands).
4828 - mark_pos = winstate->frameheadpos; 24cfb8dRow pattern recognition patch (executor and commands).
4829 - break; 24cfb8dRow pattern recognition patch (executor and commands).
4830 160 case FRAMEOPTION_EXCLUDE_GROUP: 24cfb8dRow pattern recognition patch (executor and commands).
4831 160 update_grouptailpos(winstate); 24cfb8dRow pattern recognition patch (executor and commands).
4832 160 if (abs_pos < winstate->grouptailpos && 24cfb8dRow pattern recognition patch (executor and commands).
4833 36 winstate->groupheadpos < winstate->frametailpos) 24cfb8dRow pattern recognition patch (executor and commands).
4834 - { 24cfb8dRow pattern recognition patch (executor and commands).
4835 36 int64 overlapend = Min(winstate->grouptailpos, 24cfb8dRow pattern recognition patch (executor and commands).
4836 - winstate->frametailpos); 24cfb8dRow pattern recognition patch (executor and commands).
4837 - 24cfb8dRow pattern recognition patch (executor and commands).
4838 36 abs_pos -= overlapend - winstate->groupheadpos; 24cfb8dRow pattern recognition patch (executor and commands).
4839 - } 24cfb8dRow pattern recognition patch (executor and commands).
4840 160 update_frameheadpos(winstate); 24cfb8dRow pattern recognition patch (executor and commands).
4841 160 if (abs_pos < winstate->frameheadpos) 24cfb8dRow pattern recognition patch (executor and commands).
4842 36 goto out_of_frame; 24cfb8dRow pattern recognition patch (executor and commands).
4843 - mark_pos = winstate->frameheadpos; 24cfb8dRow pattern recognition patch (executor and commands).
4844 - break; 24cfb8dRow pattern recognition patch (executor and commands).
4845 128 case FRAMEOPTION_EXCLUDE_TIES: 24cfb8dRow pattern recognition patch (executor and commands).
4846 128 update_grouptailpos(winstate); 24cfb8dRow pattern recognition patch (executor and commands).
4847 128 if (abs_pos < winstate->grouptailpos && 24cfb8dRow pattern recognition patch (executor and commands).
4848 48 winstate->groupheadpos < winstate->frametailpos) 24cfb8dRow pattern recognition patch (executor and commands).
4849 - { 24cfb8dRow pattern recognition patch (executor and commands).
4850 48 int64 overlapend = Min(winstate->grouptailpos, 24cfb8dRow pattern recognition patch (executor and commands).
4851 - winstate->frametailpos); 24cfb8dRow pattern recognition patch (executor and commands).
4852 - 24cfb8dRow pattern recognition patch (executor and commands).
4853 48 if (abs_pos == overlapend - 1) 24cfb8dRow pattern recognition patch (executor and commands).
4854 48 abs_pos = winstate->currentpos; 24cfb8dRow pattern recognition patch (executor and commands).
4855 - else 24cfb8dRow pattern recognition patch (executor and commands).
4856 0 abs_pos -= overlapend - 1 - winstate->groupheadpos; 24cfb8dRow pattern recognition patch (executor and commands).
4857 - } 24cfb8dRow pattern recognition patch (executor and commands).
4858 128 update_frameheadpos(winstate); 24cfb8dRow pattern recognition patch (executor and commands).
4859 128 if (abs_pos < winstate->frameheadpos) 24cfb8dRow pattern recognition patch (executor and commands).
4860 24 goto out_of_frame; 24cfb8dRow pattern recognition patch (executor and commands).
4861 - mark_pos = winstate->frameheadpos; 24cfb8dRow pattern recognition patch (executor and commands).
4862 - break; 24cfb8dRow pattern recognition patch (executor and commands).
4863 0 default: 24cfb8dRow pattern recognition patch (executor and commands).
4864 0 elog(ERROR, "unrecognized frame option state: 0x%x", 24cfb8dRow pattern recognition patch (executor and commands).
4865 - winstate->frameOptions); 24cfb8dRow pattern recognition patch (executor and commands).
4866 - mark_pos = 0; /* keep compiler quiet */ 24cfb8dRow pattern recognition patch (executor and commands).
4867 - break; 24cfb8dRow pattern recognition patch (executor and commands).
4868 - } 24cfb8dRow pattern recognition patch (executor and commands).
4869 - 24cfb8dRow pattern recognition patch (executor and commands).
4870 561632 num_reduced_frame = row_is_in_reduced_frame(winobj, 24cfb8dRow pattern recognition patch (executor and commands).
4871 - winstate->frameheadpos); 24cfb8dRow pattern recognition patch (executor and commands).
4872 561632 if (num_reduced_frame < 0) 24cfb8dRow pattern recognition patch (executor and commands).
4873 552824 goto out_of_frame; 24cfb8dRow pattern recognition patch (executor and commands).
4874 8808 else if (num_reduced_frame > 0) 24cfb8dRow pattern recognition patch (executor and commands).
4875 - { 24cfb8dRow pattern recognition patch (executor and commands).
4876 5764 if (-relpos >= num_reduced_frame) 24cfb8dRow pattern recognition patch (executor and commands).
4877 0 goto out_of_frame; 24cfb8dRow pattern recognition patch (executor and commands).
4878 5764 abs_pos = winstate->frameheadpos + relpos + 24cfb8dRow pattern recognition patch (executor and commands).
4879 - num_reduced_frame - 1; 24cfb8dRow pattern recognition patch (executor and commands).
4880 - } 24cfb8dRow pattern recognition patch (executor and commands).
4881 - break; 24cfb8dRow pattern recognition patch (executor and commands).
4882 0 default: 24cfb8dRow pattern recognition patch (executor and commands).
4883 0 elog(ERROR, "unrecognized window seek type: %d", seektype); 24cfb8dRow pattern recognition patch (executor and commands).
4884 - abs_pos = mark_pos = 0; /* keep compiler quiet */ 24cfb8dRow pattern recognition patch (executor and commands).
4885 - break; 24cfb8dRow pattern recognition patch (executor and commands).
4886 - } 24cfb8dRow pattern recognition patch (executor and commands).
4887 - 24cfb8dRow pattern recognition patch (executor and commands).
4888 17848 if (!window_gettupleslot(winobj, abs_pos, slot)) 24cfb8dRow pattern recognition patch (executor and commands).
4889 272 goto out_of_frame; 24cfb8dRow pattern recognition patch (executor and commands).
4890 - 24cfb8dRow pattern recognition patch (executor and commands).
4891 - /* The code above does not detect all out-of-frame cases, so check */ 24cfb8dRow pattern recognition patch (executor and commands).
4892 17576 if (row_is_in_frame(winobj, abs_pos, slot, false) <= 0) 24cfb8dRow pattern recognition patch (executor and commands).
4893 200 goto out_of_frame; 24cfb8dRow pattern recognition patch (executor and commands).
4894 - 24cfb8dRow pattern recognition patch (executor and commands).
4895 17356 if (isout) 24cfb8dRow pattern recognition patch (executor and commands).
4896 0 *isout = false; 24cfb8dRow pattern recognition patch (executor and commands).
4897 17356 if (set_mark) 24cfb8dRow pattern recognition patch (executor and commands).
4898 - { 24cfb8dRow pattern recognition patch (executor and commands).
4899 - /* 24cfb8dRow pattern recognition patch (executor and commands).
4900 - * If RPR is enabled and seek type is WINDOW_SEEK_TAIL, we set the 24cfb8dRow pattern recognition patch (executor and commands).
4901 - * mark position unconditionally to frameheadpos. In this case the 24cfb8dRow pattern recognition patch (executor and commands).
4902 - * frame always starts at CURRENT_ROW and never goes back, thus 24cfb8dRow pattern recognition patch (executor and commands).
4903 - * setting the mark at the position is safe. 24cfb8dRow pattern recognition patch (executor and commands).
4904 - */ 24cfb8dRow pattern recognition patch (executor and commands).
4905 17312 if (winstate->rpPattern != NULL && seektype == WINDOW_SEEK_TAIL) 24cfb8dRow pattern recognition patch (executor and commands).
4906 5764 mark_pos = winstate->frameheadpos; 24cfb8dRow pattern recognition patch (executor and commands).
4907 17312 WinSetMarkPosition(winobj, mark_pos); 24cfb8dRow pattern recognition patch (executor and commands).
4908 - } 24cfb8dRow pattern recognition patch (executor and commands).
4909 - return 0; 24cfb8dRow pattern recognition patch (executor and commands).
4910 - 24cfb8dRow pattern recognition patch (executor and commands).
4911 1514112 out_of_frame: 24cfb8dRow pattern recognition patch (executor and commands).
4912 1514112 if (isout) 24cfb8dRow pattern recognition patch (executor and commands).
4913 0 *isout = true; 24cfb8dRow pattern recognition patch (executor and commands).
4914 1514112 *isnull = true; 24cfb8dRow pattern recognition patch (executor and commands).
4915 1514112 return -1; 24cfb8dRow pattern recognition patch (executor and commands).
4916 - } 24cfb8dRow pattern recognition patch (executor and commands).
WinCheckAndInitializeNullTreatment() lines 4932-4949
Modified Lines Coverage: 8/8 lines (100.0%)
LineHitsSourceCommit
4932 2107559 WinCheckAndInitializeNullTreatment(WindowObject winobj, 24cfb8dRow pattern recognition patch (executor and commands).
4933 - bool allowNullTreatment, 24cfb8dRow pattern recognition patch (executor and commands).
4934 - FunctionCallInfo fcinfo) 24cfb8dRow pattern recognition patch (executor and commands).
4935 - { 24cfb8dRow pattern recognition patch (executor and commands).
4936 2107559 Assert(WindowObjectIsValid(winobj)); 24cfb8dRow pattern recognition patch (executor and commands).
4937 2107559 if (winobj->ignore_nulls != NO_NULLTREATMENT && !allowNullTreatment) 24cfb8dRow pattern recognition patch (executor and commands).
4938 - { 24cfb8dRow pattern recognition patch (executor and commands).
4939 48 const char *funcname = get_func_name(fcinfo->flinfo->fn_oid); 24cfb8dRow pattern recognition patch (executor and commands).
4940 - 24cfb8dRow pattern recognition patch (executor and commands).
4941 - /* the executing function's name always resolves; stay safe regardless */ 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
4942 48 ereport(ERROR, 24cfb8dRow pattern recognition patch (executor and commands).
4943 - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), 24cfb8dRow pattern recognition patch (executor and commands).
4944 - errmsg("function %s does not allow RESPECT/IGNORE NULLS", 24cfb8dRow pattern recognition patch (executor and commands).
4945 - funcname ? funcname : "?"))); 5afabadAdd row pattern recognition coverage tests and tidy unreachable code
4946 - } 24cfb8dRow pattern recognition patch (executor and commands).
4947 2107511 else if (winobj->ignore_nulls == PARSER_IGNORE_NULLS) 24cfb8dRow pattern recognition patch (executor and commands).
4948 152 winobj->ignore_nulls = IGNORE_NULLS; 24cfb8dRow pattern recognition patch (executor and commands).
4949 2107511 } 24cfb8dRow pattern recognition patch (executor and commands).
WinGetPartitionLocalMemory() lines 4964-4971
Modified Lines Coverage: 6/6 lines (100.0%)
LineHitsSourceCommit
4964 221280 WinGetPartitionLocalMemory(WindowObject winobj, Size sz) 24cfb8dRow pattern recognition patch (executor and commands).
4965 - { 24cfb8dRow pattern recognition patch (executor and commands).
4966 221280 Assert(WindowObjectIsValid(winobj)); 24cfb8dRow pattern recognition patch (executor and commands).
4967 221280 if (winobj->localmem == NULL) 24cfb8dRow pattern recognition patch (executor and commands).
4968 295 winobj->localmem = 24cfb8dRow pattern recognition patch (executor and commands).
4969 295 MemoryContextAllocZero(winobj->winstate->partcontext, sz); 24cfb8dRow pattern recognition patch (executor and commands).
4970 221280 return winobj->localmem; 24cfb8dRow pattern recognition patch (executor and commands).
4971 - } 24cfb8dRow pattern recognition patch (executor and commands).
WinGetCurrentPosition() lines 4979-4983
Modified Lines Coverage: 3/3 lines (100.0%)
LineHitsSourceCommit
4979 501586 WinGetCurrentPosition(WindowObject winobj) 24cfb8dRow pattern recognition patch (executor and commands).
4980 - { 24cfb8dRow pattern recognition patch (executor and commands).
4981 501586 Assert(WindowObjectIsValid(winobj)); 24cfb8dRow pattern recognition patch (executor and commands).
4982 501586 return winobj->winstate->currentpos; 24cfb8dRow pattern recognition patch (executor and commands).
4983 - } 24cfb8dRow pattern recognition patch (executor and commands).
WinGetPartitionRowCount() lines 4994-4999
Modified Lines Coverage: 4/4 lines (100.0%)
LineHitsSourceCommit
4994 208 WinGetPartitionRowCount(WindowObject winobj) 24cfb8dRow pattern recognition patch (executor and commands).
4995 - { 24cfb8dRow pattern recognition patch (executor and commands).
4996 208 Assert(WindowObjectIsValid(winobj)); 24cfb8dRow pattern recognition patch (executor and commands).
4997 208 spool_tuples(winobj->winstate, -1); 24cfb8dRow pattern recognition patch (executor and commands).
4998 208 return winobj->winstate->spooled_rows; 24cfb8dRow pattern recognition patch (executor and commands).
4999 - } 95b07bcSupport window functions a la SQL:2008.
WinGetFuncArgInFrame() lines 5277-5307
Modified Lines Coverage: 3/3 lines (100.0%)
LineHitsSourceCommit
5277 - WinGetFuncArgInFrame(WindowObject winobj, int argno, -
5278 - int relpos, int seektype, bool set_mark, -
5279 - bool *isnull, bool *isout) -
5280 - { -
5281 - WindowAggState *winstate; -
5282 - ExprContext *econtext; -
5283 - TupleTableSlot *slot; -
5284 - -
5285 - Assert(WindowObjectIsValid(winobj)); -
5286 - winstate = winobj->winstate; -
5287 - econtext = winstate->ss.ps.ps_ExprContext; -
5288 - slot = winstate->temp_slot_1; -
5289 - -
5290 - if (winobj->ignore_nulls == IGNORE_NULLS) -
5291 - return ignorenulls_getfuncarginframe(winobj, argno, relpos, seektype, -
5292 - set_mark, isnull, isout); -
5293 - -
5294 1531520 if (WinGetSlotInFrame(winobj, slot, 24cfb8dRow pattern recognition patch (executor and commands).
5295 - relpos, seektype, set_mark, 24cfb8dRow pattern recognition patch (executor and commands).
5296 - isnull, isout) == 0) 24cfb8dRow pattern recognition patch (executor and commands).
5297 - { -
5298 17356 econtext->ecxt_outertuple = slot; 24cfb8dRow pattern recognition patch (executor and commands).
5299 17356 return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno), 24cfb8dRow pattern recognition patch (executor and commands).
5300 - econtext, isnull); 24cfb8dRow pattern recognition patch (executor and commands).
5301 - } -
5302 - -
5303 - if (isout) -
5304 - *isout = true; -
5305 - *isnull = true; -
5306 - return (Datum) 0; -
5307 - } -