github.com/apache/arrow/go/v14@v14.0.1/arrow/example_test.go (about)

     1  // Licensed to the Apache Software Foundation (ASF) under one
     2  // or more contributor license agreements.  See the NOTICE file
     3  // distributed with this work for additional information
     4  // regarding copyright ownership.  The ASF licenses this file
     5  // to you under the Apache License, Version 2.0 (the
     6  // "License"); you may not use this file except in compliance
     7  // with the License.  You may obtain a copy of the License at
     8  //
     9  // http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  
    17  package arrow_test
    18  
    19  import (
    20  	"fmt"
    21  	"log"
    22  
    23  	"github.com/apache/arrow/go/v14/arrow"
    24  	"github.com/apache/arrow/go/v14/arrow/array"
    25  	"github.com/apache/arrow/go/v14/arrow/memory"
    26  	"github.com/apache/arrow/go/v14/arrow/tensor"
    27  )
    28  
    29  // This example demonstrates how to build an array of int64 values using a builder and Append.
    30  // Whilst convenient for small arrays,
    31  func Example_minimal() {
    32  	// Create an allocator.
    33  	pool := memory.NewGoAllocator()
    34  
    35  	// Create an int64 array builder.
    36  	builder := array.NewInt64Builder(pool)
    37  	defer builder.Release()
    38  
    39  	builder.Append(1)
    40  	builder.Append(2)
    41  	builder.Append(3)
    42  	builder.AppendNull()
    43  	builder.Append(5)
    44  	builder.Append(6)
    45  	builder.Append(7)
    46  	builder.Append(8)
    47  
    48  	// Finish building the int64 array and reset the builder.
    49  	ints := builder.NewInt64Array()
    50  	defer ints.Release()
    51  
    52  	// Enumerate the values.
    53  	for i, v := range ints.Int64Values() {
    54  		fmt.Printf("ints[%d] = ", i)
    55  		if ints.IsNull(i) {
    56  			fmt.Println(array.NullValueStr)
    57  		} else {
    58  			fmt.Println(v)
    59  		}
    60  	}
    61  	fmt.Printf("ints = %v\n", ints)
    62  
    63  	// Output:
    64  	// ints[0] = 1
    65  	// ints[1] = 2
    66  	// ints[2] = 3
    67  	// ints[3] = (null)
    68  	// ints[4] = 5
    69  	// ints[5] = 6
    70  	// ints[6] = 7
    71  	// ints[7] = 8
    72  	// ints = [1 2 3 (null) 5 6 7 8]
    73  }
    74  
    75  // This example demonstrates creating an array, sourcing the values and
    76  // null bitmaps directly from byte slices. The null count is set to
    77  // UnknownNullCount, instructing the array to calculate the
    78  // null count from the bitmap when NullN is called.
    79  func Example_fromMemory() {
    80  	// create LSB packed bits with the following pattern:
    81  	// 01010011 11000101
    82  	data := memory.NewBufferBytes([]byte{0xca, 0xa3})
    83  
    84  	// create LSB packed validity (null) bitmap, where every 4th element is null:
    85  	// 11101110 11101110
    86  	nullBitmap := memory.NewBufferBytes([]byte{0x77, 0x77})
    87  
    88  	// Create a boolean array and lazily determine NullN using UnknownNullCount
    89  	bools := array.NewBoolean(16, data, nullBitmap, array.UnknownNullCount)
    90  	defer bools.Release()
    91  
    92  	// Show the null count
    93  	fmt.Printf("NullN()  = %d\n", bools.NullN())
    94  
    95  	// Enumerate the values.
    96  	n := bools.Len()
    97  	for i := 0; i < n; i++ {
    98  		fmt.Printf("bools[%d] = ", i)
    99  		if bools.IsNull(i) {
   100  			fmt.Println(array.NullValueStr)
   101  		} else {
   102  			fmt.Printf("%t\n", bools.Value(i))
   103  		}
   104  	}
   105  
   106  	// Output:
   107  	// NullN()  = 4
   108  	// bools[0] = false
   109  	// bools[1] = true
   110  	// bools[2] = false
   111  	// bools[3] = (null)
   112  	// bools[4] = false
   113  	// bools[5] = false
   114  	// bools[6] = true
   115  	// bools[7] = (null)
   116  	// bools[8] = true
   117  	// bools[9] = true
   118  	// bools[10] = false
   119  	// bools[11] = (null)
   120  	// bools[12] = false
   121  	// bools[13] = true
   122  	// bools[14] = false
   123  	// bools[15] = (null)
   124  }
   125  
   126  // This example shows how to create a List array.
   127  // The resulting array should be:
   128  //
   129  //	[[0, 1, 2], [], [3], [4, 5], [6, 7, 8], [], [9]]
   130  func Example_listArray() {
   131  	pool := memory.NewGoAllocator()
   132  
   133  	lb := array.NewListBuilder(pool, arrow.PrimitiveTypes.Int64)
   134  	defer lb.Release()
   135  
   136  	vb := lb.ValueBuilder().(*array.Int64Builder)
   137  	vb.Reserve(10)
   138  
   139  	lb.Append(true)
   140  	vb.Append(0)
   141  	vb.Append(1)
   142  	vb.Append(2)
   143  
   144  	lb.AppendNull()
   145  
   146  	lb.Append(true)
   147  	vb.Append(3)
   148  
   149  	lb.Append(true)
   150  	vb.Append(4)
   151  	vb.Append(5)
   152  
   153  	lb.Append(true)
   154  	vb.Append(6)
   155  	vb.Append(7)
   156  	vb.Append(8)
   157  
   158  	lb.AppendNull()
   159  
   160  	lb.Append(true)
   161  	vb.Append(9)
   162  
   163  	arr := lb.NewArray().(*array.List)
   164  	defer arr.Release()
   165  
   166  	arr.DataType().(*arrow.ListType).SetElemNullable(false)
   167  	fmt.Printf("NullN()   = %d\n", arr.NullN())
   168  	fmt.Printf("Len()     = %d\n", arr.Len())
   169  	fmt.Printf("Offsets() = %v\n", arr.Offsets())
   170  	fmt.Printf("Type()    = %v\n", arr.DataType())
   171  
   172  	offsets := arr.Offsets()[1:]
   173  
   174  	varr := arr.ListValues().(*array.Int64)
   175  
   176  	pos := 0
   177  	for i := 0; i < arr.Len(); i++ {
   178  		if !arr.IsValid(i) {
   179  			fmt.Printf("List[%d]   = (null)\n", i)
   180  			continue
   181  		}
   182  		fmt.Printf("List[%d]   = [", i)
   183  		for j := pos; j < int(offsets[i]); j++ {
   184  			if j != pos {
   185  				fmt.Printf(", ")
   186  			}
   187  			fmt.Printf("%v", varr.Value(j))
   188  		}
   189  		pos = int(offsets[i])
   190  		fmt.Printf("]\n")
   191  	}
   192  	fmt.Printf("List      = %v\n", arr)
   193  
   194  	// Output:
   195  	// NullN()   = 2
   196  	// Len()     = 7
   197  	// Offsets() = [0 3 3 4 6 9 9 10]
   198  	// Type()    = list<item: int64>
   199  	// List[0]   = [0, 1, 2]
   200  	// List[1]   = (null)
   201  	// List[2]   = [3]
   202  	// List[3]   = [4, 5]
   203  	// List[4]   = [6, 7, 8]
   204  	// List[5]   = (null)
   205  	// List[6]   = [9]
   206  	// List      = [[0 1 2] (null) [3] [4 5] [6 7 8] (null) [9]]
   207  }
   208  
   209  // This example shows how to create a FixedSizeList array.
   210  // The resulting array should be:
   211  //
   212  //	[[0, 1, 2], (null), [3, 4, 5], [6, 7, 8], (null)]
   213  func Example_fixedSizeListArray() {
   214  	pool := memory.NewGoAllocator()
   215  
   216  	lb := array.NewFixedSizeListBuilder(pool, 3, arrow.PrimitiveTypes.Int64)
   217  	defer lb.Release()
   218  
   219  	vb := lb.ValueBuilder().(*array.Int64Builder)
   220  	vb.Reserve(10)
   221  
   222  	lb.Append(true)
   223  	vb.Append(0)
   224  	vb.Append(1)
   225  	vb.Append(2)
   226  
   227  	lb.AppendNull()
   228  
   229  	lb.Append(true)
   230  	vb.Append(3)
   231  	vb.Append(4)
   232  	vb.Append(5)
   233  
   234  	lb.Append(true)
   235  	vb.Append(6)
   236  	vb.Append(7)
   237  	vb.Append(8)
   238  
   239  	lb.AppendNull()
   240  
   241  	arr := lb.NewArray().(*array.FixedSizeList)
   242  	arr.DataType().(*arrow.FixedSizeListType).SetElemNullable(false)
   243  	defer arr.Release()
   244  
   245  	fmt.Printf("NullN()   = %d\n", arr.NullN())
   246  	fmt.Printf("Len()     = %d\n", arr.Len())
   247  	fmt.Printf("Type()    = %v\n", arr.DataType())
   248  	fmt.Printf("List      = %v\n", arr)
   249  
   250  	// Output:
   251  	// NullN()   = 2
   252  	// Len()     = 5
   253  	// Type()    = fixed_size_list<item: int64>[3]
   254  	// List      = [[0 1 2] (null) [3 4 5] [6 7 8] (null)]
   255  }
   256  
   257  // This example shows how to create a Struct array.
   258  // The resulting array should be:
   259  //
   260  //	[{‘joe’, 1}, {null, 2}, null, {‘mark’, 4}]
   261  func Example_structArray() {
   262  	pool := memory.NewGoAllocator()
   263  
   264  	dtype := arrow.StructOf([]arrow.Field{
   265  		{Name: "f1", Type: arrow.ListOf(arrow.PrimitiveTypes.Uint8)},
   266  		{Name: "f2", Type: arrow.PrimitiveTypes.Int32},
   267  	}...)
   268  
   269  	sb := array.NewStructBuilder(pool, dtype)
   270  	defer sb.Release()
   271  
   272  	f1b := sb.FieldBuilder(0).(*array.ListBuilder)
   273  	f1vb := f1b.ValueBuilder().(*array.Uint8Builder)
   274  	f2b := sb.FieldBuilder(1).(*array.Int32Builder)
   275  
   276  	sb.Reserve(4)
   277  	f1vb.Reserve(7)
   278  	f2b.Reserve(3)
   279  
   280  	sb.Append(true)
   281  	f1b.Append(true)
   282  	f1vb.AppendValues([]byte("joe"), nil)
   283  	f2b.Append(1)
   284  
   285  	sb.Append(true)
   286  	f1b.AppendNull()
   287  	f2b.Append(2)
   288  
   289  	sb.AppendNull()
   290  
   291  	sb.Append(true)
   292  	f1b.Append(true)
   293  	f1vb.AppendValues([]byte("mark"), nil)
   294  	f2b.Append(4)
   295  
   296  	arr := sb.NewArray().(*array.Struct)
   297  	defer arr.Release()
   298  
   299  	fmt.Printf("NullN() = %d\n", arr.NullN())
   300  	fmt.Printf("Len()   = %d\n", arr.Len())
   301  	fmt.Printf("Type()    = %v\n", arr.DataType())
   302  
   303  	list := arr.Field(0).(*array.List)
   304  	offsets := list.Offsets()
   305  
   306  	varr := list.ListValues().(*array.Uint8)
   307  	ints := arr.Field(1).(*array.Int32)
   308  
   309  	for i := 0; i < arr.Len(); i++ {
   310  		if !arr.IsValid(i) {
   311  			fmt.Printf("Struct[%d] = (null)\n", i)
   312  			continue
   313  		}
   314  		fmt.Printf("Struct[%d] = [", i)
   315  		pos := int(offsets[i])
   316  		switch {
   317  		case list.IsValid(pos):
   318  			fmt.Printf("[")
   319  			for j := offsets[i]; j < offsets[i+1]; j++ {
   320  				if j != offsets[i] {
   321  					fmt.Printf(", ")
   322  				}
   323  				fmt.Printf("%v", string(varr.Value(int(j))))
   324  			}
   325  			fmt.Printf("], ")
   326  		default:
   327  			fmt.Printf("(null), ")
   328  		}
   329  		fmt.Printf("%d]\n", ints.Value(i))
   330  	}
   331  
   332  	// Output:
   333  	// NullN() = 1
   334  	// Len()   = 4
   335  	// Type()    = struct<f1: list<item: uint8, nullable>, f2: int32>
   336  	// Struct[0] = [[j, o, e], 1]
   337  	// Struct[1] = [[], 2]
   338  	// Struct[2] = (null)
   339  	// Struct[3] = [[m, a, r, k], 4]
   340  }
   341  
   342  // This example shows how one can slice an array.
   343  // The initial (float64) array is:
   344  //
   345  //	[1, 2, 3, (null), 4, 5]
   346  //
   347  // and the sub-slice is:
   348  //
   349  //	[3, (null), 4]
   350  func Example_float64Slice() {
   351  	pool := memory.NewGoAllocator()
   352  
   353  	b := array.NewFloat64Builder(pool)
   354  	defer b.Release()
   355  
   356  	b.AppendValues(
   357  		[]float64{1, 2, 3, -1, 4, 5},
   358  		[]bool{true, true, true, false, true, true},
   359  	)
   360  
   361  	arr := b.NewFloat64Array()
   362  	defer arr.Release()
   363  
   364  	fmt.Printf("array = %v\n", arr)
   365  
   366  	sli := array.NewSlice(arr, 2, 5).(*array.Float64)
   367  	defer sli.Release()
   368  
   369  	fmt.Printf("slice = %v\n", sli)
   370  
   371  	// Output:
   372  	// array = [1 2 3 (null) 4 5]
   373  	// slice = [3 (null) 4]
   374  }
   375  
   376  func Example_float64Tensor2x5() {
   377  	pool := memory.NewGoAllocator()
   378  
   379  	b := array.NewFloat64Builder(pool)
   380  	defer b.Release()
   381  
   382  	raw := []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
   383  	b.AppendValues(raw, nil)
   384  
   385  	arr := b.NewFloat64Array()
   386  	defer arr.Release()
   387  
   388  	f64 := tensor.NewFloat64(arr.Data(), []int64{2, 5}, nil, []string{"x", "y"})
   389  	defer f64.Release()
   390  
   391  	for _, i := range [][]int64{
   392  		{0, 0},
   393  		{0, 1},
   394  		{0, 2},
   395  		{0, 3},
   396  		{0, 4},
   397  		{1, 0},
   398  		{1, 1},
   399  		{1, 2},
   400  		{1, 3},
   401  		{1, 4},
   402  	} {
   403  		fmt.Printf("arr%v = %v\n", i, f64.Value(i))
   404  	}
   405  
   406  	// Output:
   407  	// arr[0 0] = 1
   408  	// arr[0 1] = 2
   409  	// arr[0 2] = 3
   410  	// arr[0 3] = 4
   411  	// arr[0 4] = 5
   412  	// arr[1 0] = 6
   413  	// arr[1 1] = 7
   414  	// arr[1 2] = 8
   415  	// arr[1 3] = 9
   416  	// arr[1 4] = 10
   417  }
   418  
   419  func Example_float64Tensor2x5ColMajor() {
   420  	pool := memory.NewGoAllocator()
   421  
   422  	b := array.NewFloat64Builder(pool)
   423  	defer b.Release()
   424  
   425  	raw := []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
   426  	b.AppendValues(raw, nil)
   427  
   428  	arr := b.NewFloat64Array()
   429  	defer arr.Release()
   430  
   431  	f64 := tensor.NewFloat64(arr.Data(), []int64{2, 5}, []int64{8, 16}, []string{"x", "y"})
   432  	defer f64.Release()
   433  
   434  	for _, i := range [][]int64{
   435  		{0, 0},
   436  		{0, 1},
   437  		{0, 2},
   438  		{0, 3},
   439  		{0, 4},
   440  		{1, 0},
   441  		{1, 1},
   442  		{1, 2},
   443  		{1, 3},
   444  		{1, 4},
   445  	} {
   446  		fmt.Printf("arr%v = %v\n", i, f64.Value(i))
   447  	}
   448  
   449  	// Output:
   450  	// arr[0 0] = 1
   451  	// arr[0 1] = 3
   452  	// arr[0 2] = 5
   453  	// arr[0 3] = 7
   454  	// arr[0 4] = 9
   455  	// arr[1 0] = 2
   456  	// arr[1 1] = 4
   457  	// arr[1 2] = 6
   458  	// arr[1 3] = 8
   459  	// arr[1 4] = 10
   460  }
   461  
   462  func Example_record() {
   463  	pool := memory.NewGoAllocator()
   464  
   465  	schema := arrow.NewSchema(
   466  		[]arrow.Field{
   467  			{Name: "f1-i32", Type: arrow.PrimitiveTypes.Int32},
   468  			{Name: "f2-f64", Type: arrow.PrimitiveTypes.Float64},
   469  		},
   470  		nil,
   471  	)
   472  
   473  	b := array.NewRecordBuilder(pool, schema)
   474  	defer b.Release()
   475  
   476  	b.Field(0).(*array.Int32Builder).AppendValues([]int32{1, 2, 3, 4, 5, 6}, nil)
   477  	b.Field(0).(*array.Int32Builder).AppendValues([]int32{7, 8, 9, 10}, []bool{true, true, false, true})
   478  	b.Field(1).(*array.Float64Builder).AppendValues([]float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, nil)
   479  
   480  	rec := b.NewRecord()
   481  	defer rec.Release()
   482  
   483  	for i, col := range rec.Columns() {
   484  		fmt.Printf("column[%d] %q: %v\n", i, rec.ColumnName(i), col)
   485  	}
   486  
   487  	// Output:
   488  	// column[0] "f1-i32": [1 2 3 4 5 6 7 8 (null) 10]
   489  	// column[1] "f2-f64": [1 2 3 4 5 6 7 8 9 10]
   490  }
   491  
   492  func Example_recordReader() {
   493  	pool := memory.NewGoAllocator()
   494  
   495  	schema := arrow.NewSchema(
   496  		[]arrow.Field{
   497  			{Name: "f1-i32", Type: arrow.PrimitiveTypes.Int32},
   498  			{Name: "f2-f64", Type: arrow.PrimitiveTypes.Float64},
   499  		},
   500  		nil,
   501  	)
   502  
   503  	b := array.NewRecordBuilder(pool, schema)
   504  	defer b.Release()
   505  
   506  	b.Field(0).(*array.Int32Builder).AppendValues([]int32{1, 2, 3, 4, 5, 6}, nil)
   507  	b.Field(0).(*array.Int32Builder).AppendValues([]int32{7, 8, 9, 10}, []bool{true, true, false, true})
   508  	b.Field(1).(*array.Float64Builder).AppendValues([]float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, nil)
   509  
   510  	rec1 := b.NewRecord()
   511  	defer rec1.Release()
   512  
   513  	b.Field(0).(*array.Int32Builder).AppendValues([]int32{11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, nil)
   514  	b.Field(1).(*array.Float64Builder).AppendValues([]float64{11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, nil)
   515  
   516  	rec2 := b.NewRecord()
   517  	defer rec2.Release()
   518  
   519  	itr, err := array.NewRecordReader(schema, []arrow.Record{rec1, rec2})
   520  	if err != nil {
   521  		log.Fatal(err)
   522  	}
   523  	defer itr.Release()
   524  
   525  	n := 0
   526  	for itr.Next() {
   527  		rec := itr.Record()
   528  		for i, col := range rec.Columns() {
   529  			fmt.Printf("rec[%d][%q]: %v\n", n, rec.ColumnName(i), col)
   530  		}
   531  		n++
   532  	}
   533  
   534  	// Output:
   535  	// rec[0]["f1-i32"]: [1 2 3 4 5 6 7 8 (null) 10]
   536  	// rec[0]["f2-f64"]: [1 2 3 4 5 6 7 8 9 10]
   537  	// rec[1]["f1-i32"]: [11 12 13 14 15 16 17 18 19 20]
   538  	// rec[1]["f2-f64"]: [11 12 13 14 15 16 17 18 19 20]
   539  }
   540  
   541  func Example_table() {
   542  	pool := memory.NewGoAllocator()
   543  
   544  	schema := arrow.NewSchema(
   545  		[]arrow.Field{
   546  			{Name: "f1-i32", Type: arrow.PrimitiveTypes.Int32},
   547  			{Name: "f2-f64", Type: arrow.PrimitiveTypes.Float64},
   548  		},
   549  		nil,
   550  	)
   551  
   552  	b := array.NewRecordBuilder(pool, schema)
   553  	defer b.Release()
   554  
   555  	b.Field(0).(*array.Int32Builder).AppendValues([]int32{1, 2, 3, 4, 5, 6}, nil)
   556  	b.Field(0).(*array.Int32Builder).AppendValues([]int32{7, 8, 9, 10}, []bool{true, true, false, true})
   557  	b.Field(1).(*array.Float64Builder).AppendValues([]float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, nil)
   558  
   559  	rec1 := b.NewRecord()
   560  	defer rec1.Release()
   561  
   562  	b.Field(0).(*array.Int32Builder).AppendValues([]int32{11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, nil)
   563  	b.Field(1).(*array.Float64Builder).AppendValues([]float64{11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, nil)
   564  
   565  	rec2 := b.NewRecord()
   566  	defer rec2.Release()
   567  
   568  	tbl := array.NewTableFromRecords(schema, []arrow.Record{rec1, rec2})
   569  	defer tbl.Release()
   570  
   571  	tr := array.NewTableReader(tbl, 5)
   572  	defer tr.Release()
   573  
   574  	n := 0
   575  	for tr.Next() {
   576  		rec := tr.Record()
   577  		for i, col := range rec.Columns() {
   578  			fmt.Printf("rec[%d][%q]: %v\n", n, rec.ColumnName(i), col)
   579  		}
   580  		n++
   581  	}
   582  
   583  	// Output:
   584  	// rec[0]["f1-i32"]: [1 2 3 4 5]
   585  	// rec[0]["f2-f64"]: [1 2 3 4 5]
   586  	// rec[1]["f1-i32"]: [6 7 8 (null) 10]
   587  	// rec[1]["f2-f64"]: [6 7 8 9 10]
   588  	// rec[2]["f1-i32"]: [11 12 13 14 15]
   589  	// rec[2]["f2-f64"]: [11 12 13 14 15]
   590  	// rec[3]["f1-i32"]: [16 17 18 19 20]
   591  	// rec[3]["f2-f64"]: [16 17 18 19 20]
   592  }
   593  
   594  // This example demonstrates how to create a Map Array.
   595  // The resulting array should be:
   596  //
   597  //	[{["ab" "cd" "ef" "gh"] [1 2 3 4]} (null) {["ab" "cd" "ef" "gh"] [(null) 2 5 1]}]
   598  func Example_mapArray() {
   599  	pool := memory.NewGoAllocator()
   600  	mb := array.NewMapBuilder(pool, arrow.BinaryTypes.String, arrow.PrimitiveTypes.Int16, false)
   601  	defer mb.Release()
   602  
   603  	kb := mb.KeyBuilder().(*array.StringBuilder)
   604  	ib := mb.ItemBuilder().(*array.Int16Builder)
   605  
   606  	keys := []string{"ab", "cd", "ef", "gh"}
   607  
   608  	mb.Append(true)
   609  	kb.AppendValues(keys, nil)
   610  	ib.AppendValues([]int16{1, 2, 3, 4}, nil)
   611  
   612  	mb.AppendNull()
   613  
   614  	mb.Append(true)
   615  	kb.AppendValues(keys, nil)
   616  	ib.AppendValues([]int16{-1, 2, 5, 1}, []bool{false, true, true, true})
   617  
   618  	arr := mb.NewMapArray()
   619  	defer arr.Release()
   620  
   621  	fmt.Printf("NullN() = %d\n", arr.NullN())
   622  	fmt.Printf("Len()   = %d\n", arr.Len())
   623  
   624  	offsets := arr.Offsets()
   625  	keyArr := arr.Keys().(*array.String)
   626  	itemArr := arr.Items().(*array.Int16)
   627  
   628  	for i := 0; i < arr.Len(); i++ {
   629  		if arr.IsNull(i) {
   630  			fmt.Printf("Map[%d] = (null)\n", i)
   631  			continue
   632  		}
   633  
   634  		fmt.Printf("Map[%d] = {", i)
   635  		for j := offsets[i]; j < offsets[i+1]; j++ {
   636  			if j != offsets[i] {
   637  				fmt.Printf(", ")
   638  			}
   639  			fmt.Printf("%v => ", keyArr.Value(int(j)))
   640  			if itemArr.IsValid(int(j)) {
   641  				fmt.Printf("%v", itemArr.Value(int(j)))
   642  			} else {
   643  				fmt.Printf(array.NullValueStr)
   644  			}
   645  		}
   646  		fmt.Printf("}\n")
   647  	}
   648  	fmt.Printf("Map    = %v\n", arr)
   649  
   650  	// Output:
   651  	// NullN() = 1
   652  	// Len()   = 3
   653  	// Map[0] = {ab => 1, cd => 2, ef => 3, gh => 4}
   654  	// Map[1] = (null)
   655  	// Map[2] = {ab => (null), cd => 2, ef => 5, gh => 1}
   656  	// Map    = [{["ab" "cd" "ef" "gh"] [1 2 3 4]} (null) {["ab" "cd" "ef" "gh"] [(null) 2 5 1]}]
   657  }
   658  
   659  func Example_sparseUnionArray() {
   660  	pool := memory.NewGoAllocator()
   661  
   662  	sparseBuilder := array.NewEmptySparseUnionBuilder(pool)
   663  	defer sparseBuilder.Release()
   664  
   665  	i8Builder := array.NewInt8Builder(pool)
   666  	defer i8Builder.Release()
   667  	i8Code := sparseBuilder.AppendChild(i8Builder, "i8")
   668  
   669  	strBuilder := array.NewStringBuilder(pool)
   670  	defer strBuilder.Release()
   671  	strCode := sparseBuilder.AppendChild(strBuilder, "str")
   672  
   673  	f64Builder := array.NewFloat64Builder(pool)
   674  	defer f64Builder.Release()
   675  	f64Code := sparseBuilder.AppendChild(f64Builder, "f64")
   676  
   677  	values := []interface{}{int8(33), "abc", float64(1.0), float64(-1.0), nil,
   678  		"", int8(10), "def", int8(-10), float64(0.5)}
   679  
   680  	for _, v := range values {
   681  		switch v := v.(type) {
   682  		case int8:
   683  			sparseBuilder.Append(i8Code)
   684  			i8Builder.Append(v)
   685  			strBuilder.AppendEmptyValue()
   686  			f64Builder.AppendEmptyValue()
   687  		case string:
   688  			sparseBuilder.Append(strCode)
   689  			i8Builder.AppendEmptyValue()
   690  			strBuilder.Append(v)
   691  			f64Builder.AppendEmptyValue()
   692  		case float64:
   693  			sparseBuilder.Append(f64Code)
   694  			i8Builder.AppendEmptyValue()
   695  			strBuilder.AppendEmptyValue()
   696  			f64Builder.Append(v)
   697  		case nil:
   698  			sparseBuilder.AppendNull()
   699  		}
   700  	}
   701  
   702  	arr := sparseBuilder.NewSparseUnionArray()
   703  	defer arr.Release()
   704  
   705  	fmt.Printf("Len() = %d\n", arr.Len())
   706  	fields := arr.UnionType().Fields()
   707  	for i := 0; i < arr.Len(); i++ {
   708  		child := arr.ChildID(i)
   709  		data := arr.Field(child)
   710  		field := fields[child]
   711  
   712  		if data.IsNull(i) {
   713  			fmt.Printf("[%d]   = (null)\n", i)
   714  			continue
   715  		}
   716  		var v interface{}
   717  		switch varr := data.(type) {
   718  		case *array.Int8:
   719  			v = varr.Value(i)
   720  		case *array.String:
   721  			v = varr.Value(i)
   722  		case *array.Float64:
   723  			v = varr.Value(i)
   724  		}
   725  		fmt.Printf("[%d]   = %#5v {%s}\n", i, v, field.Name)
   726  	}
   727  
   728  	fmt.Printf("i8:  %s\n", arr.Field(0))
   729  	fmt.Printf("str: %s\n", arr.Field(1))
   730  	fmt.Printf("f64: %s\n", arr.Field(2))
   731  
   732  	// Output:
   733  	// Len() = 10
   734  	// [0]   =    33 {i8}
   735  	// [1]   = "abc" {str}
   736  	// [2]   =     1 {f64}
   737  	// [3]   =    -1 {f64}
   738  	// [4]   = (null)
   739  	// [5]   =    "" {str}
   740  	// [6]   =    10 {i8}
   741  	// [7]   = "def" {str}
   742  	// [8]   =   -10 {i8}
   743  	// [9]   =   0.5 {f64}
   744  	// i8:  [33 0 0 0 (null) 0 10 0 -10 0]
   745  	// str: ["" "abc" "" "" "" "" "" "def" "" ""]
   746  	// f64: [0 0 1 -1 0 0 0 0 0 0.5]
   747  }
   748  
   749  func Example_denseUnionArray() {
   750  	pool := memory.NewGoAllocator()
   751  
   752  	denseBuilder := array.NewEmptyDenseUnionBuilder(pool)
   753  	defer denseBuilder.Release()
   754  
   755  	i8Builder := array.NewInt8Builder(pool)
   756  	defer i8Builder.Release()
   757  	i8Code := denseBuilder.AppendChild(i8Builder, "i8")
   758  
   759  	strBuilder := array.NewStringBuilder(pool)
   760  	defer strBuilder.Release()
   761  	strCode := denseBuilder.AppendChild(strBuilder, "str")
   762  
   763  	f64Builder := array.NewFloat64Builder(pool)
   764  	defer f64Builder.Release()
   765  	f64Code := denseBuilder.AppendChild(f64Builder, "f64")
   766  
   767  	values := []interface{}{int8(33), "abc", float64(1.0), float64(-1.0), nil,
   768  		"", int8(10), "def", int8(-10), float64(0.5)}
   769  
   770  	for _, v := range values {
   771  		switch v := v.(type) {
   772  		case int8:
   773  			denseBuilder.Append(i8Code)
   774  			i8Builder.Append(v)
   775  		case string:
   776  			denseBuilder.Append(strCode)
   777  			strBuilder.Append(v)
   778  		case float64:
   779  			denseBuilder.Append(f64Code)
   780  			f64Builder.Append(v)
   781  		case nil:
   782  			denseBuilder.AppendNull()
   783  		}
   784  	}
   785  
   786  	arr := denseBuilder.NewDenseUnionArray()
   787  	defer arr.Release()
   788  
   789  	fmt.Printf("Len() = %d\n", arr.Len())
   790  	fields := arr.UnionType().Fields()
   791  	offsets := arr.RawValueOffsets()
   792  	for i := 0; i < arr.Len(); i++ {
   793  		child := arr.ChildID(i)
   794  		data := arr.Field(child)
   795  		field := fields[child]
   796  
   797  		idx := int(offsets[i])
   798  		if data.IsNull(idx) {
   799  			fmt.Printf("[%d]   = (null)\n", i)
   800  			continue
   801  		}
   802  		var v interface{}
   803  		switch varr := data.(type) {
   804  		case *array.Int8:
   805  			v = varr.Value(idx)
   806  		case *array.String:
   807  			v = varr.Value(idx)
   808  		case *array.Float64:
   809  			v = varr.Value(idx)
   810  		}
   811  		fmt.Printf("[%d]   = %#5v {%s}\n", i, v, field.Name)
   812  	}
   813  
   814  	fmt.Printf("i8:  %s\n", arr.Field(0))
   815  	fmt.Printf("str: %s\n", arr.Field(1))
   816  	fmt.Printf("f64: %s\n", arr.Field(2))
   817  
   818  	// Output:
   819  	// Len() = 10
   820  	// [0]   =    33 {i8}
   821  	// [1]   = "abc" {str}
   822  	// [2]   =     1 {f64}
   823  	// [3]   =    -1 {f64}
   824  	// [4]   = (null)
   825  	// [5]   =    "" {str}
   826  	// [6]   =    10 {i8}
   827  	// [7]   = "def" {str}
   828  	// [8]   =   -10 {i8}
   829  	// [9]   =   0.5 {f64}
   830  	// i8:  [33 (null) 10 -10]
   831  	// str: ["abc" "" "def"]
   832  	// f64: [1 -1 0.5]
   833  }