@@ -27,14 +27,15 @@ import (
2727 "github.com/apache/arrow-go/v18/arrow/array"
2828 "github.com/apache/arrow-go/v18/arrow/compute"
2929 "github.com/apache/arrow-go/v18/arrow/compute/exprs"
30+ "github.com/apache/arrow-go/v18/arrow/decimal"
3031 "github.com/apache/arrow-go/v18/arrow/extensions"
3132 "github.com/apache/arrow-go/v18/arrow/memory"
3233 "github.com/apache/arrow-go/v18/arrow/scalar"
3334 "github.com/google/uuid"
3435 "github.com/stretchr/testify/assert"
3536 "github.com/stretchr/testify/require"
36- "github.com/substrait-io/substrait-go/v3 /expr"
37- "github.com/substrait-io/substrait-go/v3 /types"
37+ "github.com/substrait-io/substrait-go/v4 /expr"
38+ "github.com/substrait-io/substrait-go/v4 /types"
3839)
3940
4041var (
@@ -478,3 +479,145 @@ func TestGenerateMask(t *testing.T) {
478479 })
479480 }
480481}
482+
483+ func Test_Types (t * testing.T ) {
484+ t .Parallel ()
485+
486+ tt := []struct {
487+ name string
488+ schema func () * arrow.Schema
489+ record func (rq * require.Assertions , schema * arrow.Schema ) arrow.Record
490+ val func (rq * require.Assertions ) expr.Literal
491+ }{
492+ {
493+ name : "expect arrow.TIME64 (ns) ok" ,
494+ schema : func () * arrow.Schema {
495+ field := arrow.Field {
496+ Name : "col" ,
497+ Type : & arrow.Time64Type {Unit : arrow .Nanosecond },
498+ Nullable : true ,
499+ }
500+
501+ return arrow .NewSchema ([]arrow.Field {field }, nil )
502+ },
503+ record : func (rq * require.Assertions , schema * arrow.Schema ) arrow.Record {
504+ b := array .NewTime64Builder (memory .DefaultAllocator , & arrow.Time64Type {Unit : arrow .Nanosecond })
505+ defer b .Release ()
506+
507+ t1 , err := arrow .Time64FromString ("10:00:00.000000" , arrow .Nanosecond )
508+ rq .NoError (err , "Failed to create Time64 value" )
509+
510+ b .AppendValues ([]arrow.Time64 {t1 }, []bool {true })
511+
512+ return array .NewRecord (schema , []arrow.Array {b .NewArray ()}, 1 )
513+ },
514+ val : func (rq * require.Assertions ) expr.Literal {
515+ v , err := arrow .Time64FromString ("11:00:00.000000" , arrow .Nanosecond )
516+ rq .NoError (err , "Failed to create Time64 value" )
517+
518+ return expr .NewPrimitiveLiteral (types .Time (v ), true )
519+ },
520+ },
521+ {
522+ name : "expect arrow.TIMESTAMP (ns) ok" ,
523+ schema : func () * arrow.Schema {
524+ field := arrow.Field {
525+ Name : "col" ,
526+ Type : & arrow.TimestampType {Unit : arrow .Nanosecond },
527+ Nullable : true ,
528+ }
529+
530+ return arrow .NewSchema ([]arrow.Field {field }, nil )
531+ },
532+ record : func (rq * require.Assertions , schema * arrow.Schema ) arrow.Record {
533+ b := array .NewTimestampBuilder (memory .DefaultAllocator , & arrow.TimestampType {Unit : arrow .Nanosecond })
534+ defer b .Release ()
535+
536+ t1 , err := arrow .TimestampFromString ("2021-01-01T10:00:00.000000Z" , arrow .Nanosecond )
537+ rq .NoError (err , "Failed to create Timestamp value" )
538+
539+ b .AppendValues ([]arrow.Timestamp {t1 }, []bool {true })
540+
541+ return array .NewRecord (schema , []arrow.Array {b .NewArray ()}, 1 )
542+ },
543+ val : func (rq * require.Assertions ) expr.Literal {
544+ v , err := arrow .TimestampFromString ("2021-01-01T11:00:00.000000Z" , arrow .Microsecond )
545+ rq .NoError (err , "Failed to create Timestamp value" )
546+
547+ return expr .NewPrimitiveLiteral (types .Timestamp (v ), true )
548+ },
549+ },
550+ {
551+ name : "expect arrow.DECIMAL128 ok" ,
552+ schema : func () * arrow.Schema {
553+ field := arrow.Field {
554+ Name : "col" ,
555+ Type : & arrow.Decimal128Type {Precision : 38 , Scale : 10 },
556+ Nullable : true ,
557+ }
558+
559+ return arrow .NewSchema ([]arrow.Field {field }, nil )
560+ },
561+ record : func (rq * require.Assertions , schema * arrow.Schema ) arrow.Record {
562+ b := array .NewDecimal128Builder (memory .DefaultAllocator , & arrow.Decimal128Type {Precision : 38 , Scale : 10 })
563+ defer b .Release ()
564+
565+ d , err := decimal .Decimal128FromFloat (123.456789 , 38 , 10 )
566+ rq .NoError (err , "Failed to create Decimal128 value" )
567+
568+ b .Append (d )
569+
570+ return array .NewRecord (schema , []arrow.Array {b .NewArray ()}, 1 )
571+ },
572+ val : func (rq * require.Assertions ) expr.Literal {
573+ v , p , s , err := expr .DecimalStringToBytes ("456.7890123456" )
574+ rq .NoError (err , "Failed to convert decimal string to bytes" )
575+
576+ lit , err := expr .NewLiteral (& types.Decimal {
577+ Value : v [:16 ],
578+ Precision : p ,
579+ Scale : s ,
580+ }, true )
581+ rq .NoError (err , "Failed to create Decimal128 literal" )
582+
583+ return lit
584+ },
585+ },
586+ }
587+
588+ for _ , tc := range tt {
589+ tc := tc
590+ t .Run (tc .name , func (t * testing.T ) {
591+ t .Parallel ()
592+
593+ ctx := context .Background ()
594+ rq := require .New (t )
595+ schema := tc .schema ()
596+ record := tc .record (rq , schema )
597+
598+ extSet := exprs .GetExtensionIDSet (ctx )
599+ builder := exprs .NewExprBuilder (extSet )
600+
601+ err := builder .SetInputSchema (schema )
602+ rq .NoError (err , "Failed to set input schema" )
603+
604+ b , err := builder .CallScalar ("less" , nil ,
605+ builder .FieldRef ("col" ),
606+ builder .Literal (tc .val (rq )),
607+ )
608+
609+ rq .NoError (err , "Failed to call scalar" )
610+
611+ e , err := b .BuildExpr ()
612+ rq .NoError (err , "Failed to build expression" )
613+
614+ ctx = exprs .WithExtensionIDSet (ctx , extSet )
615+
616+ dr := compute .NewDatum (record )
617+ defer dr .Release ()
618+
619+ _ , err = exprs .ExecuteScalarExpression (ctx , schema , e , dr )
620+ rq .NoError (err , "Failed to execute scalar expression" )
621+ })
622+ }
623+ }
0 commit comments