* Initialize the TABLESAMPLE method: evaluate params and call BeginSampleScan. */
| 230 | * Initialize the TABLESAMPLE method: evaluate params and call BeginSampleScan. |
| 231 | */ |
| 232 | static void |
| 233 | tablesample_init(SampleScanState *scanstate) |
| 234 | { |
| 235 | TsmRoutine *tsm = scanstate->tsmroutine; |
| 236 | ExprContext *econtext = scanstate->ss.ps.ps_ExprContext; |
| 237 | Datum *params; |
| 238 | Datum datum; |
| 239 | bool isnull; |
| 240 | uint32 seed; |
| 241 | bool allow_sync; |
| 242 | int i; |
| 243 | ListCell *arg; |
| 244 | |
| 245 | scanstate->donetuples = 0; |
| 246 | params = (Datum *) palloc(list_length(scanstate->args) * sizeof(Datum)); |
| 247 | |
| 248 | i = 0; |
| 249 | foreach(arg, scanstate->args) |
| 250 | { |
| 251 | ExprState *argstate = (ExprState *) lfirst(arg); |
| 252 | |
| 253 | params[i] = ExecEvalExprSwitchContext(argstate, |
| 254 | econtext, |
| 255 | &isnull); |
| 256 | if (isnull) |
| 257 | ereport(ERROR, |
| 258 | (errcode(ERRCODE_INVALID_TABLESAMPLE_ARGUMENT), |
| 259 | errmsg("TABLESAMPLE parameter cannot be null"))); |
| 260 | i++; |
| 261 | } |
| 262 | |
| 263 | if (scanstate->repeatable) |
| 264 | { |
| 265 | datum = ExecEvalExprSwitchContext(scanstate->repeatable, |
| 266 | econtext, |
| 267 | &isnull); |
| 268 | if (isnull) |
| 269 | ereport(ERROR, |
| 270 | (errcode(ERRCODE_INVALID_TABLESAMPLE_REPEAT), |
| 271 | errmsg("TABLESAMPLE REPEATABLE parameter cannot be null"))); |
| 272 | |
| 273 | /* |
| 274 | * The REPEATABLE parameter has been coerced to float8 by the parser. |
| 275 | * The reason for using float8 at the SQL level is that it will |
| 276 | * produce unsurprising results both for users used to databases that |
| 277 | * accept only integers in the REPEATABLE clause and for those who |
| 278 | * might expect that REPEATABLE works like setseed() (a float in the |
| 279 | * range from -1 to 1). |
| 280 | * |
| 281 | * We use hashfloat8() to convert the supplied value into a suitable |
| 282 | * seed. For regression-testing purposes, that has the convenient |
| 283 | * property that REPEATABLE(0) gives a machine-independent result. |
| 284 | */ |
| 285 | seed = DatumGetUInt32(DirectFunctionCall1(hashfloat8, datum)); |
| 286 | } |
| 287 | else |
| 288 | { |
| 289 | /* Use the seed selected by ExecInitSampleScan */ |
no test coverage detected