← Back to Overview

src/backend/executor/nodeWindowAgg.c

Coverage: 860/873 lines (98.5%)
Total Lines
873
modified
Covered
860
98.5%
Uncovered
13
1.5%
키보드 네비게이션
eval_windowaggregates() lines 808-1243
Modified Lines Coverage: 27/27 lines (100.0%)
LineHitsSourceCommit
808 - eval_windowaggregates(WindowAggState *winstate) -
809 - { -
810 - WindowStatePerAgg peraggstate; -
811 - int wfuncno, -
812 - numaggs, -
813 - numaggs_restart, -
814 - i; -
815 - int64 aggregatedupto_nonrestarted; -
816 - MemoryContext oldContext; -
817 - ExprContext *econtext; -
818 - WindowObject agg_winobj; -
819 - TupleTableSlot *agg_row_slot; -
820 - TupleTableSlot *temp_slot; -
821 - -
822 - numaggs = winstate->numaggs; -
823 - if (numaggs == 0) -
824 - return; /* nothing to do */ -
825 - -
826 - /* final output execution is in ps_ExprContext */ -
827 - econtext = winstate->ss.ps.ps_ExprContext; -
828 - agg_winobj = winstate->agg_winobj; -
829 - agg_row_slot = winstate->agg_row_slot; -
830 - temp_slot = winstate->temp_slot_1; -
831 - -
832 - /* -
833 - * If the window's frame start clause is UNBOUNDED_PRECEDING and no -
834 - * exclusion clause is specified, then the window frame consists of a -
835 - * contiguous group of rows extending forward from the start of the -
836 - * partition, and rows only enter the frame, never exit it, as the current -
837 - * row advances forward. This makes it possible to use an incremental -
838 - * strategy for evaluating aggregates: we run the transition function for -
839 - * each row added to the frame, and run the final function whenever we -
840 - * need the current aggregate value. This is considerably more efficient -
841 - * than the naive approach of re-running the entire aggregate calculation -
842 - * for each current row. It does assume that the final function doesn't -
843 - * damage the running transition value, but we have the same assumption in -
844 - * nodeAgg.c too (when it rescans an existing hash table). -
845 - * -
846 - * If the frame start does sometimes move, we can still optimize as above -
847 - * whenever successive rows share the same frame head, but if the frame -
848 - * head moves beyond the previous head we try to remove those rows using -
849 - * the aggregate's inverse transition function. This function restores -
850 - * the aggregate's current state to what it would be if the removed row -
851 - * had never been aggregated in the first place. Inverse transition -
852 - * functions may optionally return NULL, indicating that the function was -
853 - * unable to remove the tuple from aggregation. If this happens, or if -
854 - * the aggregate doesn't have an inverse transition function at all, we -
855 - * must perform the aggregation all over again for all tuples within the -
856 - * new frame boundaries. -
857 - * -
858 - * If there's any exclusion clause, then we may have to aggregate over a -
859 - * non-contiguous set of rows, so we punt and recalculate for every row. -
860 - * (For some frame end choices, it might be that the frame is always -
861 - * contiguous anyway, but that's an optimization to investigate later.) -
862 - * -
863 - * In many common cases, multiple rows share the same frame and hence the -
864 - * same aggregate value. (In particular, if there's no ORDER BY in a RANGE -
865 - * window, then all rows are peers and so they all have window frame equal -
866 - * to the whole partition.) We optimize such cases by calculating the -
867 - * aggregate value once when we reach the first row of a peer group, and -
868 - * then returning the saved value for all subsequent rows. -
869 - * -
870 - * 'aggregatedupto' keeps track of the first row that has not yet been -
871 - * accumulated into the aggregate transition values. Whenever we start a -
872 - * new peer group, we accumulate forward to the end of the peer group. -
873 - */ -
874 - -
875 - /* -
876 - * First, update the frame head position. -
877 - * -
878 - * The frame head should never move backwards, and the code below wouldn't -
879 - * cope if it did, so for safety we complain if it does. -
880 - */ -
881 - update_frameheadpos(winstate); -
882 - if (winstate->frameheadpos < winstate->aggregatedbase) -
883 - elog(ERROR, "window frame head moved backward"); -
884 - -
885 - /* -
886 - * If the frame didn't change compared to the previous row, we can re-use -
887 - * the result values that were previously saved at the bottom of this -
888 - * function. Since we don't know the current frame's end yet, this is not -
889 - * possible to check for fully. But if the frame end mode is UNBOUNDED -
890 - * FOLLOWING or CURRENT ROW, no exclusion clause is specified, and the -
891 - * current row lies within the previous row's frame, then the two frames' -
892 - * ends must coincide. Note that on the first row aggregatedbase == -
893 - * aggregatedupto, meaning this test must fail, so we don't need to check -
894 - * the "there was no previous row" case explicitly here. -
895 - */ -
896 - if (winstate->aggregatedbase == winstate->frameheadpos && -
897 - (winstate->frameOptions & (FRAMEOPTION_END_UNBOUNDED_FOLLOWING | -
898 - FRAMEOPTION_END_CURRENT_ROW)) && -
899 - !(winstate->frameOptions & FRAMEOPTION_EXCLUSION) && -
900 - winstate->aggregatedbase <= winstate->currentpos && -
901 - winstate->aggregatedupto > winstate->currentpos) -
902 - { -
903 - for (i = 0; i < numaggs; i++) -
904 - { -
905 - peraggstate = &winstate->peragg[i]; -
906 - wfuncno = peraggstate->wfuncno; -
907 - econtext->ecxt_aggvalues[wfuncno] = peraggstate->resultValue; -
908 - econtext->ecxt_aggnulls[wfuncno] = peraggstate->resultValueIsNull; -
909 - } -
910 - return; -
911 - } -
912 - -
913 - /*---------- -
914 - * Initialize restart flags. -
915 - * -
916 - * We restart the aggregation: -
917 - * - if we're processing the first row in the partition, or -
918 - * - if the frame's head moved and we cannot use an inverse -
919 - * transition function, or -
920 - * - we have an EXCLUSION clause, or -
921 - * - if the new frame doesn't overlap the old one -
922 - * - if RPR is enabled 56aa37bRow pattern recognition patch (executor and commands).
923 - * -
924 - * Note that we don't strictly need to restart in the last case, but if -
925 - * we're going to remove all rows from the aggregation anyway, a restart -
926 - * surely is faster. -
927 - *---------- -
928 - */ -
929 - numaggs_restart = 0; -
930 - for (i = 0; i < numaggs; i++) -
931 - { -
932 - peraggstate = &winstate->peragg[i]; -
933 - if (winstate->currentpos == 0 || -
934 - (winstate->aggregatedbase != winstate->frameheadpos && -
935 - !OidIsValid(peraggstate->invtransfn_oid)) || -
936 - (winstate->frameOptions & FRAMEOPTION_EXCLUSION) || -
937 15508 winstate->aggregatedupto <= winstate->frameheadpos || 56aa37bRow pattern recognition patch (executor and commands).
938 2191 rpr_is_defined(winstate)) 56aa37bRow pattern recognition patch (executor and commands).
939 - { -
940 - peraggstate->restart = true; -
941 - numaggs_restart++; -
942 - } -
943 - else -
944 - peraggstate->restart = false; -
945 - } -
946 - -
947 - /* -
948 - * If we have any possibly-moving aggregates, attempt to advance -
949 - * aggregatedbase to match the frame's head by removing input rows that -
950 - * fell off the top of the frame from the aggregations. This can fail, -
951 - * i.e. advance_windowaggregate_base() can return false, in which case -
952 - * we'll restart that aggregate below. -
953 - */ -
954 - while (numaggs_restart < numaggs && -
955 - winstate->aggregatedbase < winstate->frameheadpos) -
956 - { -
957 - /* -
958 - * Fetch the next tuple of those being removed. This should never fail -
959 - * as we should have been here before. -
960 - */ -
961 - if (!window_gettupleslot(agg_winobj, winstate->aggregatedbase, -
962 - temp_slot)) -
963 - elog(ERROR, "could not re-fetch previously fetched frame row"); -
964 - -
965 - /* Set tuple context for evaluation of aggregate arguments */ -
966 - winstate->tmpcontext->ecxt_outertuple = temp_slot; -
967 - -
968 - /* -
969 - * Perform the inverse transition for each aggregate function in the -
970 - * window, unless it has already been marked as needing a restart. -
971 - */ -
972 - for (i = 0; i < numaggs; i++) -
973 - { -
974 - bool ok; -
975 - -
976 - peraggstate = &winstate->peragg[i]; -
977 - if (peraggstate->restart) -
978 - continue; -
979 - -
980 - wfuncno = peraggstate->wfuncno; -
981 - ok = advance_windowaggregate_base(winstate, -
982 - &winstate->perfunc[wfuncno], -
983 - peraggstate); -
984 - if (!ok) -
985 - { -
986 - /* Inverse transition function has failed, must restart */ -
987 - peraggstate->restart = true; -
988 - numaggs_restart++; -
989 - } -
990 - } -
991 - -
992 - /* Reset per-input-tuple context after each tuple */ -
993 - ResetExprContext(winstate->tmpcontext); -
994 - -
995 - /* And advance the aggregated-row state */ -
996 - winstate->aggregatedbase++; -
997 - ExecClearTuple(temp_slot); -
998 - } -
999 - -
1000 - /* -
1001 - * If we successfully advanced the base rows of all the aggregates, -
1002 - * aggregatedbase now equals frameheadpos; but if we failed for any, we -
1003 - * must forcibly update aggregatedbase. -
1004 - */ -
1005 - winstate->aggregatedbase = winstate->frameheadpos; -
1006 - -
1007 - /* -
1008 - * If we created a mark pointer for aggregates, keep it pushed up to frame -
1009 - * head, so that tuplestore can discard unnecessary rows. -
1010 - */ -
1011 - if (agg_winobj->markptr >= 0) -
1012 - { 56aa37bRow pattern recognition patch (executor and commands).
1013 15721 int64 markpos = winstate->frameheadpos; 56aa37bRow pattern recognition patch (executor and commands).
1014 - 56aa37bRow pattern recognition patch (executor and commands).
1015 15721 if (rpr_is_defined(winstate)) 56aa37bRow pattern recognition patch (executor and commands).
1016 - { 56aa37bRow pattern recognition patch (executor and commands).
1017 - /* 56aa37bRow pattern recognition patch (executor and commands).
1018 - * If RPR is used, it is possible PREV wants to look at the 56aa37bRow pattern recognition patch (executor and commands).
1019 - * previous row. So the mark pos should be frameheadpos - 1 56aa37bRow pattern recognition patch (executor and commands).
1020 - * unless it is below 0. 56aa37bRow pattern recognition patch (executor and commands).
1021 - */ 56aa37bRow pattern recognition patch (executor and commands).
1022 15721 markpos -= 1; 56aa37bRow pattern recognition patch (executor and commands).
1023 15721 if (markpos < 0) 56aa37bRow pattern recognition patch (executor and commands).
1024 277 markpos = 0; 56aa37bRow pattern recognition patch (executor and commands).
1025 15721 } 56aa37bRow pattern recognition patch (executor and commands).
1026 15721 WinSetMarkPosition(agg_winobj, markpos); 56aa37bRow pattern recognition patch (executor and commands).
1027 15721 } 56aa37bRow pattern recognition patch (executor and commands).
1028 - -
1029 - /* -
1030 - * Now restart the aggregates that require it. -
1031 - * -
1032 - * We assume that aggregates using the shared context always restart if -
1033 - * *any* aggregate restarts, and we may thus clean up the shared -
1034 - * aggcontext if that is the case. Private aggcontexts are reset by -
1035 - * initialize_windowaggregate() if their owning aggregate restarts. If we -
1036 - * aren't restarting an aggregate, we need to free any previously saved -
1037 - * result for it, else we'll leak memory. -
1038 - */ -
1039 - if (numaggs_restart > 0) -
1040 - MemoryContextReset(winstate->aggcontext); -
1041 - for (i = 0; i < numaggs; i++) -
1042 - { -
1043 - peraggstate = &winstate->peragg[i]; -
1044 - -
1045 - /* Aggregates using the shared ctx must restart if *any* agg does */ -
1046 - Assert(peraggstate->aggcontext != winstate->aggcontext || -
1047 - numaggs_restart == 0 || -
1048 - peraggstate->restart); -
1049 - -
1050 - if (peraggstate->restart) -
1051 - { -
1052 - wfuncno = peraggstate->wfuncno; -
1053 - initialize_windowaggregate(winstate, -
1054 - &winstate->perfunc[wfuncno], -
1055 - peraggstate); -
1056 - } -
1057 - else if (!peraggstate->resultValueIsNull) -
1058 - { -
1059 - if (!peraggstate->resulttypeByVal) -
1060 - pfree(DatumGetPointer(peraggstate->resultValue)); -
1061 - peraggstate->resultValue = (Datum) 0; -
1062 - peraggstate->resultValueIsNull = true; -
1063 - } -
1064 - } -
1065 - -
1066 - /* -
1067 - * Non-restarted aggregates now contain the rows between aggregatedbase -
1068 - * (i.e., frameheadpos) and aggregatedupto, while restarted aggregates -
1069 - * contain no rows. If there are any restarted aggregates, we must thus -
1070 - * begin aggregating anew at frameheadpos, otherwise we may simply -
1071 - * continue at aggregatedupto. We must remember the old value of -
1072 - * aggregatedupto to know how long to skip advancing non-restarted -
1073 - * aggregates. If we modify aggregatedupto, we must also clear -
1074 - * agg_row_slot, per the loop invariant below. -
1075 - */ -
1076 - aggregatedupto_nonrestarted = winstate->aggregatedupto; -
1077 - if (numaggs_restart > 0 && -
1078 - winstate->aggregatedupto != winstate->frameheadpos) -
1079 - { -
1080 - winstate->aggregatedupto = winstate->frameheadpos; -
1081 - ExecClearTuple(agg_row_slot); -
1082 - 56aa37bRow pattern recognition patch (executor and commands).
1083 - /* 56aa37bRow pattern recognition patch (executor and commands).
1084 - * If RPR is defined, we do not use aggregatedupto_nonrestarted. To 56aa37bRow pattern recognition patch (executor and commands).
1085 - * avoid assertion failure below, we reset aggregatedupto_nonrestarted 56aa37bRow pattern recognition patch (executor and commands).
1086 - * to frameheadpos. 56aa37bRow pattern recognition patch (executor and commands).
1087 - */ 56aa37bRow pattern recognition patch (executor and commands).
1088 10164 if (rpr_is_defined(winstate)) 56aa37bRow pattern recognition patch (executor and commands).
1089 10164 aggregatedupto_nonrestarted = winstate->frameheadpos; 56aa37bRow pattern recognition patch (executor and commands).
1090 - } -
1091 - -
1092 - /* -
1093 - * Advance until we reach a row not in frame (or end of partition). -
1094 - * -
1095 - * Note the loop invariant: agg_row_slot is either empty or holds the row -
1096 - * at position aggregatedupto. We advance aggregatedupto after processing -
1097 - * a row. -
1098 - */ -
1099 - for (;;) -
1100 - { -
1101 - int ret; -
1102 - -
1103 - #ifdef RPR_DEBUG 56aa37bRow pattern recognition patch (executor and commands).
1104 - printf("===== loop in frame starts: aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT "\n", 56aa37bRow pattern recognition patch (executor and commands).
1105 - winstate->aggregatedupto, 56aa37bRow pattern recognition patch (executor and commands).
1106 - winstate->aggregatedbase); 56aa37bRow pattern recognition patch (executor and commands).
1107 - #endif 56aa37bRow pattern recognition patch (executor and commands).
1108 - 56aa37bRow pattern recognition patch (executor and commands).
1109 - /* Fetch next row if we didn't already */ -
1110 - if (TupIsNull(agg_row_slot)) -
1111 - { -
1112 - if (!window_gettupleslot(agg_winobj, winstate->aggregatedupto, -
1113 - agg_row_slot)) -
1114 - break; /* must be end of partition */ -
1115 - } -
1116 - -
1117 - /* -
1118 - * Exit loop if no more rows can be in frame. Skip aggregation if -
1119 - * current row is not in frame but there might be more in the frame. -
1120 - */ -
1121 - ret = row_is_in_frame(agg_winobj, winstate->aggregatedupto, -
1122 - agg_row_slot, false); -
1123 - if (ret < 0) -
1124 - break; -
1125 - 56aa37bRow pattern recognition patch (executor and commands).
1126 - if (ret == 0) -
1127 - goto next_tuple; -
1128 - -
1129 134016 if (rpr_is_defined(winstate)) 56aa37bRow pattern recognition patch (executor and commands).
1130 - { 56aa37bRow pattern recognition patch (executor and commands).
1131 - #ifdef RPR_DEBUG 56aa37bRow pattern recognition patch (executor and commands).
1132 - printf("reduced_frame_map: %d aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT "\n", 56aa37bRow pattern recognition patch (executor and commands).
1133 - get_reduced_frame_map(winstate, 56aa37bRow pattern recognition patch (executor and commands).
1134 - winstate->aggregatedupto), 56aa37bRow pattern recognition patch (executor and commands).
1135 - winstate->aggregatedupto, 56aa37bRow pattern recognition patch (executor and commands).
1136 - winstate->aggregatedbase); 56aa37bRow pattern recognition patch (executor and commands).
1137 - #endif 56aa37bRow pattern recognition patch (executor and commands).
1138 - 56aa37bRow pattern recognition patch (executor and commands).
1139 - /* 56aa37bRow pattern recognition patch (executor and commands).
1140 - * If the row status at currentpos is already decided and current 56aa37bRow pattern recognition patch (executor and commands).
1141 - * row status is not decided yet, it means we passed the last 56aa37bRow pattern recognition patch (executor and commands).
1142 - * reduced frame. Time to break the loop. 56aa37bRow pattern recognition patch (executor and commands).
1143 - */ 56aa37bRow pattern recognition patch (executor and commands).
1144 134016 if (get_reduced_frame_map(winstate, winstate->currentpos) 56aa37bRow pattern recognition patch (executor and commands).
1145 134016 != RF_NOT_DETERMINED && 56aa37bRow pattern recognition patch (executor and commands).
1146 124249 get_reduced_frame_map(winstate, winstate->aggregatedupto) 56aa37bRow pattern recognition patch (executor and commands).
1147 124249 == RF_NOT_DETERMINED) 56aa37bRow pattern recognition patch (executor and commands).
1148 7260 break; 56aa37bRow pattern recognition patch (executor and commands).
1149 - 56aa37bRow pattern recognition patch (executor and commands).
1150 - /* 56aa37bRow pattern recognition patch (executor and commands).
1151 - * Otherwise we need to calculate the reduced frame. 56aa37bRow pattern recognition patch (executor and commands).
1152 - */ 56aa37bRow pattern recognition patch (executor and commands).
1153 253512 ret = row_is_in_reduced_frame(winstate->agg_winobj, 56aa37bRow pattern recognition patch (executor and commands).
1154 126756 winstate->aggregatedupto); 56aa37bRow pattern recognition patch (executor and commands).
1155 126756 if (ret == -1) /* unmatched row */ 56aa37bRow pattern recognition patch (executor and commands).
1156 2348 break; 56aa37bRow pattern recognition patch (executor and commands).
1157 - 56aa37bRow pattern recognition patch (executor and commands).
1158 - /* 56aa37bRow pattern recognition patch (executor and commands).
1159 - * Check if current row needs to be skipped due to no match. 56aa37bRow pattern recognition patch (executor and commands).
1160 - */ 56aa37bRow pattern recognition patch (executor and commands).
1161 248816 if (get_reduced_frame_map(winstate, 56aa37bRow pattern recognition patch (executor and commands).
1162 248816 winstate->aggregatedupto) == RF_SKIPPED && 56aa37bRow pattern recognition patch (executor and commands).
1163 116934 winstate->aggregatedupto == winstate->aggregatedbase) 56aa37bRow pattern recognition patch (executor and commands).
1164 - { 56aa37bRow pattern recognition patch (executor and commands).
1165 - #ifdef RPR_DEBUG 56aa37bRow pattern recognition patch (executor and commands).
1166 - printf("skip current row for aggregation\n"); 56aa37bRow pattern recognition patch (executor and commands).
1167 - #endif 56aa37bRow pattern recognition patch (executor and commands).
1168 5899 break; 56aa37bRow pattern recognition patch (executor and commands).
1169 - } 56aa37bRow pattern recognition patch (executor and commands).
1170 118509 } 56aa37bRow pattern recognition patch (executor and commands).
1171 - 56aa37bRow pattern recognition patch (executor and commands).
1172 - /* Set tuple context for evaluation of aggregate arguments */ -
1173 - winstate->tmpcontext->ecxt_outertuple = agg_row_slot; -
1174 - -
1175 - /* Accumulate row into the aggregates */ -
1176 - for (i = 0; i < numaggs; i++) -
1177 - { -
1178 - peraggstate = &winstate->peragg[i]; -
1179 - -
1180 - /* Non-restarted aggs skip until aggregatedupto_nonrestarted */ -
1181 - if (!peraggstate->restart && -
1182 - winstate->aggregatedupto < aggregatedupto_nonrestarted) -
1183 - continue; -
1184 - -
1185 - wfuncno = peraggstate->wfuncno; -
1186 - advance_windowaggregate(winstate, -
1187 - &winstate->perfunc[wfuncno], -
1188 - peraggstate); -
1189 - } -
1190 - -
1191 - next_tuple: -
1192 - /* Reset per-input-tuple context after each tuple */ -
1193 - ResetExprContext(winstate->tmpcontext); -
1194 - -
1195 - /* And advance the aggregated-row state */ -
1196 - winstate->aggregatedupto++; -
1197 - ExecClearTuple(agg_row_slot); -
1198 - } -
1199 - -
1200 - 56aa37bRow pattern recognition patch (executor and commands).
1201 - /* The frame's end is not supposed to move backwards, ever */ -
1202 - Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto); -
1203 - -
1204 - /* -
1205 - * finalize aggregates and fill result/isnull fields. -
1206 - */ -
1207 - for (i = 0; i < numaggs; i++) -
1208 - { -
1209 - Datum *result; -
1210 - bool *isnull; -
1211 - -
1212 - peraggstate = &winstate->peragg[i]; -
1213 - wfuncno = peraggstate->wfuncno; -
1214 - result = &econtext->ecxt_aggvalues[wfuncno]; -
1215 - isnull = &econtext->ecxt_aggnulls[wfuncno]; -
1216 - finalize_windowaggregate(winstate, -
1217 - &winstate->perfunc[wfuncno], -
1218 - peraggstate, -
1219 - result, isnull); -
1220 - -
1221 - /* -
1222 - * save the result in case next row shares the same frame. -
1223 - * -
1224 - * XXX in some framing modes, eg ROWS/END_CURRENT_ROW, we can know in -
1225 - * advance that the next row can't possibly share the same frame. Is -
1226 - * it worth detecting that and skipping this code? -
1227 - */ -
1228 - if (!peraggstate->resulttypeByVal && !*isnull) -
1229 - { -
1230 - oldContext = MemoryContextSwitchTo(peraggstate->aggcontext); -
1231 - peraggstate->resultValue = -
1232 - datumCopy(*result, -
1233 - peraggstate->resulttypeByVal, -
1234 - peraggstate->resulttypeLen); -
1235 - MemoryContextSwitchTo(oldContext); -
1236 - } -
1237 - else -
1238 - { -
1239 - peraggstate->resultValue = *result; -
1240 - } -
1241 - peraggstate->resultValueIsNull = *isnull; -
1242 - } -
1243 - } -
begin_partition() lines 1415-1514
Modified Lines Coverage: 1/1 lines (100.0%)
LineHitsSourceCommit
1415 - begin_partition(WindowAggState *winstate) -
1416 - { -
1417 - PlanState *outerPlan = outerPlanState(winstate); -
1418 - int numfuncs = winstate->numfuncs; -
1419 - -
1420 - winstate->partition_spooled = false; -
1421 - winstate->framehead_valid = false; -
1422 - winstate->frametail_valid = false; -
1423 - winstate->grouptail_valid = false; -
1424 424 create_reduced_frame_map(winstate); 56aa37bRow pattern recognition patch (executor and commands).
1425 - winstate->spooled_rows = 0; -
1426 - winstate->currentpos = 0; -
1427 - winstate->frameheadpos = 0; -
1428 - winstate->frametailpos = 0; -
1429 - winstate->currentgroup = 0; -
1430 - winstate->frameheadgroup = 0; -
1431 - winstate->frametailgroup = 0; -
1432 - winstate->groupheadpos = 0; -
1433 - winstate->grouptailpos = -1; /* see update_grouptailpos */ -
1434 - ExecClearTuple(winstate->agg_row_slot); -
1435 - if (winstate->framehead_slot) -
1436 - ExecClearTuple(winstate->framehead_slot); -
1437 - if (winstate->frametail_slot) -
1438 - ExecClearTuple(winstate->frametail_slot); -
1439 - -
1440 - /* -
1441 - * If this is the very first partition, we need to fetch the first input -
1442 - * row to store in first_part_slot. -
1443 - */ -
1444 - if (TupIsNull(winstate->first_part_slot)) -
1445 - { -
1446 - TupleTableSlot *outerslot = ExecProcNode(outerPlan); -
1447 - -
1448 - if (!TupIsNull(outerslot)) -
1449 - ExecCopySlot(winstate->first_part_slot, outerslot); -
1450 - else -
1451 - { -
1452 - /* outer plan is empty, so we have nothing to do */ -
1453 - winstate->partition_spooled = true; -
1454 - winstate->more_partitions = false; -
1455 - return; -
1456 - } -
1457 - } -
1458 - -
1459 - /* Create new tuplestore if not done already. */ -
1460 - if (unlikely(winstate->buffer == NULL)) -
1461 - prepare_tuplestore(winstate); -
1462 - -
1463 - winstate->next_partition = false; -
1464 - -
1465 - if (winstate->numaggs > 0) -
1466 - { -
1467 - WindowObject agg_winobj = winstate->agg_winobj; -
1468 - -
1469 - /* reset mark and see positions for aggregate functions */ -
1470 - agg_winobj->markpos = -1; -
1471 - agg_winobj->seekpos = -1; -
1472 - -
1473 - /* Also reset the row counters for aggregates */ -
1474 - winstate->aggregatedbase = 0; -
1475 - winstate->aggregatedupto = 0; -
1476 - } -
1477 - -
1478 - /* reset mark and seek positions for each real window function */ -
1479 - for (int i = 0; i < numfuncs; i++) -
1480 - { -
1481 - WindowStatePerFunc perfuncstate = &(winstate->perfunc[i]); -
1482 - -
1483 - if (!perfuncstate->plain_agg) -
1484 - { -
1485 - WindowObject winobj = perfuncstate->winobj; -
1486 - -
1487 - winobj->markpos = -1; -
1488 - winobj->seekpos = -1; -
1489 - -
1490 - /* reset null map */ -
1491 - if (winobj->ignore_nulls == IGNORE_NULLS || -
1492 - winobj->ignore_nulls == PARSER_IGNORE_NULLS) -
1493 - { -
1494 - int numargs = perfuncstate->numArguments; -
1495 - -
1496 - for (int j = 0; j < numargs; j++) -
1497 - { -
1498 - int n = winobj->num_notnull_info[j]; -
1499 - -
1500 - if (n > 0) -
1501 - memset(winobj->notnull_info[j], 0, -
1502 - NN_POS_TO_BYTES(n)); -
1503 - } -
1504 - } -
1505 - } -
1506 - } -
1507 - -
1508 - /* -
1509 - * Store the first tuple into the tuplestore (it's always available now; -
1510 - * we either read it above, or saved it at the end of previous partition) -
1511 - */ -
1512 - tuplestore_puttupleslot(winstate->buffer, winstate->first_part_slot); -
1513 - winstate->spooled_rows++; -
1514 - } -
release_partition() lines 1615-1655
Modified Lines Coverage: 7/7 lines (100.0%)
LineHitsSourceCommit
1615 - release_partition(WindowAggState *winstate) -
1616 - { -
1617 - int i; -
1618 - -
1619 - for (i = 0; i < winstate->numfuncs; i++) -
1620 - { -
1621 - WindowStatePerFunc perfuncstate = &(winstate->perfunc[i]); -
1622 - -
1623 - /* Release any partition-local state of this window function */ -
1624 - if (perfuncstate->winobj) -
1625 - perfuncstate->winobj->localmem = NULL; -
1626 - } -
1627 - -
1628 - /* -
1629 - * Release all partition-local memory (in particular, any partition-local -
1630 - * state that we might have trashed our pointers to in the above loop, and -
1631 - * any aggregate temp data). We don't rely on retail pfree because some -
1632 - * aggregates might have allocated data we don't have direct pointers to. -
1633 - */ -
1634 - MemoryContextReset(winstate->partcontext); -
1635 - MemoryContextReset(winstate->aggcontext); -
1636 - for (i = 0; i < winstate->numaggs; i++) -
1637 - { -
1638 - if (winstate->peragg[i].aggcontext != winstate->aggcontext) -
1639 - MemoryContextReset(winstate->peragg[i].aggcontext); -
1640 - } -
1641 - -
1642 - if (winstate->buffer) -
1643 - tuplestore_clear(winstate->buffer); -
1644 - winstate->partition_spooled = false; -
1645 - winstate->next_partition = true; -
1646 - 56aa37bRow pattern recognition patch (executor and commands).
1647 - /* Reset NFA state for new partition */ 56aa37bRow pattern recognition patch (executor and commands).
1648 880 winstate->nfaContext = NULL; 56aa37bRow pattern recognition patch (executor and commands).
1649 880 winstate->nfaContextTail = NULL; 56aa37bRow pattern recognition patch (executor and commands).
1650 880 winstate->nfaContextFree = NULL; 56aa37bRow pattern recognition patch (executor and commands).
1651 880 winstate->nfaStateFree = NULL; 56aa37bRow pattern recognition patch (executor and commands).
1652 880 winstate->nfaLastProcessedRow = -1; 56aa37bRow pattern recognition patch (executor and commands).
1653 880 winstate->nfaStatesActive = 0; 56aa37bRow pattern recognition patch (executor and commands).
1654 880 winstate->nfaContextsActive = 0; 56aa37bRow pattern recognition patch (executor and commands).
1655 - } -
ExecWindowAgg() lines 2418-2692
Modified Lines Coverage: 4/4 lines (100.0%)
LineHitsSourceCommit
2418 - ExecWindowAgg(PlanState *pstate) -
2419 - { -
2420 - WindowAggState *winstate = castNode(WindowAggState, pstate); -
2421 - TupleTableSlot *slot; -
2422 - ExprContext *econtext; -
2423 - int i; -
2424 - int numfuncs; -
2425 - -
2426 - CHECK_FOR_INTERRUPTS(); -
2427 - -
2428 - #ifdef RPR_DEBUG 56aa37bRow pattern recognition patch (executor and commands).
2429 - printf("ExecWindowAgg called. pos: " INT64_FORMAT "\n", 56aa37bRow pattern recognition patch (executor and commands).
2430 - winstate->currentpos); 56aa37bRow pattern recognition patch (executor and commands).
2431 - #endif 56aa37bRow pattern recognition patch (executor and commands).
2432 - 56aa37bRow pattern recognition patch (executor and commands).
2433 - if (winstate->status == WINDOWAGG_DONE) -
2434 - return NULL; -
2435 - -
2436 - /* -
2437 - * Compute frame offset values, if any, during first call (or after a -
2438 - * rescan). These are assumed to hold constant throughout the scan; if -
2439 - * user gives us a volatile expression, we'll only use its initial value. -
2440 - */ -
2441 - if (unlikely(winstate->all_first)) -
2442 - calculate_frame_offsets(pstate); -
2443 - -
2444 - /* We need to loop as the runCondition or qual may filter out tuples */ -
2445 - for (;;) -
2446 - { -
2447 - if (winstate->next_partition) -
2448 - { -
2449 - /* Initialize for first partition and set current row = 0 */ -
2450 - begin_partition(winstate); -
2451 - /* If there are no input rows, we'll detect that and exit below */ -
2452 - } -
2453 - else -
2454 - { -
2455 - /* Advance current row within partition */ -
2456 - winstate->currentpos++; -
2457 - /* This might mean that the frame moves, too */ -
2458 - winstate->framehead_valid = false; -
2459 - winstate->frametail_valid = false; -
2460 - /* we don't need to invalidate grouptail here; see below */ -
2461 - } -
2462 - -
2463 - /* -
2464 - * Spool all tuples up to and including the current row, if we haven't -
2465 - * already -
2466 - */ -
2467 - spool_tuples(winstate, winstate->currentpos); -
2468 - -
2469 - /* Move to the next partition if we reached the end of this partition */ -
2470 - if (winstate->partition_spooled && -
2471 - winstate->currentpos >= winstate->spooled_rows) -
2472 - { -
2473 - release_partition(winstate); -
2474 - -
2475 - if (winstate->more_partitions) -
2476 - { -
2477 - begin_partition(winstate); -
2478 - Assert(winstate->spooled_rows > 0); -
2479 - -
2480 - /* Come out of pass-through mode when changing partition */ -
2481 - winstate->status = WINDOWAGG_RUN; -
2482 - } -
2483 - else -
2484 - { -
2485 - /* No further partitions? We're done */ -
2486 - winstate->status = WINDOWAGG_DONE; -
2487 - return NULL; -
2488 - } -
2489 - } -
2490 - -
2491 - /* final output execution is in ps_ExprContext */ -
2492 - econtext = winstate->ss.ps.ps_ExprContext; -
2493 - -
2494 - /* Clear the per-output-tuple context for current row */ -
2495 - ResetExprContext(econtext); -
2496 - -
2497 - /* -
2498 - * Read the current row from the tuplestore, and save in -
2499 - * ScanTupleSlot. (We can't rely on the outerplan's output slot -
2500 - * because we may have to read beyond the current row. Also, we have -
2501 - * to actually copy the row out of the tuplestore, since window -
2502 - * function evaluation might cause the tuplestore to dump its state to -
2503 - * disk.) -
2504 - * -
2505 - * In GROUPS mode, or when tracking a group-oriented exclusion clause, -
2506 - * we must also detect entering a new peer group and update associated -
2507 - * state when that happens. We use temp_slot_2 to temporarily hold -
2508 - * the previous row for this purpose. -
2509 - * -
2510 - * Current row must be in the tuplestore, since we spooled it above. -
2511 - */ -
2512 - tuplestore_select_read_pointer(winstate->buffer, winstate->current_ptr); -
2513 - if ((winstate->frameOptions & (FRAMEOPTION_GROUPS | -
2514 - FRAMEOPTION_EXCLUDE_GROUP | -
2515 - FRAMEOPTION_EXCLUDE_TIES)) && -
2516 - winstate->currentpos > 0) -
2517 - { -
2518 - ExecCopySlot(winstate->temp_slot_2, winstate->ss.ss_ScanTupleSlot); -
2519 - if (!tuplestore_gettupleslot(winstate->buffer, true, true, -
2520 - winstate->ss.ss_ScanTupleSlot)) -
2521 - elog(ERROR, "unexpected end of tuplestore"); -
2522 - if (!are_peers(winstate, winstate->temp_slot_2, -
2523 - winstate->ss.ss_ScanTupleSlot)) -
2524 - { -
2525 - winstate->currentgroup++; -
2526 - winstate->groupheadpos = winstate->currentpos; -
2527 - winstate->grouptail_valid = false; -
2528 - } -
2529 - ExecClearTuple(winstate->temp_slot_2); -
2530 - } -
2531 - else -
2532 - { -
2533 - if (!tuplestore_gettupleslot(winstate->buffer, true, true, -
2534 - winstate->ss.ss_ScanTupleSlot)) -
2535 - elog(ERROR, "unexpected end of tuplestore"); -
2536 - } -
2537 - -
2538 - /* don't evaluate the window functions when we're in pass-through mode */ -
2539 - if (winstate->status == WINDOWAGG_RUN) -
2540 - { -
2541 - /* 56aa37bRow pattern recognition patch (executor and commands).
2542 - * If RPR is defined and skip mode is next row, we need to clear 56aa37bRow pattern recognition patch (executor and commands).
2543 - * existing reduced frame info so that we newly calculate the info 56aa37bRow pattern recognition patch (executor and commands).
2544 - * starting from current row. 56aa37bRow pattern recognition patch (executor and commands).
2545 - */ 56aa37bRow pattern recognition patch (executor and commands).
2546 17959 if (rpr_is_defined(winstate)) 56aa37bRow pattern recognition patch (executor and commands).
2547 - { 56aa37bRow pattern recognition patch (executor and commands).
2548 17959 if (winstate->rpSkipTo == ST_NEXT_ROW) 56aa37bRow pattern recognition patch (executor and commands).
2549 1721 clear_reduced_frame_map(winstate); 56aa37bRow pattern recognition patch (executor and commands).
2550 17959 } 56aa37bRow pattern recognition patch (executor and commands).
2551 - 56aa37bRow pattern recognition patch (executor and commands).
2552 - /* -
2553 - * Evaluate true window functions -
2554 - */ -
2555 - numfuncs = winstate->numfuncs; -
2556 - for (i = 0; i < numfuncs; i++) -
2557 - { -
2558 - WindowStatePerFunc perfuncstate = &(winstate->perfunc[i]); -
2559 - -
2560 - if (perfuncstate->plain_agg) -
2561 - continue; -
2562 - eval_windowfunction(winstate, perfuncstate, -
2563 - &(econtext->ecxt_aggvalues[perfuncstate->wfuncstate->wfuncno]), -
2564 - &(econtext->ecxt_aggnulls[perfuncstate->wfuncstate->wfuncno])); -
2565 - } -
2566 - -
2567 - /* -
2568 - * Evaluate aggregates -
2569 - */ -
2570 - if (winstate->numaggs > 0) -
2571 - eval_windowaggregates(winstate); -
2572 - } -
2573 - -
2574 - /* -
2575 - * If we have created auxiliary read pointers for the frame or group -
2576 - * boundaries, force them to be kept up-to-date, because we don't know -
2577 - * whether the window function(s) will do anything that requires that. -
2578 - * Failing to advance the pointers would result in being unable to -
2579 - * trim data from the tuplestore, which is bad. (If we could know in -
2580 - * advance whether the window functions will use frame boundary info, -
2581 - * we could skip creating these pointers in the first place ... but -
2582 - * unfortunately the window function API doesn't require that.) -
2583 - */ -
2584 - if (winstate->framehead_ptr >= 0) -
2585 - update_frameheadpos(winstate); -
2586 - if (winstate->frametail_ptr >= 0) -
2587 - update_frametailpos(winstate); -
2588 - if (winstate->grouptail_ptr >= 0) -
2589 - update_grouptailpos(winstate); -
2590 - -
2591 - /* -
2592 - * Truncate any no-longer-needed rows from the tuplestore. -
2593 - */ -
2594 - tuplestore_trim(winstate->buffer); -
2595 - -
2596 - /* -
2597 - * Form and return a projection tuple using the windowfunc results and -
2598 - * the current row. Setting ecxt_outertuple arranges that any Vars -
2599 - * will be evaluated with respect to that row. -
2600 - */ -
2601 - econtext->ecxt_outertuple = winstate->ss.ss_ScanTupleSlot; -
2602 - -
2603 - slot = ExecProject(winstate->ss.ps.ps_ProjInfo); -
2604 - -
2605 - if (winstate->status == WINDOWAGG_RUN) -
2606 - { -
2607 - econtext->ecxt_scantuple = slot; -
2608 - -
2609 - /* -
2610 - * Now evaluate the run condition to see if we need to go into -
2611 - * pass-through mode, or maybe stop completely. -
2612 - */ -
2613 - if (!ExecQual(winstate->runcondition, econtext)) -
2614 - { -
2615 - /* -
2616 - * Determine which mode to move into. If there is no -
2617 - * PARTITION BY clause and we're the top-level WindowAgg then -
2618 - * we're done. This tuple and any future tuples cannot -
2619 - * possibly match the runcondition. However, when there is a -
2620 - * PARTITION BY clause or we're not the top-level window we -
2621 - * can't just stop as we need to either process other -
2622 - * partitions or ensure WindowAgg nodes above us receive all -
2623 - * of the tuples they need to process their WindowFuncs. -
2624 - */ -
2625 - if (winstate->use_pass_through) -
2626 - { -
2627 - /* -
2628 - * When switching into a pass-through mode, we'd better -
2629 - * NULLify the aggregate results as these are no longer -
2630 - * updated and NULLifying them avoids the old stale -
2631 - * results lingering. Some of these might be byref types -
2632 - * so we can't have them pointing to free'd memory. The -
2633 - * planner insisted that quals used in the runcondition -
2634 - * are strict, so the top-level WindowAgg will always -
2635 - * filter these NULLs out in the filter clause. -
2636 - */ -
2637 - numfuncs = winstate->numfuncs; -
2638 - for (i = 0; i < numfuncs; i++) -
2639 - { -
2640 - econtext->ecxt_aggvalues[i] = (Datum) 0; -
2641 - econtext->ecxt_aggnulls[i] = true; -
2642 - } -
2643 - -
2644 - /* -
2645 - * STRICT pass-through mode is required for the top window -
2646 - * when there is a PARTITION BY clause. Otherwise we must -
2647 - * ensure we store tuples that don't match the -
2648 - * runcondition so they're available to WindowAggs above. -
2649 - */ -
2650 - if (winstate->top_window) -
2651 - { -
2652 - winstate->status = WINDOWAGG_PASSTHROUGH_STRICT; -
2653 - continue; -
2654 - } -
2655 - else -
2656 - { -
2657 - winstate->status = WINDOWAGG_PASSTHROUGH; -
2658 - } -
2659 - } -
2660 - else -
2661 - { -
2662 - /* -
2663 - * Pass-through not required. We can just return NULL. -
2664 - * Nothing else will match the runcondition. -
2665 - */ -
2666 - winstate->status = WINDOWAGG_DONE; -
2667 - return NULL; -
2668 - } -
2669 - } -
2670 - -
2671 - /* -
2672 - * Filter out any tuples we don't need in the top-level WindowAgg. -
2673 - */ -
2674 - if (!ExecQual(winstate->ss.ps.qual, econtext)) -
2675 - { -
2676 - InstrCountFiltered1(winstate, 1); -
2677 - continue; -
2678 - } -
2679 - -
2680 - break; -
2681 - } -
2682 - -
2683 - /* -
2684 - * When not in WINDOWAGG_RUN mode, we must still return this tuple if -
2685 - * we're anything apart from the top window. -
2686 - */ -
2687 - else if (!winstate->top_window) -
2688 - break; -
2689 - } -
2690 - -
2691 - return slot; -
2692 - } -
ExecInitWindowAgg() lines 2702-3082
Modified Lines Coverage: 41/41 lines (100.0%)
LineHitsSourceCommit
2702 - ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) -
2703 - { -
2704 - WindowAggState *winstate; -
2705 - Plan *outerPlan; -
2706 - ExprContext *econtext; -
2707 - ExprContext *tmpcontext; -
2708 - WindowStatePerFunc perfunc; -
2709 - WindowStatePerAgg peragg; -
2710 - int frameOptions = node->frameOptions; -
2711 - int numfuncs, -
2712 - wfuncno, -
2713 - numaggs, -
2714 - aggno; -
2715 - TupleDesc scanDesc; -
2716 - ListCell *l; -
2717 - -
2718 464 TargetEntry *te; 56aa37bRow pattern recognition patch (executor and commands).
2719 464 Expr *expr; 56aa37bRow pattern recognition patch (executor and commands).
2720 - 56aa37bRow pattern recognition patch (executor and commands).
2721 - /* check for unsupported flags */ -
2722 - Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); -
2723 - -
2724 - /* -
2725 - * create state structure -
2726 - */ -
2727 - winstate = makeNode(WindowAggState); -
2728 - winstate->ss.ps.plan = (Plan *) node; -
2729 - winstate->ss.ps.state = estate; -
2730 - winstate->ss.ps.ExecProcNode = ExecWindowAgg; -
2731 - -
2732 - /* copy frame options to state node for easy access */ -
2733 - winstate->frameOptions = frameOptions; -
2734 - -
2735 - /* -
2736 - * Create expression contexts. We need two, one for per-input-tuple -
2737 - * processing and one for per-output-tuple processing. We cheat a little -
2738 - * by using ExecAssignExprContext() to build both. -
2739 - */ -
2740 - ExecAssignExprContext(estate, &winstate->ss.ps); -
2741 - tmpcontext = winstate->ss.ps.ps_ExprContext; -
2742 - winstate->tmpcontext = tmpcontext; -
2743 - ExecAssignExprContext(estate, &winstate->ss.ps); -
2744 - -
2745 - /* Create long-lived context for storage of partition-local memory etc */ -
2746 - winstate->partcontext = -
2747 - AllocSetContextCreate(CurrentMemoryContext, -
2748 - "WindowAgg Partition", -
2749 - ALLOCSET_DEFAULT_SIZES); -
2750 - -
2751 - /* -
2752 - * Create mid-lived context for aggregate trans values etc. -
2753 - * -
2754 - * Note that moving aggregates each use their own private context, not -
2755 - * this one. -
2756 - */ -
2757 - winstate->aggcontext = -
2758 - AllocSetContextCreate(CurrentMemoryContext, -
2759 - "WindowAgg Aggregates", -
2760 - ALLOCSET_DEFAULT_SIZES); -
2761 - -
2762 - /* Only the top-level WindowAgg may have a qual */ -
2763 - Assert(node->plan.qual == NIL || node->topWindow); -
2764 - -
2765 - /* Initialize the qual */ -
2766 - winstate->ss.ps.qual = ExecInitQual(node->plan.qual, -
2767 - (PlanState *) winstate); -
2768 - -
2769 - /* -
2770 - * Setup the run condition, if we received one from the query planner. -
2771 - * When set, this may allow us to move into pass-through mode so that we -
2772 - * don't have to perform any further evaluation of WindowFuncs in the -
2773 - * current partition or possibly stop returning tuples altogether when all -
2774 - * tuples are in the same partition. -
2775 - */ -
2776 - winstate->runcondition = ExecInitQual(node->runCondition, -
2777 - (PlanState *) winstate); -
2778 - -
2779 - /* -
2780 - * When we're not the top-level WindowAgg node or we are but have a -
2781 - * PARTITION BY clause we must move into one of the WINDOWAGG_PASSTHROUGH* -
2782 - * modes when the runCondition becomes false. -
2783 - */ -
2784 - winstate->use_pass_through = !node->topWindow || node->partNumCols > 0; -
2785 - -
2786 - /* remember if we're the top-window or we are below the top-window */ -
2787 - winstate->top_window = node->topWindow; -
2788 - -
2789 - /* -
2790 - * initialize child nodes -
2791 - */ -
2792 - outerPlan = outerPlan(node); -
2793 - outerPlanState(winstate) = ExecInitNode(outerPlan, estate, eflags); -
2794 - -
2795 - /* -
2796 - * initialize source tuple type (which is also the tuple type that we'll -
2797 - * store in the tuplestore and use in all our working slots). -
2798 - */ -
2799 - ExecCreateScanSlotFromOuterPlan(estate, &winstate->ss, &TTSOpsMinimalTuple); -
2800 - scanDesc = winstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor; -
2801 - -
2802 - /* the outer tuple isn't the child's tuple, but always a minimal tuple */ -
2803 - winstate->ss.ps.outeropsset = true; -
2804 - winstate->ss.ps.outerops = &TTSOpsMinimalTuple; -
2805 - winstate->ss.ps.outeropsfixed = true; -
2806 - -
2807 - /* -
2808 - * tuple table initialization -
2809 - */ -
2810 - winstate->first_part_slot = ExecInitExtraTupleSlot(estate, scanDesc, -
2811 - &TTSOpsMinimalTuple); -
2812 - winstate->agg_row_slot = ExecInitExtraTupleSlot(estate, scanDesc, -
2813 - &TTSOpsMinimalTuple); -
2814 - winstate->temp_slot_1 = ExecInitExtraTupleSlot(estate, scanDesc, -
2815 - &TTSOpsMinimalTuple); -
2816 - winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc, -
2817 - &TTSOpsMinimalTuple); -
2818 - -
2819 464 winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc, 56aa37bRow pattern recognition patch (executor and commands).
2820 - &TTSOpsMinimalTuple); 56aa37bRow pattern recognition patch (executor and commands).
2821 - 56aa37bRow pattern recognition patch (executor and commands).
2822 464 winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc, 56aa37bRow pattern recognition patch (executor and commands).
2823 - &TTSOpsMinimalTuple); 56aa37bRow pattern recognition patch (executor and commands).
2824 - 56aa37bRow pattern recognition patch (executor and commands).
2825 464 winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc, 56aa37bRow pattern recognition patch (executor and commands).
2826 - &TTSOpsMinimalTuple); 56aa37bRow pattern recognition patch (executor and commands).
2827 464 winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot); 56aa37bRow pattern recognition patch (executor and commands).
2828 - 56aa37bRow pattern recognition patch (executor and commands).
2829 - /* -
2830 - * create frame head and tail slots only if needed (must create slots in -
2831 - * exactly the same cases that update_frameheadpos and update_frametailpos -
2832 - * need them) -
2833 - */ -
2834 - winstate->framehead_slot = winstate->frametail_slot = NULL; -
2835 - -
2836 - if (frameOptions & (FRAMEOPTION_RANGE | FRAMEOPTION_GROUPS)) -
2837 - { -
2838 - if (((frameOptions & FRAMEOPTION_START_CURRENT_ROW) && -
2839 - node->ordNumCols != 0) || -
2840 - (frameOptions & FRAMEOPTION_START_OFFSET)) -
2841 - winstate->framehead_slot = ExecInitExtraTupleSlot(estate, scanDesc, -
2842 - &TTSOpsMinimalTuple); -
2843 - if (((frameOptions & FRAMEOPTION_END_CURRENT_ROW) && -
2844 - node->ordNumCols != 0) || -
2845 - (frameOptions & FRAMEOPTION_END_OFFSET)) -
2846 - winstate->frametail_slot = ExecInitExtraTupleSlot(estate, scanDesc, -
2847 - &TTSOpsMinimalTuple); -
2848 - } -
2849 - -
2850 - /* -
2851 - * Initialize result slot, type and projection. -
2852 - */ -
2853 - ExecInitResultTupleSlotTL(&winstate->ss.ps, &TTSOpsVirtual); -
2854 - ExecAssignProjectionInfo(&winstate->ss.ps, NULL); -
2855 - -
2856 - /* Set up data for comparing tuples */ -
2857 - if (node->partNumCols > 0) -
2858 - winstate->partEqfunction = -
2859 - execTuplesMatchPrepare(scanDesc, -
2860 - node->partNumCols, -
2861 - node->partColIdx, -
2862 - node->partOperators, -
2863 - node->partCollations, -
2864 - &winstate->ss.ps); -
2865 - -
2866 - if (node->ordNumCols > 0) -
2867 - winstate->ordEqfunction = -
2868 - execTuplesMatchPrepare(scanDesc, -
2869 - node->ordNumCols, -
2870 - node->ordColIdx, -
2871 - node->ordOperators, -
2872 - node->ordCollations, -
2873 - &winstate->ss.ps); -
2874 - -
2875 - /* -
2876 - * WindowAgg nodes use aggvalues and aggnulls as well as Agg nodes. -
2877 - */ -
2878 - numfuncs = winstate->numfuncs; -
2879 - numaggs = winstate->numaggs; -
2880 - econtext = winstate->ss.ps.ps_ExprContext; -
2881 - econtext->ecxt_aggvalues = palloc0_array(Datum, numfuncs); -
2882 - econtext->ecxt_aggnulls = palloc0_array(bool, numfuncs); -
2883 - -
2884 - /* -
2885 - * allocate per-wfunc/per-agg state information. -
2886 - */ -
2887 - perfunc = palloc0_array(WindowStatePerFuncData, numfuncs); -
2888 - peragg = palloc0_array(WindowStatePerAggData, numaggs); -
2889 - winstate->perfunc = perfunc; -
2890 - winstate->peragg = peragg; -
2891 - -
2892 - wfuncno = -1; -
2893 - aggno = -1; -
2894 - foreach(l, winstate->funcs) -
2895 - { -
2896 - WindowFuncExprState *wfuncstate = (WindowFuncExprState *) lfirst(l); -
2897 - WindowFunc *wfunc = wfuncstate->wfunc; -
2898 - WindowStatePerFunc perfuncstate; -
2899 - AclResult aclresult; -
2900 - int i; -
2901 - -
2902 - if (wfunc->winref != node->winref) /* planner screwed up? */ -
2903 - elog(ERROR, "WindowFunc with winref %u assigned to WindowAgg with winref %u", -
2904 - wfunc->winref, node->winref); -
2905 - -
2906 - /* -
2907 - * Look for a previous duplicate window function, which needs the same -
2908 - * ignore_nulls value -
2909 - */ -
2910 - for (i = 0; i <= wfuncno; i++) -
2911 - { -
2912 - if (equal(wfunc, perfunc[i].wfunc) && -
2913 - !contain_volatile_functions((Node *) wfunc)) -
2914 - break; -
2915 - } -
2916 - if (i <= wfuncno && wfunc->ignore_nulls == perfunc[i].ignore_nulls) -
2917 - { -
2918 - /* Found a match to an existing entry, so just mark it */ -
2919 - wfuncstate->wfuncno = i; -
2920 - continue; -
2921 - } -
2922 - -
2923 - /* Nope, so assign a new PerAgg record */ -
2924 - perfuncstate = &perfunc[++wfuncno]; -
2925 - -
2926 - /* Mark WindowFunc state node with assigned index in the result array */ -
2927 - wfuncstate->wfuncno = wfuncno; -
2928 - -
2929 - /* Check permission to call window function */ -
2930 - aclresult = object_aclcheck(ProcedureRelationId, wfunc->winfnoid, GetUserId(), -
2931 - ACL_EXECUTE); -
2932 - if (aclresult != ACLCHECK_OK) -
2933 - aclcheck_error(aclresult, OBJECT_FUNCTION, -
2934 - get_func_name(wfunc->winfnoid)); -
2935 - InvokeFunctionExecuteHook(wfunc->winfnoid); -
2936 - -
2937 - /* Fill in the perfuncstate data */ -
2938 - perfuncstate->wfuncstate = wfuncstate; -
2939 - perfuncstate->wfunc = wfunc; -
2940 - perfuncstate->numArguments = list_length(wfuncstate->args); -
2941 - perfuncstate->winCollation = wfunc->inputcollid; -
2942 - -
2943 - get_typlenbyval(wfunc->wintype, -
2944 - &perfuncstate->resulttypeLen, -
2945 - &perfuncstate->resulttypeByVal); -
2946 - -
2947 - /* -
2948 - * If it's really just a plain aggregate function, we'll emulate the -
2949 - * Agg environment for it. -
2950 - */ -
2951 - perfuncstate->plain_agg = wfunc->winagg; -
2952 - if (wfunc->winagg) -
2953 - { -
2954 - WindowStatePerAgg peraggstate; -
2955 - -
2956 - perfuncstate->aggno = ++aggno; -
2957 - peraggstate = &winstate->peragg[aggno]; -
2958 - initialize_peragg(winstate, wfunc, peraggstate); -
2959 - peraggstate->wfuncno = wfuncno; -
2960 - } -
2961 - else -
2962 - { -
2963 - WindowObject winobj = makeNode(WindowObjectData); -
2964 - -
2965 - winobj->winstate = winstate; -
2966 - winobj->argstates = wfuncstate->args; -
2967 - winobj->localmem = NULL; -
2968 - perfuncstate->winobj = winobj; -
2969 - winobj->ignore_nulls = wfunc->ignore_nulls; -
2970 - init_notnull_info(winobj, perfuncstate); -
2971 - -
2972 - /* It's a real window function, so set up to call it. */ -
2973 - fmgr_info_cxt(wfunc->winfnoid, &perfuncstate->flinfo, -
2974 - econtext->ecxt_per_query_memory); -
2975 - fmgr_info_set_expr((Node *) wfunc, &perfuncstate->flinfo); -
2976 - } -
2977 - } -
2978 - -
2979 - /* Update numfuncs, numaggs to match number of unique functions found */ -
2980 - winstate->numfuncs = wfuncno + 1; -
2981 - winstate->numaggs = aggno + 1; -
2982 - -
2983 - /* Set up WindowObject for aggregates, if needed */ -
2984 - if (winstate->numaggs > 0) -
2985 - { -
2986 - WindowObject agg_winobj = makeNode(WindowObjectData); -
2987 - -
2988 - agg_winobj->winstate = winstate; -
2989 - agg_winobj->argstates = NIL; -
2990 - agg_winobj->localmem = NULL; -
2991 - /* make sure markptr = -1 to invalidate. It may not get used */ -
2992 - agg_winobj->markptr = -1; -
2993 - agg_winobj->readptr = -1; -
2994 - winstate->agg_winobj = agg_winobj; -
2995 - } -
2996 - -
2997 - /* Set the status to running */ -
2998 - winstate->status = WINDOWAGG_RUN; -
2999 - -
3000 - /* initialize frame bound offset expressions */ -
3001 - winstate->startOffset = ExecInitExpr((Expr *) node->startOffset, -
3002 - (PlanState *) winstate); -
3003 - winstate->endOffset = ExecInitExpr((Expr *) node->endOffset, -
3004 - (PlanState *) winstate); -
3005 - -
3006 - /* Lookup in_range support functions if needed */ -
3007 - if (OidIsValid(node->startInRangeFunc)) -
3008 - fmgr_info(node->startInRangeFunc, &winstate->startInRangeFunc); -
3009 - if (OidIsValid(node->endInRangeFunc)) -
3010 - fmgr_info(node->endInRangeFunc, &winstate->endInRangeFunc); -
3011 - winstate->inRangeColl = node->inRangeColl; -
3012 - winstate->inRangeAsc = node->inRangeAsc; -
3013 - winstate->inRangeNullsFirst = node->inRangeNullsFirst; -
3014 - -
3015 - /* Set up SKIP TO type */ 56aa37bRow pattern recognition patch (executor and commands).
3016 464 winstate->rpSkipTo = node->rpSkipTo; 56aa37bRow pattern recognition patch (executor and commands).
3017 - /* Set up row pattern recognition PATTERN clause (compiled NFA) */ 56aa37bRow pattern recognition patch (executor and commands).
3018 464 winstate->rpPattern = node->rpPattern; 56aa37bRow pattern recognition patch (executor and commands).
3019 - 56aa37bRow pattern recognition patch (executor and commands).
3020 - /* Calculate NFA state size for allocation */ 56aa37bRow pattern recognition patch (executor and commands).
3021 464 if (node->rpPattern != NULL) 56aa37bRow pattern recognition patch (executor and commands).
3022 - { 56aa37bRow pattern recognition patch (executor and commands).
3023 463 winstate->nfaStateSize = offsetof(RPRNFAState, counts) + 56aa37bRow pattern recognition patch (executor and commands).
3024 463 sizeof(int32) * node->rpPattern->maxDepth; 56aa37bRow pattern recognition patch (executor and commands).
3025 463 } 56aa37bRow pattern recognition patch (executor and commands).
3026 - 56aa37bRow pattern recognition patch (executor and commands).
3027 - /* Set up row pattern recognition DEFINE clause */ 56aa37bRow pattern recognition patch (executor and commands).
3028 464 winstate->defineVariableList = NIL; 56aa37bRow pattern recognition patch (executor and commands).
3029 464 winstate->defineClauseList = NIL; 56aa37bRow pattern recognition patch (executor and commands).
3030 464 if (node->defineClause != NIL) 56aa37bRow pattern recognition patch (executor and commands).
3031 - { 56aa37bRow pattern recognition patch (executor and commands).
3032 - /* 56aa37bRow pattern recognition patch (executor and commands).
3033 - * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot. 56aa37bRow pattern recognition patch (executor and commands).
3034 - */ 56aa37bRow pattern recognition patch (executor and commands).
3035 1707 foreach(l, node->defineClause) 56aa37bRow pattern recognition patch (executor and commands).
3036 - { 56aa37bRow pattern recognition patch (executor and commands).
3037 1246 char *name; 56aa37bRow pattern recognition patch (executor and commands).
3038 1246 ExprState *exps; 56aa37bRow pattern recognition patch (executor and commands).
3039 - 56aa37bRow pattern recognition patch (executor and commands).
3040 1246 te = lfirst(l); 56aa37bRow pattern recognition patch (executor and commands).
3041 1246 name = te->resname; 56aa37bRow pattern recognition patch (executor and commands).
3042 1246 expr = te->expr; 56aa37bRow pattern recognition patch (executor and commands).
3043 - 56aa37bRow pattern recognition patch (executor and commands).
3044 - #ifdef RPR_DEBUG 56aa37bRow pattern recognition patch (executor and commands).
3045 - printf("defineVariable name: %s\n", name); 56aa37bRow pattern recognition patch (executor and commands).
3046 - #endif 56aa37bRow pattern recognition patch (executor and commands).
3047 1246 winstate->defineVariableList = 56aa37bRow pattern recognition patch (executor and commands).
3048 2492 lappend(winstate->defineVariableList, 56aa37bRow pattern recognition patch (executor and commands).
3049 1246 makeString(pstrdup(name))); 56aa37bRow pattern recognition patch (executor and commands).
3050 1246 attno_map((Node *) expr); 56aa37bRow pattern recognition patch (executor and commands).
3051 1246 exps = ExecInitExpr(expr, (PlanState *) winstate); 56aa37bRow pattern recognition patch (executor and commands).
3052 1246 winstate->defineClauseList = 56aa37bRow pattern recognition patch (executor and commands).
3053 1246 lappend(winstate->defineClauseList, exps); 56aa37bRow pattern recognition patch (executor and commands).
3054 1246 } 56aa37bRow pattern recognition patch (executor and commands).
3055 461 } 56aa37bRow pattern recognition patch (executor and commands).
3056 - 56aa37bRow pattern recognition patch (executor and commands).
3057 - /* Initialize NFA free lists for row pattern matching */ 56aa37bRow pattern recognition patch (executor and commands).
3058 462 winstate->nfaContext = NULL; 56aa37bRow pattern recognition patch (executor and commands).
3059 462 winstate->nfaContextTail = NULL; 56aa37bRow pattern recognition patch (executor and commands).
3060 462 winstate->nfaContextFree = NULL; 56aa37bRow pattern recognition patch (executor and commands).
3061 462 winstate->nfaStateFree = NULL; 56aa37bRow pattern recognition patch (executor and commands).
3062 462 winstate->nfaLastProcessedRow = -1; 56aa37bRow pattern recognition patch (executor and commands).
3063 462 winstate->nfaStatesActive = 0; d06525dInitialize NFA per-partition counters in ExecInitWindowAgg
3064 462 winstate->nfaContextsActive = 0; d06525dInitialize NFA per-partition counters in ExecInitWindowAgg
3065 - 56aa37bRow pattern recognition patch (executor and commands).
3066 - /* 56aa37bRow pattern recognition patch (executor and commands).
3067 - * Allocate varMatched array for NFA evaluation. With the new varNames 56aa37bRow pattern recognition patch (executor and commands).
3068 - * ordering (DEFINE order first), varId == defineIdx for all defined 56aa37bRow pattern recognition patch (executor and commands).
3069 - * variables, so no mapping is needed. 56aa37bRow pattern recognition patch (executor and commands).
3070 - */ 56aa37bRow pattern recognition patch (executor and commands).
3071 462 if (list_length(winstate->defineVariableList) > 0) 56aa37bRow pattern recognition patch (executor and commands).
3072 461 winstate->nfaVarMatched = palloc0(sizeof(bool) * 56aa37bRow pattern recognition patch (executor and commands).
3073 461 list_length(winstate->defineVariableList)); 56aa37bRow pattern recognition patch (executor and commands).
3074 - else 56aa37bRow pattern recognition patch (executor and commands).
3075 1 winstate->nfaVarMatched = NULL; 56aa37bRow pattern recognition patch (executor and commands).
3076 - winstate->all_first = true; -
3077 - winstate->partition_spooled = false; -
3078 - winstate->more_partitions = false; -
3079 - winstate->next_partition = true; -
3080 - -
3081 - return winstate; -
3082 - } -
attno_map() lines 3091-3094
Modified Lines Coverage: 3/3 lines (100.0%)
LineHitsSourceCommit
3091 1246 attno_map(Node *node) 56aa37bRow pattern recognition patch (executor and commands).
3092 - { 56aa37bRow pattern recognition patch (executor and commands).
3093 1246 (void) expression_tree_walker(node, attno_map_walker, NULL); 56aa37bRow pattern recognition patch (executor and commands).
3094 1246 } 56aa37bRow pattern recognition patch (executor and commands).
attno_map_walker() lines 3097-3129
Modified Lines Coverage: 17/18 lines (94.4%)
LineHitsSourceCommit
3097 3184 attno_map_walker(Node *node, void *context) 56aa37bRow pattern recognition patch (executor and commands).
3098 - { 56aa37bRow pattern recognition patch (executor and commands).
3099 3184 FuncExpr *func; 56aa37bRow pattern recognition patch (executor and commands).
3100 3184 int nargs; 56aa37bRow pattern recognition patch (executor and commands).
3101 3184 bool is_prev; 56aa37bRow pattern recognition patch (executor and commands).
3102 - 56aa37bRow pattern recognition patch (executor and commands).
3103 3184 if (node == NULL) 56aa37bRow pattern recognition patch (executor and commands).
3104 11 return false; 56aa37bRow pattern recognition patch (executor and commands).
3105 - 56aa37bRow pattern recognition patch (executor and commands).
3106 3173 if (IsA(node, FuncExpr)) 56aa37bRow pattern recognition patch (executor and commands).
3107 - { 56aa37bRow pattern recognition patch (executor and commands).
3108 61 func = (FuncExpr *) node; 56aa37bRow pattern recognition patch (executor and commands).
3109 - 56aa37bRow pattern recognition patch (executor and commands).
3110 61 if (func->funcid == F_PREV || func->funcid == F_NEXT) 56aa37bRow pattern recognition patch (executor and commands).
3111 - { 56aa37bRow pattern recognition patch (executor and commands).
3112 - /* 56aa37bRow pattern recognition patch (executor and commands).
3113 - * The SQL standard allows to have two more arguments form of 56aa37bRow pattern recognition patch (executor and commands).
3114 - * PREV/NEXT. But currently we allow only 1 argument form. 56aa37bRow pattern recognition patch (executor and commands).
3115 - */ 56aa37bRow pattern recognition patch (executor and commands).
3116 59 nargs = list_length(func->args); 56aa37bRow pattern recognition patch (executor and commands).
3117 59 if (list_length(func->args) != 1) 56aa37bRow pattern recognition patch (executor and commands).
3118 0 elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args", 56aa37bRow pattern recognition patch (executor and commands).
3119 - func->funcid, nargs); 56aa37bRow pattern recognition patch (executor and commands).
3120 - 56aa37bRow pattern recognition patch (executor and commands).
3121 - /* 56aa37bRow pattern recognition patch (executor and commands).
3122 - * Check expr of PREV/NEXT aruguments and replace varno. 56aa37bRow pattern recognition patch (executor and commands).
3123 - */ 56aa37bRow pattern recognition patch (executor and commands).
3124 59 is_prev = (func->funcid == F_PREV) ? true : false; 56aa37bRow pattern recognition patch (executor and commands).
3125 59 check_rpr_navigation(node, is_prev); 56aa37bRow pattern recognition patch (executor and commands).
3126 59 } 56aa37bRow pattern recognition patch (executor and commands).
3127 61 } 56aa37bRow pattern recognition patch (executor and commands).
3128 3173 return expression_tree_walker(node, attno_map_walker, NULL); 56aa37bRow pattern recognition patch (executor and commands).
3129 3184 } 56aa37bRow pattern recognition patch (executor and commands).
check_rpr_navigation() lines 3136-3146
Modified Lines Coverage: 8/8 lines (100.0%)
LineHitsSourceCommit
3136 59 check_rpr_navigation(Node *node, bool is_prev) 56aa37bRow pattern recognition patch (executor and commands).
3137 - { 56aa37bRow pattern recognition patch (executor and commands).
3138 59 NavigationInfo context; 56aa37bRow pattern recognition patch (executor and commands).
3139 - 56aa37bRow pattern recognition patch (executor and commands).
3140 59 context.is_prev = is_prev; 56aa37bRow pattern recognition patch (executor and commands).
3141 59 context.num_vars = 0; 56aa37bRow pattern recognition patch (executor and commands).
3142 59 (void) expression_tree_walker(node, rpr_navigation_walker, &context); 56aa37bRow pattern recognition patch (executor and commands).
3143 59 if (context.num_vars < 1) 56aa37bRow pattern recognition patch (executor and commands).
3144 1 ereport(ERROR, 56aa37bRow pattern recognition patch (executor and commands).
3145 - errmsg("row pattern navigation operation's argument must include at least one column reference")); 56aa37bRow pattern recognition patch (executor and commands).
3146 58 } 56aa37bRow pattern recognition patch (executor and commands).
rpr_navigation_walker() lines 3149-3186
Modified Lines Coverage: 15/18 lines (83.3%)
LineHitsSourceCommit
3149 63 rpr_navigation_walker(Node *node, void *context) 56aa37bRow pattern recognition patch (executor and commands).
3150 - { 56aa37bRow pattern recognition patch (executor and commands).
3151 63 NavigationInfo *nav = (NavigationInfo *) context; 56aa37bRow pattern recognition patch (executor and commands).
3152 - 56aa37bRow pattern recognition patch (executor and commands).
3153 63 if (node == NULL) 56aa37bRow pattern recognition patch (executor and commands).
3154 0 return false; 56aa37bRow pattern recognition patch (executor and commands).
3155 - 56aa37bRow pattern recognition patch (executor and commands).
3156 63 switch (nodeTag(node)) 56aa37bRow pattern recognition patch (executor and commands).
3157 - { 56aa37bRow pattern recognition patch (executor and commands).
3158 - case T_Var: 56aa37bRow pattern recognition patch (executor and commands).
3159 - { 56aa37bRow pattern recognition patch (executor and commands).
3160 59 Var *var = (Var *) node; 56aa37bRow pattern recognition patch (executor and commands).
3161 - 56aa37bRow pattern recognition patch (executor and commands).
3162 59 nav->num_vars++; 56aa37bRow pattern recognition patch (executor and commands).
3163 - 56aa37bRow pattern recognition patch (executor and commands).
3164 59 if (nav->is_prev) 56aa37bRow pattern recognition patch (executor and commands).
3165 - { 56aa37bRow pattern recognition patch (executor and commands).
3166 - /* 56aa37bRow pattern recognition patch (executor and commands).
3167 - * Rewrite varno from OUTER_VAR to regular var no so that 56aa37bRow pattern recognition patch (executor and commands).
3168 - * the var references scan tuple. 56aa37bRow pattern recognition patch (executor and commands).
3169 - */ 56aa37bRow pattern recognition patch (executor and commands).
3170 55 var->varno = var->varnosyn; 56aa37bRow pattern recognition patch (executor and commands).
3171 55 } 56aa37bRow pattern recognition patch (executor and commands).
3172 - else 56aa37bRow pattern recognition patch (executor and commands).
3173 4 var->varno = INNER_VAR; 56aa37bRow pattern recognition patch (executor and commands).
3174 59 } 56aa37bRow pattern recognition patch (executor and commands).
3175 59 break; 56aa37bRow pattern recognition patch (executor and commands).
3176 - case T_Const: 56aa37bRow pattern recognition patch (executor and commands).
3177 - case T_FuncExpr: 56aa37bRow pattern recognition patch (executor and commands).
3178 - case T_OpExpr: 56aa37bRow pattern recognition patch (executor and commands).
3179 4 break; 56aa37bRow pattern recognition patch (executor and commands).
3180 - 56aa37bRow pattern recognition patch (executor and commands).
3181 - default: 56aa37bRow pattern recognition patch (executor and commands).
3182 0 ereport(ERROR, 56aa37bRow pattern recognition patch (executor and commands).
3183 - errmsg("row pattern navigation operation's argument includes unsupported expression")); 56aa37bRow pattern recognition patch (executor and commands).
3184 0 } 56aa37bRow pattern recognition patch (executor and commands).
3185 63 return expression_tree_walker(node, rpr_navigation_walker, context); 56aa37bRow pattern recognition patch (executor and commands).
3186 63 } 56aa37bRow pattern recognition patch (executor and commands).
ExecReScanWindowAgg() lines 3229-3263
Modified Lines Coverage: 2/2 lines (100.0%)
LineHitsSourceCommit
3229 - ExecReScanWindowAgg(WindowAggState *node) -
3230 - { -
3231 - PlanState *outerPlan = outerPlanState(node); -
3232 - ExprContext *econtext = node->ss.ps.ps_ExprContext; -
3233 - -
3234 - node->status = WINDOWAGG_RUN; -
3235 - node->all_first = true; -
3236 - -
3237 - /* release tuplestore et al */ -
3238 - release_partition(node); -
3239 - -
3240 - /* release all temp tuples, but especially first_part_slot */ -
3241 - ExecClearTuple(node->ss.ss_ScanTupleSlot); -
3242 - ExecClearTuple(node->first_part_slot); -
3243 - ExecClearTuple(node->agg_row_slot); -
3244 - ExecClearTuple(node->temp_slot_1); -
3245 - ExecClearTuple(node->temp_slot_2); -
3246 2 ExecClearTuple(node->prev_slot); 56aa37bRow pattern recognition patch (executor and commands).
3247 2 ExecClearTuple(node->next_slot); 56aa37bRow pattern recognition patch (executor and commands).
3248 - if (node->framehead_slot) -
3249 - ExecClearTuple(node->framehead_slot); -
3250 - if (node->frametail_slot) -
3251 - ExecClearTuple(node->frametail_slot); -
3252 - -
3253 - /* Forget current wfunc values */ -
3254 - MemSet(econtext->ecxt_aggvalues, 0, sizeof(Datum) * node->numfuncs); -
3255 - MemSet(econtext->ecxt_aggnulls, 0, sizeof(bool) * node->numfuncs); -
3256 - -
3257 - /* -
3258 - * if chgParam of subnode is not null then plan will be re-scanned by -
3259 - * first ExecProcNode. -
3260 - */ -
3261 - if (outerPlan->chgParam == NULL) -
3262 - ExecReScan(outerPlan); -
3263 - } -
window_gettupleslot() lines 3589-3673
Modified Lines Coverage: 0/1 lines (0.0%)
LineHitsSourceCommit
3589 - window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot) -
3590 - { -
3591 - WindowAggState *winstate = winobj->winstate; -
3592 - MemoryContext oldcontext; -
3593 - -
3594 - /* often called repeatedly in a row */ -
3595 - CHECK_FOR_INTERRUPTS(); -
3596 - -
3597 - /* Don't allow passing -1 to spool_tuples here */ -
3598 - if (pos < 0) -
3599 - return false; -
3600 - -
3601 - /* If necessary, fetch the tuple into the spool */ -
3602 - spool_tuples(winstate, pos); -
3603 - -
3604 - if (pos >= winstate->spooled_rows) -
3605 - return false; -
3606 - -
3607 - if (pos < winobj->markpos) -
3608 0 elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT, 56aa37bRow pattern recognition patch (executor and commands).
3609 - pos, winobj->markpos); 56aa37bRow pattern recognition patch (executor and commands).
3610 - -
3611 - oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory); -
3612 - -
3613 - tuplestore_select_read_pointer(winstate->buffer, winobj->readptr); -
3614 - -
3615 - /* -
3616 - * Advance or rewind until we are within one tuple of the one we want. -
3617 - */ -
3618 - if (winobj->seekpos < pos - 1) -
3619 - { -
3620 - if (!tuplestore_skiptuples(winstate->buffer, -
3621 - pos - 1 - winobj->seekpos, -
3622 - true)) -
3623 - elog(ERROR, "unexpected end of tuplestore"); -
3624 - winobj->seekpos = pos - 1; -
3625 - } -
3626 - else if (winobj->seekpos > pos + 1) -
3627 - { -
3628 - if (!tuplestore_skiptuples(winstate->buffer, -
3629 - winobj->seekpos - (pos + 1), -
3630 - false)) -
3631 - elog(ERROR, "unexpected end of tuplestore"); -
3632 - winobj->seekpos = pos + 1; -
3633 - } -
3634 - else if (winobj->seekpos == pos) -
3635 - { -
3636 - /* -
3637 - * There's no API to refetch the tuple at the current position. We -
3638 - * have to move one tuple forward, and then one backward. (We don't -
3639 - * do it the other way because we might try to fetch the row before -
3640 - * our mark, which isn't allowed.) XXX this case could stand to be -
3641 - * optimized. -
3642 - */ -
3643 - tuplestore_advance(winstate->buffer, true); -
3644 - winobj->seekpos++; -
3645 - } -
3646 - -
3647 - /* -
3648 - * Now we should be on the tuple immediately before or after the one we -
3649 - * want, so just fetch forwards or backwards as appropriate. -
3650 - * -
3651 - * Notice that we tell tuplestore_gettupleslot to make a physical copy of -
3652 - * the fetched tuple. This ensures that the slot's contents remain valid -
3653 - * through manipulations of the tuplestore, which some callers depend on. -
3654 - */ -
3655 - if (winobj->seekpos > pos) -
3656 - { -
3657 - if (!tuplestore_gettupleslot(winstate->buffer, false, true, slot)) -
3658 - elog(ERROR, "unexpected end of tuplestore"); -
3659 - winobj->seekpos--; -
3660 - } -
3661 - else -
3662 - { -
3663 - if (!tuplestore_gettupleslot(winstate->buffer, true, true, slot)) -
3664 - elog(ERROR, "unexpected end of tuplestore"); -
3665 - winobj->seekpos++; -
3666 - } -
3667 - -
3668 - Assert(winobj->seekpos == pos); -
3669 - -
3670 - MemoryContextSwitchTo(oldcontext); -
3671 - -
3672 - return true; -
3673 - } -
ignorenulls_getfuncarginframe() lines 3713-3889
Modified Lines Coverage: 18/19 lines (94.7%)
LineHitsSourceCommit
3713 - ignorenulls_getfuncarginframe(WindowObject winobj, int argno, -
3714 - int relpos, int seektype, bool set_mark, -
3715 - bool *isnull, bool *isout) -
3716 - { -
3717 - WindowAggState *winstate; -
3718 - ExprContext *econtext; -
3719 - TupleTableSlot *slot; -
3720 - Datum datum; -
3721 - int64 abs_pos; -
3722 - int64 mark_pos; -
3723 - int notnull_offset; -
3724 - int notnull_relpos; -
3725 - int forward; -
3726 88 int num_reduced_frame; 56aa37bRow pattern recognition patch (executor and commands).
3727 - -
3728 - Assert(WindowObjectIsValid(winobj)); -
3729 - winstate = winobj->winstate; -
3730 - econtext = winstate->ss.ps.ps_ExprContext; -
3731 - slot = winstate->temp_slot_1; -
3732 - datum = (Datum) 0; -
3733 - notnull_offset = 0; -
3734 - notnull_relpos = abs(relpos); -
3735 - -
3736 - switch (seektype) -
3737 - { -
3738 - case WINDOW_SEEK_CURRENT: -
3739 - elog(ERROR, "WINDOW_SEEK_CURRENT is not supported for WinGetFuncArgInFrame"); -
3740 - abs_pos = mark_pos = 0; /* keep compiler quiet */ -
3741 - break; -
3742 - case WINDOW_SEEK_HEAD: -
3743 - /* rejecting relpos < 0 is easy and simplifies code below */ -
3744 - if (relpos < 0) -
3745 - goto out_of_frame; -
3746 - update_frameheadpos(winstate); -
3747 - abs_pos = winstate->frameheadpos; -
3748 - mark_pos = winstate->frameheadpos; -
3749 - forward = 1; -
3750 - break; -
3751 - case WINDOW_SEEK_TAIL: -
3752 - /* rejecting relpos > 0 is easy and simplifies code below */ -
3753 - if (relpos > 0) -
3754 - goto out_of_frame; -
3755 - 56aa37bRow pattern recognition patch (executor and commands).
3756 - /* 56aa37bRow pattern recognition patch (executor and commands).
3757 - * RPR cares about frame head pos. Need to call 56aa37bRow pattern recognition patch (executor and commands).
3758 - * update_frameheadpos 56aa37bRow pattern recognition patch (executor and commands).
3759 - */ 56aa37bRow pattern recognition patch (executor and commands).
3760 20 update_frameheadpos(winstate); 56aa37bRow pattern recognition patch (executor and commands).
3761 - 56aa37bRow pattern recognition patch (executor and commands).
3762 - update_frametailpos(winstate); -
3763 - abs_pos = winstate->frametailpos - 1; -
3764 - mark_pos = 0; /* keep compiler quiet */ -
3765 - forward = -1; -
3766 - break; -
3767 - default: -
3768 - elog(ERROR, "unrecognized window seek type: %d", seektype); -
3769 - abs_pos = mark_pos = 0; /* keep compiler quiet */ -
3770 - break; -
3771 - } -
3772 - -
3773 - /* -
3774 - * Get the next nonnull value in the frame, moving forward or backward -
3775 - * until we find a value or reach the frame's end. -
3776 - */ -
3777 - 56aa37bRow pattern recognition patch (executor and commands).
3778 - /* 56aa37bRow pattern recognition patch (executor and commands).
3779 - * Check whether current row is in reduced frame. 56aa37bRow pattern recognition patch (executor and commands).
3780 - */ 56aa37bRow pattern recognition patch (executor and commands).
3781 88 num_reduced_frame = row_is_in_reduced_frame(winobj, winstate->frameheadpos); 56aa37bRow pattern recognition patch (executor and commands).
3782 88 if (num_reduced_frame < 0) /* unmatched or skipped row */ 56aa37bRow pattern recognition patch (executor and commands).
3783 70 goto out_of_frame; 56aa37bRow pattern recognition patch (executor and commands).
3784 18 else if (num_reduced_frame > 0) /* the first row of the reduced frame */ 56aa37bRow pattern recognition patch (executor and commands).
3785 - { 56aa37bRow pattern recognition patch (executor and commands).
3786 - /* 56aa37bRow pattern recognition patch (executor and commands).
3787 - * Early check if row could be out of reduced frame. When RPR is 56aa37bRow pattern recognition patch (executor and commands).
3788 - * enabled, EXCUDE clause cannot be specified and the frame is always 56aa37bRow pattern recognition patch (executor and commands).
3789 - * contiguous. So we can do the check followings safely. Note, 56aa37bRow pattern recognition patch (executor and commands).
3790 - * however, it is possible that a row is out of reduced frame if 56aa37bRow pattern recognition patch (executor and commands).
3791 - * there's a NULL in the middle. So we need to check it in the 56aa37bRow pattern recognition patch (executor and commands).
3792 - * following do lopp. 56aa37bRow pattern recognition patch (executor and commands).
3793 - */ 56aa37bRow pattern recognition patch (executor and commands).
3794 18 if (seektype == WINDOW_SEEK_HEAD && relpos >= num_reduced_frame) 56aa37bRow pattern recognition patch (executor and commands).
3795 4 goto out_of_frame; 56aa37bRow pattern recognition patch (executor and commands).
3796 14 if (seektype == WINDOW_SEEK_TAIL) 56aa37bRow pattern recognition patch (executor and commands).
3797 - { 56aa37bRow pattern recognition patch (executor and commands).
3798 4 if (notnull_relpos >= num_reduced_frame) 56aa37bRow pattern recognition patch (executor and commands).
3799 0 goto out_of_frame; 56aa37bRow pattern recognition patch (executor and commands).
3800 - 56aa37bRow pattern recognition patch (executor and commands).
3801 - /* not out of reduced frame. Set abspos as a starting point */ 56aa37bRow pattern recognition patch (executor and commands).
3802 4 abs_pos = winstate->frameheadpos + num_reduced_frame - 1; 56aa37bRow pattern recognition patch (executor and commands).
3803 4 } 56aa37bRow pattern recognition patch (executor and commands).
3804 14 } 56aa37bRow pattern recognition patch (executor and commands).
3805 - 56aa37bRow pattern recognition patch (executor and commands).
3806 - do -
3807 - { -
3808 - int inframe; -
3809 - int v; -
3810 - -
3811 - /* -
3812 - * Check apparent out of frame case. We need to do this because we -
3813 - * may not call window_gettupleslot before row_is_in_frame, which -
3814 - * supposes abs_pos is never negative. -
3815 - */ -
3816 - if (abs_pos < 0) -
3817 - goto out_of_frame; -
3818 - -
3819 - /* check whether row is in frame */ -
3820 - inframe = row_is_in_frame(winobj, abs_pos, slot, true); -
3821 - if (inframe == -1) -
3822 - goto out_of_frame; -
3823 - else if (inframe == 0) -
3824 - goto advance; -
3825 - -
3826 - if (isout) -
3827 - *isout = false; -
3828 - -
3829 - v = get_notnull_info(winobj, abs_pos, argno); -
3830 - if (v == NN_NULL) /* this row is known to be NULL */ -
3831 - goto advance; -
3832 - -
3833 - else if (v == NN_UNKNOWN) /* need to check NULL or not */ -
3834 - { -
3835 - if (!window_gettupleslot(winobj, abs_pos, slot)) -
3836 - goto out_of_frame; -
3837 - -
3838 - econtext->ecxt_outertuple = slot; -
3839 - datum = ExecEvalExpr( -
3840 - (ExprState *) list_nth(winobj->argstates, -
3841 - argno), econtext, -
3842 - isnull); -
3843 - if (!*isnull) -
3844 - notnull_offset++; -
3845 - -
3846 - /* record the row status */ -
3847 - put_notnull_info(winobj, abs_pos, argno, *isnull); -
3848 - } -
3849 - else /* this row is known to be NOT NULL */ -
3850 - { -
3851 - notnull_offset++; -
3852 - if (notnull_offset > notnull_relpos) -
3853 - { -
3854 - /* to prepare exiting this loop, datum needs to be set */ -
3855 - if (!window_gettupleslot(winobj, abs_pos, slot)) -
3856 - goto out_of_frame; -
3857 - -
3858 - econtext->ecxt_outertuple = slot; -
3859 - datum = ExecEvalExpr( -
3860 - (ExprState *) list_nth -
3861 - (winobj->argstates, argno), -
3862 - econtext, isnull); -
3863 - } -
3864 - } -
3865 - advance: -
3866 - abs_pos += forward; -
3867 22 if (rpr_is_defined(winstate)) 56aa37bRow pattern recognition patch (executor and commands).
3868 - { 56aa37bRow pattern recognition patch (executor and commands).
3869 - /* 56aa37bRow pattern recognition patch (executor and commands).
3870 - * Check whether we are still in the reduced frame. (also check 56aa37bRow pattern recognition patch (executor and commands).
3871 - * if we succeeded in getting the target row). 56aa37bRow pattern recognition patch (executor and commands).
3872 - */ 56aa37bRow pattern recognition patch (executor and commands).
3873 22 num_reduced_frame--; 56aa37bRow pattern recognition patch (executor and commands).
3874 22 if (num_reduced_frame <= 0 && notnull_offset <= notnull_relpos) 56aa37bRow pattern recognition patch (executor and commands).
3875 1 goto out_of_frame; 56aa37bRow pattern recognition patch (executor and commands).
3876 21 } 56aa37bRow pattern recognition patch (executor and commands).
3877 - } while (notnull_offset <= notnull_relpos); -
3878 - -
3879 - if (set_mark) -
3880 - WinSetMarkPosition(winobj, mark_pos); -
3881 - -
3882 - return datum; -
3883 - -
3884 - out_of_frame: -
3885 - if (isout) -
3886 - *isout = true; -
3887 - *isnull = true; -
3888 - return (Datum) 0; -
3889 - } -
WinGetFuncArgInFrame() lines 4351-4381
Modified Lines Coverage: 10/11 lines (90.9%)
LineHitsSourceCommit
4351 - WinGetFuncArgInFrame(WindowObject winobj, int argno, -
4352 - int relpos, int seektype, bool set_mark, -
4353 - bool *isnull, bool *isout) -
4354 - { -
4355 - WindowAggState *winstate; -
4356 - ExprContext *econtext; -
4357 - TupleTableSlot *slot; -
4358 - -
4359 - Assert(WindowObjectIsValid(winobj)); -
4360 - winstate = winobj->winstate; -
4361 - econtext = winstate->ss.ps.ps_ExprContext; -
4362 - slot = winstate->temp_slot_1; -
4363 - -
4364 - if (winobj->ignore_nulls == IGNORE_NULLS) -
4365 - return ignorenulls_getfuncarginframe(winobj, argno, relpos, seektype, -
4366 - set_mark, isnull, isout); -
4367 - -
4368 13842 if (WinGetSlotInFrame(winobj, slot, 56aa37bRow pattern recognition patch (executor and commands).
4369 4614 relpos, seektype, set_mark, 56aa37bRow pattern recognition patch (executor and commands).
4370 9228 isnull, isout) == 0) 56aa37bRow pattern recognition patch (executor and commands).
4371 - { 56aa37bRow pattern recognition patch (executor and commands).
4372 1828 econtext->ecxt_outertuple = slot; 56aa37bRow pattern recognition patch (executor and commands).
4373 3656 return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno), 56aa37bRow pattern recognition patch (executor and commands).
4374 1828 econtext, isnull); 56aa37bRow pattern recognition patch (executor and commands).
4375 - } 56aa37bRow pattern recognition patch (executor and commands).
4376 - 56aa37bRow pattern recognition patch (executor and commands).
4377 2786 if (isout) 56aa37bRow pattern recognition patch (executor and commands).
4378 0 *isout = true; 56aa37bRow pattern recognition patch (executor and commands).
4379 2786 *isnull = true; 56aa37bRow pattern recognition patch (executor and commands).
4380 2786 return (Datum) 0; 56aa37bRow pattern recognition patch (executor and commands).
4381 4702 } 56aa37bRow pattern recognition patch (executor and commands).
WinGetSlotInFrame() lines 4398-4594
Modified Lines Coverage: 24/24 lines (100.0%)
LineHitsSourceCommit
4398 4614 WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot, 56aa37bRow pattern recognition patch (executor and commands).
4399 - int relpos, int seektype, bool set_mark, 56aa37bRow pattern recognition patch (executor and commands).
4400 - bool *isnull, bool *isout) 56aa37bRow pattern recognition patch (executor and commands).
4401 - { 56aa37bRow pattern recognition patch (executor and commands).
4402 4614 WindowAggState *winstate; 56aa37bRow pattern recognition patch (executor and commands).
4403 4614 int64 abs_pos; 56aa37bRow pattern recognition patch (executor and commands).
4404 4614 int64 mark_pos; 56aa37bRow pattern recognition patch (executor and commands).
4405 4614 int num_reduced_frame; 56aa37bRow pattern recognition patch (executor and commands).
4406 - 56aa37bRow pattern recognition patch (executor and commands).
4407 4614 Assert(WindowObjectIsValid(winobj)); 56aa37bRow pattern recognition patch (executor and commands).
4408 4614 winstate = winobj->winstate; 56aa37bRow pattern recognition patch (executor and commands).
4409 - 56aa37bRow pattern recognition patch (executor and commands).
4410 - switch (seektype) -
4411 - { -
4412 - case WINDOW_SEEK_CURRENT: -
4413 - elog(ERROR, "WINDOW_SEEK_CURRENT is not supported for WinGetFuncArgInFrame"); -
4414 - abs_pos = mark_pos = 0; /* keep compiler quiet */ -
4415 - break; -
4416 - case WINDOW_SEEK_HEAD: -
4417 - /* rejecting relpos < 0 is easy and simplifies code below */ -
4418 - if (relpos < 0) -
4419 - goto out_of_frame; -
4420 - update_frameheadpos(winstate); -
4421 - abs_pos = winstate->frameheadpos + relpos; -
4422 - mark_pos = abs_pos; -
4423 - -
4424 - /* -
4425 - * Account for exclusion option if one is active, but advance only -
4426 - * abs_pos not mark_pos. This prevents changes of the current -
4427 - * row's peer group from resulting in trying to fetch a row before -
4428 - * some previous mark position. -
4429 - * -
4430 - * Note that in some corner cases such as current row being -
4431 - * outside frame, these calculations are theoretically too simple, -
4432 - * but it doesn't matter because we'll end up deciding the row is -
4433 - * out of frame. We do not attempt to avoid fetching rows past -
4434 - * end of frame; that would happen in some cases anyway. -
4435 - */ -
4436 - switch (winstate->frameOptions & FRAMEOPTION_EXCLUSION) -
4437 - { -
4438 - case 0: -
4439 - /* no adjustment needed */ -
4440 - break; -
4441 - case FRAMEOPTION_EXCLUDE_CURRENT_ROW: -
4442 - if (abs_pos >= winstate->currentpos && -
4443 - winstate->currentpos >= winstate->frameheadpos) -
4444 - abs_pos++; -
4445 - break; -
4446 - case FRAMEOPTION_EXCLUDE_GROUP: -
4447 - update_grouptailpos(winstate); -
4448 - if (abs_pos >= winstate->groupheadpos && -
4449 - winstate->grouptailpos > winstate->frameheadpos) -
4450 - { -
4451 - int64 overlapstart = Max(winstate->groupheadpos, -
4452 - winstate->frameheadpos); -
4453 - -
4454 - abs_pos += winstate->grouptailpos - overlapstart; -
4455 - } -
4456 - break; -
4457 - case FRAMEOPTION_EXCLUDE_TIES: -
4458 - update_grouptailpos(winstate); -
4459 - if (abs_pos >= winstate->groupheadpos && -
4460 - winstate->grouptailpos > winstate->frameheadpos) -
4461 - { -
4462 - int64 overlapstart = Max(winstate->groupheadpos, -
4463 - winstate->frameheadpos); -
4464 - -
4465 - if (abs_pos == overlapstart) -
4466 - abs_pos = winstate->currentpos; -
4467 - else -
4468 - abs_pos += winstate->grouptailpos - overlapstart - 1; -
4469 - } -
4470 - break; -
4471 - default: -
4472 - elog(ERROR, "unrecognized frame option state: 0x%x", -
4473 - winstate->frameOptions); -
4474 - break; -
4475 - } -
4476 4748 num_reduced_frame = row_is_in_reduced_frame(winobj, 56aa37bRow pattern recognition patch (executor and commands).
4477 2374 winstate->frameheadpos); 56aa37bRow pattern recognition patch (executor and commands).
4478 2374 if (num_reduced_frame < 0) 56aa37bRow pattern recognition patch (executor and commands).
4479 1443 goto out_of_frame; 56aa37bRow pattern recognition patch (executor and commands).
4480 931 else if (num_reduced_frame > 0) 56aa37bRow pattern recognition patch (executor and commands).
4481 931 if (relpos >= num_reduced_frame) 56aa37bRow pattern recognition patch (executor and commands).
4482 4 goto out_of_frame; 56aa37bRow pattern recognition patch (executor and commands).
4483 - break; -
4484 - case WINDOW_SEEK_TAIL: -
4485 - /* rejecting relpos > 0 is easy and simplifies code below */ -
4486 - if (relpos > 0) -
4487 - goto out_of_frame; -
4488 - 56aa37bRow pattern recognition patch (executor and commands).
4489 - /* 56aa37bRow pattern recognition patch (executor and commands).
4490 - * RPR cares about frame head pos. Need to call 56aa37bRow pattern recognition patch (executor and commands).
4491 - * update_frameheadpos 56aa37bRow pattern recognition patch (executor and commands).
4492 - */ 56aa37bRow pattern recognition patch (executor and commands).
4493 2240 update_frameheadpos(winstate); 56aa37bRow pattern recognition patch (executor and commands).
4494 - 56aa37bRow pattern recognition patch (executor and commands).
4495 - update_frametailpos(winstate); -
4496 - abs_pos = winstate->frametailpos - 1 + relpos; -
4497 - -
4498 - /* -
4499 - * Account for exclusion option if one is active. If there is no -
4500 - * exclusion, we can safely set the mark at the accessed row. But -
4501 - * if there is, we can only mark the frame start, because we can't -
4502 - * be sure how far back in the frame the exclusion might cause us -
4503 - * to fetch in future. Furthermore, we have to actually check -
4504 - * against frameheadpos here, since it's unsafe to try to fetch a -
4505 - * row before frame start if the mark might be there already. -
4506 - */ -
4507 - switch (winstate->frameOptions & FRAMEOPTION_EXCLUSION) -
4508 - { -
4509 - case 0: -
4510 - /* no adjustment needed */ -
4511 - mark_pos = abs_pos; -
4512 - break; -
4513 - case FRAMEOPTION_EXCLUDE_CURRENT_ROW: -
4514 - if (abs_pos <= winstate->currentpos && -
4515 - winstate->currentpos < winstate->frametailpos) -
4516 - abs_pos--; -
4517 - update_frameheadpos(winstate); -
4518 - if (abs_pos < winstate->frameheadpos) -
4519 - goto out_of_frame; -
4520 - mark_pos = winstate->frameheadpos; -
4521 - break; -
4522 - case FRAMEOPTION_EXCLUDE_GROUP: -
4523 - update_grouptailpos(winstate); -
4524 - if (abs_pos < winstate->grouptailpos && -
4525 - winstate->groupheadpos < winstate->frametailpos) -
4526 - { -
4527 - int64 overlapend = Min(winstate->grouptailpos, -
4528 - winstate->frametailpos); -
4529 - -
4530 - abs_pos -= overlapend - winstate->groupheadpos; -
4531 - } -
4532 - update_frameheadpos(winstate); -
4533 - if (abs_pos < winstate->frameheadpos) -
4534 - goto out_of_frame; -
4535 - mark_pos = winstate->frameheadpos; -
4536 - break; -
4537 - case FRAMEOPTION_EXCLUDE_TIES: -
4538 - update_grouptailpos(winstate); -
4539 - if (abs_pos < winstate->grouptailpos && -
4540 - winstate->groupheadpos < winstate->frametailpos) -
4541 - { -
4542 - int64 overlapend = Min(winstate->grouptailpos, -
4543 - winstate->frametailpos); -
4544 - -
4545 - if (abs_pos == overlapend - 1) -
4546 - abs_pos = winstate->currentpos; -
4547 - else -
4548 - abs_pos -= overlapend - 1 - winstate->groupheadpos; -
4549 - } -
4550 - update_frameheadpos(winstate); -
4551 - if (abs_pos < winstate->frameheadpos) -
4552 - goto out_of_frame; -
4553 - mark_pos = winstate->frameheadpos; -
4554 - break; -
4555 - default: -
4556 - elog(ERROR, "unrecognized frame option state: 0x%x", -
4557 - winstate->frameOptions); -
4558 - mark_pos = 0; /* keep compiler quiet */ -
4559 - break; -
4560 - } -
4561 - 56aa37bRow pattern recognition patch (executor and commands).
4562 4480 num_reduced_frame = row_is_in_reduced_frame(winobj, 56aa37bRow pattern recognition patch (executor and commands).
4563 2240 winstate->frameheadpos + relpos); 56aa37bRow pattern recognition patch (executor and commands).
4564 2240 if (num_reduced_frame < 0) 56aa37bRow pattern recognition patch (executor and commands).
4565 1339 goto out_of_frame; 56aa37bRow pattern recognition patch (executor and commands).
4566 901 else if (num_reduced_frame > 0) 56aa37bRow pattern recognition patch (executor and commands).
4567 2703 abs_pos = winstate->frameheadpos + relpos + 56aa37bRow pattern recognition patch (executor and commands).
4568 1802 num_reduced_frame - 1; 56aa37bRow pattern recognition patch (executor and commands).
4569 - break; -
4570 - default: -
4571 - elog(ERROR, "unrecognized window seek type: %d", seektype); -
4572 - abs_pos = mark_pos = 0; /* keep compiler quiet */ -
4573 - break; -
4574 - } -
4575 - -
4576 - if (!window_gettupleslot(winobj, abs_pos, slot)) -
4577 - goto out_of_frame; -
4578 - -
4579 - /* The code above does not detect all out-of-frame cases, so check */ -
4580 - if (row_is_in_frame(winobj, abs_pos, slot, false) <= 0) -
4581 - goto out_of_frame; -
4582 - -
4583 - if (isout) -
4584 - *isout = false; -
4585 - if (set_mark) -
4586 - WinSetMarkPosition(winobj, mark_pos); -
4587 1828 return 0; 56aa37bRow pattern recognition patch (executor and commands).
4588 - -
4589 - out_of_frame: -
4590 - if (isout) -
4591 - *isout = true; -
4592 - *isnull = true; -
4593 2786 return -1; 56aa37bRow pattern recognition patch (executor and commands).
4594 - } -
rpr_is_defined() lines 4630-4633
Modified Lines Coverage: 2/2 lines (100.0%)
LineHitsSourceCommit
4630 311531 rpr_is_defined(WindowAggState *winstate) 56aa37bRow pattern recognition patch (executor and commands).
4631 - { 56aa37bRow pattern recognition patch (executor and commands).
4632 311531 return winstate->rpPattern != NULL; 56aa37bRow pattern recognition patch (executor and commands).
4633 - } 56aa37bRow pattern recognition patch (executor and commands).
row_is_in_reduced_frame() lines 4654-4716
Modified Lines Coverage: 24/28 lines (85.7%)
LineHitsSourceCommit
4654 131458 row_is_in_reduced_frame(WindowObject winobj, int64 pos) 56aa37bRow pattern recognition patch (executor and commands).
4655 - { 56aa37bRow pattern recognition patch (executor and commands).
4656 131458 WindowAggState *winstate = winobj->winstate; 56aa37bRow pattern recognition patch (executor and commands).
4657 131458 int state; 56aa37bRow pattern recognition patch (executor and commands).
4658 131458 int rtn; 56aa37bRow pattern recognition patch (executor and commands).
4659 - 56aa37bRow pattern recognition patch (executor and commands).
4660 131458 if (!rpr_is_defined(winstate)) 56aa37bRow pattern recognition patch (executor and commands).
4661 - { 56aa37bRow pattern recognition patch (executor and commands).
4662 - /* 56aa37bRow pattern recognition patch (executor and commands).
4663 - * RPR is not defined. Assume that we are always in the the reduced 56aa37bRow pattern recognition patch (executor and commands).
4664 - * window frame. 56aa37bRow pattern recognition patch (executor and commands).
4665 - */ 56aa37bRow pattern recognition patch (executor and commands).
4666 0 rtn = 0; 56aa37bRow pattern recognition patch (executor and commands).
4667 - #ifdef RPR_DEBUG 56aa37bRow pattern recognition patch (executor and commands).
4668 - printf("row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT "\n", 56aa37bRow pattern recognition patch (executor and commands).
4669 - rtn, pos); 56aa37bRow pattern recognition patch (executor and commands).
4670 - #endif 56aa37bRow pattern recognition patch (executor and commands).
4671 0 return rtn; 56aa37bRow pattern recognition patch (executor and commands).
4672 - } 56aa37bRow pattern recognition patch (executor and commands).
4673 - 56aa37bRow pattern recognition patch (executor and commands).
4674 131458 state = get_reduced_frame_map(winstate, pos); 56aa37bRow pattern recognition patch (executor and commands).
4675 - 56aa37bRow pattern recognition patch (executor and commands).
4676 131458 if (state == RF_NOT_DETERMINED) 56aa37bRow pattern recognition patch (executor and commands).
4677 - { 56aa37bRow pattern recognition patch (executor and commands).
4678 11709 update_frameheadpos(winstate); 56aa37bRow pattern recognition patch (executor and commands).
4679 11709 update_reduced_frame(winobj, pos); 56aa37bRow pattern recognition patch (executor and commands).
4680 11709 } 56aa37bRow pattern recognition patch (executor and commands).
4681 - 56aa37bRow pattern recognition patch (executor and commands).
4682 131458 state = get_reduced_frame_map(winstate, pos); 56aa37bRow pattern recognition patch (executor and commands).
4683 - 56aa37bRow pattern recognition patch (executor and commands).
4684 131458 switch (state) 56aa37bRow pattern recognition patch (executor and commands).
4685 - { 56aa37bRow pattern recognition patch (executor and commands).
4686 - int64 i; 56aa37bRow pattern recognition patch (executor and commands).
4687 - int num_reduced_rows; 56aa37bRow pattern recognition patch (executor and commands).
4688 - 56aa37bRow pattern recognition patch (executor and commands).
4689 - case RF_FRAME_HEAD: 56aa37bRow pattern recognition patch (executor and commands).
4690 9324 num_reduced_rows = 1; 56aa37bRow pattern recognition patch (executor and commands).
4691 324497 for (i = pos + 1; 56aa37bRow pattern recognition patch (executor and commands).
4692 324497 get_reduced_frame_map(winstate, i) == RF_SKIPPED; i++) 56aa37bRow pattern recognition patch (executor and commands).
4693 315173 num_reduced_rows++; 56aa37bRow pattern recognition patch (executor and commands).
4694 9324 rtn = num_reduced_rows; 56aa37bRow pattern recognition patch (executor and commands).
4695 9324 break; 56aa37bRow pattern recognition patch (executor and commands).
4696 - 56aa37bRow pattern recognition patch (executor and commands).
4697 - case RF_SKIPPED: 56aa37bRow pattern recognition patch (executor and commands).
4698 117748 rtn = -2; 56aa37bRow pattern recognition patch (executor and commands).
4699 117748 break; 56aa37bRow pattern recognition patch (executor and commands).
4700 - 56aa37bRow pattern recognition patch (executor and commands).
4701 - case RF_UNMATCHED: 56aa37bRow pattern recognition patch (executor and commands).
4702 4386 rtn = -1; 56aa37bRow pattern recognition patch (executor and commands).
4703 4386 break; 56aa37bRow pattern recognition patch (executor and commands).
4704 - 56aa37bRow pattern recognition patch (executor and commands).
4705 - default: 56aa37bRow pattern recognition patch (executor and commands).
4706 0 elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT, 56aa37bRow pattern recognition patch (executor and commands).
4707 - state, pos); 56aa37bRow pattern recognition patch (executor and commands).
4708 0 break; 56aa37bRow pattern recognition patch (executor and commands).
4709 - } 56aa37bRow pattern recognition patch (executor and commands).
4710 - 56aa37bRow pattern recognition patch (executor and commands).
4711 - #ifdef RPR_DEBUG 56aa37bRow pattern recognition patch (executor and commands).
4712 - printf("row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT "\n", 56aa37bRow pattern recognition patch (executor and commands).
4713 - rtn, pos); 56aa37bRow pattern recognition patch (executor and commands).
4714 - #endif 56aa37bRow pattern recognition patch (executor and commands).
4715 131458 return rtn; 56aa37bRow pattern recognition patch (executor and commands).
4716 131458 } 56aa37bRow pattern recognition patch (executor and commands).
create_reduced_frame_map() lines 4725-4732
Modified Lines Coverage: 6/6 lines (100.0%)
LineHitsSourceCommit
4725 424 create_reduced_frame_map(WindowAggState *winstate) 56aa37bRow pattern recognition patch (executor and commands).
4726 - { 56aa37bRow pattern recognition patch (executor and commands).
4727 424 winstate->reduced_frame_map = 56aa37bRow pattern recognition patch (executor and commands).
4728 424 MemoryContextAlloc(winstate->partcontext, 56aa37bRow pattern recognition patch (executor and commands).
4729 - REDUCED_FRAME_MAP_INIT_SIZE); 56aa37bRow pattern recognition patch (executor and commands).
4730 424 winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE; 56aa37bRow pattern recognition patch (executor and commands).
4731 424 clear_reduced_frame_map(winstate); 56aa37bRow pattern recognition patch (executor and commands).
4732 424 } 56aa37bRow pattern recognition patch (executor and commands).
clear_reduced_frame_map() lines 4739-4744
Modified Lines Coverage: 4/4 lines (100.0%)
LineHitsSourceCommit
4739 2145 clear_reduced_frame_map(WindowAggState *winstate) 56aa37bRow pattern recognition patch (executor and commands).
4740 - { 56aa37bRow pattern recognition patch (executor and commands).
4741 2145 Assert(winstate->reduced_frame_map != NULL); 56aa37bRow pattern recognition patch (executor and commands).
4742 267105 MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED, 56aa37bRow pattern recognition patch (executor and commands).
4743 - winstate->alloc_sz); 56aa37bRow pattern recognition patch (executor and commands).
4744 2145 } 56aa37bRow pattern recognition patch (executor and commands).
get_reduced_frame_map() lines 4751-4765
Modified Lines Coverage: 7/7 lines (100.0%)
LineHitsSourceCommit
4751 970086 get_reduced_frame_map(WindowAggState *winstate, int64 pos) 56aa37bRow pattern recognition patch (executor and commands).
4752 - { 56aa37bRow pattern recognition patch (executor and commands).
4753 970086 Assert(winstate->reduced_frame_map != NULL); 56aa37bRow pattern recognition patch (executor and commands).
4754 970086 Assert(pos >= 0); 56aa37bRow pattern recognition patch (executor and commands).
4755 - 56aa37bRow pattern recognition patch (executor and commands).
4756 - /* 56aa37bRow pattern recognition patch (executor and commands).
4757 - * If pos is not in the reduced frame map, it means that any info 56aa37bRow pattern recognition patch (executor and commands).
4758 - * regarding the pos has not been registered yet. So we return 56aa37bRow pattern recognition patch (executor and commands).
4759 - * RF_NOT_DETERMINED. 56aa37bRow pattern recognition patch (executor and commands).
4760 - */ 56aa37bRow pattern recognition patch (executor and commands).
4761 970086 if (pos >= winstate->alloc_sz) 56aa37bRow pattern recognition patch (executor and commands).
4762 15 return RF_NOT_DETERMINED; 56aa37bRow pattern recognition patch (executor and commands).
4763 - 56aa37bRow pattern recognition patch (executor and commands).
4764 970071 return winstate->reduced_frame_map[pos]; 56aa37bRow pattern recognition patch (executor and commands).
4765 970086 } 56aa37bRow pattern recognition patch (executor and commands).
register_reduced_frame_map() lines 4773-4796
Modified Lines Coverage: 12/13 lines (92.3%)
LineHitsSourceCommit
4773 124740 register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val) 56aa37bRow pattern recognition patch (executor and commands).
4774 - { 56aa37bRow pattern recognition patch (executor and commands).
4775 124740 int64 realloc_sz; 56aa37bRow pattern recognition patch (executor and commands).
4776 - 56aa37bRow pattern recognition patch (executor and commands).
4777 124740 Assert(winstate->reduced_frame_map != NULL); 56aa37bRow pattern recognition patch (executor and commands).
4778 - 56aa37bRow pattern recognition patch (executor and commands).
4779 124740 if (pos < 0) 56aa37bRow pattern recognition patch (executor and commands).
4780 0 elog(ERROR, "wrong pos: " INT64_FORMAT, pos); 56aa37bRow pattern recognition patch (executor and commands).
4781 - 56aa37bRow pattern recognition patch (executor and commands).
4782 124754 while (pos > winstate->alloc_sz - 1) 56aa37bRow pattern recognition patch (executor and commands).
4783 - { 56aa37bRow pattern recognition patch (executor and commands).
4784 14 realloc_sz = winstate->alloc_sz * 2; 56aa37bRow pattern recognition patch (executor and commands).
4785 - 56aa37bRow pattern recognition patch (executor and commands).
4786 14 winstate->reduced_frame_map = 56aa37bRow pattern recognition patch (executor and commands).
4787 14 repalloc(winstate->reduced_frame_map, realloc_sz); 56aa37bRow pattern recognition patch (executor and commands).
4788 - 56aa37bRow pattern recognition patch (executor and commands).
4789 526 MemSet(winstate->reduced_frame_map + winstate->alloc_sz, 56aa37bRow pattern recognition patch (executor and commands).
4790 - RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz); 56aa37bRow pattern recognition patch (executor and commands).
4791 - 56aa37bRow pattern recognition patch (executor and commands).
4792 14 winstate->alloc_sz = realloc_sz; 56aa37bRow pattern recognition patch (executor and commands).
4793 - } 56aa37bRow pattern recognition patch (executor and commands).
4794 - 56aa37bRow pattern recognition patch (executor and commands).
4795 124740 winstate->reduced_frame_map[pos] = val; 56aa37bRow pattern recognition patch (executor and commands).
4796 124740 } 56aa37bRow pattern recognition patch (executor and commands).
update_reduced_frame() lines 4813-4960
Modified Lines Coverage: 57/57 lines (100.0%)
LineHitsSourceCommit
4813 11709 update_reduced_frame(WindowObject winobj, int64 pos) 56aa37bRow pattern recognition patch (executor and commands).
4814 - { 56aa37bRow pattern recognition patch (executor and commands).
4815 11709 WindowAggState *winstate = winobj->winstate; 56aa37bRow pattern recognition patch (executor and commands).
4816 11709 RPRNFAContext *targetCtx; 56aa37bRow pattern recognition patch (executor and commands).
4817 11709 int64 currentPos; 56aa37bRow pattern recognition patch (executor and commands).
4818 11709 int64 startPos; 56aa37bRow pattern recognition patch (executor and commands).
4819 11709 int frameOptions = winstate->frameOptions; 56aa37bRow pattern recognition patch (executor and commands).
4820 11709 bool hasLimitedFrame; 56aa37bRow pattern recognition patch (executor and commands).
4821 11709 int64 frameOffset = 0; 56aa37bRow pattern recognition patch (executor and commands).
4822 11709 int64 matchLen; 9d2796cReview NFA executor and add comprehensive runtime tests
4823 - 56aa37bRow pattern recognition patch (executor and commands).
4824 - /* 56aa37bRow pattern recognition patch (executor and commands).
4825 - * Check if we have a limited frame (ROWS ... N FOLLOWING). Each context 56aa37bRow pattern recognition patch (executor and commands).
4826 - * needs its own frame end based on matchStartRow + offset. 56aa37bRow pattern recognition patch (executor and commands).
4827 - */ 56aa37bRow pattern recognition patch (executor and commands).
4828 23418 hasLimitedFrame = (frameOptions & FRAMEOPTION_ROWS) && 56aa37bRow pattern recognition patch (executor and commands).
4829 11709 !(frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING); 56aa37bRow pattern recognition patch (executor and commands).
4830 11709 if (hasLimitedFrame && winstate->endOffsetValue != 0) 56aa37bRow pattern recognition patch (executor and commands).
4831 74 frameOffset = DatumGetInt64(winstate->endOffsetValue); 56aa37bRow pattern recognition patch (executor and commands).
4832 - 56aa37bRow pattern recognition patch (executor and commands).
4833 - /* 56aa37bRow pattern recognition patch (executor and commands).
4834 - * Case 1: pos is before any existing context's start position. This means 56aa37bRow pattern recognition patch (executor and commands).
4835 - * the position was already processed and determined unmatched. Head is 56aa37bRow pattern recognition patch (executor and commands).
4836 - * the oldest context (lowest matchStartRow) since contexts are added at 56aa37bRow pattern recognition patch (executor and commands).
4837 - * tail with increasing positions. 56aa37bRow pattern recognition patch (executor and commands).
4838 - */ 56aa37bRow pattern recognition patch (executor and commands).
4839 11709 if (winstate->nfaContext != NULL && 56aa37bRow pattern recognition patch (executor and commands).
4840 11093 pos < winstate->nfaContext->matchStartRow) 56aa37bRow pattern recognition patch (executor and commands).
4841 - { 56aa37bRow pattern recognition patch (executor and commands).
4842 1338 register_reduced_frame_map(winstate, pos, RF_UNMATCHED); 56aa37bRow pattern recognition patch (executor and commands).
4843 1338 return; 56aa37bRow pattern recognition patch (executor and commands).
4844 - } 56aa37bRow pattern recognition patch (executor and commands).
4845 - 56aa37bRow pattern recognition patch (executor and commands).
4846 - /* 56aa37bRow pattern recognition patch (executor and commands).
4847 - * Case 2: Find existing context for this pos, or create new one. 56aa37bRow pattern recognition patch (executor and commands).
4848 - */ 56aa37bRow pattern recognition patch (executor and commands).
4849 10371 targetCtx = nfa_get_head_context(winstate, pos); 9d2796cReview NFA executor and add comprehensive runtime tests
4850 10371 if (targetCtx == NULL) 56aa37bRow pattern recognition patch (executor and commands).
4851 - { 56aa37bRow pattern recognition patch (executor and commands).
4852 - /* 56aa37bRow pattern recognition patch (executor and commands).
4853 - * No context exists. If pos is already processed, it means this row 56aa37bRow pattern recognition patch (executor and commands).
4854 - * was already determined to be unmatched or skipped - no need to 56aa37bRow pattern recognition patch (executor and commands).
4855 - * reprocess. 56aa37bRow pattern recognition patch (executor and commands).
4856 - */ 56aa37bRow pattern recognition patch (executor and commands).
4857 616 if (pos <= winstate->nfaLastProcessedRow) 56aa37bRow pattern recognition patch (executor and commands).
4858 - { 56aa37bRow pattern recognition patch (executor and commands).
4859 195 register_reduced_frame_map(winstate, pos, RF_UNMATCHED); 56aa37bRow pattern recognition patch (executor and commands).
4860 195 return; 56aa37bRow pattern recognition patch (executor and commands).
4861 - } 56aa37bRow pattern recognition patch (executor and commands).
4862 - /* Not yet processed - create new context and start fresh */ 56aa37bRow pattern recognition patch (executor and commands).
4863 421 targetCtx = nfa_start_context(winstate, pos); 56aa37bRow pattern recognition patch (executor and commands).
4864 421 } 56aa37bRow pattern recognition patch (executor and commands).
4865 9755 else if (targetCtx->states == NULL) 56aa37bRow pattern recognition patch (executor and commands).
4866 - { 56aa37bRow pattern recognition patch (executor and commands).
4867 - /* Context already completed - skip to result registration */ 56aa37bRow pattern recognition patch (executor and commands).
4868 138 goto register_result; 56aa37bRow pattern recognition patch (executor and commands).
4869 - } 56aa37bRow pattern recognition patch (executor and commands).
4870 - 56aa37bRow pattern recognition patch (executor and commands).
4871 - /* 56aa37bRow pattern recognition patch (executor and commands).
4872 - * Determine where to start processing. Usually nfaLastProcessedRow+1 >= 56aa37bRow pattern recognition patch (executor and commands).
4873 - * pos since contexts are created at currentPos+1 during processing. 56aa37bRow pattern recognition patch (executor and commands).
4874 - * However, pos can exceed this when rows are skipped (e.g., unmatched 56aa37bRow pattern recognition patch (executor and commands).
4875 - * rows don't update nfaLastProcessedRow). 56aa37bRow pattern recognition patch (executor and commands).
4876 - */ 56aa37bRow pattern recognition patch (executor and commands).
4877 10038 startPos = Max(pos, winstate->nfaLastProcessedRow + 1); 56aa37bRow pattern recognition patch (executor and commands).
4878 - 56aa37bRow pattern recognition patch (executor and commands).
4879 - /* 56aa37bRow pattern recognition patch (executor and commands).
4880 - * Process rows until target context completes or we hit boundaries. Each 56aa37bRow pattern recognition patch (executor and commands).
4881 - * row evaluation is shared across all active contexts. 56aa37bRow pattern recognition patch (executor and commands).
4882 - */ 56aa37bRow pattern recognition patch (executor and commands).
4883 133029 for (currentPos = startPos; targetCtx->states != NULL; currentPos++) 56aa37bRow pattern recognition patch (executor and commands).
4884 - { 56aa37bRow pattern recognition patch (executor and commands).
4885 123209 bool rowExists; 56aa37bRow pattern recognition patch (executor and commands).
4886 - 56aa37bRow pattern recognition patch (executor and commands).
4887 - /* 56aa37bRow pattern recognition patch (executor and commands).
4888 - * Evaluate variables for this row - done only once, shared by all 56aa37bRow pattern recognition patch (executor and commands).
4889 - * contexts 56aa37bRow pattern recognition patch (executor and commands).
4890 - */ 56aa37bRow pattern recognition patch (executor and commands).
4891 123209 rowExists = nfa_evaluate_row(winobj, currentPos, winstate->nfaVarMatched); 56aa37bRow pattern recognition patch (executor and commands).
4892 - 56aa37bRow pattern recognition patch (executor and commands).
4893 - /* No more rows in partition? Finalize all contexts */ 56aa37bRow pattern recognition patch (executor and commands).
4894 123209 if (!rowExists) 56aa37bRow pattern recognition patch (executor and commands).
4895 - { 56aa37bRow pattern recognition patch (executor and commands).
4896 218 nfa_finalize_all_contexts(winstate, currentPos - 1); 56aa37bRow pattern recognition patch (executor and commands).
4897 - /* Clean up dead contexts from finalization */ 56aa37bRow pattern recognition patch (executor and commands).
4898 218 nfa_cleanup_dead_contexts(winstate, targetCtx); 56aa37bRow pattern recognition patch (executor and commands).
4899 - /* Absorb contexts at partition boundary */ 56aa37bRow pattern recognition patch (executor and commands).
4900 218 if (winstate->rpPattern->isAbsorbable) 56aa37bRow pattern recognition patch (executor and commands).
4901 - { 56aa37bRow pattern recognition patch (executor and commands).
4902 115 nfa_absorb_contexts(winstate); 56aa37bRow pattern recognition patch (executor and commands).
4903 115 } 56aa37bRow pattern recognition patch (executor and commands).
4904 218 break; 56aa37bRow pattern recognition patch (executor and commands).
4905 - } 56aa37bRow pattern recognition patch (executor and commands).
4906 - 56aa37bRow pattern recognition patch (executor and commands).
4907 - /* Update last processed row */ 56aa37bRow pattern recognition patch (executor and commands).
4908 122991 winstate->nfaLastProcessedRow = currentPos; 56aa37bRow pattern recognition patch (executor and commands).
4909 - 56aa37bRow pattern recognition patch (executor and commands).
4910 - /*-------------------------- 56aa37bRow pattern recognition patch (executor and commands).
4911 - * Process all contexts for this row: 56aa37bRow pattern recognition patch (executor and commands).
4912 - * 1. Match all (convergence) 56aa37bRow pattern recognition patch (executor and commands).
4913 - * 2. Absorb redundant 56aa37bRow pattern recognition patch (executor and commands).
4914 - * 3. Advance all (divergence) 56aa37bRow pattern recognition patch (executor and commands).
4915 - */ 56aa37bRow pattern recognition patch (executor and commands).
4916 122991 nfa_process_row(winstate, currentPos, hasLimitedFrame, frameOffset); 56aa37bRow pattern recognition patch (executor and commands).
4917 - 56aa37bRow pattern recognition patch (executor and commands).
4918 - /* 56aa37bRow pattern recognition patch (executor and commands).
4919 - * Create a new context for the next potential start position. This 56aa37bRow pattern recognition patch (executor and commands).
4920 - * enables overlapping match detection for SKIP TO NEXT ROW. 56aa37bRow pattern recognition patch (executor and commands).
4921 - */ 56aa37bRow pattern recognition patch (executor and commands).
4922 122991 nfa_start_context(winstate, currentPos + 1); 56aa37bRow pattern recognition patch (executor and commands).
4923 - 56aa37bRow pattern recognition patch (executor and commands).
4924 - /* 56aa37bRow pattern recognition patch (executor and commands).
4925 - * Clean up dead contexts (failed with no active states and no match). 56aa37bRow pattern recognition patch (executor and commands).
4926 - * This removes contexts that failed during processing and counts them 56aa37bRow pattern recognition patch (executor and commands).
4927 - * appropriately as pruned or mismatched. 56aa37bRow pattern recognition patch (executor and commands).
4928 - */ 56aa37bRow pattern recognition patch (executor and commands).
4929 122991 nfa_cleanup_dead_contexts(winstate, targetCtx); 56aa37bRow pattern recognition patch (executor and commands).
4930 133029 } 56aa37bRow pattern recognition patch (executor and commands).
4931 - 56aa37bRow pattern recognition patch (executor and commands).
4932 - register_result: 56aa37bRow pattern recognition patch (executor and commands).
4933 10176 Assert(pos == targetCtx->matchStartRow); 56aa37bRow pattern recognition patch (executor and commands).
4934 - 56aa37bRow pattern recognition patch (executor and commands).
4935 - /* 56aa37bRow pattern recognition patch (executor and commands).
4936 - * Register reduced frame map based on match result. 56aa37bRow pattern recognition patch (executor and commands).
4937 - */ 56aa37bRow pattern recognition patch (executor and commands).
4938 10176 if (targetCtx->matchEndRow < targetCtx->matchStartRow) 56aa37bRow pattern recognition patch (executor and commands).
4939 - { 56aa37bRow pattern recognition patch (executor and commands).
4940 1808 matchLen = targetCtx->lastProcessedRow - targetCtx->matchStartRow + 1; 9d2796cReview NFA executor and add comprehensive runtime tests
4941 - 56aa37bRow pattern recognition patch (executor and commands).
4942 1808 register_reduced_frame_map(winstate, targetCtx->matchStartRow, RF_UNMATCHED); 56aa37bRow pattern recognition patch (executor and commands).
4943 1808 nfa_record_context_failure(winstate, matchLen); 9d2796cReview NFA executor and add comprehensive runtime tests
4944 1808 nfa_context_free(winstate, targetCtx); 9d2796cReview NFA executor and add comprehensive runtime tests
4945 1808 return; 9d2796cReview NFA executor and add comprehensive runtime tests
4946 - } 56aa37bRow pattern recognition patch (executor and commands).
4947 - 56aa37bRow pattern recognition patch (executor and commands).
4948 - /* Match succeeded - register frame map and record statistics */ 9d2796cReview NFA executor and add comprehensive runtime tests
4949 8368 matchLen = targetCtx->matchEndRow - targetCtx->matchStartRow + 1; 9d2796cReview NFA executor and add comprehensive runtime tests
4950 - 56aa37bRow pattern recognition patch (executor and commands).
4951 8368 register_reduced_frame_map(winstate, targetCtx->matchStartRow, RF_FRAME_HEAD); 9d2796cReview NFA executor and add comprehensive runtime tests
4952 121399 for (int64 i = targetCtx->matchStartRow + 1; i <= targetCtx->matchEndRow; i++) 9d2796cReview NFA executor and add comprehensive runtime tests
4953 - { 56aa37bRow pattern recognition patch (executor and commands).
4954 113031 register_reduced_frame_map(winstate, i, RF_SKIPPED); 9d2796cReview NFA executor and add comprehensive runtime tests
4955 113031 } 56aa37bRow pattern recognition patch (executor and commands).
4956 8368 nfa_record_context_success(winstate, matchLen); 9d2796cReview NFA executor and add comprehensive runtime tests
4957 - 9d2796cReview NFA executor and add comprehensive runtime tests
4958 - /* Remove the matched context */ 9d2796cReview NFA executor and add comprehensive runtime tests
4959 8368 nfa_context_free(winstate, targetCtx); 9d2796cReview NFA executor and add comprehensive runtime tests
4960 11709 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_process_row() lines 5055-5120
Modified Lines Coverage: 27/27 lines (100.0%)
LineHitsSourceCommit
5055 122991 nfa_process_row(WindowAggState *winstate, int64 currentPos, 9d2796cReview NFA executor and add comprehensive runtime tests
5056 - bool hasLimitedFrame, int64 frameOffset) 9d2796cReview NFA executor and add comprehensive runtime tests
5057 - { 9d2796cReview NFA executor and add comprehensive runtime tests
5058 122991 RPRNFAContext *ctx; 9d2796cReview NFA executor and add comprehensive runtime tests
5059 122991 bool *varMatched = winstate->nfaVarMatched; 9d2796cReview NFA executor and add comprehensive runtime tests
5060 - 9d2796cReview NFA executor and add comprehensive runtime tests
5061 - /* 9d2796cReview NFA executor and add comprehensive runtime tests
5062 - * Phase 1: Match all contexts (convergence) Evaluate VAR elements, update 9d2796cReview NFA executor and add comprehensive runtime tests
5063 - * counts, remove dead states. 9d2796cReview NFA executor and add comprehensive runtime tests
5064 - */ 9d2796cReview NFA executor and add comprehensive runtime tests
5065 367291 for (ctx = winstate->nfaContext; ctx != NULL; ctx = ctx->next) 9d2796cReview NFA executor and add comprehensive runtime tests
5066 - { 9d2796cReview NFA executor and add comprehensive runtime tests
5067 244300 if (ctx->states == NULL) 9d2796cReview NFA executor and add comprehensive runtime tests
5068 5 continue; 9d2796cReview NFA executor and add comprehensive runtime tests
5069 - 9d2796cReview NFA executor and add comprehensive runtime tests
5070 - /* Check frame boundary - finalize if exceeded */ 9d2796cReview NFA executor and add comprehensive runtime tests
5071 244295 if (hasLimitedFrame) 9d2796cReview NFA executor and add comprehensive runtime tests
5072 - { 9d2796cReview NFA executor and add comprehensive runtime tests
5073 276 int64 ctxFrameEnd = ctx->matchStartRow + frameOffset + 1; 9d2796cReview NFA executor and add comprehensive runtime tests
5074 - 9d2796cReview NFA executor and add comprehensive runtime tests
5075 276 if (currentPos >= ctxFrameEnd) 9d2796cReview NFA executor and add comprehensive runtime tests
5076 - { 9d2796cReview NFA executor and add comprehensive runtime tests
5077 - /* Frame boundary exceeded: force mismatch */ 9d2796cReview NFA executor and add comprehensive runtime tests
5078 10 nfa_match(winstate, ctx, NULL); 9d2796cReview NFA executor and add comprehensive runtime tests
5079 10 continue; 9d2796cReview NFA executor and add comprehensive runtime tests
5080 - } 9d2796cReview NFA executor and add comprehensive runtime tests
5081 276 } 9d2796cReview NFA executor and add comprehensive runtime tests
5082 - 9d2796cReview NFA executor and add comprehensive runtime tests
5083 244285 nfa_match(winstate, ctx, varMatched); 9d2796cReview NFA executor and add comprehensive runtime tests
5084 244285 ctx->lastProcessedRow = currentPos; 9d2796cReview NFA executor and add comprehensive runtime tests
5085 244285 } 9d2796cReview NFA executor and add comprehensive runtime tests
5086 - 9d2796cReview NFA executor and add comprehensive runtime tests
5087 - /* 9d2796cReview NFA executor and add comprehensive runtime tests
5088 - * Phase 2: Absorb redundant contexts After match phase, states have 9d2796cReview NFA executor and add comprehensive runtime tests
5089 - * converged - ideal for absorption. First update absorption flags that 9d2796cReview NFA executor and add comprehensive runtime tests
5090 - * may have changed due to state removal. 9d2796cReview NFA executor and add comprehensive runtime tests
5091 - */ 9d2796cReview NFA executor and add comprehensive runtime tests
5092 122991 if (winstate->rpPattern->isAbsorbable) 9d2796cReview NFA executor and add comprehensive runtime tests
5093 - { 9d2796cReview NFA executor and add comprehensive runtime tests
5094 327213 for (ctx = winstate->nfaContext; ctx != NULL; ctx = ctx->next) 9d2796cReview NFA executor and add comprehensive runtime tests
5095 217913 nfa_update_absorption_flags(ctx); 9d2796cReview NFA executor and add comprehensive runtime tests
5096 - 9d2796cReview NFA executor and add comprehensive runtime tests
5097 109300 nfa_absorb_contexts(winstate); 9d2796cReview NFA executor and add comprehensive runtime tests
5098 109300 } 9d2796cReview NFA executor and add comprehensive runtime tests
5099 - 9d2796cReview NFA executor and add comprehensive runtime tests
5100 - /* 9d2796cReview NFA executor and add comprehensive runtime tests
5101 - * Phase 3: Advance all contexts (divergence) Create new states 9d2796cReview NFA executor and add comprehensive runtime tests
5102 - * (loop/exit) from surviving matched states. 9d2796cReview NFA executor and add comprehensive runtime tests
5103 - */ 9d2796cReview NFA executor and add comprehensive runtime tests
5104 299690 for (ctx = winstate->nfaContext; ctx != NULL; ctx = ctx->next) 9d2796cReview NFA executor and add comprehensive runtime tests
5105 - { 9d2796cReview NFA executor and add comprehensive runtime tests
5106 176699 if (ctx->states == NULL) 9d2796cReview NFA executor and add comprehensive runtime tests
5107 47394 continue; 9d2796cReview NFA executor and add comprehensive runtime tests
5108 - 9d2796cReview NFA executor and add comprehensive runtime tests
5109 - /* 9d2796cReview NFA executor and add comprehensive runtime tests
5110 - * Phase 1 already handled frame boundary exceeded contexts by forcing 9d2796cReview NFA executor and add comprehensive runtime tests
5111 - * mismatch (nfa_match with NULL), which removes all states (all 74205caRun pgindent on RPR source files
5112 - * states are at VAR positions after advance). So any surviving 74205caRun pgindent on RPR source files
5113 - * context here must be within its frame boundary. 74205caRun pgindent on RPR source files
5114 - */ 9d2796cReview NFA executor and add comprehensive runtime tests
5115 129305 Assert(!hasLimitedFrame || 9d2796cReview NFA executor and add comprehensive runtime tests
5116 - currentPos < ctx->matchStartRow + frameOffset + 1); 9d2796cReview NFA executor and add comprehensive runtime tests
5117 - 9d2796cReview NFA executor and add comprehensive runtime tests
5118 129305 nfa_advance(winstate, ctx, currentPos, false); 9d2796cReview NFA executor and add comprehensive runtime tests
5119 129305 } 9d2796cReview NFA executor and add comprehensive runtime tests
5120 122991 } 9d2796cReview NFA executor and add comprehensive runtime tests
nfa_state_alloc() lines 5130-5156
Modified Lines Coverage: 14/14 lines (100.0%)
LineHitsSourceCommit
5130 265885 nfa_state_alloc(WindowAggState *winstate) 56aa37bRow pattern recognition patch (executor and commands).
5131 - { 56aa37bRow pattern recognition patch (executor and commands).
5132 265885 RPRNFAState *state; 56aa37bRow pattern recognition patch (executor and commands).
5133 - 56aa37bRow pattern recognition patch (executor and commands).
5134 - /* Try to reuse from free list first */ 56aa37bRow pattern recognition patch (executor and commands).
5135 265885 if (winstate->nfaStateFree != NULL) 56aa37bRow pattern recognition patch (executor and commands).
5136 - { 56aa37bRow pattern recognition patch (executor and commands).
5137 263772 state = winstate->nfaStateFree; 56aa37bRow pattern recognition patch (executor and commands).
5138 263772 winstate->nfaStateFree = state->next; 56aa37bRow pattern recognition patch (executor and commands).
5139 263772 } 56aa37bRow pattern recognition patch (executor and commands).
5140 - else 56aa37bRow pattern recognition patch (executor and commands).
5141 - { 56aa37bRow pattern recognition patch (executor and commands).
5142 - /* Allocate in partition context for proper lifetime */ 56aa37bRow pattern recognition patch (executor and commands).
5143 2113 state = MemoryContextAlloc(winstate->partcontext, winstate->nfaStateSize); 56aa37bRow pattern recognition patch (executor and commands).
5144 - } 56aa37bRow pattern recognition patch (executor and commands).
5145 - 56aa37bRow pattern recognition patch (executor and commands).
5146 - /* Initialize entire state to zero */ 56aa37bRow pattern recognition patch (executor and commands).
5147 265885 memset(state, 0, winstate->nfaStateSize); 56aa37bRow pattern recognition patch (executor and commands).
5148 - 56aa37bRow pattern recognition patch (executor and commands).
5149 - /* Update statistics */ 56aa37bRow pattern recognition patch (executor and commands).
5150 265885 winstate->nfaStatesActive++; 56aa37bRow pattern recognition patch (executor and commands).
5151 265885 winstate->nfaStatesTotalCreated++; 56aa37bRow pattern recognition patch (executor and commands).
5152 265885 if (winstate->nfaStatesActive > winstate->nfaStatesMax) 56aa37bRow pattern recognition patch (executor and commands).
5153 1929 winstate->nfaStatesMax = winstate->nfaStatesActive; 56aa37bRow pattern recognition patch (executor and commands).
5154 - 56aa37bRow pattern recognition patch (executor and commands).
5155 531770 return state; 56aa37bRow pattern recognition patch (executor and commands).
5156 265885 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_state_free() lines 5164-5169
Modified Lines Coverage: 5/5 lines (100.0%)
LineHitsSourceCommit
5164 265621 nfa_state_free(WindowAggState *winstate, RPRNFAState *state) 56aa37bRow pattern recognition patch (executor and commands).
5165 - { 56aa37bRow pattern recognition patch (executor and commands).
5166 265621 winstate->nfaStatesActive--; 56aa37bRow pattern recognition patch (executor and commands).
5167 265621 state->next = winstate->nfaStateFree; 56aa37bRow pattern recognition patch (executor and commands).
5168 265621 winstate->nfaStateFree = state; 56aa37bRow pattern recognition patch (executor and commands).
5169 265621 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_state_free_list() lines 5177-5186
Modified Lines Coverage: 7/7 lines (100.0%)
LineHitsSourceCommit
5177 42322 nfa_state_free_list(WindowAggState *winstate, RPRNFAState *list) 56aa37bRow pattern recognition patch (executor and commands).
5178 - { 56aa37bRow pattern recognition patch (executor and commands).
5179 42322 RPRNFAState *next; 9d2796cReview NFA executor and add comprehensive runtime tests
5180 - 56aa37bRow pattern recognition patch (executor and commands).
5181 84659 for (; list != NULL; list = next) 9d2796cReview NFA executor and add comprehensive runtime tests
5182 - { 56aa37bRow pattern recognition patch (executor and commands).
5183 42337 next = list->next; 9d2796cReview NFA executor and add comprehensive runtime tests
5184 42337 nfa_state_free(winstate, list); 9d2796cReview NFA executor and add comprehensive runtime tests
5185 42337 } 56aa37bRow pattern recognition patch (executor and commands).
5186 42322 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_state_create() lines 5198-5219
Modified Lines Coverage: 12/12 lines (100.0%)
LineHitsSourceCommit
5198 142473 nfa_state_create(WindowAggState *winstate, int16 elemIdx, int16 altPriority, 9d2796cReview NFA executor and add comprehensive runtime tests
5199 - int32 *counts, bool sourceAbsorbable) 9d2796cReview NFA executor and add comprehensive runtime tests
5200 - { 56aa37bRow pattern recognition patch (executor and commands).
5201 142473 RPRPattern *pattern = winstate->rpPattern; 56aa37bRow pattern recognition patch (executor and commands).
5202 142473 int maxDepth = pattern->maxDepth; 56aa37bRow pattern recognition patch (executor and commands).
5203 142473 RPRNFAState *state = nfa_state_alloc(winstate); 56aa37bRow pattern recognition patch (executor and commands).
5204 142473 RPRPatternElement *elem = &pattern->elements[elemIdx]; 56aa37bRow pattern recognition patch (executor and commands).
5205 - 56aa37bRow pattern recognition patch (executor and commands).
5206 142473 state->elemIdx = elemIdx; 56aa37bRow pattern recognition patch (executor and commands).
5207 142473 state->altPriority = altPriority; 56aa37bRow pattern recognition patch (executor and commands).
5208 142473 if (counts != NULL && maxDepth > 0) 56aa37bRow pattern recognition patch (executor and commands).
5209 142473 memcpy(state->counts, counts, sizeof(int32) * maxDepth); 56aa37bRow pattern recognition patch (executor and commands).
5210 - 56aa37bRow pattern recognition patch (executor and commands).
5211 - /* 56aa37bRow pattern recognition patch (executor and commands).
5212 - * Compute isAbsorbable immediately at transition time. isAbsorbable = 56aa37bRow pattern recognition patch (executor and commands).
5213 - * sourceAbsorbable && (elem->flags & ABSORBABLE_BRANCH) Monotonic: once 56aa37bRow pattern recognition patch (executor and commands).
5214 - * false, stays false (can't re-enter absorbable region). 56aa37bRow pattern recognition patch (executor and commands).
5215 - */ 56aa37bRow pattern recognition patch (executor and commands).
5216 142473 state->isAbsorbable = sourceAbsorbable && RPRElemIsAbsorbableBranch(elem); 56aa37bRow pattern recognition patch (executor and commands).
5217 - 56aa37bRow pattern recognition patch (executor and commands).
5218 284946 return state; 56aa37bRow pattern recognition patch (executor and commands).
5219 142473 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_states_equal() lines 5227-5245
Modified Lines Coverage: 13/13 lines (100.0%)
LineHitsSourceCommit
5227 148510 nfa_states_equal(WindowAggState *winstate, RPRNFAState *s1, RPRNFAState *s2) 56aa37bRow pattern recognition patch (executor and commands).
5228 - { 56aa37bRow pattern recognition patch (executor and commands).
5229 148510 RPRPattern *pattern = winstate->rpPattern; 9d2796cReview NFA executor and add comprehensive runtime tests
5230 148510 RPRPatternElement *elem; 9d2796cReview NFA executor and add comprehensive runtime tests
5231 148510 int compareDepth; 9d2796cReview NFA executor and add comprehensive runtime tests
5232 - 56aa37bRow pattern recognition patch (executor and commands).
5233 148510 if (s1->elemIdx != s2->elemIdx) 56aa37bRow pattern recognition patch (executor and commands).
5234 148008 return false; 56aa37bRow pattern recognition patch (executor and commands).
5235 - 56aa37bRow pattern recognition patch (executor and commands).
5236 - /* Compare counts up to current element's depth */ 9d2796cReview NFA executor and add comprehensive runtime tests
5237 502 elem = &pattern->elements[s1->elemIdx]; 9d2796cReview NFA executor and add comprehensive runtime tests
5238 502 compareDepth = elem->depth + 1; /* depth 0 needs 1 count, etc. */ 74205caRun pgindent on RPR source files
5239 - 9d2796cReview NFA executor and add comprehensive runtime tests
5240 502 if (compareDepth > 0 && 9d2796cReview NFA executor and add comprehensive runtime tests
5241 502 memcmp(s1->counts, s2->counts, sizeof(int32) * compareDepth) != 0) 9d2796cReview NFA executor and add comprehensive runtime tests
5242 440 return false; 56aa37bRow pattern recognition patch (executor and commands).
5243 - 56aa37bRow pattern recognition patch (executor and commands).
5244 62 return true; 56aa37bRow pattern recognition patch (executor and commands).
5245 148510 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_add_state_unique() lines 5255-5284
Modified Lines Coverage: 16/16 lines (100.0%)
LineHitsSourceCommit
5255 357038 nfa_add_state_unique(WindowAggState *winstate, RPRNFAContext *ctx, RPRNFAState *state) 56aa37bRow pattern recognition patch (executor and commands).
5256 - { 56aa37bRow pattern recognition patch (executor and commands).
5257 357038 RPRNFAState *s; 56aa37bRow pattern recognition patch (executor and commands).
5258 357038 RPRNFAState *tail = NULL; 56aa37bRow pattern recognition patch (executor and commands).
5259 - 56aa37bRow pattern recognition patch (executor and commands).
5260 - /* Check for duplicate and find tail */ 56aa37bRow pattern recognition patch (executor and commands).
5261 505486 for (s = ctx->states; s != NULL; s = s->next) 56aa37bRow pattern recognition patch (executor and commands).
5262 - { 56aa37bRow pattern recognition patch (executor and commands).
5263 148510 if (nfa_states_equal(winstate, s, state)) 56aa37bRow pattern recognition patch (executor and commands).
5264 - { 56aa37bRow pattern recognition patch (executor and commands).
5265 - /* 56aa37bRow pattern recognition patch (executor and commands).
5266 - * Duplicate found - existing has better lexical order, discard 56aa37bRow pattern recognition patch (executor and commands).
5267 - * new 56aa37bRow pattern recognition patch (executor and commands).
5268 - */ 56aa37bRow pattern recognition patch (executor and commands).
5269 62 nfa_state_free(winstate, state); 56aa37bRow pattern recognition patch (executor and commands).
5270 62 winstate->nfaStatesMerged++; 56aa37bRow pattern recognition patch (executor and commands).
5271 62 return false; 56aa37bRow pattern recognition patch (executor and commands).
5272 - } 56aa37bRow pattern recognition patch (executor and commands).
5273 148448 tail = s; 56aa37bRow pattern recognition patch (executor and commands).
5274 148448 } 56aa37bRow pattern recognition patch (executor and commands).
5275 - 56aa37bRow pattern recognition patch (executor and commands).
5276 - /* No duplicate, add at end */ 56aa37bRow pattern recognition patch (executor and commands).
5277 356976 state->next = NULL; 56aa37bRow pattern recognition patch (executor and commands).
5278 356976 if (tail == NULL) 56aa37bRow pattern recognition patch (executor and commands).
5279 245137 ctx->states = state; 56aa37bRow pattern recognition patch (executor and commands).
5280 - else 56aa37bRow pattern recognition patch (executor and commands).
5281 111839 tail->next = state; 56aa37bRow pattern recognition patch (executor and commands).
5282 - 56aa37bRow pattern recognition patch (executor and commands).
5283 356976 return true; 56aa37bRow pattern recognition patch (executor and commands).
5284 357038 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_add_matched_state() lines 5307-5380
Modified Lines Coverage: 32/32 lines (100.0%)
LineHitsSourceCommit
5307 38090 nfa_add_matched_state(WindowAggState *winstate, RPRNFAContext *ctx, 56aa37bRow pattern recognition patch (executor and commands).
5308 - RPRNFAState *state, int64 matchEndRow) 56aa37bRow pattern recognition patch (executor and commands).
5309 - { 56aa37bRow pattern recognition patch (executor and commands).
5310 38090 bool shouldUpdate = false; 56aa37bRow pattern recognition patch (executor and commands).
5311 - 56aa37bRow pattern recognition patch (executor and commands).
5312 38090 if (ctx->matchedState == NULL) 56aa37bRow pattern recognition patch (executor and commands).
5313 8369 shouldUpdate = true; 56aa37bRow pattern recognition patch (executor and commands).
5314 29721 else if (state->altPriority < ctx->matchedState->altPriority) 56aa37bRow pattern recognition patch (executor and commands).
5315 3 shouldUpdate = true; /* Better lexical order wins */ 56aa37bRow pattern recognition patch (executor and commands).
5316 29718 else if (state->altPriority == ctx->matchedState->altPriority && 56aa37bRow pattern recognition patch (executor and commands).
5317 29716 matchEndRow > ctx->matchEndRow) 56aa37bRow pattern recognition patch (executor and commands).
5318 29631 shouldUpdate = true; /* Same lexical order, longer wins */ 56aa37bRow pattern recognition patch (executor and commands).
5319 - 56aa37bRow pattern recognition patch (executor and commands).
5320 38090 if (shouldUpdate) 56aa37bRow pattern recognition patch (executor and commands).
5321 - { 56aa37bRow pattern recognition patch (executor and commands).
5322 - /* Free old matchedState if exists */ 56aa37bRow pattern recognition patch (executor and commands).
5323 38003 if (ctx->matchedState != NULL) 56aa37bRow pattern recognition patch (executor and commands).
5324 29634 nfa_state_free(winstate, ctx->matchedState); 56aa37bRow pattern recognition patch (executor and commands).
5325 - 56aa37bRow pattern recognition patch (executor and commands).
5326 - /* Take ownership of the new state */ 56aa37bRow pattern recognition patch (executor and commands).
5327 38003 ctx->matchedState = state; 56aa37bRow pattern recognition patch (executor and commands).
5328 38003 state->next = NULL; 56aa37bRow pattern recognition patch (executor and commands).
5329 38003 ctx->matchEndRow = matchEndRow; 56aa37bRow pattern recognition patch (executor and commands).
5330 - 9d2796cReview NFA executor and add comprehensive runtime tests
5331 - /*---------- 74205caRun pgindent on RPR source files
5332 - * SKIP PAST LAST ROW: eagerly prune contexts within match range. 9d2796cReview NFA executor and add comprehensive runtime tests
5333 - * 9d2796cReview NFA executor and add comprehensive runtime tests
5334 - * This function is called whenever a FIN state is reached, including 9d2796cReview NFA executor and add comprehensive runtime tests
5335 - * during greedy matching when intermediate (shorter) matches are 74205caRun pgindent on RPR source files
5336 - * found. Each time we update matchEndRow (whether extending a greedy 74205caRun pgindent on RPR source files
5337 - * match or finding a new match), we can prune pending contexts that 74205caRun pgindent on RPR source files
5338 - * started within the current match range. 74205caRun pgindent on RPR source files
5339 - * 9d2796cReview NFA executor and add comprehensive runtime tests
5340 - * SKIP PAST LAST ROW uses lexical order (matchStartRow). Therefore, 9d2796cReview NFA executor and add comprehensive runtime tests
5341 - * any pending context that started at or before matchEndRow can never 9d2796cReview NFA executor and add comprehensive runtime tests
5342 - * produce a valid output row - it would be skipped anyway per SQL 9d2796cReview NFA executor and add comprehensive runtime tests
5343 - * standard. 9d2796cReview NFA executor and add comprehensive runtime tests
5344 - * 9d2796cReview NFA executor and add comprehensive runtime tests
5345 - * Example (greedy matching in progress): 9d2796cReview NFA executor and add comprehensive runtime tests
5346 - * Pattern: START UP+ 9d2796cReview NFA executor and add comprehensive runtime tests
5347 - * Rows: 1 2 3 4 5 9d2796cReview NFA executor and add comprehensive runtime tests
5348 - * Context A starts at row 1: 9d2796cReview NFA executor and add comprehensive runtime tests
5349 - * - Matches START UP (rows 1-2) → matchEndRow=2 → prune Context B(row 2) 9d2796cReview NFA executor and add comprehensive runtime tests
5350 - * - Matches START UP UP (rows 1-3) → matchEndRow=3 → prune Context C(row 3) 9d2796cReview NFA executor and add comprehensive runtime tests
5351 - * - Continues greedy extension while pruning incrementally 9d2796cReview NFA executor and add comprehensive runtime tests
5352 - *---------- 74205caRun pgindent on RPR source files
5353 - */ 9d2796cReview NFA executor and add comprehensive runtime tests
5354 38003 if (winstate->rpSkipTo == ST_PAST_LAST_ROW) 9d2796cReview NFA executor and add comprehensive runtime tests
5355 - { 9d2796cReview NFA executor and add comprehensive runtime tests
5356 37036 RPRNFAContext *nextCtx; 9d2796cReview NFA executor and add comprehensive runtime tests
5357 37036 int64 skippedLen; 9d2796cReview NFA executor and add comprehensive runtime tests
5358 - 9d2796cReview NFA executor and add comprehensive runtime tests
5359 90114 while (ctx->next != NULL && 9d2796cReview NFA executor and add comprehensive runtime tests
5360 26539 ctx->next->matchStartRow <= matchEndRow) 9d2796cReview NFA executor and add comprehensive runtime tests
5361 - { 9d2796cReview NFA executor and add comprehensive runtime tests
5362 26539 nextCtx = ctx->next; 9d2796cReview NFA executor and add comprehensive runtime tests
5363 26539 ctx->next = ctx->next->next; 9d2796cReview NFA executor and add comprehensive runtime tests
5364 - 9d2796cReview NFA executor and add comprehensive runtime tests
5365 26539 Assert(nextCtx->lastProcessedRow >= nextCtx->matchStartRow); 9d2796cReview NFA executor and add comprehensive runtime tests
5366 26539 skippedLen = nextCtx->lastProcessedRow - nextCtx->matchStartRow + 1; 9d2796cReview NFA executor and add comprehensive runtime tests
5367 26539 nfa_record_context_skipped(winstate, skippedLen); 9d2796cReview NFA executor and add comprehensive runtime tests
5368 - 9d2796cReview NFA executor and add comprehensive runtime tests
5369 26539 nfa_context_free(winstate, nextCtx); 9d2796cReview NFA executor and add comprehensive runtime tests
5370 - } 9d2796cReview NFA executor and add comprehensive runtime tests
5371 37036 if (ctx->next == NULL) 9d2796cReview NFA executor and add comprehensive runtime tests
5372 37036 winstate->nfaContextTail = ctx; 9d2796cReview NFA executor and add comprehensive runtime tests
5373 37036 } 9d2796cReview NFA executor and add comprehensive runtime tests
5374 38003 } 56aa37bRow pattern recognition patch (executor and commands).
5375 - else 56aa37bRow pattern recognition patch (executor and commands).
5376 - { 56aa37bRow pattern recognition patch (executor and commands).
5377 - /* This state didn't win, free it */ 56aa37bRow pattern recognition patch (executor and commands).
5378 87 nfa_state_free(winstate, state); 56aa37bRow pattern recognition patch (executor and commands).
5379 - } 56aa37bRow pattern recognition patch (executor and commands).
5380 38090 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_context_alloc() lines 5388-5423
Modified Lines Coverage: 24/24 lines (100.0%)
LineHitsSourceCommit
5388 123412 nfa_context_alloc(WindowAggState *winstate) 56aa37bRow pattern recognition patch (executor and commands).
5389 - { 56aa37bRow pattern recognition patch (executor and commands).
5390 123412 RPRNFAContext *ctx; 56aa37bRow pattern recognition patch (executor and commands).
5391 - 56aa37bRow pattern recognition patch (executor and commands).
5392 123412 if (winstate->nfaContextFree != NULL) 56aa37bRow pattern recognition patch (executor and commands).
5393 - { 56aa37bRow pattern recognition patch (executor and commands).
5394 121948 ctx = winstate->nfaContextFree; 56aa37bRow pattern recognition patch (executor and commands).
5395 121948 winstate->nfaContextFree = ctx->next; 56aa37bRow pattern recognition patch (executor and commands).
5396 121948 } 56aa37bRow pattern recognition patch (executor and commands).
5397 - else 56aa37bRow pattern recognition patch (executor and commands).
5398 - { 56aa37bRow pattern recognition patch (executor and commands).
5399 - /* Allocate in partition context for proper lifetime */ 56aa37bRow pattern recognition patch (executor and commands).
5400 1464 ctx = MemoryContextAlloc(winstate->partcontext, sizeof(RPRNFAContext)); 56aa37bRow pattern recognition patch (executor and commands).
5401 - } 56aa37bRow pattern recognition patch (executor and commands).
5402 - 56aa37bRow pattern recognition patch (executor and commands).
5403 123412 ctx->next = NULL; 56aa37bRow pattern recognition patch (executor and commands).
5404 123412 ctx->prev = NULL; 56aa37bRow pattern recognition patch (executor and commands).
5405 123412 ctx->states = NULL; 56aa37bRow pattern recognition patch (executor and commands).
5406 123412 ctx->matchStartRow = -1; 56aa37bRow pattern recognition patch (executor and commands).
5407 123412 ctx->matchEndRow = -1; 56aa37bRow pattern recognition patch (executor and commands).
5408 123412 ctx->lastProcessedRow = -1; 56aa37bRow pattern recognition patch (executor and commands).
5409 123412 ctx->matchedState = NULL; 56aa37bRow pattern recognition patch (executor and commands).
5410 - /* Initialize two-flag absorption design based on pattern */ 56aa37bRow pattern recognition patch (executor and commands).
5411 246824 ctx->hasAbsorbableState = (winstate->rpPattern != NULL && 56aa37bRow pattern recognition patch (executor and commands).
5412 123412 winstate->rpPattern->isAbsorbable); 56aa37bRow pattern recognition patch (executor and commands).
5413 246824 ctx->allStatesAbsorbable = (winstate->rpPattern != NULL && 56aa37bRow pattern recognition patch (executor and commands).
5414 123412 winstate->rpPattern->isAbsorbable); 56aa37bRow pattern recognition patch (executor and commands).
5415 - 56aa37bRow pattern recognition patch (executor and commands).
5416 - /* Update statistics */ 56aa37bRow pattern recognition patch (executor and commands).
5417 123412 winstate->nfaContextsActive++; 56aa37bRow pattern recognition patch (executor and commands).
5418 123412 winstate->nfaContextsTotalCreated++; 56aa37bRow pattern recognition patch (executor and commands).
5419 123412 if (winstate->nfaContextsActive > winstate->nfaContextsMax) 56aa37bRow pattern recognition patch (executor and commands).
5420 1338 winstate->nfaContextsMax = winstate->nfaContextsActive; 56aa37bRow pattern recognition patch (executor and commands).
5421 - 56aa37bRow pattern recognition patch (executor and commands).
5422 246824 return ctx; 56aa37bRow pattern recognition patch (executor and commands).
5423 123412 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_unlink_context() lines 5432-5446
Modified Lines Coverage: 10/10 lines (100.0%)
LineHitsSourceCommit
5432 123209 nfa_unlink_context(WindowAggState *winstate, RPRNFAContext *ctx) 56aa37bRow pattern recognition patch (executor and commands).
5433 - { 56aa37bRow pattern recognition patch (executor and commands).
5434 123209 if (ctx->prev != NULL) 56aa37bRow pattern recognition patch (executor and commands).
5435 113033 ctx->prev->next = ctx->next; 56aa37bRow pattern recognition patch (executor and commands).
5436 - else 56aa37bRow pattern recognition patch (executor and commands).
5437 10176 winstate->nfaContext = ctx->next; /* was head */ 56aa37bRow pattern recognition patch (executor and commands).
5438 - 56aa37bRow pattern recognition patch (executor and commands).
5439 123209 if (ctx->next != NULL) 56aa37bRow pattern recognition patch (executor and commands).
5440 55931 ctx->next->prev = ctx->prev; 56aa37bRow pattern recognition patch (executor and commands).
5441 - else 56aa37bRow pattern recognition patch (executor and commands).
5442 67278 winstate->nfaContextTail = ctx->prev; /* was tail */ 56aa37bRow pattern recognition patch (executor and commands).
5443 - 56aa37bRow pattern recognition patch (executor and commands).
5444 123209 ctx->next = NULL; 56aa37bRow pattern recognition patch (executor and commands).
5445 123209 ctx->prev = NULL; 56aa37bRow pattern recognition patch (executor and commands).
5446 123209 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_context_free() lines 5455-5472
Modified Lines Coverage: 12/12 lines (100.0%)
LineHitsSourceCommit
5455 123209 nfa_context_free(WindowAggState *winstate, RPRNFAContext *ctx) 56aa37bRow pattern recognition patch (executor and commands).
5456 - { 56aa37bRow pattern recognition patch (executor and commands).
5457 - /* Unlink from active list first */ 56aa37bRow pattern recognition patch (executor and commands).
5458 123209 nfa_unlink_context(winstate, ctx); 56aa37bRow pattern recognition patch (executor and commands).
5459 - 56aa37bRow pattern recognition patch (executor and commands).
5460 - /* Update statistics */ 56aa37bRow pattern recognition patch (executor and commands).
5461 123209 winstate->nfaContextsActive--; 56aa37bRow pattern recognition patch (executor and commands).
5462 - 56aa37bRow pattern recognition patch (executor and commands).
5463 123209 if (ctx->states != NULL) 56aa37bRow pattern recognition patch (executor and commands).
5464 42322 nfa_state_free_list(winstate, ctx->states); 56aa37bRow pattern recognition patch (executor and commands).
5465 123209 if (ctx->matchedState != NULL) 56aa37bRow pattern recognition patch (executor and commands).
5466 8369 nfa_state_free(winstate, ctx->matchedState); 56aa37bRow pattern recognition patch (executor and commands).
5467 - 56aa37bRow pattern recognition patch (executor and commands).
5468 123209 ctx->states = NULL; 56aa37bRow pattern recognition patch (executor and commands).
5469 123209 ctx->matchedState = NULL; 56aa37bRow pattern recognition patch (executor and commands).
5470 123209 ctx->next = winstate->nfaContextFree; 56aa37bRow pattern recognition patch (executor and commands).
5471 123209 winstate->nfaContextFree = ctx; 56aa37bRow pattern recognition patch (executor and commands).
5472 123209 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_start_context() lines 5483-5543
Modified Lines Coverage: 26/26 lines (100.0%)
LineHitsSourceCommit
5483 123412 nfa_start_context(WindowAggState *winstate, int64 startPos) 56aa37bRow pattern recognition patch (executor and commands).
5484 - { 56aa37bRow pattern recognition patch (executor and commands).
5485 123412 RPRNFAContext *ctx; 56aa37bRow pattern recognition patch (executor and commands).
5486 123412 RPRPattern *pattern = winstate->rpPattern; 56aa37bRow pattern recognition patch (executor and commands).
5487 - 56aa37bRow pattern recognition patch (executor and commands).
5488 123412 ctx = nfa_context_alloc(winstate); 56aa37bRow pattern recognition patch (executor and commands).
5489 123412 ctx->matchStartRow = startPos; 56aa37bRow pattern recognition patch (executor and commands).
5490 123412 ctx->states = nfa_state_alloc(winstate); /* initial state at elem 0 */ 56aa37bRow pattern recognition patch (executor and commands).
5491 - 56aa37bRow pattern recognition patch (executor and commands).
5492 - /*-------------------------- 56aa37bRow pattern recognition patch (executor and commands).
5493 - * Initialize two-flag absorption design: 56aa37bRow pattern recognition patch (executor and commands).
5494 - * hasAbsorbableState: can this context absorb others? (>= 1 absorbable state) 56aa37bRow pattern recognition patch (executor and commands).
5495 - * allStatesAbsorbable: can this context be absorbed? (ALL states absorbable) 56aa37bRow pattern recognition patch (executor and commands).
5496 - * Both initialized from pattern->isAbsorbable at context start. 56aa37bRow pattern recognition patch (executor and commands).
5497 - */ 56aa37bRow pattern recognition patch (executor and commands).
5498 123412 ctx->hasAbsorbableState = (pattern != NULL && pattern->isAbsorbable); 56aa37bRow pattern recognition patch (executor and commands).
5499 123412 ctx->allStatesAbsorbable = (pattern != NULL && pattern->isAbsorbable); 56aa37bRow pattern recognition patch (executor and commands).
5500 - 56aa37bRow pattern recognition patch (executor and commands).
5501 123412 if (ctx->states != NULL && pattern != NULL && pattern->numElements > 0) 56aa37bRow pattern recognition patch (executor and commands).
5502 - { 56aa37bRow pattern recognition patch (executor and commands).
5503 123412 RPRPatternElement *elem = &pattern->elements[0]; 56aa37bRow pattern recognition patch (executor and commands).
5504 - 56aa37bRow pattern recognition patch (executor and commands).
5505 - /* 56aa37bRow pattern recognition patch (executor and commands).
5506 - * Initial state at element 0. Check if element 0 is in absorbable 56aa37bRow pattern recognition patch (executor and commands).
5507 - * branch. 56aa37bRow pattern recognition patch (executor and commands).
5508 - */ 56aa37bRow pattern recognition patch (executor and commands).
5509 123412 if (RPRElemIsAbsorbableBranch(elem)) 56aa37bRow pattern recognition patch (executor and commands).
5510 - { 56aa37bRow pattern recognition patch (executor and commands).
5511 - /* Element 0 is in absorbable branch - flags stay true */ 56aa37bRow pattern recognition patch (executor and commands).
5512 109466 ctx->states->isAbsorbable = true; 56aa37bRow pattern recognition patch (executor and commands).
5513 109466 } 56aa37bRow pattern recognition patch (executor and commands).
5514 - else 56aa37bRow pattern recognition patch (executor and commands).
5515 - { 56aa37bRow pattern recognition patch (executor and commands).
5516 - /* Element 0 is NOT in absorbable branch - turn flags OFF */ 56aa37bRow pattern recognition patch (executor and commands).
5517 13946 ctx->hasAbsorbableState = false; 56aa37bRow pattern recognition patch (executor and commands).
5518 13946 ctx->allStatesAbsorbable = false; 56aa37bRow pattern recognition patch (executor and commands).
5519 13946 ctx->states->isAbsorbable = false; 56aa37bRow pattern recognition patch (executor and commands).
5520 - } 56aa37bRow pattern recognition patch (executor and commands).
5521 123412 } 56aa37bRow pattern recognition patch (executor and commands).
5522 - 56aa37bRow pattern recognition patch (executor and commands).
5523 - /* Add to tail of active context list (doubly-linked, oldest-first) */ 56aa37bRow pattern recognition patch (executor and commands).
5524 123412 ctx->prev = winstate->nfaContextTail; 56aa37bRow pattern recognition patch (executor and commands).
5525 123412 ctx->next = NULL; 56aa37bRow pattern recognition patch (executor and commands).
5526 123412 if (winstate->nfaContextTail != NULL) 56aa37bRow pattern recognition patch (executor and commands).
5527 122991 winstate->nfaContextTail->next = ctx; 56aa37bRow pattern recognition patch (executor and commands).
5528 - else 56aa37bRow pattern recognition patch (executor and commands).
5529 421 winstate->nfaContext = ctx; /* first context becomes head */ 56aa37bRow pattern recognition patch (executor and commands).
5530 123412 winstate->nfaContextTail = ctx; 56aa37bRow pattern recognition patch (executor and commands).
5531 - 56aa37bRow pattern recognition patch (executor and commands).
5532 - /* 56aa37bRow pattern recognition patch (executor and commands).
5533 - * Initial advance (divergence): expand ALT branches and create exit 56aa37bRow pattern recognition patch (executor and commands).
5534 - * states for VAR elements with min=0. This prepares the context for the 56aa37bRow pattern recognition patch (executor and commands).
5535 - * first row's match phase. 56aa37bRow pattern recognition patch (executor and commands).
5536 - * 56aa37bRow pattern recognition patch (executor and commands).
5537 - * Pass initialAdvance=true to prevent recording zero-length matches when 56aa37bRow pattern recognition patch (executor and commands).
5538 - * optional patterns can skip all VARs to reach FIN immediately. 56aa37bRow pattern recognition patch (executor and commands).
5539 - */ 56aa37bRow pattern recognition patch (executor and commands).
5540 123412 nfa_advance(winstate, ctx, startPos, true); 56aa37bRow pattern recognition patch (executor and commands).
5541 - 56aa37bRow pattern recognition patch (executor and commands).
5542 246824 return ctx; 56aa37bRow pattern recognition patch (executor and commands).
5543 123412 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_get_head_context() lines 5552-5564
Modified Lines Coverage: 6/6 lines (100.0%)
LineHitsSourceCommit
5552 10371 nfa_get_head_context(WindowAggState *winstate, int64 pos) 9d2796cReview NFA executor and add comprehensive runtime tests
5553 - { 56aa37bRow pattern recognition patch (executor and commands).
5554 10371 RPRNFAContext *ctx = winstate->nfaContext; 9d2796cReview NFA executor and add comprehensive runtime tests
5555 - 56aa37bRow pattern recognition patch (executor and commands).
5556 - /* 56aa37bRow pattern recognition patch (executor and commands).
5557 - * Contexts are sorted by matchStartRow ascending. If the head context 74205caRun pgindent on RPR source files
5558 - * doesn't match pos, no context exists for this position. 74205caRun pgindent on RPR source files
5559 - */ 56aa37bRow pattern recognition patch (executor and commands).
5560 10371 if (ctx == NULL || ctx->matchStartRow != pos) 9d2796cReview NFA executor and add comprehensive runtime tests
5561 616 return NULL; 9d2796cReview NFA executor and add comprehensive runtime tests
5562 - 9d2796cReview NFA executor and add comprehensive runtime tests
5563 9755 return ctx; 9d2796cReview NFA executor and add comprehensive runtime tests
5564 10371 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_update_length_stats() lines 5573-5588
Modified Lines Coverage: 11/11 lines (100.0%)
LineHitsSourceCommit
5573 76574 nfa_update_length_stats(int64 count, NFALengthStats *stats, int64 newLen) 56aa37bRow pattern recognition patch (executor and commands).
5574 - { 56aa37bRow pattern recognition patch (executor and commands).
5575 76574 if (count == 1) 56aa37bRow pattern recognition patch (executor and commands).
5576 - { 56aa37bRow pattern recognition patch (executor and commands).
5577 731 stats->min = newLen; 56aa37bRow pattern recognition patch (executor and commands).
5578 731 stats->max = newLen; 56aa37bRow pattern recognition patch (executor and commands).
5579 731 } 56aa37bRow pattern recognition patch (executor and commands).
5580 - else 56aa37bRow pattern recognition patch (executor and commands).
5581 - { 56aa37bRow pattern recognition patch (executor and commands).
5582 75843 if (newLen < stats->min) 56aa37bRow pattern recognition patch (executor and commands).
5583 369 stats->min = newLen; 56aa37bRow pattern recognition patch (executor and commands).
5584 75843 if (newLen > stats->max) 56aa37bRow pattern recognition patch (executor and commands).
5585 54 stats->max = newLen; 56aa37bRow pattern recognition patch (executor and commands).
5586 - } 56aa37bRow pattern recognition patch (executor and commands).
5587 76574 stats->total += newLen; 56aa37bRow pattern recognition patch (executor and commands).
5588 76574 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_record_context_success() lines 5596-5602
Modified Lines Coverage: 6/6 lines (100.0%)
LineHitsSourceCommit
5596 8368 nfa_record_context_success(WindowAggState *winstate, int64 matchLen) 9d2796cReview NFA executor and add comprehensive runtime tests
5597 - { 9d2796cReview NFA executor and add comprehensive runtime tests
5598 8368 winstate->nfaMatchesSucceeded++; 9d2796cReview NFA executor and add comprehensive runtime tests
5599 16736 nfa_update_length_stats(winstate->nfaMatchesSucceeded, 9d2796cReview NFA executor and add comprehensive runtime tests
5600 8368 &winstate->nfaMatchLen, 9d2796cReview NFA executor and add comprehensive runtime tests
5601 8368 matchLen); 9d2796cReview NFA executor and add comprehensive runtime tests
5602 8368 } 9d2796cReview NFA executor and add comprehensive runtime tests
nfa_record_context_failure() lines 5612-5625
Modified Lines Coverage: 9/9 lines (100.0%)
LineHitsSourceCommit
5612 47022 nfa_record_context_failure(WindowAggState *winstate, int64 failedLen) 56aa37bRow pattern recognition patch (executor and commands).
5613 - { 56aa37bRow pattern recognition patch (executor and commands).
5614 47022 if (failedLen == 1) 56aa37bRow pattern recognition patch (executor and commands).
5615 - { 56aa37bRow pattern recognition patch (executor and commands).
5616 46417 winstate->nfaContextsPruned++; 56aa37bRow pattern recognition patch (executor and commands).
5617 46417 } 56aa37bRow pattern recognition patch (executor and commands).
5618 - else 56aa37bRow pattern recognition patch (executor and commands).
5619 - { 56aa37bRow pattern recognition patch (executor and commands).
5620 605 winstate->nfaMatchesFailed++; 56aa37bRow pattern recognition patch (executor and commands).
5621 1210 nfa_update_length_stats(winstate->nfaMatchesFailed, 56aa37bRow pattern recognition patch (executor and commands).
5622 605 &winstate->nfaFailLen, 56aa37bRow pattern recognition patch (executor and commands).
5623 605 failedLen); 56aa37bRow pattern recognition patch (executor and commands).
5624 - } 56aa37bRow pattern recognition patch (executor and commands).
5625 47022 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_record_context_skipped() lines 5633-5639
Modified Lines Coverage: 6/6 lines (100.0%)
LineHitsSourceCommit
5633 26539 nfa_record_context_skipped(WindowAggState *winstate, int64 skippedLen) 9d2796cReview NFA executor and add comprehensive runtime tests
5634 - { 9d2796cReview NFA executor and add comprehensive runtime tests
5635 26539 winstate->nfaContextsSkipped++; 9d2796cReview NFA executor and add comprehensive runtime tests
5636 53078 nfa_update_length_stats(winstate->nfaContextsSkipped, 9d2796cReview NFA executor and add comprehensive runtime tests
5637 26539 &winstate->nfaSkippedLen, 9d2796cReview NFA executor and add comprehensive runtime tests
5638 26539 skippedLen); 9d2796cReview NFA executor and add comprehensive runtime tests
5639 26539 } 9d2796cReview NFA executor and add comprehensive runtime tests
nfa_record_context_absorbed() lines 5647-5653
Modified Lines Coverage: 6/6 lines (100.0%)
LineHitsSourceCommit
5647 41062 nfa_record_context_absorbed(WindowAggState *winstate, int64 absorbedLen) 9d2796cReview NFA executor and add comprehensive runtime tests
5648 - { 9d2796cReview NFA executor and add comprehensive runtime tests
5649 41062 winstate->nfaContextsAbsorbed++; 9d2796cReview NFA executor and add comprehensive runtime tests
5650 82124 nfa_update_length_stats(winstate->nfaContextsAbsorbed, 9d2796cReview NFA executor and add comprehensive runtime tests
5651 41062 &winstate->nfaAbsorbedLen, 9d2796cReview NFA executor and add comprehensive runtime tests
5652 41062 absorbedLen); 9d2796cReview NFA executor and add comprehensive runtime tests
5653 41062 } 9d2796cReview NFA executor and add comprehensive runtime tests
nfa_evaluate_row() lines 5664-5721
Modified Lines Coverage: 33/34 lines (97.1%)
LineHitsSourceCommit
5664 123209 nfa_evaluate_row(WindowObject winobj, int64 pos, bool *varMatched) 56aa37bRow pattern recognition patch (executor and commands).
5665 - { 56aa37bRow pattern recognition patch (executor and commands).
5666 123209 WindowAggState *winstate = winobj->winstate; 56aa37bRow pattern recognition patch (executor and commands).
5667 123209 ExprContext *econtext = winstate->ss.ps.ps_ExprContext; 56aa37bRow pattern recognition patch (executor and commands).
5668 123209 int numDefineVars = list_length(winstate->defineVariableList); 56aa37bRow pattern recognition patch (executor and commands).
5669 123209 ListCell *lc; 56aa37bRow pattern recognition patch (executor and commands).
5670 123209 int varIdx = 0; 56aa37bRow pattern recognition patch (executor and commands).
5671 123209 TupleTableSlot *slot; 56aa37bRow pattern recognition patch (executor and commands).
5672 - 56aa37bRow pattern recognition patch (executor and commands).
5673 - /* 56aa37bRow pattern recognition patch (executor and commands).
5674 - * Set up slots for current, previous, and next rows. We don't call 56aa37bRow pattern recognition patch (executor and commands).
5675 - * get_slots() here to avoid recursion through row_is_in_frame -> 56aa37bRow pattern recognition patch (executor and commands).
5676 - * update_reduced_frame -> nfa_process_row. 56aa37bRow pattern recognition patch (executor and commands).
5677 - */ 56aa37bRow pattern recognition patch (executor and commands).
5678 - 56aa37bRow pattern recognition patch (executor and commands).
5679 - /* Current row -> ecxt_outertuple */ 56aa37bRow pattern recognition patch (executor and commands).
5680 123209 slot = winstate->temp_slot_1; 56aa37bRow pattern recognition patch (executor and commands).
5681 123209 if (!window_gettupleslot(winobj, pos, slot)) 56aa37bRow pattern recognition patch (executor and commands).
5682 218 return false; /* No row exists */ 56aa37bRow pattern recognition patch (executor and commands).
5683 122991 econtext->ecxt_outertuple = slot; 56aa37bRow pattern recognition patch (executor and commands).
5684 - 56aa37bRow pattern recognition patch (executor and commands).
5685 - /* Previous row -> ecxt_scantuple (for PREV) */ 56aa37bRow pattern recognition patch (executor and commands).
5686 122991 if (pos > 0) 56aa37bRow pattern recognition patch (executor and commands).
5687 - { 56aa37bRow pattern recognition patch (executor and commands).
5688 122570 slot = winstate->prev_slot; 56aa37bRow pattern recognition patch (executor and commands).
5689 122570 if (!window_gettupleslot(winobj, pos - 1, slot)) 56aa37bRow pattern recognition patch (executor and commands).
5690 0 econtext->ecxt_scantuple = winstate->null_slot; 56aa37bRow pattern recognition patch (executor and commands).
5691 - else 56aa37bRow pattern recognition patch (executor and commands).
5692 122570 econtext->ecxt_scantuple = slot; 56aa37bRow pattern recognition patch (executor and commands).
5693 122570 } 56aa37bRow pattern recognition patch (executor and commands).
5694 - else 56aa37bRow pattern recognition patch (executor and commands).
5695 421 econtext->ecxt_scantuple = winstate->null_slot; 56aa37bRow pattern recognition patch (executor and commands).
5696 - 56aa37bRow pattern recognition patch (executor and commands).
5697 - /* Next row -> ecxt_innertuple (for NEXT) */ 56aa37bRow pattern recognition patch (executor and commands).
5698 122991 slot = winstate->next_slot; 56aa37bRow pattern recognition patch (executor and commands).
5699 122991 if (!window_gettupleslot(winobj, pos + 1, slot)) 56aa37bRow pattern recognition patch (executor and commands).
5700 419 econtext->ecxt_innertuple = winstate->null_slot; 56aa37bRow pattern recognition patch (executor and commands).
5701 - else 56aa37bRow pattern recognition patch (executor and commands).
5702 122572 econtext->ecxt_innertuple = slot; 56aa37bRow pattern recognition patch (executor and commands).
5703 - 56aa37bRow pattern recognition patch (executor and commands).
5704 466111 foreach(lc, winstate->defineClauseList) 56aa37bRow pattern recognition patch (executor and commands).
5705 - { 56aa37bRow pattern recognition patch (executor and commands).
5706 343120 ExprState *exprState = (ExprState *) lfirst(lc); 56aa37bRow pattern recognition patch (executor and commands).
5707 343120 Datum result; 56aa37bRow pattern recognition patch (executor and commands).
5708 343120 bool isnull; 56aa37bRow pattern recognition patch (executor and commands).
5709 - 56aa37bRow pattern recognition patch (executor and commands).
5710 - /* Evaluate DEFINE expression */ 56aa37bRow pattern recognition patch (executor and commands).
5711 343120 result = ExecEvalExpr(exprState, econtext, &isnull); 56aa37bRow pattern recognition patch (executor and commands).
5712 - 56aa37bRow pattern recognition patch (executor and commands).
5713 343120 varMatched[varIdx] = (!isnull && DatumGetBool(result)); 56aa37bRow pattern recognition patch (executor and commands).
5714 - 56aa37bRow pattern recognition patch (executor and commands).
5715 343120 varIdx++; 56aa37bRow pattern recognition patch (executor and commands).
5716 343120 if (varIdx >= numDefineVars) 56aa37bRow pattern recognition patch (executor and commands).
5717 122989 break; 56aa37bRow pattern recognition patch (executor and commands).
5718 343120 } 56aa37bRow pattern recognition patch (executor and commands).
5719 - 56aa37bRow pattern recognition patch (executor and commands).
5720 122991 return true; /* Row exists */ 56aa37bRow pattern recognition patch (executor and commands).
5721 123209 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_cleanup_dead_contexts() lines 5731-5763
Modified Lines Coverage: 16/16 lines (100.0%)
LineHitsSourceCommit
5731 123209 nfa_cleanup_dead_contexts(WindowAggState *winstate, RPRNFAContext *excludeCtx) 56aa37bRow pattern recognition patch (executor and commands).
5732 - { 56aa37bRow pattern recognition patch (executor and commands).
5733 123209 RPRNFAContext *ctx; 56aa37bRow pattern recognition patch (executor and commands).
5734 123209 RPRNFAContext *next; 56aa37bRow pattern recognition patch (executor and commands).
5735 - 56aa37bRow pattern recognition patch (executor and commands).
5736 423538 for (ctx = winstate->nfaContext; ctx != NULL; ctx = next) 56aa37bRow pattern recognition patch (executor and commands).
5737 - { 56aa37bRow pattern recognition patch (executor and commands).
5738 300329 next = ctx->next; 56aa37bRow pattern recognition patch (executor and commands).
5739 - 56aa37bRow pattern recognition patch (executor and commands).
5740 - /* Skip the target context and contexts still processing */ 56aa37bRow pattern recognition patch (executor and commands).
5741 300329 if (ctx == excludeCtx || ctx->states != NULL) 56aa37bRow pattern recognition patch (executor and commands).
5742 254754 continue; 56aa37bRow pattern recognition patch (executor and commands).
5743 - 56aa37bRow pattern recognition patch (executor and commands).
5744 - /* Skip successfully matched contexts (will be handled by SKIP logic) */ 56aa37bRow pattern recognition patch (executor and commands).
5745 45575 if (ctx->matchEndRow >= ctx->matchStartRow) 56aa37bRow pattern recognition patch (executor and commands).
5746 143 continue; 56aa37bRow pattern recognition patch (executor and commands).
5747 - 56aa37bRow pattern recognition patch (executor and commands).
5748 - /* 56aa37bRow pattern recognition patch (executor and commands).
5749 - * This is a failed context - count and remove it. Only count if it 56aa37bRow pattern recognition patch (executor and commands).
5750 - * actually processed its start row. Contexts created for 56aa37bRow pattern recognition patch (executor and commands).
5751 - * beyond-partition rows are silently removed. 56aa37bRow pattern recognition patch (executor and commands).
5752 - */ 56aa37bRow pattern recognition patch (executor and commands).
5753 45432 if (ctx->lastProcessedRow >= ctx->matchStartRow) 56aa37bRow pattern recognition patch (executor and commands).
5754 - { 56aa37bRow pattern recognition patch (executor and commands).
5755 45214 int64 failedLen = ctx->lastProcessedRow - ctx->matchStartRow + 1; 56aa37bRow pattern recognition patch (executor and commands).
5756 - 56aa37bRow pattern recognition patch (executor and commands).
5757 45214 nfa_record_context_failure(winstate, failedLen); 56aa37bRow pattern recognition patch (executor and commands).
5758 45214 } 56aa37bRow pattern recognition patch (executor and commands).
5759 - /* else: context was never processed (beyond-partition), just remove */ 56aa37bRow pattern recognition patch (executor and commands).
5760 - 56aa37bRow pattern recognition patch (executor and commands).
5761 45432 nfa_context_free(winstate, ctx); 56aa37bRow pattern recognition patch (executor and commands).
5762 45432 } 56aa37bRow pattern recognition patch (executor and commands).
5763 123209 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_finalize_all_contexts() lines 5772-5784
Modified Lines Coverage: 9/9 lines (100.0%)
LineHitsSourceCommit
5772 218 nfa_finalize_all_contexts(WindowAggState *winstate, int64 lastPos) 9d2796cReview NFA executor and add comprehensive runtime tests
5773 - { 9d2796cReview NFA executor and add comprehensive runtime tests
5774 218 RPRNFAContext *ctx; 9d2796cReview NFA executor and add comprehensive runtime tests
5775 - 9d2796cReview NFA executor and add comprehensive runtime tests
5776 857 for (ctx = winstate->nfaContext; ctx != NULL; ctx = ctx->next) 9d2796cReview NFA executor and add comprehensive runtime tests
5777 - { 9d2796cReview NFA executor and add comprehensive runtime tests
5778 639 if (ctx->states != NULL) 9d2796cReview NFA executor and add comprehensive runtime tests
5779 - { 9d2796cReview NFA executor and add comprehensive runtime tests
5780 639 nfa_match(winstate, ctx, NULL); 9d2796cReview NFA executor and add comprehensive runtime tests
5781 639 nfa_advance(winstate, ctx, lastPos, false); 9d2796cReview NFA executor and add comprehensive runtime tests
5782 639 } 9d2796cReview NFA executor and add comprehensive runtime tests
5783 639 } 9d2796cReview NFA executor and add comprehensive runtime tests
5784 218 } 9d2796cReview NFA executor and add comprehensive runtime tests
nfa_update_absorption_flags() lines 5803-5843
Modified Lines Coverage: 19/19 lines (100.0%)
LineHitsSourceCommit
5803 217913 nfa_update_absorption_flags(RPRNFAContext *ctx) 9d2796cReview NFA executor and add comprehensive runtime tests
5804 - { 56aa37bRow pattern recognition patch (executor and commands).
5805 217913 RPRNFAState *state; 56aa37bRow pattern recognition patch (executor and commands).
5806 217913 bool hasAbsorbable = false; 56aa37bRow pattern recognition patch (executor and commands).
5807 217913 bool allAbsorbable = true; 56aa37bRow pattern recognition patch (executor and commands).
5808 - 56aa37bRow pattern recognition patch (executor and commands).
5809 - /* 56aa37bRow pattern recognition patch (executor and commands).
5810 - * Optimization: Once hasAbsorbableState becomes false, it stays false. No 56aa37bRow pattern recognition patch (executor and commands).
5811 - * need to recalculate - both flags remain false permanently. 56aa37bRow pattern recognition patch (executor and commands).
5812 - */ 56aa37bRow pattern recognition patch (executor and commands).
5813 217913 if (!ctx->hasAbsorbableState) 56aa37bRow pattern recognition patch (executor and commands).
5814 - { 56aa37bRow pattern recognition patch (executor and commands).
5815 66772 ctx->allStatesAbsorbable = false; 56aa37bRow pattern recognition patch (executor and commands).
5816 66772 return; 56aa37bRow pattern recognition patch (executor and commands).
5817 - } 56aa37bRow pattern recognition patch (executor and commands).
5818 - 56aa37bRow pattern recognition patch (executor and commands).
5819 - /* No states means no absorbable states */ 56aa37bRow pattern recognition patch (executor and commands).
5820 151141 if (ctx->states == NULL) 56aa37bRow pattern recognition patch (executor and commands).
5821 - { 56aa37bRow pattern recognition patch (executor and commands).
5822 67796 ctx->hasAbsorbableState = false; 56aa37bRow pattern recognition patch (executor and commands).
5823 67796 ctx->allStatesAbsorbable = false; 56aa37bRow pattern recognition patch (executor and commands).
5824 67796 return; 56aa37bRow pattern recognition patch (executor and commands).
5825 - } 56aa37bRow pattern recognition patch (executor and commands).
5826 - 56aa37bRow pattern recognition patch (executor and commands).
5827 - /* 56aa37bRow pattern recognition patch (executor and commands).
5828 - * Iterate through all states to check absorption status. Uses 56aa37bRow pattern recognition patch (executor and commands).
5829 - * state->isAbsorbable which tracks if state is in absorbable region. This 56aa37bRow pattern recognition patch (executor and commands).
5830 - * is different from RPRElemIsAbsorbable(elem) which checks judgment 56aa37bRow pattern recognition patch (executor and commands).
5831 - * point. 56aa37bRow pattern recognition patch (executor and commands).
5832 - */ 56aa37bRow pattern recognition patch (executor and commands).
5833 166765 for (state = ctx->states; state != NULL; state = state->next) 56aa37bRow pattern recognition patch (executor and commands).
5834 - { 56aa37bRow pattern recognition patch (executor and commands).
5835 83420 if (state->isAbsorbable) 56aa37bRow pattern recognition patch (executor and commands).
5836 83298 hasAbsorbable = true; 56aa37bRow pattern recognition patch (executor and commands).
5837 - else 56aa37bRow pattern recognition patch (executor and commands).
5838 122 allAbsorbable = false; 56aa37bRow pattern recognition patch (executor and commands).
5839 83420 } 56aa37bRow pattern recognition patch (executor and commands).
5840 - 56aa37bRow pattern recognition patch (executor and commands).
5841 83345 ctx->hasAbsorbableState = hasAbsorbable; 56aa37bRow pattern recognition patch (executor and commands).
5842 83345 ctx->allStatesAbsorbable = allAbsorbable; 56aa37bRow pattern recognition patch (executor and commands).
5843 217913 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_states_covered() lines 5859-5891
Modified Lines Coverage: 21/21 lines (100.0%)
LineHitsSourceCommit
5859 41077 nfa_states_covered(RPRPattern *pattern, RPRNFAContext *older, RPRNFAContext *newer) 56aa37bRow pattern recognition patch (executor and commands).
5860 - { 56aa37bRow pattern recognition patch (executor and commands).
5861 41077 RPRNFAState *newerState; 56aa37bRow pattern recognition patch (executor and commands).
5862 - 56aa37bRow pattern recognition patch (executor and commands).
5863 82140 for (newerState = newer->states; newerState != NULL; newerState = newerState->next) 56aa37bRow pattern recognition patch (executor and commands).
5864 - { 56aa37bRow pattern recognition patch (executor and commands).
5865 41078 RPRNFAState *olderState; 56aa37bRow pattern recognition patch (executor and commands).
5866 41078 RPRPatternElement *elem; 56aa37bRow pattern recognition patch (executor and commands).
5867 41078 int depth; 56aa37bRow pattern recognition patch (executor and commands).
5868 41078 bool found = false; 56aa37bRow pattern recognition patch (executor and commands).
5869 - 56aa37bRow pattern recognition patch (executor and commands).
5870 - /* All states are absorbable (caller checks allStatesAbsorbable) */ 56aa37bRow pattern recognition patch (executor and commands).
5871 41078 elem = &pattern->elements[newerState->elemIdx]; 56aa37bRow pattern recognition patch (executor and commands).
5872 41078 depth = elem->depth; 56aa37bRow pattern recognition patch (executor and commands).
5873 - 56aa37bRow pattern recognition patch (executor and commands).
5874 41093 for (olderState = older->states; olderState != NULL; olderState = olderState->next) 56aa37bRow pattern recognition patch (executor and commands).
5875 - { 56aa37bRow pattern recognition patch (executor and commands).
5876 - /* Covering state must also be absorbable */ 56aa37bRow pattern recognition patch (executor and commands).
5877 82141 if (olderState->isAbsorbable && 56aa37bRow pattern recognition patch (executor and commands).
5878 41078 olderState->elemIdx == newerState->elemIdx && 56aa37bRow pattern recognition patch (executor and commands).
5879 41063 olderState->counts[depth] >= newerState->counts[depth]) 56aa37bRow pattern recognition patch (executor and commands).
5880 - { 56aa37bRow pattern recognition patch (executor and commands).
5881 41063 found = true; 56aa37bRow pattern recognition patch (executor and commands).
5882 41063 break; 56aa37bRow pattern recognition patch (executor and commands).
5883 - } 56aa37bRow pattern recognition patch (executor and commands).
5884 15 } 56aa37bRow pattern recognition patch (executor and commands).
5885 - 56aa37bRow pattern recognition patch (executor and commands).
5886 41078 if (!found) 56aa37bRow pattern recognition patch (executor and commands).
5887 15 return false; 56aa37bRow pattern recognition patch (executor and commands).
5888 41078 } 56aa37bRow pattern recognition patch (executor and commands).
5889 - 56aa37bRow pattern recognition patch (executor and commands).
5890 41062 return true; 56aa37bRow pattern recognition patch (executor and commands).
5891 41077 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_try_absorb_context() lines 5912-5949
Modified Lines Coverage: 19/19 lines (100.0%)
LineHitsSourceCommit
5912 150101 nfa_try_absorb_context(WindowAggState *winstate, RPRNFAContext *ctx) 56aa37bRow pattern recognition patch (executor and commands).
5913 - { 56aa37bRow pattern recognition patch (executor and commands).
5914 150101 RPRPattern *pattern = winstate->rpPattern; 56aa37bRow pattern recognition patch (executor and commands).
5915 150101 RPRNFAContext *older; 56aa37bRow pattern recognition patch (executor and commands).
5916 - 56aa37bRow pattern recognition patch (executor and commands).
5917 - /* Early exit: ctx must have all states absorbable */ 56aa37bRow pattern recognition patch (executor and commands).
5918 150101 if (!ctx->allStatesAbsorbable) 56aa37bRow pattern recognition patch (executor and commands).
5919 66863 return false; 56aa37bRow pattern recognition patch (executor and commands).
5920 - 56aa37bRow pattern recognition patch (executor and commands).
5921 83369 for (older = ctx->prev; older != NULL; older = older->prev) 56aa37bRow pattern recognition patch (executor and commands).
5922 - { 56aa37bRow pattern recognition patch (executor and commands).
5923 - /* 56aa37bRow pattern recognition patch (executor and commands).
5924 - * By invariant: ctx->prev chain is in creation order (oldest first), 56aa37bRow pattern recognition patch (executor and commands).
5925 - * and each row creates at most one context. So all contexts in this 56aa37bRow pattern recognition patch (executor and commands).
5926 - * chain have matchStartRow < ctx->matchStartRow. 56aa37bRow pattern recognition patch (executor and commands).
5927 - */ 56aa37bRow pattern recognition patch (executor and commands).
5928 - 56aa37bRow pattern recognition patch (executor and commands).
5929 - /* Older must also be in-progress */ 56aa37bRow pattern recognition patch (executor and commands).
5930 41193 if (older->states == NULL) 56aa37bRow pattern recognition patch (executor and commands).
5931 78 continue; 56aa37bRow pattern recognition patch (executor and commands).
5932 - 56aa37bRow pattern recognition patch (executor and commands).
5933 - /* Older must have at least one absorbable state */ 56aa37bRow pattern recognition patch (executor and commands).
5934 41115 if (!older->hasAbsorbableState) 56aa37bRow pattern recognition patch (executor and commands).
5935 38 continue; 56aa37bRow pattern recognition patch (executor and commands).
5936 - 56aa37bRow pattern recognition patch (executor and commands).
5937 - /* Check if all newer states are covered by older */ 56aa37bRow pattern recognition patch (executor and commands).
5938 41077 if (nfa_states_covered(pattern, older, ctx)) 56aa37bRow pattern recognition patch (executor and commands).
5939 - { 56aa37bRow pattern recognition patch (executor and commands).
5940 41062 int64 absorbedLen = ctx->lastProcessedRow - ctx->matchStartRow + 1; 56aa37bRow pattern recognition patch (executor and commands).
5941 - 56aa37bRow pattern recognition patch (executor and commands).
5942 41062 nfa_context_free(winstate, ctx); 56aa37bRow pattern recognition patch (executor and commands).
5943 41062 nfa_record_context_absorbed(winstate, absorbedLen); 9d2796cReview NFA executor and add comprehensive runtime tests
5944 41062 return true; 56aa37bRow pattern recognition patch (executor and commands).
5945 41062 } 56aa37bRow pattern recognition patch (executor and commands).
5946 15 } 56aa37bRow pattern recognition patch (executor and commands).
5947 - 56aa37bRow pattern recognition patch (executor and commands).
5948 42176 return false; 56aa37bRow pattern recognition patch (executor and commands).
5949 150101 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_absorb_contexts() lines 5965-5981
Modified Lines Coverage: 9/9 lines (100.0%)
LineHitsSourceCommit
5965 109415 nfa_absorb_contexts(WindowAggState *winstate) 56aa37bRow pattern recognition patch (executor and commands).
5966 - { 56aa37bRow pattern recognition patch (executor and commands).
5967 109415 RPRNFAContext *ctx; 56aa37bRow pattern recognition patch (executor and commands).
5968 109415 RPRNFAContext *nextCtx; 56aa37bRow pattern recognition patch (executor and commands).
5969 - 56aa37bRow pattern recognition patch (executor and commands).
5970 327443 for (ctx = winstate->nfaContextTail; ctx != NULL; ctx = nextCtx) 56aa37bRow pattern recognition patch (executor and commands).
5971 - { 56aa37bRow pattern recognition patch (executor and commands).
5972 218028 nextCtx = ctx->prev; 56aa37bRow pattern recognition patch (executor and commands).
5973 - 56aa37bRow pattern recognition patch (executor and commands).
5974 - /* 56aa37bRow pattern recognition patch (executor and commands).
5975 - * Only absorb in-progress contexts; completed contexts are valid 56aa37bRow pattern recognition patch (executor and commands).
5976 - * results 56aa37bRow pattern recognition patch (executor and commands).
5977 - */ 56aa37bRow pattern recognition patch (executor and commands).
5978 218028 if (ctx->states != NULL) 56aa37bRow pattern recognition patch (executor and commands).
5979 150101 nfa_try_absorb_context(winstate, ctx); 56aa37bRow pattern recognition patch (executor and commands).
5980 218028 } 56aa37bRow pattern recognition patch (executor and commands).
5981 109415 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_eval_var_match() lines 5990-6001
Modified Lines Coverage: 8/8 lines (100.0%)
LineHitsSourceCommit
5990 356712 nfa_eval_var_match(WindowAggState *winstate, RPRPatternElement *elem, 56aa37bRow pattern recognition patch (executor and commands).
5991 - bool *varMatched) 56aa37bRow pattern recognition patch (executor and commands).
5992 - { 56aa37bRow pattern recognition patch (executor and commands).
5993 - /* This function should only be called for VAR elements */ 9d2796cReview NFA executor and add comprehensive runtime tests
5994 356712 Assert(RPRElemIsVar(elem)); 9d2796cReview NFA executor and add comprehensive runtime tests
5995 - 9d2796cReview NFA executor and add comprehensive runtime tests
5996 356712 if (varMatched == NULL) 56aa37bRow pattern recognition patch (executor and commands).
5997 837 return false; 56aa37bRow pattern recognition patch (executor and commands).
5998 355875 if (elem->varId >= list_length(winstate->defineVariableList)) 56aa37bRow pattern recognition patch (executor and commands).
5999 28 return true; 56aa37bRow pattern recognition patch (executor and commands).
6000 355847 return varMatched[elem->varId]; 56aa37bRow pattern recognition patch (executor and commands).
6001 356712 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_match() lines 6021-6106
Modified Lines Coverage: 39/39 lines (100.0%)
LineHitsSourceCommit
6021 244934 nfa_match(WindowAggState *winstate, RPRNFAContext *ctx, bool *varMatched) 56aa37bRow pattern recognition patch (executor and commands).
6022 - { 56aa37bRow pattern recognition patch (executor and commands).
6023 244934 RPRPattern *pattern = winstate->rpPattern; 56aa37bRow pattern recognition patch (executor and commands).
6024 244934 RPRPatternElement *elements = pattern->elements; 56aa37bRow pattern recognition patch (executor and commands).
6025 244934 RPRNFAState **prevPtr = &ctx->states; 56aa37bRow pattern recognition patch (executor and commands).
6026 244934 RPRNFAState *state; 56aa37bRow pattern recognition patch (executor and commands).
6027 244934 RPRNFAState *nextState; 9d2796cReview NFA executor and add comprehensive runtime tests
6028 - 56aa37bRow pattern recognition patch (executor and commands).
6029 - /* 56aa37bRow pattern recognition patch (executor and commands).
6030 - * Evaluate VAR elements against current row. For simple VARs with END 56aa37bRow pattern recognition patch (executor and commands).
6031 - * next, advance to END and update group count inline so absorb phase can 56aa37bRow pattern recognition patch (executor and commands).
6032 - * compare states properly. 56aa37bRow pattern recognition patch (executor and commands).
6033 - */ 56aa37bRow pattern recognition patch (executor and commands).
6034 601646 for (state = ctx->states; state != NULL; state = nextState) 9d2796cReview NFA executor and add comprehensive runtime tests
6035 - { 56aa37bRow pattern recognition patch (executor and commands).
6036 356712 RPRPatternElement *elem = &elements[state->elemIdx]; 56aa37bRow pattern recognition patch (executor and commands).
6037 - 56aa37bRow pattern recognition patch (executor and commands).
6038 356712 nextState = state->next; 9d2796cReview NFA executor and add comprehensive runtime tests
6039 - 9d2796cReview NFA executor and add comprehensive runtime tests
6040 356712 if (RPRElemIsVar(elem)) 56aa37bRow pattern recognition patch (executor and commands).
6041 - { 56aa37bRow pattern recognition patch (executor and commands).
6042 356712 bool matched; 56aa37bRow pattern recognition patch (executor and commands).
6043 356712 int depth = elem->depth; 56aa37bRow pattern recognition patch (executor and commands).
6044 356712 int32 count = state->counts[depth]; 56aa37bRow pattern recognition patch (executor and commands).
6045 - 56aa37bRow pattern recognition patch (executor and commands).
6046 356712 matched = nfa_eval_var_match(winstate, elem, varMatched); 56aa37bRow pattern recognition patch (executor and commands).
6047 - 56aa37bRow pattern recognition patch (executor and commands).
6048 356712 if (matched) 56aa37bRow pattern recognition patch (executor and commands).
6049 - { 56aa37bRow pattern recognition patch (executor and commands).
6050 - /* Increment count */ 56aa37bRow pattern recognition patch (executor and commands).
6051 171884 if (count < RPR_COUNT_MAX) 56aa37bRow pattern recognition patch (executor and commands).
6052 171884 count++; 56aa37bRow pattern recognition patch (executor and commands).
6053 - 56aa37bRow pattern recognition patch (executor and commands).
6054 - /* Max constraint should not be exceeded */ 9d2796cReview NFA executor and add comprehensive runtime tests
6055 171884 Assert(elem->max == RPR_QUANTITY_INF || count <= elem->max); 9d2796cReview NFA executor and add comprehensive runtime tests
6056 - 56aa37bRow pattern recognition patch (executor and commands).
6057 171884 state->counts[depth] = count; 56aa37bRow pattern recognition patch (executor and commands).
6058 - 56aa37bRow pattern recognition patch (executor and commands).
6059 - /* 56aa37bRow pattern recognition patch (executor and commands).
6060 - * For simple VAR (min=max=1) with END next, advance to END 56aa37bRow pattern recognition patch (executor and commands).
6061 - * and update group count inline. This keeps state in place, 56aa37bRow pattern recognition patch (executor and commands).
6062 - * preserving lexical order. 56aa37bRow pattern recognition patch (executor and commands).
6063 - */ 56aa37bRow pattern recognition patch (executor and commands).
6064 171884 if (elem->min == 1 && elem->max == 1 && 9d2796cReview NFA executor and add comprehensive runtime tests
6065 14562 RPRElemIsEnd(&elements[elem->next])) 56aa37bRow pattern recognition patch (executor and commands).
6066 - { 56aa37bRow pattern recognition patch (executor and commands).
6067 3397 RPRPatternElement *endElem = &elements[elem->next]; 56aa37bRow pattern recognition patch (executor and commands).
6068 3397 int endDepth = endElem->depth; 56aa37bRow pattern recognition patch (executor and commands).
6069 3397 int32 endCount = state->counts[endDepth]; 56aa37bRow pattern recognition patch (executor and commands).
6070 - 56aa37bRow pattern recognition patch (executor and commands).
6071 3397 Assert(count == 1); 9d2796cReview NFA executor and add comprehensive runtime tests
6072 - 9d2796cReview NFA executor and add comprehensive runtime tests
6073 - /* Increment group count with overflow protection */ 56aa37bRow pattern recognition patch (executor and commands).
6074 3397 if (endCount < RPR_COUNT_MAX) 56aa37bRow pattern recognition patch (executor and commands).
6075 3397 endCount++; 56aa37bRow pattern recognition patch (executor and commands).
6076 - 56aa37bRow pattern recognition patch (executor and commands).
6077 - /* 9d2796cReview NFA executor and add comprehensive runtime tests
6078 - * END's max can never be exceeded here because 9d2796cReview NFA executor and add comprehensive runtime tests
6079 - * nfa_advance_end only loops when count < max, so 74205caRun pgindent on RPR source files
6080 - * endCount entering inline advance is at most max-1, and 74205caRun pgindent on RPR source files
6081 - * incrementing yields at most max. 74205caRun pgindent on RPR source files
6082 - */ 9d2796cReview NFA executor and add comprehensive runtime tests
6083 3397 Assert(endElem->max == RPR_QUANTITY_INF || 9d2796cReview NFA executor and add comprehensive runtime tests
6084 - endCount <= endElem->max); 9d2796cReview NFA executor and add comprehensive runtime tests
6085 - 56aa37bRow pattern recognition patch (executor and commands).
6086 3397 state->elemIdx = elem->next; 56aa37bRow pattern recognition patch (executor and commands).
6087 3397 state->counts[endDepth] = endCount; 56aa37bRow pattern recognition patch (executor and commands).
6088 3397 } 56aa37bRow pattern recognition patch (executor and commands).
6089 - /* else: stay at VAR for advance phase */ 56aa37bRow pattern recognition patch (executor and commands).
6090 171884 } 56aa37bRow pattern recognition patch (executor and commands).
6091 - else 56aa37bRow pattern recognition patch (executor and commands).
6092 - { 56aa37bRow pattern recognition patch (executor and commands).
6093 - /* 56aa37bRow pattern recognition patch (executor and commands).
6094 - * Not matched - remove state. Exit alternatives were already 56aa37bRow pattern recognition patch (executor and commands).
6095 - * created by advance phase when count >= min was satisfied. 56aa37bRow pattern recognition patch (executor and commands).
6096 - */ 56aa37bRow pattern recognition patch (executor and commands).
6097 184828 *prevPtr = nextState; 56aa37bRow pattern recognition patch (executor and commands).
6098 184828 nfa_state_free(winstate, state); 56aa37bRow pattern recognition patch (executor and commands).
6099 184828 continue; 56aa37bRow pattern recognition patch (executor and commands).
6100 - } 56aa37bRow pattern recognition patch (executor and commands).
6101 356712 } 56aa37bRow pattern recognition patch (executor and commands).
6102 - /* Non-VAR elements: keep as-is for advance phase */ 56aa37bRow pattern recognition patch (executor and commands).
6103 - 56aa37bRow pattern recognition patch (executor and commands).
6104 171884 prevPtr = &state->next; 56aa37bRow pattern recognition patch (executor and commands).
6105 356712 } 56aa37bRow pattern recognition patch (executor and commands).
6106 244934 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_route_to_elem() lines 6115-6136
Modified Lines Coverage: 13/13 lines (100.0%)
LineHitsSourceCommit
6115 119744 nfa_route_to_elem(WindowAggState *winstate, RPRNFAContext *ctx, 56aa37bRow pattern recognition patch (executor and commands).
6116 - RPRNFAState *state, RPRPatternElement *nextElem, 56aa37bRow pattern recognition patch (executor and commands).
6117 - int64 currentPos, bool initialAdvance) 56aa37bRow pattern recognition patch (executor and commands).
6118 - { 56aa37bRow pattern recognition patch (executor and commands).
6119 119744 if (RPRElemIsVar(nextElem)) 56aa37bRow pattern recognition patch (executor and commands).
6120 - { 56aa37bRow pattern recognition patch (executor and commands).
6121 75425 nfa_add_state_unique(winstate, ctx, state); 56aa37bRow pattern recognition patch (executor and commands).
6122 75425 if (RPRElemCanSkip(nextElem)) 56aa37bRow pattern recognition patch (executor and commands).
6123 - { 56aa37bRow pattern recognition patch (executor and commands).
6124 33498 RPRNFAState *skipState; 56aa37bRow pattern recognition patch (executor and commands).
6125 - 56aa37bRow pattern recognition patch (executor and commands).
6126 66996 skipState = nfa_state_create(winstate, nextElem->next, 9d2796cReview NFA executor and add comprehensive runtime tests
6127 33498 state->altPriority, state->counts, 9d2796cReview NFA executor and add comprehensive runtime tests
6128 33498 state->isAbsorbable); 9d2796cReview NFA executor and add comprehensive runtime tests
6129 33498 nfa_advance_state(winstate, ctx, skipState, currentPos, initialAdvance); 56aa37bRow pattern recognition patch (executor and commands).
6130 33498 } 56aa37bRow pattern recognition patch (executor and commands).
6131 75425 } 56aa37bRow pattern recognition patch (executor and commands).
6132 - else 56aa37bRow pattern recognition patch (executor and commands).
6133 - { 56aa37bRow pattern recognition patch (executor and commands).
6134 44319 nfa_advance_state(winstate, ctx, state, currentPos, initialAdvance); 56aa37bRow pattern recognition patch (executor and commands).
6135 - } 56aa37bRow pattern recognition patch (executor and commands).
6136 119744 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_advance_alt() lines 6145-6183
Modified Lines Coverage: 23/23 lines (100.0%)
LineHitsSourceCommit
6145 5762 nfa_advance_alt(WindowAggState *winstate, RPRNFAContext *ctx, 56aa37bRow pattern recognition patch (executor and commands).
6146 - RPRNFAState *state, RPRPatternElement *elem, 56aa37bRow pattern recognition patch (executor and commands).
6147 - int64 currentPos, bool initialAdvance) 56aa37bRow pattern recognition patch (executor and commands).
6148 - { 56aa37bRow pattern recognition patch (executor and commands).
6149 5762 RPRPattern *pattern = winstate->rpPattern; 56aa37bRow pattern recognition patch (executor and commands).
6150 5762 RPRPatternElement *elements = pattern->elements; 56aa37bRow pattern recognition patch (executor and commands).
6151 5762 RPRElemIdx altIdx = elem->next; 56aa37bRow pattern recognition patch (executor and commands).
6152 5762 bool first = true; 56aa37bRow pattern recognition patch (executor and commands).
6153 - 56aa37bRow pattern recognition patch (executor and commands).
6154 18276 while (altIdx >= 0 && altIdx < pattern->numElements) 56aa37bRow pattern recognition patch (executor and commands).
6155 - { 56aa37bRow pattern recognition patch (executor and commands).
6156 12523 RPRPatternElement *altElem = &elements[altIdx]; 56aa37bRow pattern recognition patch (executor and commands).
6157 12523 RPRNFAState *newState; 56aa37bRow pattern recognition patch (executor and commands).
6158 - 56aa37bRow pattern recognition patch (executor and commands).
6159 - /* Stop if element is outside ALT scope (not a branch) */ 9d2796cReview NFA executor and add comprehensive runtime tests
6160 12523 if (altElem->depth <= elem->depth) 9d2796cReview NFA executor and add comprehensive runtime tests
6161 9 break; 9d2796cReview NFA executor and add comprehensive runtime tests
6162 - 9d2796cReview NFA executor and add comprehensive runtime tests
6163 12514 if (first) 56aa37bRow pattern recognition patch (executor and commands).
6164 - { 56aa37bRow pattern recognition patch (executor and commands).
6165 5762 state->elemIdx = altIdx; 56aa37bRow pattern recognition patch (executor and commands).
6166 5762 state->altPriority = altIdx; 56aa37bRow pattern recognition patch (executor and commands).
6167 5762 newState = state; 56aa37bRow pattern recognition patch (executor and commands).
6168 5762 first = false; 56aa37bRow pattern recognition patch (executor and commands).
6169 5762 } 56aa37bRow pattern recognition patch (executor and commands).
6170 - else 56aa37bRow pattern recognition patch (executor and commands).
6171 - { 56aa37bRow pattern recognition patch (executor and commands).
6172 13504 newState = nfa_state_create(winstate, altIdx, altIdx, 9d2796cReview NFA executor and add comprehensive runtime tests
6173 6752 state->counts, state->isAbsorbable); 9d2796cReview NFA executor and add comprehensive runtime tests
6174 - } 56aa37bRow pattern recognition patch (executor and commands).
6175 - 56aa37bRow pattern recognition patch (executor and commands).
6176 - /* Recursively process this branch before next */ 56aa37bRow pattern recognition patch (executor and commands).
6177 12514 nfa_advance_state(winstate, ctx, newState, currentPos, initialAdvance); 56aa37bRow pattern recognition patch (executor and commands).
6178 12514 altIdx = altElem->jump; 56aa37bRow pattern recognition patch (executor and commands).
6179 12523 } 56aa37bRow pattern recognition patch (executor and commands).
6180 - 56aa37bRow pattern recognition patch (executor and commands).
6181 - /* ALT must have at least one branch */ 9d2796cReview NFA executor and add comprehensive runtime tests
6182 5762 Assert(!first); 9d2796cReview NFA executor and add comprehensive runtime tests
6183 5762 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_advance_begin() lines 6194-6222
Modified Lines Coverage: 17/17 lines (100.0%)
LineHitsSourceCommit
6194 3885 nfa_advance_begin(WindowAggState *winstate, RPRNFAContext *ctx, 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6195 - RPRNFAState *state, RPRPatternElement *elem, 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6196 - int64 currentPos, bool initialAdvance) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6197 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6198 3885 RPRPattern *pattern = winstate->rpPattern; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6199 3885 RPRPatternElement *elements = pattern->elements; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6200 3885 RPRNFAState *skipState = NULL; 9d2796cReview NFA executor and add comprehensive runtime tests
6201 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6202 3885 state->counts[elem->depth] = 0; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6203 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6204 - /* Optional group: create skip path (but don't route yet) */ 9d2796cReview NFA executor and add comprehensive runtime tests
6205 3885 if (elem->min == 0) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6206 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6207 310 skipState = nfa_state_create(winstate, elem->jump, state->altPriority, 9d2796cReview NFA executor and add comprehensive runtime tests
6208 155 state->counts, state->isAbsorbable); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6209 155 } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6210 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6211 - /* Enter group: route to first child (lexically first) */ 9d2796cReview NFA executor and add comprehensive runtime tests
6212 3885 state->elemIdx = elem->next; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6213 7770 nfa_route_to_elem(winstate, ctx, state, 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6214 3885 &elements[state->elemIdx], currentPos, initialAdvance); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6215 - 9d2796cReview NFA executor and add comprehensive runtime tests
6216 - /* Now route skip path (lexically second) */ 9d2796cReview NFA executor and add comprehensive runtime tests
6217 3885 if (skipState != NULL) 9d2796cReview NFA executor and add comprehensive runtime tests
6218 - { 9d2796cReview NFA executor and add comprehensive runtime tests
6219 310 nfa_route_to_elem(winstate, ctx, skipState, 9d2796cReview NFA executor and add comprehensive runtime tests
6220 155 &elements[elem->jump], currentPos, initialAdvance); 9d2796cReview NFA executor and add comprehensive runtime tests
6221 155 } 9d2796cReview NFA executor and add comprehensive runtime tests
6222 3885 } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
nfa_advance_end() lines 6231-6323
Modified Lines Coverage: 44/44 lines (100.0%)
LineHitsSourceCommit
6231 2848 nfa_advance_end(WindowAggState *winstate, RPRNFAContext *ctx, 56aa37bRow pattern recognition patch (executor and commands).
6232 - RPRNFAState *state, RPRPatternElement *elem, 56aa37bRow pattern recognition patch (executor and commands).
6233 - int64 currentPos, bool initialAdvance) 56aa37bRow pattern recognition patch (executor and commands).
6234 - { 56aa37bRow pattern recognition patch (executor and commands).
6235 2848 RPRPattern *pattern = winstate->rpPattern; 56aa37bRow pattern recognition patch (executor and commands).
6236 2848 RPRPatternElement *elements = pattern->elements; 56aa37bRow pattern recognition patch (executor and commands).
6237 2848 int depth = elem->depth; 56aa37bRow pattern recognition patch (executor and commands).
6238 2848 int32 count = state->counts[depth]; 56aa37bRow pattern recognition patch (executor and commands).
6239 - 56aa37bRow pattern recognition patch (executor and commands).
6240 2848 if (count < elem->min) 56aa37bRow pattern recognition patch (executor and commands).
6241 - { 56aa37bRow pattern recognition patch (executor and commands).
6242 - /* Must loop back */ 56aa37bRow pattern recognition patch (executor and commands).
6243 840 RPRPatternElement *jumpElem; 56aa37bRow pattern recognition patch (executor and commands).
6244 - 56aa37bRow pattern recognition patch (executor and commands).
6245 2469 for (int d = depth + 1; d < pattern->maxDepth; d++) 56aa37bRow pattern recognition patch (executor and commands).
6246 1629 state->counts[d] = 0; 56aa37bRow pattern recognition patch (executor and commands).
6247 840 state->elemIdx = elem->jump; 56aa37bRow pattern recognition patch (executor and commands).
6248 840 jumpElem = &elements[state->elemIdx]; 56aa37bRow pattern recognition patch (executor and commands).
6249 - 56aa37bRow pattern recognition patch (executor and commands).
6250 840 nfa_route_to_elem(winstate, ctx, state, jumpElem, currentPos, initialAdvance); 56aa37bRow pattern recognition patch (executor and commands).
6251 840 } 56aa37bRow pattern recognition patch (executor and commands).
6252 2071 else if ((elem->max != RPR_QUANTITY_INF && count >= elem->max) || 56aa37bRow pattern recognition patch (executor and commands).
6253 1889 (count == 0 && elem->min == 0)) 56aa37bRow pattern recognition patch (executor and commands).
6254 - { 56aa37bRow pattern recognition patch (executor and commands).
6255 - /*---------- 74205caRun pgindent on RPR source files
6256 - * Must exit: either reached max iterations, or group matched empty. 56aa37bRow pattern recognition patch (executor and commands).
6257 - * 56aa37bRow pattern recognition patch (executor and commands).
6258 - * FIXME: The (count == 0 && min == 0) condition is insufficient for 9d2796cReview NFA executor and add comprehensive runtime tests
6259 - * cycle prevention. Cycles can occur at any count value when loop back 9d2796cReview NFA executor and add comprehensive runtime tests
6260 - * happens without consuming rows. For example: 9d2796cReview NFA executor and add comprehensive runtime tests
6261 - * Pattern: (A*)* 9d2796cReview NFA executor and add comprehensive runtime tests
6262 - * After matching 3 A's (count=3), loop back at a B row 9d2796cReview NFA executor and add comprehensive runtime tests
6263 - * Inner A* matches 0 times (skip path) → same (elemIdx, count=3) 9d2796cReview NFA executor and add comprehensive runtime tests
6264 - * Infinite cycle at count=3, not count=0 9d2796cReview NFA executor and add comprehensive runtime tests
6265 - * 9d2796cReview NFA executor and add comprehensive runtime tests
6266 - * Currently, cycles are silently prevented by nfa_add_state_unique 9d2796cReview NFA executor and add comprehensive runtime tests
6267 - * detecting duplicate states, but this is implicit and not guaranteed 9d2796cReview NFA executor and add comprehensive runtime tests
6268 - * for all code paths. Explicit cycle detection is needed. 9d2796cReview NFA executor and add comprehensive runtime tests
6269 - *---------- 74205caRun pgindent on RPR source files
6270 - */ 56aa37bRow pattern recognition patch (executor and commands).
6271 137 RPRPatternElement *nextElem; 56aa37bRow pattern recognition patch (executor and commands).
6272 - 56aa37bRow pattern recognition patch (executor and commands).
6273 137 state->counts[depth] = 0; 56aa37bRow pattern recognition patch (executor and commands).
6274 137 state->elemIdx = elem->next; 56aa37bRow pattern recognition patch (executor and commands).
6275 137 nextElem = &elements[state->elemIdx]; 56aa37bRow pattern recognition patch (executor and commands).
6276 - 56aa37bRow pattern recognition patch (executor and commands).
6277 - /* END->END: increment outer END's count */ 1cc2ebdFix non-ASCII characters in RPR code and comments
6278 137 if (RPRElemIsEnd(nextElem) && state->counts[nextElem->depth] < RPR_COUNT_MAX) 56aa37bRow pattern recognition patch (executor and commands).
6279 22 state->counts[nextElem->depth]++; 56aa37bRow pattern recognition patch (executor and commands).
6280 - 56aa37bRow pattern recognition patch (executor and commands).
6281 137 nfa_route_to_elem(winstate, ctx, state, nextElem, currentPos, initialAdvance); 56aa37bRow pattern recognition patch (executor and commands).
6282 137 } 56aa37bRow pattern recognition patch (executor and commands).
6283 - else 56aa37bRow pattern recognition patch (executor and commands).
6284 - { 56aa37bRow pattern recognition patch (executor and commands).
6285 - /* 56aa37bRow pattern recognition patch (executor and commands).
6286 - * Between min and max (with at least one iteration) - can exit or 56aa37bRow pattern recognition patch (executor and commands).
6287 - * loop 56aa37bRow pattern recognition patch (executor and commands).
6288 - */ 56aa37bRow pattern recognition patch (executor and commands).
6289 1889 RPRElemIdx exitAltPriority; 56aa37bRow pattern recognition patch (executor and commands).
6290 1889 RPRNFAState *exitState; 56aa37bRow pattern recognition patch (executor and commands).
6291 1889 RPRPatternElement *jumpElem; 56aa37bRow pattern recognition patch (executor and commands).
6292 1889 RPRPatternElement *nextElem; 56aa37bRow pattern recognition patch (executor and commands).
6293 - 56aa37bRow pattern recognition patch (executor and commands).
6294 - /* Preserve altPriority for greedy extension */ 56aa37bRow pattern recognition patch (executor and commands).
6295 1889 exitAltPriority = state->altPriority; 56aa37bRow pattern recognition patch (executor and commands).
6296 1889 if (ctx->matchedState != NULL) 56aa37bRow pattern recognition patch (executor and commands).
6297 680 exitAltPriority = ctx->matchedState->altPriority; 56aa37bRow pattern recognition patch (executor and commands).
6298 - 56aa37bRow pattern recognition patch (executor and commands).
6299 - /* 56aa37bRow pattern recognition patch (executor and commands).
6300 - * Create exit state first (need original counts before modifying 56aa37bRow pattern recognition patch (executor and commands).
6301 - * state) 56aa37bRow pattern recognition patch (executor and commands).
6302 - */ 56aa37bRow pattern recognition patch (executor and commands).
6303 3778 exitState = nfa_state_create(winstate, elem->next, exitAltPriority, 9d2796cReview NFA executor and add comprehensive runtime tests
6304 1889 state->counts, state->isAbsorbable); 9d2796cReview NFA executor and add comprehensive runtime tests
6305 1889 exitState->counts[depth] = 0; 56aa37bRow pattern recognition patch (executor and commands).
6306 1889 nextElem = &elements[exitState->elemIdx]; 56aa37bRow pattern recognition patch (executor and commands).
6307 - 56aa37bRow pattern recognition patch (executor and commands).
6308 - /* END->END: increment outer END's count */ 1cc2ebdFix non-ASCII characters in RPR code and comments
6309 1889 if (RPRElemIsEnd(nextElem) && exitState->counts[nextElem->depth] < RPR_COUNT_MAX) 56aa37bRow pattern recognition patch (executor and commands).
6310 45 exitState->counts[nextElem->depth]++; 56aa37bRow pattern recognition patch (executor and commands).
6311 - 56aa37bRow pattern recognition patch (executor and commands).
6312 - /* Route loop state first (earlier in pattern = lexical order) */ 56aa37bRow pattern recognition patch (executor and commands).
6313 5451 for (int d = depth + 1; d < pattern->maxDepth; d++) 56aa37bRow pattern recognition patch (executor and commands).
6314 3562 state->counts[d] = 0; 56aa37bRow pattern recognition patch (executor and commands).
6315 1889 state->elemIdx = elem->jump; 56aa37bRow pattern recognition patch (executor and commands).
6316 1889 jumpElem = &elements[state->elemIdx]; 56aa37bRow pattern recognition patch (executor and commands).
6317 - 56aa37bRow pattern recognition patch (executor and commands).
6318 1889 nfa_route_to_elem(winstate, ctx, state, jumpElem, currentPos, initialAdvance); 56aa37bRow pattern recognition patch (executor and commands).
6319 - 56aa37bRow pattern recognition patch (executor and commands).
6320 - /* Then route exit state */ 56aa37bRow pattern recognition patch (executor and commands).
6321 1889 nfa_route_to_elem(winstate, ctx, exitState, nextElem, currentPos, initialAdvance); 56aa37bRow pattern recognition patch (executor and commands).
6322 1889 } 56aa37bRow pattern recognition patch (executor and commands).
6323 2866 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_advance_var() lines 6332-6379
Modified Lines Coverage: 30/30 lines (100.0%)
LineHitsSourceCommit
6332 292383 nfa_advance_var(WindowAggState *winstate, RPRNFAContext *ctx, 56aa37bRow pattern recognition patch (executor and commands).
6333 - RPRNFAState *state, RPRPatternElement *elem, 56aa37bRow pattern recognition patch (executor and commands).
6334 - int64 currentPos, bool initialAdvance) 56aa37bRow pattern recognition patch (executor and commands).
6335 - { 56aa37bRow pattern recognition patch (executor and commands).
6336 292383 RPRPattern *pattern = winstate->rpPattern; 56aa37bRow pattern recognition patch (executor and commands).
6337 292383 RPRPatternElement *elements = pattern->elements; 56aa37bRow pattern recognition patch (executor and commands).
6338 292383 int depth = elem->depth; 56aa37bRow pattern recognition patch (executor and commands).
6339 292383 int32 count = state->counts[depth]; 56aa37bRow pattern recognition patch (executor and commands).
6340 292383 bool canLoop = (elem->max == RPR_QUANTITY_INF || count < elem->max); 56aa37bRow pattern recognition patch (executor and commands).
6341 292383 bool canExit = (count >= elem->min); 56aa37bRow pattern recognition patch (executor and commands).
6342 - 56aa37bRow pattern recognition patch (executor and commands).
6343 - /* After a successful match, count >= 1, so at least one must be true */ 9d2796cReview NFA executor and add comprehensive runtime tests
6344 292383 Assert(canLoop || canExit); 9d2796cReview NFA executor and add comprehensive runtime tests
6345 - 9d2796cReview NFA executor and add comprehensive runtime tests
6346 292383 if (canLoop && canExit) 56aa37bRow pattern recognition patch (executor and commands).
6347 - { 56aa37bRow pattern recognition patch (executor and commands).
6348 - /* Both: clone for loop, modify original for exit */ 56aa37bRow pattern recognition patch (executor and commands).
6349 100179 RPRNFAState *loopState; 56aa37bRow pattern recognition patch (executor and commands).
6350 100179 RPRPatternElement *nextElem; 56aa37bRow pattern recognition patch (executor and commands).
6351 - 56aa37bRow pattern recognition patch (executor and commands).
6352 200358 loopState = nfa_state_create(winstate, state->elemIdx, state->altPriority, 9d2796cReview NFA executor and add comprehensive runtime tests
6353 100179 state->counts, state->isAbsorbable); 9d2796cReview NFA executor and add comprehensive runtime tests
6354 100179 nfa_add_state_unique(winstate, ctx, loopState); 56aa37bRow pattern recognition patch (executor and commands).
6355 - 56aa37bRow pattern recognition patch (executor and commands).
6356 - /* Exit: advance to next element */ 56aa37bRow pattern recognition patch (executor and commands).
6357 100179 state->counts[depth] = 0; 56aa37bRow pattern recognition patch (executor and commands).
6358 100179 state->elemIdx = elem->next; 56aa37bRow pattern recognition patch (executor and commands).
6359 100179 nextElem = &elements[state->elemIdx]; 56aa37bRow pattern recognition patch (executor and commands).
6360 - 56aa37bRow pattern recognition patch (executor and commands).
6361 100179 nfa_route_to_elem(winstate, ctx, state, nextElem, currentPos, initialAdvance); 56aa37bRow pattern recognition patch (executor and commands).
6362 100179 } 56aa37bRow pattern recognition patch (executor and commands).
6363 192204 else if (canLoop) 56aa37bRow pattern recognition patch (executor and commands).
6364 - { 56aa37bRow pattern recognition patch (executor and commands).
6365 - /* Loop only: keep state as-is */ 56aa37bRow pattern recognition patch (executor and commands).
6366 181434 nfa_add_state_unique(winstate, ctx, state); 56aa37bRow pattern recognition patch (executor and commands).
6367 181434 } 56aa37bRow pattern recognition patch (executor and commands).
6368 10770 else if (canExit) 56aa37bRow pattern recognition patch (executor and commands).
6369 - { 56aa37bRow pattern recognition patch (executor and commands).
6370 - /* Exit only: advance to next element */ 9d2796cReview NFA executor and add comprehensive runtime tests
6371 10770 RPRPatternElement *nextElem; 56aa37bRow pattern recognition patch (executor and commands).
6372 - 56aa37bRow pattern recognition patch (executor and commands).
6373 10770 state->counts[depth] = 0; 56aa37bRow pattern recognition patch (executor and commands).
6374 10770 state->elemIdx = elem->next; 56aa37bRow pattern recognition patch (executor and commands).
6375 10770 nextElem = &elements[state->elemIdx]; 56aa37bRow pattern recognition patch (executor and commands).
6376 - 56aa37bRow pattern recognition patch (executor and commands).
6377 10770 nfa_route_to_elem(winstate, ctx, state, nextElem, currentPos, initialAdvance); 56aa37bRow pattern recognition patch (executor and commands).
6378 10770 } 56aa37bRow pattern recognition patch (executor and commands).
6379 292383 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_advance_state() lines 6390-6426
Modified Lines Coverage: 19/19 lines (100.0%)
LineHitsSourceCommit
6390 343290 nfa_advance_state(WindowAggState *winstate, RPRNFAContext *ctx, 56aa37bRow pattern recognition patch (executor and commands).
6391 - RPRNFAState *state, int64 currentPos, bool initialAdvance) 56aa37bRow pattern recognition patch (executor and commands).
6392 - { 56aa37bRow pattern recognition patch (executor and commands).
6393 343290 RPRPattern *pattern = winstate->rpPattern; 56aa37bRow pattern recognition patch (executor and commands).
6394 343290 RPRPatternElement *elem; 56aa37bRow pattern recognition patch (executor and commands).
6395 - 56aa37bRow pattern recognition patch (executor and commands).
6396 343290 Assert(state->elemIdx >= 0 && state->elemIdx < pattern->numElements); 56aa37bRow pattern recognition patch (executor and commands).
6397 343290 elem = &pattern->elements[state->elemIdx]; 56aa37bRow pattern recognition patch (executor and commands).
6398 - 56aa37bRow pattern recognition patch (executor and commands).
6399 343290 switch (elem->varId) 56aa37bRow pattern recognition patch (executor and commands).
6400 - { 56aa37bRow pattern recognition patch (executor and commands).
6401 - case RPR_VARID_FIN: 56aa37bRow pattern recognition patch (executor and commands).
6402 - /* FIN: record match (skip for initial advance) */ 56aa37bRow pattern recognition patch (executor and commands).
6403 38394 if (!initialAdvance) 56aa37bRow pattern recognition patch (executor and commands).
6404 38090 nfa_add_matched_state(winstate, ctx, state, currentPos); 56aa37bRow pattern recognition patch (executor and commands).
6405 - else 56aa37bRow pattern recognition patch (executor and commands).
6406 304 nfa_state_free(winstate, state); 56aa37bRow pattern recognition patch (executor and commands).
6407 38394 break; 56aa37bRow pattern recognition patch (executor and commands).
6408 - 56aa37bRow pattern recognition patch (executor and commands).
6409 - case RPR_VARID_ALT: 56aa37bRow pattern recognition patch (executor and commands).
6410 5762 nfa_advance_alt(winstate, ctx, state, elem, currentPos, initialAdvance); 56aa37bRow pattern recognition patch (executor and commands).
6411 5762 break; 56aa37bRow pattern recognition patch (executor and commands).
6412 - 56aa37bRow pattern recognition patch (executor and commands).
6413 - case RPR_VARID_BEGIN: 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6414 3885 nfa_advance_begin(winstate, ctx, state, elem, currentPos, initialAdvance); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6415 3885 break; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6416 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
6417 - case RPR_VARID_END: 56aa37bRow pattern recognition patch (executor and commands).
6418 2866 nfa_advance_end(winstate, ctx, state, elem, currentPos, initialAdvance); 56aa37bRow pattern recognition patch (executor and commands).
6419 2866 break; 56aa37bRow pattern recognition patch (executor and commands).
6420 - 56aa37bRow pattern recognition patch (executor and commands).
6421 - default: 56aa37bRow pattern recognition patch (executor and commands).
6422 - /* VAR element */ 56aa37bRow pattern recognition patch (executor and commands).
6423 292383 nfa_advance_var(winstate, ctx, state, elem, currentPos, initialAdvance); 56aa37bRow pattern recognition patch (executor and commands).
6424 292383 break; 56aa37bRow pattern recognition patch (executor and commands).
6425 - } 56aa37bRow pattern recognition patch (executor and commands).
6426 343290 } 56aa37bRow pattern recognition patch (executor and commands).
nfa_advance() lines 6438-6455
Modified Lines Coverage: 10/10 lines (100.0%)
LineHitsSourceCommit
6438 253356 nfa_advance(WindowAggState *winstate, RPRNFAContext *ctx, int64 currentPos, 56aa37bRow pattern recognition patch (executor and commands).
6439 - bool initialAdvance) 56aa37bRow pattern recognition patch (executor and commands).
6440 - { 56aa37bRow pattern recognition patch (executor and commands).
6441 253356 RPRNFAState *states = ctx->states; 56aa37bRow pattern recognition patch (executor and commands).
6442 253356 RPRNFAState *state; 56aa37bRow pattern recognition patch (executor and commands).
6443 - 56aa37bRow pattern recognition patch (executor and commands).
6444 253356 ctx->states = NULL; /* Will rebuild */ 56aa37bRow pattern recognition patch (executor and commands).
6445 - 56aa37bRow pattern recognition patch (executor and commands).
6446 - /* Process each state in order */ 56aa37bRow pattern recognition patch (executor and commands).
6447 506315 while (states != NULL) 56aa37bRow pattern recognition patch (executor and commands).
6448 - { 56aa37bRow pattern recognition patch (executor and commands).
6449 252959 state = states; 56aa37bRow pattern recognition patch (executor and commands).
6450 252959 states = states->next; 56aa37bRow pattern recognition patch (executor and commands).
6451 252959 state->next = NULL; 56aa37bRow pattern recognition patch (executor and commands).
6452 - 56aa37bRow pattern recognition patch (executor and commands).
6453 252959 nfa_advance_state(winstate, ctx, state, currentPos, initialAdvance); 56aa37bRow pattern recognition patch (executor and commands).
6454 - } 56aa37bRow pattern recognition patch (executor and commands).
6455 253356 } 56aa37bRow pattern recognition patch (executor and commands).