List:Commits« Previous MessageNext Message »
From:Craig L Russell Date:June 2 2011 1:58pm
Subject:bzr push into mysql-5.1-telco-7.1 branch (Craig.Russell:4233 to 4234)
View as plain text  
 4234 Craig L Russell	2011-06-02
      Add LIKE for binary and varbinary columns

    added:
      storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/QueryLikeByteArrayTypesTest.java
      storage/ndb/clusterj/clusterj-tie/src/test/java/testsuite/clusterj/tie/QueryLikeByteArrayTypesTest.java
    modified:
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/LikePredicateImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/PropertyImpl.java
      storage/ndb/clusterj/clusterj-test/Makefile.am
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanFilterImpl.java
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/Utility.java
 4233 jonas oreland	2011-06-01 [merge]
      ndb - merge 70 to 71

    modified:
      storage/ndb/include/transporter/TransporterRegistry.hpp
      storage/ndb/src/common/transporter/Transporter.cpp
      storage/ndb/src/common/transporter/Transporter.hpp
      storage/ndb/src/common/transporter/TransporterRegistry.cpp
      storage/ndb/src/mgmsrv/MgmtSrvr.cpp
      storage/ndb/src/mgmsrv/MgmtSrvr.hpp
      storage/ndb/src/mgmsrv/Services.cpp
=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/LikePredicateImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/LikePredicateImpl.java	2011-05-26 21:04:45 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/LikePredicateImpl.java	2011-06-02 13:56:47 +0000
@@ -17,7 +17,6 @@
 
 package com.mysql.clusterj.core.query;
 
-import com.mysql.clusterj.core.store.IndexScanOperation;
 import com.mysql.clusterj.core.store.ScanFilter;
 import com.mysql.clusterj.core.store.ScanOperation;
 
@@ -32,15 +31,7 @@ public class LikePredicateImpl extends C
 
     @Override
     public void markBoundsForCandidateIndices(QueryExecutionContextImpl context, CandidateIndexImpl[] candidateIndices) {
-        Object value = param.getParameterValue(context);
-        property.markLikeBound(candidateIndices, value, this);
-    }
-
-    @Override
-    public void operationSetBounds(QueryExecutionContextImpl context, IndexScanOperation op, boolean lastColumn) {
-        // set lower and upper bounds
-        String parameterValue = (String)param.getParameterValue(context);
-        property.operationSetLikeBounds(parameterValue, op, lastColumn);
+        // like does not support index bounds
     }
 
     /** Set the condition into the filter.

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/PropertyImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/PropertyImpl.java	2011-05-26 21:04:45 +0000
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/PropertyImpl.java	2011-06-02 13:56:47 +0000
@@ -17,7 +17,6 @@
 
 package com.mysql.clusterj.core.query;
 
-import com.mysql.clusterj.ClusterJFatalInternalException;
 import com.mysql.clusterj.ClusterJUserException;
 
 import com.mysql.clusterj.core.spi.DomainFieldHandler;
@@ -55,12 +54,6 @@ public class PropertyImpl implements Pre
         fmd.operationSetBounds(value, type, op);
     }
 
-    public void operationSetLikeBounds(Object value, IndexScanOperation op, boolean lastColumn) {
-        // not currently implemented
-//        fmd.operationSetBounds(value, type, op);
-        throw new ClusterJFatalInternalException(local.message("ERR_NotImplemented"));
-    }
-
     public void operationEqual(Object value, Operation op) {
         fmd.operationEqual(value, op);
     }
@@ -157,88 +150,4 @@ public class PropertyImpl implements Pre
         fmd.markInBounds(candidateIndices, predicate);
     }
 
-    public void markLikeBound(CandidateIndexImpl[] candidateIndices, Object value, LikePredicateImpl predicate) {
-        // not currently implemented
-//        if (isSuitableForLikeIndex(value)) {
-//            fmd.markLikeBounds(candidateIndices, predicate);
-//        }
-    }
-
-    /** Determine whether the value is suitable for use as bounds for an index scan.
-     * Used to create bounds for "like" queries. 
-     * This method should just delegate to the DomainFieldHandler...
-     * @param value the value
-     * @return true if the value can be used to create lower and upper bounds
-     */
-    @SuppressWarnings("unused")
-    private boolean isSuitableForLikeIndex(Object value) {
-        boolean result = false;
-        if (value instanceof String) {
-            String stringValue = (String)value;
-            int firstPercent = stringValue.indexOf('%');
-            int firstUnderbar = stringValue.indexOf('_');
-            if (firstPercent != 0 && firstUnderbar != 0) {
-                 // neither % or _ is the first character so index can be used
-                result = true;
-            }
-        }
-        if (logger.isDebugEnabled()) logger.debug(
-                "" + value + (result?" is suitable for index.":" is not suitable for index."));
-        return result;
-    }
-
-    /** Create a lower bound from a "like" parameter.
-     * This method should just delegate to the DomainFieldHandler...
-     * @param parameterValue the value whence to create a lower bound
-     * @return the lower bound
-     */
-    @SuppressWarnings("unused")
-    private String getLowerBound(String parameterValue) {
-        String result = parameterValue;
-        int firstPercent = parameterValue.indexOf('%');
-        int firstUnderbar = parameterValue.indexOf('_');
-        int firstWildCard = 0;
-        if (firstPercent == -1) {
-            firstWildCard = firstUnderbar;
-        } else if (firstUnderbar == -1) {
-            firstWildCard = firstPercent;
-        } else {
-            firstWildCard = Math.min(firstPercent, firstUnderbar);
-        }
-        if (firstWildCard != -1) {
-            // either % or _ appears in the string
-            result = parameterValue.substring(0, firstWildCard);
-        }
-        if (logger.isDebugEnabled()) logger.debug("lower bound for " + parameterValue + " is " + result);
-        return result;
-    }
-
-    /** Create an upper bound from a "like" parameter.
-     * This method should just delegate to the DomainFieldHandler...
-     * @param parameterValue the "like" parameter
-     * @return the upper bound
-     */
-    @SuppressWarnings("unused")
-    private String getUpperBound(String parameterValue) {
-        int firstPercent = parameterValue.indexOf('%');
-        int firstUnderbar = parameterValue.indexOf('_');
-        int firstWildCard = 0;
-        if (firstPercent == -1) {
-            firstWildCard = firstUnderbar;
-        } else if (firstUnderbar == -1) {
-            firstWildCard = firstPercent;
-        } else {
-            firstWildCard = Math.min(firstPercent, firstUnderbar);
-        }
-        if (firstWildCard == -1) {
-            // neither % nor _ appears in the string
-            firstWildCard = parameterValue.length();
-        }
-        StringBuilder builder = new StringBuilder(parameterValue.subSequence(0, firstWildCard - 1));
-        builder.append((char)(parameterValue.charAt(firstWildCard - 1) + 1));
-        String result = builder.toString();
-        if (logger.isDebugEnabled()) logger.debug("upper bound for " + parameterValue + " is " + result);
-        return result;
-    }
-
 }

=== modified file 'storage/ndb/clusterj/clusterj-test/Makefile.am'
--- a/storage/ndb/clusterj/clusterj-test/Makefile.am	2011-05-26 21:04:45 +0000
+++ b/storage/ndb/clusterj/clusterj-test/Makefile.am	2011-06-02 13:56:47 +0000
@@ -90,6 +90,7 @@ clusterj_test_java = \
   $(clusterj_test_src)/testsuite/clusterj/QueryHashIndexScanTest.java \
   $(clusterj_test_src)/testsuite/clusterj/QueryInTest.java \
   $(clusterj_test_src)/testsuite/clusterj/QueryLikeTest.java \
+  $(clusterj_test_src)/testsuite/clusterj/QueryLikeByteArrayTypesTest.java \
   $(clusterj_test_src)/testsuite/clusterj/QueryMultiColumnIndexInTest.java \
   $(clusterj_test_src)/testsuite/clusterj/QueryNotNullTest.java \
   $(clusterj_test_src)/testsuite/clusterj/QueryNotTest.java \

=== added file 'storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/QueryLikeByteArrayTypesTest.java'
--- a/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/QueryLikeByteArrayTypesTest.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/QueryLikeByteArrayTypesTest.java	2011-06-02 13:56:47 +0000
@@ -0,0 +1,132 @@
+/*
+   Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+*/
+
+package testsuite.clusterj;
+
+import testsuite.clusterj.model.ByteArrayTypes;
+import testsuite.clusterj.model.IdBase;
+
+/** Derived from QueryStringTypesTest.
+ */
+public class QueryLikeByteArrayTypesTest extends AbstractQueryTest {
+
+    @Override
+    public Class<?> getInstanceType() {
+        return ByteArrayTypes.class;
+    }
+
+    @Override
+    void createInstances(int number) {
+        createAllByteArrayTypesInstances(number);
+    }
+
+    static byte[][] bytes = new byte[][] {
+        new byte[] {'a', 'a', 'a', 'a'},
+        new byte[] {'a', 'a', 'a', 'b'},
+        new byte[] {'a', 'a', 'b', 'a'},
+        new byte[] {'a', 'a', 'b', 'b'},
+        new byte[] {'a', 'b', 'a', 'a'},
+        new byte[] {'a', 'b', 'a', 'b'},
+        new byte[] {'a', 'b', 'b', 'a'},
+        new byte[] {'a', 'b', 'b', 'b'},
+        new byte[] {'b', 'a', 'a', 'a'},
+        new byte[] {'b', 'a', 'a', 'b'},
+    };
+
+    /** Schema
+    *
+drop table if exists bytestype;
+create table bytestype (
+ id int not null primary key,
+
+ bytes_null_hash varbinary(8),
+ bytes_null_btree varbinary(8),
+ bytes_null_both varbinary(8),
+ bytes_null_none varbinary(8),
+key idx_bytes_null_btree (bytes_null_btree),
+unique key idx_bytes_null_both (bytes_null_both),
+unique key idx_bytes_null_hash (bytes_null_hash) using hash
+
+) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
+
+    */
+    public void test() {
+        btreeIndexScanString();
+        hashIndexScanString();
+        bothIndexScanString();
+        noneIndexScanString();
+        failOnError();
+    }
+
+    public void btreeIndexScanString() {
+        likeQuery("bytes_null_btree", "none", new byte[] {(byte)'%'}, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+        likeQuery("bytes_null_btree", "none", new byte[] {(byte)'_'});
+        likeQuery("bytes_null_btree", "none", new byte[] {(byte)'_', (byte)'_', (byte)'_', (byte)'_'}, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+        likeQuery("bytes_null_btree", "none", new byte[] {(byte)'_', (byte)'a', (byte)'a', (byte)'a'}, 0, 8);
+        likeQuery("bytes_null_btree", "none", new byte[] {(byte)'a', (byte)'b', (byte)'a', (byte)'a'}, 4);
+        likeQuery("bytes_null_btree", "none", new byte[] {(byte)'a', (byte)'b', (byte)'a', (byte)'%'}, 4, 5);
+        likeQuery("bytes_null_btree", "none", new byte[] {(byte)'a', (byte)'b', (byte)'%'}, 4, 5, 6, 7);
+        greaterEqualAndLikeQuery("bytes_null_btree", "idx_bytes_null_btree", getBytes(4), new byte[] {(byte)'%'}, 4, 5, 6, 7, 8, 9);
+        greaterEqualAndLikeQuery("bytes_null_btree", "idx_bytes_null_btree", getBytes(4), new byte[] {(byte)'a', (byte)'%', (byte)'b'}, 5, 7);
+        greaterThanAndLikeQuery("bytes_null_btree", "idx_bytes_null_btree", getBytes(4), new byte[] {(byte)'%', (byte)'b', (byte)'b', (byte)'%'}, 6, 7);
+    }
+
+    public void hashIndexScanString() {
+        greaterEqualAndLikeQuery("bytes_null_hash", "none", getBytes(3), new byte[] {(byte)'%', (byte)'b', (byte)'b', (byte)'%'}, 3, 6, 7);
+        greaterThanAndLikeQuery("bytes_null_hash", "none", getBytes(3), new byte[] {(byte)'%', (byte)'b', (byte)'b', (byte)'%'}, 6, 7);
+    }
+
+    public void bothIndexScanString() {
+        greaterEqualAndLikeQuery("bytes_null_both", "idx_bytes_null_both", getBytes(3), new byte[] {(byte)'%', (byte)'b', (byte)'b', (byte)'%'}, 3, 6, 7);
+        greaterThanAndLikeQuery("bytes_null_both", "idx_bytes_null_both", getBytes(3), new byte[] {(byte)'%', (byte)'b', (byte)'b', (byte)'%'}, 6, 7);
+    }
+
+    public void noneIndexScanString() {
+        greaterEqualAndLikeQuery("bytes_null_none", "none", getBytes(3), new byte[] {(byte)'%', (byte)'b', (byte)'b', (byte)'%'}, 3, 6, 7);
+        greaterThanAndLikeQuery("bytes_null_none", "none", getBytes(3), new byte[] {(byte)'%', (byte)'b', (byte)'b', (byte)'%'}, 6, 7);
+    }
+
+    private void createAllByteArrayTypesInstances(int number) {
+        for (int i = 0; i < number; ++i) {
+            ByteArrayTypes instance = session.newInstance(ByteArrayTypes.class);
+            instance.setId(i);
+            instance.setBytes_null_hash(getBytes(i));
+            instance.setBytes_null_btree(getBytes(i));
+            instance.setBytes_null_both(getBytes(i));
+            instance.setBytes_null_none(getBytes(i));
+            instances.add(instance);
+        }
+    }
+
+    protected byte[] getBytes(int number) {
+        return bytes[number];
+    }
+
+    /** Print the results of a query for debugging.
+     *
+     * @param instance the instance to print
+     */
+    @Override
+    protected void printResultInstance(IdBase instance) {
+        if (instance instanceof ByteArrayTypes) {
+            @SuppressWarnings("unused")
+            ByteArrayTypes stringType = (ByteArrayTypes)instance;
+//            System.out.println(toString(stringType));
+        }
+    }
+
+}

=== modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanFilterImpl.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanFilterImpl.java	2011-05-26 21:04:45 +0000
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ScanFilterImpl.java	2011-06-02 13:56:47 +0000
@@ -81,7 +81,12 @@ class ScanFilterImpl implements ScanFilt
     }
 
     public void cmpBytes(BinaryCondition condition, Column storeColumn, byte[] value) {
-        ByteBuffer buffer = Utility.convertValue(storeColumn, value);
+        ByteBuffer buffer;
+        if (condition == BinaryCondition.COND_LIKE) {
+            buffer = Utility.convertValueForLikeFilter(storeColumn, value);
+        } else {
+            buffer = Utility.convertValue(storeColumn, value);
+        }
         int returnCode = ndbScanFilter.cmp(convertCondition(condition),
                 storeColumn.getColumnId(), buffer, buffer.capacity());
         handleError(returnCode, ndbScanFilter);

=== modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/Utility.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/Utility.java	2011-05-26 21:04:45 +0000
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/Utility.java	2011-06-02 13:56:47 +0000
@@ -97,6 +97,8 @@ public class Utility {
         }
     }
 
+    static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+
     // TODO: change this to a weak reference so we can call delete on it when not needed
     /** Note that mysql refers to charset number and charset name, but the number is
     * actually a collation number. The CharsetMap interface thus has methods like
@@ -978,6 +980,23 @@ public class Utility {
         return byteBuffer;
     }
 
+    /** Encode a byte[] as a ByteBuffer that can be passed to ndbjtie in a COND_LIKE filter.
+     * There is no length information in the beginning of the buffer.
+     * @param storeColumn the column definition
+     * @param value the value to be converted
+     * @return the ByteBuffer
+     */
+    protected static ByteBuffer convertValueForLikeFilter(Column storeColumn, byte[] value) {
+        if (value == null) {
+            value = EMPTY_BYTE_ARRAY;
+        }
+        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(value.length);
+        byteBuffer.put(value);
+        byteBuffer.flip();
+        if (logger.isDetailEnabled()) dumpBytesToLog(byteBuffer, byteBuffer.limit());
+        return byteBuffer;
+    }
+
     /** Pad the value with blanks on the right.
      * @param value the input value
      * @param storeColumn the store column

=== added file 'storage/ndb/clusterj/clusterj-tie/src/test/java/testsuite/clusterj/tie/QueryLikeByteArrayTypesTest.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/test/java/testsuite/clusterj/tie/QueryLikeByteArrayTypesTest.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/clusterj/clusterj-tie/src/test/java/testsuite/clusterj/tie/QueryLikeByteArrayTypesTest.java	2011-06-02 13:56:47 +0000
@@ -0,0 +1,22 @@
+/*
+   Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+*/
+
+package testsuite.clusterj.tie;
+
+public class QueryLikeByteArrayTypesTest extends testsuite.clusterj.QueryLikeByteArrayTypesTest {
+
+}


Attachment: [text/bzr-bundle] bzr/craig.russell@oracle.com-20110602135647-e7oplct42vusp844.bundle
Thread
bzr push into mysql-5.1-telco-7.1 branch (Craig.Russell:4233 to 4234)Craig L Russell2 Jun