UDF problem with maps

Hello, i want to do some operation on maps with a UDF. I want to do some nested map merging with a user passed map. However, the map that i am passing from the client to the UDF says it is of type userdata and value null. It is unclear to me what to do about that. I want to use the merge method on maps with this userdata type. And i am 100% sure it is not null because i am hardcoding it from the client side.

UDF

function map_merge(rec, old_bin, new_bin, identifiers)
    old_bin_type = type(old_bin)
    new_bin_type = type(new_bin)
    --ident_type = type(identifiers)

    assert(old_bin_type == 'number', 'old_bin should be a number, ' .. old_bin_type .. ' given')
    assert( new_bin_type == 'number', 'new_bin should be a number, ' .. new_bin_type .. ' given')
    --assert(ident_type == 'map', 'identifiers should be a map, ' .. ident_type .. ' given' )

    local ret = map()
    if not aerospike:exists(rec) then
        ret['status'] = 'RECORD DOES NOT EXIST'
        return ret
    end

    names = record.bin_names(rec)
    exists = false

    for i, name in ipairs(names) do
        if name == old_bin then
            exists = true
            break
        end
    end

    if not exists then
        ret['status'] = 'old_bin(' .. tostring(old_bin) .. ') does not exist'
    end


    local idents = identifiers.pairs()
    local new_list = map.merge(rec[old_bin], idents)
    rec[new_bin] = new_list

    return ret
end

Client

let res = client
        .execute_udf(
            &WritePolicy::default(),
            &key,
            "map_merge",
            "map_merge",
            Some(&[
                old_bin,
                Value::Int(now.timestamp()),
                Value::HashMap(val_map),
            ]),
        )
        .await;

Response

  UdfBadResponse(
            "/opt/aerospike/usr/udf/lua/map_merge.lua:31: attempt to call field 'pairs' (a nil value)",
        ),

In addition, i’ve printed the object metadata.

function print_type(identifiers)
    mt = getmetatable(identifiers)
    return tostring(mt)
end
"table: 0x41290fb0"

Hi @Petar_Dambovaliev, it looks like you are trying to assign the iterator function from map.pairs(m: Map) to idents and then trying to merge that as a map with rec[old_bin]. Have you had a look at the map section of the UDF API docs?

@aanderson I have sense fixed that mistake. However, i faced other issues. The nested map in a record wouldn’t update because of whatever reason. Then i found this and it worked but it is super weird. Is it a language weirdness or it comes from the aerospike types? In any case, aerospike should come up with some pattern for it or encapsulate it somehow and document it, so it is easier for people to use.

Also, a lot of details are missing from the documentation. In the client, you specify map ordering. In the UDFs, you don’t. How does that work? It is unclear.

Not sure I understand the map ordering point. Is this about the order of the map that can be set through the set_type operation?

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.