use of herddb.model.StatementExecutionException in project herddb by diennea.
the class JSQLParserPlanner method planAggregate.
private PlannerOp planAggregate(List<SelectExpressionItem> fieldList, OpSchema inputSchema, PlannerOp input, OpSchema originalTableSchema, GroupByElement groupBy) {
List<Column> outputSchemaKeysInGroupBy = new ArrayList<>();
List<String> fieldnamesKeysInGroupBy = new ArrayList<>();
List<Column> outputSchemaAggregationResults = new ArrayList<>();
List<String> fieldnamesAggregationResults = new ArrayList<>();
List<Integer> projectionAggregationResults = new ArrayList<>();
List<List<Integer>> argLists = new ArrayList<>();
List<String> aggtypes = new ArrayList<>();
List<Column> originalOutputSchema = new ArrayList<>();
List<String> originalFieldNames = new ArrayList<>();
Set<String> nonAggregateColumns = new HashSet<>();
int k = 0;
for (SelectExpressionItem sel : fieldList) {
Alias alias = sel.getAlias();
String fieldName = null;
if (alias != null) {
checkSupported(alias.getAliasColumns() == null);
fieldName = fixMySqlBackTicks(alias.getName().toLowerCase());
}
Expression exp = sel.getExpression();
Function fn = SQLParserExpressionCompiler.detectAggregatedFunction(exp);
if (fn != null) {
int type = SQLParserExpressionCompiler.getAggregateFunctionType(exp, inputSchema);
ColumnRef additionalColumn = SQLParserExpressionCompiler.getAggregateFunctionArgument(fn, inputSchema);
aggtypes.add(fixMySqlBackTicks(fn.getName().toLowerCase()));
if (additionalColumn != null) {
// SELECT min(col) -> we have to add "col" to the scan
IntHolder pos = new IntHolder();
findColumnInSchema(additionalColumn.tableName, fixMySqlBackTicks(additionalColumn.name), originalTableSchema, pos);
checkSupported(pos.value >= 0);
argLists.add(Collections.singletonList(pos.value));
} else {
argLists.add(Collections.emptyList());
}
if (fieldName == null) {
fieldName = "expr$" + k;
}
Column col = Column.column(fieldName, type);
outputSchemaAggregationResults.add(col);
originalFieldNames.add(fieldName);
originalOutputSchema.add(col);
fieldnamesAggregationResults.add(fieldName);
projectionAggregationResults.add(k);
} else if (exp instanceof net.sf.jsqlparser.schema.Column) {
net.sf.jsqlparser.schema.Column colRef = (net.sf.jsqlparser.schema.Column) exp;
String tableAlias = extractTableName(colRef);
ColumnRef colInSchema = findColumnInSchema(tableAlias, fixMySqlBackTicks(colRef.getColumnName()), inputSchema, new IntHolder());
checkSupported(colInSchema != null);
if (fieldName == null) {
fieldName = colInSchema.name;
}
Column col = Column.column(fieldName, colInSchema.type);
originalFieldNames.add(fieldName);
originalOutputSchema.add(col);
nonAggregateColumns.add(fieldName);
} else {
checkSupported(false);
}
k++;
}
// GROUP BY
List<Integer> groupedFieldsIndexes = new ArrayList<>();
List<Integer> projectionForGroupByFields = new ArrayList<>();
if (groupBy != null) {
checkSupported(groupBy.getGroupingSets() == null || groupBy.getGroupingSets().isEmpty());
int posInGroupBy = 0;
for (Expression exp : groupBy.getGroupByExpressions()) {
if (exp instanceof net.sf.jsqlparser.schema.Column) {
net.sf.jsqlparser.schema.Column colRef = (net.sf.jsqlparser.schema.Column) exp;
String tableName = extractTableName(colRef);
IntHolder pos = new IntHolder();
ColumnRef colInSchema = findColumnInSchema(tableName, fixMySqlBackTicks(colRef.getColumnName()), inputSchema, pos);
checkSupported(colInSchema != null);
groupedFieldsIndexes.add(pos.value);
fieldnamesKeysInGroupBy.add(fixMySqlBackTicks(colRef.getColumnName()));
outputSchemaKeysInGroupBy.add(colInSchema.toColumn());
projectionForGroupByFields.add(posInGroupBy);
} else {
checkSupported(false);
}
posInGroupBy++;
}
} else {
// -> column MUST be in GROUP BY !
for (String s : nonAggregateColumns) {
throw new StatementExecutionException("field " + s + " MUST appear in GROUP BY clause");
}
}
PlannerOp op;
if (!groupedFieldsIndexes.isEmpty()) {
// this is tricky,
// the AggregateOp always create a result in the form of
// FIELD1,FIELD2......AGG1,AGG2
// Basically it puts all of the results of the aggregation to the right
// So we have to add a projection that makes the resultset appear
// as it is defined in the SELECT clause
List<Column> outputSchema = new ArrayList<>();
outputSchema.addAll(outputSchemaKeysInGroupBy);
outputSchema.addAll(outputSchemaAggregationResults);
Column[] outputSchemaArray = outputSchema.toArray(new Column[0]);
List<String> aggreateFieldNames = new ArrayList<>();
aggreateFieldNames.addAll(fieldnamesKeysInGroupBy);
aggreateFieldNames.addAll(fieldnamesAggregationResults);
op = new AggregateOp(input, aggreateFieldNames.toArray(new String[0]), outputSchemaArray, aggtypes.toArray(new String[0]), argLists, groupedFieldsIndexes);
String[] reodereded = originalFieldNames.toArray(new String[0]);
int[] projections = new int[originalFieldNames.size()];
int i = 0;
for (int pos : projectionForGroupByFields) {
projections[pos] = i++;
}
for (int pos : projectionAggregationResults) {
projections[pos] = i++;
}
ProjectOp.ZeroCopyProjection projection = new ProjectOp.ZeroCopyProjection(reodereded, originalOutputSchema.toArray(new Column[0]), projections);
op = new ProjectOp(projection, op);
} else {
// no "GROUP BY", so no need for an additional projection
// this is the SELECT COUNT(*) FROM TABLE case
op = new AggregateOp(input, originalFieldNames.toArray(new String[0]), originalOutputSchema.toArray(new Column[0]), aggtypes.toArray(new String[0]), argLists, groupedFieldsIndexes);
}
return op;
}
use of herddb.model.StatementExecutionException in project herddb by diennea.
the class JSQLParserPlanner method buildCreateIndexStatement.
private Statement buildCreateIndexStatement(String defaultTableSpace, CreateIndex s) throws StatementExecutionException {
try {
String tableSpace = s.getTable().getSchemaName();
if (tableSpace == null) {
tableSpace = defaultTableSpace;
}
tableSpace = fixMySqlBackTicks(tableSpace);
String tableName = fixMySqlBackTicks(s.getTable().getName().toLowerCase());
String indexName = fixMySqlBackTicks(s.getIndex().getName().toLowerCase());
boolean unique = isUnique(s.getIndex().getType());
String indexType = convertIndexType(s.getIndex().getType());
herddb.model.Index.Builder builder = herddb.model.Index.builder().name(indexName).uuid(UUID.randomUUID().toString()).type(indexType).unique(unique).table(tableName).tablespace(tableSpace);
AbstractTableManager tableDefinition = manager.getTableSpaceManager(tableSpace).getTableManager(tableName);
if (tableDefinition == null) {
throw new TableDoesNotExistException("no such table " + tableName + " in tablespace " + tableSpace);
}
for (String columnName : s.getIndex().getColumnsNames()) {
columnName = fixMySqlBackTicks(columnName.toLowerCase());
Column column = tableDefinition.getTable().getColumn(columnName);
if (column == null) {
throw new StatementExecutionException("no such column " + columnName + " on table " + tableName + " in tablespace " + tableSpace);
}
builder.column(column.name, column.type);
}
CreateIndexStatement statement = new CreateIndexStatement(builder.build());
return statement;
} catch (IllegalArgumentException err) {
throw new StatementExecutionException("bad index definition: " + err.getMessage(), err);
}
}
use of herddb.model.StatementExecutionException in project herddb by diennea.
the class JSQLParserPlanner method buildProjection.
private Projection buildProjection(final List<SelectExpressionItem> projects, final boolean allowIdentity, final OpSchema tableSchema) {
boolean allowZeroCopyProjection = true;
List<CompiledSQLExpression> fields = new ArrayList<>(projects.size());
Column[] columns = new Column[projects.size()];
String[] fieldNames = new String[columns.length];
int i = 0;
int[] zeroCopyProjections = new int[fieldNames.length];
boolean identity = allowIdentity && tableSchema != null && tableSchema.columns.length == fieldNames.length;
for (SelectExpressionItem node : projects) {
int type = ColumnTypes.ANYTYPE;
CompiledSQLExpression exp;
String alias = null;
if (node.getAlias() != null) {
alias = fixMySqlBackTicks(node.getAlias().getName().toLowerCase());
checkSupported(node.getAlias().getAliasColumns() == null);
}
if (node.getExpression() instanceof net.sf.jsqlparser.schema.Column && !isBooleanLiteral((net.sf.jsqlparser.schema.Column) node.getExpression())) {
net.sf.jsqlparser.schema.Column col = (net.sf.jsqlparser.schema.Column) node.getExpression();
// checkSupported(col.getTable() == null);
String columnName = fixMySqlBackTicks(col.getColumnName());
String tableAlias = extractTableName(col);
if (alias == null) {
alias = columnName;
}
IntHolder indexInSchema = new IntHolder(-1);
ColumnRef found = findColumnInSchema(tableAlias, columnName, tableSchema, indexInSchema);
if (indexInSchema.value == -1 || found == null) {
String nameInError = tableAlias != null ? tableAlias + "." + columnName : columnName;
throw new StatementExecutionException("Column " + nameInError + " not found in target table (schema " + tableSchema + ")");
}
exp = new AccessCurrentRowExpression(indexInSchema.value, found.type);
type = found.type;
} else {
exp = SQLParserExpressionCompiler.compileExpression(node.getExpression(), tableSchema);
if (alias == null) {
alias = "col" + i;
}
}
if (exp instanceof AccessCurrentRowExpression) {
AccessCurrentRowExpression accessCurrentRowExpression = (AccessCurrentRowExpression) exp;
int mappedIndex = accessCurrentRowExpression.getIndex();
zeroCopyProjections[i] = mappedIndex;
if (i != mappedIndex) {
identity = false;
}
} else {
allowZeroCopyProjection = false;
}
fields.add(exp);
Column col = Column.column(alias, type);
identity = identity && col.name.equals(tableSchema.columns[i].name);
fieldNames[i] = alias;
columns[i++] = col;
}
if (allowZeroCopyProjection) {
if (identity) {
return Projection.IDENTITY(fieldNames, columns);
}
return new ProjectOp.ZeroCopyProjection(fieldNames, columns, zeroCopyProjections);
} else {
return new ProjectOp.BasicProjection(fieldNames, columns, fields);
}
}
use of herddb.model.StatementExecutionException in project herddb by diennea.
the class ServerSideConnectionPeer method handleRestoreFinished.
private void handleRestoreFinished(Pdu message, Channel channel) {
try {
String tableSpace = PduCodec.TableRestoreFinished.readTablespace(message);
server.getManager().getTableSpaceManager(tableSpace).restoreFinished();
ByteBuf res = PduCodec.AckResponse.write(message.messageId);
channel.sendReplyMessage(message.messageId, res);
} catch (StatementExecutionException err) {
ByteBuf res = composeErrorResponse(message.messageId, err);
channel.sendReplyMessage(message.messageId, res);
}
}
use of herddb.model.StatementExecutionException in project herddb by diennea.
the class ServerSideConnectionPeer method handlePushTableData.
private void handlePushTableData(Pdu message, Channel channel) {
try {
String tableSpace = PduCodec.PushTableData.readTablespace(message);
String table = PduCodec.PushTableData.readTablename(message);
long _start = System.currentTimeMillis();
List<Record> records = new ArrayList<>();
PduCodec.PushTableData.readRecords(message, (key, value) -> records.add(new Record(Bytes.from_array(key), Bytes.from_array(value))));
LOGGER.log(Level.INFO, "Received {0} records for restore of table {1} in tableSpace {2}", new Object[] { records.size(), table, tableSpace });
TableManager tableManager = (TableManager) server.getManager().getTableSpaceManager(tableSpace).getTableManager(table);
tableManager.writeFromDump(records);
long _stop = System.currentTimeMillis();
LOGGER.log(Level.INFO, "Time restore {0} records: data {1} ms", new Object[] { records.size(), _stop - _start });
ByteBuf res = PduCodec.AckResponse.write(message.messageId);
channel.sendReplyMessage(message.messageId, res);
} catch (StatementExecutionException err) {
ByteBuf res = composeErrorResponse(message.messageId, err);
channel.sendReplyMessage(message.messageId, res);
}
}
Aggregations