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

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

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