Search in sources :

Example 11 with SchemaConfig

use of com.actiontech.dble.config.model.SchemaConfig in project dble by actiontech.

the class DruidInsertParser method parserBatchInsert.

/**
 * insert into .... select .... or insert into table() values (),(),....
 *
 * @param schemaInfo SchemaInfo
 * @param rrs RouteResultset
 * @param partitionColumn partitionColumn
 * @param insertStmt insertStmt
 * @throws SQLNonTransientException if the column size of values is not correct
 */
private void parserBatchInsert(SchemaInfo schemaInfo, RouteResultset rrs, String partitionColumn, MySqlInsertStatement insertStmt) throws SQLNonTransientException {
    // insert into table() values (),(),....
    SchemaConfig schema = schemaInfo.getSchemaConfig();
    String tableName = schemaInfo.getTable();
    // the size of columns
    int columnNum = getTableColumns(schemaInfo, insertStmt.getColumns());
    int shardingColIndex = tryGetShardingColIndex(schemaInfo, insertStmt, partitionColumn);
    List<ValuesClause> valueClauseList = insertStmt.getValuesList();
    Map<Integer, List<ValuesClause>> nodeValuesMap = new HashMap<>();
    TableConfig tableConfig = schema.getTables().get(tableName);
    AbstractPartitionAlgorithm algorithm = tableConfig.getRule().getRuleAlgorithm();
    for (ValuesClause valueClause : valueClauseList) {
        if (valueClause.getValues().size() != columnNum) {
            String msg = "bad insert sql columnSize != valueSize:" + columnNum + " != " + valueClause.getValues().size() + "values:" + valueClause;
            LOGGER.info(msg);
            throw new SQLNonTransientException(msg);
        }
        SQLExpr expr = valueClause.getValues().get(shardingColIndex);
        String shardingValue = shardingValueToSting(expr);
        Integer nodeIndex = algorithm.calculate(shardingValue);
        // null means can't find any valid index
        if (nodeIndex == null) {
            String msg = "can't find any valid datanode :" + tableName + " -> " + partitionColumn + " -> " + shardingValue;
            LOGGER.info(msg);
            throw new SQLNonTransientException(msg);
        }
        if (nodeValuesMap.get(nodeIndex) == null) {
            nodeValuesMap.put(nodeIndex, new ArrayList<ValuesClause>());
        }
        nodeValuesMap.get(nodeIndex).add(valueClause);
    }
    RouteResultsetNode[] nodes = new RouteResultsetNode[nodeValuesMap.size()];
    int count = 0;
    for (Map.Entry<Integer, List<ValuesClause>> node : nodeValuesMap.entrySet()) {
        Integer nodeIndex = node.getKey();
        List<ValuesClause> valuesList = node.getValue();
        insertStmt.setValuesList(valuesList);
        nodes[count] = new RouteResultsetNode(tableConfig.getDataNodes().get(nodeIndex), rrs.getSqlType(), RouterUtil.removeSchema(insertStmt.toString(), schemaInfo.getSchema()));
        count++;
    }
    rrs.setNodes(nodes);
    rrs.setFinishedRoute(true);
}
Also used : AbstractPartitionAlgorithm(com.actiontech.dble.route.function.AbstractPartitionAlgorithm) SchemaConfig(com.actiontech.dble.config.model.SchemaConfig) SQLExpr(com.alibaba.druid.sql.ast.SQLExpr) SQLNonTransientException(java.sql.SQLNonTransientException) RouteResultsetNode(com.actiontech.dble.route.RouteResultsetNode) TableConfig(com.actiontech.dble.config.model.TableConfig) ValuesClause(com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause)

Example 12 with SchemaConfig

use of com.actiontech.dble.config.model.SchemaConfig in project dble by actiontech.

the class DruidReplaceParser method parserBatchInsert.

/**
 * insert into .... select .... OR insert into table() values (),(),....
 *
 * @param schemaInfo SchemaInfo
 * @param rrs RouteResultset
 * @param partitionColumn partitionColumn
 * @param replace MySqlReplaceStatement
 * @throws SQLNonTransientException  if the column size of values is not correct
 */
private void parserBatchInsert(SchemaInfo schemaInfo, RouteResultset rrs, String partitionColumn, MySqlReplaceStatement replace) throws SQLNonTransientException {
    // insert into table() values (),(),....
    SchemaConfig schema = schemaInfo.getSchemaConfig();
    String tableName = schemaInfo.getTable();
    // column number
    int columnNum = getTableColumns(schemaInfo, replace.getColumns());
    int shardingColIndex = tryGetShardingColIndex(schemaInfo, replace, partitionColumn);
    List<SQLInsertStatement.ValuesClause> valueClauseList = replace.getValuesList();
    Map<Integer, List<SQLInsertStatement.ValuesClause>> nodeValuesMap = new HashMap<>();
    TableConfig tableConfig = schema.getTables().get(tableName);
    AbstractPartitionAlgorithm algorithm = tableConfig.getRule().getRuleAlgorithm();
    for (SQLInsertStatement.ValuesClause valueClause : valueClauseList) {
        if (valueClause.getValues().size() != columnNum) {
            String msg = "bad insert sql columnSize != valueSize:" + columnNum + " != " + valueClause.getValues().size() + "values:" + valueClause;
            LOGGER.info(msg);
            throw new SQLNonTransientException(msg);
        }
        SQLExpr expr = valueClause.getValues().get(shardingColIndex);
        String shardingValue = shardingValueToSting(expr);
        Integer nodeIndex = algorithm.calculate(shardingValue);
        // no part find for this record
        if (nodeIndex == null) {
            String msg = "can't find any valid datanode :" + tableName + " -> " + partitionColumn + " -> " + shardingValue;
            LOGGER.info(msg);
            throw new SQLNonTransientException(msg);
        }
        if (nodeValuesMap.get(nodeIndex) == null) {
            nodeValuesMap.put(nodeIndex, new ArrayList<SQLInsertStatement.ValuesClause>());
        }
        nodeValuesMap.get(nodeIndex).add(valueClause);
    }
    RouteResultsetNode[] nodes = new RouteResultsetNode[nodeValuesMap.size()];
    int count = 0;
    for (Map.Entry<Integer, List<SQLInsertStatement.ValuesClause>> node : nodeValuesMap.entrySet()) {
        Integer nodeIndex = node.getKey();
        List<SQLInsertStatement.ValuesClause> valuesList = node.getValue();
        ReplaceTemp temp = new ReplaceTemp(replace);
        temp.setValuesList(valuesList);
        nodes[count] = new RouteResultsetNode(tableConfig.getDataNodes().get(nodeIndex), rrs.getSqlType(), RouterUtil.removeSchema(temp.toString(), schemaInfo.getSchema()));
        count++;
    }
    rrs.setNodes(nodes);
    rrs.setFinishedRoute(true);
}
Also used : AbstractPartitionAlgorithm(com.actiontech.dble.route.function.AbstractPartitionAlgorithm) SchemaConfig(com.actiontech.dble.config.model.SchemaConfig) ReplaceTemp(com.actiontech.dble.route.parser.druid.ReplaceTemp) SQLExpr(com.alibaba.druid.sql.ast.SQLExpr) SQLNonTransientException(java.sql.SQLNonTransientException) RouteResultsetNode(com.actiontech.dble.route.RouteResultsetNode) SQLInsertStatement(com.alibaba.druid.sql.ast.statement.SQLInsertStatement) TableConfig(com.actiontech.dble.config.model.TableConfig)

Example 13 with SchemaConfig

use of com.actiontech.dble.config.model.SchemaConfig in project dble by actiontech.

the class DruidReplaceParser method parserChildTable.

private void parserChildTable(SchemaInfo schemaInfo, final RouteResultset rrs, MySqlReplaceStatement replace, final ServerConnection sc) throws SQLNonTransientException {
    final SchemaConfig schema = schemaInfo.getSchemaConfig();
    String tableName = schemaInfo.getTable();
    final TableConfig tc = schema.getTables().get(tableName);
    // check if the childtable replace with the multi
    if (isMultiReplace(replace)) {
        String msg = "ChildTable multi insert not provided";
        LOGGER.info(msg);
        throw new SQLNonTransientException(msg);
    }
    // find the value of child table join key
    String joinKey = tc.getJoinKey();
    int joinKeyIndex = getJoinKeyIndex(schemaInfo, replace, joinKey);
    final String joinKeyVal = replace.getValuesList().get(0).getValues().get(joinKeyIndex).toString();
    String realVal = StringUtil.removeApostrophe(joinKeyVal);
    final String sql = RouterUtil.removeSchema(replace.toString(), schemaInfo.getSchema());
    rrs.setStatement(sql);
    // try to route by ER parent partition key
    RouteResultset theRrs = routeByERParentKey(rrs, tc, realVal);
    if (theRrs != null) {
        rrs.setFinishedRoute(true);
    } else {
        rrs.setFinishedExecute(true);
        DbleServer.getInstance().getComplexQueryExecutor().execute(new Runnable() {

            // get child result will be blocked, so use ComplexQueryExecutor
            @Override
            public void run() {
                // route by sql query root parent's data node
                String findRootTBSql = tc.getLocateRTableKeySql().toLowerCase() + joinKeyVal;
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("to find root parent's node sql :" + findRootTBSql);
                }
                FetchStoreNodeOfChildTableHandler fetchHandler = new FetchStoreNodeOfChildTableHandler(findRootTBSql, sc.getSession2());
                String dn = fetchHandler.execute(schema.getName(), tc.getRootParent().getDataNodes());
                if (dn == null) {
                    sc.writeErrMessage(ErrorCode.ER_UNKNOWN_ERROR, "can't find (root) parent sharding node for sql:" + sql);
                    return;
                }
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("found partition node for child table to insert " + dn + " sql :" + sql);
                }
                RouterUtil.routeToSingleNode(rrs, dn);
                sc.getSession2().execute(rrs);
            }
        });
    }
}
Also used : SQLNonTransientException(java.sql.SQLNonTransientException) SchemaConfig(com.actiontech.dble.config.model.SchemaConfig) FetchStoreNodeOfChildTableHandler(com.actiontech.dble.backend.mysql.nio.handler.FetchStoreNodeOfChildTableHandler) TableConfig(com.actiontech.dble.config.model.TableConfig) RouteResultset(com.actiontech.dble.route.RouteResultset)

Example 14 with SchemaConfig

use of com.actiontech.dble.config.model.SchemaConfig in project dble by actiontech.

the class DruidSelectParser method executeComplexSQL.

private SchemaConfig executeComplexSQL(String schemaName, SchemaConfig schema, RouteResultset rrs, SQLSelectStatement selectStmt, ServerConnection sc) throws SQLException {
    StringPtr sqlSchema = new StringPtr(null);
    if (!SchemaUtil.isNoSharding(sc, selectStmt.getSelect().getQuery(), selectStmt, schemaName, sqlSchema)) {
        rrs.setSqlStatement(selectStmt);
        rrs.setNeedOptimizer(true);
        return schema;
    } else {
        String realSchema = sqlSchema.get() == null ? schemaName : sqlSchema.get();
        SchemaConfig schemaConfig = DbleServer.getInstance().getConfig().getSchemas().get(realSchema);
        rrs.setStatement(RouterUtil.removeSchema(rrs.getStatement(), realSchema));
        RouterUtil.routeToSingleNode(rrs, schemaConfig.getDataNode());
        return schemaConfig;
    }
}
Also used : SchemaConfig(com.actiontech.dble.config.model.SchemaConfig) StringPtr(com.actiontech.dble.plan.common.ptr.StringPtr)

Example 15 with SchemaConfig

use of com.actiontech.dble.config.model.SchemaConfig in project dble by actiontech.

the class DruidSingleUnitSelectParser method visitorParse.

@Override
public SchemaConfig visitorParse(SchemaConfig schema, RouteResultset rrs, SQLStatement stmt, ServerSchemaStatVisitor visitor, ServerConnection sc) throws SQLException {
    SQLSelectStatement selectStmt = (SQLSelectStatement) stmt;
    SQLSelectQuery sqlSelectQuery = selectStmt.getSelect().getQuery();
    String schemaName = schema == null ? null : schema.getName();
    if (sqlSelectQuery instanceof MySqlSelectQueryBlock) {
        MySqlSelectQueryBlock mysqlSelectQuery = (MySqlSelectQueryBlock) selectStmt.getSelect().getQuery();
        SQLTableSource mysqlFrom = mysqlSelectQuery.getFrom();
        if (mysqlFrom == null) {
            RouterUtil.routeNoNameTableToSingleNode(rrs, schema);
            return schema;
        }
        if (mysqlFrom instanceof SQLSubqueryTableSource || mysqlFrom instanceof SQLJoinTableSource || mysqlFrom instanceof SQLUnionQueryTableSource) {
            StringPtr sqlSchema = new StringPtr(null);
            if (SchemaUtil.isNoSharding(sc, selectStmt.getSelect().getQuery(), selectStmt, schemaName, sqlSchema)) {
                String realSchema = sqlSchema.get() == null ? schemaName : sqlSchema.get();
                SchemaConfig schemaConfig = DbleServer.getInstance().getConfig().getSchemas().get(realSchema);
                rrs.setStatement(RouterUtil.removeSchema(rrs.getStatement(), realSchema));
                RouterUtil.routeToSingleNode(rrs, schemaConfig.getDataNode());
                return schemaConfig;
            } else {
                super.visitorParse(schema, rrs, stmt, visitor, sc);
                return schema;
            }
        }
        SQLExprTableSource fromSource = (SQLExprTableSource) mysqlFrom;
        SchemaInfo schemaInfo = SchemaUtil.getSchemaInfo(sc.getUser(), schemaName, fromSource);
        if (schemaInfo.getSchemaConfig() == null) {
            String msg = "No Supported, sql:" + stmt;
            throw new SQLNonTransientException(msg);
        }
        if (!ServerPrivileges.checkPrivilege(sc, schemaInfo.getSchema(), schemaInfo.getTable(), CheckType.SELECT)) {
            String msg = "The statement DML privilege check is not passed, sql:" + stmt;
            throw new SQLNonTransientException(msg);
        }
        rrs.setStatement(RouterUtil.removeSchema(rrs.getStatement(), schemaInfo.getSchema()));
        schema = schemaInfo.getSchemaConfig();
        super.visitorParse(schema, rrs, stmt, visitor, sc);
        if (visitor.isHasSubQuery()) {
            this.getCtx().getRouteCalculateUnits().clear();
        }
        // change canRunInReadDB
        if ((mysqlSelectQuery.isForUpdate() || mysqlSelectQuery.isLockInShareMode()) && !sc.isAutocommit()) {
            rrs.setCanRunInReadDB(false);
        }
    } else if (sqlSelectQuery instanceof MySqlUnionQuery) {
        StringPtr sqlSchema = new StringPtr(null);
        if (SchemaUtil.isNoSharding(sc, selectStmt.getSelect().getQuery(), selectStmt, schemaName, sqlSchema)) {
            String realSchema = sqlSchema.get() == null ? schemaName : sqlSchema.get();
            SchemaConfig schemaConfig = DbleServer.getInstance().getConfig().getSchemas().get(realSchema);
            rrs.setStatement(RouterUtil.removeSchema(rrs.getStatement(), realSchema));
            RouterUtil.routeToSingleNode(rrs, schemaConfig.getDataNode());
            return schemaConfig;
        } else {
            super.visitorParse(schema, rrs, stmt, visitor, sc);
        }
    }
    return schema;
}
Also used : SchemaConfig(com.actiontech.dble.config.model.SchemaConfig) MySqlSelectQueryBlock(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock) SQLNonTransientException(java.sql.SQLNonTransientException) StringPtr(com.actiontech.dble.plan.common.ptr.StringPtr) MySqlUnionQuery(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery) SchemaInfo(com.actiontech.dble.server.util.SchemaUtil.SchemaInfo)

Aggregations

SchemaConfig (com.actiontech.dble.config.model.SchemaConfig)70 TableConfig (com.actiontech.dble.config.model.TableConfig)16 SQLNonTransientException (java.sql.SQLNonTransientException)16 Test (org.junit.Test)15 RouteResultset (com.actiontech.dble.route.RouteResultset)6 PhysicalDBNode (com.actiontech.dble.backend.datasource.PhysicalDBNode)5 ServerConfig (com.actiontech.dble.config.ServerConfig)5 UserConfig (com.actiontech.dble.config.model.UserConfig)5 SQLStatement (com.alibaba.druid.sql.ast.SQLStatement)5 MySqlStatementParser (com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser)5 CacheService (com.actiontech.dble.cache.CacheService)4 EOFPacket (com.actiontech.dble.net.mysql.EOFPacket)4 FieldPacket (com.actiontech.dble.net.mysql.FieldPacket)4 RowDataPacket (com.actiontech.dble.net.mysql.RowDataPacket)4 StringPtr (com.actiontech.dble.plan.common.ptr.StringPtr)4 ByteBuffer (java.nio.ByteBuffer)4 ArrayList (java.util.ArrayList)4 PhysicalDBPool (com.actiontech.dble.backend.datasource.PhysicalDBPool)3 ERTable (com.actiontech.dble.config.model.ERTable)3 FirewallConfig (com.actiontech.dble.config.model.FirewallConfig)3