EvalAsOfTimestamp evaluates the timestamp argument to an AS OF SYSTEM TIME query.
( asOf AsOfClause, semaCtx *SemaContext, evalCtx *EvalContext, )
| 35 | |
| 36 | // EvalAsOfTimestamp evaluates the timestamp argument to an AS OF SYSTEM TIME query. |
| 37 | func EvalAsOfTimestamp( |
| 38 | asOf AsOfClause, semaCtx *SemaContext, evalCtx *EvalContext, |
| 39 | ) (tsss hlc.Timestamp, err error) { |
| 40 | // We need to save and restore the previous value of the field in |
| 41 | // semaCtx in case we are recursively called within a subquery |
| 42 | // context. |
| 43 | scalarProps := &semaCtx.Properties |
| 44 | defer scalarProps.Restore(*scalarProps) |
| 45 | scalarProps.Require("AS OF SYSTEM TIME", RejectSpecial|RejectSubqueries) |
| 46 | |
| 47 | // In order to support the follower reads feature we permit this expression |
| 48 | // to be a simple invocation of the `FollowerReadTimestampFunction`. |
| 49 | // Over time we could expand the set of allowed functions or expressions. |
| 50 | // All non-function expressions must be const and must TypeCheck into a |
| 51 | // string. |
| 52 | var te TypedExpr |
| 53 | if fe, ok := asOf.Expr.(*FuncExpr); ok { |
| 54 | def, err := fe.Func.Resolve(semaCtx.SearchPath) |
| 55 | if err != nil { |
| 56 | return hlc.Timestamp{}, errInvalidExprForAsOf |
| 57 | } |
| 58 | if def.Name != FollowerReadTimestampFunctionName { |
| 59 | return hlc.Timestamp{}, errInvalidExprForAsOf |
| 60 | } |
| 61 | if te, err = fe.TypeCheck(semaCtx, types.TimestampTZ); err != nil { |
| 62 | return hlc.Timestamp{}, err |
| 63 | } |
| 64 | } else { |
| 65 | var err error |
| 66 | te, err = asOf.Expr.TypeCheck(semaCtx, types.String) |
| 67 | if err != nil { |
| 68 | return hlc.Timestamp{}, err |
| 69 | } |
| 70 | if !IsConst(evalCtx, te) { |
| 71 | return hlc.Timestamp{}, errInvalidExprForAsOf |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | d, err := te.Eval(evalCtx) |
| 76 | if err != nil { |
| 77 | return hlc.Timestamp{}, err |
| 78 | } |
| 79 | |
| 80 | stmtTimestamp := evalCtx.GetStmtTimestamp() |
| 81 | ts, err := DatumToHLC(evalCtx, stmtTimestamp, d) |
| 82 | return ts, errors.Wrap(err, "AS OF SYSTEM TIME") |
| 83 | } |
| 84 | |
| 85 | // DatumToHLC performs the conversion from a Datum to an HLC timestamp. |
| 86 | func DatumToHLC(evalCtx *EvalContext, stmtTimestamp time.Time, d Datum) (hlc.Timestamp, error) { |
nothing calls this directly
no test coverage detected
searching dependent graphs…