| 16 | static OpBase *LimitClone(const ExecutionPlan *plan, const OpBase *opBase); |
| 17 | |
| 18 | static void _eval_limit(OpLimit *op, AR_ExpNode *limit_exp) { |
| 19 | /* Store a copy of the original expression. |
| 20 | * This is required in the case of a parameterized limit: "LIMIT $L" |
| 21 | * Evaluating the expression will modify it, replacing the parameter with a constant. |
| 22 | * As a result, clones of this operation would invalidly resolve to an outdated constant. */ |
| 23 | op->limit_exp = AR_EXP_Clone(limit_exp); |
| 24 | |
| 25 | // Evaluate using the input expression, leaving the stored expression untouched. |
| 26 | SIValue l = AR_EXP_Evaluate(limit_exp, NULL); |
| 27 | |
| 28 | // Validate that the limit value is numeric and non-negative. |
| 29 | if(SI_TYPE(l) != T_INT64 || SI_GET_NUMERIC(l) < 0) { |
| 30 | ErrorCtx_SetError("Limit operates only on non-negative integers"); |
| 31 | } |
| 32 | |
| 33 | op->limit = SI_GET_NUMERIC(l); |
| 34 | |
| 35 | // Free the expression we've evaluated. |
| 36 | AR_EXP_Free(limit_exp); |
| 37 | } |
| 38 | |
| 39 | OpBase *NewLimitOp(const ExecutionPlan *plan, AR_ExpNode *limit_exp) { |
| 40 | // validate inputs |
no test coverage detected