提交 60fcd5aa authored 作者: Sergi's avatar Sergi

Index hints: Lookup for indexes only once + other minor improvements.

上级 efd50a4e
......@@ -1263,7 +1263,7 @@ public class Parser {
// for backward compatibility, handle case where USE is a table alias
if (readIf("USE")) {
if (readIf("INDEX")) {
indexHints = parseUseIndexList();
indexHints = parseIndexHints(table);
} else {
alias = "USE";
}
......@@ -1273,7 +1273,7 @@ public class Parser {
// if alias present, a second chance to parse index hints
if (readIf("USE")) {
read("INDEX");
indexHints = parseUseIndexList();
indexHints = parseIndexHints(table);
}
}
}
......@@ -1281,18 +1281,20 @@ public class Parser {
currentSelect, orderInFrom++, indexHints);
}
private IndexHints parseUseIndexList() {
private IndexHints parseIndexHints(Table table) {
if (table == null) {
throw getSyntaxError();
}
read("(");
LinkedHashSet<String> indexNames = new LinkedHashSet<>();
if (!readIf(")")) {
do {
indexNames.add(readIdentifierWithSchema());
String indexName = readIdentifierWithSchema();
Index index = table.getIndex(indexName);
indexNames.add(index.getName());
} while (readIf(","));
read(")");
}
return IndexHints.createUseIndexHints(indexNames);
}
......
......@@ -246,6 +246,25 @@ public abstract class Table extends SchemaObjectBase {
*/
public abstract ArrayList<Index> getIndexes();
/**
* Get an index by name.
*
* @param indexName the index name to search for
* @return the found index
*/
public Index getIndex(String indexName) {
ArrayList<Index> indexes = getIndexes();
if (indexes != null) {
for (int i = 0; i < indexes.size(); i++) {
Index index = indexes.get(i);
if (index.getName().equals(indexName)) {
return index;
}
}
}
throw DbException.get(ErrorCode.INDEX_NOT_FOUND_1, indexName);
}
/**
* Check if this table is locked exclusively.
*
......@@ -693,7 +712,7 @@ public abstract class Table extends SchemaObjectBase {
item.cost, item.getIndex().getPlanSQL());
}
ArrayList<Index> indexes = getIndexes();
IndexHints indexHints = getIndexHints(session, filters, filter);
IndexHints indexHints = getIndexHints(filters, filter);
if (indexes != null && masks != null) {
for (int i = 1, size = indexes.size(); i < size; i++) {
......@@ -718,27 +737,12 @@ public abstract class Table extends SchemaObjectBase {
return item;
}
private boolean isIndexExcludedByHints(IndexHints indexHints, Index index) {
private static boolean isIndexExcludedByHints(IndexHints indexHints, Index index) {
return indexHints != null && !indexHints.allowIndex(index);
}
private IndexHints getIndexHints(Session session, TableFilter[] filters, int filter) {
if (filters == null) {
return null;
}
IndexHints indexHints = filters[filter].getIndexHints();
if (indexHints == null) {
return null;
}
// check all index names in hints are valid indexes
for (String indexName : indexHints.getAllowedIndexes()) {
Index index = getSchema().findIndex(session, indexName);
if (index == null) {
throw DbException.get(ErrorCode.INDEX_NOT_FOUND_1, indexName);
}
}
return indexHints;
private static IndexHints getIndexHints(TableFilter[] filters, int filter) {
return filters == null ? null : filters[filter].getIndexHints();
}
/**
......
......@@ -5,6 +5,7 @@
*/
package org.h2.test.db;
import org.h2.api.ErrorCode;
import org.h2.test.TestBase;
import java.sql.Connection;
......@@ -126,10 +127,9 @@ public class TestIndexHints extends TestBase {
fail("Expected exception: "
+ "Index \"IDX_DOESNT_EXIST\" not found");
} catch (SQLException e) {
assert(e.getErrorCode() == 1);
assertEquals(ErrorCode.INDEX_NOT_FOUND_1, e.getErrorCode());
} finally {
conn.close();
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论