Search in sources :

Example 11 with TableConfig

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

the class DruidReplaceParser method parserSingleInsert.

/**
 * insert single record
 *
 * @param schemaInfo SchemaInfo
 * @param rrs RouteResultset
 * @param partitionColumn partitionColumn
 * @param replaceStatement MySqlReplaceStatement
 * @throws SQLNonTransientException if not find a valid data node
 */
private void parserSingleInsert(SchemaInfo schemaInfo, RouteResultset rrs, String partitionColumn, MySqlReplaceStatement replaceStatement) throws SQLNonTransientException {
    int shardingColIndex = tryGetShardingColIndex(schemaInfo, replaceStatement, partitionColumn);
    SQLExpr valueExpr = replaceStatement.getValuesList().get(0).getValues().get(shardingColIndex);
    String shardingValue = shardingValueToSting(valueExpr);
    TableConfig tableConfig = schemaInfo.getSchemaConfig().getTables().get(schemaInfo.getTable());
    AbstractPartitionAlgorithm algorithm = tableConfig.getRule().getRuleAlgorithm();
    Integer nodeIndex = algorithm.calculate(shardingValue);
    if (nodeIndex == null) {
        String msg = "can't find any valid data node :" + schemaInfo.getTable() + " -> " + partitionColumn + " -> " + shardingValue;
        LOGGER.info(msg);
        throw new SQLNonTransientException(msg);
    }
    RouteResultsetNode[] nodes = new RouteResultsetNode[1];
    nodes[0] = new RouteResultsetNode(tableConfig.getDataNodes().get(nodeIndex), rrs.getSqlType(), RouterUtil.removeSchema(replaceStatement.toString(), schemaInfo.getSchema()));
    rrs.setNodes(nodes);
    rrs.setFinishedRoute(true);
}
Also used : AbstractPartitionAlgorithm(com.actiontech.dble.route.function.AbstractPartitionAlgorithm) SQLNonTransientException(java.sql.SQLNonTransientException) RouteResultsetNode(com.actiontech.dble.route.RouteResultsetNode) TableConfig(com.actiontech.dble.config.model.TableConfig) SQLExpr(com.alibaba.druid.sql.ast.SQLExpr)

Example 12 with TableConfig

use of com.actiontech.dble.config.model.TableConfig 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 13 with TableConfig

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

the class DruidSelectParser 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) sqlSelectQuery;
        if (mysqlSelectQuery.getInto() != null) {
            throw new SQLNonTransientException("select ... into is not supported!");
        }
        SQLTableSource mysqlFrom = mysqlSelectQuery.getFrom();
        if (mysqlFrom == null) {
            List<SQLSelectItem> selectList = mysqlSelectQuery.getSelectList();
            for (SQLSelectItem item : selectList) {
                SQLExpr itemExpr = item.getExpr();
                if (itemExpr instanceof SQLQueryExpr) {
                    rrs.setSqlStatement(selectStmt);
                    rrs.setNeedOptimizer(true);
                    return schema;
                }
            }
            RouterUtil.routeNoNameTableToSingleNode(rrs, schema);
            return schema;
        }
        SchemaInfo schemaInfo;
        if (mysqlFrom instanceof SQLExprTableSource) {
            SQLExprTableSource fromSource = (SQLExprTableSource) mysqlFrom;
            schemaInfo = SchemaUtil.getSchemaInfo(sc.getUser(), schemaName, fromSource);
            if (schemaInfo.isDual()) {
                RouterUtil.routeNoNameTableToSingleNode(rrs, schema);
                return schema;
            }
            if (matchSysTable(rrs, sc, schemaInfo)) {
                return schema;
            }
            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.setSchema(schemaInfo.getSchema());
            rrs.setTable(schemaInfo.getTable());
            rrs.setTableAlias(schemaInfo.getTableAlias());
            rrs.setStatement(RouterUtil.removeSchema(rrs.getStatement(), schemaInfo.getSchema()));
            schema = schemaInfo.getSchemaConfig();
            if (DbleServer.getInstance().getTmManager().getSyncView(schema.getName(), schemaInfo.getTable()) != null) {
                rrs.setNeedOptimizer(true);
                rrs.setSqlStatement(selectStmt);
                return schema;
            }
            if (RouterUtil.isNoSharding(schema, schemaInfo.getTable())) {
                RouterUtil.routeToSingleNode(rrs, schema.getDataNode());
                return schema;
            }
            TableConfig tc = schema.getTables().get(schemaInfo.getTable());
            if (tc == null) {
                String msg = "Table '" + schema.getName() + "." + schemaInfo.getTable() + "' doesn't exist";
                throw new SQLException(msg, "42S02", ErrorCode.ER_NO_SUCH_TABLE);
            }
            super.visitorParse(schema, rrs, stmt, visitor, sc);
            if (visitor.isHasSubQuery()) {
                rrs.setSqlStatement(selectStmt);
                rrs.setNeedOptimizer(true);
                return schema;
            }
            parseOrderAggGroupMysql(schema, stmt, rrs, mysqlSelectQuery, tc);
            // select ...for update /in shard mode /in transaction
            if ((mysqlSelectQuery.isForUpdate() || mysqlSelectQuery.isLockInShareMode()) && !sc.isAutocommit()) {
                rrs.setCanRunInReadDB(false);
            }
        } else if (mysqlFrom instanceof SQLSubqueryTableSource || mysqlFrom instanceof SQLJoinTableSource || mysqlFrom instanceof SQLUnionQueryTableSource) {
            return executeComplexSQL(schemaName, schema, rrs, selectStmt, sc);
        }
    } else if (sqlSelectQuery instanceof MySqlUnionQuery) {
        return executeComplexSQL(schemaName, schema, rrs, selectStmt, sc);
    }
    return schema;
}
Also used : SQLException(java.sql.SQLException) MySqlSelectQueryBlock(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock) SQLNonTransientException(java.sql.SQLNonTransientException) MySqlUnionQuery(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnionQuery) TableConfig(com.actiontech.dble.config.model.TableConfig) SchemaInfo(com.actiontech.dble.server.util.SchemaUtil.SchemaInfo)

Example 14 with TableConfig

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

the class DDLRouteTest method testDDL.

/**
 * ddl deal test
 *
 * @throws Exception
 */
@Test
public void testDDL() throws Exception {
    SchemaConfig schema = schemaMap.get("TESTDB");
    CacheService cacheService = new CacheService(false);
    RouteService routerService = new RouteService(cacheService);
    // create table/view/function/..
    String sql = " create table company(idd int)";
    sql = RouterUtil.getFixedSql(sql);
    String upsql = sql.toUpperCase();
    // TODO : modify by zhuam
    String tablename = "company";
    tablename = tablename.toUpperCase();
    List<String> dataNodes = new ArrayList<>();
    Map<String, TableConfig> tables = schema.getTables();
    TableConfig tc;
    if (tables != null && (tc = tables.get(tablename)) != null) {
        dataNodes = tc.getDataNodes();
    }
    int nodeSize = dataNodes.size();
    int rs = ServerParse.parse(sql);
    int sqlType = rs & 0xff;
    RouteResultset rrs = routerService.route(schema, sqlType, sql, null);
    Assert.assertTrue("COMPANY".equals(tablename));
    Assert.assertTrue(rrs.getNodes().length == nodeSize);
    // drop table test
    sql = " drop table COMPANY";
    sql = RouterUtil.getFixedSql(sql);
    upsql = sql.toUpperCase();
    tablename = "COMPANY";
    tables = schema.getTables();
    if (tables != null && (tc = tables.get(tablename)) != null) {
        dataNodes = tc.getDataNodes();
    }
    nodeSize = dataNodes.size();
    rs = ServerParse.parse(sql);
    sqlType = rs & 0xff;
    rrs = routerService.route(schema, sqlType, sql, null);
    Assert.assertTrue("COMPANY".equals(tablename));
    Assert.assertTrue(rrs.getNodes().length == nodeSize);
    // alter table
    sql = "   alter table COMPANY add COLUMN name int ;";
    sql = RouterUtil.getFixedSql(sql);
    upsql = sql.toUpperCase();
    tablename = "COMPANY";
    tables = schema.getTables();
    if (tables != null && (tc = tables.get(tablename)) != null) {
        dataNodes = tc.getDataNodes();
    }
    nodeSize = dataNodes.size();
    rs = ServerParse.parse(sql);
    sqlType = rs & 0xff;
    rrs = routerService.route(schema, sqlType, sql, null);
    Assert.assertTrue("COMPANY".equals(tablename));
    Assert.assertTrue(rrs.getNodes().length == nodeSize);
    // truncate table;
    sql = " truncate table COMPANY";
    sql = RouterUtil.getFixedSql(sql);
    upsql = sql.toUpperCase();
    tablename = "COMPANY";
    tables = schema.getTables();
    if (tables != null && (tc = tables.get(tablename)) != null) {
        dataNodes = tc.getDataNodes();
    }
    nodeSize = dataNodes.size();
    rs = ServerParse.parse(sql);
    sqlType = rs & 0xff;
    rrs = routerService.route(schema, sqlType, sql, null);
    Assert.assertTrue("COMPANY".equals(tablename));
    Assert.assertTrue(rrs.getNodes().length == nodeSize);
}
Also used : SchemaConfig(com.actiontech.dble.config.model.SchemaConfig) ArrayList(java.util.ArrayList) TableConfig(com.actiontech.dble.config.model.TableConfig) CacheService(com.actiontech.dble.cache.CacheService) Test(org.junit.Test)

Example 15 with TableConfig

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

the class ExplainHandler method isInsertSeq.

private static boolean isInsertSeq(ServerConnection c, String stmt, SchemaConfig schema) throws SQLException {
    SQLStatementParser parser = new MySqlStatementParser(stmt);
    MySqlInsertStatement statement = (MySqlInsertStatement) parser.parseStatement();
    String schemaName = schema == null ? null : schema.getName();
    SQLExprTableSource tableSource = statement.getTableSource();
    SchemaUtil.SchemaInfo schemaInfo = SchemaUtil.getSchemaInfo(c.getUser(), schemaName, tableSource);
    String tableName = schemaInfo.getTable();
    schema = schemaInfo.getSchemaConfig();
    TableConfig tableConfig = schema.getTables().get(tableName);
    if (tableConfig == null) {
        return false;
    } else if (tableConfig.isAutoIncrement()) {
        return true;
    }
    return false;
}
Also used : SQLStatementParser(com.alibaba.druid.sql.parser.SQLStatementParser) SchemaUtil(com.actiontech.dble.server.util.SchemaUtil) TableConfig(com.actiontech.dble.config.model.TableConfig) MySqlInsertStatement(com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement) SQLExprTableSource(com.alibaba.druid.sql.ast.statement.SQLExprTableSource) MySqlStatementParser(com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser)

Aggregations

TableConfig (com.actiontech.dble.config.model.TableConfig)32 SchemaConfig (com.actiontech.dble.config.model.SchemaConfig)16 SQLNonTransientException (java.sql.SQLNonTransientException)16 SQLException (java.sql.SQLException)7 RouteResultsetNode (com.actiontech.dble.route.RouteResultsetNode)6 SchemaInfo (com.actiontech.dble.server.util.SchemaUtil.SchemaInfo)5 RouteResultset (com.actiontech.dble.route.RouteResultset)4 AbstractPartitionAlgorithm (com.actiontech.dble.route.function.AbstractPartitionAlgorithm)4 SQLExpr (com.alibaba.druid.sql.ast.SQLExpr)4 SQLExprTableSource (com.alibaba.druid.sql.ast.statement.SQLExprTableSource)4 MySqlStatementParser (com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser)4 CacheService (com.actiontech.dble.cache.CacheService)3 ServerConfig (com.actiontech.dble.config.ServerConfig)3 SQLStatementParser (com.alibaba.druid.sql.parser.SQLStatementParser)3 Matcher (java.util.regex.Matcher)3 PhysicalDBNode (com.actiontech.dble.backend.datasource.PhysicalDBNode)2 FetchStoreNodeOfChildTableHandler (com.actiontech.dble.backend.mysql.nio.handler.FetchStoreNodeOfChildTableHandler)2 EOFPacket (com.actiontech.dble.net.mysql.EOFPacket)2 FieldPacket (com.actiontech.dble.net.mysql.FieldPacket)2 RowDataPacket (com.actiontech.dble.net.mysql.RowDataPacket)2