Float64 not supported


#1

I have a payload generated from PHP and sent to GO which gets imported to Aerospike.

Here is an example:

PHP:

$p_data['tracking_lander_url_string_' . $nugget['lander_id']] = array(
	'chn_viewport' => (string)$nugget['options']['change_viewport'],
	'viewport_text' => $nugget['options']['change_viewport_text'],
	'spintax' => array(),
	'last_update' => date("Y-m-d H:i:s")
);

So I am casting an integer as a string. I have to do this as I get a panic with go:

map[chn_viewport:0 viewport_text:,,, spintax:[] last_update:2015-08-26 10:43:46]
panic: Value type 'float64' not supported

Why is the go code in value.go failing to detect as an int64?

Thanks


#2

Do you encounter this while reading from the database, or writing?

Can you provide a small code snippet to show me what you are trying to do?


#3

I’m writing to the database.

Go receives json as the payload and then processes it into aerospike.

The code is pretty trivial:

type Record struct {
	Bin     string                 `json:"bin"`
	Table   string                 `json:"table"`
	DataRaw map[string]interface{} `json:"data"`
}

func process(client *as.Client, payload string) {
	var jsonData Record
	json.Unmarshal([]byte(payload), &jsonData)

	for _key := range jsonData.DataRaw {
		i := jsonData.DataRaw[_key]
		m := i.(map[string]interface{})

		key, _ := as.NewKey(jsonData.Bin, jsonData.Table, _key)
		err := client.Put(nil, key, m)

		if err != nil {
			fmt.Println(_key)
			fmt.Println(m)

			panic(err)
		}
	}
}

#4

float32 and float64 can be used in maps and arrays (there are tests in client_test.go regarding that)

I assume you are passing a direct float value to Put. The code you’ve posted runs just fine on my system.

Are you sure this is the place you are getting your panic?


#5

I’m passing a map to Put. As you can see, I’m just converting the interface to a map.

I don’t know if in the conversion it will define the types correctly. The payload I am generating at php is HUGE. There is no way I am going to loop through everything sub-object and define it. It’s too dynamic in nature.

This is the place for the panic, because if I remove the (string) cast at php for the integer, I get the same panic.

Also:

I only panic when the map is like this:

{ "foo" : 0, "a" : "a", "b" : "b", "c" : "c" }

This does not panic:

{ "bar" : {"foo" : 0, "a" : "a", "b" : "b", "c" : "c" } }

#6

Your maps work without an error. Here’s another example with explicit float values which also works perfectly well:

package main

import (
    "flag"
    "fmt"
    "log"

    as "github.com/aerospike/aerospike-client-go"
)

var host = flag.String("h", "127.0.0.1", "host")
var port = flag.Int("p", 3000, "port")
var user = flag.String("U", "", "User.")
var password = flag.String("P", "", "Password.")
var clientPolicy *as.ClientPolicy

func main() {
    flag.Parse()
    clientPolicy = as.NewClientPolicy()
    if *user != "" {
        clientPolicy.User = *user
        clientPolicy.Password = *password
    }

    client, err := as.NewClientWithPolicyAndHost(clientPolicy, as.NewHost(*host, *port))
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    // m := map[string]interface{}{"foo": 0, "a": "a", "b": "b", "c": "c"}
    // m := map[string]interface{}{"bar": map[string]interface{}{"foo": 0, "a": "a", "b": "b", "c": "c"}}
    m := map[string]interface{}{"bar": map[string]interface{}{"foo": float32(0.11), "foo2": float64(0.11), "a": "a", "b": "b", "c": "c"}}

    key, _ := as.NewKey("test", "test", 1)
    err = client.Put(nil, key, m)
    if err != nil {
        fmt.Println(m)

        panic(err)
    }

    rec, err := client.Get(nil, key)
    if err != nil {
        panic(err)
    }

    fmt.Printf("map is: %#v\n", rec.Bins)

    fmt.Println("Success...")
}

#7

Now I see, you are iterating over the Record.DataRaw, and assume you are getting a map[string]map[string]interface{}.

When you pass { "foo" : 0, "a" : "a", "b" : "b", "c" : "c" } as payload, it will be decoded as map[string]interface{}, and will panic when you try to cast elements like 0 or "c" into map[string]interface{}.


#8

Thanks for the explanation. Now I understand.

I’ll just keep my code as normal. I’ll cast things as a string, as I’m getting it from PHP.