Float64 not supported

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

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?

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)
		}
	}
}

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?

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" } }

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...")
}

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{}.

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.