diff --git a/sql3/planner/opbulkinsert.go b/sql3/planner/opbulkinsert.go index fd0ebed2d..dd448ce3c 100644 --- a/sql3/planner/opbulkinsert.go +++ b/sql3/planner/opbulkinsert.go @@ -540,20 +540,32 @@ func (i *bulkInsertSourceNDJsonRowIter) Next(ctx context.Context) (types.Row, er case []interface{}: setValue := make([]int64, 0) for _, i := range v { - f, ok := i.(float64) - if !ok { - return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription()) - } - if f == float64(int64(f)) { - setValue = append(setValue, int64(f)) - } else { + switch v := i.(type) { + case float64: + if v == float64(int64(v)) { + setValue = append(setValue, int64(v)) + } else { + return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription()) + } + case string: + intVal, err := strconv.ParseInt(v, 10, 64) + if err != nil { + return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription()) + } + setValue = append(setValue, int64(intVal)) + + default: return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription()) } } result[idx] = setValue case string: - return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription()) + intVal, err := strconv.ParseInt(v, 10, 64) + if err != nil { + return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription()) + } + result[idx] = []int64{int64(intVal)} case bool: return nil, sql3.NewErrTypeConversionOnMap(0, 0, v, mapColumn.colType.TypeDescription()) diff --git a/sql3/sql_complex_test.go b/sql3/sql_complex_test.go index 0cf4ae162..65df947fd 100644 --- a/sql3/sql_complex_test.go +++ b/sql3/sql_complex_test.go @@ -1897,6 +1897,99 @@ func TestPlanner_BulkInsert(t *testing.T) { } }) + t.Run("BulkInsertNDJSONStringIDSet", func(t *testing.T) { + + _, _, err = sql_test.MustQueryRows(t, c.GetNode(0).Server, `create table greg-test-01 ( + _id STRING, + id_col ID, + string_col STRING cachetype ranked size 1000, + int_col int, + decimal_col DECIMAL(2), + bool_col BOOL + time_col TIMESTAMP, + stringset_col STRINGSET, + ideset_col IDSET + );`) + if err != nil { + t.Fatal(err) + } + + _, _, err = sql_test.MustQueryRows(t, c.GetNode(0).Server, `BULK INSERT INTO greg-test-01 ( + _id, + id_col, + string_col, + int_col, + decimal_col, + bool_col, + time_col, + stringset_col, + ideset_col) + map ( + 'id_col' ID, + 'string_col' STRING, + 'int_col' INT, + 'decimal_col' DECIMAL(2), + 'bool_col' BOOL, + 'time_col' TIMESTAMP, + 'stringset_col' STRINGSET, + 'ideset_col' IDSET) + transform( + @1, + @0, + @1, + @2, + @3, + @4, + @5, + @6, + @7) + FROM '{"id_col": "3", "string_col": "TEST", "int_col": "-123", "decimal_col": "1.12", "bool_col": false, "time_col": "2013-07-15T01:18:46Z", "stringset_col": "stringset1","ideset_col": "1"}' + with + BATCHSIZE 10000 + format 'NDJSON' + input 'STREAM';`) + if err != nil { + t.Fatal(err) + } + + _, _, err = sql_test.MustQueryRows(t, c.GetNode(0).Server, `BULK INSERT INTO greg-test-01 ( + _id, + id_col, + string_col, + int_col, + decimal_col, + bool_col, + time_col, + stringset_col, + ideset_col) + map ( + 'id_col' ID, + 'string_col' STRING, + 'int_col' INT, + 'decimal_col' DECIMAL(2), + 'bool_col' BOOL, + 'time_col' TIMESTAMP, + 'stringset_col' STRINGSET, + 'ideset_col' IDSET) + transform( + @1, + @0, + @1, + @2, + @3, + @4, + @5, + @6, + @7) + FROM '{"id_col": "3", "string_col": "TEST", "int_col": "-123", "decimal_col": "1.12", "bool_col": false, "time_col": "2013-07-15T01:18:46Z", "stringset_col": "stringset1","ideset_col": ["1","2"]}' + with + BATCHSIZE 10000 + format 'NDJSON' + input 'STREAM';`) + if err != nil { + t.Fatal(err) + } + }) } func TestPlanner_SelectSelectSource(t *testing.T) {