← Back to Overview

src/backend/executor/nodeWindowAgg.c

Coverage: 560/580 lines (96.6%)
Total Lines
580
modified
Covered
560
96.6%
Uncovered
20
3.4%
키보드 네비게이션
STRSET_MATCHED() lines 181-192
Modified Lines Coverage: 0/0 lines (0.0%)
LineHitsSourceCommit
181 - #define STRSET_MATCHED (1 << 2) /* string is confirmed to be matched 2abe7c8Row pattern recognition patch (executor).
182 - * with pattern */ 2abe7c8Row pattern recognition patch (executor).
183 - 2abe7c8Row pattern recognition patch (executor).
184 - typedef struct StringSet 2abe7c8Row pattern recognition patch (executor).
185 - { 2abe7c8Row pattern recognition patch (executor).
186 - StringInfo *str_set; 2abe7c8Row pattern recognition patch (executor).
187 - Size set_size; /* current array allocation size in number of 2abe7c8Row pattern recognition patch (executor).
188 - * items */ 2abe7c8Row pattern recognition patch (executor).
189 - int set_index; /* current used size */ 2abe7c8Row pattern recognition patch (executor).
190 - int *info; /* an array of information bit per StringInfo. 2abe7c8Row pattern recognition patch (executor).
191 - * see above */ 2abe7c8Row pattern recognition patch (executor).
192 - } StringSet; 2abe7c8Row pattern recognition patch (executor).
eval_windowaggregates() lines 788-1223
Modified Lines Coverage: 19/19 lines (100.0%)
LineHitsSourceCommit
788 - eval_windowaggregates(WindowAggState *winstate) -
789 - { -
790 - WindowStatePerAgg peraggstate; -
791 - int wfuncno, -
792 - numaggs, -
793 - numaggs_restart, -
794 - i; -
795 - int64 aggregatedupto_nonrestarted; -
796 - MemoryContext oldContext; -
797 - ExprContext *econtext; -
798 - WindowObject agg_winobj; -
799 - TupleTableSlot *agg_row_slot; -
800 - TupleTableSlot *temp_slot; -
801 - -
802 - numaggs = winstate->numaggs; -
803 - if (numaggs == 0) -
804 - return; /* nothing to do */ -
805 - -
806 - /* final output execution is in ps_ExprContext */ -
807 - econtext = winstate->ss.ps.ps_ExprContext; -
808 - agg_winobj = winstate->agg_winobj; -
809 - agg_row_slot = winstate->agg_row_slot; -
810 - temp_slot = winstate->temp_slot_1; -
811 - -
812 - /* -
813 - * If the window's frame start clause is UNBOUNDED_PRECEDING and no -
814 - * exclusion clause is specified, then the window frame consists of a -
815 - * contiguous group of rows extending forward from the start of the -
816 - * partition, and rows only enter the frame, never exit it, as the current -
817 - * row advances forward. This makes it possible to use an incremental -
818 - * strategy for evaluating aggregates: we run the transition function for -
819 - * each row added to the frame, and run the final function whenever we -
820 - * need the current aggregate value. This is considerably more efficient -
821 - * than the naive approach of re-running the entire aggregate calculation -
822 - * for each current row. It does assume that the final function doesn't -
823 - * damage the running transition value, but we have the same assumption in -
824 - * nodeAgg.c too (when it rescans an existing hash table). -
825 - * -
826 - * If the frame start does sometimes move, we can still optimize as above -
827 - * whenever successive rows share the same frame head, but if the frame -
828 - * head moves beyond the previous head we try to remove those rows using -
829 - * the aggregate's inverse transition function. This function restores -
830 - * the aggregate's current state to what it would be if the removed row -
831 - * had never been aggregated in the first place. Inverse transition -
832 - * functions may optionally return NULL, indicating that the function was -
833 - * unable to remove the tuple from aggregation. If this happens, or if -
834 - * the aggregate doesn't have an inverse transition function at all, we -
835 - * must perform the aggregation all over again for all tuples within the -
836 - * new frame boundaries. -
837 - * -
838 - * If there's any exclusion clause, then we may have to aggregate over a -
839 - * non-contiguous set of rows, so we punt and recalculate for every row. -
840 - * (For some frame end choices, it might be that the frame is always -
841 - * contiguous anyway, but that's an optimization to investigate later.) -
842 - * -
843 - * In many common cases, multiple rows share the same frame and hence the -
844 - * same aggregate value. (In particular, if there's no ORDER BY in a RANGE -
845 - * window, then all rows are peers and so they all have window frame equal -
846 - * to the whole partition.) We optimize such cases by calculating the -
847 - * aggregate value once when we reach the first row of a peer group, and -
848 - * then returning the saved value for all subsequent rows. -
849 - * -
850 - * 'aggregatedupto' keeps track of the first row that has not yet been -
851 - * accumulated into the aggregate transition values. Whenever we start a -
852 - * new peer group, we accumulate forward to the end of the peer group. -
853 - */ -
854 - -
855 - /* -
856 - * First, update the frame head position. -
857 - * -
858 - * The frame head should never move backwards, and the code below wouldn't -
859 - * cope if it did, so for safety we complain if it does. -
860 - */ -
861 - update_frameheadpos(winstate); -
862 - if (winstate->frameheadpos < winstate->aggregatedbase) -
863 - elog(ERROR, "window frame head moved backward"); -
864 - -
865 - /* -
866 - * If the frame didn't change compared to the previous row, we can re-use -
867 - * the result values that were previously saved at the bottom of this -
868 - * function. Since we don't know the current frame's end yet, this is not -
869 - * possible to check for fully. But if the frame end mode is UNBOUNDED -
870 - * FOLLOWING or CURRENT ROW, no exclusion clause is specified, and the -
871 - * current row lies within the previous row's frame, then the two frames' -
872 - * ends must coincide. Note that on the first row aggregatedbase == -
873 - * aggregatedupto, meaning this test must fail, so we don't need to check -
874 - * the "there was no previous row" case explicitly here. -
875 - */ -
876 - if (winstate->aggregatedbase == winstate->frameheadpos && -
877 - (winstate->frameOptions & (FRAMEOPTION_END_UNBOUNDED_FOLLOWING | -
878 - FRAMEOPTION_END_CURRENT_ROW)) && -
879 - !(winstate->frameOptions & FRAMEOPTION_EXCLUSION) && -
880 - winstate->aggregatedbase <= winstate->currentpos && -
881 - winstate->aggregatedupto > winstate->currentpos) -
882 - { -
883 - for (i = 0; i < numaggs; i++) -
884 - { -
885 - peraggstate = &winstate->peragg[i]; -
886 - wfuncno = peraggstate->wfuncno; -
887 - econtext->ecxt_aggvalues[wfuncno] = peraggstate->resultValue; -
888 - econtext->ecxt_aggnulls[wfuncno] = peraggstate->resultValueIsNull; -
889 - } -
890 - return; -
891 - } -
892 - -
893 - /*---------- -
894 - * Initialize restart flags. -
895 - * -
896 - * We restart the aggregation: -
897 - * - if we're processing the first row in the partition, or -
898 - * - if the frame's head moved and we cannot use an inverse -
899 - * transition function, or -
900 - * - we have an EXCLUSION clause, or -
901 - * - if the new frame doesn't overlap the old one -
902 - * - if RPR is enabled 2abe7c8Row pattern recognition patch (executor).
903 - * -
904 - * Note that we don't strictly need to restart in the last case, but if -
905 - * we're going to remove all rows from the aggregation anyway, a restart -
906 - * surely is faster. -
907 - *---------- -
908 - */ -
909 - numaggs_restart = 0; -
910 - for (i = 0; i < numaggs; i++) -
911 - { -
912 - peraggstate = &winstate->peragg[i]; -
913 - if (winstate->currentpos == 0 || -
914 - (winstate->aggregatedbase != winstate->frameheadpos && -
915 - !OidIsValid(peraggstate->invtransfn_oid)) || -
916 - (winstate->frameOptions & FRAMEOPTION_EXCLUSION) || -
917 19277 winstate->aggregatedupto <= winstate->frameheadpos || 2abe7c8Row pattern recognition patch (executor).
918 3665 rpr_is_defined(winstate)) 2abe7c8Row pattern recognition patch (executor).
919 - { -
920 - peraggstate->restart = true; -
921 - numaggs_restart++; -
922 - } -
923 - else -
924 - peraggstate->restart = false; -
925 - } -
926 - -
927 - /* -
928 - * If we have any possibly-moving aggregates, attempt to advance -
929 - * aggregatedbase to match the frame's head by removing input rows that -
930 - * fell off the top of the frame from the aggregations. This can fail, -
931 - * i.e. advance_windowaggregate_base() can return false, in which case -
932 - * we'll restart that aggregate below. -
933 - */ -
934 - while (numaggs_restart < numaggs && -
935 - winstate->aggregatedbase < winstate->frameheadpos) -
936 - { -
937 - /* -
938 - * Fetch the next tuple of those being removed. This should never fail -
939 - * as we should have been here before. -
940 - */ -
941 - if (!window_gettupleslot(agg_winobj, winstate->aggregatedbase, -
942 - temp_slot)) -
943 - elog(ERROR, "could not re-fetch previously fetched frame row"); -
944 - -
945 - /* Set tuple context for evaluation of aggregate arguments */ -
946 - winstate->tmpcontext->ecxt_outertuple = temp_slot; -
947 - -
948 - /* -
949 - * Perform the inverse transition for each aggregate function in the -
950 - * window, unless it has already been marked as needing a restart. -
951 - */ -
952 - for (i = 0; i < numaggs; i++) -
953 - { -
954 - bool ok; -
955 - -
956 - peraggstate = &winstate->peragg[i]; -
957 - if (peraggstate->restart) -
958 - continue; -
959 - -
960 - wfuncno = peraggstate->wfuncno; -
961 - ok = advance_windowaggregate_base(winstate, -
962 - &winstate->perfunc[wfuncno], -
963 - peraggstate); -
964 - if (!ok) -
965 - { -
966 - /* Inverse transition function has failed, must restart */ -
967 - peraggstate->restart = true; -
968 - numaggs_restart++; -
969 - } -
970 - } -
971 - -
972 - /* Reset per-input-tuple context after each tuple */ -
973 - ResetExprContext(winstate->tmpcontext); -
974 - -
975 - /* And advance the aggregated-row state */ -
976 - winstate->aggregatedbase++; -
977 - ExecClearTuple(temp_slot); -
978 - } -
979 - -
980 - /* -
981 - * If we successfully advanced the base rows of all the aggregates, -
982 - * aggregatedbase now equals frameheadpos; but if we failed for any, we -
983 - * must forcibly update aggregatedbase. -
984 - */ -
985 - winstate->aggregatedbase = winstate->frameheadpos; -
986 - -
987 - /* -
988 - * If we created a mark pointer for aggregates, keep it pushed up to frame -
989 - * head, so that tuplestore can discard unnecessary rows. -
990 - */ -
991 - if (agg_winobj->markptr >= 0) -
992 - { 2abe7c8Row pattern recognition patch (executor).
993 18457 int64 markpos = winstate->frameheadpos; 2abe7c8Row pattern recognition patch (executor).
994 - 2abe7c8Row pattern recognition patch (executor).
995 18457 if (rpr_is_defined(winstate)) 2abe7c8Row pattern recognition patch (executor).
996 - { 2abe7c8Row pattern recognition patch (executor).
997 - /* 2abe7c8Row pattern recognition patch (executor).
998 - * If RPR is used, it is possible PREV wants to look at the 2abe7c8Row pattern recognition patch (executor).
999 - * previous row. So the mark pos should be frameheadpos - 1 2abe7c8Row pattern recognition patch (executor).
1000 - * unless it is below 0. 2abe7c8Row pattern recognition patch (executor).
1001 - */ 2abe7c8Row pattern recognition patch (executor).
1002 15345 markpos -= 1; 2abe7c8Row pattern recognition patch (executor).
1003 15345 if (markpos < 0) 2abe7c8Row pattern recognition patch (executor).
1004 42 markpos = 0; 2abe7c8Row pattern recognition patch (executor).
1005 - } 2abe7c8Row pattern recognition patch (executor).
1006 18457 WinSetMarkPosition(agg_winobj, markpos); 2abe7c8Row pattern recognition patch (executor).
1007 - } 2abe7c8Row pattern recognition patch (executor).
1008 - -
1009 - /* -
1010 - * Now restart the aggregates that require it. -
1011 - * -
1012 - * We assume that aggregates using the shared context always restart if -
1013 - * *any* aggregate restarts, and we may thus clean up the shared -
1014 - * aggcontext if that is the case. Private aggcontexts are reset by -
1015 - * initialize_windowaggregate() if their owning aggregate restarts. If we -
1016 - * aren't restarting an aggregate, we need to free any previously saved -
1017 - * result for it, else we'll leak memory. -
1018 - */ -
1019 - if (numaggs_restart > 0) -
1020 - MemoryContextReset(winstate->aggcontext); -
1021 - for (i = 0; i < numaggs; i++) -
1022 - { -
1023 - peraggstate = &winstate->peragg[i]; -
1024 - -
1025 - /* Aggregates using the shared ctx must restart if *any* agg does */ -
1026 - Assert(peraggstate->aggcontext != winstate->aggcontext || -
1027 - numaggs_restart == 0 || -
1028 - peraggstate->restart); -
1029 - -
1030 - if (peraggstate->restart) -
1031 - { -
1032 - wfuncno = peraggstate->wfuncno; -
1033 - initialize_windowaggregate(winstate, -
1034 - &winstate->perfunc[wfuncno], -
1035 - peraggstate); -
1036 - } -
1037 - else if (!peraggstate->resultValueIsNull) -
1038 - { -
1039 - if (!peraggstate->resulttypeByVal) -
1040 - pfree(DatumGetPointer(peraggstate->resultValue)); -
1041 - peraggstate->resultValue = (Datum) 0; -
1042 - peraggstate->resultValueIsNull = true; -
1043 - } -
1044 - } -
1045 - -
1046 - /* -
1047 - * Non-restarted aggregates now contain the rows between aggregatedbase -
1048 - * (i.e., frameheadpos) and aggregatedupto, while restarted aggregates -
1049 - * contain no rows. If there are any restarted aggregates, we must thus -
1050 - * begin aggregating anew at frameheadpos, otherwise we may simply -
1051 - * continue at aggregatedupto. We must remember the old value of -
1052 - * aggregatedupto to know how long to skip advancing non-restarted -
1053 - * aggregates. If we modify aggregatedupto, we must also clear -
1054 - * agg_row_slot, per the loop invariant below. -
1055 - */ -
1056 - aggregatedupto_nonrestarted = winstate->aggregatedupto; -
1057 - if (numaggs_restart > 0 && -
1058 - winstate->aggregatedupto != winstate->frameheadpos) -
1059 - { -
1060 - winstate->aggregatedupto = winstate->frameheadpos; -
1061 - ExecClearTuple(agg_row_slot); -
1062 - 2abe7c8Row pattern recognition patch (executor).
1063 - /* 2abe7c8Row pattern recognition patch (executor).
1064 - * If RPR is defined, we do not use aggregatedupto_nonrestarted. To 2abe7c8Row pattern recognition patch (executor).
1065 - * avoid assertion failure below, we reset aggregatedupto_nonrestarted 2abe7c8Row pattern recognition patch (executor).
1066 - * to frameheadpos. 2abe7c8Row pattern recognition patch (executor).
1067 - */ 2abe7c8Row pattern recognition patch (executor).
1068 995 if (rpr_is_defined(winstate)) 2abe7c8Row pattern recognition patch (executor).
1069 294 aggregatedupto_nonrestarted = winstate->frameheadpos; 2abe7c8Row pattern recognition patch (executor).
1070 - } -
1071 - -
1072 - /* -
1073 - * Advance until we reach a row not in frame (or end of partition). -
1074 - * -
1075 - * Note the loop invariant: agg_row_slot is either empty or holds the row -
1076 - * at position aggregatedupto. We advance aggregatedupto after processing -
1077 - * a row. -
1078 - */ -
1079 - for (;;) -
1080 - { -
1081 - int ret; -
1082 - -
1083 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
1084 - elog(DEBUG1, "===== loop in frame starts: aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT, 2abe7c8Row pattern recognition patch (executor).
1085 - winstate->aggregatedupto, 2abe7c8Row pattern recognition patch (executor).
1086 - winstate->aggregatedbase); 2abe7c8Row pattern recognition patch (executor).
1087 - #endif 2abe7c8Row pattern recognition patch (executor).
1088 - 2abe7c8Row pattern recognition patch (executor).
1089 - /* Fetch next row if we didn't already */ -
1090 - if (TupIsNull(agg_row_slot)) -
1091 - { -
1092 - if (!window_gettupleslot(agg_winobj, winstate->aggregatedupto, -
1093 - agg_row_slot)) -
1094 - break; /* must be end of partition */ -
1095 - } -
1096 - -
1097 - /* -
1098 - * Exit loop if no more rows can be in frame. Skip aggregation if -
1099 - * current row is not in frame but there might be more in the frame. -
1100 - */ -
1101 - ret = row_is_in_frame(agg_winobj, winstate->aggregatedupto, -
1102 - agg_row_slot, false); -
1103 - if (ret < 0) -
1104 - break; -
1105 - 2abe7c8Row pattern recognition patch (executor).
1106 - if (ret == 0) -
1107 - goto next_tuple; -
1108 - -
1109 132893 if (rpr_is_defined(winstate)) 2abe7c8Row pattern recognition patch (executor).
1110 - { 2abe7c8Row pattern recognition patch (executor).
1111 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
1112 - elog(DEBUG1, "reduced_frame_map: %d aggregatedupto: " INT64_FORMAT " aggregatedbase: " INT64_FORMAT, 2abe7c8Row pattern recognition patch (executor).
1113 - get_reduced_frame_map(winstate, 2abe7c8Row pattern recognition patch (executor).
1114 - winstate->aggregatedupto), 2abe7c8Row pattern recognition patch (executor).
1115 - winstate->aggregatedupto, 2abe7c8Row pattern recognition patch (executor).
1116 - winstate->aggregatedbase); 2abe7c8Row pattern recognition patch (executor).
1117 - #endif 2abe7c8Row pattern recognition patch (executor).
1118 - 2abe7c8Row pattern recognition patch (executor).
1119 - /* 2abe7c8Row pattern recognition patch (executor).
1120 - * If the row status at currentpos is already decided and current 2abe7c8Row pattern recognition patch (executor).
1121 - * row status is not decided yet, it means we passed the last 2abe7c8Row pattern recognition patch (executor).
1122 - * reduced frame. Time to break the loop. 2abe7c8Row pattern recognition patch (executor).
1123 - */ 2abe7c8Row pattern recognition patch (executor).
1124 45561 if (get_reduced_frame_map(winstate, winstate->currentpos) 2abe7c8Row pattern recognition patch (executor).
1125 30453 != RF_NOT_DETERMINED && 2abe7c8Row pattern recognition patch (executor).
1126 30453 get_reduced_frame_map(winstate, winstate->aggregatedupto) 2abe7c8Row pattern recognition patch (executor).
1127 - == RF_NOT_DETERMINED) 2abe7c8Row pattern recognition patch (executor).
1128 - break; 2abe7c8Row pattern recognition patch (executor).
1129 - 2abe7c8Row pattern recognition patch (executor).
1130 - /* 2abe7c8Row pattern recognition patch (executor).
1131 - * Otherwise we need to calculate the reduced frame. 2abe7c8Row pattern recognition patch (executor).
1132 - */ 2abe7c8Row pattern recognition patch (executor).
1133 30504 ret = row_is_in_reduced_frame(winstate->agg_winobj, 2abe7c8Row pattern recognition patch (executor).
1134 - winstate->aggregatedupto); 2abe7c8Row pattern recognition patch (executor).
1135 30504 if (ret == -1) /* unmatched row */ 2abe7c8Row pattern recognition patch (executor).
1136 - break; 2abe7c8Row pattern recognition patch (executor).
1137 - 2abe7c8Row pattern recognition patch (executor).
1138 - /* 2abe7c8Row pattern recognition patch (executor).
1139 - * Check if current row needs to be skipped due to no match. 2abe7c8Row pattern recognition patch (executor).
1140 - */ 2abe7c8Row pattern recognition patch (executor).
1141 30345 if (get_reduced_frame_map(winstate, 2abe7c8Row pattern recognition patch (executor).
1142 15264 winstate->aggregatedupto) == RF_SKIPPED && 2abe7c8Row pattern recognition patch (executor).
1143 15264 winstate->aggregatedupto == winstate->aggregatedbase) 2abe7c8Row pattern recognition patch (executor).
1144 - { 2abe7c8Row pattern recognition patch (executor).
1145 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
1146 - elog(DEBUG1, "skip current row for aggregation"); 2abe7c8Row pattern recognition patch (executor).
1147 - #endif 2abe7c8Row pattern recognition patch (executor).
1148 - break; 2abe7c8Row pattern recognition patch (executor).
1149 - } 2abe7c8Row pattern recognition patch (executor).
1150 - } 2abe7c8Row pattern recognition patch (executor).
1151 - 2abe7c8Row pattern recognition patch (executor).
1152 - /* Set tuple context for evaluation of aggregate arguments */ -
1153 - winstate->tmpcontext->ecxt_outertuple = agg_row_slot; -
1154 - -
1155 - /* Accumulate row into the aggregates */ -
1156 - for (i = 0; i < numaggs; i++) -
1157 - { -
1158 - peraggstate = &winstate->peragg[i]; -
1159 - -
1160 - /* Non-restarted aggs skip until aggregatedupto_nonrestarted */ -
1161 - if (!peraggstate->restart && -
1162 - winstate->aggregatedupto < aggregatedupto_nonrestarted) -
1163 - continue; -
1164 - -
1165 - wfuncno = peraggstate->wfuncno; -
1166 - advance_windowaggregate(winstate, -
1167 - &winstate->perfunc[wfuncno], -
1168 - peraggstate); -
1169 - } -
1170 - -
1171 - next_tuple: -
1172 - /* Reset per-input-tuple context after each tuple */ -
1173 - ResetExprContext(winstate->tmpcontext); -
1174 - -
1175 - /* And advance the aggregated-row state */ -
1176 - winstate->aggregatedupto++; -
1177 - ExecClearTuple(agg_row_slot); -
1178 - } -
1179 - -
1180 - 2abe7c8Row pattern recognition patch (executor).
1181 - /* The frame's end is not supposed to move backwards, ever */ -
1182 - Assert(aggregatedupto_nonrestarted <= winstate->aggregatedupto); -
1183 - -
1184 - /* -
1185 - * finalize aggregates and fill result/isnull fields. -
1186 - */ -
1187 - for (i = 0; i < numaggs; i++) -
1188 - { -
1189 - Datum *result; -
1190 - bool *isnull; -
1191 - -
1192 - peraggstate = &winstate->peragg[i]; -
1193 - wfuncno = peraggstate->wfuncno; -
1194 - result = &econtext->ecxt_aggvalues[wfuncno]; -
1195 - isnull = &econtext->ecxt_aggnulls[wfuncno]; -
1196 - finalize_windowaggregate(winstate, -
1197 - &winstate->perfunc[wfuncno], -
1198 - peraggstate, -
1199 - result, isnull); -
1200 - -
1201 - /* -
1202 - * save the result in case next row shares the same frame. -
1203 - * -
1204 - * XXX in some framing modes, eg ROWS/END_CURRENT_ROW, we can know in -
1205 - * advance that the next row can't possibly share the same frame. Is -
1206 - * it worth detecting that and skipping this code? -
1207 - */ -
1208 - if (!peraggstate->resulttypeByVal && !*isnull) -
1209 - { -
1210 - oldContext = MemoryContextSwitchTo(peraggstate->aggcontext); -
1211 - peraggstate->resultValue = -
1212 - datumCopy(*result, -
1213 - peraggstate->resulttypeByVal, -
1214 - peraggstate->resulttypeLen); -
1215 - MemoryContextSwitchTo(oldContext); -
1216 - } -
1217 - else -
1218 - { -
1219 - peraggstate->resultValue = *result; -
1220 - } -
1221 - peraggstate->resultValueIsNull = *isnull; -
1222 - } -
1223 - } -
begin_partition() lines 1395-1494
Modified Lines Coverage: 1/1 lines (100.0%)
LineHitsSourceCommit
1395 - begin_partition(WindowAggState *winstate) -
1396 - { -
1397 - PlanState *outerPlan = outerPlanState(winstate); -
1398 - int numfuncs = winstate->numfuncs; -
1399 - -
1400 - winstate->partition_spooled = false; -
1401 - winstate->framehead_valid = false; -
1402 - winstate->frametail_valid = false; -
1403 - winstate->grouptail_valid = false; -
1404 1936 create_reduced_frame_map(winstate); 2abe7c8Row pattern recognition patch (executor).
1405 - winstate->spooled_rows = 0; -
1406 - winstate->currentpos = 0; -
1407 - winstate->frameheadpos = 0; -
1408 - winstate->frametailpos = 0; -
1409 - winstate->currentgroup = 0; -
1410 - winstate->frameheadgroup = 0; -
1411 - winstate->frametailgroup = 0; -
1412 - winstate->groupheadpos = 0; -
1413 - winstate->grouptailpos = -1; /* see update_grouptailpos */ -
1414 - ExecClearTuple(winstate->agg_row_slot); -
1415 - if (winstate->framehead_slot) -
1416 - ExecClearTuple(winstate->framehead_slot); -
1417 - if (winstate->frametail_slot) -
1418 - ExecClearTuple(winstate->frametail_slot); -
1419 - -
1420 - /* -
1421 - * If this is the very first partition, we need to fetch the first input -
1422 - * row to store in first_part_slot. -
1423 - */ -
1424 - if (TupIsNull(winstate->first_part_slot)) -
1425 - { -
1426 - TupleTableSlot *outerslot = ExecProcNode(outerPlan); -
1427 - -
1428 - if (!TupIsNull(outerslot)) -
1429 - ExecCopySlot(winstate->first_part_slot, outerslot); -
1430 - else -
1431 - { -
1432 - /* outer plan is empty, so we have nothing to do */ -
1433 - winstate->partition_spooled = true; -
1434 - winstate->more_partitions = false; -
1435 - return; -
1436 - } -
1437 - } -
1438 - -
1439 - /* Create new tuplestore if not done already. */ -
1440 - if (unlikely(winstate->buffer == NULL)) -
1441 - prepare_tuplestore(winstate); -
1442 - -
1443 - winstate->next_partition = false; -
1444 - -
1445 - if (winstate->numaggs > 0) -
1446 - { -
1447 - WindowObject agg_winobj = winstate->agg_winobj; -
1448 - -
1449 - /* reset mark and see positions for aggregate functions */ -
1450 - agg_winobj->markpos = -1; -
1451 - agg_winobj->seekpos = -1; -
1452 - -
1453 - /* Also reset the row counters for aggregates */ -
1454 - winstate->aggregatedbase = 0; -
1455 - winstate->aggregatedupto = 0; -
1456 - } -
1457 - -
1458 - /* reset mark and seek positions for each real window function */ -
1459 - for (int i = 0; i < numfuncs; i++) -
1460 - { -
1461 - WindowStatePerFunc perfuncstate = &(winstate->perfunc[i]); -
1462 - -
1463 - if (!perfuncstate->plain_agg) -
1464 - { -
1465 - WindowObject winobj = perfuncstate->winobj; -
1466 - -
1467 - winobj->markpos = -1; -
1468 - winobj->seekpos = -1; -
1469 - -
1470 - /* reset null map */ -
1471 - if (winobj->ignore_nulls == IGNORE_NULLS || -
1472 - winobj->ignore_nulls == PARSER_IGNORE_NULLS) -
1473 - { -
1474 - int numargs = perfuncstate->numArguments; -
1475 - -
1476 - for (int j = 0; j < numargs; j++) -
1477 - { -
1478 - int n = winobj->num_notnull_info[j]; -
1479 - -
1480 - if (n > 0) -
1481 - memset(winobj->notnull_info[j], 0, -
1482 - NN_POS_TO_BYTES(n)); -
1483 - } -
1484 - } -
1485 - } -
1486 - } -
1487 - -
1488 - /* -
1489 - * Store the first tuple into the tuplestore (it's always available now; -
1490 - * we either read it above, or saved it at the end of previous partition) -
1491 - */ -
1492 - tuplestore_puttupleslot(winstate->buffer, winstate->first_part_slot); -
1493 - winstate->spooled_rows++; -
1494 - } -
ExecWindowAgg() lines 2389-2663
Modified Lines Coverage: 3/3 lines (100.0%)
LineHitsSourceCommit
2389 - ExecWindowAgg(PlanState *pstate) -
2390 - { -
2391 - WindowAggState *winstate = castNode(WindowAggState, pstate); -
2392 - TupleTableSlot *slot; -
2393 - ExprContext *econtext; -
2394 - int i; -
2395 - int numfuncs; -
2396 - -
2397 - CHECK_FOR_INTERRUPTS(); -
2398 - -
2399 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
2400 - elog(DEBUG1, "ExecWindowAgg called. pos: " INT64_FORMAT, 2abe7c8Row pattern recognition patch (executor).
2401 - winstate->currentpos); 2abe7c8Row pattern recognition patch (executor).
2402 - #endif 2abe7c8Row pattern recognition patch (executor).
2403 - 2abe7c8Row pattern recognition patch (executor).
2404 - if (winstate->status == WINDOWAGG_DONE) -
2405 - return NULL; -
2406 - -
2407 - /* -
2408 - * Compute frame offset values, if any, during first call (or after a -
2409 - * rescan). These are assumed to hold constant throughout the scan; if -
2410 - * user gives us a volatile expression, we'll only use its initial value. -
2411 - */ -
2412 - if (unlikely(winstate->all_first)) -
2413 - calculate_frame_offsets(pstate); -
2414 - -
2415 - /* We need to loop as the runCondition or qual may filter out tuples */ -
2416 - for (;;) -
2417 - { -
2418 - if (winstate->next_partition) -
2419 - { -
2420 - /* Initialize for first partition and set current row = 0 */ -
2421 - begin_partition(winstate); -
2422 - /* If there are no input rows, we'll detect that and exit below */ -
2423 - } -
2424 - else -
2425 - { -
2426 - /* Advance current row within partition */ -
2427 - winstate->currentpos++; -
2428 - /* This might mean that the frame moves, too */ -
2429 - winstate->framehead_valid = false; -
2430 - winstate->frametail_valid = false; -
2431 - /* we don't need to invalidate grouptail here; see below */ -
2432 - } -
2433 - -
2434 - /* -
2435 - * Spool all tuples up to and including the current row, if we haven't -
2436 - * already -
2437 - */ -
2438 - spool_tuples(winstate, winstate->currentpos); -
2439 - -
2440 - /* Move to the next partition if we reached the end of this partition */ -
2441 - if (winstate->partition_spooled && -
2442 - winstate->currentpos >= winstate->spooled_rows) -
2443 - { -
2444 - release_partition(winstate); -
2445 - -
2446 - if (winstate->more_partitions) -
2447 - { -
2448 - begin_partition(winstate); -
2449 - Assert(winstate->spooled_rows > 0); -
2450 - -
2451 - /* Come out of pass-through mode when changing partition */ -
2452 - winstate->status = WINDOWAGG_RUN; -
2453 - } -
2454 - else -
2455 - { -
2456 - /* No further partitions? We're done */ -
2457 - winstate->status = WINDOWAGG_DONE; -
2458 - return NULL; -
2459 - } -
2460 - } -
2461 - -
2462 - /* final output execution is in ps_ExprContext */ -
2463 - econtext = winstate->ss.ps.ps_ExprContext; -
2464 - -
2465 - /* Clear the per-output-tuple context for current row */ -
2466 - ResetExprContext(econtext); -
2467 - -
2468 - /* -
2469 - * Read the current row from the tuplestore, and save in -
2470 - * ScanTupleSlot. (We can't rely on the outerplan's output slot -
2471 - * because we may have to read beyond the current row. Also, we have -
2472 - * to actually copy the row out of the tuplestore, since window -
2473 - * function evaluation might cause the tuplestore to dump its state to -
2474 - * disk.) -
2475 - * -
2476 - * In GROUPS mode, or when tracking a group-oriented exclusion clause, -
2477 - * we must also detect entering a new peer group and update associated -
2478 - * state when that happens. We use temp_slot_2 to temporarily hold -
2479 - * the previous row for this purpose. -
2480 - * -
2481 - * Current row must be in the tuplestore, since we spooled it above. -
2482 - */ -
2483 - tuplestore_select_read_pointer(winstate->buffer, winstate->current_ptr); -
2484 - if ((winstate->frameOptions & (FRAMEOPTION_GROUPS | -
2485 - FRAMEOPTION_EXCLUDE_GROUP | -
2486 - FRAMEOPTION_EXCLUDE_TIES)) && -
2487 - winstate->currentpos > 0) -
2488 - { -
2489 - ExecCopySlot(winstate->temp_slot_2, winstate->ss.ss_ScanTupleSlot); -
2490 - if (!tuplestore_gettupleslot(winstate->buffer, true, true, -
2491 - winstate->ss.ss_ScanTupleSlot)) -
2492 - elog(ERROR, "unexpected end of tuplestore"); -
2493 - if (!are_peers(winstate, winstate->temp_slot_2, -
2494 - winstate->ss.ss_ScanTupleSlot)) -
2495 - { -
2496 - winstate->currentgroup++; -
2497 - winstate->groupheadpos = winstate->currentpos; -
2498 - winstate->grouptail_valid = false; -
2499 - } -
2500 - ExecClearTuple(winstate->temp_slot_2); -
2501 - } -
2502 - else -
2503 - { -
2504 - if (!tuplestore_gettupleslot(winstate->buffer, true, true, -
2505 - winstate->ss.ss_ScanTupleSlot)) -
2506 - elog(ERROR, "unexpected end of tuplestore"); -
2507 - } -
2508 - -
2509 - /* don't evaluate the window functions when we're in pass-through mode */ -
2510 - if (winstate->status == WINDOWAGG_RUN) -
2511 - { -
2512 - /* 2abe7c8Row pattern recognition patch (executor).
2513 - * If RPR is defined and skip mode is next row, we need to clear 2abe7c8Row pattern recognition patch (executor).
2514 - * existing reduced frame info so that we newly calculate the info 2abe7c8Row pattern recognition patch (executor).
2515 - * starting from current row. 2abe7c8Row pattern recognition patch (executor).
2516 - */ 2abe7c8Row pattern recognition patch (executor).
2517 468789 if (rpr_is_defined(winstate)) 2abe7c8Row pattern recognition patch (executor).
2518 - { 2abe7c8Row pattern recognition patch (executor).
2519 16185 if (winstate->rpSkipTo == ST_NEXT_ROW) 2abe7c8Row pattern recognition patch (executor).
2520 180 clear_reduced_frame_map(winstate); 2abe7c8Row pattern recognition patch (executor).
2521 - } 2abe7c8Row pattern recognition patch (executor).
2522 - 2abe7c8Row pattern recognition patch (executor).
2523 - /* -
2524 - * Evaluate true window functions -
2525 - */ -
2526 - numfuncs = winstate->numfuncs; -
2527 - for (i = 0; i < numfuncs; i++) -
2528 - { -
2529 - WindowStatePerFunc perfuncstate = &(winstate->perfunc[i]); -
2530 - -
2531 - if (perfuncstate->plain_agg) -
2532 - continue; -
2533 - eval_windowfunction(winstate, perfuncstate, -
2534 - &(econtext->ecxt_aggvalues[perfuncstate->wfuncstate->wfuncno]), -
2535 - &(econtext->ecxt_aggnulls[perfuncstate->wfuncstate->wfuncno])); -
2536 - } -
2537 - -
2538 - /* -
2539 - * Evaluate aggregates -
2540 - */ -
2541 - if (winstate->numaggs > 0) -
2542 - eval_windowaggregates(winstate); -
2543 - } -
2544 - -
2545 - /* -
2546 - * If we have created auxiliary read pointers for the frame or group -
2547 - * boundaries, force them to be kept up-to-date, because we don't know -
2548 - * whether the window function(s) will do anything that requires that. -
2549 - * Failing to advance the pointers would result in being unable to -
2550 - * trim data from the tuplestore, which is bad. (If we could know in -
2551 - * advance whether the window functions will use frame boundary info, -
2552 - * we could skip creating these pointers in the first place ... but -
2553 - * unfortunately the window function API doesn't require that.) -
2554 - */ -
2555 - if (winstate->framehead_ptr >= 0) -
2556 - update_frameheadpos(winstate); -
2557 - if (winstate->frametail_ptr >= 0) -
2558 - update_frametailpos(winstate); -
2559 - if (winstate->grouptail_ptr >= 0) -
2560 - update_grouptailpos(winstate); -
2561 - -
2562 - /* -
2563 - * Truncate any no-longer-needed rows from the tuplestore. -
2564 - */ -
2565 - tuplestore_trim(winstate->buffer); -
2566 - -
2567 - /* -
2568 - * Form and return a projection tuple using the windowfunc results and -
2569 - * the current row. Setting ecxt_outertuple arranges that any Vars -
2570 - * will be evaluated with respect to that row. -
2571 - */ -
2572 - econtext->ecxt_outertuple = winstate->ss.ss_ScanTupleSlot; -
2573 - -
2574 - slot = ExecProject(winstate->ss.ps.ps_ProjInfo); -
2575 - -
2576 - if (winstate->status == WINDOWAGG_RUN) -
2577 - { -
2578 - econtext->ecxt_scantuple = slot; -
2579 - -
2580 - /* -
2581 - * Now evaluate the run condition to see if we need to go into -
2582 - * pass-through mode, or maybe stop completely. -
2583 - */ -
2584 - if (!ExecQual(winstate->runcondition, econtext)) -
2585 - { -
2586 - /* -
2587 - * Determine which mode to move into. If there is no -
2588 - * PARTITION BY clause and we're the top-level WindowAgg then -
2589 - * we're done. This tuple and any future tuples cannot -
2590 - * possibly match the runcondition. However, when there is a -
2591 - * PARTITION BY clause or we're not the top-level window we -
2592 - * can't just stop as we need to either process other -
2593 - * partitions or ensure WindowAgg nodes above us receive all -
2594 - * of the tuples they need to process their WindowFuncs. -
2595 - */ -
2596 - if (winstate->use_pass_through) -
2597 - { -
2598 - /* -
2599 - * When switching into a pass-through mode, we'd better -
2600 - * NULLify the aggregate results as these are no longer -
2601 - * updated and NULLifying them avoids the old stale -
2602 - * results lingering. Some of these might be byref types -
2603 - * so we can't have them pointing to free'd memory. The -
2604 - * planner insisted that quals used in the runcondition -
2605 - * are strict, so the top-level WindowAgg will always -
2606 - * filter these NULLs out in the filter clause. -
2607 - */ -
2608 - numfuncs = winstate->numfuncs; -
2609 - for (i = 0; i < numfuncs; i++) -
2610 - { -
2611 - econtext->ecxt_aggvalues[i] = (Datum) 0; -
2612 - econtext->ecxt_aggnulls[i] = true; -
2613 - } -
2614 - -
2615 - /* -
2616 - * STRICT pass-through mode is required for the top window -
2617 - * when there is a PARTITION BY clause. Otherwise we must -
2618 - * ensure we store tuples that don't match the -
2619 - * runcondition so they're available to WindowAggs above. -
2620 - */ -
2621 - if (winstate->top_window) -
2622 - { -
2623 - winstate->status = WINDOWAGG_PASSTHROUGH_STRICT; -
2624 - continue; -
2625 - } -
2626 - else -
2627 - { -
2628 - winstate->status = WINDOWAGG_PASSTHROUGH; -
2629 - } -
2630 - } -
2631 - else -
2632 - { -
2633 - /* -
2634 - * Pass-through not required. We can just return NULL. -
2635 - * Nothing else will match the runcondition. -
2636 - */ -
2637 - winstate->status = WINDOWAGG_DONE; -
2638 - return NULL; -
2639 - } -
2640 - } -
2641 - -
2642 - /* -
2643 - * Filter out any tuples we don't need in the top-level WindowAgg. -
2644 - */ -
2645 - if (!ExecQual(winstate->ss.ps.qual, econtext)) -
2646 - { -
2647 - InstrCountFiltered1(winstate, 1); -
2648 - continue; -
2649 - } -
2650 - -
2651 - break; -
2652 - } -
2653 - -
2654 - /* -
2655 - * When not in WINDOWAGG_RUN mode, we must still return this tuple if -
2656 - * we're anything apart from the top window. -
2657 - */ -
2658 - else if (!winstate->top_window) -
2659 - break; -
2660 - } -
2661 - -
2662 - return slot; -
2663 - } -
ExecInitWindowAgg() lines 2673-3038
Modified Lines Coverage: 30/30 lines (100.0%)
LineHitsSourceCommit
2673 - ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) -
2674 - { -
2675 - WindowAggState *winstate; -
2676 - Plan *outerPlan; -
2677 - ExprContext *econtext; -
2678 - ExprContext *tmpcontext; -
2679 - WindowStatePerFunc perfunc; -
2680 - WindowStatePerAgg peragg; -
2681 - int frameOptions = node->frameOptions; -
2682 - int numfuncs, -
2683 - wfuncno, -
2684 - numaggs, -
2685 - aggno; -
2686 - TupleDesc scanDesc; -
2687 - ListCell *l; -
2688 - -
2689 1453 TargetEntry *te; 2abe7c8Row pattern recognition patch (executor).
2690 1453 Expr *expr; 2abe7c8Row pattern recognition patch (executor).
2691 - 2abe7c8Row pattern recognition patch (executor).
2692 - /* check for unsupported flags */ -
2693 - Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); -
2694 - -
2695 - /* -
2696 - * create state structure -
2697 - */ -
2698 - winstate = makeNode(WindowAggState); -
2699 - winstate->ss.ps.plan = (Plan *) node; -
2700 - winstate->ss.ps.state = estate; -
2701 - winstate->ss.ps.ExecProcNode = ExecWindowAgg; -
2702 - -
2703 - /* copy frame options to state node for easy access */ -
2704 - winstate->frameOptions = frameOptions; -
2705 - -
2706 - /* -
2707 - * Create expression contexts. We need two, one for per-input-tuple -
2708 - * processing and one for per-output-tuple processing. We cheat a little -
2709 - * by using ExecAssignExprContext() to build both. -
2710 - */ -
2711 - ExecAssignExprContext(estate, &winstate->ss.ps); -
2712 - tmpcontext = winstate->ss.ps.ps_ExprContext; -
2713 - winstate->tmpcontext = tmpcontext; -
2714 - ExecAssignExprContext(estate, &winstate->ss.ps); -
2715 - -
2716 - /* Create long-lived context for storage of partition-local memory etc */ -
2717 - winstate->partcontext = -
2718 - AllocSetContextCreate(CurrentMemoryContext, -
2719 - "WindowAgg Partition", -
2720 - ALLOCSET_DEFAULT_SIZES); -
2721 - -
2722 - /* -
2723 - * Create mid-lived context for aggregate trans values etc. -
2724 - * -
2725 - * Note that moving aggregates each use their own private context, not -
2726 - * this one. -
2727 - */ -
2728 - winstate->aggcontext = -
2729 - AllocSetContextCreate(CurrentMemoryContext, -
2730 - "WindowAgg Aggregates", -
2731 - ALLOCSET_DEFAULT_SIZES); -
2732 - -
2733 - /* Only the top-level WindowAgg may have a qual */ -
2734 - Assert(node->plan.qual == NIL || node->topWindow); -
2735 - -
2736 - /* Initialize the qual */ -
2737 - winstate->ss.ps.qual = ExecInitQual(node->plan.qual, -
2738 - (PlanState *) winstate); -
2739 - -
2740 - /* -
2741 - * Setup the run condition, if we received one from the query planner. -
2742 - * When set, this may allow us to move into pass-through mode so that we -
2743 - * don't have to perform any further evaluation of WindowFuncs in the -
2744 - * current partition or possibly stop returning tuples altogether when all -
2745 - * tuples are in the same partition. -
2746 - */ -
2747 - winstate->runcondition = ExecInitQual(node->runCondition, -
2748 - (PlanState *) winstate); -
2749 - -
2750 - /* -
2751 - * When we're not the top-level WindowAgg node or we are but have a -
2752 - * PARTITION BY clause we must move into one of the WINDOWAGG_PASSTHROUGH* -
2753 - * modes when the runCondition becomes false. -
2754 - */ -
2755 - winstate->use_pass_through = !node->topWindow || node->partNumCols > 0; -
2756 - -
2757 - /* remember if we're the top-window or we are below the top-window */ -
2758 - winstate->top_window = node->topWindow; -
2759 - -
2760 - /* -
2761 - * initialize child nodes -
2762 - */ -
2763 - outerPlan = outerPlan(node); -
2764 - outerPlanState(winstate) = ExecInitNode(outerPlan, estate, eflags); -
2765 - -
2766 - /* -
2767 - * initialize source tuple type (which is also the tuple type that we'll -
2768 - * store in the tuplestore and use in all our working slots). -
2769 - */ -
2770 - ExecCreateScanSlotFromOuterPlan(estate, &winstate->ss, &TTSOpsMinimalTuple); -
2771 - scanDesc = winstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor; -
2772 - -
2773 - /* the outer tuple isn't the child's tuple, but always a minimal tuple */ -
2774 - winstate->ss.ps.outeropsset = true; -
2775 - winstate->ss.ps.outerops = &TTSOpsMinimalTuple; -
2776 - winstate->ss.ps.outeropsfixed = true; -
2777 - -
2778 - /* -
2779 - * tuple table initialization -
2780 - */ -
2781 - winstate->first_part_slot = ExecInitExtraTupleSlot(estate, scanDesc, -
2782 - &TTSOpsMinimalTuple); -
2783 - winstate->agg_row_slot = ExecInitExtraTupleSlot(estate, scanDesc, -
2784 - &TTSOpsMinimalTuple); -
2785 - winstate->temp_slot_1 = ExecInitExtraTupleSlot(estate, scanDesc, -
2786 - &TTSOpsMinimalTuple); -
2787 - winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc, -
2788 - &TTSOpsMinimalTuple); -
2789 - -
2790 1453 winstate->prev_slot = ExecInitExtraTupleSlot(estate, scanDesc, 2abe7c8Row pattern recognition patch (executor).
2791 - &TTSOpsMinimalTuple); 2abe7c8Row pattern recognition patch (executor).
2792 - 2abe7c8Row pattern recognition patch (executor).
2793 1453 winstate->next_slot = ExecInitExtraTupleSlot(estate, scanDesc, 2abe7c8Row pattern recognition patch (executor).
2794 - &TTSOpsMinimalTuple); 2abe7c8Row pattern recognition patch (executor).
2795 - 2abe7c8Row pattern recognition patch (executor).
2796 1453 winstate->null_slot = ExecInitExtraTupleSlot(estate, scanDesc, 2abe7c8Row pattern recognition patch (executor).
2797 - &TTSOpsMinimalTuple); 2abe7c8Row pattern recognition patch (executor).
2798 1453 winstate->null_slot = ExecStoreAllNullTuple(winstate->null_slot); 2abe7c8Row pattern recognition patch (executor).
2799 - 2abe7c8Row pattern recognition patch (executor).
2800 - /* -
2801 - * create frame head and tail slots only if needed (must create slots in -
2802 - * exactly the same cases that update_frameheadpos and update_frametailpos -
2803 - * need them) -
2804 - */ -
2805 - winstate->framehead_slot = winstate->frametail_slot = NULL; -
2806 - -
2807 - if (frameOptions & (FRAMEOPTION_RANGE | FRAMEOPTION_GROUPS)) -
2808 - { -
2809 - if (((frameOptions & FRAMEOPTION_START_CURRENT_ROW) && -
2810 - node->ordNumCols != 0) || -
2811 - (frameOptions & FRAMEOPTION_START_OFFSET)) -
2812 - winstate->framehead_slot = ExecInitExtraTupleSlot(estate, scanDesc, -
2813 - &TTSOpsMinimalTuple); -
2814 - if (((frameOptions & FRAMEOPTION_END_CURRENT_ROW) && -
2815 - node->ordNumCols != 0) || -
2816 - (frameOptions & FRAMEOPTION_END_OFFSET)) -
2817 - winstate->frametail_slot = ExecInitExtraTupleSlot(estate, scanDesc, -
2818 - &TTSOpsMinimalTuple); -
2819 - } -
2820 - -
2821 - /* -
2822 - * Initialize result slot, type and projection. -
2823 - */ -
2824 - ExecInitResultTupleSlotTL(&winstate->ss.ps, &TTSOpsVirtual); -
2825 - ExecAssignProjectionInfo(&winstate->ss.ps, NULL); -
2826 - -
2827 - /* Set up data for comparing tuples */ -
2828 - if (node->partNumCols > 0) -
2829 - winstate->partEqfunction = -
2830 - execTuplesMatchPrepare(scanDesc, -
2831 - node->partNumCols, -
2832 - node->partColIdx, -
2833 - node->partOperators, -
2834 - node->partCollations, -
2835 - &winstate->ss.ps); -
2836 - -
2837 - if (node->ordNumCols > 0) -
2838 - winstate->ordEqfunction = -
2839 - execTuplesMatchPrepare(scanDesc, -
2840 - node->ordNumCols, -
2841 - node->ordColIdx, -
2842 - node->ordOperators, -
2843 - node->ordCollations, -
2844 - &winstate->ss.ps); -
2845 - -
2846 - /* -
2847 - * WindowAgg nodes use aggvalues and aggnulls as well as Agg nodes. -
2848 - */ -
2849 - numfuncs = winstate->numfuncs; -
2850 - numaggs = winstate->numaggs; -
2851 - econtext = winstate->ss.ps.ps_ExprContext; -
2852 - econtext->ecxt_aggvalues = palloc0_array(Datum, numfuncs); -
2853 - econtext->ecxt_aggnulls = palloc0_array(bool, numfuncs); -
2854 - -
2855 - /* -
2856 - * allocate per-wfunc/per-agg state information. -
2857 - */ -
2858 - perfunc = palloc0_array(WindowStatePerFuncData, numfuncs); -
2859 - peragg = palloc0_array(WindowStatePerAggData, numaggs); -
2860 - winstate->perfunc = perfunc; -
2861 - winstate->peragg = peragg; -
2862 - -
2863 - wfuncno = -1; -
2864 - aggno = -1; -
2865 - foreach(l, winstate->funcs) -
2866 - { -
2867 - WindowFuncExprState *wfuncstate = (WindowFuncExprState *) lfirst(l); -
2868 - WindowFunc *wfunc = wfuncstate->wfunc; -
2869 - WindowStatePerFunc perfuncstate; -
2870 - AclResult aclresult; -
2871 - int i; -
2872 - -
2873 - if (wfunc->winref != node->winref) /* planner screwed up? */ -
2874 - elog(ERROR, "WindowFunc with winref %u assigned to WindowAgg with winref %u", -
2875 - wfunc->winref, node->winref); -
2876 - -
2877 - /* -
2878 - * Look for a previous duplicate window function, which needs the same -
2879 - * ignore_nulls value -
2880 - */ -
2881 - for (i = 0; i <= wfuncno; i++) -
2882 - { -
2883 - if (equal(wfunc, perfunc[i].wfunc) && -
2884 - !contain_volatile_functions((Node *) wfunc)) -
2885 - break; -
2886 - } -
2887 - if (i <= wfuncno && wfunc->ignore_nulls == perfunc[i].ignore_nulls) -
2888 - { -
2889 - /* Found a match to an existing entry, so just mark it */ -
2890 - wfuncstate->wfuncno = i; -
2891 - continue; -
2892 - } -
2893 - -
2894 - /* Nope, so assign a new PerAgg record */ -
2895 - perfuncstate = &perfunc[++wfuncno]; -
2896 - -
2897 - /* Mark WindowFunc state node with assigned index in the result array */ -
2898 - wfuncstate->wfuncno = wfuncno; -
2899 - -
2900 - /* Check permission to call window function */ -
2901 - aclresult = object_aclcheck(ProcedureRelationId, wfunc->winfnoid, GetUserId(), -
2902 - ACL_EXECUTE); -
2903 - if (aclresult != ACLCHECK_OK) -
2904 - aclcheck_error(aclresult, OBJECT_FUNCTION, -
2905 - get_func_name(wfunc->winfnoid)); -
2906 - InvokeFunctionExecuteHook(wfunc->winfnoid); -
2907 - -
2908 - /* Fill in the perfuncstate data */ -
2909 - perfuncstate->wfuncstate = wfuncstate; -
2910 - perfuncstate->wfunc = wfunc; -
2911 - perfuncstate->numArguments = list_length(wfuncstate->args); -
2912 - perfuncstate->winCollation = wfunc->inputcollid; -
2913 - -
2914 - get_typlenbyval(wfunc->wintype, -
2915 - &perfuncstate->resulttypeLen, -
2916 - &perfuncstate->resulttypeByVal); -
2917 - -
2918 - /* -
2919 - * If it's really just a plain aggregate function, we'll emulate the -
2920 - * Agg environment for it. -
2921 - */ -
2922 - perfuncstate->plain_agg = wfunc->winagg; -
2923 - if (wfunc->winagg) -
2924 - { -
2925 - WindowStatePerAgg peraggstate; -
2926 - -
2927 - perfuncstate->aggno = ++aggno; -
2928 - peraggstate = &winstate->peragg[aggno]; -
2929 - initialize_peragg(winstate, wfunc, peraggstate); -
2930 - peraggstate->wfuncno = wfuncno; -
2931 - } -
2932 - else -
2933 - { -
2934 - WindowObject winobj = makeNode(WindowObjectData); -
2935 - -
2936 - winobj->winstate = winstate; -
2937 - winobj->argstates = wfuncstate->args; -
2938 - winobj->localmem = NULL; -
2939 - perfuncstate->winobj = winobj; -
2940 - winobj->ignore_nulls = wfunc->ignore_nulls; -
2941 - init_notnull_info(winobj, perfuncstate); -
2942 - -
2943 - /* It's a real window function, so set up to call it. */ -
2944 - fmgr_info_cxt(wfunc->winfnoid, &perfuncstate->flinfo, -
2945 - econtext->ecxt_per_query_memory); -
2946 - fmgr_info_set_expr((Node *) wfunc, &perfuncstate->flinfo); -
2947 - } -
2948 - } -
2949 - -
2950 - /* Update numfuncs, numaggs to match number of unique functions found */ -
2951 - winstate->numfuncs = wfuncno + 1; -
2952 - winstate->numaggs = aggno + 1; -
2953 - -
2954 - /* Set up WindowObject for aggregates, if needed */ -
2955 - if (winstate->numaggs > 0) -
2956 - { -
2957 - WindowObject agg_winobj = makeNode(WindowObjectData); -
2958 - -
2959 - agg_winobj->winstate = winstate; -
2960 - agg_winobj->argstates = NIL; -
2961 - agg_winobj->localmem = NULL; -
2962 - /* make sure markptr = -1 to invalidate. It may not get used */ -
2963 - agg_winobj->markptr = -1; -
2964 - agg_winobj->readptr = -1; -
2965 - winstate->agg_winobj = agg_winobj; -
2966 - } -
2967 - -
2968 - /* Set the status to running */ -
2969 - winstate->status = WINDOWAGG_RUN; -
2970 - -
2971 - /* initialize frame bound offset expressions */ -
2972 - winstate->startOffset = ExecInitExpr((Expr *) node->startOffset, -
2973 - (PlanState *) winstate); -
2974 - winstate->endOffset = ExecInitExpr((Expr *) node->endOffset, -
2975 - (PlanState *) winstate); -
2976 - -
2977 - /* Lookup in_range support functions if needed */ -
2978 - if (OidIsValid(node->startInRangeFunc)) -
2979 - fmgr_info(node->startInRangeFunc, &winstate->startInRangeFunc); -
2980 - if (OidIsValid(node->endInRangeFunc)) -
2981 - fmgr_info(node->endInRangeFunc, &winstate->endInRangeFunc); -
2982 - winstate->inRangeColl = node->inRangeColl; -
2983 - winstate->inRangeAsc = node->inRangeAsc; -
2984 - winstate->inRangeNullsFirst = node->inRangeNullsFirst; -
2985 - -
2986 - /* Set up SKIP TO type */ 2abe7c8Row pattern recognition patch (executor).
2987 1453 winstate->rpSkipTo = node->rpSkipTo; 2abe7c8Row pattern recognition patch (executor).
2988 - /* Set up row pattern recognition PATTERN clause */ 2abe7c8Row pattern recognition patch (executor).
2989 1453 winstate->patternVariableList = node->patternVariable; 2abe7c8Row pattern recognition patch (executor).
2990 1453 winstate->patternRegexpList = node->patternRegexp; 2abe7c8Row pattern recognition patch (executor).
2991 - 2abe7c8Row pattern recognition patch (executor).
2992 - /* Set up row pattern recognition DEFINE clause */ 2abe7c8Row pattern recognition patch (executor).
2993 1453 winstate->defineInitial = node->defineInitial; 2abe7c8Row pattern recognition patch (executor).
2994 1453 winstate->defineVariableList = NIL; 2abe7c8Row pattern recognition patch (executor).
2995 1453 winstate->defineClauseList = NIL; 2abe7c8Row pattern recognition patch (executor).
2996 1453 if (node->defineClause != NIL) 2abe7c8Row pattern recognition patch (executor).
2997 - { 2abe7c8Row pattern recognition patch (executor).
2998 - /* 2abe7c8Row pattern recognition patch (executor).
2999 - * Tweak arg var of PREV/NEXT so that it refers to scan/inner slot. 2abe7c8Row pattern recognition patch (executor).
3000 - */ 2abe7c8Row pattern recognition patch (executor).
3001 237 foreach(l, node->defineClause) 2abe7c8Row pattern recognition patch (executor).
3002 - { 2abe7c8Row pattern recognition patch (executor).
3003 168 char *name; 2abe7c8Row pattern recognition patch (executor).
3004 168 ExprState *exps; 2abe7c8Row pattern recognition patch (executor).
3005 - 2abe7c8Row pattern recognition patch (executor).
3006 168 te = lfirst(l); 2abe7c8Row pattern recognition patch (executor).
3007 168 name = te->resname; 2abe7c8Row pattern recognition patch (executor).
3008 168 expr = te->expr; 2abe7c8Row pattern recognition patch (executor).
3009 - 2abe7c8Row pattern recognition patch (executor).
3010 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
3011 - elog(DEBUG1, "defineVariable name: %s", name); 2abe7c8Row pattern recognition patch (executor).
3012 - #endif 2abe7c8Row pattern recognition patch (executor).
3013 336 winstate->defineVariableList = 2abe7c8Row pattern recognition patch (executor).
3014 168 lappend(winstate->defineVariableList, 2abe7c8Row pattern recognition patch (executor).
3015 168 makeString(pstrdup(name))); 2abe7c8Row pattern recognition patch (executor).
3016 168 attno_map((Node *) expr); 2abe7c8Row pattern recognition patch (executor).
3017 165 exps = ExecInitExpr(expr, (PlanState *) winstate); 2abe7c8Row pattern recognition patch (executor).
3018 165 winstate->defineClauseList = 2abe7c8Row pattern recognition patch (executor).
3019 165 lappend(winstate->defineClauseList, exps); 2abe7c8Row pattern recognition patch (executor).
3020 - } 2abe7c8Row pattern recognition patch (executor).
3021 - } 2abe7c8Row pattern recognition patch (executor).
3022 - /* set up regular expression compiled result cache for RPR */ 2abe7c8Row pattern recognition patch (executor).
3023 1450 winstate->patbuf = NULL; 2abe7c8Row pattern recognition patch (executor).
3024 1450 memset(&winstate->preg, 0, sizeof(winstate->preg)); 2abe7c8Row pattern recognition patch (executor).
3025 - 2abe7c8Row pattern recognition patch (executor).
3026 - /* 2abe7c8Row pattern recognition patch (executor).
3027 - * Build variable_pos 2abe7c8Row pattern recognition patch (executor).
3028 - */ 2abe7c8Row pattern recognition patch (executor).
3029 1450 if (winstate->defineInitial) 2abe7c8Row pattern recognition patch (executor).
3030 69 winstate->variable_pos = variable_pos_build(winstate); 2abe7c8Row pattern recognition patch (executor).
3031 - 2abe7c8Row pattern recognition patch (executor).
3032 - winstate->all_first = true; -
3033 - winstate->partition_spooled = false; -
3034 - winstate->more_partitions = false; -
3035 - winstate->next_partition = true; -
3036 - -
3037 - return winstate; -
3038 - } -
attno_map() lines 3047-3050
Modified Lines Coverage: 3/3 lines (100.0%)
LineHitsSourceCommit
3047 168 attno_map(Node *node) 2abe7c8Row pattern recognition patch (executor).
3048 - { 2abe7c8Row pattern recognition patch (executor).
3049 168 (void) expression_tree_walker(node, attno_map_walker, NULL); 2abe7c8Row pattern recognition patch (executor).
3050 165 } 2abe7c8Row pattern recognition patch (executor).
attno_map_walker() lines 3053-3085
Modified Lines Coverage: 13/14 lines (92.9%)
LineHitsSourceCommit
3053 393 attno_map_walker(Node *node, void *context) 2abe7c8Row pattern recognition patch (executor).
3054 - { 2abe7c8Row pattern recognition patch (executor).
3055 393 FuncExpr *func; 2abe7c8Row pattern recognition patch (executor).
3056 393 int nargs; 2abe7c8Row pattern recognition patch (executor).
3057 393 bool is_prev; 2abe7c8Row pattern recognition patch (executor).
3058 - 2abe7c8Row pattern recognition patch (executor).
3059 393 if (node == NULL) 2abe7c8Row pattern recognition patch (executor).
3060 - return false; 2abe7c8Row pattern recognition patch (executor).
3061 - 2abe7c8Row pattern recognition patch (executor).
3062 393 if (IsA(node, FuncExpr)) 2abe7c8Row pattern recognition patch (executor).
3063 - { 2abe7c8Row pattern recognition patch (executor).
3064 102 func = (FuncExpr *) node; 2abe7c8Row pattern recognition patch (executor).
3065 - 2abe7c8Row pattern recognition patch (executor).
3066 102 if (func->funcid == F_PREV || func->funcid == F_NEXT) 2abe7c8Row pattern recognition patch (executor).
3067 - { 2abe7c8Row pattern recognition patch (executor).
3068 - /* 2abe7c8Row pattern recognition patch (executor).
3069 - * The SQL standard allows to have two more arguments form of 2abe7c8Row pattern recognition patch (executor).
3070 - * PREV/NEXT. But currently we allow only 1 argument form. 2abe7c8Row pattern recognition patch (executor).
3071 - */ 2abe7c8Row pattern recognition patch (executor).
3072 96 nargs = list_length(func->args); 2abe7c8Row pattern recognition patch (executor).
3073 96 if (list_length(func->args) != 1) 2abe7c8Row pattern recognition patch (executor).
3074 0 elog(ERROR, "PREV/NEXT must have 1 argument but function %d has %d args", 2abe7c8Row pattern recognition patch (executor).
3075 - func->funcid, nargs); 2abe7c8Row pattern recognition patch (executor).
3076 - 2abe7c8Row pattern recognition patch (executor).
3077 - /* 2abe7c8Row pattern recognition patch (executor).
3078 - * Check expr of PREV/NEXT aruguments and replace varno. 2abe7c8Row pattern recognition patch (executor).
3079 - */ 2abe7c8Row pattern recognition patch (executor).
3080 96 is_prev = (func->funcid == F_PREV) ? true : false; 2abe7c8Row pattern recognition patch (executor).
3081 96 check_rpr_navigation(node, is_prev); 2abe7c8Row pattern recognition patch (executor).
3082 - } 2abe7c8Row pattern recognition patch (executor).
3083 - } 2abe7c8Row pattern recognition patch (executor).
3084 390 return expression_tree_walker(node, attno_map_walker, NULL); 2abe7c8Row pattern recognition patch (executor).
3085 - } 2abe7c8Row pattern recognition patch (executor).
check_rpr_navigation() lines 3092-3102
Modified Lines Coverage: 8/8 lines (100.0%)
LineHitsSourceCommit
3092 96 check_rpr_navigation(Node *node, bool is_prev) 2abe7c8Row pattern recognition patch (executor).
3093 - { 2abe7c8Row pattern recognition patch (executor).
3094 96 NavigationInfo context; 2abe7c8Row pattern recognition patch (executor).
3095 - 2abe7c8Row pattern recognition patch (executor).
3096 96 context.is_prev = is_prev; 2abe7c8Row pattern recognition patch (executor).
3097 96 context.num_vars = 0; 2abe7c8Row pattern recognition patch (executor).
3098 96 (void) expression_tree_walker(node, rpr_navigation_walker, &context); 2abe7c8Row pattern recognition patch (executor).
3099 96 if (context.num_vars < 1) 2abe7c8Row pattern recognition patch (executor).
3100 3 ereport(ERROR, 2abe7c8Row pattern recognition patch (executor).
3101 - errmsg("row pattern navigation operation's argument must include at least one column reference")); 2abe7c8Row pattern recognition patch (executor).
3102 93 } 2abe7c8Row pattern recognition patch (executor).
rpr_navigation_walker() lines 3105-3142
Modified Lines Coverage: 11/13 lines (84.6%)
LineHitsSourceCommit
3105 108 rpr_navigation_walker(Node *node, void *context) 2abe7c8Row pattern recognition patch (executor).
3106 - { 2abe7c8Row pattern recognition patch (executor).
3107 108 NavigationInfo *nav = (NavigationInfo *) context; 2abe7c8Row pattern recognition patch (executor).
3108 - 2abe7c8Row pattern recognition patch (executor).
3109 108 if (node == NULL) 2abe7c8Row pattern recognition patch (executor).
3110 - return false; 2abe7c8Row pattern recognition patch (executor).
3111 - 2abe7c8Row pattern recognition patch (executor).
3112 108 switch (nodeTag(node)) 2abe7c8Row pattern recognition patch (executor).
3113 - { 2abe7c8Row pattern recognition patch (executor).
3114 96 case T_Var: 2abe7c8Row pattern recognition patch (executor).
3115 - { 2abe7c8Row pattern recognition patch (executor).
3116 96 Var *var = (Var *) node; 2abe7c8Row pattern recognition patch (executor).
3117 - 2abe7c8Row pattern recognition patch (executor).
3118 96 nav->num_vars++; 2abe7c8Row pattern recognition patch (executor).
3119 - 2abe7c8Row pattern recognition patch (executor).
3120 96 if (nav->is_prev) 2abe7c8Row pattern recognition patch (executor).
3121 - { 2abe7c8Row pattern recognition patch (executor).
3122 - /* 2abe7c8Row pattern recognition patch (executor).
3123 - * Rewrite varno from OUTER_VAR to regular var no so that 2abe7c8Row pattern recognition patch (executor).
3124 - * the var references scan tuple. 2abe7c8Row pattern recognition patch (executor).
3125 - */ 2abe7c8Row pattern recognition patch (executor).
3126 90 var->varno = var->varnosyn; 2abe7c8Row pattern recognition patch (executor).
3127 - } 2abe7c8Row pattern recognition patch (executor).
3128 - else 2abe7c8Row pattern recognition patch (executor).
3129 6 var->varno = INNER_VAR; 2abe7c8Row pattern recognition patch (executor).
3130 - } 2abe7c8Row pattern recognition patch (executor).
3131 - break; 2abe7c8Row pattern recognition patch (executor).
3132 - case T_Const: 2abe7c8Row pattern recognition patch (executor).
3133 - case T_FuncExpr: 2abe7c8Row pattern recognition patch (executor).
3134 - case T_OpExpr: 2abe7c8Row pattern recognition patch (executor).
3135 - break; 2abe7c8Row pattern recognition patch (executor).
3136 - 2abe7c8Row pattern recognition patch (executor).
3137 0 default: 2abe7c8Row pattern recognition patch (executor).
3138 0 ereport(ERROR, 2abe7c8Row pattern recognition patch (executor).
3139 - errmsg("row pattern navigation operation's argument includes unsupported expression")); 2abe7c8Row pattern recognition patch (executor).
3140 - } 2abe7c8Row pattern recognition patch (executor).
3141 108 return expression_tree_walker(node, rpr_navigation_walker, context); 2abe7c8Row pattern recognition patch (executor).
3142 - } 2abe7c8Row pattern recognition patch (executor).
ExecEndWindowAgg() lines 3150-3180
Modified Lines Coverage: 1/1 lines (100.0%)
LineHitsSourceCommit
3150 - ExecEndWindowAgg(WindowAggState *node) -
3151 - { -
3152 - PlanState *outerPlan; -
3153 - int i; -
3154 - -
3155 - if (node->buffer != NULL) -
3156 - { -
3157 - tuplestore_end(node->buffer); -
3158 - -
3159 - /* nullify so that release_partition skips the tuplestore_clear() */ -
3160 - node->buffer = NULL; -
3161 - } -
3162 - -
3163 - release_partition(node); -
3164 - -
3165 - for (i = 0; i < node->numaggs; i++) -
3166 - { -
3167 - if (node->peragg[i].aggcontext != node->aggcontext) -
3168 - MemoryContextDelete(node->peragg[i].aggcontext); -
3169 - } -
3170 - MemoryContextDelete(node->partcontext); -
3171 - MemoryContextDelete(node->aggcontext); -
3172 - -
3173 - pfree(node->perfunc); -
3174 - pfree(node->peragg); -
3175 - -
3176 1348 pattern_regfree(node); 2abe7c8Row pattern recognition patch (executor).
3177 - 2abe7c8Row pattern recognition patch (executor).
3178 - outerPlan = outerPlanState(node); -
3179 - ExecEndNode(outerPlan); -
3180 - } -
ExecReScanWindowAgg() lines 3187-3221
Modified Lines Coverage: 2/2 lines (100.0%)
LineHitsSourceCommit
3187 - ExecReScanWindowAgg(WindowAggState *node) -
3188 - { -
3189 - PlanState *outerPlan = outerPlanState(node); -
3190 - ExprContext *econtext = node->ss.ps.ps_ExprContext; -
3191 - -
3192 - node->status = WINDOWAGG_RUN; -
3193 - node->all_first = true; -
3194 - -
3195 - /* release tuplestore et al */ -
3196 - release_partition(node); -
3197 - -
3198 - /* release all temp tuples, but especially first_part_slot */ -
3199 - ExecClearTuple(node->ss.ss_ScanTupleSlot); -
3200 - ExecClearTuple(node->first_part_slot); -
3201 - ExecClearTuple(node->agg_row_slot); -
3202 - ExecClearTuple(node->temp_slot_1); -
3203 - ExecClearTuple(node->temp_slot_2); -
3204 39 ExecClearTuple(node->prev_slot); 2abe7c8Row pattern recognition patch (executor).
3205 39 ExecClearTuple(node->next_slot); 2abe7c8Row pattern recognition patch (executor).
3206 - if (node->framehead_slot) -
3207 - ExecClearTuple(node->framehead_slot); -
3208 - if (node->frametail_slot) -
3209 - ExecClearTuple(node->frametail_slot); -
3210 - -
3211 - /* Forget current wfunc values */ -
3212 - MemSet(econtext->ecxt_aggvalues, 0, sizeof(Datum) * node->numfuncs); -
3213 - MemSet(econtext->ecxt_aggnulls, 0, sizeof(bool) * node->numfuncs); -
3214 - -
3215 - /* -
3216 - * if chgParam of subnode is not null then plan will be re-scanned by -
3217 - * first ExecProcNode. -
3218 - */ -
3219 - if (outerPlan->chgParam == NULL) -
3220 - ExecReScan(outerPlan); -
3221 - } -
window_gettupleslot() lines 3547-3631
Modified Lines Coverage: 0/1 lines (0.0%)
LineHitsSourceCommit
3547 - window_gettupleslot(WindowObject winobj, int64 pos, TupleTableSlot *slot) -
3548 - { -
3549 - WindowAggState *winstate = winobj->winstate; -
3550 - MemoryContext oldcontext; -
3551 - -
3552 - /* often called repeatedly in a row */ -
3553 - CHECK_FOR_INTERRUPTS(); -
3554 - -
3555 - /* Don't allow passing -1 to spool_tuples here */ -
3556 - if (pos < 0) -
3557 - return false; -
3558 - -
3559 - /* If necessary, fetch the tuple into the spool */ -
3560 - spool_tuples(winstate, pos); -
3561 - -
3562 - if (pos >= winstate->spooled_rows) -
3563 - return false; -
3564 - -
3565 - if (pos < winobj->markpos) -
3566 0 elog(ERROR, "cannot fetch row: " INT64_FORMAT " before WindowObject's mark position: " INT64_FORMAT, 2abe7c8Row pattern recognition patch (executor).
3567 - pos, winobj->markpos); 2abe7c8Row pattern recognition patch (executor).
3568 - -
3569 - oldcontext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory); -
3570 - -
3571 - tuplestore_select_read_pointer(winstate->buffer, winobj->readptr); -
3572 - -
3573 - /* -
3574 - * Advance or rewind until we are within one tuple of the one we want. -
3575 - */ -
3576 - if (winobj->seekpos < pos - 1) -
3577 - { -
3578 - if (!tuplestore_skiptuples(winstate->buffer, -
3579 - pos - 1 - winobj->seekpos, -
3580 - true)) -
3581 - elog(ERROR, "unexpected end of tuplestore"); -
3582 - winobj->seekpos = pos - 1; -
3583 - } -
3584 - else if (winobj->seekpos > pos + 1) -
3585 - { -
3586 - if (!tuplestore_skiptuples(winstate->buffer, -
3587 - winobj->seekpos - (pos + 1), -
3588 - false)) -
3589 - elog(ERROR, "unexpected end of tuplestore"); -
3590 - winobj->seekpos = pos + 1; -
3591 - } -
3592 - else if (winobj->seekpos == pos) -
3593 - { -
3594 - /* -
3595 - * There's no API to refetch the tuple at the current position. We -
3596 - * have to move one tuple forward, and then one backward. (We don't -
3597 - * do it the other way because we might try to fetch the row before -
3598 - * our mark, which isn't allowed.) XXX this case could stand to be -
3599 - * optimized. -
3600 - */ -
3601 - tuplestore_advance(winstate->buffer, true); -
3602 - winobj->seekpos++; -
3603 - } -
3604 - -
3605 - /* -
3606 - * Now we should be on the tuple immediately before or after the one we -
3607 - * want, so just fetch forwards or backwards as appropriate. -
3608 - * -
3609 - * Notice that we tell tuplestore_gettupleslot to make a physical copy of -
3610 - * the fetched tuple. This ensures that the slot's contents remain valid -
3611 - * through manipulations of the tuplestore, which some callers depend on. -
3612 - */ -
3613 - if (winobj->seekpos > pos) -
3614 - { -
3615 - if (!tuplestore_gettupleslot(winstate->buffer, false, true, slot)) -
3616 - elog(ERROR, "unexpected end of tuplestore"); -
3617 - winobj->seekpos--; -
3618 - } -
3619 - else -
3620 - { -
3621 - if (!tuplestore_gettupleslot(winstate->buffer, true, true, slot)) -
3622 - elog(ERROR, "unexpected end of tuplestore"); -
3623 - winobj->seekpos++; -
3624 - } -
3625 - -
3626 - Assert(winobj->seekpos == pos); -
3627 - -
3628 - MemoryContextSwitchTo(oldcontext); -
3629 - -
3630 - return true; -
3631 - } -
WinGetFuncArgInFrame() lines 4262-4292
Modified Lines Coverage: 6/7 lines (85.7%)
LineHitsSourceCommit
4262 - WinGetFuncArgInFrame(WindowObject winobj, int argno, -
4263 - int relpos, int seektype, bool set_mark, -
4264 - bool *isnull, bool *isout) -
4265 - { -
4266 - WindowAggState *winstate; -
4267 - ExprContext *econtext; -
4268 - TupleTableSlot *slot; -
4269 - -
4270 - Assert(WindowObjectIsValid(winobj)); -
4271 - winstate = winobj->winstate; -
4272 - econtext = winstate->ss.ps.ps_ExprContext; -
4273 - slot = winstate->temp_slot_1; -
4274 - -
4275 - if (winobj->ignore_nulls == IGNORE_NULLS) -
4276 - return ignorenulls_getfuncarginframe(winobj, argno, relpos, seektype, -
4277 - set_mark, isnull, isout); -
4278 - -
4279 6876 if (WinGetSlotInFrame(winobj, slot, 2abe7c8Row pattern recognition patch (executor).
4280 - relpos, seektype, set_mark, 2abe7c8Row pattern recognition patch (executor).
4281 - isnull, isout) == 0) 2abe7c8Row pattern recognition patch (executor).
4282 - { 2abe7c8Row pattern recognition patch (executor).
4283 4671 econtext->ecxt_outertuple = slot; 2abe7c8Row pattern recognition patch (executor).
4284 4671 return ExecEvalExpr((ExprState *) list_nth(winobj->argstates, argno), 2abe7c8Row pattern recognition patch (executor).
4285 - econtext, isnull); 2abe7c8Row pattern recognition patch (executor).
4286 - } 2abe7c8Row pattern recognition patch (executor).
4287 - 2abe7c8Row pattern recognition patch (executor).
4288 2166 if (isout) 2abe7c8Row pattern recognition patch (executor).
4289 0 *isout = true; 2abe7c8Row pattern recognition patch (executor).
4290 2166 *isnull = true; 2abe7c8Row pattern recognition patch (executor).
4291 2166 return (Datum) 0; 2abe7c8Row pattern recognition patch (executor).
4292 - } 2abe7c8Row pattern recognition patch (executor).
WinGetSlotInFrame() lines 4309-4505
Modified Lines Coverage: 20/21 lines (95.2%)
LineHitsSourceCommit
4309 6876 WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot, 2abe7c8Row pattern recognition patch (executor).
4310 - int relpos, int seektype, bool set_mark, 2abe7c8Row pattern recognition patch (executor).
4311 - bool *isnull, bool *isout) 2abe7c8Row pattern recognition patch (executor).
4312 - { 2abe7c8Row pattern recognition patch (executor).
4313 6876 WindowAggState *winstate; 2abe7c8Row pattern recognition patch (executor).
4314 6876 int64 abs_pos; 2abe7c8Row pattern recognition patch (executor).
4315 6876 int64 mark_pos; 2abe7c8Row pattern recognition patch (executor).
4316 6876 int num_reduced_frame; 2abe7c8Row pattern recognition patch (executor).
4317 - 2abe7c8Row pattern recognition patch (executor).
4318 6876 Assert(WindowObjectIsValid(winobj)); 2abe7c8Row pattern recognition patch (executor).
4319 6876 winstate = winobj->winstate; 2abe7c8Row pattern recognition patch (executor).
4320 - 2abe7c8Row pattern recognition patch (executor).
4321 - switch (seektype) -
4322 - { -
4323 - case WINDOW_SEEK_CURRENT: -
4324 - elog(ERROR, "WINDOW_SEEK_CURRENT is not supported for WinGetFuncArgInFrame"); -
4325 - abs_pos = mark_pos = 0; /* keep compiler quiet */ -
4326 - break; -
4327 - case WINDOW_SEEK_HEAD: -
4328 - /* rejecting relpos < 0 is easy and simplifies code below */ -
4329 - if (relpos < 0) -
4330 - goto out_of_frame; -
4331 - update_frameheadpos(winstate); -
4332 - abs_pos = winstate->frameheadpos + relpos; -
4333 - mark_pos = abs_pos; -
4334 - -
4335 - /* -
4336 - * Account for exclusion option if one is active, but advance only -
4337 - * abs_pos not mark_pos. This prevents changes of the current -
4338 - * row's peer group from resulting in trying to fetch a row before -
4339 - * some previous mark position. -
4340 - * -
4341 - * Note that in some corner cases such as current row being -
4342 - * outside frame, these calculations are theoretically too simple, -
4343 - * but it doesn't matter because we'll end up deciding the row is -
4344 - * out of frame. We do not attempt to avoid fetching rows past -
4345 - * end of frame; that would happen in some cases anyway. -
4346 - */ -
4347 - switch (winstate->frameOptions & FRAMEOPTION_EXCLUSION) -
4348 - { -
4349 - case 0: -
4350 - /* no adjustment needed */ -
4351 - break; -
4352 - case FRAMEOPTION_EXCLUDE_CURRENT_ROW: -
4353 - if (abs_pos >= winstate->currentpos && -
4354 - winstate->currentpos >= winstate->frameheadpos) -
4355 - abs_pos++; -
4356 - break; -
4357 - case FRAMEOPTION_EXCLUDE_GROUP: -
4358 - update_grouptailpos(winstate); -
4359 - if (abs_pos >= winstate->groupheadpos && -
4360 - winstate->grouptailpos > winstate->frameheadpos) -
4361 - { -
4362 - int64 overlapstart = Max(winstate->groupheadpos, -
4363 - winstate->frameheadpos); -
4364 - -
4365 - abs_pos += winstate->grouptailpos - overlapstart; -
4366 - } -
4367 - break; -
4368 - case FRAMEOPTION_EXCLUDE_TIES: -
4369 - update_grouptailpos(winstate); -
4370 - if (abs_pos >= winstate->groupheadpos && -
4371 - winstate->grouptailpos > winstate->frameheadpos) -
4372 - { -
4373 - int64 overlapstart = Max(winstate->groupheadpos, -
4374 - winstate->frameheadpos); -
4375 - -
4376 - if (abs_pos == overlapstart) -
4377 - abs_pos = winstate->currentpos; -
4378 - else -
4379 - abs_pos += winstate->grouptailpos - overlapstart - 1; -
4380 - } -
4381 - break; -
4382 - default: -
4383 - elog(ERROR, "unrecognized frame option state: 0x%x", -
4384 - winstate->frameOptions); -
4385 - break; -
4386 - } -
4387 3564 num_reduced_frame = row_is_in_reduced_frame(winobj, 2abe7c8Row pattern recognition patch (executor).
4388 - winstate->frameheadpos); 2abe7c8Row pattern recognition patch (executor).
4389 3564 if (num_reduced_frame < 0) 2abe7c8Row pattern recognition patch (executor).
4390 1026 goto out_of_frame; 2abe7c8Row pattern recognition patch (executor).
4391 2538 else if (num_reduced_frame > 0) 2abe7c8Row pattern recognition patch (executor).
4392 336 if (relpos >= num_reduced_frame) 2abe7c8Row pattern recognition patch (executor).
4393 0 goto out_of_frame; 2abe7c8Row pattern recognition patch (executor).
4394 - break; -
4395 - case WINDOW_SEEK_TAIL: -
4396 - /* rejecting relpos > 0 is easy and simplifies code below */ -
4397 - if (relpos > 0) -
4398 - goto out_of_frame; -
4399 - 2abe7c8Row pattern recognition patch (executor).
4400 - /* 2abe7c8Row pattern recognition patch (executor).
4401 - * RPR cares about frame head pos. Need to call 2abe7c8Row pattern recognition patch (executor).
4402 - * update_frameheadpos 2abe7c8Row pattern recognition patch (executor).
4403 - */ 2abe7c8Row pattern recognition patch (executor).
4404 3291 update_frameheadpos(winstate); 2abe7c8Row pattern recognition patch (executor).
4405 - 2abe7c8Row pattern recognition patch (executor).
4406 - update_frametailpos(winstate); -
4407 - abs_pos = winstate->frametailpos - 1 + relpos; -
4408 - -
4409 - /* -
4410 - * Account for exclusion option if one is active. If there is no -
4411 - * exclusion, we can safely set the mark at the accessed row. But -
4412 - * if there is, we can only mark the frame start, because we can't -
4413 - * be sure how far back in the frame the exclusion might cause us -
4414 - * to fetch in future. Furthermore, we have to actually check -
4415 - * against frameheadpos here, since it's unsafe to try to fetch a -
4416 - * row before frame start if the mark might be there already. -
4417 - */ -
4418 - switch (winstate->frameOptions & FRAMEOPTION_EXCLUSION) -
4419 - { -
4420 - case 0: -
4421 - /* no adjustment needed */ -
4422 - mark_pos = abs_pos; -
4423 - break; -
4424 - case FRAMEOPTION_EXCLUDE_CURRENT_ROW: -
4425 - if (abs_pos <= winstate->currentpos && -
4426 - winstate->currentpos < winstate->frametailpos) -
4427 - abs_pos--; -
4428 - update_frameheadpos(winstate); -
4429 - if (abs_pos < winstate->frameheadpos) -
4430 - goto out_of_frame; -
4431 - mark_pos = winstate->frameheadpos; -
4432 - break; -
4433 - case FRAMEOPTION_EXCLUDE_GROUP: -
4434 - update_grouptailpos(winstate); -
4435 - if (abs_pos < winstate->grouptailpos && -
4436 - winstate->groupheadpos < winstate->frametailpos) -
4437 - { -
4438 - int64 overlapend = Min(winstate->grouptailpos, -
4439 - winstate->frametailpos); -
4440 - -
4441 - abs_pos -= overlapend - winstate->groupheadpos; -
4442 - } -
4443 - update_frameheadpos(winstate); -
4444 - if (abs_pos < winstate->frameheadpos) -
4445 - goto out_of_frame; -
4446 - mark_pos = winstate->frameheadpos; -
4447 - break; -
4448 - case FRAMEOPTION_EXCLUDE_TIES: -
4449 - update_grouptailpos(winstate); -
4450 - if (abs_pos < winstate->grouptailpos && -
4451 - winstate->groupheadpos < winstate->frametailpos) -
4452 - { -
4453 - int64 overlapend = Min(winstate->grouptailpos, -
4454 - winstate->frametailpos); -
4455 - -
4456 - if (abs_pos == overlapend - 1) -
4457 - abs_pos = winstate->currentpos; -
4458 - else -
4459 - abs_pos -= overlapend - 1 - winstate->groupheadpos; -
4460 - } -
4461 - update_frameheadpos(winstate); -
4462 - if (abs_pos < winstate->frameheadpos) -
4463 - goto out_of_frame; -
4464 - mark_pos = winstate->frameheadpos; -
4465 - break; -
4466 - default: -
4467 - elog(ERROR, "unrecognized frame option state: 0x%x", -
4468 - winstate->frameOptions); -
4469 - mark_pos = 0; /* keep compiler quiet */ -
4470 - break; -
4471 - } -
4472 - 2abe7c8Row pattern recognition patch (executor).
4473 6516 num_reduced_frame = row_is_in_reduced_frame(winobj, 2abe7c8Row pattern recognition patch (executor).
4474 3258 winstate->frameheadpos + relpos); 2abe7c8Row pattern recognition patch (executor).
4475 3258 if (num_reduced_frame < 0) 2abe7c8Row pattern recognition patch (executor).
4476 762 goto out_of_frame; 2abe7c8Row pattern recognition patch (executor).
4477 2496 else if (num_reduced_frame > 0) 2abe7c8Row pattern recognition patch (executor).
4478 258 abs_pos = winstate->frameheadpos + relpos + 2abe7c8Row pattern recognition patch (executor).
4479 - num_reduced_frame - 1; 2abe7c8Row pattern recognition patch (executor).
4480 - break; -
4481 - default: -
4482 - elog(ERROR, "unrecognized window seek type: %d", seektype); -
4483 - abs_pos = mark_pos = 0; /* keep compiler quiet */ -
4484 - break; -
4485 - } -
4486 - -
4487 - if (!window_gettupleslot(winobj, abs_pos, slot)) -
4488 - goto out_of_frame; -
4489 - -
4490 - /* The code above does not detect all out-of-frame cases, so check */ -
4491 - if (row_is_in_frame(winobj, abs_pos, slot, false) <= 0) -
4492 - goto out_of_frame; -
4493 - -
4494 - if (isout) -
4495 - *isout = false; -
4496 - if (set_mark) -
4497 - WinSetMarkPosition(winobj, mark_pos); -
4498 - return 0; 2abe7c8Row pattern recognition patch (executor).
4499 - -
4500 - out_of_frame: -
4501 - if (isout) -
4502 - *isout = true; -
4503 - *isnull = true; -
4504 2166 return -1; 2abe7c8Row pattern recognition patch (executor).
4505 - } -
rpr_is_defined() lines 4542-4545
Modified Lines Coverage: 2/2 lines (100.0%)
LineHitsSourceCommit
4542 662125 rpr_is_defined(WindowAggState *winstate) 2abe7c8Row pattern recognition patch (executor).
4543 - { 2abe7c8Row pattern recognition patch (executor).
4544 662125 return winstate->patternVariableList != NIL; 2abe7c8Row pattern recognition patch (executor).
4545 - } 2abe7c8Row pattern recognition patch (executor).
row_is_in_reduced_frame() lines 4567-4629
Modified Lines Coverage: 22/24 lines (91.7%)
LineHitsSourceCommit
4567 37326 row_is_in_reduced_frame(WindowObject winobj, int64 pos) 2abe7c8Row pattern recognition patch (executor).
4568 - { 2abe7c8Row pattern recognition patch (executor).
4569 37326 WindowAggState *winstate = winobj->winstate; 2abe7c8Row pattern recognition patch (executor).
4570 37326 int state; 2abe7c8Row pattern recognition patch (executor).
4571 37326 int rtn; 2abe7c8Row pattern recognition patch (executor).
4572 - 2abe7c8Row pattern recognition patch (executor).
4573 37326 if (!rpr_is_defined(winstate)) 2abe7c8Row pattern recognition patch (executor).
4574 - { 2abe7c8Row pattern recognition patch (executor).
4575 - /* 2abe7c8Row pattern recognition patch (executor).
4576 - * RPR is not defined. Assume that we are always in the the reduced 2abe7c8Row pattern recognition patch (executor).
4577 - * window frame. 2abe7c8Row pattern recognition patch (executor).
4578 - */ 2abe7c8Row pattern recognition patch (executor).
4579 37326 rtn = 0; 2abe7c8Row pattern recognition patch (executor).
4580 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
4581 - elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, 2abe7c8Row pattern recognition patch (executor).
4582 - rtn, pos); 2abe7c8Row pattern recognition patch (executor).
4583 - #endif 2abe7c8Row pattern recognition patch (executor).
4584 - return rtn; 2abe7c8Row pattern recognition patch (executor).
4585 - } 2abe7c8Row pattern recognition patch (executor).
4586 - 2abe7c8Row pattern recognition patch (executor).
4587 32886 state = get_reduced_frame_map(winstate, pos); 2abe7c8Row pattern recognition patch (executor).
4588 - 2abe7c8Row pattern recognition patch (executor).
4589 32886 if (state == RF_NOT_DETERMINED) 2abe7c8Row pattern recognition patch (executor).
4590 - { 2abe7c8Row pattern recognition patch (executor).
4591 15654 update_frameheadpos(winstate); 2abe7c8Row pattern recognition patch (executor).
4592 15654 update_reduced_frame(winobj, pos); 2abe7c8Row pattern recognition patch (executor).
4593 - } 2abe7c8Row pattern recognition patch (executor).
4594 - 2abe7c8Row pattern recognition patch (executor).
4595 32886 state = get_reduced_frame_map(winstate, pos); 2abe7c8Row pattern recognition patch (executor).
4596 - 2abe7c8Row pattern recognition patch (executor).
4597 32886 switch (state) 2abe7c8Row pattern recognition patch (executor).
4598 - { 2abe7c8Row pattern recognition patch (executor).
4599 15675 int64 i; 2abe7c8Row pattern recognition patch (executor).
4600 15675 int num_reduced_rows; 2abe7c8Row pattern recognition patch (executor).
4601 - 2abe7c8Row pattern recognition patch (executor).
4602 15675 case RF_FRAME_HEAD: 2abe7c8Row pattern recognition patch (executor).
4603 15675 num_reduced_rows = 1; 2abe7c8Row pattern recognition patch (executor).
4604 15675 for (i = pos + 1; 2abe7c8Row pattern recognition patch (executor).
4605 32340 get_reduced_frame_map(winstate, i) == RF_SKIPPED; i++) 2abe7c8Row pattern recognition patch (executor).
4606 16665 num_reduced_rows++; 2abe7c8Row pattern recognition patch (executor).
4607 - rtn = num_reduced_rows; 2abe7c8Row pattern recognition patch (executor).
4608 - break; 2abe7c8Row pattern recognition patch (executor).
4609 - 2abe7c8Row pattern recognition patch (executor).
4610 - case RF_SKIPPED: 2abe7c8Row pattern recognition patch (executor).
4611 - rtn = -2; 2abe7c8Row pattern recognition patch (executor).
4612 - break; 2abe7c8Row pattern recognition patch (executor).
4613 - 2abe7c8Row pattern recognition patch (executor).
4614 741 case RF_UNMATCHED: 2abe7c8Row pattern recognition patch (executor).
4615 741 rtn = -1; 2abe7c8Row pattern recognition patch (executor).
4616 741 break; 2abe7c8Row pattern recognition patch (executor).
4617 - 2abe7c8Row pattern recognition patch (executor).
4618 0 default: 2abe7c8Row pattern recognition patch (executor).
4619 0 elog(ERROR, "Unrecognized state: %d at: " INT64_FORMAT, 2abe7c8Row pattern recognition patch (executor).
4620 - state, pos); 2abe7c8Row pattern recognition patch (executor).
4621 - break; 2abe7c8Row pattern recognition patch (executor).
4622 - } 2abe7c8Row pattern recognition patch (executor).
4623 - 2abe7c8Row pattern recognition patch (executor).
4624 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
4625 - elog(DEBUG1, "row_is_in_reduced_frame returns %d: pos: " INT64_FORMAT, 2abe7c8Row pattern recognition patch (executor).
4626 - rtn, pos); 2abe7c8Row pattern recognition patch (executor).
4627 - #endif 2abe7c8Row pattern recognition patch (executor).
4628 - return rtn; 2abe7c8Row pattern recognition patch (executor).
4629 - } 2abe7c8Row pattern recognition patch (executor).
create_reduced_frame_map() lines 4639-4646
Modified Lines Coverage: 6/6 lines (100.0%)
LineHitsSourceCommit
4639 1936 create_reduced_frame_map(WindowAggState *winstate) 2abe7c8Row pattern recognition patch (executor).
4640 - { 2abe7c8Row pattern recognition patch (executor).
4641 3872 winstate->reduced_frame_map = 2abe7c8Row pattern recognition patch (executor).
4642 1936 MemoryContextAlloc(winstate->partcontext, 2abe7c8Row pattern recognition patch (executor).
4643 - REDUCED_FRAME_MAP_INIT_SIZE); 2abe7c8Row pattern recognition patch (executor).
4644 1936 winstate->alloc_sz = REDUCED_FRAME_MAP_INIT_SIZE; 2abe7c8Row pattern recognition patch (executor).
4645 1936 clear_reduced_frame_map(winstate); 2abe7c8Row pattern recognition patch (executor).
4646 1936 } 2abe7c8Row pattern recognition patch (executor).
clear_reduced_frame_map() lines 4654-4659
Modified Lines Coverage: 4/4 lines (100.0%)
LineHitsSourceCommit
4654 2116 clear_reduced_frame_map(WindowAggState *winstate) 2abe7c8Row pattern recognition patch (executor).
4655 - { 2abe7c8Row pattern recognition patch (executor).
4656 2116 Assert(winstate->reduced_frame_map != NULL); 2abe7c8Row pattern recognition patch (executor).
4657 272964 MemSet(winstate->reduced_frame_map, RF_NOT_DETERMINED, 2abe7c8Row pattern recognition patch (executor).
4658 - winstate->alloc_sz); 2abe7c8Row pattern recognition patch (executor).
4659 2116 } 2abe7c8Row pattern recognition patch (executor).
get_reduced_frame_map() lines 4667-4681
Modified Lines Coverage: 5/5 lines (100.0%)
LineHitsSourceCommit
4667 204471 get_reduced_frame_map(WindowAggState *winstate, int64 pos) 2abe7c8Row pattern recognition patch (executor).
4668 - { 2abe7c8Row pattern recognition patch (executor).
4669 204471 Assert(winstate->reduced_frame_map != NULL); 2abe7c8Row pattern recognition patch (executor).
4670 204471 Assert(pos >= 0); 2abe7c8Row pattern recognition patch (executor).
4671 - 2abe7c8Row pattern recognition patch (executor).
4672 - /* 2abe7c8Row pattern recognition patch (executor).
4673 - * If pos is not in the reduced frame map, it means that any info 2abe7c8Row pattern recognition patch (executor).
4674 - * regarding the pos has not been registered yet. So we return 2abe7c8Row pattern recognition patch (executor).
4675 - * RF_NOT_DETERMINED. 2abe7c8Row pattern recognition patch (executor).
4676 - */ 2abe7c8Row pattern recognition patch (executor).
4677 204471 if (pos >= winstate->alloc_sz) 2abe7c8Row pattern recognition patch (executor).
4678 - return RF_NOT_DETERMINED; 2abe7c8Row pattern recognition patch (executor).
4679 - 2abe7c8Row pattern recognition patch (executor).
4680 204435 return winstate->reduced_frame_map[pos]; 2abe7c8Row pattern recognition patch (executor).
4681 - } 2abe7c8Row pattern recognition patch (executor).
register_reduced_frame_map() lines 4690-4713
Modified Lines Coverage: 12/13 lines (92.3%)
LineHitsSourceCommit
4690 31329 register_reduced_frame_map(WindowAggState *winstate, int64 pos, int val) 2abe7c8Row pattern recognition patch (executor).
4691 - { 2abe7c8Row pattern recognition patch (executor).
4692 31329 int64 realloc_sz; 2abe7c8Row pattern recognition patch (executor).
4693 - 2abe7c8Row pattern recognition patch (executor).
4694 31329 Assert(winstate->reduced_frame_map != NULL); 2abe7c8Row pattern recognition patch (executor).
4695 - 2abe7c8Row pattern recognition patch (executor).
4696 31329 if (pos < 0) 2abe7c8Row pattern recognition patch (executor).
4697 0 elog(ERROR, "wrong pos: " INT64_FORMAT, pos); 2abe7c8Row pattern recognition patch (executor).
4698 - 2abe7c8Row pattern recognition patch (executor).
4699 31329 if (pos > winstate->alloc_sz - 1) 2abe7c8Row pattern recognition patch (executor).
4700 - { 2abe7c8Row pattern recognition patch (executor).
4701 18 realloc_sz = winstate->alloc_sz * 2; 2abe7c8Row pattern recognition patch (executor).
4702 - 2abe7c8Row pattern recognition patch (executor).
4703 36 winstate->reduced_frame_map = 2abe7c8Row pattern recognition patch (executor).
4704 18 repalloc(winstate->reduced_frame_map, realloc_sz); 2abe7c8Row pattern recognition patch (executor).
4705 - 2abe7c8Row pattern recognition patch (executor).
4706 786 MemSet(winstate->reduced_frame_map + winstate->alloc_sz, 2abe7c8Row pattern recognition patch (executor).
4707 - RF_NOT_DETERMINED, realloc_sz - winstate->alloc_sz); 2abe7c8Row pattern recognition patch (executor).
4708 - 2abe7c8Row pattern recognition patch (executor).
4709 18 winstate->alloc_sz = realloc_sz; 2abe7c8Row pattern recognition patch (executor).
4710 - } 2abe7c8Row pattern recognition patch (executor).
4711 - 2abe7c8Row pattern recognition patch (executor).
4712 31329 winstate->reduced_frame_map[pos] = val; 2abe7c8Row pattern recognition patch (executor).
4713 31329 } 2abe7c8Row pattern recognition patch (executor).
update_reduced_frame() lines 4721-4930
Modified Lines Coverage: 61/61 lines (100.0%)
LineHitsSourceCommit
4721 15654 update_reduced_frame(WindowObject winobj, int64 pos) 2abe7c8Row pattern recognition patch (executor).
4722 - { 2abe7c8Row pattern recognition patch (executor).
4723 15654 WindowAggState *winstate = winobj->winstate; 2abe7c8Row pattern recognition patch (executor).
4724 15654 ListCell *lc1, 2abe7c8Row pattern recognition patch (executor).
4725 - *lc2; 2abe7c8Row pattern recognition patch (executor).
4726 15654 bool expression_result; 2abe7c8Row pattern recognition patch (executor).
4727 15654 int num_matched_rows; 2abe7c8Row pattern recognition patch (executor).
4728 15654 int64 original_pos; 2abe7c8Row pattern recognition patch (executor).
4729 15654 bool anymatch; 2abe7c8Row pattern recognition patch (executor).
4730 15654 StringInfo encoded_str; 2abe7c8Row pattern recognition patch (executor).
4731 15654 StringSet *str_set; 2abe7c8Row pattern recognition patch (executor).
4732 15654 bool greedy = false; 2abe7c8Row pattern recognition patch (executor).
4733 15654 int64 result_pos, 2abe7c8Row pattern recognition patch (executor).
4734 - i; 2abe7c8Row pattern recognition patch (executor).
4735 15654 int init_size; 2abe7c8Row pattern recognition patch (executor).
4736 - 2abe7c8Row pattern recognition patch (executor).
4737 - /* 2abe7c8Row pattern recognition patch (executor).
4738 - * Set of pattern variables evaluated to true. Each character corresponds 2abe7c8Row pattern recognition patch (executor).
4739 - * to pattern variable. Example: str_set[0] = "AB"; str_set[1] = "AC"; In 2abe7c8Row pattern recognition patch (executor).
4740 - * this case at row 0 A and B are true, and A and C are true in row 1. 2abe7c8Row pattern recognition patch (executor).
4741 - */ 2abe7c8Row pattern recognition patch (executor).
4742 - 2abe7c8Row pattern recognition patch (executor).
4743 - /* initialize pattern variables set */ 2abe7c8Row pattern recognition patch (executor).
4744 15654 str_set = string_set_init(); 2abe7c8Row pattern recognition patch (executor).
4745 - 2abe7c8Row pattern recognition patch (executor).
4746 - /* save original pos */ 2abe7c8Row pattern recognition patch (executor).
4747 15654 original_pos = pos; 2abe7c8Row pattern recognition patch (executor).
4748 - 2abe7c8Row pattern recognition patch (executor).
4749 - /* 2abe7c8Row pattern recognition patch (executor).
4750 - * Calculate initial memory allocation size from the number of pattern 2abe7c8Row pattern recognition patch (executor).
4751 - * variables, 2abe7c8Row pattern recognition patch (executor).
4752 - */ 2abe7c8Row pattern recognition patch (executor).
4753 15654 init_size = sizeof(char) * list_length(winstate->patternVariableList) + 1; 2abe7c8Row pattern recognition patch (executor).
4754 - 2abe7c8Row pattern recognition patch (executor).
4755 - /* 2abe7c8Row pattern recognition patch (executor).
4756 - * Check if the pattern does not include any greedy quantifier. If it does 2abe7c8Row pattern recognition patch (executor).
4757 - * not, we can just apply the pattern to each row. If it succeeds, we are 2abe7c8Row pattern recognition patch (executor).
4758 - * done. 2abe7c8Row pattern recognition patch (executor).
4759 - */ 2abe7c8Row pattern recognition patch (executor).
4760 31425 foreach(lc1, winstate->patternRegexpList) 2abe7c8Row pattern recognition patch (executor).
4761 - { 2abe7c8Row pattern recognition patch (executor).
4762 16242 char *quantifier = strVal(lfirst(lc1)); 2abe7c8Row pattern recognition patch (executor).
4763 - 2abe7c8Row pattern recognition patch (executor).
4764 16242 if (*quantifier == '+' || *quantifier == '*' || *quantifier == '?') 2abe7c8Row pattern recognition patch (executor).
4765 - { 2abe7c8Row pattern recognition patch (executor).
4766 - greedy = true; 2abe7c8Row pattern recognition patch (executor).
4767 - break; 2abe7c8Row pattern recognition patch (executor).
4768 - } 2abe7c8Row pattern recognition patch (executor).
4769 - } 2abe7c8Row pattern recognition patch (executor).
4770 - 2abe7c8Row pattern recognition patch (executor).
4771 - /* 2abe7c8Row pattern recognition patch (executor).
4772 - * Non greedy case 2abe7c8Row pattern recognition patch (executor).
4773 - */ 2abe7c8Row pattern recognition patch (executor).
4774 15654 if (!greedy) 2abe7c8Row pattern recognition patch (executor).
4775 - { 2abe7c8Row pattern recognition patch (executor).
4776 15183 num_matched_rows = 0; 2abe7c8Row pattern recognition patch (executor).
4777 15183 encoded_str = makeStringInfoExt(init_size); 2abe7c8Row pattern recognition patch (executor).
4778 - 2abe7c8Row pattern recognition patch (executor).
4779 30342 foreach(lc1, winstate->patternVariableList) 2abe7c8Row pattern recognition patch (executor).
4780 - { 2abe7c8Row pattern recognition patch (executor).
4781 15291 char *vname = strVal(lfirst(lc1)); 2abe7c8Row pattern recognition patch (executor).
4782 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
4783 - elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s", 2abe7c8Row pattern recognition patch (executor).
4784 - pos, vname); 2abe7c8Row pattern recognition patch (executor).
4785 - #endif 2abe7c8Row pattern recognition patch (executor).
4786 15291 expression_result = false; 2abe7c8Row pattern recognition patch (executor).
4787 - 2abe7c8Row pattern recognition patch (executor).
4788 - /* evaluate row pattern against current row */ 2abe7c8Row pattern recognition patch (executor).
4789 15291 result_pos = evaluate_pattern(winobj, pos, vname, 2abe7c8Row pattern recognition patch (executor).
4790 - encoded_str, &expression_result); 2abe7c8Row pattern recognition patch (executor).
4791 15291 if (!expression_result || result_pos < 0) 2abe7c8Row pattern recognition patch (executor).
4792 - { 2abe7c8Row pattern recognition patch (executor).
4793 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
4794 - elog(DEBUG1, "expression result is false or out of frame"); 2abe7c8Row pattern recognition patch (executor).
4795 - #endif 2abe7c8Row pattern recognition patch (executor).
4796 132 register_reduced_frame_map(winstate, original_pos, 2abe7c8Row pattern recognition patch (executor).
4797 - RF_UNMATCHED); 2abe7c8Row pattern recognition patch (executor).
4798 132 destroyStringInfo(encoded_str); 2abe7c8Row pattern recognition patch (executor).
4799 132 return; 2abe7c8Row pattern recognition patch (executor).
4800 - } 2abe7c8Row pattern recognition patch (executor).
4801 - /* move to next row */ 2abe7c8Row pattern recognition patch (executor).
4802 15159 pos++; 2abe7c8Row pattern recognition patch (executor).
4803 15159 num_matched_rows++; 2abe7c8Row pattern recognition patch (executor).
4804 - } 2abe7c8Row pattern recognition patch (executor).
4805 15051 destroyStringInfo(encoded_str); 2abe7c8Row pattern recognition patch (executor).
4806 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
4807 - elog(DEBUG1, "pattern matched"); 2abe7c8Row pattern recognition patch (executor).
4808 - #endif 2abe7c8Row pattern recognition patch (executor).
4809 15051 register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD); 2abe7c8Row pattern recognition patch (executor).
4810 - 2abe7c8Row pattern recognition patch (executor).
4811 15093 for (i = original_pos + 1; i < original_pos + num_matched_rows; i++) 2abe7c8Row pattern recognition patch (executor).
4812 - { 2abe7c8Row pattern recognition patch (executor).
4813 42 register_reduced_frame_map(winstate, i, RF_SKIPPED); 2abe7c8Row pattern recognition patch (executor).
4814 - } 2abe7c8Row pattern recognition patch (executor).
4815 - return; 2abe7c8Row pattern recognition patch (executor).
4816 - } 2abe7c8Row pattern recognition patch (executor).
4817 - 2abe7c8Row pattern recognition patch (executor).
4818 - /* 2abe7c8Row pattern recognition patch (executor).
4819 - * Greedy quantifiers included. Loop over until none of pattern matches or 2abe7c8Row pattern recognition patch (executor).
4820 - * encounters end of frame. 2abe7c8Row pattern recognition patch (executor).
4821 - */ 2abe7c8Row pattern recognition patch (executor).
4822 17409 for (;;) 2abe7c8Row pattern recognition patch (executor).
4823 - { 2abe7c8Row pattern recognition patch (executor).
4824 17409 result_pos = -1; 2abe7c8Row pattern recognition patch (executor).
4825 - 2abe7c8Row pattern recognition patch (executor).
4826 - /* 2abe7c8Row pattern recognition patch (executor).
4827 - * Loop over each PATTERN variable. 2abe7c8Row pattern recognition patch (executor).
4828 - */ 2abe7c8Row pattern recognition patch (executor).
4829 17409 anymatch = false; 2abe7c8Row pattern recognition patch (executor).
4830 - 2abe7c8Row pattern recognition patch (executor).
4831 17409 encoded_str = makeStringInfoExt(init_size); 2abe7c8Row pattern recognition patch (executor).
4832 - 2abe7c8Row pattern recognition patch (executor).
4833 38181 forboth(lc1, winstate->patternVariableList, lc2, 2abe7c8Row pattern recognition patch (executor).
4834 - winstate->patternRegexpList) 2abe7c8Row pattern recognition patch (executor).
4835 - { 2abe7c8Row pattern recognition patch (executor).
4836 21135 char *vname = strVal(lfirst(lc1)); 2abe7c8Row pattern recognition patch (executor).
4837 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
4838 - char *quantifier = strVal(lfirst(lc2)); 2abe7c8Row pattern recognition patch (executor).
4839 - 2abe7c8Row pattern recognition patch (executor).
4840 - elog(DEBUG1, "pos: " INT64_FORMAT " pattern vname: %s quantifier: %s", 2abe7c8Row pattern recognition patch (executor).
4841 - pos, vname, quantifier); 2abe7c8Row pattern recognition patch (executor).
4842 - #endif 2abe7c8Row pattern recognition patch (executor).
4843 21135 expression_result = false; 2abe7c8Row pattern recognition patch (executor).
4844 - 2abe7c8Row pattern recognition patch (executor).
4845 - /* evaluate row pattern against current row */ 2abe7c8Row pattern recognition patch (executor).
4846 21135 result_pos = evaluate_pattern(winobj, pos, vname, 2abe7c8Row pattern recognition patch (executor).
4847 - encoded_str, &expression_result); 2abe7c8Row pattern recognition patch (executor).
4848 21135 if (expression_result) 2abe7c8Row pattern recognition patch (executor).
4849 - { 2abe7c8Row pattern recognition patch (executor).
4850 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
4851 - elog(DEBUG1, "expression result is true"); 2abe7c8Row pattern recognition patch (executor).
4852 - #endif 2abe7c8Row pattern recognition patch (executor).
4853 18348 anymatch = true; 2abe7c8Row pattern recognition patch (executor).
4854 - } 2abe7c8Row pattern recognition patch (executor).
4855 - 2abe7c8Row pattern recognition patch (executor).
4856 - /* 2abe7c8Row pattern recognition patch (executor).
4857 - * If out of frame, we are done. 2abe7c8Row pattern recognition patch (executor).
4858 - */ 2abe7c8Row pattern recognition patch (executor).
4859 21135 if (result_pos < 0) 2abe7c8Row pattern recognition patch (executor).
4860 - break; 2abe7c8Row pattern recognition patch (executor).
4861 - } 2abe7c8Row pattern recognition patch (executor).
4862 - 2abe7c8Row pattern recognition patch (executor).
4863 17409 if (!anymatch) 2abe7c8Row pattern recognition patch (executor).
4864 - { 2abe7c8Row pattern recognition patch (executor).
4865 - /* none of patterns matched. */ 2abe7c8Row pattern recognition patch (executor).
4866 - break; 2abe7c8Row pattern recognition patch (executor).
4867 - } 2abe7c8Row pattern recognition patch (executor).
4868 - 2abe7c8Row pattern recognition patch (executor).
4869 16938 string_set_add(str_set, encoded_str, 0); 2abe7c8Row pattern recognition patch (executor).
4870 - 2abe7c8Row pattern recognition patch (executor).
4871 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
4872 - elog(DEBUG1, "pos: " INT64_FORMAT " encoded_str: %s", 2abe7c8Row pattern recognition patch (executor).
4873 - encoded_str->data); 2abe7c8Row pattern recognition patch (executor).
4874 - #endif 2abe7c8Row pattern recognition patch (executor).
4875 - 2abe7c8Row pattern recognition patch (executor).
4876 - /* move to next row */ 2abe7c8Row pattern recognition patch (executor).
4877 16938 pos++; 2abe7c8Row pattern recognition patch (executor).
4878 - 2abe7c8Row pattern recognition patch (executor).
4879 16938 if (result_pos < 0) 2abe7c8Row pattern recognition patch (executor).
4880 - { 2abe7c8Row pattern recognition patch (executor).
4881 - /* out of frame */ 2abe7c8Row pattern recognition patch (executor).
4882 - break; 2abe7c8Row pattern recognition patch (executor).
4883 - } 2abe7c8Row pattern recognition patch (executor).
4884 - } 2abe7c8Row pattern recognition patch (executor).
4885 - 2abe7c8Row pattern recognition patch (executor).
4886 471 if (string_set_get_size(str_set) == 0) 2abe7c8Row pattern recognition patch (executor).
4887 - { 2abe7c8Row pattern recognition patch (executor).
4888 - /* no match found in the first row */ 2abe7c8Row pattern recognition patch (executor).
4889 66 register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED); 2abe7c8Row pattern recognition patch (executor).
4890 66 destroyStringInfo(encoded_str); 2abe7c8Row pattern recognition patch (executor).
4891 66 return; 2abe7c8Row pattern recognition patch (executor).
4892 - } 2abe7c8Row pattern recognition patch (executor).
4893 - 2abe7c8Row pattern recognition patch (executor).
4894 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
4895 - elog(DEBUG2, "pos: " INT64_FORMAT " encoded_str: %s", 2abe7c8Row pattern recognition patch (executor).
4896 - pos, encoded_str->data); 2abe7c8Row pattern recognition patch (executor).
4897 - #endif 2abe7c8Row pattern recognition patch (executor).
4898 - 2abe7c8Row pattern recognition patch (executor).
4899 - /* look for matching pattern variable sequence */ 2abe7c8Row pattern recognition patch (executor).
4900 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
4901 - elog(DEBUG1, "search_str_set started"); 2abe7c8Row pattern recognition patch (executor).
4902 - #endif 2abe7c8Row pattern recognition patch (executor).
4903 405 num_matched_rows = search_str_set(winstate, str_set); 2abe7c8Row pattern recognition patch (executor).
4904 - 2abe7c8Row pattern recognition patch (executor).
4905 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
4906 - elog(DEBUG1, "search_str_set returns: %d", num_matched_rows); 2abe7c8Row pattern recognition patch (executor).
4907 - #endif 2abe7c8Row pattern recognition patch (executor).
4908 405 string_set_discard(str_set); 2abe7c8Row pattern recognition patch (executor).
4909 - 2abe7c8Row pattern recognition patch (executor).
4910 - /* 2abe7c8Row pattern recognition patch (executor).
4911 - * We are at the first row in the reduced frame. Save the number of 2abe7c8Row pattern recognition patch (executor).
4912 - * matched rows as the number of rows in the reduced frame. 2abe7c8Row pattern recognition patch (executor).
4913 - */ 2abe7c8Row pattern recognition patch (executor).
4914 405 if (num_matched_rows <= 0) 2abe7c8Row pattern recognition patch (executor).
4915 - { 2abe7c8Row pattern recognition patch (executor).
4916 - /* no match */ 2abe7c8Row pattern recognition patch (executor).
4917 171 register_reduced_frame_map(winstate, original_pos, RF_UNMATCHED); 2abe7c8Row pattern recognition patch (executor).
4918 - } 2abe7c8Row pattern recognition patch (executor).
4919 - else 2abe7c8Row pattern recognition patch (executor).
4920 - { 2abe7c8Row pattern recognition patch (executor).
4921 234 register_reduced_frame_map(winstate, original_pos, RF_FRAME_HEAD); 2abe7c8Row pattern recognition patch (executor).
4922 - 2abe7c8Row pattern recognition patch (executor).
4923 15867 for (i = original_pos + 1; i < original_pos + num_matched_rows; i++) 2abe7c8Row pattern recognition patch (executor).
4924 - { 2abe7c8Row pattern recognition patch (executor).
4925 15633 register_reduced_frame_map(winstate, i, RF_SKIPPED); 2abe7c8Row pattern recognition patch (executor).
4926 - } 2abe7c8Row pattern recognition patch (executor).
4927 - } 2abe7c8Row pattern recognition patch (executor).
4928 - 2abe7c8Row pattern recognition patch (executor).
4929 - return; 2abe7c8Row pattern recognition patch (executor).
4930 - } 2abe7c8Row pattern recognition patch (executor).
search_str_set() lines 4957-5035
Modified Lines Coverage: 32/33 lines (97.0%)
LineHitsSourceCommit
4957 405 search_str_set(WindowAggState *winstate, StringSet *input_str_set) 2abe7c8Row pattern recognition patch (executor).
4958 - { 2abe7c8Row pattern recognition patch (executor).
4959 405 char *pattern; /* search regexp pattern */ 2abe7c8Row pattern recognition patch (executor).
4960 405 VariablePos *variable_pos; 2abe7c8Row pattern recognition patch (executor).
4961 405 int set_size; /* number of rows in the set */ 2abe7c8Row pattern recognition patch (executor).
4962 405 int resultlen; 2abe7c8Row pattern recognition patch (executor).
4963 405 int index; 2abe7c8Row pattern recognition patch (executor).
4964 405 StringSet *new_str_set; 2abe7c8Row pattern recognition patch (executor).
4965 405 int new_str_size; 2abe7c8Row pattern recognition patch (executor).
4966 405 int len; 2abe7c8Row pattern recognition patch (executor).
4967 405 int info; 2abe7c8Row pattern recognition patch (executor).
4968 405 char tail_pattern_initial; 2abe7c8Row pattern recognition patch (executor).
4969 - 2abe7c8Row pattern recognition patch (executor).
4970 - /* 2abe7c8Row pattern recognition patch (executor).
4971 - * Set last initial char to tail_pattern_initial if we can apply "tail 2abe7c8Row pattern recognition patch (executor).
4972 - * pattern initial optimization". If the last regexp component in pattern 2abe7c8Row pattern recognition patch (executor).
4973 - * is with '+' quatifier, set the initial to tail_pattern_initial. For 2abe7c8Row pattern recognition patch (executor).
4974 - * example if pattern = "ab+", tail_pattern_initial will be 'b'. 2abe7c8Row pattern recognition patch (executor).
4975 - * Otherwise, tail_pattern_initial is '\0'. 2abe7c8Row pattern recognition patch (executor).
4976 - */ 2abe7c8Row pattern recognition patch (executor).
4977 405 pattern = winstate->pattern_str->data; 2abe7c8Row pattern recognition patch (executor).
4978 405 if (pattern[strlen(pattern) - 1] == '+') 2abe7c8Row pattern recognition patch (executor).
4979 405 tail_pattern_initial = pattern[strlen(pattern) - 2]; 2abe7c8Row pattern recognition patch (executor).
4980 - else 2abe7c8Row pattern recognition patch (executor).
4981 - tail_pattern_initial = '\0'; 2abe7c8Row pattern recognition patch (executor).
4982 - 2abe7c8Row pattern recognition patch (executor).
4983 - /* 2abe7c8Row pattern recognition patch (executor).
4984 - * Generate all possible pattern variable name initials as a set of 2abe7c8Row pattern recognition patch (executor).
4985 - * StringInfo named "new_str_set". For example, if we have two rows 2abe7c8Row pattern recognition patch (executor).
4986 - * having "ab" (row 0) and "ac" (row 1) in the input str_set, new_str_set 2abe7c8Row pattern recognition patch (executor).
4987 - * will have set of StringInfo "aa", "ac", "ba" and "bc" in the end. 2abe7c8Row pattern recognition patch (executor).
4988 - */ 2abe7c8Row pattern recognition patch (executor).
4989 405 variable_pos = winstate->variable_pos; 2abe7c8Row pattern recognition patch (executor).
4990 405 new_str_set = generate_patterns(winstate, input_str_set, pattern, variable_pos, 2abe7c8Row pattern recognition patch (executor).
4991 - tail_pattern_initial); 2abe7c8Row pattern recognition patch (executor).
4992 - 2abe7c8Row pattern recognition patch (executor).
4993 - /* 2abe7c8Row pattern recognition patch (executor).
4994 - * Perform pattern matching to find out the longest match. 2abe7c8Row pattern recognition patch (executor).
4995 - */ 2abe7c8Row pattern recognition patch (executor).
4996 405 new_str_size = string_set_get_size(new_str_set); 2abe7c8Row pattern recognition patch (executor).
4997 405 len = 0; 2abe7c8Row pattern recognition patch (executor).
4998 405 resultlen = 0; 2abe7c8Row pattern recognition patch (executor).
4999 405 set_size = string_set_get_size(input_str_set); 2abe7c8Row pattern recognition patch (executor).
5000 - 2abe7c8Row pattern recognition patch (executor).
5001 1029 for (index = 0; index < new_str_size; index++) 2abe7c8Row pattern recognition patch (executor).
5002 - { 2abe7c8Row pattern recognition patch (executor).
5003 711 StringInfo s; 2abe7c8Row pattern recognition patch (executor).
5004 - 2abe7c8Row pattern recognition patch (executor).
5005 711 s = string_set_get(new_str_set, index, &info); 2abe7c8Row pattern recognition patch (executor).
5006 711 if (s == NULL) 2abe7c8Row pattern recognition patch (executor).
5007 0 continue; /* no data */ 2abe7c8Row pattern recognition patch (executor).
5008 - 2abe7c8Row pattern recognition patch (executor).
5009 - /* 2abe7c8Row pattern recognition patch (executor).
5010 - * If the string is scheduled to be discarded, we just disregard it. 2abe7c8Row pattern recognition patch (executor).
5011 - */ 2abe7c8Row pattern recognition patch (executor).
5012 711 if (info & STRSET_DISCARDED) 2abe7c8Row pattern recognition patch (executor).
5013 6 continue; 2abe7c8Row pattern recognition patch (executor).
5014 - 2abe7c8Row pattern recognition patch (executor).
5015 705 len = do_pattern_match(winstate, pattern, s->data, s->len); 2abe7c8Row pattern recognition patch (executor).
5016 705 if (len > resultlen) 2abe7c8Row pattern recognition patch (executor).
5017 - { 2abe7c8Row pattern recognition patch (executor).
5018 - /* remember the longest match */ 2abe7c8Row pattern recognition patch (executor).
5019 234 resultlen = len; 2abe7c8Row pattern recognition patch (executor).
5020 - 2abe7c8Row pattern recognition patch (executor).
5021 - /* 2abe7c8Row pattern recognition patch (executor).
5022 - * If the size of result set is equal to the number of rows in the 2abe7c8Row pattern recognition patch (executor).
5023 - * set, we are done because it's not possible that the number of 2abe7c8Row pattern recognition patch (executor).
5024 - * matching rows exceeds the number of rows in the set. 2abe7c8Row pattern recognition patch (executor).
5025 - */ 2abe7c8Row pattern recognition patch (executor).
5026 234 if (resultlen >= set_size) 2abe7c8Row pattern recognition patch (executor).
5027 - break; 2abe7c8Row pattern recognition patch (executor).
5028 - } 2abe7c8Row pattern recognition patch (executor).
5029 - } 2abe7c8Row pattern recognition patch (executor).
5030 - 2abe7c8Row pattern recognition patch (executor).
5031 - /* we no longer need new string set */ 2abe7c8Row pattern recognition patch (executor).
5032 405 string_set_discard(new_str_set); 2abe7c8Row pattern recognition patch (executor).
5033 - 2abe7c8Row pattern recognition patch (executor).
5034 405 return resultlen; 2abe7c8Row pattern recognition patch (executor).
5035 - } 2abe7c8Row pattern recognition patch (executor).
generate_patterns() lines 5049-5176
Modified Lines Coverage: 49/49 lines (100.0%)
LineHitsSourceCommit
5049 405 generate_patterns(WindowAggState *winstate, StringSet *input_str_set, 2abe7c8Row pattern recognition patch (executor).
5050 - char *pattern, VariablePos *variable_pos, 2abe7c8Row pattern recognition patch (executor).
5051 - char tail_pattern_initial) 2abe7c8Row pattern recognition patch (executor).
5052 - { 2abe7c8Row pattern recognition patch (executor).
5053 405 StringSet *old_str_set, 2abe7c8Row pattern recognition patch (executor).
5054 - *new_str_set; 2abe7c8Row pattern recognition patch (executor).
5055 405 int index; 2abe7c8Row pattern recognition patch (executor).
5056 405 int set_size; 2abe7c8Row pattern recognition patch (executor).
5057 405 int old_set_size; 2abe7c8Row pattern recognition patch (executor).
5058 405 int info; 2abe7c8Row pattern recognition patch (executor).
5059 405 int resultlen; 2abe7c8Row pattern recognition patch (executor).
5060 405 StringInfo str; 2abe7c8Row pattern recognition patch (executor).
5061 405 int i; 2abe7c8Row pattern recognition patch (executor).
5062 405 char *p; 2abe7c8Row pattern recognition patch (executor).
5063 - 2abe7c8Row pattern recognition patch (executor).
5064 405 new_str_set = string_set_init(); 2abe7c8Row pattern recognition patch (executor).
5065 405 set_size = string_set_get_size(input_str_set); 2abe7c8Row pattern recognition patch (executor).
5066 405 if (set_size == 0) /* if there's no row in input, return empty 2abe7c8Row pattern recognition patch (executor).
5067 - * set */ 2abe7c8Row pattern recognition patch (executor).
5068 - return new_str_set; 2abe7c8Row pattern recognition patch (executor).
5069 - 2abe7c8Row pattern recognition patch (executor).
5070 405 resultlen = 0; 2abe7c8Row pattern recognition patch (executor).
5071 - 2abe7c8Row pattern recognition patch (executor).
5072 - /* 2abe7c8Row pattern recognition patch (executor).
5073 - * Generate initial new_string_set for input row 0. 2abe7c8Row pattern recognition patch (executor).
5074 - */ 2abe7c8Row pattern recognition patch (executor).
5075 405 str = string_set_get(input_str_set, 0, &info); 2abe7c8Row pattern recognition patch (executor).
5076 405 p = str->data; 2abe7c8Row pattern recognition patch (executor).
5077 - 2abe7c8Row pattern recognition patch (executor).
5078 - /* 2abe7c8Row pattern recognition patch (executor).
5079 - * Loop over each new pattern variable char. 2abe7c8Row pattern recognition patch (executor).
5080 - */ 2abe7c8Row pattern recognition patch (executor).
5081 870 while (*p) 2abe7c8Row pattern recognition patch (executor).
5082 - { 2abe7c8Row pattern recognition patch (executor).
5083 465 StringInfo new = makeStringInfo(); 2abe7c8Row pattern recognition patch (executor).
5084 - 2abe7c8Row pattern recognition patch (executor).
5085 - /* add pattern variable char */ 2abe7c8Row pattern recognition patch (executor).
5086 465 appendStringInfoChar(new, *p); 2abe7c8Row pattern recognition patch (executor).
5087 - /* add new one to string set */ 2abe7c8Row pattern recognition patch (executor).
5088 465 string_set_add(new_str_set, new, 0); 2abe7c8Row pattern recognition patch (executor).
5089 465 p++; /* next pattern variable */ 2abe7c8Row pattern recognition patch (executor).
5090 - } 2abe7c8Row pattern recognition patch (executor).
5091 - 2abe7c8Row pattern recognition patch (executor).
5092 - /* 2abe7c8Row pattern recognition patch (executor).
5093 - * Generate new_string_set for each input row. 2abe7c8Row pattern recognition patch (executor).
5094 - */ 2abe7c8Row pattern recognition patch (executor).
5095 16938 for (index = 1; index < set_size; index++) 2abe7c8Row pattern recognition patch (executor).
5096 - { 2abe7c8Row pattern recognition patch (executor).
5097 - /* previous new str set now becomes old str set */ 2abe7c8Row pattern recognition patch (executor).
5098 16533 old_str_set = new_str_set; 2abe7c8Row pattern recognition patch (executor).
5099 16533 new_str_set = string_set_init(); /* create new string set */ 2abe7c8Row pattern recognition patch (executor).
5100 - /* pick up input string */ 2abe7c8Row pattern recognition patch (executor).
5101 16533 str = string_set_get(input_str_set, index, &info); 2abe7c8Row pattern recognition patch (executor).
5102 16533 old_set_size = string_set_get_size(old_str_set); 2abe7c8Row pattern recognition patch (executor).
5103 - 2abe7c8Row pattern recognition patch (executor).
5104 - /* 2abe7c8Row pattern recognition patch (executor).
5105 - * Loop over each row in the previous result set. 2abe7c8Row pattern recognition patch (executor).
5106 - */ 2abe7c8Row pattern recognition patch (executor).
5107 33864 for (i = 0; i < old_set_size; i++) 2abe7c8Row pattern recognition patch (executor).
5108 - { 2abe7c8Row pattern recognition patch (executor).
5109 17331 char last_old_char; 2abe7c8Row pattern recognition patch (executor).
5110 17331 int old_str_len; 2abe7c8Row pattern recognition patch (executor).
5111 17331 int old_info; 2abe7c8Row pattern recognition patch (executor).
5112 17331 StringInfo old; 2abe7c8Row pattern recognition patch (executor).
5113 - 2abe7c8Row pattern recognition patch (executor).
5114 17331 old = string_set_get(old_str_set, i, &old_info); 2abe7c8Row pattern recognition patch (executor).
5115 17331 p = old->data; 2abe7c8Row pattern recognition patch (executor).
5116 17331 old_str_len = old->len; 2abe7c8Row pattern recognition patch (executor).
5117 17331 if (old_str_len > 0) 2abe7c8Row pattern recognition patch (executor).
5118 17331 last_old_char = p[old_str_len - 1]; 2abe7c8Row pattern recognition patch (executor).
5119 - else 2abe7c8Row pattern recognition patch (executor).
5120 - last_old_char = '\0'; 2abe7c8Row pattern recognition patch (executor).
5121 - 2abe7c8Row pattern recognition patch (executor).
5122 - /* Can this old set be discarded? */ 2abe7c8Row pattern recognition patch (executor).
5123 17331 if (old_info & STRSET_DISCARDED) 2abe7c8Row pattern recognition patch (executor).
5124 855 continue; /* discard the old string */ 2abe7c8Row pattern recognition patch (executor).
5125 - 2abe7c8Row pattern recognition patch (executor).
5126 - /* Is this old set frozen? */ 2abe7c8Row pattern recognition patch (executor).
5127 17325 else if (old_info & STRSET_FROZEN) 2abe7c8Row pattern recognition patch (executor).
5128 - { 2abe7c8Row pattern recognition patch (executor).
5129 - /* if shorter match. we can discard it */ 2abe7c8Row pattern recognition patch (executor).
5130 849 if (old_str_len < resultlen) 2abe7c8Row pattern recognition patch (executor).
5131 177 continue; /* discard the shorter string */ 2abe7c8Row pattern recognition patch (executor).
5132 - 2abe7c8Row pattern recognition patch (executor).
5133 - /* move the old set to new_str_set */ 2abe7c8Row pattern recognition patch (executor).
5134 672 string_set_add(new_str_set, old, old_info); 2abe7c8Row pattern recognition patch (executor).
5135 672 old_str_set->str_set[i] = NULL; 2abe7c8Row pattern recognition patch (executor).
5136 672 continue; 2abe7c8Row pattern recognition patch (executor).
5137 - } 2abe7c8Row pattern recognition patch (executor).
5138 - 2abe7c8Row pattern recognition patch (executor).
5139 - /* 2abe7c8Row pattern recognition patch (executor).
5140 - * loop over each pattern variable initial char in the input set. 2abe7c8Row pattern recognition patch (executor).
5141 - */ 2abe7c8Row pattern recognition patch (executor).
5142 34512 for (p = str->data; *p; p++) 2abe7c8Row pattern recognition patch (executor).
5143 - { 2abe7c8Row pattern recognition patch (executor).
5144 - /* 2abe7c8Row pattern recognition patch (executor).
5145 - * Optimization. Check if the row's pattern variable initial 2abe7c8Row pattern recognition patch (executor).
5146 - * character position is greater than or equal to the old 2abe7c8Row pattern recognition patch (executor).
5147 - * set's last pattern variable initial character position. For 2abe7c8Row pattern recognition patch (executor).
5148 - * example, if the old set's last pattern variable initials 2abe7c8Row pattern recognition patch (executor).
5149 - * are "ab", then the new pattern variable initial can be "b" 2abe7c8Row pattern recognition patch (executor).
5150 - * or "c" but can not be "a", if the initials in PATTERN is 2abe7c8Row pattern recognition patch (executor).
5151 - * something like "a b c" or "a b+ c+" etc. This optimization 2abe7c8Row pattern recognition patch (executor).
5152 - * is possible when we only allow "+" quantifier. 2abe7c8Row pattern recognition patch (executor).
5153 - */ 2abe7c8Row pattern recognition patch (executor).
5154 18036 if (variable_pos_compare(variable_pos, last_old_char, *p)) 2abe7c8Row pattern recognition patch (executor).
5155 - 2abe7c8Row pattern recognition patch (executor).
5156 - /* 2abe7c8Row pattern recognition patch (executor).
5157 - * Satisfied the condition. Add new pattern char to 2abe7c8Row pattern recognition patch (executor).
5158 - * new_str_set if it looks good. 2abe7c8Row pattern recognition patch (executor).
5159 - */ 2abe7c8Row pattern recognition patch (executor).
5160 16842 resultlen = add_pattern(winstate, old, old_info, new_str_set, *p, 2abe7c8Row pattern recognition patch (executor).
5161 - pattern, tail_pattern_initial, resultlen); 2abe7c8Row pattern recognition patch (executor).
5162 - else 2abe7c8Row pattern recognition patch (executor).
5163 - 2abe7c8Row pattern recognition patch (executor).
5164 - /* 2abe7c8Row pattern recognition patch (executor).
5165 - * The old_str did not satisfy the condition and it cannot 2abe7c8Row pattern recognition patch (executor).
5166 - * be extended further. "Freeze" it. 2abe7c8Row pattern recognition patch (executor).
5167 - */ 2abe7c8Row pattern recognition patch (executor).
5168 1194 resultlen = freeze_pattern(winstate, old, old_info, 2abe7c8Row pattern recognition patch (executor).
5169 - new_str_set, pattern, resultlen); 2abe7c8Row pattern recognition patch (executor).
5170 - } 2abe7c8Row pattern recognition patch (executor).
5171 - } 2abe7c8Row pattern recognition patch (executor).
5172 - /* we no longer need old string set */ 2abe7c8Row pattern recognition patch (executor).
5173 16533 string_set_discard(old_str_set); 2abe7c8Row pattern recognition patch (executor).
5174 - } 2abe7c8Row pattern recognition patch (executor).
5175 - return new_str_set; 2abe7c8Row pattern recognition patch (executor).
5176 - } 2abe7c8Row pattern recognition patch (executor).
add_pattern() lines 5189-5265
Modified Lines Coverage: 23/23 lines (100.0%)
LineHitsSourceCommit
5189 16842 add_pattern(WindowAggState *winstate, StringInfo old, int old_info, 2abe7c8Row pattern recognition patch (executor).
5190 - StringSet *new_str_set, char c, char *pattern, char tail_pattern_initial, 2abe7c8Row pattern recognition patch (executor).
5191 - int resultlen) 2abe7c8Row pattern recognition patch (executor).
5192 - { 2abe7c8Row pattern recognition patch (executor).
5193 16842 StringInfo new; 2abe7c8Row pattern recognition patch (executor).
5194 16842 int info; 2abe7c8Row pattern recognition patch (executor).
5195 16842 int len; 2abe7c8Row pattern recognition patch (executor).
5196 - 2abe7c8Row pattern recognition patch (executor).
5197 - /* 2abe7c8Row pattern recognition patch (executor).
5198 - * New char in the input row satisfies the condition above. 2abe7c8Row pattern recognition patch (executor).
5199 - */ 2abe7c8Row pattern recognition patch (executor).
5200 16842 new = makeStringInfoExt(old->len + 1); /* copy source string */ 2abe7c8Row pattern recognition patch (executor).
5201 16842 appendStringInfoString(new, old->data); 2abe7c8Row pattern recognition patch (executor).
5202 - 2abe7c8Row pattern recognition patch (executor).
5203 - /* add pattern variable char */ 2abe7c8Row pattern recognition patch (executor).
5204 16842 appendStringInfoChar(new, c); 2abe7c8Row pattern recognition patch (executor).
5205 - 2abe7c8Row pattern recognition patch (executor).
5206 - /* 2abe7c8Row pattern recognition patch (executor).
5207 - * Adhoc optimization. If the first letter in the input string is in the 2abe7c8Row pattern recognition patch (executor).
5208 - * head and second position and there's no associated quatifier '+', then 2abe7c8Row pattern recognition patch (executor).
5209 - * we can dicard the input because there's no chance to expand the string 2abe7c8Row pattern recognition patch (executor).
5210 - * further. 2abe7c8Row pattern recognition patch (executor).
5211 - * 2abe7c8Row pattern recognition patch (executor).
5212 - * For example, pattern "abc" cannot match "aa". 2abe7c8Row pattern recognition patch (executor).
5213 - */ 2abe7c8Row pattern recognition patch (executor).
5214 16842 if (pattern[1] == new->data[0] && 2abe7c8Row pattern recognition patch (executor).
5215 16734 pattern[1] == new->data[1] && 2abe7c8Row pattern recognition patch (executor).
5216 15492 pattern[2] != '+' && 2abe7c8Row pattern recognition patch (executor).
5217 - pattern[1] != pattern[2]) 2abe7c8Row pattern recognition patch (executor).
5218 - { 2abe7c8Row pattern recognition patch (executor).
5219 249 destroyStringInfo(new); 2abe7c8Row pattern recognition patch (executor).
5220 249 return resultlen; 2abe7c8Row pattern recognition patch (executor).
5221 - } 2abe7c8Row pattern recognition patch (executor).
5222 - 2abe7c8Row pattern recognition patch (executor).
5223 16593 info = old_info; 2abe7c8Row pattern recognition patch (executor).
5224 - 2abe7c8Row pattern recognition patch (executor).
5225 - /* 2abe7c8Row pattern recognition patch (executor).
5226 - * Check if we can apply "tail pattern initial optimization". If the last 2abe7c8Row pattern recognition patch (executor).
5227 - * regexp component in pattern has '+' quantifier, the component is set to 2abe7c8Row pattern recognition patch (executor).
5228 - * the last pattern initial. For example if pattern is "ab+", 2abe7c8Row pattern recognition patch (executor).
5229 - * tail_pattern_initial will become 'b'. Otherwise, tail_pattern_initial 2abe7c8Row pattern recognition patch (executor).
5230 - * is '\0'. If the tail pattern initial optimization is possible, we do 2abe7c8Row pattern recognition patch (executor).
5231 - * not need to apply regular expression match again. Suppose we have the 2abe7c8Row pattern recognition patch (executor).
5232 - * previous string ended with "b" and the it was confirmed the regular 2abe7c8Row pattern recognition patch (executor).
5233 - * expression match, then char 'b' can be added to the string without 2abe7c8Row pattern recognition patch (executor).
5234 - * applying the regular expression match again. 2abe7c8Row pattern recognition patch (executor).
5235 - */ 2abe7c8Row pattern recognition patch (executor).
5236 16593 if (c == tail_pattern_initial) /* tail pattern initial optimization 2abe7c8Row pattern recognition patch (executor).
5237 - * possible? */ 2abe7c8Row pattern recognition patch (executor).
5238 - { 2abe7c8Row pattern recognition patch (executor).
5239 - /* 2abe7c8Row pattern recognition patch (executor).
5240 - * Is already confirmed to be matched with pattern? 2abe7c8Row pattern recognition patch (executor).
5241 - */ 2abe7c8Row pattern recognition patch (executor).
5242 16107 if ((info & STRSET_MATCHED) == 0) 2abe7c8Row pattern recognition patch (executor).
5243 - { 2abe7c8Row pattern recognition patch (executor).
5244 - /* not confirmed yet */ 2abe7c8Row pattern recognition patch (executor).
5245 576 len = do_pattern_match(winstate, pattern, new->data, new->len); 2abe7c8Row pattern recognition patch (executor).
5246 576 if (len > 0) 2abe7c8Row pattern recognition patch (executor).
5247 354 info = STRSET_MATCHED; /* set already confirmed flag */ 2abe7c8Row pattern recognition patch (executor).
5248 - } 2abe7c8Row pattern recognition patch (executor).
5249 - else 2abe7c8Row pattern recognition patch (executor).
5250 - 2abe7c8Row pattern recognition patch (executor).
5251 - /* 2abe7c8Row pattern recognition patch (executor).
5252 - * already confirmed. Use the string length as the matching length 2abe7c8Row pattern recognition patch (executor).
5253 - */ 2abe7c8Row pattern recognition patch (executor).
5254 15531 len = new->len; 2abe7c8Row pattern recognition patch (executor).
5255 - 2abe7c8Row pattern recognition patch (executor).
5256 - /* update the longest match length if needed */ 2abe7c8Row pattern recognition patch (executor).
5257 16107 if (len > resultlen) 2abe7c8Row pattern recognition patch (executor).
5258 15423 resultlen = len; 2abe7c8Row pattern recognition patch (executor).
5259 - } 2abe7c8Row pattern recognition patch (executor).
5260 - 2abe7c8Row pattern recognition patch (executor).
5261 - /* add new StringInfo to the string set */ 2abe7c8Row pattern recognition patch (executor).
5262 16593 string_set_add(new_str_set, new, info); 2abe7c8Row pattern recognition patch (executor).
5263 - 2abe7c8Row pattern recognition patch (executor).
5264 16593 return resultlen; 2abe7c8Row pattern recognition patch (executor).
5265 - } 2abe7c8Row pattern recognition patch (executor).
freeze_pattern() lines 5279-5356
Modified Lines Coverage: 23/23 lines (100.0%)
LineHitsSourceCommit
5279 1194 freeze_pattern(WindowAggState *winstate, StringInfo old, int old_info, 2abe7c8Row pattern recognition patch (executor).
5280 - StringSet *new_str_set, 2abe7c8Row pattern recognition patch (executor).
5281 - char *pattern, int resultlen) 2abe7c8Row pattern recognition patch (executor).
5282 - { 2abe7c8Row pattern recognition patch (executor).
5283 1194 int len; 2abe7c8Row pattern recognition patch (executor).
5284 1194 StringInfo new; 2abe7c8Row pattern recognition patch (executor).
5285 1194 int new_str_size; 2abe7c8Row pattern recognition patch (executor).
5286 1194 int new_index; 2abe7c8Row pattern recognition patch (executor).
5287 - 2abe7c8Row pattern recognition patch (executor).
5288 - /* 2abe7c8Row pattern recognition patch (executor).
5289 - * We are freezing this pattern string. If the pattern string length is 2abe7c8Row pattern recognition patch (executor).
5290 - * shorter than the current longest string length, we don't need to keep 2abe7c8Row pattern recognition patch (executor).
5291 - * it. 2abe7c8Row pattern recognition patch (executor).
5292 - */ 2abe7c8Row pattern recognition patch (executor).
5293 1194 if (old->len < resultlen) 2abe7c8Row pattern recognition patch (executor).
5294 - return resultlen; 2abe7c8Row pattern recognition patch (executor).
5295 - 2abe7c8Row pattern recognition patch (executor).
5296 828 if (old_info & STRSET_MATCHED) 2abe7c8Row pattern recognition patch (executor).
5297 - /* we don't need to apply pattern match again */ 2abe7c8Row pattern recognition patch (executor).
5298 - len = old->len; 2abe7c8Row pattern recognition patch (executor).
5299 - else 2abe7c8Row pattern recognition patch (executor).
5300 - { 2abe7c8Row pattern recognition patch (executor).
5301 - /* apply pattern match */ 2abe7c8Row pattern recognition patch (executor).
5302 366 len = do_pattern_match(winstate, pattern, old->data, old->len); 2abe7c8Row pattern recognition patch (executor).
5303 366 if (len <= 0) 2abe7c8Row pattern recognition patch (executor).
5304 - { 2abe7c8Row pattern recognition patch (executor).
5305 - /* no match. we can discard it */ 2abe7c8Row pattern recognition patch (executor).
5306 - return resultlen; 2abe7c8Row pattern recognition patch (executor).
5307 - } 2abe7c8Row pattern recognition patch (executor).
5308 - } 2abe7c8Row pattern recognition patch (executor).
5309 462 if (len < resultlen) 2abe7c8Row pattern recognition patch (executor).
5310 - { 2abe7c8Row pattern recognition patch (executor).
5311 - /* shorter match. we can discard it */ 2abe7c8Row pattern recognition patch (executor).
5312 - return resultlen; 2abe7c8Row pattern recognition patch (executor).
5313 - } 2abe7c8Row pattern recognition patch (executor).
5314 - 2abe7c8Row pattern recognition patch (executor).
5315 - /* 2abe7c8Row pattern recognition patch (executor).
5316 - * Match length is the longest so far 2abe7c8Row pattern recognition patch (executor).
5317 - */ 2abe7c8Row pattern recognition patch (executor).
5318 462 resultlen = len; /* remember the longest match */ 2abe7c8Row pattern recognition patch (executor).
5319 - 2abe7c8Row pattern recognition patch (executor).
5320 - /* freeze the pattern string */ 2abe7c8Row pattern recognition patch (executor).
5321 462 new = makeStringInfo(); 2abe7c8Row pattern recognition patch (executor).
5322 462 enlargeStringInfo(new, old->len + 1); 2abe7c8Row pattern recognition patch (executor).
5323 462 appendStringInfoString(new, old->data); 2abe7c8Row pattern recognition patch (executor).
5324 - /* set frozen mark */ 2abe7c8Row pattern recognition patch (executor).
5325 462 string_set_add(new_str_set, new, STRSET_FROZEN); 2abe7c8Row pattern recognition patch (executor).
5326 - 2abe7c8Row pattern recognition patch (executor).
5327 - /* 2abe7c8Row pattern recognition patch (executor).
5328 - * Search new_str_set to find out frozen entries that have shorter match 2abe7c8Row pattern recognition patch (executor).
5329 - * length. Mark them as "discard" so that they are discarded in the next 2abe7c8Row pattern recognition patch (executor).
5330 - * round. 2abe7c8Row pattern recognition patch (executor).
5331 - */ 2abe7c8Row pattern recognition patch (executor).
5332 462 new_str_size = 2abe7c8Row pattern recognition patch (executor).
5333 462 string_set_get_size(new_str_set) - 1; 2abe7c8Row pattern recognition patch (executor).
5334 - 2abe7c8Row pattern recognition patch (executor).
5335 - /* loop over new_str_set */ 2abe7c8Row pattern recognition patch (executor).
5336 2112 for (new_index = 0; new_index < new_str_size; new_index++) 2abe7c8Row pattern recognition patch (executor).
5337 - { 2abe7c8Row pattern recognition patch (executor).
5338 1650 int info; 2abe7c8Row pattern recognition patch (executor).
5339 - 2abe7c8Row pattern recognition patch (executor).
5340 1650 new = string_set_get(new_str_set, new_index, &info); 2abe7c8Row pattern recognition patch (executor).
5341 - 2abe7c8Row pattern recognition patch (executor).
5342 - /* 2abe7c8Row pattern recognition patch (executor).
5343 - * If this is frozen and is not longer than the current longest match 2abe7c8Row pattern recognition patch (executor).
5344 - * length, we don't need to keep this. 2abe7c8Row pattern recognition patch (executor).
5345 - */ 2abe7c8Row pattern recognition patch (executor).
5346 1650 if (info & STRSET_FROZEN && new->len < resultlen) 2abe7c8Row pattern recognition patch (executor).
5347 - { 2abe7c8Row pattern recognition patch (executor).
5348 - /* 2abe7c8Row pattern recognition patch (executor).
5349 - * mark this set to discard in the next round 2abe7c8Row pattern recognition patch (executor).
5350 - */ 2abe7c8Row pattern recognition patch (executor).
5351 12 info |= STRSET_DISCARDED; 2abe7c8Row pattern recognition patch (executor).
5352 12 new_str_set->info[new_index] = info; 2abe7c8Row pattern recognition patch (executor).
5353 - } 2abe7c8Row pattern recognition patch (executor).
5354 - } 2abe7c8Row pattern recognition patch (executor).
5355 - return resultlen; 2abe7c8Row pattern recognition patch (executor).
5356 - } 2abe7c8Row pattern recognition patch (executor).
do_pattern_match() lines 5367-5447
Modified Lines Coverage: 29/33 lines (87.9%)
LineHitsSourceCommit
5367 1647 do_pattern_match(WindowAggState *winstate, char *pattern, char *encoded_str, int len) 2abe7c8Row pattern recognition patch (executor).
5368 - { 2abe7c8Row pattern recognition patch (executor).
5369 1647 int plen; 2abe7c8Row pattern recognition patch (executor).
5370 1647 int cflags = REG_EXTENDED; 2abe7c8Row pattern recognition patch (executor).
5371 1647 size_t nmatch = 1; 2abe7c8Row pattern recognition patch (executor).
5372 1647 int eflags = 0; 2abe7c8Row pattern recognition patch (executor).
5373 1647 regmatch_t pmatch[1]; 2abe7c8Row pattern recognition patch (executor).
5374 1647 int sts; 2abe7c8Row pattern recognition patch (executor).
5375 1647 pg_wchar *data; 2abe7c8Row pattern recognition patch (executor).
5376 1647 int data_len; 2abe7c8Row pattern recognition patch (executor).
5377 - 2abe7c8Row pattern recognition patch (executor).
5378 - /* 2abe7c8Row pattern recognition patch (executor).
5379 - * Compile regexp if cache does not exist or existing cache is not same as 2abe7c8Row pattern recognition patch (executor).
5380 - * "pattern". 2abe7c8Row pattern recognition patch (executor).
5381 - */ 2abe7c8Row pattern recognition patch (executor).
5382 1647 if (winstate->patbuf == NULL || strcmp(winstate->patbuf, pattern)) 2abe7c8Row pattern recognition patch (executor).
5383 - { 2abe7c8Row pattern recognition patch (executor).
5384 54 MemoryContext oldContext = MemoryContextSwitchTo 2abe7c8Row pattern recognition patch (executor).
5385 54 (winstate->ss.ps.ps_ExprContext->ecxt_per_query_memory); 2abe7c8Row pattern recognition patch (executor).
5386 - 2abe7c8Row pattern recognition patch (executor).
5387 54 pattern_regfree(winstate); 2abe7c8Row pattern recognition patch (executor).
5388 - 2abe7c8Row pattern recognition patch (executor).
5389 - /* we need to convert to char to pg_wchar */ 2abe7c8Row pattern recognition patch (executor).
5390 54 plen = strlen(pattern); 2abe7c8Row pattern recognition patch (executor).
5391 54 data = (pg_wchar *) palloc((plen + 1) * sizeof(pg_wchar)); 2abe7c8Row pattern recognition patch (executor).
5392 54 data_len = pg_mb2wchar_with_len(pattern, data, plen); 2abe7c8Row pattern recognition patch (executor).
5393 - /* compile re */ 2abe7c8Row pattern recognition patch (executor).
5394 54 sts = pg_regcomp(&winstate->preg, /* compiled re */ 2abe7c8Row pattern recognition patch (executor).
5395 - data, /* target pattern */ 2abe7c8Row pattern recognition patch (executor).
5396 - data_len, /* length of pattern */ 2abe7c8Row pattern recognition patch (executor).
5397 - cflags, /* compile option */ 2abe7c8Row pattern recognition patch (executor).
5398 - C_COLLATION_OID /* collation */ 2abe7c8Row pattern recognition patch (executor).
5399 - ); 2abe7c8Row pattern recognition patch (executor).
5400 54 pfree(data); 2abe7c8Row pattern recognition patch (executor).
5401 - 2abe7c8Row pattern recognition patch (executor).
5402 54 if (sts != REG_OKAY) 2abe7c8Row pattern recognition patch (executor).
5403 - { 2abe7c8Row pattern recognition patch (executor).
5404 - /* re didn't compile (no need for pg_regfree, if so) */ 2abe7c8Row pattern recognition patch (executor).
5405 0 ereport(ERROR, 2abe7c8Row pattern recognition patch (executor).
5406 - (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION), 2abe7c8Row pattern recognition patch (executor).
5407 - errmsg("invalid regular expression: %s", pattern))); 2abe7c8Row pattern recognition patch (executor).
5408 - } 2abe7c8Row pattern recognition patch (executor).
5409 - 2abe7c8Row pattern recognition patch (executor).
5410 - /* save pattern */ 2abe7c8Row pattern recognition patch (executor).
5411 54 winstate->patbuf = pstrdup(pattern); 2abe7c8Row pattern recognition patch (executor).
5412 54 MemoryContextSwitchTo(oldContext); 2abe7c8Row pattern recognition patch (executor).
5413 - } 2abe7c8Row pattern recognition patch (executor).
5414 - 2abe7c8Row pattern recognition patch (executor).
5415 1647 data = (pg_wchar *) palloc((len + 1) * sizeof(pg_wchar)); 2abe7c8Row pattern recognition patch (executor).
5416 1647 data_len = pg_mb2wchar_with_len(encoded_str, data, len); 2abe7c8Row pattern recognition patch (executor).
5417 - 2abe7c8Row pattern recognition patch (executor).
5418 - /* execute the regular expression match */ 2abe7c8Row pattern recognition patch (executor).
5419 1647 sts = pg_regexec( 2abe7c8Row pattern recognition patch (executor).
5420 - &winstate->preg, /* compiled re */ 2abe7c8Row pattern recognition patch (executor).
5421 - data, /* target string */ 2abe7c8Row pattern recognition patch (executor).
5422 - data_len, /* length of encoded_str */ 2abe7c8Row pattern recognition patch (executor).
5423 - 0, /* search start */ 2abe7c8Row pattern recognition patch (executor).
5424 - NULL, /* rm details */ 2abe7c8Row pattern recognition patch (executor).
5425 - nmatch, /* number of match sub re */ 2abe7c8Row pattern recognition patch (executor).
5426 - pmatch, /* match result details */ 2abe7c8Row pattern recognition patch (executor).
5427 - eflags); 2abe7c8Row pattern recognition patch (executor).
5428 - 2abe7c8Row pattern recognition patch (executor).
5429 1647 pfree(data); 2abe7c8Row pattern recognition patch (executor).
5430 - 2abe7c8Row pattern recognition patch (executor).
5431 1647 if (sts != REG_OKAY) 2abe7c8Row pattern recognition patch (executor).
5432 - { 2abe7c8Row pattern recognition patch (executor).
5433 741 if (sts != REG_NOMATCH) 2abe7c8Row pattern recognition patch (executor).
5434 - { 2abe7c8Row pattern recognition patch (executor).
5435 0 char errMsg[100]; 2abe7c8Row pattern recognition patch (executor).
5436 - 2abe7c8Row pattern recognition patch (executor).
5437 0 pg_regerror(sts, &winstate->preg, errMsg, sizeof(errMsg)); 2abe7c8Row pattern recognition patch (executor).
5438 0 ereport(ERROR, 2abe7c8Row pattern recognition patch (executor).
5439 - (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION), 2abe7c8Row pattern recognition patch (executor).
5440 - errmsg("regular expression failed: %s", errMsg))); 2abe7c8Row pattern recognition patch (executor).
5441 - } 2abe7c8Row pattern recognition patch (executor).
5442 - return 0; /* does not match */ 2abe7c8Row pattern recognition patch (executor).
5443 - } 2abe7c8Row pattern recognition patch (executor).
5444 - 2abe7c8Row pattern recognition patch (executor).
5445 906 len = pmatch[0].rm_eo; /* return match length */ 2abe7c8Row pattern recognition patch (executor).
5446 906 return len; 2abe7c8Row pattern recognition patch (executor).
5447 - } 2abe7c8Row pattern recognition patch (executor).
pattern_regfree() lines 5456-5464
Modified Lines Coverage: 6/6 lines (100.0%)
LineHitsSourceCommit
5456 1402 pattern_regfree(WindowAggState *winstate) 2abe7c8Row pattern recognition patch (executor).
5457 - { 2abe7c8Row pattern recognition patch (executor).
5458 1402 if (winstate->patbuf != NULL) 2abe7c8Row pattern recognition patch (executor).
5459 - { 2abe7c8Row pattern recognition patch (executor).
5460 54 pg_regfree(&winstate->preg); /* free previous re */ 2abe7c8Row pattern recognition patch (executor).
5461 54 pfree(winstate->patbuf); 2abe7c8Row pattern recognition patch (executor).
5462 54 winstate->patbuf = NULL; 2abe7c8Row pattern recognition patch (executor).
5463 - } 2abe7c8Row pattern recognition patch (executor).
5464 1402 } 2abe7c8Row pattern recognition patch (executor).
evaluate_pattern() lines 5482-5572
Modified Lines Coverage: 38/38 lines (100.0%)
LineHitsSourceCommit
5482 36426 evaluate_pattern(WindowObject winobj, int64 current_pos, 2abe7c8Row pattern recognition patch (executor).
5483 - char *vname, StringInfo encoded_str, bool *result) 2abe7c8Row pattern recognition patch (executor).
5484 - { 2abe7c8Row pattern recognition patch (executor).
5485 36426 WindowAggState *winstate = winobj->winstate; 2abe7c8Row pattern recognition patch (executor).
5486 36426 ExprContext *econtext = winstate->ss.ps.ps_ExprContext; 2abe7c8Row pattern recognition patch (executor).
5487 36426 ListCell *lc1, 2abe7c8Row pattern recognition patch (executor).
5488 - *lc2, 2abe7c8Row pattern recognition patch (executor).
5489 - *lc3; 2abe7c8Row pattern recognition patch (executor).
5490 36426 ExprState *pat; 2abe7c8Row pattern recognition patch (executor).
5491 36426 Datum eval_result; 2abe7c8Row pattern recognition patch (executor).
5492 36426 bool out_of_frame = false; 2abe7c8Row pattern recognition patch (executor).
5493 36426 bool isnull; 2abe7c8Row pattern recognition patch (executor).
5494 36426 TupleTableSlot *slot; 2abe7c8Row pattern recognition patch (executor).
5495 - 2abe7c8Row pattern recognition patch (executor).
5496 41952 forthree(lc1, winstate->defineVariableList, 2abe7c8Row pattern recognition patch (executor).
5497 - lc2, winstate->defineClauseList, 2abe7c8Row pattern recognition patch (executor).
5498 - lc3, winstate->defineInitial) 2abe7c8Row pattern recognition patch (executor).
5499 - { 2abe7c8Row pattern recognition patch (executor).
5500 41952 char initial; /* initial letter associated with vname */ 2abe7c8Row pattern recognition patch (executor).
5501 41952 char *name = strVal(lfirst(lc1)); 2abe7c8Row pattern recognition patch (executor).
5502 - 2abe7c8Row pattern recognition patch (executor).
5503 41952 if (strcmp(vname, name)) 2abe7c8Row pattern recognition patch (executor).
5504 5526 continue; 2abe7c8Row pattern recognition patch (executor).
5505 - 2abe7c8Row pattern recognition patch (executor).
5506 36426 initial = *(strVal(lfirst(lc3))); 2abe7c8Row pattern recognition patch (executor).
5507 - 2abe7c8Row pattern recognition patch (executor).
5508 - /* set expression to evaluate */ 2abe7c8Row pattern recognition patch (executor).
5509 36426 pat = lfirst(lc2); 2abe7c8Row pattern recognition patch (executor).
5510 - 2abe7c8Row pattern recognition patch (executor).
5511 - /* get current, previous and next tuples */ 2abe7c8Row pattern recognition patch (executor).
5512 36426 if (!get_slots(winobj, current_pos)) 2abe7c8Row pattern recognition patch (executor).
5513 - { 2abe7c8Row pattern recognition patch (executor).
5514 375 out_of_frame = true; 2abe7c8Row pattern recognition patch (executor).
5515 - } 2abe7c8Row pattern recognition patch (executor).
5516 - else 2abe7c8Row pattern recognition patch (executor).
5517 - { 2abe7c8Row pattern recognition patch (executor).
5518 - /* evaluate the expression */ 2abe7c8Row pattern recognition patch (executor).
5519 36051 eval_result = ExecEvalExpr(pat, econtext, &isnull); 2abe7c8Row pattern recognition patch (executor).
5520 36051 if (isnull) 2abe7c8Row pattern recognition patch (executor).
5521 - { 2abe7c8Row pattern recognition patch (executor).
5522 - /* expression is NULL */ 2abe7c8Row pattern recognition patch (executor).
5523 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
5524 - elog(DEBUG1, "expression for %s is NULL at row: " INT64_FORMAT, 2abe7c8Row pattern recognition patch (executor).
5525 - vname, current_pos); 2abe7c8Row pattern recognition patch (executor).
5526 - #endif 2abe7c8Row pattern recognition patch (executor).
5527 756 *result = false; 2abe7c8Row pattern recognition patch (executor).
5528 - } 2abe7c8Row pattern recognition patch (executor).
5529 - else 2abe7c8Row pattern recognition patch (executor).
5530 - { 2abe7c8Row pattern recognition patch (executor).
5531 35295 if (!DatumGetBool(eval_result)) 2abe7c8Row pattern recognition patch (executor).
5532 - { 2abe7c8Row pattern recognition patch (executor).
5533 - /* expression is false */ 2abe7c8Row pattern recognition patch (executor).
5534 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
5535 - elog(DEBUG1, "expression for %s is false at row: " INT64_FORMAT, 2abe7c8Row pattern recognition patch (executor).
5536 - vname, current_pos); 2abe7c8Row pattern recognition patch (executor).
5537 - #endif 2abe7c8Row pattern recognition patch (executor).
5538 1788 *result = false; 2abe7c8Row pattern recognition patch (executor).
5539 - } 2abe7c8Row pattern recognition patch (executor).
5540 - else 2abe7c8Row pattern recognition patch (executor).
5541 - { 2abe7c8Row pattern recognition patch (executor).
5542 - /* expression is true */ 2abe7c8Row pattern recognition patch (executor).
5543 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
5544 - elog(DEBUG1, "expression for %s is true at row: " INT64_FORMAT, 2abe7c8Row pattern recognition patch (executor).
5545 - vname, current_pos); 2abe7c8Row pattern recognition patch (executor).
5546 - #endif 2abe7c8Row pattern recognition patch (executor).
5547 33507 appendStringInfoChar(encoded_str, initial); 2abe7c8Row pattern recognition patch (executor).
5548 33507 *result = true; 2abe7c8Row pattern recognition patch (executor).
5549 - } 2abe7c8Row pattern recognition patch (executor).
5550 - } 2abe7c8Row pattern recognition patch (executor).
5551 - 2abe7c8Row pattern recognition patch (executor).
5552 36051 slot = winstate->temp_slot_1; 2abe7c8Row pattern recognition patch (executor).
5553 36051 if (slot != winstate->null_slot) 2abe7c8Row pattern recognition patch (executor).
5554 36051 ExecClearTuple(slot); 2abe7c8Row pattern recognition patch (executor).
5555 36051 slot = winstate->prev_slot; 2abe7c8Row pattern recognition patch (executor).
5556 36051 if (slot != winstate->null_slot) 2abe7c8Row pattern recognition patch (executor).
5557 36051 ExecClearTuple(slot); 2abe7c8Row pattern recognition patch (executor).
5558 36051 slot = winstate->next_slot; 2abe7c8Row pattern recognition patch (executor).
5559 36051 if (slot != winstate->null_slot) 2abe7c8Row pattern recognition patch (executor).
5560 36051 ExecClearTuple(slot); 2abe7c8Row pattern recognition patch (executor).
5561 - 2abe7c8Row pattern recognition patch (executor).
5562 - break; 2abe7c8Row pattern recognition patch (executor).
5563 - } 2abe7c8Row pattern recognition patch (executor).
5564 - 2abe7c8Row pattern recognition patch (executor).
5565 375 if (out_of_frame) 2abe7c8Row pattern recognition patch (executor).
5566 - { 2abe7c8Row pattern recognition patch (executor).
5567 375 *result = false; 2abe7c8Row pattern recognition patch (executor).
5568 375 return -1; 2abe7c8Row pattern recognition patch (executor).
5569 - } 2abe7c8Row pattern recognition patch (executor).
5570 - } 2abe7c8Row pattern recognition patch (executor).
5571 36051 return current_pos; 2abe7c8Row pattern recognition patch (executor).
5572 - } 2abe7c8Row pattern recognition patch (executor).
get_slots() lines 5582-5672
Modified Lines Coverage: 30/31 lines (96.8%)
LineHitsSourceCommit
5582 36426 get_slots(WindowObject winobj, int64 current_pos) 2abe7c8Row pattern recognition patch (executor).
5583 - { 2abe7c8Row pattern recognition patch (executor).
5584 36426 WindowAggState *winstate = winobj->winstate; 2abe7c8Row pattern recognition patch (executor).
5585 36426 TupleTableSlot *slot; 2abe7c8Row pattern recognition patch (executor).
5586 36426 int ret; 2abe7c8Row pattern recognition patch (executor).
5587 36426 ExprContext *econtext; 2abe7c8Row pattern recognition patch (executor).
5588 - 2abe7c8Row pattern recognition patch (executor).
5589 36426 econtext = winstate->ss.ps.ps_ExprContext; 2abe7c8Row pattern recognition patch (executor).
5590 - 2abe7c8Row pattern recognition patch (executor).
5591 - /* set up current row tuple slot */ 2abe7c8Row pattern recognition patch (executor).
5592 36426 slot = winstate->temp_slot_1; 2abe7c8Row pattern recognition patch (executor).
5593 36426 if (!window_gettupleslot(winobj, current_pos, slot)) 2abe7c8Row pattern recognition patch (executor).
5594 - { 2abe7c8Row pattern recognition patch (executor).
5595 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
5596 - elog(DEBUG1, "current row is out of partition at:" INT64_FORMAT, 2abe7c8Row pattern recognition patch (executor).
5597 - current_pos); 2abe7c8Row pattern recognition patch (executor).
5598 - #endif 2abe7c8Row pattern recognition patch (executor).
5599 - return false; 2abe7c8Row pattern recognition patch (executor).
5600 - } 2abe7c8Row pattern recognition patch (executor).
5601 36069 ret = row_is_in_frame(winobj, current_pos, slot, false); 2abe7c8Row pattern recognition patch (executor).
5602 36069 if (ret <= 0) 2abe7c8Row pattern recognition patch (executor).
5603 - { 2abe7c8Row pattern recognition patch (executor).
5604 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
5605 - elog(DEBUG1, "current row is out of frame at: " INT64_FORMAT, 2abe7c8Row pattern recognition patch (executor).
5606 - current_pos); 2abe7c8Row pattern recognition patch (executor).
5607 - #endif 2abe7c8Row pattern recognition patch (executor).
5608 18 ExecClearTuple(slot); 2abe7c8Row pattern recognition patch (executor).
5609 18 return false; 2abe7c8Row pattern recognition patch (executor).
5610 - } 2abe7c8Row pattern recognition patch (executor).
5611 36051 econtext->ecxt_outertuple = slot; 2abe7c8Row pattern recognition patch (executor).
5612 - 2abe7c8Row pattern recognition patch (executor).
5613 - /* for PREV */ 2abe7c8Row pattern recognition patch (executor).
5614 36051 if (current_pos > 0) 2abe7c8Row pattern recognition patch (executor).
5615 - { 2abe7c8Row pattern recognition patch (executor).
5616 35748 slot = winstate->prev_slot; 2abe7c8Row pattern recognition patch (executor).
5617 35748 if (!window_gettupleslot(winobj, current_pos - 1, slot)) 2abe7c8Row pattern recognition patch (executor).
5618 - { 2abe7c8Row pattern recognition patch (executor).
5619 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
5620 - elog(DEBUG1, "previous row is out of partition at: " INT64_FORMAT, 2abe7c8Row pattern recognition patch (executor).
5621 - current_pos - 1); 2abe7c8Row pattern recognition patch (executor).
5622 - #endif 2abe7c8Row pattern recognition patch (executor).
5623 0 econtext->ecxt_scantuple = winstate->null_slot; 2abe7c8Row pattern recognition patch (executor).
5624 - } 2abe7c8Row pattern recognition patch (executor).
5625 - else 2abe7c8Row pattern recognition patch (executor).
5626 - { 2abe7c8Row pattern recognition patch (executor).
5627 35748 ret = row_is_in_frame(winobj, current_pos - 1, slot, false); 2abe7c8Row pattern recognition patch (executor).
5628 35748 if (ret <= 0) 2abe7c8Row pattern recognition patch (executor).
5629 - { 2abe7c8Row pattern recognition patch (executor).
5630 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
5631 - elog(DEBUG1, "previous row is out of frame at: " INT64_FORMAT, 2abe7c8Row pattern recognition patch (executor).
5632 - current_pos - 1); 2abe7c8Row pattern recognition patch (executor).
5633 - #endif 2abe7c8Row pattern recognition patch (executor).
5634 16179 ExecClearTuple(slot); 2abe7c8Row pattern recognition patch (executor).
5635 16179 econtext->ecxt_scantuple = winstate->null_slot; 2abe7c8Row pattern recognition patch (executor).
5636 - } 2abe7c8Row pattern recognition patch (executor).
5637 - else 2abe7c8Row pattern recognition patch (executor).
5638 - { 2abe7c8Row pattern recognition patch (executor).
5639 19569 econtext->ecxt_scantuple = slot; 2abe7c8Row pattern recognition patch (executor).
5640 - } 2abe7c8Row pattern recognition patch (executor).
5641 - } 2abe7c8Row pattern recognition patch (executor).
5642 - } 2abe7c8Row pattern recognition patch (executor).
5643 - else 2abe7c8Row pattern recognition patch (executor).
5644 303 econtext->ecxt_scantuple = winstate->null_slot; 2abe7c8Row pattern recognition patch (executor).
5645 - 2abe7c8Row pattern recognition patch (executor).
5646 - /* for NEXT */ 2abe7c8Row pattern recognition patch (executor).
5647 36051 slot = winstate->next_slot; 2abe7c8Row pattern recognition patch (executor).
5648 36051 if (!window_gettupleslot(winobj, current_pos + 1, slot)) 2abe7c8Row pattern recognition patch (executor).
5649 - { 2abe7c8Row pattern recognition patch (executor).
5650 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
5651 - elog(DEBUG1, "next row is out of partiton at: " INT64_FORMAT, 2abe7c8Row pattern recognition patch (executor).
5652 - current_pos + 1); 2abe7c8Row pattern recognition patch (executor).
5653 - #endif 2abe7c8Row pattern recognition patch (executor).
5654 1047 econtext->ecxt_innertuple = winstate->null_slot; 2abe7c8Row pattern recognition patch (executor).
5655 - } 2abe7c8Row pattern recognition patch (executor).
5656 - else 2abe7c8Row pattern recognition patch (executor).
5657 - { 2abe7c8Row pattern recognition patch (executor).
5658 35004 ret = row_is_in_frame(winobj, current_pos + 1, slot, false); 2abe7c8Row pattern recognition patch (executor).
5659 35004 if (ret <= 0) 2abe7c8Row pattern recognition patch (executor).
5660 - { 2abe7c8Row pattern recognition patch (executor).
5661 - #ifdef RPR_DEBUG 2abe7c8Row pattern recognition patch (executor).
5662 - elog(DEBUG1, "next row is out of frame at: " INT64_FORMAT, 2abe7c8Row pattern recognition patch (executor).
5663 - current_pos + 1); 2abe7c8Row pattern recognition patch (executor).
5664 - #endif 2abe7c8Row pattern recognition patch (executor).
5665 54 ExecClearTuple(slot); 2abe7c8Row pattern recognition patch (executor).
5666 54 econtext->ecxt_innertuple = winstate->null_slot; 2abe7c8Row pattern recognition patch (executor).
5667 - } 2abe7c8Row pattern recognition patch (executor).
5668 - else 2abe7c8Row pattern recognition patch (executor).
5669 34950 econtext->ecxt_innertuple = slot; 2abe7c8Row pattern recognition patch (executor).
5670 - } 2abe7c8Row pattern recognition patch (executor).
5671 - return true; 2abe7c8Row pattern recognition patch (executor).
5672 - } 2abe7c8Row pattern recognition patch (executor).
pattern_initial() lines 5683-5701
Modified Lines Coverage: 9/10 lines (90.0%)
LineHitsSourceCommit
5683 171 pattern_initial(WindowAggState *winstate, char *vname) 2abe7c8Row pattern recognition patch (executor).
5684 - { 2abe7c8Row pattern recognition patch (executor).
5685 171 char initial; 2abe7c8Row pattern recognition patch (executor).
5686 171 char *name; 2abe7c8Row pattern recognition patch (executor).
5687 171 ListCell *lc1, 2abe7c8Row pattern recognition patch (executor).
5688 - *lc2; 2abe7c8Row pattern recognition patch (executor).
5689 - 2abe7c8Row pattern recognition patch (executor).
5690 306 forboth(lc1, winstate->defineVariableList, 2abe7c8Row pattern recognition patch (executor).
5691 - lc2, winstate->defineInitial) 2abe7c8Row pattern recognition patch (executor).
5692 - { 2abe7c8Row pattern recognition patch (executor).
5693 306 name = strVal(lfirst(lc1)); /* DEFINE variable name */ 2abe7c8Row pattern recognition patch (executor).
5694 306 initial = *(strVal(lfirst(lc2))); /* DEFINE variable initial */ 2abe7c8Row pattern recognition patch (executor).
5695 - 2abe7c8Row pattern recognition patch (executor).
5696 - 2abe7c8Row pattern recognition patch (executor).
5697 306 if (!strcmp(name, vname)) 2abe7c8Row pattern recognition patch (executor).
5698 171 return initial; /* found */ 2abe7c8Row pattern recognition patch (executor).
5699 - } 2abe7c8Row pattern recognition patch (executor).
5700 0 return 0; 2abe7c8Row pattern recognition patch (executor).
5701 - } 2abe7c8Row pattern recognition patch (executor).
string_set_init() lines 5710-5726
Modified Lines Coverage: 10/10 lines (100.0%)
LineHitsSourceCommit
5710 32592 string_set_init(void) 2abe7c8Row pattern recognition patch (executor).
5711 - { 2abe7c8Row pattern recognition patch (executor).
5712 - /* Initial allocation size of str_set */ 2abe7c8Row pattern recognition patch (executor).
5713 - #define STRING_SET_ALLOC_SIZE 1024 2abe7c8Row pattern recognition patch (executor).
5714 - 2abe7c8Row pattern recognition patch (executor).
5715 32592 StringSet *string_set; 2abe7c8Row pattern recognition patch (executor).
5716 32592 Size set_size; 2abe7c8Row pattern recognition patch (executor).
5717 - 2abe7c8Row pattern recognition patch (executor).
5718 32592 string_set = palloc0(sizeof(StringSet)); 2abe7c8Row pattern recognition patch (executor).
5719 32592 string_set->set_index = 0; 2abe7c8Row pattern recognition patch (executor).
5720 32592 set_size = STRING_SET_ALLOC_SIZE; 2abe7c8Row pattern recognition patch (executor).
5721 32592 string_set->str_set = palloc(set_size * sizeof(StringInfo)); 2abe7c8Row pattern recognition patch (executor).
5722 32592 string_set->info = palloc0(set_size * sizeof(int)); 2abe7c8Row pattern recognition patch (executor).
5723 32592 string_set->set_size = set_size; 2abe7c8Row pattern recognition patch (executor).
5724 - 2abe7c8Row pattern recognition patch (executor).
5725 32592 return string_set; 2abe7c8Row pattern recognition patch (executor).
5726 - } 2abe7c8Row pattern recognition patch (executor).
string_set_add() lines 5735-5757
Modified Lines Coverage: 13/13 lines (100.0%)
LineHitsSourceCommit
5735 35130 string_set_add(StringSet *string_set, StringInfo str, int info) 2abe7c8Row pattern recognition patch (executor).
5736 - { 2abe7c8Row pattern recognition patch (executor).
5737 35130 Size set_size; 2abe7c8Row pattern recognition patch (executor).
5738 35130 Size old_set_size; 2abe7c8Row pattern recognition patch (executor).
5739 - 2abe7c8Row pattern recognition patch (executor).
5740 35130 set_size = string_set->set_size; 2abe7c8Row pattern recognition patch (executor).
5741 35130 if (string_set->set_index >= set_size) 2abe7c8Row pattern recognition patch (executor).
5742 - { 2abe7c8Row pattern recognition patch (executor).
5743 9 old_set_size = set_size; 2abe7c8Row pattern recognition patch (executor).
5744 9 set_size *= 2; 2abe7c8Row pattern recognition patch (executor).
5745 9 string_set->str_set = repalloc(string_set->str_set, 2abe7c8Row pattern recognition patch (executor).
5746 - set_size * sizeof(StringInfo)); 2abe7c8Row pattern recognition patch (executor).
5747 9 string_set->info = repalloc0(string_set->info, 2abe7c8Row pattern recognition patch (executor).
5748 - old_set_size * sizeof(int), 2abe7c8Row pattern recognition patch (executor).
5749 - set_size * sizeof(int)); 2abe7c8Row pattern recognition patch (executor).
5750 9 string_set->set_size = set_size; 2abe7c8Row pattern recognition patch (executor).
5751 - } 2abe7c8Row pattern recognition patch (executor).
5752 - 2abe7c8Row pattern recognition patch (executor).
5753 35130 string_set->info[string_set->set_index] = info; 2abe7c8Row pattern recognition patch (executor).
5754 35130 string_set->str_set[string_set->set_index++] = str; 2abe7c8Row pattern recognition patch (executor).
5755 - 2abe7c8Row pattern recognition patch (executor).
5756 35130 return; 2abe7c8Row pattern recognition patch (executor).
5757 - } 2abe7c8Row pattern recognition patch (executor).
string_set_get() lines 5767-5781
Modified Lines Coverage: 6/7 lines (85.7%)
LineHitsSourceCommit
5767 36630 string_set_get(StringSet *string_set, int index, int *info) 2abe7c8Row pattern recognition patch (executor).
5768 - { 2abe7c8Row pattern recognition patch (executor).
5769 36630 *info = 0; 2abe7c8Row pattern recognition patch (executor).
5770 - 2abe7c8Row pattern recognition patch (executor).
5771 - /* no data? */ 2abe7c8Row pattern recognition patch (executor).
5772 36630 if (index == 0 && string_set->set_index == 0) 2abe7c8Row pattern recognition patch (executor).
5773 - return NULL; 2abe7c8Row pattern recognition patch (executor).
5774 - 2abe7c8Row pattern recognition patch (executor).
5775 36630 if (index < 0 || index >= string_set->set_index) 2abe7c8Row pattern recognition patch (executor).
5776 0 elog(ERROR, "invalid index: %d", index); 2abe7c8Row pattern recognition patch (executor).
5777 - 2abe7c8Row pattern recognition patch (executor).
5778 36630 *info = string_set->info[index]; 2abe7c8Row pattern recognition patch (executor).
5779 - 2abe7c8Row pattern recognition patch (executor).
5780 36630 return string_set->str_set[index]; 2abe7c8Row pattern recognition patch (executor).
5781 - } 2abe7c8Row pattern recognition patch (executor).
string_set_get_size() lines 5790-5793
Modified Lines Coverage: 2/2 lines (100.0%)
LineHitsSourceCommit
5790 18681 string_set_get_size(StringSet *string_set) 2abe7c8Row pattern recognition patch (executor).
5791 - { 2abe7c8Row pattern recognition patch (executor).
5792 18681 return string_set->set_index; 2abe7c8Row pattern recognition patch (executor).
5793 - } 2abe7c8Row pattern recognition patch (executor).
string_set_discard() lines 5802-5816
Modified Lines Coverage: 10/10 lines (100.0%)
LineHitsSourceCommit
5802 17343 string_set_discard(StringSet *string_set) 2abe7c8Row pattern recognition patch (executor).
5803 - { 2abe7c8Row pattern recognition patch (executor).
5804 17343 int i; 2abe7c8Row pattern recognition patch (executor).
5805 - 2abe7c8Row pattern recognition patch (executor).
5806 52473 for (i = 0; i < string_set->set_index; i++) 2abe7c8Row pattern recognition patch (executor).
5807 - { 2abe7c8Row pattern recognition patch (executor).
5808 35130 StringInfo str = string_set->str_set[i]; 2abe7c8Row pattern recognition patch (executor).
5809 - 2abe7c8Row pattern recognition patch (executor).
5810 35130 if (str) 2abe7c8Row pattern recognition patch (executor).
5811 34458 destroyStringInfo(str); 2abe7c8Row pattern recognition patch (executor).
5812 - } 2abe7c8Row pattern recognition patch (executor).
5813 17343 pfree(string_set->info); 2abe7c8Row pattern recognition patch (executor).
5814 17343 pfree(string_set->str_set); 2abe7c8Row pattern recognition patch (executor).
5815 17343 pfree(string_set); 2abe7c8Row pattern recognition patch (executor).
5816 17343 } 2abe7c8Row pattern recognition patch (executor).
variable_pos_init() lines 5825-5832
Modified Lines Coverage: 5/5 lines (100.0%)
LineHitsSourceCommit
5825 69 variable_pos_init(void) 2abe7c8Row pattern recognition patch (executor).
5826 - { 2abe7c8Row pattern recognition patch (executor).
5827 69 VariablePos *variable_pos; 2abe7c8Row pattern recognition patch (executor).
5828 - 2abe7c8Row pattern recognition patch (executor).
5829 69 variable_pos = palloc(sizeof(VariablePos) * NUM_ALPHABETS); 2abe7c8Row pattern recognition patch (executor).
5830 69 MemSet(variable_pos, -1, sizeof(VariablePos) * NUM_ALPHABETS); 2abe7c8Row pattern recognition patch (executor).
5831 69 return variable_pos; 2abe7c8Row pattern recognition patch (executor).
5832 - } 2abe7c8Row pattern recognition patch (executor).
variable_pos_register() lines 5843-5863
Modified Lines Coverage: 11/12 lines (91.7%)
LineHitsSourceCommit
5843 171 variable_pos_register(VariablePos *variable_pos, char initial, int pos) 2abe7c8Row pattern recognition patch (executor).
5844 - { 2abe7c8Row pattern recognition patch (executor).
5845 171 int index = initial - 'a'; 2abe7c8Row pattern recognition patch (executor).
5846 171 int slot; 2abe7c8Row pattern recognition patch (executor).
5847 171 int i; 2abe7c8Row pattern recognition patch (executor).
5848 - 2abe7c8Row pattern recognition patch (executor).
5849 171 if (pos < 0 || pos > NUM_ALPHABETS) 2abe7c8Row pattern recognition patch (executor).
5850 0 elog(ERROR, "initial is not valid char: %c", initial); 2abe7c8Row pattern recognition patch (executor).
5851 - 2abe7c8Row pattern recognition patch (executor).
5852 183 for (i = 0; i < NUM_ALPHABETS; i++) 2abe7c8Row pattern recognition patch (executor).
5853 - { 2abe7c8Row pattern recognition patch (executor).
5854 183 slot = variable_pos[index].pos[i]; 2abe7c8Row pattern recognition patch (executor).
5855 183 if (slot < 0) 2abe7c8Row pattern recognition patch (executor).
5856 - { 2abe7c8Row pattern recognition patch (executor).
5857 - /* empty slot found */ 2abe7c8Row pattern recognition patch (executor).
5858 171 variable_pos[index].pos[i] = pos; 2abe7c8Row pattern recognition patch (executor).
5859 171 return; 2abe7c8Row pattern recognition patch (executor).
5860 - } 2abe7c8Row pattern recognition patch (executor).
5861 - } 2abe7c8Row pattern recognition patch (executor).
5862 171 elog(ERROR, "no empty slot for initial: %c", initial); 2abe7c8Row pattern recognition patch (executor).
5863 - } 2abe7c8Row pattern recognition patch (executor).
variable_pos_compare() lines 5872-5895
Modified Lines Coverage: 10/10 lines (100.0%)
LineHitsSourceCommit
5872 18036 variable_pos_compare(VariablePos *variable_pos, char initial1, char initial2) 2abe7c8Row pattern recognition patch (executor).
5873 - { 2abe7c8Row pattern recognition patch (executor).
5874 18036 int index1, 2abe7c8Row pattern recognition patch (executor).
5875 - index2; 2abe7c8Row pattern recognition patch (executor).
5876 18036 int pos1, 2abe7c8Row pattern recognition patch (executor).
5877 - pos2; 2abe7c8Row pattern recognition patch (executor).
5878 - 2abe7c8Row pattern recognition patch (executor).
5879 18036 for (index1 = 0;; index1++) 2abe7c8Row pattern recognition patch (executor).
5880 - { 2abe7c8Row pattern recognition patch (executor).
5881 19446 pos1 = variable_pos_fetch(variable_pos, initial1, index1); 2abe7c8Row pattern recognition patch (executor).
5882 19446 if (pos1 < 0) 2abe7c8Row pattern recognition patch (executor).
5883 - break; 2abe7c8Row pattern recognition patch (executor).
5884 - 2abe7c8Row pattern recognition patch (executor).
5885 1722 for (index2 = 0;; index2++) 2abe7c8Row pattern recognition patch (executor).
5886 - { 2abe7c8Row pattern recognition patch (executor).
5887 19974 pos2 = variable_pos_fetch(variable_pos, initial2, index2); 2abe7c8Row pattern recognition patch (executor).
5888 19974 if (pos2 < 0) 2abe7c8Row pattern recognition patch (executor).
5889 - break; 2abe7c8Row pattern recognition patch (executor).
5890 18564 if (pos1 <= pos2) 2abe7c8Row pattern recognition patch (executor).
5891 - return true; 2abe7c8Row pattern recognition patch (executor).
5892 - } 2abe7c8Row pattern recognition patch (executor).
5893 - } 2abe7c8Row pattern recognition patch (executor).
5894 - return false; 2abe7c8Row pattern recognition patch (executor).
5895 - } 2abe7c8Row pattern recognition patch (executor).
variable_pos_fetch() lines 5905-5916
Modified Lines Coverage: 5/7 lines (71.4%)
LineHitsSourceCommit
5905 39420 variable_pos_fetch(VariablePos *variable_pos, char initial, int index) 2abe7c8Row pattern recognition patch (executor).
5906 - { 2abe7c8Row pattern recognition patch (executor).
5907 39420 int pos = initial - 'a'; 2abe7c8Row pattern recognition patch (executor).
5908 - 2abe7c8Row pattern recognition patch (executor).
5909 39420 if (pos < 0 || pos > NUM_ALPHABETS) 2abe7c8Row pattern recognition patch (executor).
5910 0 elog(ERROR, "initial is not valid char: %c", initial); 2abe7c8Row pattern recognition patch (executor).
5911 - 2abe7c8Row pattern recognition patch (executor).
5912 39420 if (index < 0 || index > NUM_ALPHABETS) 2abe7c8Row pattern recognition patch (executor).
5913 0 elog(ERROR, "index is not valid: %d", index); 2abe7c8Row pattern recognition patch (executor).
5914 - 2abe7c8Row pattern recognition patch (executor).
5915 39420 return variable_pos[pos].pos[index]; 2abe7c8Row pattern recognition patch (executor).
5916 - } 2abe7c8Row pattern recognition patch (executor).
variable_pos_build() lines 5925-5962
Modified Lines Coverage: 20/20 lines (100.0%)
LineHitsSourceCommit
5925 69 variable_pos_build(WindowAggState *winstate) 2abe7c8Row pattern recognition patch (executor).
5926 - { 2abe7c8Row pattern recognition patch (executor).
5927 69 VariablePos *variable_pos; 2abe7c8Row pattern recognition patch (executor).
5928 69 StringInfo pattern_str; 2abe7c8Row pattern recognition patch (executor).
5929 69 int initial_index = 0; 2abe7c8Row pattern recognition patch (executor).
5930 69 ListCell *lc1, 2abe7c8Row pattern recognition patch (executor).
5931 - *lc2; 2abe7c8Row pattern recognition patch (executor).
5932 - 2abe7c8Row pattern recognition patch (executor).
5933 69 variable_pos = winstate->variable_pos = variable_pos_init(); 2abe7c8Row pattern recognition patch (executor).
5934 69 pattern_str = winstate->pattern_str = makeStringInfo(); 2abe7c8Row pattern recognition patch (executor).
5935 69 appendStringInfoChar(pattern_str, '^'); 2abe7c8Row pattern recognition patch (executor).
5936 - 2abe7c8Row pattern recognition patch (executor).
5937 240 forboth(lc1, winstate->patternVariableList, 2abe7c8Row pattern recognition patch (executor).
5938 - lc2, winstate->patternRegexpList) 2abe7c8Row pattern recognition patch (executor).
5939 - { 2abe7c8Row pattern recognition patch (executor).
5940 171 char *vname = strVal(lfirst(lc1)); 2abe7c8Row pattern recognition patch (executor).
5941 171 char *quantifier = strVal(lfirst(lc2)); 2abe7c8Row pattern recognition patch (executor).
5942 171 char initial; 2abe7c8Row pattern recognition patch (executor).
5943 - 2abe7c8Row pattern recognition patch (executor).
5944 171 initial = pattern_initial(winstate, vname); 2abe7c8Row pattern recognition patch (executor).
5945 171 Assert(initial != 0); 2abe7c8Row pattern recognition patch (executor).
5946 171 appendStringInfoChar(pattern_str, initial); 2abe7c8Row pattern recognition patch (executor).
5947 171 if (quantifier[0]) 2abe7c8Row pattern recognition patch (executor).
5948 102 appendStringInfoChar(pattern_str, quantifier[0]); 2abe7c8Row pattern recognition patch (executor).
5949 - 2abe7c8Row pattern recognition patch (executor).
5950 - /* 2abe7c8Row pattern recognition patch (executor).
5951 - * Register the initial at initial_index. If the initial appears more 2abe7c8Row pattern recognition patch (executor).
5952 - * than once, all of it's initial_index will be recorded. This could 2abe7c8Row pattern recognition patch (executor).
5953 - * happen if a pattern variable appears in the PATTERN clause more 2abe7c8Row pattern recognition patch (executor).
5954 - * than once like "UP DOWN UP" "UP UP UP". 2abe7c8Row pattern recognition patch (executor).
5955 - */ 2abe7c8Row pattern recognition patch (executor).
5956 171 variable_pos_register(variable_pos, initial, initial_index); 2abe7c8Row pattern recognition patch (executor).
5957 - 2abe7c8Row pattern recognition patch (executor).
5958 171 initial_index++; 2abe7c8Row pattern recognition patch (executor).
5959 - } 2abe7c8Row pattern recognition patch (executor).
5960 - 2abe7c8Row pattern recognition patch (executor).
5961 69 return variable_pos; 2abe7c8Row pattern recognition patch (executor).
5962 - } 2abe7c8Row pattern recognition patch (executor).