laskoviymishka commented on code in PR #1590:
URL: https://github.com/apache/iceberg-go/pull/1590#discussion_r3680750829


##########
table/substrait/substrait_test.go:
##########
@@ -137,6 +137,60 @@ func TestExprs(t *testing.T) {
        }
 }
 
+func TestNanosecondTimestampLiterals(t *testing.T) {
+       tests := []struct {
+               name       string
+               fieldType  iceberg.Type
+               predicate  iceberg.BooleanExpression
+               wantValues []string
+               wantType   string
+       }{
+               {
+                       name:       "timestamp equality",
+                       fieldType:  iceberg.PrimitiveTypes.TimestampNs,
+                       predicate:  iceberg.EqualTo(iceberg.Reference("ts"), 
iceberg.TimestampNano(123456789)),
+                       wantValues: []string{"1970-01-01 00:00:00.123456789"},
+                       wantType:   "precision_timestamp<9>",
+               },
+               {
+                       name:       "timestamp with timezone equality before 
epoch",
+                       fieldType:  iceberg.PrimitiveTypes.TimestampTzNs,
+                       predicate:  iceberg.EqualTo(iceberg.Reference("ts"), 
iceberg.TimestampNano(-123456789)),
+                       wantValues: []string{"1969-12-31T23:59:59.876543211Z"},
+                       wantType:   "precision_timestamp_tz<9>",
+               },
+               {
+                       name:       "timestamp in",
+                       fieldType:  iceberg.PrimitiveTypes.TimestampNs,
+                       predicate:  iceberg.IsIn(iceberg.Reference("ts"), 
iceberg.TimestampNano(1), iceberg.TimestampNano(1001)),
+                       wantValues: []string{"1970-01-01 00:00:00.000000001", 
"1970-01-01 00:00:00.000001001"},
+                       wantType:   "precision_timestamp<9>",
+               },
+               {
+                       name:       "timestamp with timezone not in",
+                       fieldType:  iceberg.PrimitiveTypes.TimestampTzNs,
+                       predicate:  iceberg.NotIn(iceberg.Reference("ts"), 
iceberg.TimestampNano(-1), iceberg.TimestampNano(1001)),
+                       wantValues: []string{"1969-12-31T23:59:59.999999999Z", 
"1970-01-01T00:00:00.000001001Z"},
+                       wantType:   "precision_timestamp_tz<9>",
+               },
+       }
+
+       for _, tt := range tests {
+               t.Run(tt.name, func(t *testing.T) {
+                       sc := iceberg.NewSchema(1, iceberg.NestedField{ID: 1, 
Name: "ts", Type: tt.fieldType})
+                       bound, err := iceberg.BindExpr(sc, tt.predicate, true)
+                       require.NoError(t, err)
+
+                       _, converted, err := substrait.ConvertExpr(sc, bound, 
true)
+                       require.NoError(t, err)
+                       for _, value := range tt.wantValues {
+                               assert.Contains(t, converted.String(), value)

Review Comment:
   `assert.Contains` here is doing less than it looks — a wrong literal whose 
rendering happened to contain this substring would still pass, and the 
assertion goes quietly vacuous if substrait-go ever changes how it formats 
`PrecisionTimestampLiteral`. `TestExprs` right above uses `assert.Equal` on the 
full expression string; I'd match that here so the regression test actually 
pins the value. wdyt?



##########
table/substrait/substrait_test.go:
##########
@@ -137,6 +137,60 @@ func TestExprs(t *testing.T) {
        }
 }
 
+func TestNanosecondTimestampLiterals(t *testing.T) {

Review Comment:
   The original panic hit every predicate carrying a ns literal, including 
range comparisons — but the cases here only cover equality and in/not-in. A 
single `GreaterThan`/`LessThan` case per ns type would lock the comparison path 
that was also broken. Not blocking, just cheap insurance while we're here.



##########
table/substrait/substrait.go:
##########
@@ -318,6 +318,16 @@ func toSubstraitLiteral(typ iceberg.Type, lit 
iceberg.Literal) expr.Literal {
                }
 
                return toPrimitiveSubstraitLiteral(types.Timestamp(lit))
+       case iceberg.TimestampNsLiteral:
+               if typ.Equals(iceberg.PrimitiveTypes.TimestampTzNs) {

Review Comment:
   This `err` can't actually be non-nil — `literal.NewPrecisionTimestamp[Tz]` 
only fails on an unknown precision, and we hand it the `PrecisionNanoSeconds` 
constant — so the panic is guarding a dead path. 
`expr.NewPrecisionTimestampLiteral` / `NewPrecisionTimestampTzLiteral` are 
already in scope and don't return an error, which lets this arm drop the var 
block and mirror the two-line `TimestampLiteral` case above:
   
   ```go
   case iceberg.TimestampNsLiteral:
        if typ.Equals(iceberg.PrimitiveTypes.TimestampTzNs) {
                return expr.NewPrecisionTimestampTzLiteral(int64(lit), 
types.PrecisionNanoSeconds, types.NullabilityRequired)
        }
   
        return expr.NewPrecisionTimestampLiteral(int64(lit), 
types.PrecisionNanoSeconds, types.NullabilityRequired)
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to