Bug #22526 NdbOperation::equal() with too-long VARCHAR can cause tx->execute() to hang

Submitted: 20 Sep 2006 16:06 Modified: 26 Oct 2006 10:25
Reporter: John David Duncan Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Cluster: NDB API Severity:S2 (Serious)
Version:5.0.20 OS:MacOS (Mac OS X 10.4 PPC)
Assigned to: Hartmut Holzgraefe CPU Architecture:Any

[20 Sep 2006 16:06] John David Duncan
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;
}
[20 Sep 2006 16:10] John David Duncan
And here's the table:

CREATE TABLE `table4` (
  `i` int(11) NOT NULL default '0',
  `j` int(11) NOT NULL default '0',
  `name` varchar(20) NOT NULL,
  PRIMARY KEY  USING HASH (`i`,`j`),
  UNIQUE KEY `name` USING HASH (`name`)
) ENGINE=ndbcluster
[26 Oct 2006 10:25] Hartmut Holzgraefe
can't repeat with current 5.0 source, as soon as the my_search_param length exceeds the table field length i'm getting a "op->getValue failed" error message immediately

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.