| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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 | - | } | - |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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 | - | } | - |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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 | - | } | - |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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 | - | } | - |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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 | - | } | - |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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 | - | } | - |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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 | - | } | - |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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 | - | } | - |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |