@@ -243,7 +243,6 @@ func readDataFrameJSON(frame *Frame, iter *jsoniter.Iterator) error {
243243 iter .ReportError ("bind l1" , "unexpected field: " + l1Field )
244244 }
245245 }
246-
247246 return iter .Error
248247}
249248
@@ -260,19 +259,22 @@ func readDataFramesJSON(frames *Frames, iter *jsoniter.Iterator) error {
260259}
261260
262261func readFrameData (iter * jsoniter.Iterator , frame * Frame ) error {
262+ var readValues , readNanos bool
263+ nanos := make ([][]int64 , len (frame .Fields ))
263264 for l2Field := iter .ReadObject (); l2Field != "" ; l2Field = iter .ReadObject () {
264265 switch l2Field {
265266 case "values" :
266267 if ! iter .ReadArray () {
267268 continue // empty fields
268269 }
269-
270+ var fieldIndex int
270271 // Load the first field with a generic interface.
271272 // The length of the first will be assumed for the other fields
272273 // and can have a specialized parser
273274 if frame .Fields == nil {
274275 return errors .New ("fields is nil, malformed key order or frame without schema" )
275276 }
277+
276278 field := frame .Fields [0 ]
277279 first := make ([]interface {}, 0 )
278280 iter .ReadVal (& first )
@@ -283,16 +285,34 @@ func readFrameData(iter *jsoniter.Iterator, frame *Frame) error {
283285 field .vector = vec
284286 size := len (first )
285287
286- fieldIndex := 1
288+ addNanos := func () {
289+ if readNanos {
290+ if nanos [fieldIndex ] != nil {
291+ for i := 0 ; i < size ; i ++ {
292+ t , ok := field .ConcreteAt (i )
293+ if ! ok {
294+ continue
295+ }
296+ field .Set (i , t .(time.Time ).Add (time .Nanosecond * time .Duration (nanos [fieldIndex ][i ])))
297+ }
298+ }
299+ }
300+ }
301+
302+ addNanos ()
303+ fieldIndex ++
287304 for iter .ReadArray () {
288305 field = frame .Fields [fieldIndex ]
289306 vec , err = readVector (iter , field .Type (), size )
290307 if err != nil {
291308 return err
292309 }
310+
293311 field .vector = vec
312+ addNanos ()
294313 fieldIndex ++
295314 }
315+ readValues = true
296316
297317 case "entities" :
298318 fieldIndex := 0
@@ -308,13 +328,40 @@ func readFrameData(iter *jsoniter.Iterator, frame *Frame) error {
308328 }
309329 }
310330 } else {
311- iter .ReadAny () // skip nills
331+ iter .ReadAny () // skip nils
312332 }
313333 fieldIndex ++
314334 }
315335
316- default :
317- iter .ReportError ("bind l2" , "unexpected field: " + l2Field )
336+ case "nanos" :
337+ fieldIndex := 0
338+ for iter .ReadArray () {
339+ field := frame .Fields [fieldIndex ]
340+
341+ t := iter .WhatIsNext ()
342+ if t == jsoniter .ArrayValue {
343+ for idx := 0 ; iter .ReadArray (); idx ++ {
344+ ns := iter .ReadInt64 ()
345+ if readValues {
346+ t , ok := field .vector .ConcreteAt (idx )
347+ if ! ok {
348+ continue
349+ }
350+ tWithNS := t .(time.Time ).Add (time .Nanosecond * time .Duration (ns ))
351+ field .vector .SetConcrete (idx , tWithNS )
352+ continue
353+ }
354+ if idx == 0 {
355+ nanos [fieldIndex ] = append (nanos [fieldIndex ], ns )
356+ }
357+ }
358+ } else {
359+ iter .ReadAny () // skip nils
360+ }
361+ fieldIndex ++
362+ }
363+
364+ readNanos = true
318365 }
319366 }
320367 return nil
@@ -793,13 +840,18 @@ func writeDataFrameData(frame *Frame, stream *jsoniter.Stream) {
793840 entities := make ([]* fieldEntityLookup , len (frame .Fields ))
794841 entityCount := 0
795842
843+ nanos := make ([][]int64 , len (frame .Fields ))
844+ nsOffSetCount := 0
845+
796846 stream .WriteObjectField ("values" )
797847 stream .WriteArrayStart ()
798848 for fidx , f := range frame .Fields {
799849 if fidx > 0 {
800850 stream .WriteMore ()
801851 }
802852 isTime := f .Type ().Time ()
853+ nsTime := make ([]int64 , rowCount )
854+ var hasNSTime bool
803855 isFloat := f .Type () == FieldTypeFloat64 || f .Type () == FieldTypeNullableFloat64 ||
804856 f .Type () == FieldTypeFloat32 || f .Type () == FieldTypeNullableFloat32
805857
@@ -811,8 +863,14 @@ func writeDataFrameData(frame *Frame, stream *jsoniter.Stream) {
811863 if v , ok := f .ConcreteAt (i ); ok {
812864 switch {
813865 case isTime :
814- vTyped := v .(time.Time ).UnixNano () / int64 (time .Millisecond ) // Milliseconds precision.
815- stream .WriteVal (vTyped )
866+ t := v .(time.Time )
867+ stream .WriteVal (t .UnixMilli ())
868+ msRes := t .Truncate (time .Millisecond )
869+ ns := t .Sub (msRes ).Nanoseconds ()
870+ if ns != 0 {
871+ hasNSTime = true
872+ nsTime [i ] = ns
873+ }
816874 case isFloat :
817875 // For float and nullable float we check whether a value is a special
818876 // entity (NaN, -Inf, +Inf) not supported by JSON spec, we then encode this
@@ -848,6 +906,10 @@ func writeDataFrameData(frame *Frame, stream *jsoniter.Stream) {
848906 }
849907 }
850908 stream .WriteArrayEnd ()
909+ if hasNSTime {
910+ nanos [fidx ] = nsTime
911+ nsOffSetCount ++
912+ }
851913 }
852914 stream .WriteArrayEnd ()
853915
@@ -857,6 +919,12 @@ func writeDataFrameData(frame *Frame, stream *jsoniter.Stream) {
857919 stream .WriteVal (entities )
858920 }
859921
922+ if nsOffSetCount > 0 {
923+ stream .WriteMore ()
924+ stream .WriteObjectField ("nanos" )
925+ stream .WriteVal (nanos )
926+ }
927+
860928 stream .WriteObjectEnd ()
861929}
862930
@@ -1027,6 +1095,8 @@ func writeArrowData(stream *jsoniter.Stream, record array.Record) error {
10271095 stream .WriteObjectStart ()
10281096
10291097 entities := make ([]* fieldEntityLookup , fieldCount )
1098+ nanos := make ([][]int64 , fieldCount )
1099+ var hasNano bool
10301100 entityCount := 0
10311101
10321102 stream .WriteObjectField ("values" )
@@ -1040,7 +1110,11 @@ func writeArrowData(stream *jsoniter.Stream, record array.Record) error {
10401110
10411111 switch col .DataType ().ID () {
10421112 case arrow .TIMESTAMP :
1043- writeArrowDataTIMESTAMP (stream , col )
1113+ nanoOffset := writeArrowDataTIMESTAMP (stream , col )
1114+ if nanoOffset != nil {
1115+ nanos [fidx ] = nanoOffset
1116+ hasNano = true
1117+ }
10441118
10451119 case arrow .UINT8 :
10461120 ent = writeArrowDataUint8 (stream , col )
@@ -1085,14 +1159,21 @@ func writeArrowData(stream *jsoniter.Stream, record array.Record) error {
10851159 stream .WriteVal (entities )
10861160 }
10871161
1162+ if hasNano {
1163+ stream .WriteMore ()
1164+ stream .WriteObjectField ("nanos" )
1165+ stream .WriteVal (nanos )
1166+ }
1167+
10881168 stream .WriteObjectEnd ()
10891169 return nil
10901170}
10911171
10921172// Custom timestamp extraction... assumes nanoseconds for everything now
1093- func writeArrowDataTIMESTAMP (stream * jsoniter.Stream , col array.Interface ) {
1173+ func writeArrowDataTIMESTAMP (stream * jsoniter.Stream , col array.Interface ) [] int64 {
10941174 count := col .Len ()
1095-
1175+ var hasNSTime bool
1176+ nsTime := make ([]int64 , count )
10961177 v := array .NewTimestampData (col .Data ())
10971178 stream .WriteArrayStart ()
10981179 for i := 0 ; i < count ; i ++ {
@@ -1107,12 +1188,22 @@ func writeArrowDataTIMESTAMP(stream *jsoniter.Stream, col array.Interface) {
11071188 ms := int64 (ns ) / int64 (time .Millisecond ) // nanosecond assumption
11081189 stream .WriteInt64 (ms )
11091190
1191+ nsOffSet := int64 (ns ) - ms * int64 (1e6 )
1192+ if nsOffSet != 0 {
1193+ hasNSTime = true
1194+ nsTime [i ] = nsOffSet
1195+ }
1196+
11101197 if stream .Error != nil { // ???
11111198 stream .Error = nil
11121199 stream .WriteNil ()
11131200 }
11141201 }
11151202 stream .WriteArrayEnd ()
1203+ if hasNSTime {
1204+ return nsTime
1205+ }
1206+ return nil
11161207}
11171208
11181209func readTimeVectorJSON (iter * jsoniter.Iterator , nullable bool , size int ) (vector , error ) {
0 commit comments