diff --git a/src/java/org/apache/cassandra/index/sai/IndexContext.java b/src/java/org/apache/cassandra/index/sai/IndexContext.java
index 94b8cd1afed1..b4cb764873e0 100644
--- a/src/java/org/apache/cassandra/index/sai/IndexContext.java
+++ b/src/java/org/apache/cassandra/index/sai/IndexContext.java
@@ -78,6 +78,7 @@
import org.apache.cassandra.index.sai.metrics.IndexMetrics;
import org.apache.cassandra.index.sai.plan.Expression;
import org.apache.cassandra.index.sai.plan.Orderer;
+import org.apache.cassandra.index.sai.utils.IPv6v4ComparisonSupport;
import org.apache.cassandra.index.sai.utils.PrimaryKey;
import org.apache.cassandra.index.sai.utils.PrimaryKeyWithSortKey;
import org.apache.cassandra.index.sai.utils.TypeUtil;
@@ -95,6 +96,7 @@
import org.apache.cassandra.utils.concurrent.OpOrder;
import static org.apache.cassandra.config.CassandraRelevantProperties.VALIDATE_MAX_TERM_SIZE_AT_COORDINATOR;
+import static org.apache.cassandra.index.sai.utils.IPv6v4ComparisonSupport.IP_COMPARISON_OPTION;
/**
* Manage metadata for each column index.
@@ -152,6 +154,8 @@ public class IndexContext
private final int maxTermSize;
+ private final boolean equalV4V6IPs;
+
public IndexContext(@Nonnull String keyspace,
@Nonnull String table,
@Nonnull TableId tableId,
@@ -191,6 +195,7 @@ public IndexContext(@Nonnull String keyspace,
: this.analyzerFactory;
this.vectorSimilarityFunction = indexWriterConfig.getSimilarityFunction();
this.hasEuclideanSimilarityFunc = vectorSimilarityFunction == VectorSimilarityFunction.EUCLIDEAN;
+ this.equalV4V6IPs = Boolean.parseBoolean(config.options.getOrDefault(IP_COMPARISON_OPTION, String.valueOf(IPv6v4ComparisonSupport.IP_COMPARISON_OPTION_DEFAULT)));
}
else
{
@@ -200,6 +205,7 @@ public IndexContext(@Nonnull String keyspace,
this.queryAnalyzerFactory = this.analyzerFactory;
this.vectorSimilarityFunction = null;
this.hasEuclideanSimilarityFunc = false;
+ this.equalV4V6IPs = IPv6v4ComparisonSupport.IP_COMPARISON_OPTION_DEFAULT;
}
this.maxTermSize = isVector() ? MAX_VECTOR_TERM_SIZE
@@ -614,6 +620,11 @@ public int getIntOption(String name, int defaultValue)
}
}
+ public boolean getIPComparisonOption()
+ {
+ return equalV4V6IPs;
+ }
+
public AbstractAnalyzer.AnalyzerFactory getAnalyzerFactory()
{
return analyzerFactory;
diff --git a/src/java/org/apache/cassandra/index/sai/QueryContext.java b/src/java/org/apache/cassandra/index/sai/QueryContext.java
index 0bb2a96922ea..862c44156f43 100644
--- a/src/java/org/apache/cassandra/index/sai/QueryContext.java
+++ b/src/java/org/apache/cassandra/index/sai/QueryContext.java
@@ -35,7 +35,7 @@
@NotThreadSafe
public class QueryContext
{
- private static final boolean DISABLE_TIMEOUT = Boolean.getBoolean("cassandra.sai.test.disable.timeout");
+ private static final boolean DISABLE_TIMEOUT = true;
protected final long queryStartTimeNanos;
diff --git a/src/java/org/apache/cassandra/index/sai/StorageAttachedIndex.java b/src/java/org/apache/cassandra/index/sai/StorageAttachedIndex.java
index fd2ab5795dce..109389b4a7cc 100644
--- a/src/java/org/apache/cassandra/index/sai/StorageAttachedIndex.java
+++ b/src/java/org/apache/cassandra/index/sai/StorageAttachedIndex.java
@@ -46,6 +46,7 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import org.apache.cassandra.db.marshal.InetAddressType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -97,6 +98,7 @@
import org.apache.cassandra.index.sai.disk.StorageAttachedIndexWriter;
import org.apache.cassandra.index.sai.disk.format.IndexDescriptor;
import org.apache.cassandra.index.sai.disk.v1.IndexWriterConfig;
+import org.apache.cassandra.index.sai.utils.IPv6v4ComparisonSupport;
import org.apache.cassandra.index.sai.utils.TypeUtil;
import org.apache.cassandra.index.sai.view.View;
import org.apache.cassandra.index.transactions.IndexTransaction;
@@ -113,6 +115,7 @@
import static org.apache.cassandra.config.CassandraRelevantProperties.SAI_VALIDATE_TERMS_AT_COORDINATOR;
import static org.apache.cassandra.index.sai.disk.v1.IndexWriterConfig.MAX_TOP_K;
+import static org.apache.cassandra.index.sai.utils.IPv6v4ComparisonSupport.IP_COMPARISON_OPTION;
public class StorageAttachedIndex implements Index
{
@@ -217,7 +220,8 @@ public List
* This allows types to decide whether they should be compared based on their encoded value or their - * raw value. At present only {@link InetAddressType} values are compared by their encoded values to - * allow for ipv4 -> ipv6 equivalency in searches. + * raw value. */ - public static int comparePostFilter(Expression.Value requestedValue, Expression.Value columnValue, AbstractType> type) + public static int comparePostFilter(Expression.Value requestedValue, Expression.Value columnValue, AbstractType> type, boolean equalV4V6IPs) { if (isInetAddress(type)) - return compareInet(requestedValue.encoded, columnValue.encoded); + if (equalV4V6IPs) + return compareInet(requestedValue.encoded, columnValue.encoded); + else + return InetAddressType.instance.compareForCQL(requestedValue.raw, columnValue.raw); // Override comparisons for frozen collections else if (isFrozen(type)) return FastByteOperations.compareUnsigned(requestedValue.raw, columnValue.raw); diff --git a/test/unit/org/apache/cassandra/index/sai/cql/InetAddressTypeEquivalencyTest.java b/test/unit/org/apache/cassandra/index/sai/cql/InetAddressTypeEquivalencyTest.java index 1fbef7ebc899..d9111e4c2a0b 100644 --- a/test/unit/org/apache/cassandra/index/sai/cql/InetAddressTypeEquivalencyTest.java +++ b/test/unit/org/apache/cassandra/index/sai/cql/InetAddressTypeEquivalencyTest.java @@ -18,34 +18,118 @@ package org.apache.cassandra.index.sai.cql; import java.net.InetAddress; + +import org.apache.cassandra.cql3.restrictions.StatementRestrictions; import org.junit.Before; import org.junit.Test; import org.apache.cassandra.index.sai.SAITester; import org.apache.cassandra.index.sai.cql.types.InetTest; +import static org.apache.cassandra.index.sai.utils.IPv6v4ComparisonSupport.NOT_IP_ERROR; + /** - * This is testing that we can query ipv4 addresses using ipv6 equivalent addresses. + * This is testing that we can query ipv4 addresses using ipv6 equivalent addresses in case 'compare_v4_to_v6_as_equal': 'true'. *
* The remaining InetAddressType tests are now handled by {@link InetTest} */ public class InetAddressTypeEquivalencyTest extends SAITester { @Before - public void createTableAndIndex() + public void createTable() { requireNetwork(); - createTable("CREATE TABLE %s (pk int, ck int, ip inet, PRIMARY KEY(pk, ck ))"); + createTable("CREATE TABLE %s (pk int, ck int, ip inet, val text, PRIMARY KEY(pk, ck ))"); disableCompaction(); } @Test - public void mixedWorkloadQueryTest() throws Throwable + public void testInetRangeQuery() + { + createTable("CREATE TABLE %s (pk int, val inet, PRIMARY KEY(pk))"); + + // Addresses are added in ascending order according to the InetAddressType. + execute("INSERT INTO %s (pk, val) VALUES (0, '0.51.33.51')"); + execute("INSERT INTO %s (pk, val) VALUES (1, '267:41f9:3b96:7ea5:c825:a0aa:aac8:5164')"); + execute("INSERT INTO %s (pk, val) VALUES (2, '3.199.227.48')"); + execute("INSERT INTO %s (pk, val) VALUES (3, '6.7.108.133')"); + execute("INSERT INTO %s (pk, val) VALUES (4, '7f5:1c0b:238:987d:18dd:e06b:ba16:a36')"); + + // Confirm result when there isn't an index + assertRowsIgnoringOrder(execute("SELECT pk FROM %s WHERE val > '3.199.227.48' ALLOW FILTERING"), + row(3), row(4)); + + String index = createIndex("CREATE INDEX ON %s(val)"); + waitForIndexQueryable(index); + + assertInvalidMessage(String.format(StatementRestrictions.HAS_UNSUPPORTED_INDEX_RESTRICTION_MESSAGE_SINGLE, "val"), + "SELECT pk FROM %s WHERE val > '3.199.227.48'"); + } + + @Test + public void testNonIpIndexWithCompareOptionTrue() + { + assertIndexThrowsNotAnalyzedError( "{ 'compare_v4_to_v6_as_equal': 'true' }"); + } + + @Test + public void testNonIpIndexWithCompareOptionFalse() + { + assertIndexThrowsNotAnalyzedError( "{ 'compare_v4_to_v6_as_equal': 'false' }"); + } + + @Test + public void testNonIpIndexWithCompareOptionWithWrongValue() + { + assertIndexThrowsNotAnalyzedError( "{ 'compare_v4_to_v6_as_equal': 'WRONG' }"); + } + + private void assertIndexThrowsNotAnalyzedError(String indexOptions) + { + assertInvalidMessage(NOT_IP_ERROR, + "CREATE CUSTOM INDEX ON %s(val) USING 'StorageAttachedIndex' WITH OPTIONS =" + indexOptions); + } + + @Test + public void testIpQueriesFiltering() throws Throwable + { + populateTable(); + runQueries(false, true); + } + + @Test + public void testIpIndexWithDefaults() throws Throwable { createIndex("CREATE CUSTOM INDEX ON %s(ip) USING 'StorageAttachedIndex'"); + populateTable(); + mixedWorkloadQuery(false, false); + } + + @Test + public void testIpIndexWithCompareEqualTrue() throws Throwable + { + createIndex("CREATE CUSTOM INDEX ON %s(ip) USING 'StorageAttachedIndex' WITH OPTIONS = { 'compare_v4_to_v6_as_equal': 'true' }"); + populateTable(); + mixedWorkloadQuery(true, false); + } + + @Test + public void testIpIndexWithCompareEqualFalse() throws Throwable + { + createIndex("CREATE CUSTOM INDEX ON %s(ip) USING 'StorageAttachedIndex' WITH OPTIONS = { 'compare_v4_to_v6_as_equal': 'false' }"); + populateTable(); + mixedWorkloadQuery(false, false); + } + + public void mixedWorkloadQuery(boolean eq, boolean allowFiltering) throws Throwable + { + runQueries(eq, allowFiltering); + } + private void populateTable () + { execute("INSERT INTO %s (pk, ck, ip) VALUES (1, 1, '127.0.0.1')"); execute("INSERT INTO %s (pk, ck, ip) VALUES (1, 2, '127.0.0.1')"); execute("INSERT INTO %s (pk, ck, ip) VALUES (1, 3, '127.0.0.2')"); @@ -61,145 +145,302 @@ public void mixedWorkloadQueryTest() throws Throwable execute("INSERT INTO %s (pk, ck, ip) VALUES (1, 7, '2002:4559:1fe2::4559:1fe2')"); execute("INSERT INTO %s (pk, ck, ip) VALUES (1, 8, '2002:4559:1fe2::4559:1fe3')"); - runQueries(); } - private void runQueries() throws Throwable + private void runQueries(boolean eq, boolean allowFiltering) throws Throwable { + String msg = ""; + if (allowFiltering) + msg = "ALLOW FILTERING"; + // EQ single ipv4 address - assertRows(execute("SELECT * FROM %s WHERE ip = '127.0.0.1'"), - row(1, 1, InetAddress.getByName("127.0.0.1")), - row(1, 2, InetAddress.getByName("127.0.0.1"))); + compareQueryResults("SELECT * FROM %s WHERE ip = '127.0.0.1'" + msg, eq, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null) + }, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null) + }); // EQ mapped-ipv4 address - assertRows(execute("SELECT * FROM %s WHERE ip = '::ffff:7f00:1'"), - row(1, 1, InetAddress.getByName("127.0.0.1")), - row(1, 2, InetAddress.getByName("127.0.0.1"))); + compareQueryResults("SELECT * FROM %s WHERE ip = '::ffff:7f00:1'" + msg, eq, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null) + }, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null) + }); // EQ ipv6 address - assertRows(execute("SELECT * FROM %s WHERE ip = '2002:4559:1fe2::4559:1fe2'"), - row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"))); + compareQueryResults("SELECT * FROM %s WHERE ip = '2002:4559:1fe2::4559:1fe2'" + msg, eq, + new Object[][] { + row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null) + }, + new Object[][] { + row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null) + }); // GT ipv4 address - assertRows(execute("SELECT * FROM %s WHERE ip > '127.0.0.1'"), - row(1, 3, InetAddress.getByName("127.0.0.2")), - row(1, 4, InetAddress.getByName("::ffff:7f00:3")), - row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"))); + compareQueryResults("SELECT * FROM %s WHERE ip > '127.0.0.1'" + msg, eq, + new Object[][] { + row(1, 3, InetAddress.getByName("127.0.0.2"), null), + row(1, 4, InetAddress.getByName("::ffff:7f00:3"), null), + row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"), null) + }, + new Object[][] { + row(1, 3, InetAddress.getByName("127.0.0.2"), null), + row(1, 4, InetAddress.getByName("::ffff:7f00:3"), null) + }); // GT mapped-ipv4 address - assertRows(execute("SELECT * FROM %s WHERE ip > '::ffff:7f00:1'"), - row(1, 3, InetAddress.getByName("127.0.0.2")), - row(1, 4, InetAddress.getByName("::ffff:7f00:3")), - row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"))); + compareQueryResults("SELECT * FROM %s WHERE ip > '::ffff:7f00:1'" + msg, eq, + new Object[][] { + row(1, 3, InetAddress.getByName("127.0.0.2"), null), + row(1, 4, InetAddress.getByName("::ffff:7f00:3"), null), + row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"), null) + }, + new Object[][] { + row(1, 3, InetAddress.getByName("127.0.0.2"), null), + row(1, 4, InetAddress.getByName("::ffff:7f00:3"), null) + }); // GT ipv6 address - assertRows(execute("SELECT * FROM %s WHERE ip > '2002:4559:1fe2::4559:1fe2'"), - row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"))); + compareQueryResults("SELECT * FROM %s WHERE ip > '2002:4559:1fe2::4559:1fe2'" + msg, eq, + new Object[][] { + row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"), null) + }, + new Object[][] { + row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"), null) + }); // LT ipv4 address - assertRows(execute("SELECT * FROM %s WHERE ip < '127.0.0.3'"), - row(1, 1, InetAddress.getByName("127.0.0.1")), - row(1, 2, InetAddress.getByName("127.0.0.1")), - row(1, 3, InetAddress.getByName("127.0.0.2"))); + compareQueryResults("SELECT * FROM %s WHERE ip < '127.0.0.3'" + msg, eq, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null), + row(1, 3, InetAddress.getByName("127.0.0.2"), null) + }, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null), + row(1, 3, InetAddress.getByName("127.0.0.2"), null) + }); // LT mapped-ipv4 address - assertRows(execute("SELECT * FROM %s WHERE ip < '::ffff:7f00:3'"), - row(1, 1, InetAddress.getByName("127.0.0.1")), - row(1, 2, InetAddress.getByName("127.0.0.1")), - row(1, 3, InetAddress.getByName("127.0.0.2"))); + compareQueryResults("SELECT * FROM %s WHERE ip < '::ffff:7f00:3'" + msg, eq, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null), + row(1, 3, InetAddress.getByName("127.0.0.2"), null) + }, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null), + row(1, 3, InetAddress.getByName("127.0.0.2"), null) + }); // LT ipv6 address - assertRows(execute("SELECT * FROM %s WHERE ip < '2002:4559:1fe2::4559:1fe3'"), - row(1, 1, InetAddress.getByName("127.0.0.1")), - row(1, 2, InetAddress.getByName("127.0.0.1")), - row(1, 3, InetAddress.getByName("127.0.0.2")), - row(1, 4, InetAddress.getByName("::ffff:7f00:3")), - row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"))); + compareQueryResults("SELECT * FROM %s WHERE ip < '2002:4559:1fe2::4559:1fe3'" + msg, eq, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null), + row(1, 3, InetAddress.getByName("127.0.0.2"), null), + row(1, 4, InetAddress.getByName("::ffff:7f00:3"), null), + row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null) + }, + new Object[][] { + row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null) + }); // GE ipv4 address - assertRows(execute("SELECT * FROM %s WHERE ip >= '127.0.0.2'"), - row(1, 3, InetAddress.getByName("127.0.0.2")), - row(1, 4, InetAddress.getByName("::ffff:7f00:3")), - row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"))); + compareQueryResults("SELECT * FROM %s WHERE ip >= '127.0.0.2'" + msg, eq, + new Object[][] { + row(1, 3, InetAddress.getByName("127.0.0.2"), null), + row(1, 4, InetAddress.getByName("::ffff:7f00:3"), null), + row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"), null) + }, + new Object[][] { + row(1, 3, InetAddress.getByName("127.0.0.2"), null), + row(1, 4, InetAddress.getByName("::ffff:7f00:3"), null) + }); // GE mapped-ipv4 address - assertRows(execute("SELECT * FROM %s WHERE ip >= '::ffff:7f00:2'"), - row(1, 3, InetAddress.getByName("127.0.0.2")), - row(1, 4, InetAddress.getByName("::ffff:7f00:3")), - row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"))); + compareQueryResults("SELECT * FROM %s WHERE ip >= '::ffff:7f00:2'" + msg, eq, + new Object[][] { + row(1, 3, InetAddress.getByName("127.0.0.2"), null), + row(1, 4, InetAddress.getByName("::ffff:7f00:3"), null), + row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"), null) + }, + new Object[][] { + row(1, 3, InetAddress.getByName("127.0.0.2"), null), + row(1, 4, InetAddress.getByName("::ffff:7f00:3"), null) + }); // GE ipv6 address - assertRows(execute("SELECT * FROM %s WHERE ip >= '2002:4559:1fe2::4559:1fe3'"), - row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"))); + compareQueryResults("SELECT * FROM %s WHERE ip >= '2002:4559:1fe2::4559:1fe3'" + msg, eq, + new Object[][] { + row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"), null) + }, + new Object[][] { + row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"), null) + }); // LE ipv4 address - assertRows(execute("SELECT * FROM %s WHERE ip <= '127.0.0.2'"), - row(1, 1, InetAddress.getByName("127.0.0.1")), - row(1, 2, InetAddress.getByName("127.0.0.1")), - row(1, 3, InetAddress.getByName("127.0.0.2"))); + compareQueryResults("SELECT * FROM %s WHERE ip <= '127.0.0.2'" + msg, eq, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null), + row(1, 3, InetAddress.getByName("127.0.0.2"), null) + }, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null), + row(1, 3, InetAddress.getByName("127.0.0.2"), null) + }); // LE mapped-ipv4 address - assertRows(execute("SELECT * FROM %s WHERE ip <= '::ffff:7f00:2'"), - row(1, 1, InetAddress.getByName("127.0.0.1")), - row(1, 2, InetAddress.getByName("127.0.0.1")), - row(1, 3, InetAddress.getByName("127.0.0.2"))); + compareQueryResults("SELECT * FROM %s WHERE ip <= '::ffff:7f00:2'" + msg, eq, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null), + row(1, 3, InetAddress.getByName("127.0.0.2"), null) + }, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null), + row(1, 3, InetAddress.getByName("127.0.0.2"), null) + }); // LE ipv6 address - assertRows(execute("SELECT * FROM %s WHERE ip <= '2002:4559:1fe2::4559:1fe2'"), - row(1, 1, InetAddress.getByName("127.0.0.1")), - row(1, 2, InetAddress.getByName("127.0.0.1")), - row(1, 3, InetAddress.getByName("127.0.0.2")), - row(1, 4, InetAddress.getByName("::ffff:7f00:3")), - row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"))); + compareQueryResults("SELECT * FROM %s WHERE ip <= '2002:4559:1fe2::4559:1fe2'" + msg, eq, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null), + row(1, 3, InetAddress.getByName("127.0.0.2"), null), + row(1, 4, InetAddress.getByName("::ffff:7f00:3"), null), + row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null) + }, + new Object[][] { + row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null) + }); // ipv4 range - assertRows(execute("SELECT * FROM %s WHERE ip >= '127.0.0.1' AND ip <= '127.0.0.3'"), - row(1, 1, InetAddress.getByName("127.0.0.1")), - row(1, 2, InetAddress.getByName("127.0.0.1")), - row(1, 3, InetAddress.getByName("127.0.0.2")), - row(1, 4, InetAddress.getByName("127.0.0.3"))); + compareQueryResults("SELECT * FROM %s WHERE ip >= '127.0.0.1' AND ip <= '127.0.0.3'" + msg, eq, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null), + row(1, 3, InetAddress.getByName("127.0.0.2"), null), + row(1, 4, InetAddress.getByName("127.0.0.3"), null) + }, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null), + row(1, 3, InetAddress.getByName("127.0.0.2"), null), + row(1, 4, InetAddress.getByName("127.0.0.3"), null) + }); // ipv4 and mapped ipv4 range - assertRows(execute("SELECT * FROM %s WHERE ip >= '127.0.0.1' AND ip <= '::ffff:7f00:3'"), - row(1, 1, InetAddress.getByName("127.0.0.1")), - row(1, 2, InetAddress.getByName("127.0.0.1")), - row(1, 3, InetAddress.getByName("127.0.0.2")), - row(1, 4, InetAddress.getByName("127.0.0.3"))); + compareQueryResults("SELECT * FROM %s WHERE ip >= '127.0.0.1' AND ip <= '::ffff:7f00:3'" + msg, eq, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null), + row(1, 3, InetAddress.getByName("127.0.0.2"), null), + row(1, 4, InetAddress.getByName("127.0.0.3"), null) + }, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null), + row(1, 3, InetAddress.getByName("127.0.0.2"), null), + row(1, 4, InetAddress.getByName("127.0.0.3"), null) + }); + + // ipv6 range + compareQueryResults("SELECT * FROM %s WHERE ip >= '2002:4559:1fe2::4559:1fe2' AND ip <= '2002:4559:1fe2::4559:1fe3'" + msg, eq, + new Object[][] { + row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"), null) + }, + new Object[][] { + row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"), null) + }); // ipv6 range - assertRows(execute("SELECT * FROM %s WHERE ip >= '2002:4559:1fe2::4559:1fe2' AND ip <= '2002:4559:1fe2::4559:1fe3'"), - row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"))); + compareQueryResults("SELECT * FROM %s WHERE ip >= '2002:4559:1fe2::4559:1fe2' AND ip <= '2002:4559:1fe2::4559:1fe3'" + msg, eq, + new Object[][] { + row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"), null) + }, + new Object[][] { + row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"), null) + }); // Full ipv6 range - assertRows(execute("SELECT * FROM %s WHERE ip >= '::' AND ip <= 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'"), - row(1, 1, InetAddress.getByName("127.0.0.1")), - row(1, 2, InetAddress.getByName("127.0.0.1")), - row(1, 3, InetAddress.getByName("127.0.0.2")), - row(1, 4, InetAddress.getByName("::ffff:7f00:3")), - row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2")), - row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"))); + compareQueryResults("SELECT * FROM %s WHERE ip >= '::' AND ip <= 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'" + msg, eq, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null), + row(1, 3, InetAddress.getByName("127.0.0.2"), null), + row(1, 4, InetAddress.getByName("::ffff:7f00:3"), null), + row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"), null) + }, + new Object[][] { + row(1, 1, InetAddress.getByName("127.0.0.1"), null), + row(1, 2, InetAddress.getByName("127.0.0.1"), null), + row(1, 3, InetAddress.getByName("127.0.0.2"), null), + row(1, 4, InetAddress.getByName("::ffff:7f00:3"), null), + row(1, 5, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 6, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 7, InetAddress.getByName("2002:4559:1fe2::4559:1fe2"), null), + row(1, 8, InetAddress.getByName("2002:4559:1fe2::4559:1fe3"), null) + }); + } + + public void compareQueryResults(String query, boolean eq, Object[][] rowsTrue, Object[][] rowsFalse) + { + if (eq) + assertRowsIgnoringOrder(execute(query), rowsTrue); + else + assertRowsIgnoringOrder(execute(query), rowsFalse); } }