* Collect sample rows from the result of query. * - Use all tuples in sample until target # of samples are collected. * - Subsequently, replace already-sampled tuples randomly. */
| 5169 | * - Subsequently, replace already-sampled tuples randomly. |
| 5170 | */ |
| 5171 | static void |
| 5172 | analyze_row_processor(PGresult *res, int row, PgFdwAnalyzeState *astate) |
| 5173 | { |
| 5174 | int targrows = astate->targrows; |
| 5175 | int pos; /* array index to store tuple in */ |
| 5176 | MemoryContext oldcontext; |
| 5177 | |
| 5178 | /* Always increment sample row counter. */ |
| 5179 | astate->samplerows += 1; |
| 5180 | |
| 5181 | /* |
| 5182 | * Determine the slot where this sample row should be stored. Set pos to |
| 5183 | * negative value to indicate the row should be skipped. |
| 5184 | */ |
| 5185 | if (astate->numrows < targrows) |
| 5186 | { |
| 5187 | /* First targrows rows are always included into the sample */ |
| 5188 | pos = astate->numrows++; |
| 5189 | } |
| 5190 | else |
| 5191 | { |
| 5192 | /* |
| 5193 | * Now we start replacing tuples in the sample until we reach the end |
| 5194 | * of the relation. Same algorithm as in acquire_sample_rows in |
| 5195 | * analyze.c; see Jeff Vitter's paper. |
| 5196 | */ |
| 5197 | if (astate->rowstoskip < 0) |
| 5198 | astate->rowstoskip = reservoir_get_next_S(&astate->rstate, astate->samplerows, targrows); |
| 5199 | |
| 5200 | if (astate->rowstoskip <= 0) |
| 5201 | { |
| 5202 | /* Choose a random reservoir element to replace. */ |
| 5203 | pos = (int) (targrows * sampler_random_fract(astate->rstate.randstate)); |
| 5204 | Assert(pos >= 0 && pos < targrows); |
| 5205 | heap_freetuple(astate->rows[pos]); |
| 5206 | } |
| 5207 | else |
| 5208 | { |
| 5209 | /* Skip this tuple. */ |
| 5210 | pos = -1; |
| 5211 | } |
| 5212 | |
| 5213 | astate->rowstoskip -= 1; |
| 5214 | } |
| 5215 | |
| 5216 | if (pos >= 0) |
| 5217 | { |
| 5218 | /* |
| 5219 | * Create sample tuple from current result row, and store it in the |
| 5220 | * position determined above. The tuple has to be created in anl_cxt. |
| 5221 | */ |
| 5222 | oldcontext = MemoryContextSwitchTo(astate->anl_cxt); |
| 5223 | |
| 5224 | astate->rows[pos] = make_tuple_from_result_row(res, row, |
| 5225 | astate->rel, |
| 5226 | astate->attinmeta, |
| 5227 | astate->retrieved_attrs, |
| 5228 | NULL, |
no test coverage detected