* Try to match an lquery (of qlen items) to an ltree (of tlen items) */
| 133 | * Try to match an lquery (of qlen items) to an ltree (of tlen items) |
| 134 | */ |
| 135 | static bool |
| 136 | checkCond(lquery_level *curq, int qlen, |
| 137 | ltree_level *curt, int tlen) |
| 138 | { |
| 139 | /* Since this function recurses, it could be driven to stack overflow */ |
| 140 | check_stack_depth(); |
| 141 | |
| 142 | /* Pathological patterns could take awhile, too */ |
| 143 | CHECK_FOR_INTERRUPTS(); |
| 144 | |
| 145 | /* Loop while we have query items to consider */ |
| 146 | while (qlen > 0) |
| 147 | { |
| 148 | int low, |
| 149 | high; |
| 150 | lquery_level *nextq; |
| 151 | |
| 152 | /* |
| 153 | * Get min and max repetition counts for this query item, dealing with |
| 154 | * the backwards-compatibility hack that the low/high fields aren't |
| 155 | * meaningful for non-'*' items unless LQL_COUNT is set. |
| 156 | */ |
| 157 | if ((curq->flag & LQL_COUNT) || curq->numvar == 0) |
| 158 | low = curq->low, high = curq->high; |
| 159 | else |
| 160 | low = high = 1; |
| 161 | |
| 162 | /* |
| 163 | * We may limit "high" to the remaining text length; this avoids |
| 164 | * separate tests below. |
| 165 | */ |
| 166 | if (high > tlen) |
| 167 | high = tlen; |
| 168 | |
| 169 | /* Fail if a match of required number of items is impossible */ |
| 170 | if (high < low) |
| 171 | return false; |
| 172 | |
| 173 | /* |
| 174 | * Recursively check the rest of the pattern against each possible |
| 175 | * start point following some of this item's match(es). |
| 176 | */ |
| 177 | nextq = LQL_NEXT(curq); |
| 178 | qlen--; |
| 179 | |
| 180 | for (int matchcnt = 0; matchcnt < high; matchcnt++) |
| 181 | { |
| 182 | /* |
| 183 | * If we've consumed an acceptable number of matches of this item, |
| 184 | * and the rest of the pattern matches beginning here, we're good. |
| 185 | */ |
| 186 | if (matchcnt >= low && checkCond(nextq, qlen, curt, tlen)) |
| 187 | return true; |
| 188 | |
| 189 | /* |
| 190 | * Otherwise, try to match one more text item to this query item. |
| 191 | */ |
| 192 | if (!checkLevel(curq, curt)) |
no test coverage detected