Skip to content

Commit

Permalink
Fixed booleans parsing when returned as int (#267)
Browse files Browse the repository at this point in the history
  • Loading branch information
AsafMah authored Sep 9, 2024
1 parent 6536611 commit 7ccd4f2
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed
- Proper parsing of booleans for rare cases where the values are returned as integers.

## [1.0.0-preview-4] - 2024-08-27
### Changed
- the `WithApplicationCertificate` on `KustoConnectionStringBuilder` was removed as it was ambiguous and not implemented correctly. Instead there are two new methods:
Expand Down
32 changes: 32 additions & 0 deletions azkustodata/query/v1/dataset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,35 @@ func TestDatasetPartialErrors(t *testing.T) {
assert.Nil(t, ds)
assert.ErrorContains(t, err, "Query execution has exceeded the allowed limits")
}

func TestBoolAsInt(t *testing.T) {
t.Parallel()

reader := io.NopCloser(strings.NewReader(booleanIntFile))
ctx := context.Background()
op := errors.OpQuery
ds, err := NewDatasetFromReader(ctx, op, reader)
assert.NoError(t, err)

rows := ds.Tables()[0].Rows()

falseBool, err := rows[0].BoolByIndex(0)
assert.NoError(t, err)
assert.Equal(t, *falseBool, false)

falseInt, err := rows[1].BoolByIndex(0)
assert.NoError(t, err)
assert.Equal(t, *falseInt, false)

trueBool, err := rows[2].BoolByIndex(0)
assert.NoError(t, err)
assert.Equal(t, *trueBool, true)

trueInt, err := rows[3].BoolByIndex(0)
assert.NoError(t, err)
assert.Equal(t, *trueInt, true)

nullBool, err := rows[4].BoolByIndex(0)
assert.NoError(t, err)
assert.Nil(t, nullBool)
}
3 changes: 3 additions & 0 deletions azkustodata/query/v1/decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ var partialErrorFile string
//go:embed testData/error.txt
var errorFile string

//go:embed testData/booleanInt.json
var booleanIntFile string

func TestDecodeSuccess(t *testing.T) {
t.Parallel()

Expand Down
31 changes: 31 additions & 0 deletions azkustodata/query/v1/testData/booleanInt.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"Tables": [
{
"TableName": "Table_0",
"Columns": [
{
"ColumnName": "a",
"DataType": "Boolean",
"ColumnType": "bool"
}
],
"Rows": [
[
false
],
[
0
],
[
true
],
[
1
],
[
null
]
]
}
]
}
30 changes: 30 additions & 0 deletions azkustodata/value/bool.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package value

import (
"encoding/json"
"fmt"
"github.com/Azure/azure-kusto-go/azkustodata/types"
"reflect"
)
Expand All @@ -23,6 +25,34 @@ func (bo *Bool) Convert(v reflect.Value) error {
return Convert[bool](*bo, &bo.pointerValue, v)
}

func (bo *Bool) Unmarshal(i interface{}) error {
if i == nil {
bo.value = nil
return nil
}

// Boolean may sometimes be represented as an integer, 0 means false, 1 means true.
if num, ok := i.(json.Number); ok {
num, err := num.Int64()
if err != nil {
return parseError(bo, i, err)
}

bo.value = new(bool)

if num == 0 {
*bo.value = false
} else if num == 1 {
*bo.value = true
} else {
return parseError(bo, i, fmt.Errorf("expected 0 or 1, got %d", num))
}
return nil
}

return bo.pointerValue.Unmarshal(i)
}

// GetType returns the type of the value.
func (bo *Bool) GetType() types.Column {
return types.Bool
Expand Down

0 comments on commit 7ccd4f2

Please sign in to comment.