[improvement] create/drop index support if [not] exist (#7748)
create or drop index clause support if [not] exist
This commit is contained in:
@ -231,13 +231,13 @@ under the License.
|
||||
Bitmap index supports the following modifications:
|
||||
1. create bitmap index
|
||||
grammar:
|
||||
ADD INDEX index_name (column [, ...],) [USING BITMAP] [COMMENT 'balabala'];
|
||||
ADD INDEX [IF NOT EXISTS] index_name (column [, ...],) [USING BITMAP] [COMMENT 'balabala'];
|
||||
note:
|
||||
1. only supports bitmap index for current version
|
||||
2. BITMAP index only supports apply on single column
|
||||
2. drop index
|
||||
grammar:
|
||||
DROP INDEX index_name;
|
||||
DROP INDEX [IF EXISTS] index_name;
|
||||
|
||||
## example
|
||||
|
||||
@ -418,9 +418,9 @@ under the License.
|
||||
|
||||
[index]
|
||||
1. create index on table1 column siteid using bitmap
|
||||
ALTER TABLE table1 ADD INDEX index_name [USING BITMAP] (siteid) COMMENT 'balabala';
|
||||
ALTER TABLE table1 ADD INDEX [IF NOT EXISTS] index_name [USING BITMAP] (siteid) COMMENT 'balabala';
|
||||
2. drop bitmap index of table1
|
||||
ALTER TABLE table1 DROP INDEX index_name;
|
||||
ALTER TABLE table1 DROP INDEX [IF EXISTS] index_name;
|
||||
|
||||
## keyword
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ under the License.
|
||||
|
||||
This statement is used to create index
|
||||
grammer:
|
||||
CREATE INDEX index_name ON table_name (column [, ...],) [USING BITMAP] [COMMENT'balabala'];
|
||||
CREATE INDEX [IF NOT EXISTS] index_name ON table_name (column [, ...],) [USING BITMAP] [COMMENT'balabala'];
|
||||
note:
|
||||
1. only support bitmap index in current version
|
||||
2. BITMAP index only supports apply to single column
|
||||
@ -38,7 +38,7 @@ under the License.
|
||||
## example
|
||||
|
||||
1. create index on table1 column siteid using bitmap
|
||||
CREATE INDEX index_name ON table1 (siteid) USING BITMAP COMMENT 'balabala';
|
||||
CREATE INDEX [IF NOT EXISTS] index_name ON table1 (siteid) USING BITMAP COMMENT 'balabala';
|
||||
|
||||
## keyword
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ under the License.
|
||||
|
||||
This statement is used to delete index from table
|
||||
grammer:
|
||||
DROP INDEX index_name ON [db_name.]table_name;
|
||||
DROP INDEX [IF EXISTS] index_name ON [db_name.]table_name;
|
||||
|
||||
## keyword
|
||||
|
||||
|
||||
@ -229,14 +229,14 @@ under the License.
|
||||
bitmap index 支持如下几种修改方式
|
||||
1. 创建bitmap 索引
|
||||
语法:
|
||||
ADD INDEX index_name (column [, ...],) [USING BITMAP] [COMMENT 'balabala'];
|
||||
ADD INDEX [IF NOT EXISTS] index_name (column [, ...],) [USING BITMAP] [COMMENT 'balabala'];
|
||||
注意:
|
||||
1. 目前仅支持bitmap 索引
|
||||
1. BITMAP 索引仅在单列上创建
|
||||
|
||||
2. 删除索引
|
||||
语法:
|
||||
DROP INDEX index_name;
|
||||
DROP INDEX [IF EXISTS] index_name;
|
||||
|
||||
## example
|
||||
|
||||
@ -413,9 +413,9 @@ under the License.
|
||||
ALTER TABLE example_table RENAME PARTITION p1 p2;
|
||||
[index]
|
||||
1. 在table1 上为siteid 创建bitmap 索引
|
||||
ALTER TABLE table1 ADD INDEX index_name (siteid) [USING BITMAP] COMMENT 'balabala';
|
||||
ALTER TABLE table1 ADD INDEX [IF NOT EXISTS] index_name (siteid) [USING BITMAP] COMMENT 'balabala';
|
||||
2. 删除table1 上的siteid列的bitmap 索引
|
||||
ALTER TABLE table1 DROP INDEX index_name;
|
||||
ALTER TABLE table1 DROP INDEX [IF EXISTS] index_name;
|
||||
|
||||
## keyword
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ under the License.
|
||||
|
||||
该语句用于创建索引
|
||||
语法:
|
||||
CREATE INDEX index_name ON table_name (column [, ...],) [USING BITMAP] [COMMENT'balabala'];
|
||||
CREATE INDEX [IF NOT EXISTS] index_name ON table_name (column [, ...],) [USING BITMAP] [COMMENT'balabala'];
|
||||
注意:
|
||||
1. 目前只支持bitmap 索引
|
||||
2. BITMAP 索引仅在单列上创建
|
||||
@ -38,7 +38,7 @@ under the License.
|
||||
## example
|
||||
|
||||
1. 在table1 上为siteid 创建bitmap 索引
|
||||
CREATE INDEX index_name ON table1 (siteid) USING BITMAP COMMENT 'balabala';
|
||||
CREATE INDEX [IF NOT EXISTS] index_name ON table1 (siteid) USING BITMAP COMMENT 'balabala';
|
||||
|
||||
## keyword
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ under the License.
|
||||
|
||||
该语句用于从一个表中删除指定名称的索引,目前仅支持bitmap 索引
|
||||
语法:
|
||||
DROP INDEX index_name ON [db_name.]table_name;
|
||||
DROP INDEX [IF EXISTS] index_name ON [db_name.]table_name;
|
||||
|
||||
## keyword
|
||||
|
||||
|
||||
@ -1071,9 +1071,9 @@ alter_table_clause ::=
|
||||
{:
|
||||
RESULT = new CreateIndexClause(null, indexDef, true);
|
||||
:}
|
||||
| KW_DROP KW_INDEX ident:indexName
|
||||
| KW_DROP KW_INDEX opt_if_exists:ifExists ident:indexName
|
||||
{:
|
||||
RESULT = new DropIndexClause(indexName, null, true);
|
||||
RESULT = new DropIndexClause(indexName, ifExists, null, true);
|
||||
:}
|
||||
| KW_ENABLE KW_FEATURE STRING_LITERAL:featureName opt_enable_feature_properties:properties
|
||||
{:
|
||||
@ -1302,9 +1302,9 @@ create_stmt ::=
|
||||
{:
|
||||
RESULT = new CreateMaterializedViewStmt(mvName, selectStmt, properties);
|
||||
:}
|
||||
| KW_CREATE KW_INDEX ident:indexName KW_ON table_name:tableName LPAREN ident_list:cols RPAREN opt_index_type:indexType opt_comment:comment
|
||||
| KW_CREATE KW_INDEX opt_if_not_exists:ifNotExists ident:indexName KW_ON table_name:tableName LPAREN ident_list:cols RPAREN opt_index_type:indexType opt_comment:comment
|
||||
{:
|
||||
RESULT = new AlterTableStmt(tableName, Lists.newArrayList(new CreateIndexClause(tableName, new IndexDef(indexName, cols, indexType, comment), false)));
|
||||
RESULT = new AlterTableStmt(tableName, Lists.newArrayList(new CreateIndexClause(tableName, new IndexDef(indexName, ifNotExists, cols, indexType, comment), false)));
|
||||
:}
|
||||
/* resource */
|
||||
| KW_CREATE opt_external:isExternal KW_RESOURCE ident_or_text:resourceName opt_properties:properties
|
||||
@ -2011,9 +2011,9 @@ drop_stmt ::=
|
||||
{:
|
||||
RESULT = new DropFileStmt(fileName, dbName, properties);
|
||||
:}
|
||||
| KW_DROP KW_INDEX ident:indexName KW_ON table_name:tableName
|
||||
| KW_DROP KW_INDEX opt_if_exists:ifExists ident:indexName KW_ON table_name:tableName
|
||||
{:
|
||||
RESULT = new AlterTableStmt(tableName, Lists.newArrayList(new DropIndexClause(indexName, tableName, false)));
|
||||
RESULT = new AlterTableStmt(tableName, Lists.newArrayList(new DropIndexClause(indexName, ifExists, tableName, false)));
|
||||
:}
|
||||
| KW_DROP KW_MATERIALIZED KW_VIEW opt_if_exists:ifExists ident:mvName KW_ON table_name:tableName
|
||||
{:
|
||||
@ -2416,9 +2416,9 @@ column_definition ::=
|
||||
;
|
||||
|
||||
index_definition ::=
|
||||
KW_INDEX ident:indexName LPAREN ident_list:cols RPAREN opt_index_type:indexType opt_comment:comment
|
||||
KW_INDEX opt_if_not_exists:ifNotExists ident:indexName LPAREN ident_list:cols RPAREN opt_index_type:indexType opt_comment:comment
|
||||
{:
|
||||
RESULT = new IndexDef(indexName, cols, indexType, comment);
|
||||
RESULT = new IndexDef(indexName, ifNotExists, cols, indexType, comment);
|
||||
:}
|
||||
;
|
||||
|
||||
|
||||
@ -1702,9 +1702,13 @@ public class SchemaChangeHandler extends AlterHandler {
|
||||
// modify table properties
|
||||
// do nothing, properties are already in propertyMap
|
||||
} else if (alterClause instanceof CreateIndexClause) {
|
||||
processAddIndex((CreateIndexClause) alterClause, olapTable, newIndexes);
|
||||
if (processAddIndex((CreateIndexClause) alterClause, olapTable, newIndexes)) {
|
||||
return;
|
||||
}
|
||||
} else if (alterClause instanceof DropIndexClause) {
|
||||
processDropIndex((DropIndexClause) alterClause, olapTable, newIndexes);
|
||||
if (processDropIndex((DropIndexClause) alterClause, olapTable, newIndexes)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Preconditions.checkState(false);
|
||||
}
|
||||
@ -1967,10 +1971,14 @@ public class SchemaChangeHandler extends AlterHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private void processAddIndex(CreateIndexClause alterClause, OlapTable olapTable, List<Index> newIndexes)
|
||||
/**
|
||||
* Returns true if the index already exists, there is no need to create the job to add the index.
|
||||
* Otherwise return false, there is need to create a job to add the index.
|
||||
*/
|
||||
private boolean processAddIndex(CreateIndexClause alterClause, OlapTable olapTable, List<Index> newIndexes)
|
||||
throws UserException {
|
||||
if (alterClause.getIndex() == null) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
List<Index> existedIndexes = olapTable.getIndexes();
|
||||
@ -1979,6 +1987,10 @@ public class SchemaChangeHandler extends AlterHandler {
|
||||
newColset.addAll(indexDef.getColumns());
|
||||
for (Index existedIdx : existedIndexes) {
|
||||
if (existedIdx.getIndexName().equalsIgnoreCase(indexDef.getIndexName())) {
|
||||
if (indexDef.isSetIfNotExists()) {
|
||||
LOG.info("create index[{}] which already exists on table[{}]", indexDef.getIndexName(), olapTable.getName());
|
||||
return true;
|
||||
}
|
||||
throw new DdlException("index `" + indexDef.getIndexName() + "` already exist.");
|
||||
}
|
||||
Set<String> existedIdxColSet = Sets.newTreeSet(String.CASE_INSENSITIVE_ORDER);
|
||||
@ -1999,9 +2011,14 @@ public class SchemaChangeHandler extends AlterHandler {
|
||||
}
|
||||
|
||||
newIndexes.add(alterClause.getIndex());
|
||||
return false;
|
||||
}
|
||||
|
||||
private void processDropIndex(DropIndexClause alterClause, OlapTable olapTable, List<Index> indexes) throws DdlException {
|
||||
/**
|
||||
* Returns true if the index does not exist, there is no need to create the job to drop the index.
|
||||
* Otherwise return false, there is need to create a job to drop the index.
|
||||
*/
|
||||
private boolean processDropIndex(DropIndexClause alterClause, OlapTable olapTable, List<Index> indexes) throws DdlException {
|
||||
String indexName = alterClause.getIndexName();
|
||||
List<Index> existedIndexes = olapTable.getIndexes();
|
||||
Index found = null;
|
||||
@ -2012,6 +2029,10 @@ public class SchemaChangeHandler extends AlterHandler {
|
||||
}
|
||||
}
|
||||
if (found == null) {
|
||||
if (alterClause.isSetIfExists()) {
|
||||
LOG.info("drop index[{}] which does not exist on table[{}]", indexName, olapTable.getName());
|
||||
return true;
|
||||
}
|
||||
throw new DdlException("index " + indexName + " does not exist");
|
||||
}
|
||||
|
||||
@ -2023,6 +2044,7 @@ public class SchemaChangeHandler extends AlterHandler {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -28,11 +28,14 @@ import java.util.Map;
|
||||
public class DropIndexClause extends AlterTableClause {
|
||||
private final String indexName;
|
||||
private final TableName tableName;
|
||||
private boolean ifExists;
|
||||
|
||||
private boolean alter;
|
||||
|
||||
public DropIndexClause(String indexName, TableName tableName, boolean alter) {
|
||||
public DropIndexClause(String indexName, boolean ifExists, TableName tableName, boolean alter) {
|
||||
super(AlterOpType.SCHEMA_CHANGE);
|
||||
this.indexName = indexName;
|
||||
this.ifExists = ifExists;
|
||||
this.tableName = tableName;
|
||||
this.alter = alter;
|
||||
}
|
||||
@ -45,6 +48,10 @@ public class DropIndexClause extends AlterTableClause {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public boolean isSetIfExists() {
|
||||
return ifExists;
|
||||
}
|
||||
|
||||
public boolean isAlter() {
|
||||
return alter;
|
||||
}
|
||||
|
||||
@ -29,12 +29,14 @@ import java.util.TreeSet;
|
||||
|
||||
public class IndexDef {
|
||||
private String indexName;
|
||||
private boolean ifNotExists;
|
||||
private List<String> columns;
|
||||
private IndexType indexType;
|
||||
private String comment;
|
||||
|
||||
public IndexDef(String indexName, List<String> columns, IndexType indexType, String comment) {
|
||||
public IndexDef(String indexName, boolean ifNotExists, List<String> columns, IndexType indexType, String comment) {
|
||||
this.indexName = indexName;
|
||||
this.ifNotExists = ifNotExists;
|
||||
this.columns = columns;
|
||||
if (indexType == null) {
|
||||
this.indexType = IndexType.BITMAP;
|
||||
@ -118,6 +120,10 @@ public class IndexDef {
|
||||
return comment;
|
||||
}
|
||||
|
||||
public boolean isSetIfNotExists() {
|
||||
return ifNotExists;
|
||||
}
|
||||
|
||||
public enum IndexType {
|
||||
BITMAP,
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ public class CreateIndexClauseTest {
|
||||
|
||||
@Test
|
||||
public void testNormal() throws AnalysisException {
|
||||
CreateIndexClause clause = new CreateIndexClause(new TableName("db", "table"), new IndexDef("index1",
|
||||
CreateIndexClause clause = new CreateIndexClause(new TableName("db", "table"), new IndexDef("index1", false,
|
||||
Lists.newArrayList("col1"), IndexDef.IndexType.BITMAP, "balabala"), false);
|
||||
clause.analyze(analyzer);
|
||||
Assert.assertEquals("CREATE INDEX index1 ON `db`.`table` (`col1`) USING BITMAP COMMENT 'balabala'",
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
package org.apache.doris.analysis;
|
||||
|
||||
import org.apache.doris.catalog.Catalog;
|
||||
import org.apache.doris.common.AnalysisException;
|
||||
import org.apache.doris.common.UserException;
|
||||
|
||||
@ -35,14 +36,14 @@ public class DropIndexClauseTest {
|
||||
|
||||
@Test
|
||||
public void testNormal() throws UserException {
|
||||
DropIndexClause clause = new DropIndexClause("index1", new TableName("db", "table"), false);
|
||||
DropIndexClause clause = new DropIndexClause("index1", false, new TableName("db", "table"), false);
|
||||
clause.analyze(analyzer);
|
||||
Assert.assertEquals("DROP INDEX index1 ON `db`.`table`", clause.toSql());
|
||||
}
|
||||
|
||||
@Test(expected = AnalysisException.class)
|
||||
public void testNoIndex() throws UserException {
|
||||
DropIndexClause clause = new DropIndexClause("", new TableName("db", "table"), false);
|
||||
DropIndexClause clause = new DropIndexClause("", false, new TableName("db", "table"), false);
|
||||
clause.analyze(analyzer);
|
||||
}
|
||||
}
|
||||
@ -30,7 +30,7 @@ public class IndexDefTest {
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
def = new IndexDef("index1", Lists.newArrayList("col1"), IndexDef.IndexType.BITMAP, "balabala");
|
||||
def = new IndexDef("index1", false, Lists.newArrayList("col1"), IndexDef.IndexType.BITMAP, "balabala");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -46,7 +46,7 @@ public class IndexDefTest {
|
||||
+ "xxxxxxxxxxxindex1xxxxxxxxxxxxxxxxxindex1xxxxxxxxxxxxxxxxxindex1xxxxxxxxxxxxxxxxxinde"
|
||||
+ "x1xxxxxxxxxxxxxxxxxindex1xxxxxxxxxxxxxxxxxindex1xxxxxxxxxxxxxxxxxindex1xxxxxxxxxxxxx"
|
||||
+ "xxxxindex1xxxxxxxxxxxxxxxxxindex1xxxxxxxxxxxxxxxxxindex1xxxxxxxxxxxxxxxxxindex1xxxxx"
|
||||
+ "xxxxxxxxxxxxindex1xxxxxxxxxxxxxxxxx",
|
||||
+ "xxxxxxxxxxxxindex1xxxxxxxxxxxxxxxxx", false,
|
||||
Lists.newArrayList("col1"), IndexDef.IndexType.BITMAP,
|
||||
"balabala");
|
||||
def.analyze();
|
||||
@ -55,7 +55,7 @@ public class IndexDefTest {
|
||||
Assert.assertTrue(e instanceof AnalysisException);
|
||||
}
|
||||
try {
|
||||
def = new IndexDef("", Lists.newArrayList("col1"), IndexDef.IndexType.BITMAP, "balabala");
|
||||
def = new IndexDef("", false, Lists.newArrayList("col1"), IndexDef.IndexType.BITMAP, "balabala");
|
||||
def.analyze();
|
||||
Assert.fail("No exception throws.");
|
||||
} catch (AnalysisException e) {
|
||||
|
||||
Reference in New Issue
Block a user