Forum: Building VoltDB Clients

Post: addBytes problem in C++ client program

addBytes problem in C++ client program
Mar 10, 2016
Now I'm trying to program a C++ program (modified from HellowWorld.cpp), to invoke default procedure of table ABC:

ID integer NOT NULL,
VALUE float,
QUALITY tinyint,
HIS varbinary(40),
TIME_STAMP timestamp,

my code just like below:
voltdb::ClientConfig config("","");
voltdb::Client client = voltdb::Client::create(config);

* Describe the stored procedure to be invoked
std::vector<voltdb::Parameter> parameterTypes(5);
parameterTypes[0] = voltdb::Parameter(voltdb::WIRE_TYPE_INTEGER);
parameterTypes[1] = voltdb::Parameter(voltdb::WIRE_TYPE_FLOAT);
parameterTypes[2] = voltdb::Parameter(voltdb::WIRE_TYPE_VARBINARY);
parameterTypes[3] = voltdb::Parameter(voltdb::WIRE_TYPE_TINYINT);
parameterTypes[4] = voltdb::Parameter(voltdb::WIRE_TYPE_TIMESTAMP);
voltdb::Procedure procedure("ABC.upsert", parameterTypes);

voltdb::InvocationResponse response;
* Load the database.
const uint8_t vars[40] = {1,1,1};
voltdb::ParameterSet* params = procedure.params();
params->addInt32(202).addDouble(55.55).addBytes(40, vars).addInt8(1).addTimestamp(1415289765);

response = client.invoke(procedure);
if (response.failure()) { std::cout << response.toString() << std::endl; return -1; }

When execute, error occurred:

Status: -2, VOLTDB ERROR: PROCEDURE ABC.upsert TYPE ERROR FOR PARAMETER 3: org.voltdb.VoltTypeException: Array / Scalar parameter mismatch (java.lang.Byte to [B)
App Status: -128,
Client Data: -9223372036854775610
Cluster Round Trip Time: 0

What's wrong with my program, thank you for your help.
Mar 12, 2016
The problem was settled. It's not caused by program, but running environment. I just run the program on another linux system with voltdb deployed then it run well.
Mar 22, 2016
Hi, this is Bill White from VoltDB.

It turns out that the wire protocol representation of VARBINARY and array of TINYINT are almost exactly identical. The only difference is in the type metadata. ARRAY OF TINYINT uses two bytes, one to tell that the value is an array and one to tell that the element type is TINYINT. VARBINARY uses one byte, with a special VARBINARY value. There is no way in Java to specify VARBINARY or ARRAY OF TINYINT though. There is just byte[] for both. So the Java client doesn't necessarily know the types of the values they are sending given only the value. Sometimes it chooses incorrectly. This is a bug which we are working through right now.

It's my understanding that both the C++ and Java clients turn array of byte (or array of char) to VARBINARY in the most recent release. So, I think you should be alright if you always use VARBINARY in the parameter type.
Mar 22, 2016
I reread your post and see that you are using VARBINARY already. Try using ARRAY OF TINYINT instead. VARBINARY should work correctly with the release of the C++ client that is in the master branch in github. However, I don't know if that version has been formally released yet. The release engineer is out of the office this week, so I can't ask her.

Is this a high priority problem?
Mar 24, 2016
Thank you, Bill. Yes it's a hight priority problem but my program is now running well by using VARBINARY, I'll also try your suggestion. I'm not sure why the issue occurred, but after I rebuild the program on another linux environment, the problem disappeared.