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 Russell | 2 Jun |