Bug #22526 NdbOperation::equal() with too-long VARCHAR can cause tx->execute() to hang
Description:
If you call NdbOperation::equal() for example with a 20-character VARCHAR, when the column is defined as VARCHAR(16), and then call tx->execute(), the execute call will hang for 6 minutes before returning an empty result. I tested this on Mac OS X but I think it also effects other OSes.
(This looks like a duplicate of some other issues, but those are reported as fixed before 5.0.20)
How to repeat:
Here is my basic test code for this (you will need to create a table and try a too-long varchar case)
#include <cstdlib>
#include <stdio.h>
#include <string.h>
#include "NdbApi.hpp"
int main() {
Ndb *db;
const NdbDictionary::Dictionary *dict;
const NdbDictionary::Table *tab;
const NdbDictionary::Index *idx;
NdbTransaction *tx;
NdbIndexOperation *op;
NdbRecAttr *result_cols[4];
char name[255];
char *s;
size_t l;
char *connect_string = "";
char *my_table = "table4";
char *my_index = "name$unique";
char my_search_param[255];
my_search_param[0] = 5;
strcpy( my_search_param + 1, "allen");
printf("search on: '%s'\n", my_search_param);
ndb_init();
Ndb_cluster_connection conn(connect_string);
conn.connect(4,5,1);
conn.wait_until_ready(20, 0);
db = new Ndb( & conn);
db->init();
db->setDatabaseName("ndb_test");
dict = db->getDictionary();
tab = dict->getTable(my_table);
idx = dict->getIndex(my_index , my_table);
tx = db->startTransaction();
if(!tx) puts(db->getNdbError().message);
op = tx->getNdbIndexOperation(idx);
if(!op) puts(db->getNdbError().message);
printf("table: %s \n", op->getTableName());
op->readTuple(NdbOperation::LM_Read);
op->equal("name", (const char *) my_search_param);
result_cols[0] = op->getValue("i",0);
result_cols[1] = op->getValue("j",0);
result_cols[2] = op->getValue("name",0);
if(! result_cols[2]) puts("op->getValue failed.\n");
if(tx->execute( NdbTransaction::NoCommit,
NdbTransaction::AbortOnError, 1))
puts(db->getNdbError().message);
l = (size_t) *(result_cols[2]->aRef());
s = (result_cols[2]->aRef() + 1);
printf("len: %lu, string: %s \n", l, s);
strncpy(name, s, l);
name[l] = 0;
printf("RESULTS: %d %d %s \n", result_cols[0]->int32_value(),
result_cols[1]->int32_value(), name);
tx->close();
delete db;
return 0;
}
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.051 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
Description: If you call NdbOperation::equal() for example with a 20-character VARCHAR, when the column is defined as VARCHAR(16), and then call tx->execute(), the execute call will hang for 6 minutes before returning an empty result. I tested this on Mac OS X but I think it also effects other OSes. (This looks like a duplicate of some other issues, but those are reported as fixed before 5.0.20) How to repeat: Here is my basic test code for this (you will need to create a table and try a too-long varchar case) #include <cstdlib> #include <stdio.h> #include <string.h> #include "NdbApi.hpp" int main() { Ndb *db; const NdbDictionary::Dictionary *dict; const NdbDictionary::Table *tab; const NdbDictionary::Index *idx; NdbTransaction *tx; NdbIndexOperation *op; NdbRecAttr *result_cols[4]; char name[255]; char *s; size_t l; char *connect_string = ""; char *my_table = "table4"; char *my_index = "name$unique"; char my_search_param[255]; my_search_param[0] = 5; strcpy( my_search_param + 1, "allen"); printf("search on: '%s'\n", my_search_param); ndb_init(); Ndb_cluster_connection conn(connect_string); conn.connect(4,5,1); conn.wait_until_ready(20, 0); db = new Ndb( & conn); db->init(); db->setDatabaseName("ndb_test"); dict = db->getDictionary(); tab = dict->getTable(my_table); idx = dict->getIndex(my_index , my_table); tx = db->startTransaction(); if(!tx) puts(db->getNdbError().message); op = tx->getNdbIndexOperation(idx); if(!op) puts(db->getNdbError().message); printf("table: %s \n", op->getTableName()); op->readTuple(NdbOperation::LM_Read); op->equal("name", (const char *) my_search_param); result_cols[0] = op->getValue("i",0); result_cols[1] = op->getValue("j",0); result_cols[2] = op->getValue("name",0); if(! result_cols[2]) puts("op->getValue failed.\n"); if(tx->execute( NdbTransaction::NoCommit, NdbTransaction::AbortOnError, 1)) puts(db->getNdbError().message); l = (size_t) *(result_cols[2]->aRef()); s = (result_cols[2]->aRef() + 1); printf("len: %lu, string: %s \n", l, s); strncpy(name, s, l); name[l] = 0; printf("RESULTS: %d %d %s \n", result_cols[0]->int32_value(), result_cols[1]->int32_value(), name); tx->close(); delete db; return 0; }