Search in sources :

Example 6 with ValuesClause

use of com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause in project druid by alibaba.

the class WallVisitorUtils method checkInsertForMultiTenant.

private static void checkInsertForMultiTenant(WallVisitor visitor, SQLInsertInto x) {
    TenantCallBack tenantCallBack = visitor.getConfig().getTenantCallBack();
    String tenantTablePattern = visitor.getConfig().getTenantTablePattern();
    if (tenantCallBack == null && (tenantTablePattern == null || tenantTablePattern.length() == 0)) {
        return;
    }
    if (x == null) {
        throw new IllegalStateException("x is null");
    }
    SQLExprTableSource tableSource = x.getTableSource();
    String alias = null;
    String matchTableName = null;
    String tenantColumn = null;
    SQLExpr tableExpr = tableSource.getExpr();
    if (tableExpr instanceof SQLIdentifierExpr) {
        String tableName = ((SQLIdentifierExpr) tableExpr).getName();
        if (tenantCallBack != null) {
            tenantColumn = tenantCallBack.getTenantColumn(StatementType.INSERT, tableName);
        }
        if (StringUtils.isEmpty(tenantColumn) && ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName)) {
            tenantColumn = visitor.getConfig().getTenantColumn();
        }
        if (!StringUtils.isEmpty(tenantColumn)) {
            matchTableName = tableName;
            alias = tableSource.getAlias();
        }
    }
    if (matchTableName == null) {
        return;
    }
    SQLExpr item = null;
    if (alias != null) {
        item = new SQLPropertyExpr(new SQLIdentifierExpr(alias), tenantColumn);
    } else {
        item = new SQLIdentifierExpr(tenantColumn);
    }
    SQLExpr value = generateTenantValue(visitor, alias, StatementType.INSERT, matchTableName);
    // add insert item and value
    x.getColumns().add(item);
    List<ValuesClause> valuesClauses = null;
    ValuesClause valuesClause = null;
    if (x instanceof MySqlInsertStatement) {
        valuesClauses = ((MySqlInsertStatement) x).getValuesList();
    } else if (x instanceof SQLServerInsertStatement) {
        valuesClauses = ((MySqlInsertStatement) x).getValuesList();
    } else {
        valuesClause = x.getValues();
    }
    if (valuesClauses != null && valuesClauses.size() > 0) {
        for (ValuesClause clause : valuesClauses) {
            clause.addValue(value);
        }
    }
    if (valuesClause != null) {
        valuesClause.addValue(value);
    }
    // insert .. select
    SQLSelect select = x.getQuery();
    if (select != null) {
        List<SQLSelectQueryBlock> queryBlocks = splitSQLSelectQuery(select.getQuery());
        for (SQLSelectQueryBlock queryBlock : queryBlocks) {
            queryBlock.getSelectList().add(new SQLSelectItem(value));
        }
    }
    visitor.setSqlModified(true);
}
Also used : TenantCallBack(com.alibaba.druid.wall.WallConfig.TenantCallBack) SQLServerInsertStatement(com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement) ValuesClause(com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause)

Example 7 with ValuesClause

use of com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause in project Mycat_plus by coderczp.

the class BatchInsertSequence method route.

@Override
public void route(SystemConfig sysConfig, SchemaConfig schema, int sqlType, String realSQL, String charset, ServerConnection sc, LayerCachePool cachePool) {
    int rs = ServerParse.parse(realSQL);
    this.sqltype = rs & 0xff;
    this.sysConfig = sysConfig;
    this.schema = schema;
    this.charset = charset;
    this.sc = sc;
    this.cachePool = cachePool;
    try {
        MySqlStatementParser parser = new MySqlStatementParser(realSQL);
        SQLStatement statement = parser.parseStatement();
        MySqlInsertStatement insert = (MySqlInsertStatement) statement;
        if (insert.getValuesList() != null) {
            String tableName = StringUtil.getTableName(realSQL).toUpperCase();
            TableConfig tableConfig = schema.getTables().get(tableName);
            // 获得表的主键字段
            String primaryKey = tableConfig.getPrimaryKey();
            SQLIdentifierExpr sqlIdentifierExpr = new SQLIdentifierExpr();
            sqlIdentifierExpr.setName(primaryKey);
            insert.getColumns().add(sqlIdentifierExpr);
            if (sequenceHandler == null) {
                int seqHandlerType = MycatServer.getInstance().getConfig().getSystem().getSequnceHandlerType();
                switch(seqHandlerType) {
                    case SystemConfig.SEQUENCEHANDLER_MYSQLDB:
                        sequenceHandler = IncrSequenceMySQLHandler.getInstance();
                        break;
                    case SystemConfig.SEQUENCEHANDLER_LOCALFILE:
                        sequenceHandler = IncrSequencePropHandler.getInstance();
                        break;
                    case SystemConfig.SEQUENCEHANDLER_LOCAL_TIME:
                        sequenceHandler = IncrSequenceTimeHandler.getInstance();
                        break;
                    case SystemConfig.SEQUENCEHANDLER_ZK_DISTRIBUTED:
                        sequenceHandler = DistributedSequenceHandler.getInstance(MycatServer.getInstance().getConfig().getSystem());
                        break;
                    case SystemConfig.SEQUENCEHANDLER_ZK_GLOBAL_INCREMENT:
                        sequenceHandler = IncrSequenceZKHandler.getInstance();
                        break;
                    default:
                        throw new java.lang.IllegalArgumentException("Invalid sequnce handler type " + seqHandlerType);
                }
            }
            for (ValuesClause vc : insert.getValuesList()) {
                SQLIntegerExpr sqlIntegerExpr = new SQLIntegerExpr();
                long value = sequenceHandler.nextId(tableName.toUpperCase());
                // 插入生成的sequence值
                sqlIntegerExpr.setNumber(value);
                vc.addValue(sqlIntegerExpr);
            }
            String insertSql = insert.toString();
            this.executeSql = insertSql;
        }
    } catch (Exception e) {
        LOGGER.error("BatchInsertSequence.route(......)", e);
    }
}
Also used : SQLIdentifierExpr(com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr) MySqlInsertStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement) SQLStatement(com.alibaba.druid.sql.ast.SQLStatement) TableConfig(io.mycat.config.model.TableConfig) SQLIntegerExpr(com.alibaba.druid.sql.ast.expr.SQLIntegerExpr) MySqlStatementParser(com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser) ValuesClause(com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause)

Example 8 with ValuesClause

use of com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause in project Mycat_plus by coderczp.

the class DruidInsertParser method parserBatchInsert.

/**
 * insert into .... select .... 或insert into table() values (),(),....
 * @param schema
 * @param rrs
 * @param insertStmt
 * @throws SQLNonTransientException
 */
private void parserBatchInsert(SchemaConfig schema, RouteResultset rrs, String partitionColumn, String tableName, MySqlInsertStatement insertStmt) throws SQLNonTransientException {
    // insert into table() values (),(),....
    if (insertStmt.getValuesList().size() > 1) {
        // 字段列数
        int columnNum = insertStmt.getColumns().size();
        int shardingColIndex = getShardingColIndex(insertStmt, partitionColumn);
        if (shardingColIndex == -1) {
            String msg = "bad insert sql (sharding column:" + partitionColumn + " not provided," + insertStmt;
            LOGGER.warn(msg);
            throw new SQLNonTransientException(msg);
        } else {
            List<ValuesClause> valueClauseList = insertStmt.getValuesList();
            Map<Integer, List<ValuesClause>> nodeValuesMap = new HashMap<Integer, List<ValuesClause>>();
            Map<Integer, Integer> slotsMap = 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.warn(msg);
                    throw new SQLNonTransientException(msg);
                }
                SQLExpr expr = valueClause.getValues().get(shardingColIndex);
                String shardingValue = null;
                if (expr instanceof SQLIntegerExpr) {
                    SQLIntegerExpr intExpr = (SQLIntegerExpr) expr;
                    shardingValue = intExpr.getNumber() + "";
                } else if (expr instanceof SQLCharExpr) {
                    SQLCharExpr charExpr = (SQLCharExpr) expr;
                    shardingValue = charExpr.getText();
                }
                Integer nodeIndex = algorithm.calculate(shardingValue);
                if (algorithm instanceof SlotFunction) {
                    slotsMap.put(nodeIndex, ((SlotFunction) algorithm).slotValue());
                }
                // 没找到插入的分片
                if (nodeIndex == null) {
                    String msg = "can't find any valid datanode :" + tableName + " -> " + partitionColumn + " -> " + shardingValue;
                    LOGGER.warn(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(), insertStmt.toString());
                if (algorithm instanceof SlotFunction) {
                    nodes[count].setSlot(slotsMap.get(nodeIndex));
                    nodes[count].setStatement(ParseUtil.changeInsertAddSlot(nodes[count].getStatement(), nodes[count].getSlot()));
                }
                nodes[count++].setSource(rrs);
            }
            rrs.setNodes(nodes);
            rrs.setFinishedRoute(true);
        }
    } else if (insertStmt.getQuery() != null) {
        // insert into .... select ....
        String msg = "TODO:insert into .... select .... not supported!";
        LOGGER.warn(msg);
        throw new SQLNonTransientException(msg);
    }
}
Also used : AbstractPartitionAlgorithm(io.mycat.route.function.AbstractPartitionAlgorithm) SQLCharExpr(com.alibaba.druid.sql.ast.expr.SQLCharExpr) HashMap(java.util.HashMap) SQLExpr(com.alibaba.druid.sql.ast.SQLExpr) SlotFunction(io.mycat.route.function.SlotFunction) SQLNonTransientException(java.sql.SQLNonTransientException) RouteResultsetNode(io.mycat.route.RouteResultsetNode) TableConfig(io.mycat.config.model.TableConfig) SQLIntegerExpr(com.alibaba.druid.sql.ast.expr.SQLIntegerExpr) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) ValuesClause(com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause)

Example 9 with ValuesClause

use of com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause in project Mycat-Server by MyCATApache.

the class DruidInsertParser method parserBatchInsert.

/**
 * insert into .... select .... 或insert into table() values (),(),....
 * @param schema
 * @param rrs
 * @param insertStmt
 * @throws SQLNonTransientException
 */
private void parserBatchInsert(SchemaConfig schema, RouteResultset rrs, String partitionColumn, String tableName, MySqlInsertStatement insertStmt) throws SQLNonTransientException {
    // insert into table() values (),(),....
    if (insertStmt.getValuesList().size() > 1) {
        // 字段列数
        int columnNum = insertStmt.getColumns().size();
        int shardingColIndex = getShardingColIndex(insertStmt, partitionColumn);
        if (shardingColIndex == -1) {
            String msg = "bad insert sql (sharding column:" + partitionColumn + " not provided," + insertStmt;
            LOGGER.warn(msg);
            throw new SQLNonTransientException(msg);
        } else {
            List<ValuesClause> valueClauseList = insertStmt.getValuesList();
            Map<Integer, List<ValuesClause>> nodeValuesMap = new HashMap<Integer, List<ValuesClause>>();
            Map<Integer, Integer> slotsMap = 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.warn(msg);
                    throw new SQLNonTransientException(msg);
                }
                SQLExpr expr = valueClause.getValues().get(shardingColIndex);
                String shardingValue = null;
                if (expr instanceof SQLIntegerExpr) {
                    SQLIntegerExpr intExpr = (SQLIntegerExpr) expr;
                    shardingValue = intExpr.getNumber() + "";
                } else if (expr instanceof SQLCharExpr) {
                    SQLCharExpr charExpr = (SQLCharExpr) expr;
                    shardingValue = charExpr.getText();
                }
                Integer nodeIndex = algorithm.calculate(shardingValue);
                if (algorithm instanceof SlotFunction) {
                    slotsMap.put(nodeIndex, ((SlotFunction) algorithm).slotValue());
                }
                // 没找到插入的分片
                if (nodeIndex == null) {
                    String msg = "can't find any valid datanode :" + tableName + " -> " + partitionColumn + " -> " + shardingValue;
                    LOGGER.warn(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(), insertStmt.toString());
                if (algorithm instanceof SlotFunction) {
                    nodes[count].setSlot(slotsMap.get(nodeIndex));
                    nodes[count].setStatement(ParseUtil.changeInsertAddSlot(nodes[count].getStatement(), nodes[count].getSlot()));
                }
                nodes[count++].setSource(rrs);
            }
            rrs.setNodes(nodes);
            rrs.setFinishedRoute(true);
        }
    } else if (insertStmt.getQuery() != null) {
        // insert into .... select ....
        String msg = "TODO:insert into .... select .... not supported!";
        LOGGER.warn(msg);
        throw new SQLNonTransientException(msg);
    }
}
Also used : AbstractPartitionAlgorithm(io.mycat.route.function.AbstractPartitionAlgorithm) SQLCharExpr(com.alibaba.druid.sql.ast.expr.SQLCharExpr) HashMap(java.util.HashMap) SQLExpr(com.alibaba.druid.sql.ast.SQLExpr) SlotFunction(io.mycat.route.function.SlotFunction) SQLNonTransientException(java.sql.SQLNonTransientException) RouteResultsetNode(io.mycat.route.RouteResultsetNode) TableConfig(io.mycat.config.model.TableConfig) SQLIntegerExpr(com.alibaba.druid.sql.ast.expr.SQLIntegerExpr) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) ValuesClause(com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause)

Example 10 with ValuesClause

use of com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause in project Mycat-Server by MyCATApache.

the class BatchInsertSequence method route.

@Override
public void route(SystemConfig sysConfig, SchemaConfig schema, int sqlType, String realSQL, String charset, ServerConnection sc, LayerCachePool cachePool) {
    int rs = ServerParse.parse(realSQL);
    this.sqltype = rs & 0xff;
    this.sysConfig = sysConfig;
    this.schema = schema;
    this.charset = charset;
    this.sc = sc;
    this.cachePool = cachePool;
    try {
        MySqlStatementParser parser = new MySqlStatementParser(realSQL);
        SQLStatement statement = parser.parseStatement();
        MySqlInsertStatement insert = (MySqlInsertStatement) statement;
        if (insert.getValuesList() != null) {
            String tableName = StringUtil.getTableName(realSQL).toUpperCase();
            TableConfig tableConfig = schema.getTables().get(tableName);
            // 获得表的主键字段
            String primaryKey = tableConfig.getPrimaryKey();
            SQLIdentifierExpr sqlIdentifierExpr = new SQLIdentifierExpr();
            sqlIdentifierExpr.setName(primaryKey);
            insert.getColumns().add(sqlIdentifierExpr);
            if (sequenceHandler == null) {
                int seqHandlerType = MycatServer.getInstance().getConfig().getSystem().getSequnceHandlerType();
                switch(seqHandlerType) {
                    case SystemConfig.SEQUENCEHANDLER_MYSQLDB:
                        sequenceHandler = IncrSequenceMySQLHandler.getInstance();
                        break;
                    case SystemConfig.SEQUENCEHANDLER_LOCALFILE:
                        sequenceHandler = IncrSequencePropHandler.getInstance();
                        break;
                    case SystemConfig.SEQUENCEHANDLER_LOCAL_TIME:
                        sequenceHandler = IncrSequenceTimeHandler.getInstance();
                        break;
                    case SystemConfig.SEQUENCEHANDLER_ZK_DISTRIBUTED:
                        sequenceHandler = DistributedSequenceHandler.getInstance(MycatServer.getInstance().getConfig().getSystem());
                        break;
                    case SystemConfig.SEQUENCEHANDLER_ZK_GLOBAL_INCREMENT:
                        sequenceHandler = IncrSequenceZKHandler.getInstance();
                        break;
                    default:
                        throw new java.lang.IllegalArgumentException("Invalid sequnce handler type " + seqHandlerType);
                }
            }
            for (ValuesClause vc : insert.getValuesList()) {
                SQLIntegerExpr sqlIntegerExpr = new SQLIntegerExpr();
                long value = sequenceHandler.nextId(tableName.toUpperCase());
                // 插入生成的sequence值
                sqlIntegerExpr.setNumber(value);
                vc.addValue(sqlIntegerExpr);
            }
            String insertSql = insert.toString();
            this.executeSql = insertSql;
        }
    } catch (Exception e) {
        LOGGER.error("BatchInsertSequence.route(......)", e);
    }
}
Also used : SQLIdentifierExpr(com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr) MySqlInsertStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement) SQLStatement(com.alibaba.druid.sql.ast.SQLStatement) TableConfig(io.mycat.config.model.TableConfig) SQLIntegerExpr(com.alibaba.druid.sql.ast.expr.SQLIntegerExpr) MySqlStatementParser(com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser) ValuesClause(com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause)

Aggregations

ValuesClause (com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause)10 SQLExpr (com.alibaba.druid.sql.ast.SQLExpr)6 SQLIntegerExpr (com.alibaba.druid.sql.ast.expr.SQLIntegerExpr)5 SQLStatement (com.alibaba.druid.sql.ast.SQLStatement)4 MySqlInsertStatement (com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement)4 MySqlStatementParser (com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser)4 TableConfig (io.mycat.config.model.TableConfig)4 SQLCharExpr (com.alibaba.druid.sql.ast.expr.SQLCharExpr)3 SQLNonTransientException (java.sql.SQLNonTransientException)3 SQLIdentifierExpr (com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr)2 SQLConstraint (com.alibaba.druid.sql.ast.statement.SQLConstraint)2 RouteResultsetNode (io.mycat.route.RouteResultsetNode)2 AbstractPartitionAlgorithm (io.mycat.route.function.AbstractPartitionAlgorithm)2 SlotFunction (io.mycat.route.function.SlotFunction)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Map (java.util.Map)2 SchemaConfig (com.actiontech.dble.config.model.SchemaConfig)1 TableConfig (com.actiontech.dble.config.model.TableConfig)1