Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

### Core

- Added NP/PP box index
iterator [support](https://github.com/tarantool/tarantool/commit/96df090fe71a7152ddee105eca454efc0c096c28)
- Added
[LINEARIZABLE](https://github.com/tarantool/tarantool/blob/e643f88a5e0c6d9ef2789b2033088fd04e7d39ae/src/box/txn.h#L228)
isolation level.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,149 @@

package io.tarantool.core.protocol;

/** Tarantool iterator types for data selection. Used in {@code box.select} requests. */
public enum BoxIterator {

/**
* Matches keys equal to the provided search key (ASC order).
*
* <p>Binary value: {@code 0}
*
* @since Supported in all versions.
*/
EQ(0),

/**
* Matches keys equal to the provided search key (DESC order).
*
* <p>Binary value: {@code 1}
*
* @since Supported in all versions.
*/
REQ(1),

/**
* Iterates over all tuples in the index. The search key is ignored.
*
* <p>Binary value: {@code 2}
*
* @since Supported in all versions.
*/
ALL(2),

/**
* Matches keys strictly less than the provided search key ({@code key < x}).
*
* <p>Binary value: {@code 3}
*
* @since Supported in all versions.
*/
LT(3),

/**
* Matches keys less than or equal to the provided search key ({@code key <= x}).
*
* <p>Binary value: {@code 4}
*
* @since Supported in all versions.
*/
LE(4),

/**
* Matches keys greater than or equal to the provided search key ({@code key >= x}).
*
* <p>Binary value: {@code 5}
*
* @since Supported in all versions.
*/
GE(5),

/**
* Matches keys strictly greater than the provided search key ({@code key > x}).
*
* <p>Binary value: {@code 6}
*
* @since Supported in all versions.
*/
GT(6),

/**
* Matches keys where all bits from the search key are set (<b>Bitset index only</b>).
*
* <p>Binary value: {@code 7}
*
* @since Supported in all versions.
*/
BITS_ALL_SET(7),

/**
* Matches keys where at least one bit from the search key is set (<b>Bitset index only</b>).
*
* <p>Binary value: {@code 8}
*
* @since Supported in all versions.
*/
BITS_ANY_SET(8),

/**
* Matches keys where all bits from the search key are not set (<b>Bitset index only</b>).
*
* <p>Binary value: {@code 9}
*
* @since Supported in all versions.
*/
BITS_ALL_NOT_SET(9),

/**
* Matches keys that overlap with the provided search key (<b>RTREE index only</b>).
*
* <p>Binary value: {@code 10}
*
* @since Supported in all versions.
*/
OVERLAPS(10),
NEIGHBOR(11);

/**
* Iterates over tuples as they move away from the specified point {@code x} (<b>RTREE neighbor
* search</b>).
*
* <p>Binary value: {@code 11}
*
* @since Supported in all versions.
*/
NEIGHBOR(11),

/**
* Next Prefix iterator.
*
* <p>Binary value: {@code 12}
*
* <p>Performs a prefix-based search on the last part of the key (if it is a string, ASC order).
* It skips all keys sharing the same prefix as the search key and starts the sequential scan from
* the first key whose prefix is strictly greater than the search key.
*
* <p>Degrades to {@link #GT} if the last part of the key is not a string. <b>Works only in {@code
* memtx} tree indexes</b>.
*
* @since Tarantool 3.2.0
*/
NP(12),

/**
* Previous Prefix iterator.
*
* <p>Binary value: {@code 13}
*
* <p>Performs a prefix-based search on the last part of the key (if it is a string, DESC order).
* It looks for the last key whose prefix is strictly less than the search key, and then proceeds
* with a sequential reverse-order scan.
*
* <p>Degrades to {@link #LT} if the last part of the key is not a string. <b>Works only in {@code
* memtx} tree indexes</b>.
*
* @since Tarantool 3.2.0
*/
PP(13);

private final int code;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,74 @@ public void testSelect(
assertEquals(expected, decodeTuple(client, data));
}

public static Stream<Arguments> dataForTestIterator3() {
final String prepared =
"box.space.space_a:insert({'a', 'a'});"
+ "box.space.space_a:insert({'aa', 'aa'});"
+ "box.space.space_a:insert({'ab', 'ab'});"
+ "box.space.space_a:insert({'b', 'b'});"
+ "box.space.space_a:insert({'ba', 'ba'});"
+ "box.space.space_a:insert({'bb', 'bb'});"
+ "box.space.space_a:insert({'c', 'c'});"
+ "box.space.space_a:insert({'ca', 'ca'});"
+ "box.space.space_a:insert({'cb', 'cb'});";

return Stream.of(
Arguments.of(
BoxIterator.NP.toString(),
prepared,
ValueFactory.newArray(ValueFactory.newString("b")),
ValueFactory.newArray(
ValueFactory.newArray(ValueFactory.newString("c"), ValueFactory.newString("c")),
ValueFactory.newArray(ValueFactory.newString("ca"), ValueFactory.newString("ca")),
ValueFactory.newArray(ValueFactory.newString("cb"), ValueFactory.newString("cb"))),
spaceAId,
BoxIterator.NP),
Arguments.of(
BoxIterator.PP.toString(),
prepared,
ValueFactory.newArray(ValueFactory.newString("b")),
ValueFactory.newArray(
ValueFactory.newArray(ValueFactory.newString("ab"), ValueFactory.newString("ab")),
ValueFactory.newArray(ValueFactory.newString("aa"), ValueFactory.newString("aa")),
ValueFactory.newArray(ValueFactory.newString("a"), ValueFactory.newString("a"))),
spaceAId,
BoxIterator.PP));
}

@EnabledIfEnvironmentVariable(named = "TARANTOOL_VERSION", matches = "3.*")
@ParameterizedTest(name = "{0}")
@MethodSource("dataForTestIterator3")
void testIterator3(
String label,
String toPrepare,
ArrayValue key,
ArrayValue expected,
Integer space,
BoxIterator iterator)
throws Exception {
testIteratorCommon(toPrepare, key, expected, space, 0, Integer.MAX_VALUE, 0, iterator);
}

void testIteratorCommon(
String toPrepare,
ArrayValue key,
ArrayValue expected,
Integer space,
Integer index,
Integer limit,
Integer offset,
BoxIterator iterator)
throws Exception {
TarantoolContainerClientHelper.executeCommand(tt, toPrepare);
IProtoClient client = createClientAndConnect(address, true);
client.authorize(API_USER, CREDS.get(API_USER)).join();
IProtoMessage message = client.select(space, index, key, limit, offset, iterator).get();
checkMessageHeader(message, IPROTO_OK, 4);
ArrayValue data = message.getBodyArrayValue(IPROTO_DATA);
Assertions.assertEquals(expected, decodeTuple(client, data));
}

@ParameterizedTest
@MethodSource("dataForTestSelect")
public void testRawSelect(
Expand Down
Loading