Bug #78682 Searching for columns when have text type results in NullPointerException
Submitted: 2 Oct 2015 14:07 Modified: 25 Aug 2018 15:44
Reporter: deyan pandulev Email Updates:
Status: Duplicate Impact on me:
None 
Category:MySQL Cluster: Cluster/J Severity:S3 (Non-critical)
Version:7.4.6 OS:Ubuntu
Assigned to: Bogdan Kecman CPU Architecture:Any

[2 Oct 2015 14:07] deyan pandulev
Description:
Server version: 5.6.24-ndb-7.4.6-cluster-gpl-log MySQL Cluster Community Server (GPL)

clusterj-7.4.6

jdk 1.7.0_67

If searching by a column and having another text column in the table the operation results in an exception or error. If the column is varchar instead of text everything runs fine.

How to repeat:
Have the following table:

show create table test_blob;

| test_blob | CREATE TABLE `test_blob` (
  `test_blob_id` int(11) NOT NULL,
  `data` varchar(2048) DEFAULT NULL,
  `ref` int(11) NOT NULL,
  PRIMARY KEY (`test_blob_id`)
) ENGINE=ndbcluster DEFAULT CHARSET=utf8 |

insert into test_blob values (1,'this is a test',100);

Test case:

public void executeCustomTransaction() {

	final int testBlobId = 1;
	final int ref = 100;

	final QueryBuilder queryBuilder = session.getQueryBuilder();
	final QueryDomainType<TestBlob> domain = queryBuilder.createQueryDefinition(TestBlob.class);
	domain.where(domain.get("ref").equal(domain.param("ref")));

	final Query<TestBlob> query = session.createQuery(domain);

	query.setParameter("ref", ref);
	final List<TestBlob> testBlobResults = query.getResultList();

	assert testBlobResults.size() == 1;

	final TestBlob testBlob = testBlobResults.get(0);
	assert testBlob.getTestBlobId() == testBlobId;
	assert testBlob.getRef() == ref;

    }

This test passes fine.

Now alter the table:

alter table test_blob modify data text default null;

Running the test again gives the following exception:

java.lang.RuntimeException: com.mysql.clusterj.ClusterJException: Exception executing query. Caused by java.lang.NullPointerException:null
	at com.egt.rtgs.roulette.ndb.transactions.AbstractNDBTransaction.execute(AbstractNDBTransaction.java:35)
	at com.egt.rtgs.roulette.test.ndb.bug.BuggyTransaction.test(BuggyTransaction.java:17)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
	at org.testng.internal.Invoker.invokeMethod(Invoker.java:639)
	at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:816)
	at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1124)
	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:124)
	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
	at org.testng.TestRunner.privateRun(TestRunner.java:773)
	at org.testng.TestRunner.run(TestRunner.java:623)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:359)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:354)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:312)
	at org.testng.SuiteRunner.run(SuiteRunner.java:261)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1185)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1110)
	at org.testng.TestNG.run(TestNG.java:1018)
	at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:112)
	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:205)
	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:176)
Caused by: com.mysql.clusterj.ClusterJException: Exception executing query. Caused by java.lang.NullPointerException:null
	at com.mysql.clusterj.core.query.QueryDomainTypeImpl.getResultList(QueryDomainTypeImpl.java:194)
	at com.mysql.clusterj.core.query.QueryImpl.getResultList(QueryImpl.java:144)
	at com.egt.rtgs.roulette.test.ndb.bug.BuggyTransaction.executeCustomTransaction(BuggyTransaction.java:33)
	at com.egt.rtgs.roulette.ndb.transactions.AbstractNDBTransaction.execute(AbstractNDBTransaction.java:26)
	... 25 more
Caused by: java.lang.NullPointerException
	at com.mysql.clusterj.tie.BlobImpl.getLength(BlobImpl.java:57)
	at com.mysql.clusterj.tie.NdbRecordBlobImpl.readData(NdbRecordBlobImpl.java:110)
	at com.mysql.clusterj.tie.NdbRecordOperationImpl.loadBlobValues(NdbRecordOperationImpl.java:927)
	at com.mysql.clusterj.tie.NdbRecordScanResultDataImpl.next(NdbRecordScanResultDataImpl.java:137)
	at com.mysql.clusterj.core.query.QueryDomainTypeImpl.getResultList(QueryDomainTypeImpl.java:183)
	... 28 more

Altering the db again: 
alter table test_blob modify data text not null;

Running the test again gives:

*** Error in `/home/deyan/install/jdk1.7.0_67/bin/java': malloc(): memory corruption: 0x00007ff5ac423c50 ***
[2 Oct 2015 14:55] Bogdan Kecman
Hi,

Thanks for the bug report and the way to reproduce it but I cannot reproduce this with 7.4.8 and latest jdk (not even with old 7u79)

all best
Bogdan
[2 Oct 2015 15:06] deyan pandulev
Will try with the latest version. Thanks
[7 Jun 2016 11:45] Alexander Potapov
Hello there!

I have the same issue in mysql-cluster-gpl-7.4.11-winx64.
[7 Jun 2016 11:46] Bogdan Kecman
Hi,

What java version are you using?

all best
Bogdan
[7 Jun 2016 11:48] Alexander Potapov
Wow! It was fast! I mean response...

I use 1.8.0_45 java.
[7 Jun 2016 11:50] Bogdan Kecman
Hi,

The next update will not be that fast. Lemme test this with exactly those 2 versions and see how it goes. I could not reproduce so far.

all best
Bogdan
[14 Jul 2016 13:03] Bogdan Kecman
I apologize but something you are doing is wrong as I can't reproduce this, works like a charm every time ... 

[root@localhost dev]# java -Djava.library.path=/usr/local/mysql/lib/ -classpath .:clusterj.jar:myconn.jar kukuriku
Jul 14, 2016 2:56:11 PM com.mysql.clusterj.core.metadata.DomainTypeHandlerFactoryImpl <clinit>
INFO: Found 0 DomainTypeHandlerFactories
Jul 14, 2016 2:56:11 PM com.mysql.clusterj.tie.Utility addCollation
INFO: Adding charset converter latin1 for collation 5
Jul 14, 2016 2:56:11 PM com.mysql.clusterj.tie.Utility addCollation
INFO: Adding charset converter latin1 for collation 8
Jul 14, 2016 2:56:11 PM com.mysql.clusterj.tie.Utility addCollation
INFO: Adding charset converter latin1 for collation 15
Jul 14, 2016 2:56:11 PM com.mysql.clusterj.tie.Utility addCollation
INFO: Adding charset converter latin1 for collation 31
Jul 14, 2016 2:56:11 PM com.mysql.clusterj.tie.Utility addCollation
INFO: Adding charset converter latin1 for collation 47
Jul 14, 2016 2:56:11 PM com.mysql.clusterj.tie.Utility addCollation
INFO: Adding charset converter latin1 for collation 48
Jul 14, 2016 2:56:11 PM com.mysql.clusterj.tie.Utility addCollation
INFO: Adding charset converter latin1 for collation 49
Jul 14, 2016 2:56:11 PM com.mysql.clusterj.tie.Utility addCollation
INFO: Adding charset converter latin1 for collation 94
Jul 14, 2016 2:56:11 PM com.mysql.clusterj.tie.ClusterConnectionImpl <init>
INFO: Created cluster connection 'localhost:1186' with node id 0.
[root@localhost dev]#

mysql> show create table test_blob;
+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table     | Create Table                                                                                                                                                                                         |
+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| test_blob | CREATE TABLE `test_blob` (
  `test_blob_id` int(11) NOT NULL,
  `data` varchar(2048) DEFAULT NULL,
  `ref` int(11) NOT NULL,
  PRIMARY KEY (`test_blob_id`)
) ENGINE=ndbcluster DEFAULT CHARSET=utf8 |
+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> alter table test_blob modify data text default null;
Query OK, 80 rows affected (0.80 sec)
Records: 80  Duplicates: 0  Warnings: 0

mysql> show create table test_blob;
+-----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table     | Create Table                                                                                                                                                                   |
+-----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| test_blob | CREATE TABLE `test_blob` (
  `test_blob_id` int(11) NOT NULL,
  `data` text,
  `ref` int(11) NOT NULL,
  PRIMARY KEY (`test_blob_id`)
) ENGINE=ndbcluster DEFAULT CHARSET=utf8 |
+-----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

javac -classpath .:clusterj.jar:myconn.jar TestBlob.java
javac -classpath .:clusterj.jar:myconn.jar kukuriku.java

[root@localhost dev]# cat TestBlob.java

import com.mysql.jdbc.*;
import com.mysql.clusterj.*;
import com.mysql.clusterj.query.*;
import com.mysql.clusterj.annotation.*;
import java.util.Properties;

/*
CREATE TABLE `test_blob` (
  `test_blob_id` int(11) NOT NULL,
  `data` varchar(2048) DEFAULT NULL,
  `ref` int(11) NOT NULL,
  PRIMARY KEY (`test_blob_id`)
)
*/

@PersistenceCapable(table="test_blob")
@PrimaryKey(column="test_blob_id")
public interface TestBlob {

    @Column(name="test_blob_id")
    int getTest_blob_id();
    void setTest_blob_id(int id);

    @Column(name="data")
    byte[] getData();
    void setData(byte[] value);

    @Column(name="ref")
    int getRef();
    void setRef(int value);

}

[root@localhost dev]# cat kukuriku.java
import com.mysql.jdbc.*;
import com.mysql.clusterj.*;
import com.mysql.clusterj.query.*;
import com.mysql.clusterj.annotation.*;
import java.util.*;

public class kukuriku{

   public static void main(String[] args) {
        try {

          Properties props = new Properties();
          props.put("com.mysql.clusterj.connectstring", "localhost:1186");
          props.put("com.mysql.clusterj.database", "test");

          SessionFactory factory = ClusterJHelper.getSessionFactory(props);
          Session session = factory.getSession();

          final int testBlobId = 1;
          final int ref = 100;

          final QueryBuilder queryBuilder = session.getQueryBuilder();
          final QueryDomainType<TestBlob> domain = queryBuilder.createQueryDefinition(TestBlob.class);
          domain.where(domain.get("ref").equal(domain.param("ref")));

          final Query<TestBlob> query = session.createQuery(domain);

          query.setParameter("ref", ref);
          final List<TestBlob> testBlobResults = query.getResultList();

          assert testBlobResults.size() == 1;

          final TestBlob testBlob = testBlobResults.get(0);
          assert testBlob.getTest_blob_id() == testBlobId;
          assert testBlob.getRef() == ref;

        } catch (Exception ex){
          System.out.println("DANGE: " + ex.getMessage());
          return;
        }

    }
}

the only way to get 
DANGE: Exception executing query. Caused by java.lang.NullPointerException:null

is to make getData String and not byte[] but you can't expect String type from blob.. If you have your interface like this:

@PersistenceCapable(table="test_blob")
@PrimaryKey(column="test_blob_id")
public interface TestBlob {

    @Column(name="test_blob_id")
    int getTest_blob_id();
    void setTest_blob_id(int id);

    @Column(name="data")
    String getData();
    void setData(String value);

    @Column(name="ref")
    int getRef();
    void setRef(int value);

}

Then yes, it will fail on BLOB but BLOB is not a String ... on the other hand byte[] will work for both BLOB and VARCHAR

hope this clarifies the problem? definitively not a bug what I see here.

hope this helps
All best
Bogdan Kecman
[25 Aug 2018 15:44] Lakshmi Narayanan Sreethar
Duplicate of Bug#91242