Search in sources :

Example 56 with StatementExecutionException

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;
}
Also used : SelectExpressionItem(net.sf.jsqlparser.statement.select.SelectExpressionItem) ArrayList(java.util.ArrayList) StatementExecutionException(herddb.model.StatementExecutionException) Function(net.sf.jsqlparser.expression.Function) CompiledFunction(herddb.sql.expressions.CompiledFunction) RecordFunction(herddb.model.RecordFunction) AutoIncrementPrimaryKeyRecordFunction(herddb.model.AutoIncrementPrimaryKeyRecordFunction) Column(herddb.model.Column) IntHolder(herddb.utils.IntHolder) ItemsList(net.sf.jsqlparser.expression.operators.relational.ItemsList) ArrayList(java.util.ArrayList) ExpressionList(net.sf.jsqlparser.expression.operators.relational.ExpressionList) MultiExpressionList(net.sf.jsqlparser.expression.operators.relational.MultiExpressionList) List(java.util.List) SetOperationList(net.sf.jsqlparser.statement.select.SetOperationList) HashSet(java.util.HashSet) PlannerOp(herddb.model.planner.PlannerOp) ProjectOp(herddb.model.planner.ProjectOp) AggregateOp(herddb.model.planner.AggregateOp) AccessCurrentRowExpression(herddb.sql.expressions.AccessCurrentRowExpression) Expression(net.sf.jsqlparser.expression.Expression) CompiledMultiAndExpression(herddb.sql.expressions.CompiledMultiAndExpression) JdbcParameterExpression(herddb.sql.expressions.JdbcParameterExpression) AlterExpression(net.sf.jsqlparser.statement.alter.AlterExpression) TypedJdbcParameterExpression(herddb.sql.expressions.TypedJdbcParameterExpression) ConstantExpression(herddb.sql.expressions.ConstantExpression) SignedExpression(net.sf.jsqlparser.expression.SignedExpression) CompiledSQLExpression(herddb.sql.expressions.CompiledSQLExpression) CompiledEqualsExpression(herddb.sql.expressions.CompiledEqualsExpression) Alias(net.sf.jsqlparser.expression.Alias) ColumnRef(herddb.sql.expressions.ColumnRef)

Example 57 with StatementExecutionException

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);
    }
}
Also used : TableDoesNotExistException(herddb.model.TableDoesNotExistException) AbstractTableManager(herddb.core.AbstractTableManager) Column(herddb.model.Column) CreateIndexStatement(herddb.model.commands.CreateIndexStatement) CreateIndex(net.sf.jsqlparser.statement.create.index.CreateIndex) ForeignKeyIndex(net.sf.jsqlparser.statement.create.table.ForeignKeyIndex) Index(net.sf.jsqlparser.statement.create.table.Index) StatementExecutionException(herddb.model.StatementExecutionException)

Example 58 with StatementExecutionException

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);
    }
}
Also used : SelectExpressionItem(net.sf.jsqlparser.statement.select.SelectExpressionItem) ArrayList(java.util.ArrayList) AccessCurrentRowExpression(herddb.sql.expressions.AccessCurrentRowExpression) CompiledSQLExpression(herddb.sql.expressions.CompiledSQLExpression) StatementExecutionException(herddb.model.StatementExecutionException) Column(herddb.model.Column) IntHolder(herddb.utils.IntHolder) ColumnRef(herddb.sql.expressions.ColumnRef)

Example 59 with StatementExecutionException

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);
    }
}
Also used : RawString(herddb.utils.RawString) ByteBuf(io.netty.buffer.ByteBuf) StatementExecutionException(herddb.model.StatementExecutionException)

Example 60 with StatementExecutionException

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);
    }
}
Also used : CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) TableManager(herddb.core.TableManager) Record(herddb.model.Record) RawString(herddb.utils.RawString) ByteBuf(io.netty.buffer.ByteBuf) StatementExecutionException(herddb.model.StatementExecutionException)

Aggregations

StatementExecutionException (herddb.model.StatementExecutionException)163 Table (herddb.model.Table)69 ArrayList (java.util.ArrayList)57 DataScanner (herddb.model.DataScanner)49 TransactionContext (herddb.model.TransactionContext)47 DataStorageManagerException (herddb.storage.DataStorageManagerException)40 List (java.util.List)40 DataScannerException (herddb.model.DataScannerException)39 StatementExecutionResult (herddb.model.StatementExecutionResult)39 Column (herddb.model.Column)37 DataAccessor (herddb.utils.DataAccessor)36 LogNotAvailableException (herddb.log.LogNotAvailableException)35 LogEntry (herddb.log.LogEntry)34 Test (org.junit.Test)34 InsertStatement (herddb.model.commands.InsertStatement)32 Bytes (herddb.utils.Bytes)32 CommitLogResult (herddb.log.CommitLogResult)31 Record (herddb.model.Record)31 DMLStatementExecutionResult (herddb.model.DMLStatementExecutionResult)30 Map (java.util.Map)30