github.com/fraugster/parquet-go@v0.12.0/floor/writeread_test.go (about)

     1  package floor
     2  
     3  import (
     4  	"bytes"
     5  	"os"
     6  	"reflect"
     7  	"testing"
     8  	"time"
     9  
    10  	goparquet "github.com/fraugster/parquet-go"
    11  	"github.com/fraugster/parquet-go/parquet"
    12  	"github.com/fraugster/parquet-go/parquetschema"
    13  	"github.com/fraugster/parquet-go/parquetschema/autoschema"
    14  	"github.com/stretchr/testify/assert"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  func writeReadOne(t *testing.T, o interface{}, schema string) interface{} {
    19  	t.Helper()
    20  	defer func() {
    21  		if r := recover(); r != nil {
    22  			t.Error(r)
    23  		}
    24  	}()
    25  	schemaDef, err := parquetschema.ParseSchemaDefinition(schema)
    26  	require.NoError(t, err)
    27  
    28  	var buf bytes.Buffer
    29  	w := NewWriter(goparquet.NewFileWriter(&buf,
    30  		goparquet.WithCompressionCodec(parquet.CompressionCodec_SNAPPY),
    31  		goparquet.WithSchemaDefinition(schemaDef),
    32  	))
    33  
    34  	err = w.Write(o)
    35  	require.NoError(t, err)
    36  
    37  	err = w.Close()
    38  	require.NoError(t, err)
    39  
    40  	fr, err := goparquet.NewFileReader(bytes.NewReader(buf.Bytes()))
    41  	require.NoError(t, err)
    42  
    43  	pr := NewReader(fr)
    44  
    45  	pr.Next()
    46  
    47  	o2val := reflect.New(reflect.TypeOf(o))
    48  	err = pr.Scan(o2val.Interface())
    49  	require.NoError(t, err)
    50  
    51  	return o2val.Elem().Interface()
    52  }
    53  
    54  func TestWriteRead(t *testing.T) {
    55  	t.Run("by parquet type", func(t *testing.T) {
    56  		t.Run("int64", func(t *testing.T) {
    57  			t.Run("int go type", func(t *testing.T) {
    58  				o := struct{ Val int }{Val: 1}
    59  				s := `message test {required int64 val;}`
    60  				assert.EqualValues(t, o, writeReadOne(t, o, s))
    61  			})
    62  
    63  			t.Run("int64 go type", func(t *testing.T) {
    64  				o := struct{ Val int64 }{Val: 1}
    65  				s := `message test {required int64 val;}`
    66  				assert.EqualValues(t, o, writeReadOne(t, o, s))
    67  			})
    68  
    69  			t.Run("int32 go type", func(t *testing.T) {
    70  				o := struct{ Val int32 }{Val: 1}
    71  				s := `message test {required int64 val;}`
    72  				assert.EqualValues(t, o, writeReadOne(t, o, s))
    73  			})
    74  
    75  			t.Run("int16 go type", func(t *testing.T) {
    76  				o := struct{ Val int16 }{Val: 1}
    77  				s := `message test {required int64 val;}`
    78  				assert.EqualValues(t, o, writeReadOne(t, o, s))
    79  			})
    80  
    81  			t.Run("int8 go type", func(t *testing.T) {
    82  				o := struct{ Val int8 }{Val: 1}
    83  				s := `message test {required int64 val;}`
    84  				assert.EqualValues(t, o, writeReadOne(t, o, s))
    85  			})
    86  
    87  			t.Run("uint go type", func(t *testing.T) {
    88  				o := struct{ Val uint }{Val: 1}
    89  				s := `message test {required int64 val;}`
    90  				assert.EqualValues(t, o, writeReadOne(t, o, s))
    91  			})
    92  
    93  			t.Run("uint64 go type", func(t *testing.T) {
    94  				o := struct{ Val uint64 }{Val: 1}
    95  				s := `message test {required int64 val;}`
    96  				assert.EqualValues(t, o, writeReadOne(t, o, s))
    97  			})
    98  
    99  			t.Run("uint32 go type", func(t *testing.T) {
   100  				o := struct{ Val uint32 }{Val: 1}
   101  				s := `message test {required int64 val;}`
   102  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   103  			})
   104  
   105  			t.Run("uint16 go type", func(t *testing.T) {
   106  				o := struct{ Val uint16 }{Val: 1}
   107  				s := `message test {required int64 val;}`
   108  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   109  			})
   110  
   111  			t.Run("uint8 go type", func(t *testing.T) {
   112  				o := struct{ Val uint8 }{Val: 1}
   113  				s := `message test {required int64 val;}`
   114  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   115  			})
   116  
   117  			t.Run("Time go type", func(t *testing.T) {
   118  				t.Run("nanos", func(t *testing.T) {
   119  					o := struct{ Val time.Time }{Val: time.Now().UTC()}
   120  					s := `message test {required int64 val (TIMESTAMP(NANOS, true));}`
   121  					assert.EqualValues(t, o, writeReadOne(t, o, s))
   122  				})
   123  
   124  				t.Run("micros", func(t *testing.T) {
   125  					o := struct{ Val time.Time }{Val: time.Now().Truncate(time.Microsecond).UTC()}
   126  					s := `message test {required int64 val (TIMESTAMP(MICROS, true));}`
   127  					assert.EqualValues(t, o, writeReadOne(t, o, s))
   128  				})
   129  
   130  				t.Run("millis", func(t *testing.T) {
   131  					o := struct{ Val time.Time }{Val: time.Now().Truncate(time.Millisecond).UTC()}
   132  					s := `message test {required int64 val (TIMESTAMP(MILLIS, true));}`
   133  					assert.EqualValues(t, o, writeReadOne(t, o, s))
   134  				})
   135  			})
   136  		})
   137  
   138  		t.Run("int32", func(t *testing.T) {
   139  			t.Run("int go type", func(t *testing.T) {
   140  				o := struct{ Val int }{Val: 1}
   141  				s := `message test {required int32 val;}`
   142  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   143  			})
   144  
   145  			t.Run("int64 go type", func(t *testing.T) {
   146  				o := struct{ Val int64 }{Val: 1}
   147  				s := `message test {required int32 val;}`
   148  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   149  			})
   150  
   151  			t.Run("int32 go type", func(t *testing.T) {
   152  				o := struct{ Val int32 }{Val: 1}
   153  				s := `message test {required int32 val;}`
   154  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   155  			})
   156  
   157  			t.Run("int16 go type", func(t *testing.T) {
   158  				o := struct{ Val int16 }{Val: 1}
   159  				s := `message test {required int32 val;}`
   160  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   161  			})
   162  
   163  			t.Run("int8 go type", func(t *testing.T) {
   164  				o := struct{ Val int8 }{Val: 1}
   165  				s := `message test {required int32 val;}`
   166  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   167  			})
   168  
   169  			t.Run("uint go type", func(t *testing.T) {
   170  				o := struct{ Val uint }{Val: 1}
   171  				s := `message test {required int32 val;}`
   172  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   173  			})
   174  
   175  			t.Run("uint64 go type", func(t *testing.T) {
   176  				o := struct{ Val uint64 }{Val: 1}
   177  				s := `message test {required int32 val;}`
   178  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   179  			})
   180  
   181  			t.Run("uint32 go type", func(t *testing.T) {
   182  				o := struct{ Val uint32 }{Val: 1}
   183  				s := `message test {required int32 val;}`
   184  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   185  			})
   186  
   187  			t.Run("uint16 go type", func(t *testing.T) {
   188  				o := struct{ Val uint16 }{Val: 1}
   189  				s := `message test {required int32 val;}`
   190  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   191  			})
   192  
   193  			t.Run("uint8 go type", func(t *testing.T) {
   194  				o := struct{ Val uint8 }{Val: 1}
   195  				s := `message test {required int32 val;}`
   196  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   197  			})
   198  		})
   199  
   200  		t.Run("byte_arrays", func(t *testing.T) {
   201  			t.Run("string go type", func(t *testing.T) {
   202  				o := struct{ Val string }{Val: "1"}
   203  				s := `message test {required binary val;}`
   204  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   205  			})
   206  
   207  			t.Run("[]byte go type", func(t *testing.T) {
   208  				o := struct{ Val []byte }{Val: []byte("1")}
   209  				s := `message test {required binary val;}`
   210  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   211  			})
   212  
   213  			t.Run("[1]byte go type", func(t *testing.T) {
   214  				o := struct{ Val [1]byte }{Val: [1]byte{'1'}}
   215  				s := `message test {required binary val;}`
   216  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   217  			})
   218  		})
   219  
   220  		t.Run("float", func(t *testing.T) {
   221  			t.Run("float32 go type", func(t *testing.T) {
   222  				o := struct{ Val float32 }{Val: 1.1}
   223  				s := `message test {required float val;}`
   224  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   225  			})
   226  		})
   227  
   228  		t.Run("double", func(t *testing.T) {
   229  			t.Run("float64 go type", func(t *testing.T) {
   230  				o := struct{ Val float64 }{Val: 1.1}
   231  				s := `message test {required double val;}`
   232  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   233  			})
   234  		})
   235  
   236  		t.Run("boolean", func(t *testing.T) {
   237  			t.Run("bool go type", func(t *testing.T) {
   238  				o := struct{ Val bool }{Val: true}
   239  				s := `message test {required boolean val;}`
   240  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   241  			})
   242  		})
   243  
   244  		t.Run("groups", func(t *testing.T) {
   245  			t.Run("nested struct go type", func(t *testing.T) {
   246  				type child struct{ Val int64 }
   247  				type parent struct{ Child child }
   248  				o := parent{child{1}}
   249  				s := `message parent {
   250  				required group child {
   251  					required int64 val;
   252  				}
   253  			}`
   254  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   255  			})
   256  
   257  			t.Run("slice go type", func(t *testing.T) {
   258  				o := struct{ Val []int64 }{Val: []int64{1}}
   259  				s := `message test {
   260  				required group val (LIST) {
   261  					repeated group list {
   262  						required int64 element;
   263  					}
   264  				}
   265  			}`
   266  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   267  			})
   268  
   269  			t.Run("map go type", func(t *testing.T) {
   270  				o := struct{ Val map[int64]int64 }{Val: map[int64]int64{1: 1}}
   271  				s := `message test {
   272  				required group val (MAP) {
   273  					repeated group key_value {
   274  						required int64 key;
   275  						required int64 value;
   276  					}
   277  				}
   278  			}`
   279  				assert.EqualValues(t, o, writeReadOne(t, o, s))
   280  			})
   281  		})
   282  	})
   283  
   284  	t.Run("fields not defined in schema are ignored, but do not error", func(t *testing.T) {
   285  		t.Run("int", func(t *testing.T) {
   286  			s := `message test {
   287  				required int64 val;
   288  			}`
   289  			o := struct {
   290  				Val   int64
   291  				extra int
   292  			}{Val: 1, extra: 1}
   293  			e := struct {
   294  				Val   int64
   295  				extra int
   296  			}{Val: 1, extra: 0}
   297  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   298  		})
   299  		t.Run("int64", func(t *testing.T) {
   300  			s := `message test {
   301  				required int64 val;
   302  			}`
   303  			o := struct {
   304  				Val   int64
   305  				extra int64
   306  			}{Val: 1, extra: 1}
   307  			e := struct {
   308  				Val   int64
   309  				extra int64
   310  			}{Val: 1, extra: 0}
   311  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   312  		})
   313  		t.Run("int32", func(t *testing.T) {
   314  			s := `message test {
   315  				required int64 val;
   316  			}`
   317  			o := struct {
   318  				Val   int64
   319  				extra int32
   320  			}{Val: 1, extra: 1}
   321  			e := struct {
   322  				Val   int64
   323  				extra int32
   324  			}{Val: 1, extra: 0}
   325  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   326  		})
   327  		t.Run("int16", func(t *testing.T) {
   328  			s := `message test {
   329  				required int64 val;
   330  			}`
   331  			o := struct {
   332  				Val   int64
   333  				extra int16
   334  			}{Val: 1, extra: 1}
   335  			e := struct {
   336  				Val   int64
   337  				extra int16
   338  			}{Val: 1, extra: 0}
   339  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   340  		})
   341  		t.Run("int8", func(t *testing.T) {
   342  			s := `message test {
   343  				required int64 val;
   344  			}`
   345  			o := struct {
   346  				Val   int64
   347  				extra int8
   348  			}{Val: 1, extra: 1}
   349  			e := struct {
   350  				Val   int64
   351  				extra int8
   352  			}{Val: 1, extra: 0}
   353  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   354  		})
   355  		t.Run("uint", func(t *testing.T) {
   356  			s := `message test {
   357  				required int64 val;
   358  			}`
   359  			o := struct {
   360  				Val   int64
   361  				extra uint
   362  			}{Val: 1, extra: 1}
   363  			e := struct {
   364  				Val   int64
   365  				extra uint
   366  			}{Val: 1, extra: 0}
   367  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   368  		})
   369  		t.Run("uint64", func(t *testing.T) {
   370  			s := `message test {
   371  				required int64 val;
   372  			}`
   373  			o := struct {
   374  				Val   int64
   375  				extra uint64
   376  			}{Val: 1, extra: 1}
   377  			e := struct {
   378  				Val   int64
   379  				extra uint64
   380  			}{Val: 1, extra: 0}
   381  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   382  		})
   383  		t.Run("uint32", func(t *testing.T) {
   384  			s := `message test {
   385  				required int64 val;
   386  			}`
   387  			o := struct {
   388  				Val   int64
   389  				extra uint32
   390  			}{Val: 1, extra: 1}
   391  			e := struct {
   392  				Val   int64
   393  				extra uint32
   394  			}{Val: 1, extra: 0}
   395  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   396  		})
   397  		t.Run("uint16", func(t *testing.T) {
   398  			s := `message test {
   399  				required int64 val;
   400  			}`
   401  			o := struct {
   402  				Val   int64
   403  				extra uint16
   404  			}{Val: 1, extra: 1}
   405  			e := struct {
   406  				Val   int64
   407  				extra uint16
   408  			}{Val: 1, extra: 0}
   409  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   410  		})
   411  		t.Run("uint8", func(t *testing.T) {
   412  			s := `message test {
   413  				required int64 val;
   414  			}`
   415  			o := struct {
   416  				Val   int64
   417  				extra uint8
   418  			}{Val: 1, extra: 1}
   419  			e := struct {
   420  				Val   int64
   421  				extra uint8
   422  			}{Val: 1, extra: 0}
   423  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   424  		})
   425  		t.Run("float32", func(t *testing.T) {
   426  			s := `message test {
   427  				required int64 val;
   428  			}`
   429  			o := struct {
   430  				Val   int64
   431  				extra float32
   432  			}{Val: 1, extra: 1}
   433  			e := struct {
   434  				Val   int64
   435  				extra float32
   436  			}{Val: 1, extra: 0}
   437  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   438  		})
   439  		t.Run("float64", func(t *testing.T) {
   440  			s := `message test {
   441  				required int64 val;
   442  			}`
   443  			o := struct {
   444  				Val   int64
   445  				extra float64
   446  			}{Val: 1, extra: 1}
   447  			e := struct {
   448  				Val   int64
   449  				extra float64
   450  			}{Val: 1, extra: 0}
   451  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   452  		})
   453  		t.Run("bool", func(t *testing.T) {
   454  			s := `message test {
   455  				required int64 val;
   456  			}`
   457  			o := struct {
   458  				Val   int64
   459  				extra bool
   460  			}{Val: 1, extra: true}
   461  			e := struct {
   462  				Val   int64
   463  				extra bool
   464  			}{Val: 1, extra: false}
   465  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   466  		})
   467  		t.Run("[1]byte", func(t *testing.T) {
   468  			s := `message test {
   469  				required int64 val;
   470  			}`
   471  			o := struct {
   472  				Val   int64
   473  				extra [1]byte
   474  			}{Val: 1, extra: [1]byte{'1'}}
   475  			e := struct {
   476  				Val   int64
   477  				extra [1]byte
   478  			}{Val: 1, extra: [1]byte{}}
   479  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   480  		})
   481  		t.Run("[]byte", func(t *testing.T) {
   482  			s := `message test {
   483  				required int64 val;
   484  			}`
   485  			o := struct {
   486  				Val   int64
   487  				extra []byte
   488  			}{Val: 1, extra: []byte{'1'}}
   489  			e := struct {
   490  				Val   int64
   491  				extra []byte
   492  			}{Val: 1, extra: nil}
   493  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   494  		})
   495  		t.Run("string", func(t *testing.T) {
   496  			s := `message test {
   497  				required int64 val;
   498  			}`
   499  			o := struct {
   500  				Val   int64
   501  				extra string
   502  			}{Val: 1, extra: "1"}
   503  			e := struct {
   504  				Val   int64
   505  				extra string
   506  			}{Val: 1, extra: ""}
   507  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   508  		})
   509  		t.Run("[]int", func(t *testing.T) {
   510  			s := `message test {
   511  				required int64 val;
   512  			}`
   513  			o := struct {
   514  				Val   int64
   515  				extra []int
   516  			}{Val: 1, extra: []int{1}}
   517  			e := struct {
   518  				Val   int64
   519  				extra []int
   520  			}{Val: 1, extra: nil}
   521  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   522  		})
   523  		t.Run("struct", func(t *testing.T) {
   524  			s := `message test {
   525  				required int64 val;
   526  			}`
   527  			o := struct {
   528  				Val   int64
   529  				extra struct{ i int }
   530  			}{Val: 1, extra: struct{ i int }{1}}
   531  			e := struct {
   532  				Val   int64
   533  				extra struct{ i int }
   534  			}{Val: 1, extra: struct{ i int }{}}
   535  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   536  		})
   537  		t.Run("time.Time", func(t *testing.T) {
   538  			s := `message test {
   539  				required int64 val;
   540  			}`
   541  			o := struct {
   542  				Val   int64
   543  				extra time.Time
   544  			}{Val: 1, extra: time.Now()}
   545  			e := struct {
   546  				Val   int64
   547  				extra time.Time
   548  			}{Val: 1, extra: time.Time{}}
   549  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   550  		})
   551  		t.Run("map[int]int", func(t *testing.T) {
   552  			s := `message test {
   553  				required int64 val;
   554  			}`
   555  			o := struct {
   556  				Val   int64
   557  				extra map[int]int
   558  			}{Val: 1, extra: map[int]int{1: 1}}
   559  			e := struct {
   560  				Val   int64
   561  				extra map[int]int
   562  			}{Val: 1, extra: nil}
   563  			assert.EqualValues(t, e, writeReadOne(t, o, s))
   564  		})
   565  	})
   566  }
   567  
   568  func writeReadOneWithAutoSchema(t *testing.T, o interface{}) interface{} {
   569  	t.Helper()
   570  	defer func() {
   571  		if r := recover(); r != nil {
   572  			t.Error(r)
   573  		}
   574  	}()
   575  	schemaDef, err := autoschema.GenerateSchema(o)
   576  	require.NoError(t, err)
   577  	t.Logf("auto-generated schema: %v", schemaDef)
   578  
   579  	var buf bytes.Buffer
   580  	w := NewWriter(goparquet.NewFileWriter(&buf,
   581  		goparquet.WithCompressionCodec(parquet.CompressionCodec_SNAPPY),
   582  		goparquet.WithSchemaDefinition(schemaDef),
   583  	))
   584  
   585  	err = w.Write(o)
   586  	require.NoError(t, err)
   587  
   588  	err = w.Close()
   589  	require.NoError(t, err)
   590  
   591  	fr, err := goparquet.NewFileReader(bytes.NewReader(buf.Bytes()))
   592  	require.NoError(t, err)
   593  
   594  	pr := NewReader(fr)
   595  
   596  	pr.Next()
   597  
   598  	o2val := reflect.New(reflect.TypeOf(o))
   599  	err = pr.Scan(o2val.Interface())
   600  	require.NoError(t, err)
   601  
   602  	return o2val.Elem().Interface()
   603  }
   604  
   605  func TestWriteReadWithAutoSchema(t *testing.T) {
   606  	t.Run("by parquet type", func(t *testing.T) {
   607  		t.Run("int64", func(t *testing.T) {
   608  			t.Run("int go type", func(t *testing.T) {
   609  				o := struct{ Val int }{Val: 1}
   610  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   611  			})
   612  
   613  			t.Run("int64 go type", func(t *testing.T) {
   614  				o := struct{ Val int64 }{Val: 1}
   615  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   616  			})
   617  
   618  			t.Run("int32 go type", func(t *testing.T) {
   619  				o := struct{ Val int32 }{Val: 1}
   620  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   621  			})
   622  
   623  			t.Run("int16 go type", func(t *testing.T) {
   624  				o := struct{ Val int16 }{Val: 1}
   625  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   626  			})
   627  
   628  			t.Run("int8 go type", func(t *testing.T) {
   629  				o := struct{ Val int8 }{Val: 1}
   630  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   631  			})
   632  
   633  			t.Run("uint go type", func(t *testing.T) {
   634  				o := struct{ Val uint }{Val: 1}
   635  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   636  			})
   637  
   638  			t.Run("uint32 go type", func(t *testing.T) {
   639  				o := struct{ Val uint32 }{Val: 1}
   640  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   641  			})
   642  
   643  			t.Run("uint16 go type", func(t *testing.T) {
   644  				o := struct{ Val uint16 }{Val: 1}
   645  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   646  			})
   647  
   648  			t.Run("uint8 go type", func(t *testing.T) {
   649  				o := struct{ Val uint8 }{Val: 1}
   650  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   651  			})
   652  		})
   653  
   654  		t.Run("int32", func(t *testing.T) {
   655  			t.Run("int go type", func(t *testing.T) {
   656  				o := struct{ Val int }{Val: 1}
   657  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   658  			})
   659  
   660  			t.Run("int64 go type", func(t *testing.T) {
   661  				o := struct{ Val int64 }{Val: 1}
   662  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   663  			})
   664  
   665  			t.Run("int32 go type", func(t *testing.T) {
   666  				o := struct{ Val int32 }{Val: 1}
   667  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   668  			})
   669  
   670  			t.Run("int16 go type", func(t *testing.T) {
   671  				o := struct{ Val int16 }{Val: 1}
   672  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   673  			})
   674  
   675  			t.Run("int8 go type", func(t *testing.T) {
   676  				o := struct{ Val int8 }{Val: 1}
   677  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   678  			})
   679  
   680  			t.Run("uint go type", func(t *testing.T) {
   681  				o := struct{ Val uint }{Val: 1}
   682  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   683  			})
   684  
   685  			t.Run("uint32 go type", func(t *testing.T) {
   686  				o := struct{ Val uint32 }{Val: 1}
   687  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   688  			})
   689  
   690  			t.Run("uint16 go type", func(t *testing.T) {
   691  				o := struct{ Val uint16 }{Val: 1}
   692  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   693  			})
   694  
   695  			t.Run("uint8 go type", func(t *testing.T) {
   696  				o := struct{ Val uint8 }{Val: 1}
   697  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   698  			})
   699  		})
   700  
   701  		t.Run("byte_arrays", func(t *testing.T) {
   702  			t.Run("string go type", func(t *testing.T) {
   703  				o := struct{ Val string }{Val: "1"}
   704  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   705  			})
   706  
   707  			t.Run("[]byte go type", func(t *testing.T) {
   708  				o := struct{ Val []byte }{Val: []byte("1")}
   709  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   710  			})
   711  
   712  			t.Run("[1]byte go type", func(t *testing.T) {
   713  				o := struct{ Val [1]byte }{Val: [1]byte{'1'}}
   714  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   715  			})
   716  		})
   717  
   718  		t.Run("float", func(t *testing.T) {
   719  			t.Run("float32 go type", func(t *testing.T) {
   720  				o := struct{ Val float32 }{Val: 1.1}
   721  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   722  			})
   723  		})
   724  
   725  		t.Run("double", func(t *testing.T) {
   726  			t.Run("float64 go type", func(t *testing.T) {
   727  				o := struct{ Val float64 }{Val: 1.1}
   728  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   729  			})
   730  		})
   731  
   732  		t.Run("boolean", func(t *testing.T) {
   733  			t.Run("bool go type", func(t *testing.T) {
   734  				o := struct{ Val bool }{Val: true}
   735  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   736  			})
   737  		})
   738  
   739  		t.Run("time.Time", func(t *testing.T) {
   740  			t.Run("time.Time go type", func(t *testing.T) {
   741  				o := struct{ Val time.Time }{Val: time.Now().UTC()}
   742  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   743  			})
   744  		})
   745  
   746  		t.Run("groups", func(t *testing.T) {
   747  			t.Run("nested struct go type", func(t *testing.T) {
   748  				type child struct{ Val int64 }
   749  				type parent struct{ Child child }
   750  				o := parent{child{1}}
   751  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   752  			})
   753  
   754  			t.Run("slice go type", func(t *testing.T) {
   755  				o := struct{ Val []int64 }{Val: []int64{1}}
   756  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   757  			})
   758  
   759  			t.Run("map go type", func(t *testing.T) {
   760  				o := struct{ Val map[int64]int64 }{Val: map[int64]int64{1: 1}}
   761  				assert.EqualValues(t, o, writeReadOneWithAutoSchema(t, o))
   762  			})
   763  		})
   764  	})
   765  }
   766  
   767  func TestReflectMarshallerPanicIssue13(t *testing.T) {
   768  	_ = os.Mkdir("files", 0755)
   769  
   770  	write := func(filename string, obj interface{}) {
   771  		schemaDef, err := parquetschema.ParseSchemaDefinition(`message test { required int32 foo; }`)
   772  		require.NoError(t, err)
   773  		fw, err := NewFileWriter(filename,
   774  			goparquet.WithSchemaDefinition(schemaDef),
   775  			goparquet.WithCompressionCodec(parquet.CompressionCodec_SNAPPY),
   776  		)
   777  		require.NoError(t, err)
   778  		require.NoError(t, fw.Write(obj))
   779  		require.NoError(t, fw.Close())
   780  	}
   781  
   782  	write("files/issue13_bool.parquet", struct{ Bar bool }{Bar: true})
   783  	write("files/issue13_byteslice.parquet", struct{ Bar []byte }{Bar: []byte{0xFF, 0x0A}})
   784  }