Skip to content

Commit

Permalink
IGNITE-12887 Fix handle type mismatch exception on compare values whi…
Browse files Browse the repository at this point in the history
…le traversing index tree.
  • Loading branch information
Taras Ledkov committed Apr 20, 2020
1 parent 8212bf4 commit 0534488
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 40 deletions.
Expand Up @@ -55,6 +55,7 @@
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.lang.IgniteProductVersion;
import org.h2.message.DbException;
import org.h2.result.SearchRow;
import org.h2.table.IndexColumn;
import org.h2.value.Value;
Expand Down Expand Up @@ -419,66 +420,71 @@ private void upgradeMetaPage(boolean inlineObjSupported) throws IgniteCheckedExc
@SuppressWarnings("ForLoopReplaceableByForEach")
@Override protected int compare(BPlusIO<H2Row> io, long pageAddr, int idx,
H2Row row) throws IgniteCheckedException {
if (inlineSize() == 0)
return compareRows(getRow(io, pageAddr, idx), row);
else {
int off = io.offset(idx);
try {
if (inlineSize() == 0)
return compareRows(getRow(io, pageAddr, idx), row);
else {
int off = io.offset(idx);

int fieldOff = 0;
int fieldOff = 0;

int lastIdxUsed = 0;
int lastIdxUsed = 0;

for (int i = 0; i < inlineIdxs.size(); i++) {
InlineIndexHelper inlineIdx = inlineIdxs.get(i);
for (int i = 0; i < inlineIdxs.size(); i++) {
InlineIndexHelper inlineIdx = inlineIdxs.get(i);

Value v2 = row.getValue(inlineIdx.columnIndex());
Value v2 = row.getValue(inlineIdx.columnIndex());

if (v2 == null)
return 0;
if (v2 == null)
return 0;

int c = inlineIdx.compare(pageAddr, off + fieldOff, inlineSize() - fieldOff, v2, comp);
int c = inlineIdx.compare(pageAddr, off + fieldOff, inlineSize() - fieldOff, v2, comp);

if (c == CANT_BE_COMPARE)
break;
if (c == CANT_BE_COMPARE)
break;

lastIdxUsed++;
lastIdxUsed++;

if (c != 0)
return c;
if (c != 0)
return c;

fieldOff += inlineIdx.fullSize(pageAddr, off + fieldOff);
fieldOff += inlineIdx.fullSize(pageAddr, off + fieldOff);

if (fieldOff > inlineSize())
break;
}
if (fieldOff > inlineSize())
break;
}

if (lastIdxUsed == cols.length)
return mvccCompare((H2RowLinkIO)io, pageAddr, idx, row);
if (lastIdxUsed == cols.length)
return mvccCompare((H2RowLinkIO)io, pageAddr, idx, row);

inlineSizeRecomendation(row);
inlineSizeRecomendation(row);

SearchRow rowData = getRow(io, pageAddr, idx);
SearchRow rowData = getRow(io, pageAddr, idx);

for (int i = lastIdxUsed, len = cols.length; i < len; i++) {
IndexColumn col = cols[i];
int idx0 = col.column.getColumnId();
for (int i = lastIdxUsed, len = cols.length; i < len; i++) {
IndexColumn col = cols[i];
int idx0 = col.column.getColumnId();

Value v2 = row.getValue(idx0);
Value v2 = row.getValue(idx0);

if (v2 == null) {
// Can't compare further.
return mvccCompare((H2RowLinkIO)io, pageAddr, idx, row);
}
if (v2 == null) {
// Can't compare further.
return mvccCompare((H2RowLinkIO)io, pageAddr, idx, row);
}

Value v1 = rowData.getValue(idx0);
Value v1 = rowData.getValue(idx0);

int c = compareValues(v1, v2);
int c = compareValues(v1, v2);

if (c != 0)
return InlineIndexHelper.fixSort(c, col.sortType);
}
if (c != 0)
return InlineIndexHelper.fixSort(c, col.sortType);
}

return mvccCompare((H2RowLinkIO)io, pageAddr, idx, row);
return mvccCompare((H2RowLinkIO)io, pageAddr, idx, row);
}
}
catch (DbException ex) {
throw new IgniteCheckedException("Rows cannot be compared", ex);
}
}

Expand Down
Expand Up @@ -26,16 +26,19 @@
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
import javax.cache.CacheException;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cache.QueryEntity;
import org.apache.ignite.cache.QueryIndex;
import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
import org.apache.ignite.cache.query.FieldsQueryCursor;
import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.DataRegionConfiguration;
import org.apache.ignite.configuration.DataStorageConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.failure.StopNodeFailureHandler;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.internal.processors.query.GridQueryProcessor;
import org.apache.ignite.internal.processors.query.QueryUtils;
Expand Down Expand Up @@ -139,7 +142,8 @@ else if (srvLog != null)
);
}

return igniteCfg;
return igniteCfg
.setFailureHandler(new StopNodeFailureHandler());
}

/**
Expand Down Expand Up @@ -1149,6 +1153,35 @@ public void testDynamicIndexesWithPersistenceIndexRebuild() throws Exception {
}
}

/**
*/
@Test
public void testStopNodeOnSqlQueryWithIncompatibleType() throws Exception {
inlineSize = 10;

startGrid();

sql("CREATE TABLE TEST (ID INT PRIMARY KEY, val_int INT, VAL_OBJ OTHER)");
sql("CREATE INDEX TEST_VAL_INT ON TEST(VAL_INT)");
sql("CREATE INDEX TEST_VAL_OBJ ON TEST(VAL_OBJ)");

sql("INSERT INTO TEST VALUES (0, 0, ?)", new Pojo(0));

GridTestUtils.assertThrows(log, () -> {
sql("SELECT * FROM TEST WHERE VAL_OBJ < CURRENT_TIMESTAMP()").getAll();

return null;
}, CacheException.class, null);

GridTestUtils.assertThrows(log, () -> {
sql("SELECT * FROM TEST WHERE VAL_INT < CURRENT_TIMESTAMP()").getAll();

return null;
}, CacheException.class, null);

assertFalse(grid().context().isStopping());
}

/** */
private void checkAll() {
IgniteCache<Key, Val> cache = grid(0).cache(DEFAULT_CACHE_NAME);
Expand Down Expand Up @@ -1347,6 +1380,26 @@ private static Val val(long i) {
return new Val(String.format("bar%03d", i), i, new Pojo(i));
}

/**
* @param sql SQL query.
* @param args Query parameters.
* @return Results cursor.
*/
private FieldsQueryCursor<List<?>> sql(String sql, Object ... args) {
return sql(grid(), sql, args);
}

/**
* @param ign Node.
* @param sql SQL query.
* @param args Query parameters.
* @return Results cursor.
*/
private FieldsQueryCursor<List<?>> sql(IgniteEx ign, String sql, Object ... args) {
return ign.context().query().querySqlFields(new SqlFieldsQuery(sql)
.setArgs(args), false);
}

/** */
private static class Key {
/** */
Expand Down

0 comments on commit 0534488

Please sign in to comment.