func benchmarkWriteTimestamp(b *testing.B, format formatCode) { ts, err := parser.ParseDTimestamp("2010-09-28 12:00:00.1", time.Microsecond) if err != nil { b.Fatal(err) } benchmarkWriteType(b, ts, format) }
func TestBinaryTimestamp(t *testing.T) { defer leaktest.AfterTest(t)() testBinaryDatumType(t, "timestamp", func(val string) parser.Datum { ts, err := parser.ParseDTimestamp(val, time.Microsecond) if err != nil { t.Fatal(err) } return ts }) }
// isAsOf analyzes a select statement to bypass the logic in newPlan(), // since that requires the transaction to be started already. If the returned // timestamp is not nil, it is the timestamp to which a transaction should // be set. // // max is a lower bound on what the transaction's timestamp will be. Used to // check that the user didn't specify a timestamp in the future. func isAsOf(planMaker *planner, stmt parser.Statement, max hlc.Timestamp) (*hlc.Timestamp, error) { s, ok := stmt.(*parser.Select) if !ok { return nil, nil } sc, ok := s.Select.(*parser.SelectClause) if !ok { return nil, nil } if sc.From == nil || sc.From.AsOf.Expr == nil { return nil, nil } te, err := sc.From.AsOf.Expr.TypeCheck(nil, parser.TypeString) if err != nil { return nil, err } d, err := te.Eval(&planMaker.evalCtx) if err != nil { return nil, err } var ts hlc.Timestamp switch d := d.(type) { case *parser.DString: // Allow nanosecond precision because the timestamp is only used by the // system and won't be returned to the user over pgwire. dt, err := parser.ParseDTimestamp(string(*d), time.Nanosecond) if err != nil { return nil, err } ts.WallTime = dt.Time.UnixNano() case *parser.DInt: ts.WallTime = int64(*d) case *parser.DDecimal: // Format the decimal into a string and split on `.` to extract the nanosecond // walltime and logical tick parts. s := d.String() parts := strings.SplitN(s, ".", 2) nanos, err := strconv.ParseInt(parts[0], 10, 64) if err != nil { return nil, errors.Wrap(err, "parse AS OF SYSTEM TIME argument") } var logical int64 if len(parts) > 1 { // logicalLength is the number of decimal digits expected in the // logical part to the right of the decimal. See the implementation of // cluster_logical_timestamp(). const logicalLength = 10 p := parts[1] if lp := len(p); lp > logicalLength { return nil, errors.Errorf("bad AS OF SYSTEM TIME argument: logical part has too many digits") } else if lp < logicalLength { p += strings.Repeat("0", logicalLength-lp) } logical, err = strconv.ParseInt(p, 10, 32) if err != nil { return nil, errors.Wrap(err, "parse AS OF SYSTEM TIME argument") } } ts.WallTime = nanos ts.Logical = int32(logical) default: return nil, fmt.Errorf("unexpected AS OF SYSTEM TIME argument: %s (%T)", d.ResolvedType(), d) } if max.Less(ts) { return nil, fmt.Errorf("cannot specify timestamp in the future") } return &ts, nil }