use of herddb.core.AbstractIndexManager in project herddb by diennea.
the class SQLPlanner method discoverIndexOperations.
private void discoverIndexOperations(Expression expressionWhere, Table table, String mainTableAlias, SQLRecordPredicate where, TableSpaceManager tableSpaceManager) throws StatementExecutionException {
SQLRecordKeyFunction keyFunction = findIndexAccess(expressionWhere, table.primaryKey, table, mainTableAlias, EqualsTo.class);
IndexOperation result = null;
if (keyFunction != null) {
if (keyFunction.isFullPrimaryKey()) {
result = new PrimaryIndexSeek(keyFunction);
} else {
result = new PrimaryIndexPrefixScan(keyFunction);
}
} else {
SQLRecordKeyFunction rangeMin = findIndexAccess(expressionWhere, table.primaryKey, table, mainTableAlias, GreaterThanEquals.class);
if (rangeMin != null && !rangeMin.isFullPrimaryKey()) {
rangeMin = null;
}
if (rangeMin == null) {
rangeMin = findIndexAccess(expressionWhere, table.primaryKey, table, mainTableAlias, GreaterThan.class);
if (rangeMin != null && !rangeMin.isFullPrimaryKey()) {
rangeMin = null;
}
}
SQLRecordKeyFunction rangeMax = findIndexAccess(expressionWhere, table.primaryKey, table, mainTableAlias, MinorThanEquals.class);
if (rangeMax != null && !rangeMax.isFullPrimaryKey()) {
rangeMax = null;
}
if (rangeMax == null) {
rangeMax = findIndexAccess(expressionWhere, table.primaryKey, table, mainTableAlias, MinorThan.class);
if (rangeMax != null && !rangeMax.isFullPrimaryKey()) {
rangeMax = null;
}
}
if (rangeMin != null || rangeMax != null) {
result = new PrimaryIndexRangeScan(table.primaryKey, rangeMin, rangeMax);
}
}
if (result == null) {
Map<String, AbstractIndexManager> indexes = tableSpaceManager.getIndexesOnTable(table.name);
if (indexes != null) {
// TODO: use some kind of statistics, maybe using an index is more expensive than a full table scan
for (AbstractIndexManager index : indexes.values()) {
if (!index.isAvailable()) {
continue;
}
IndexOperation secondaryIndexOperation = findSecondaryIndexOperation(index, expressionWhere, table);
if (secondaryIndexOperation != null) {
result = secondaryIndexOperation;
break;
}
}
}
}
where.setIndexOperation(result);
Expression filterPk = findFiltersOnPrimaryKey(table, table.name, expressionWhere);
where.setPrimaryKeyFilter(filterPk);
}
use of herddb.core.AbstractIndexManager in project herddb by diennea.
the class SQLPlanner method buildAlterStatement.
private Statement buildAlterStatement(String defaultTableSpace, Alter alter) throws StatementExecutionException {
if (alter.getTable() == null) {
throw new StatementExecutionException("missing table name");
}
String tableSpace = alter.getTable().getSchemaName();
if (tableSpace == null) {
tableSpace = defaultTableSpace;
}
List<Column> addColumns = new ArrayList<>();
List<Column> modifyColumns = new ArrayList<>();
List<String> dropColumns = new ArrayList<>();
String tableName = alter.getTable().getName();
if (alter.getAlterExpressions() == null || alter.getAlterExpressions().size() != 1) {
throw new StatementExecutionException("supported multi-alter operation '" + alter + "'");
}
AlterExpression alterExpression = alter.getAlterExpressions().get(0);
AlterOperation operation = alterExpression.getOperation();
Boolean changeAutoIncrement = null;
switch(operation) {
case ADD:
{
List<AlterExpression.ColumnDataType> cols = alterExpression.getColDataTypeList();
for (AlterExpression.ColumnDataType cl : cols) {
Column newColumn = Column.column(cl.getColumnName(), sqlDataTypeToColumnType(cl.getColDataType().getDataType(), cl.getColDataType().getArgumentsStringList()));
addColumns.add(newColumn);
}
}
break;
case DROP:
dropColumns.add(alterExpression.getColumnName());
break;
case MODIFY:
{
TableSpaceManager tableSpaceManager = manager.getTableSpaceManager(tableSpace);
if (tableSpaceManager == null) {
throw new StatementExecutionException("bad tablespace '" + tableSpace + "'");
}
AbstractTableManager tableManager = tableSpaceManager.getTableManager(tableName);
if (tableManager == null) {
throw new StatementExecutionException("bad table " + tableName + " in tablespace '" + tableSpace + "'");
}
Table table = tableManager.getTable();
List<AlterExpression.ColumnDataType> cols = alterExpression.getColDataTypeList();
for (AlterExpression.ColumnDataType cl : cols) {
String columnName = cl.getColumnName().toLowerCase();
Column oldColumn = table.getColumn(columnName);
if (oldColumn == null) {
throw new StatementExecutionException("bad column " + columnName + " in table " + tableName + " in tablespace '" + tableSpace + "'");
}
Map<String, AbstractIndexManager> indexes = tableSpaceManager.getIndexesOnTable(tableName);
if (indexes != null) {
for (AbstractIndexManager am : indexes.values()) {
for (String indexedColumn : am.getColumnNames()) {
if (indexedColumn.equalsIgnoreCase(oldColumn.name)) {
throw new StatementExecutionException("cannot alter indexed " + columnName + " in table " + tableName + " in tablespace '" + tableSpace + "'," + "index name is " + am.getIndexName());
}
}
}
}
int newType = sqlDataTypeToColumnType(cl.getColDataType().getDataType(), cl.getColDataType().getArgumentsStringList());
if (oldColumn.type != newType) {
throw new StatementExecutionException("cannot change datatype to " + cl.getColDataType().getDataType() + " for column " + columnName + " in table " + tableName + " in tablespace '" + tableSpace + "'");
}
List<String> columnSpecs = decodeColumnSpecs(cl.getColumnSpecs());
if (table.isPrimaryKeyColumn(columnName)) {
boolean new_auto_increment = decodeAutoIncrement(columnSpecs);
if (new_auto_increment && table.primaryKey.length > 1) {
throw new StatementExecutionException("cannot add auto_increment flag to " + cl.getColDataType().getDataType() + " for column " + columnName + " in table " + tableName + " in tablespace '" + tableSpace + "'");
}
if (table.auto_increment != new_auto_increment) {
changeAutoIncrement = new_auto_increment;
}
}
String renameTo = decodeRenameTo(columnSpecs);
if (renameTo != null) {
columnName = renameTo;
}
Column newColumnDef = Column.column(columnName, newType, oldColumn.serialPosition);
modifyColumns.add(newColumnDef);
}
}
break;
default:
throw new StatementExecutionException("supported alter operation '" + alter + "'");
}
return new AlterTableStatement(addColumns, modifyColumns, dropColumns, changeAutoIncrement, tableName, tableSpace, null);
}
use of herddb.core.AbstractIndexManager in project herddb by diennea.
the class CalcitePlanner method scanForIndexAccess.
private IndexOperation scanForIndexAccess(CompiledSQLExpression expressionWhere, Table table, TableSpaceManager tableSpaceManager) {
SQLRecordKeyFunction keyFunction = findIndexAccess(expressionWhere, table.primaryKey, table, "=", table);
IndexOperation result = null;
if (keyFunction != null) {
if (keyFunction.isFullPrimaryKey()) {
result = new PrimaryIndexSeek(keyFunction);
} else {
result = new PrimaryIndexPrefixScan(keyFunction);
}
} else {
SQLRecordKeyFunction rangeMin = findIndexAccess(expressionWhere, table.primaryKey, table, ">=", table);
if (rangeMin != null && !rangeMin.isFullPrimaryKey()) {
rangeMin = null;
}
if (rangeMin == null) {
rangeMin = findIndexAccess(expressionWhere, table.primaryKey, table, ">", table);
if (rangeMin != null && !rangeMin.isFullPrimaryKey()) {
rangeMin = null;
}
}
SQLRecordKeyFunction rangeMax = findIndexAccess(expressionWhere, table.primaryKey, table, "<=", table);
if (rangeMax != null && !rangeMax.isFullPrimaryKey()) {
rangeMax = null;
}
if (rangeMax == null) {
rangeMax = findIndexAccess(expressionWhere, table.primaryKey, table, "<", table);
if (rangeMax != null && !rangeMax.isFullPrimaryKey()) {
rangeMax = null;
}
}
if (rangeMin != null || rangeMax != null) {
result = new PrimaryIndexRangeScan(table.primaryKey, rangeMin, rangeMax);
}
}
if (result == null) {
Map<String, AbstractIndexManager> indexes = tableSpaceManager.getIndexesOnTable(table.name);
if (indexes != null) {
// TODO: use some kind of statistics, maybe using an index is more expensive than a full table scan
for (AbstractIndexManager index : indexes.values()) {
if (!index.isAvailable()) {
continue;
}
IndexOperation secondaryIndexOperation = findSecondaryIndexOperation(index, expressionWhere, table);
if (secondaryIndexOperation != null) {
result = secondaryIndexOperation;
break;
}
}
}
}
return result;
}
Aggregations