Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IGNITE-12887 fix handle exception inside index on compare values with… #7659

Merged
merged 4 commits into from Apr 20, 2020
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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