use of com.wplatform.ddal.dbobject.table.IndexColumn in project jdbc-shards by wplatform.
the class IndexMate method getCostRangeIndex.
/**
* Calculate the cost for the given mask as if this index was a typical
* b-tree range index. This is the estimated cost required to search one
* row, and then iterate over the given number of rows.
*
* @param masks the search mask
* @param rowCount the number of rows in the index
* @param filter the table filter
* @param sortOrder the sort order
* @return the estimated cost
*/
protected long getCostRangeIndex(int[] masks, long rowCount, TableFilter filter, SortOrder sortOrder) {
rowCount += Constants.COST_ROW_OFFSET;
long cost = rowCount;
long rows = rowCount;
int totalSelectivity = 0;
if (masks == null) {
return cost;
}
for (int i = 0, len = columns.length; i < len; i++) {
Column column = columns[i];
int index = column.getColumnId();
int mask = masks[index];
if ((mask & IndexCondition.EQUALITY) == IndexCondition.EQUALITY) {
if (i == columns.length - 1 && getIndexType().isUnique()) {
cost = 3;
break;
}
totalSelectivity = 100 - ((100 - totalSelectivity) * (100 - column.getSelectivity()) / 100);
long distinctRows = rowCount * totalSelectivity / 100;
if (distinctRows <= 0) {
distinctRows = 1;
}
rows = Math.max(rowCount / distinctRows, 1);
cost = 2 + rows;
} else if ((mask & IndexCondition.RANGE) == IndexCondition.RANGE) {
cost = 2 + rows / 4;
break;
} else if ((mask & IndexCondition.START) == IndexCondition.START) {
cost = 2 + rows / 3;
break;
} else if ((mask & IndexCondition.END) == IndexCondition.END) {
cost = rows / 3;
break;
} else {
break;
}
}
// it will be cheaper than another index, so adjust the cost accordingly
if (sortOrder != null) {
boolean sortOrderMatches = true;
int coveringCount = 0;
int[] sortTypes = sortOrder.getSortTypes();
for (int i = 0, len = sortTypes.length; i < len; i++) {
if (i >= indexColumns.length) {
// more of the order by columns
break;
}
Column col = sortOrder.getColumn(i, filter);
if (col == null) {
sortOrderMatches = false;
break;
}
IndexColumn indexCol = indexColumns[i];
if (col != indexCol.column) {
sortOrderMatches = false;
break;
}
int sortType = sortTypes[i];
if (sortType != indexCol.sortType) {
sortOrderMatches = false;
break;
}
coveringCount++;
}
if (sortOrderMatches) {
// "coveringCount" makes sure that when we have two
// or more covering indexes, we choose the one
// that covers more
cost -= coveringCount;
}
}
return cost;
}
use of com.wplatform.ddal.dbobject.table.IndexColumn in project jdbc-shards by wplatform.
the class CreateTableExecutor method doTranslate.
@Override
protected String doTranslate(TableNode tableNode) {
StatementBuilder buff = new StatementBuilder("CREATE ");
if (prepared.isTemporary()) {
buff.append("TEMPORARY ");
}
buff.append("TABLE ");
if (prepared.isIfNotExists()) {
buff.append("IF NOT EXISTS ");
}
buff.append(identifier(tableNode.getCompositeObjectName()));
if (prepared.getComment() != null) {
// buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(prepared.getComment()));
}
buff.append("(");
for (Column column : prepared.getColumns()) {
buff.appendExceptFirst(", ");
buff.append(column.getCreateSQL());
}
for (DefineCommand command : prepared.getConstraintCommands()) {
buff.appendExceptFirst(", ");
int type = command.getType();
switch(type) {
case CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_PRIMARY_KEY:
{
AlterTableAddConstraint stmt = (AlterTableAddConstraint) command;
buff.append(" CONSTRAINT PRIMARY KEY");
if (stmt.isPrimaryKeyHash()) {
buff.append(" USING HASH");
}
buff.resetCount();
buff.append("(");
for (IndexColumn c : stmt.getIndexColumns()) {
buff.appendExceptFirst(", ");
buff.append(identifier(c.columnName));
}
buff.append(")");
break;
}
case CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_UNIQUE:
{
AlterTableAddConstraint stmt = (AlterTableAddConstraint) command;
buff.append(" CONSTRAINT UNIQUE KEY");
buff.resetCount();
buff.append("(");
for (IndexColumn c : stmt.getIndexColumns()) {
buff.appendExceptFirst(", ");
buff.append(identifier(c.columnName));
}
buff.append(")");
break;
}
case CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_CHECK:
{
AlterTableAddConstraint stmt = (AlterTableAddConstraint) command;
String enclose = StringUtils.enclose(stmt.getCheckExpression().getSQL());
buff.append(" CHECK").append(enclose);
break;
}
case CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_REFERENTIAL:
{
AlterTableAddConstraint stmt = (AlterTableAddConstraint) command;
String refTableName = stmt.getRefTableName();
TableMate table = getTableMate(stmt.getTableName());
TableMate refTable = getTableMate(refTableName);
if (refTable != null) {
TableNode[] partitionNode = refTable.getPartitionNode();
if (partitionNode.length > 1) {
TableNode[] tableNodes = table.getPartitionNode();
TableNode[] refTableNodes = partitionNode;
Map<TableNode, TableNode> symmetryRelation = getSymmetryRelation(tableNodes, refTableNodes);
TableNode relation = symmetryRelation.get(tableNode);
if (relation == null) {
throw DbException.get(ErrorCode.CHECK_CONSTRAINT_INVALID, "The original table and reference table should be symmetrical.");
}
refTableName = relation.getCompositeObjectName();
} else if (partitionNode.length == 1) {
refTableName = partitionNode[0].getCompositeObjectName();
}
}
IndexColumn[] cols = stmt.getIndexColumns();
IndexColumn[] refCols = stmt.getRefIndexColumns();
buff.resetCount();
buff.append(" CONSTRAINT FOREIGN KEY(");
for (IndexColumn c : cols) {
buff.appendExceptFirst(", ");
buff.append(c.columnName);
}
buff.append(")");
buff.append(" REFERENCES ");
buff.append(identifier(refTableName)).append("(");
buff.resetCount();
for (IndexColumn r : refCols) {
buff.appendExceptFirst(", ");
buff.append(r.columnName);
}
buff.append(")");
break;
}
case CommandInterface.CREATE_INDEX:
{
CreateIndex stmt = (CreateIndex) command;
if (stmt.isSpatial()) {
buff.append(" SPATIAL INDEX");
} else {
buff.append(" INDEX");
if (stmt.isHash()) {
buff.append(" USING HASH");
}
}
buff.resetCount();
buff.append("(");
for (IndexColumn c : stmt.getIndexColumns()) {
buff.appendExceptFirst(", ");
buff.append(identifier(c.columnName));
}
buff.append(")");
break;
}
default:
throw DbException.throwInternalError("type=" + type);
}
}
buff.append(")");
if (prepared.getTableEngine() != null) {
buff.append(" ENGINE = ");
buff.append(prepared.getTableEngine());
}
ArrayList<String> tableEngineParams = prepared.getTableEngineParams();
if (tableEngineParams != null && tableEngineParams.isEmpty()) {
buff.append("WITH ");
buff.resetCount();
for (String parameter : tableEngineParams) {
buff.appendExceptFirst(", ");
buff.append(StringUtils.quoteIdentifier(parameter));
}
}
if (prepared.getCharset() != null) {
buff.append(" DEFAULT CHARACTER SET = ");
buff.append(prepared.getCharset());
}
return buff.toString();
}
use of com.wplatform.ddal.dbobject.table.IndexColumn in project jdbc-shards by wplatform.
the class AlterTableAddConstraintExecutor method doBuildReferences.
private String doBuildReferences(String forTable, String forRefTable) {
StatementBuilder buff = new StatementBuilder("ALTER TABLE ");
buff.append(identifier(forTable)).append(" ADD CONSTRAINT ");
String constraintName = prepared.getConstraintName();
if (!StringUtils.isNullOrEmpty(constraintName)) {
buff.append(constraintName);
}
IndexColumn[] cols = prepared.getIndexColumns();
IndexColumn[] refCols = prepared.getRefIndexColumns();
buff.append(" FOREIGN KEY(");
for (IndexColumn c : cols) {
buff.appendExceptFirst(", ");
buff.append(c.getSQL());
}
buff.append(')');
buff.append(" REFERENCES ");
buff.append(forRefTable).append('(');
buff.resetCount();
for (IndexColumn r : refCols) {
buff.appendExceptFirst(", ");
buff.append(r.getSQL());
}
buff.append(')');
if (prepared.getDeleteAction() != AlterTableAddConstraint.RESTRICT) {
buff.append(" ON DELETE ");
appendAction(buff, prepared.getDeleteAction());
}
if (prepared.getUpdateAction() != AlterTableAddConstraint.RESTRICT) {
buff.append(" ON UPDATE ");
appendAction(buff, prepared.getDeleteAction());
}
return buff.toString();
}
use of com.wplatform.ddal.dbobject.table.IndexColumn in project jdbc-shards by wplatform.
the class AlterTableAddConstraintExecutor method doBuildUnique.
private String doBuildUnique(String forTable, String uniqueType) {
StatementBuilder buff = new StatementBuilder("ALTER TABLE ");
buff.append(identifier(forTable)).append(" ADD CONSTRAINT ");
String constraintName = prepared.getConstraintName();
// MySQL constraintName is optional
if (!StringUtils.isNullOrEmpty(constraintName)) {
buff.append(constraintName);
}
buff.append(' ').append(uniqueType);
if (prepared.isPrimaryKeyHash()) {
buff.append(" USING ").append("HASH");
}
buff.append('(');
for (IndexColumn c : prepared.getIndexColumns()) {
buff.appendExceptFirst(", ");
buff.append(identifier(c.column.getName()));
}
buff.append(')');
return buff.toString();
}
Aggregations