/** * confirmChildColumnNotUpdated * * @throws SQLNonTransientException */ private void confirmChildColumnNotUpdated(SQLUpdateStatement update, SchemaConfig schema, String tableName) throws SQLNonTransientException { if (schema.getFkErRelations() == null) { return; } List<SQLUpdateSetItem> updateSetItem = update.getItems(); if (updateSetItem != null && updateSetItem.size() > 0) { for (SQLUpdateSetItem item : updateSetItem) { String column = StringUtil.removeBackQuote(item.getColumn().toString().toUpperCase()); if (isJoinColumn(column, schema, tableName)) { String msg = "child relevant column can't be updated " + tableName + "->" + column; LOGGER.info(msg); throw new SQLNonTransientException(msg); } } } }
@Override public void statementParse(SchemaConfig schema, RouteResultset rrs, SQLStatement stmt) throws SQLNonTransientException { MySqlCreateTableStatement createStmt = (MySqlCreateTableStatement)stmt; if(createStmt.getQuery() != null) { String msg = "create table from other table not supported :" + stmt; LOGGER.warn(msg); throw new SQLNonTransientException(msg); } String tableName = StringUtil.removeBackquote(createStmt.getTableSource().toString().toUpperCase()); if(schema.getTables().containsKey(tableName)) { TableConfig tableConfig = schema.getTables().get(tableName); AbstractPartitionAlgorithm algorithm = tableConfig.getRule().getRuleAlgorithm(); if(algorithm instanceof SlotFunction){ SQLColumnDefinition column = new SQLColumnDefinition(); column.setDataType(new SQLCharacterDataType("int")); column.setName(new SQLIdentifierExpr("_slot")); column.setComment(new SQLCharExpr("自动迁移算法slot,禁止修改")); ((SQLCreateTableStatement)stmt).getTableElementList().add(column); String sql = createStmt.toString(); rrs.setStatement(sql); ctx.setSql(sql); } } ctx.addTable(tableName); }
private boolean isRoutMultiNode(SchemaConfig schema, RouteResultset rrs) { if(rrs.getNodes()!=null&&rrs.getNodes().length>1) { return true; } LayerCachePool tableId2DataNodeCache = (LayerCachePool) MycatServer.getInstance().getCacheService().getCachePool("TableID2DataNodeCache"); try { tryRoute(schema, rrs, tableId2DataNodeCache); if(rrs.getNodes()!=null&&rrs.getNodes().length>1) { return true; } } catch (SQLNonTransientException e) { throw new RuntimeException(e); } return false; }
protected void setLimitIFChange(SQLStatement stmt, RouteResultset rrs, SchemaConfig schema, SQLBinaryOpExpr one, int firstrownum, int lastrownum) { rrs.setLimitStart(firstrownum); rrs.setLimitSize(lastrownum - firstrownum); LayerCachePool tableId2DataNodeCache = (LayerCachePool) MycatServer.getInstance().getCacheService().getCachePool("TableID2DataNodeCache"); try { tryRoute(schema, rrs, tableId2DataNodeCache); } catch (SQLNonTransientException e) { throw new RuntimeException(e); } if (isNeedChangeLimit(rrs)) { one.setRight(new SQLIntegerExpr(0)); String curentDbType ="db2".equalsIgnoreCase(this.getCurentDbType())?"oracle":getCurentDbType(); String sql = SQLUtils.toSQLString(stmt, curentDbType);; rrs.changeNodeSqlAfterAddLimit(schema,getCurentDbType(), sql,0,lastrownum, false); //设置改写后的sql getCtx().setSql(sql); } }
private static void routerForJoinTable(RouteResultset rrs, TableConfig tableConfig, Map<String, Set<ColumnRoutePair>> columnsMap, String joinKey) throws SQLNonTransientException { //childTable (if it's ER JOIN of select)must find root table,remove childTable, only left root table Set<ColumnRoutePair> joinKeyValue = columnsMap.get(joinKey); Set<String> dataNodeSet = ruleByJoinValueCalculate(rrs, tableConfig, joinKeyValue); if (dataNodeSet.isEmpty()) { throw new SQLNonTransientException( "parent key can't find any valid datanode "); } if (LOGGER.isDebugEnabled()) { LOGGER.debug("found partion nodes (using parent partion rule directly) for child table to update " + Arrays.toString(dataNodeSet.toArray()) + " sql :" + rrs.getStatement()); } if (dataNodeSet.size() > 1) { routeToMultiNode(rrs.isCacheAble(), rrs, dataNodeSet); rrs.setFinishedRoute(true); return; } else { rrs.setCacheAble(true); routeToSingleNode(rrs, dataNodeSet.iterator().next()); return; } }
@Override public SchemaConfig visitorParse(SchemaConfig schema, RouteResultset rrs, SQLStatement stmt, ServerSchemaStatVisitor visitor, ServerConnection sc) throws SQLException { SQLDropTableStatement dropTable = (SQLDropTableStatement) stmt; if (dropTable.getTableSources().size() > 1) { String msg = "dropping multi-tables is not supported, sql:" + stmt; throw new SQLNonTransientException(msg); } String schemaName = schema == null ? null : schema.getName(); SchemaInfo schemaInfo = SchemaUtil.getSchemaInfo(sc.getUser(), schemaName, dropTable.getTableSources().get(0)); String statement = RouterUtil.removeSchema(rrs.getStatement(), schemaInfo.getSchema()); rrs.setStatement(statement); if (RouterUtil.isNoSharding(schemaInfo.getSchemaConfig(), schemaInfo.getTable())) { RouterUtil.routeToSingleDDLNode(schemaInfo, rrs); return schemaInfo.getSchemaConfig(); } RouterUtil.routeToDDLNode(schemaInfo, rrs); return schemaInfo.getSchemaConfig(); }
/** * 从全局的schema列表中查询指定的schema是否存在, 如果存在则替换connection属性中原有的schema, * 如果不存在,则throws SQLNonTransientException,表示指定的schema 不存在 * * @param sysConfig * @param schema * @param sqlType * @param realSQL * @param charset * @param info * @param cachePool * @param hintSQLValue * @return * @throws SQLNonTransientException */ @Override public RouteResultset route(SystemConfig sysConfig, SchemaConfig schema, int sqlType, String realSQL, String charset, ServerConnection sc, LayerCachePool cachePool, String hintSQLValue,int hintSqlType, Map hintMap) throws SQLNonTransientException { // sc.setEngineCtx ctx String cateletClass = hintSQLValue; if (LOGGER.isDebugEnabled()) { LOGGER.debug("load catelet class:" + hintSQLValue + " to run sql " + realSQL); } try { Catlet catlet = (Catlet) MycatServer.getInstance() .getCatletClassLoader().getInstanceofClass(cateletClass); catlet.route(sysConfig, schema, sqlType, realSQL,charset, sc, cachePool); catlet.processSQL(realSQL, new EngineCtx(sc.getSession2())); } catch (Exception e) { LOGGER.warn("catlet error "+e); throw new SQLNonTransientException(e); } return null; }
private void routeEndExecuteSQL(String sql, int type, SchemaConfig schema) { RouteResultset rrs; try { rrs = DbleServer.getInstance().getRouterService().route(schema, type, sql, this); if (rrs == null) { return; } if (rrs.getSqlType() == ServerParse.DDL) { addTableMetaLock(rrs); if (DbleServer.getInstance().getTmManager().getCatalogs().get(rrs.getSchema()).getView(rrs.getTable()) != null) { DbleServer.getInstance().getTmManager().removeMetaLock(rrs.getSchema(), rrs.getTable()); String msg = "Table '" + rrs.getTable() + "' already exists as a view"; LOGGER.info(msg); throw new SQLNonTransientException(msg); } } } catch (Exception e) { executeException(e, sql); return; } session.execute(rrs); }
private void genDuplicate(boolean isGlobalCheck, StringBuilder sb, List<SQLExpr> dku) throws SQLNonTransientException { boolean flag = false; sb.append(" on duplicate key update "); for (int i = 0; i < dku.size(); i++) { SQLExpr exp = dku.get(i); if (!(exp instanceof SQLBinaryOpExpr)) { String msg = "not supported! on duplicate key update exp is " + exp.getClass(); LOGGER.info(msg); throw new SQLNonTransientException(msg); } SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) exp; if (isGlobalCheck && !flag && GlobalTableUtil.GLOBAL_TABLE_CHECK_COLUMN.equals(binaryOpExpr.getLeft().toString())) { flag = true; onDuplicateGlobalColumn(sb); } else { sb.append(binaryOpExpr.toString()); } if (i < dku.size() - 1) { sb.append(","); } } if (isGlobalCheck && !flag) { sb.append(","); onDuplicateGlobalColumn(sb); } }
@Test public void testRange() throws SQLNonTransientException { String sql = "select * from offer1 where col_date between '2014-01-01 00:00:00' and '2014-01-03 23:59:59' order by id desc limit 100"; SchemaConfig schema = schemaMap.get("TESTDB"); RouteResultset rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); junit.framework.Assert.assertEquals(6, rrs.getNodes().length); sql = "select * from offer1 where col_date between '2014-01-01 00:00:00' and '2014-01-04 00:00:59' order by id desc limit 100"; rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); junit.framework.Assert.assertEquals(12, rrs.getNodes().length); sql = "select * from offer1 where col_date between '2014-01-04 00:00:00' and '2014-01-06 23:59:59' order by id desc limit 100"; rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); junit.framework.Assert.assertEquals(6, rrs.getNodes().length); }
@Test public void testRange() throws SQLNonTransientException { String sql = "select * from offer where id between 2000000 and 4000001 order by id desc limit 100"; SchemaConfig schema = schemaMap.get("TESTDB"); RouteResultset rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(10, rrs.getNodes().length); sql = "select * from offer where id between 9 and 2000 order by id desc limit 100"; rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(5, rrs.getNodes().length); sql = "select * from offer where id between 4000001 and 6005001 order by id desc limit 100"; rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(8, rrs.getNodes().length); }
@Test public void testHaving() throws SQLNonTransientException { String sql = "select avg(offer_id) avgofferid, member_id from offer_detail group by member_id having avgofferid > 100"; SchemaConfig schema = schemaMap.get("cndb"); RouteResultset rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(3, rrs.getSqlMerge().getHavingColsName().length); sql = "select avg(offer_id) avgofferid, member_id from offer_detail group by member_id having avg(offer_id) > 100"; rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(3, rrs.getSqlMerge().getHavingColsName().length); sql = "select count(offer_id) countofferid, member_id from offer_detail group by member_id having countofferid > 100"; rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(3, rrs.getSqlMerge().getHavingColsName().length); sql = "select count(offer_id) countofferid, member_id from offer_detail group by member_id having count(offer_id) > 100"; rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(3, rrs.getSqlMerge().getHavingColsName().length); }
@Override public SchemaConfig visitorParse(SchemaConfig schema, RouteResultset rrs, SQLStatement stmt, ServerSchemaStatVisitor visitor, ServerConnection sc) throws SQLException { stmt.accept(visitor); if (visitor.getNotSupportMsg() != null) { throw new SQLNonTransientException(visitor.getNotSupportMsg()); } List<List<Condition>> mergedConditionList = new ArrayList<>(); if (visitor.hasOrCondition()) { mergedConditionList = visitor.splitConditions(); } else { mergedConditionList.add(visitor.getConditions()); } Map<String, String> tableAliasMap = getTableAliasMap(visitor.getAliasMap()); ctx.setRouteCalculateUnits(this.buildRouteCalculateUnits(tableAliasMap, mergedConditionList)); return schema; }
/** * Validate that the ordering of the returned Exceptions is correct * using traditional while loop */ @Test public void test12() { SQLNonTransientException ex = new SQLNonTransientException("Exception 1", t1); SQLNonTransientException ex1 = new SQLNonTransientException("Exception 2"); SQLNonTransientException ex2 = new SQLNonTransientException("Exception 3", t2); ex.setNextException(ex1); ex.setNextException(ex2); int num = 0; SQLException sqe = ex; while (sqe != null) { assertTrue(msgs[num++].equals(sqe.getMessage())); Throwable c = sqe.getCause(); while (c != null) { assertTrue(msgs[num++].equals(c.getMessage())); c = c.getCause(); } sqe = sqe.getNextException(); } }
@Override public RouteResultset route(SchemaConfig schema, int sqlType, String realSQL, ServerConnection sc, LayerCachePool cachePool, String hintSQLValue, int hintSqlType, Map hintMap) throws SQLNonTransientException { if (LOGGER.isDebugEnabled()) { LOGGER.debug("route datanode sql hint from " + realSQL); } RouteResultset rrs = new RouteResultset(realSQL, sqlType); PhysicalDBNode dataNode = DbleServer.getInstance().getConfig().getDataNodes().get(hintSQLValue); if (dataNode != null) { rrs = RouterUtil.routeToSingleNode(rrs, dataNode.getName()); } else { String msg = "can't find hint datanode:" + hintSQLValue; LOGGER.info(msg); throw new SQLNonTransientException(msg); } return rrs; }
protected static RouteResultset routeByERParentKey(RouteResultset rrs, TableConfig tc, String joinKeyVal) throws SQLNonTransientException { if (tc.getDirectRouteTC() != null) { Set<ColumnRoutePair> parentColVal = new HashSet<>(1); ColumnRoutePair pair = new ColumnRoutePair(joinKeyVal); parentColVal.add(pair); Set<String> dataNodeSet = RouterUtil.ruleCalculate(tc.getDirectRouteTC(), parentColVal); if (dataNodeSet.isEmpty() || dataNodeSet.size() > 1) { throw new SQLNonTransientException("parent key can't find valid data node ,expect 1 but found: " + dataNodeSet.size()); } String dn = dataNodeSet.iterator().next(); if (SQLJob.LOGGER.isDebugEnabled()) { SQLJob.LOGGER.debug("found partion node (using parent partition rule directly) for child table to insert " + dn + " sql :" + rrs.getStatement()); } return RouterUtil.routeToSingleNode(rrs, dn); } return null; }
private void tryRouteSingleTable(SchemaConfig schema, RouteResultset rrs, LayerCachePool cachePool) throws SQLException { if (rrs.isFinishedRoute()) { return; } SortedSet<RouteResultsetNode> nodeSet = new TreeSet<>(); String table = ctx.getTables().get(0); if (RouterUtil.isNoSharding(schema, table)) { RouterUtil.routeToSingleNode(rrs, schema.getDataNode()); return; } for (RouteCalculateUnit unit : ctx.getRouteCalculateUnits()) { RouteResultset rrsTmp = RouterUtil.tryRouteForOneTable(schema, unit, table, rrs, true, cachePool); if (rrsTmp != null && rrsTmp.getNodes() != null) { Collections.addAll(nodeSet, rrsTmp.getNodes()); if (rrsTmp.isGlobalTable()) { break; } } } if (nodeSet.size() == 0) { String msg = " find no Route:" + rrs.getStatement(); LOGGER.info(msg); throw new SQLNonTransientException(msg); } RouteResultsetNode[] nodes = new RouteResultsetNode[nodeSet.size()]; int i = 0; for (RouteResultsetNode aNodeSet : nodeSet) { nodes[i] = aNodeSet; i++; } rrs.setNodes(nodes); rrs.setFinishedRoute(true); }
private static boolean columnInExpr(SQLExpr sqlExpr, String colName) throws SQLNonTransientException { String column; if (sqlExpr instanceof SQLIdentifierExpr) { column = StringUtil.removeBackquote(((SQLIdentifierExpr) sqlExpr).getName()).toUpperCase(); } else if (sqlExpr instanceof SQLPropertyExpr) { column = StringUtil.removeBackquote(((SQLPropertyExpr) sqlExpr).getName()).toUpperCase(); } else { throw new SQLNonTransientException("Unhandled SQL AST node type encountered: " + sqlExpr.getClass()); } return column.equals(colName.toUpperCase()); }
/** * @param schema * @param sqlType * @param realSQL * @param sc * @param cachePool * @param hintSQLValue * @return * @throws SQLNonTransientException */ @Override public RouteResultset route(SchemaConfig schema, int sqlType, String realSQL, ServerConnection sc, LayerCachePool cachePool, String hintSQLValue, int hintSqlType, Map hintMap) throws SQLException { SchemaConfig tempSchema = DbleServer.getInstance().getConfig().getSchemas().get(hintSQLValue); if (tempSchema != null) { return routeStrategy.route(tempSchema, sqlType, realSQL, sc, cachePool); } else { String msg = "can't find hint schema:" + hintSQLValue; LOGGER.info(msg); throw new SQLNonTransientException(msg); } }
private Long getNextValidSeqVal(SequenceVal seqVal) throws SQLNonTransientException { Long nexVal = seqVal.nextValue(); if (seqVal.isNexValValid(nexVal)) { return nexVal; } else { seqVal.fetching.compareAndSet(true, false); return getSeqValueFromDB(seqVal); } }
public static boolean processInsert(SchemaConfig schema, int sqlType, String origSQL, ServerConnection sc) throws SQLNonTransientException { String tableName = StringUtil.getTableName(origSQL).toUpperCase(); TableConfig tableConfig = schema.getTables().get(tableName); boolean processedInsert=false; //判断是有自增字段 if (null != tableConfig && tableConfig.isAutoIncrement()) { String primaryKey = tableConfig.getPrimaryKey(); processedInsert=processInsert(sc,schema,sqlType,origSQL,tableName,primaryKey); } return processedInsert; }
/** * 路由之前必要的处理 * 主要是全局序列号插入,还有子表插入 */ private boolean beforeRouteProcess(SchemaConfig schema, int sqlType, String origSQL, ServerConnection sc) throws SQLNonTransientException { return RouterUtil.processWithMycatSeq(schema, sqlType, origSQL, sc) || (sqlType == ServerParse.INSERT && RouterUtil.processERChildTable(schema, origSQL, sc)) || (sqlType == ServerParse.INSERT && RouterUtil.processInsert(schema, sqlType, origSQL, sc)); }
public void throwExceptionParse(String sql, boolean throwException) throws NoSuchMethodException { MySqlStatementParser parser = new MySqlStatementParser(sql); List<SQLStatement> statementList = parser.parseStatementList(); SQLStatement sqlStatement = statementList.get(0); MySqlUpdateStatement update = (MySqlUpdateStatement) sqlStatement; SchemaConfig schemaConfig = mock(SchemaConfig.class); Map<String, TableConfig> tables = mock(Map.class); TableConfig tableConfig = mock(TableConfig.class); String tableName = "hotnews"; when((schemaConfig).getTables()).thenReturn(tables); when(tables.get(tableName)).thenReturn(tableConfig); when(tableConfig.getParentTC()).thenReturn(null); RouteResultset routeResultset = new RouteResultset(sql, 11); Class c = DruidUpdateParser.class; Method method = c.getDeclaredMethod("confirmShardColumnNotUpdated", new Class[]{SQLUpdateStatement.class, SchemaConfig.class, String.class, String.class, String.class, RouteResultset.class}); method.setAccessible(true); try { method.invoke(c.newInstance(), update, schemaConfig, tableName, "ID", "", routeResultset); if (throwException) { System.out.println("未抛异常,解析通过则不对!"); Assert.assertTrue(false); } else { System.out.println("未抛异常,解析通过,此情况分片字段可能在update语句中但是实际不会被更新"); Assert.assertTrue(true); } } catch (Exception e) { if (throwException) { System.out.println(e.getCause().getClass()); Assert.assertTrue(e.getCause() instanceof SQLNonTransientException); System.out.println("抛异常原因为SQLNonTransientException则正确"); } else { System.out.println("抛异常,需要检查"); Assert.assertTrue(false); } } }
protected static String shardingValueToSting(SQLExpr valueExpr) throws SQLNonTransientException { String shardingValue = null; if (valueExpr instanceof SQLIntegerExpr) { SQLIntegerExpr intExpr = (SQLIntegerExpr) valueExpr; shardingValue = intExpr.getNumber() + ""; } else if (valueExpr instanceof SQLCharExpr) { SQLCharExpr charExpr = (SQLCharExpr) valueExpr; shardingValue = charExpr.getText(); } if (shardingValue == null) { throw new SQLNonTransientException("Not Supported of Sharding Value EXPR :" + valueExpr.toString()); } return shardingValue; }
@Test public void testTopPageSQL() throws SQLNonTransientException { SchemaConfig schema = schemaMap.get("sqlserverdb"); RouteResultset rrs = null; String sql="SELECT TOP 10 * \n" + " FROM offer1 where sts<>'N' and asf like '%'+'akka'+'%' \n" + " ORDER BY sid desc" ; rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(1, rrs.getNodes().length); Assert.assertEquals(0, rrs.getLimitStart()); Assert.assertEquals(10, rrs.getLimitSize()); Assert.assertEquals(0, rrs.getNodes()[0].getLimitStart()); Assert.assertEquals(10, rrs.getNodes()[0].getLimitSize()); Assert.assertEquals(sql,rrs.getNodes()[0].getStatement()) ; Assert.assertEquals("sqlserver_1", rrs.getNodes()[0].getName()); sql="SELECT TOP 10 offer1.name,offer1.id \n" + " FROM offer1 where sts<>'N' and asf like '%'+'akka'+'%' \n" + " ORDER BY sid desc" ; rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(1, rrs.getNodes().length); Assert.assertEquals(0, rrs.getLimitStart()); Assert.assertEquals(10, rrs.getLimitSize()); Assert.assertEquals(0, rrs.getNodes()[0].getLimitStart()); Assert.assertEquals(10, rrs.getNodes()[0].getLimitSize()); Assert.assertEquals(sql,rrs.getNodes()[0].getStatement()) ; Assert.assertEquals("sqlserver_1", rrs.getNodes()[0].getName()); }
@Test public void testLimitToDb2Page() throws SQLNonTransientException { String sql = "select * from offer order by id desc limit 5,10"; SchemaConfig schema = schemaMap.get("db2db"); RouteResultset rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(2, rrs.getNodes().length); Assert.assertEquals(5, rrs.getLimitStart()); Assert.assertEquals(10, rrs.getLimitSize()); Assert.assertEquals(0, rrs.getNodes()[0].getLimitStart()); Assert.assertEquals(15, rrs.getNodes()[0].getLimitSize()); Assert.assertEquals("db2_1", rrs.getNodes()[0].getName()); Assert.assertEquals("db2_2", rrs.getNodes()[1].getName()); sql= rrs.getNodes()[0].getStatement() ; rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(0, rrs.getNodes()[0].getLimitStart()); Assert.assertEquals(15, rrs.getNodes()[0].getLimitSize()); Assert.assertEquals(0, rrs.getLimitStart()); Assert.assertEquals(15, rrs.getLimitSize()); sql="select * from offer1 order by id desc limit 5,10" ; rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(1, rrs.getNodes().length); Assert.assertEquals(5, rrs.getLimitStart()); Assert.assertEquals(10, rrs.getLimitSize()); Assert.assertEquals(5, rrs.getNodes()[0].getLimitStart()); Assert.assertEquals(10, rrs.getNodes()[0].getLimitSize()); Assert.assertEquals("db2_1", rrs.getNodes()[0].getName()); }
/** * 路由到tableSpace的性能测试 * * @throws SQLNonTransientException */ public void testTableSpace() throws SQLNonTransientException { SchemaConfig schema = getSchema(); String sql = "select id,member_id,gmt_create from offer where member_id in ('1','22','333','1124','4525')"; for (int i = 0; i < total; i++) { RouteStrategyFactory.getRouteStrategy().route(new SystemConfig(),schema, -1,sql, null, null,cachePool); } }
/** * 路由到defaultSpace的性能测试 */ public void testDefaultSpace() throws SQLNonTransientException { SchemaConfig schema = this.getSchema(); String sql = "insert into offer (member_id, gmt_create) values ('1','2001-09-13 20:20:33')"; for (int i = 0; i < total; i++) { RouteStrategyFactory.getRouteStrategy().route(new SystemConfig(),schema,-1, sql, null, null,cachePool); } }
public void testDefaultSpace() throws SQLNonTransientException { SchemaConfig schema = this.schema; String stmt = "insert into offer (member_id, gmt_create) values ('1','2001-09-13 20:20:33')"; for (int i = 0; i < total; i++) { RouteStrategyFactory.getRouteStrategy().route(new SystemConfig(),schema, -1,stmt, null, null,cachePool); } }
public static void main(String[] args) throws SQLNonTransientException { NoShardingSpace test = new NoShardingSpace(); System.currentTimeMillis(); long start = System.currentTimeMillis(); test.testDefaultSpace(); long end = System.currentTimeMillis(); System.out.println("take " + (end - start) + " ms. avg "+(end-start+0.0)/total); }
@Test public void testLimitToOraclePage() throws SQLNonTransientException { String sql = "select * from offer order by id desc limit 5,10"; SchemaConfig schema = schemaMap.get("oracledb"); RouteResultset rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(2, rrs.getNodes().length); Assert.assertEquals(5, rrs.getLimitStart()); Assert.assertEquals(10, rrs.getLimitSize()); Assert.assertEquals(0, rrs.getNodes()[0].getLimitStart()); Assert.assertEquals(15, rrs.getNodes()[0].getLimitSize()); Assert.assertEquals("d_oracle1", rrs.getNodes()[0].getName()); Assert.assertEquals("d_oracle2", rrs.getNodes()[1].getName()); sql= rrs.getNodes()[0].getStatement() ; rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(0, rrs.getNodes()[0].getLimitStart()); Assert.assertEquals(15, rrs.getNodes()[0].getLimitSize()); Assert.assertEquals(0, rrs.getLimitStart()); Assert.assertEquals(15, rrs.getLimitSize()); sql="select * from offer1 order by id desc limit 5,10" ; rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(1, rrs.getNodes().length); Assert.assertEquals(5, rrs.getLimitStart()); Assert.assertEquals(10, rrs.getLimitSize()); Assert.assertEquals(5, rrs.getNodes()[0].getLimitStart()); Assert.assertEquals(10, rrs.getNodes()[0].getLimitSize()); Assert.assertEquals("d_oracle1", rrs.getNodes()[0].getName()); }
@Test public void testLimitToPgPage() throws SQLNonTransientException { String sql = "select * from offer order by id desc limit 5,10"; SchemaConfig schema = schemaMap.get("pgdb"); RouteResultset rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(2, rrs.getNodes().length); Assert.assertEquals(5, rrs.getLimitStart()); Assert.assertEquals(10, rrs.getLimitSize()); Assert.assertEquals(0, rrs.getNodes()[0].getLimitStart()); Assert.assertEquals(15, rrs.getNodes()[0].getLimitSize()); sql= rrs.getNodes()[0].getStatement() ; rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(0, rrs.getNodes()[0].getLimitStart()); Assert.assertEquals(15, rrs.getNodes()[0].getLimitSize()); Assert.assertEquals(0, rrs.getLimitStart()); Assert.assertEquals(15, rrs.getLimitSize()); sql="select * from offer1 order by id desc limit 5,10" ; rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(1, rrs.getNodes().length); Assert.assertEquals(5, rrs.getLimitStart()); Assert.assertEquals(10, rrs.getLimitSize()); Assert.assertEquals(5, rrs.getNodes()[0].getLimitStart()); Assert.assertEquals(10, rrs.getNodes()[0].getLimitSize()); }
@Test public void testPGPageSQL() throws SQLNonTransientException { String sql = "select sid from offer order by sid limit 10 offset 5"; SchemaConfig schema = schemaMap.get("pgdb"); RouteResultset rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(2, rrs.getNodes().length); Assert.assertEquals(5, rrs.getLimitStart()); Assert.assertEquals(10, rrs.getLimitSize()); Assert.assertEquals(0, rrs.getNodes()[0].getLimitStart()); Assert.assertEquals(15, rrs.getNodes()[0].getLimitSize()); sql = "select sid from offer1 order by sid limit 10 offset 5"; rrs = routeStrategy.route(new SystemConfig(), schema, -1, sql, null, null, cachePool); Assert.assertEquals(1, rrs.getNodes().length); Assert.assertEquals(5, rrs.getLimitStart()); Assert.assertEquals(10, rrs.getLimitSize()); Assert.assertEquals(5, rrs.getNodes()[0].getLimitStart()); Assert.assertEquals(10, rrs.getNodes()[0].getLimitSize()); Assert.assertEquals("SELECT sid\n" + "FROM offer1\n" + "ORDER BY sid\n" + "LIMIT 10 OFFSET 5",rrs.getNodes()[0].getStatement()) ; }
@Test public void testLockTableSql() throws SQLNonTransientException{ String sql = "lock tables goods write"; SchemaConfig schema = schemaMap.get("TESTDB"); RouteResultset rrs = routeStrategy.route(new SystemConfig(), schema, ServerParse.LOCK, sql, null, null, cachePool); Assert.assertEquals(3, rrs.getNodes().length); }
@Override protected DataAccessException doTranslate(String task, String sql, SQLException ex) { if (ex instanceof SQLTransientException) { if (ex instanceof SQLTransientConnectionException) { return new TransientDataAccessResourceException(buildMessage(task, sql, ex), ex); } else if (ex instanceof SQLTransactionRollbackException) { return new ConcurrencyFailureException(buildMessage(task, sql, ex), ex); } else if (ex instanceof SQLTimeoutException) { return new QueryTimeoutException(buildMessage(task, sql, ex), ex); } } else if (ex instanceof SQLNonTransientException) { if (ex instanceof SQLNonTransientConnectionException) { return new DataAccessResourceFailureException(buildMessage(task, sql, ex), ex); } else if (ex instanceof SQLDataException) { return new DataIntegrityViolationException(buildMessage(task, sql, ex), ex); } else if (ex instanceof SQLIntegrityConstraintViolationException) { return new DataIntegrityViolationException(buildMessage(task, sql, ex), ex); } else if (ex instanceof SQLInvalidAuthorizationSpecException) { return new PermissionDeniedDataAccessException(buildMessage(task, sql, ex), ex); } else if (ex instanceof SQLSyntaxErrorException) { return new BadSqlGrammarException(task, sql, ex); } else if (ex instanceof SQLFeatureNotSupportedException) { return new InvalidDataAccessApiUsageException(buildMessage(task, sql, ex), ex); } } else if (ex instanceof SQLRecoverableException) { return new RecoverableDataAccessException(buildMessage(task, sql, ex), ex); } // Fallback to Spring's own SQL state translation... return null; }
public void throwExceptionParse(String sql, boolean throwException) throws NoSuchMethodException { MySqlStatementParser parser = new MySqlStatementParser(sql); List<SQLStatement> statementList = parser.parseStatementList(); SQLStatement sqlStatement = statementList.get(0); MySqlUpdateStatement update = (MySqlUpdateStatement) sqlStatement; SchemaConfig schemaConfig = mock(SchemaConfig.class); Map<String, TableConfig> tables = mock(Map.class); TableConfig tableConfig = mock(TableConfig.class); String tableName = "hotnews"; when((schemaConfig).getTables()).thenReturn(tables); when(tables.get(tableName)).thenReturn(tableConfig); when(tableConfig.getParentTC()).thenReturn(null); RouteResultset routeResultset = new RouteResultset(sql, 11); Class c = DruidUpdateParser.class; Method method = c.getDeclaredMethod("confirmShardColumnNotUpdated", new Class[]{SQLUpdateStatement.class, SchemaConfig.class, String.class, String.class, String.class, RouteResultset.class}); method.setAccessible(true); try { method.invoke(c.newInstance(), update, schemaConfig, tableName, "ID", "", routeResultset); if (throwException) { System.out.println("Not passed without exception is not correct"); Assert.assertTrue(false); } else { System.out.println("Passed without exception. Maybe the partition key exists in update statement,but not update in fact"); Assert.assertTrue(true); } } catch (Exception e) { if (throwException) { System.out.println(e.getCause().getClass()); Assert.assertTrue(e.getCause() instanceof SQLNonTransientException); System.out.println("SQLNonTransientException is expected"); } else { System.out.println("need checked"); Assert.assertTrue(false); } } }
/** * Create SQLNonTransientException and setting all objects to null */ @Test public void test() { SQLNonTransientException e = new SQLNonTransientException(null, null, errorCode, null); assertTrue(e.getMessage() == null && e.getSQLState() == null && e.getCause() == null && e.getErrorCode() == errorCode); }
/** * Create SQLNonTransientException with no-arg constructor */ @Test public void test1() { SQLNonTransientException ex = new SQLNonTransientException(); assertTrue(ex.getMessage() == null && ex.getSQLState() == null && ex.getCause() == null && ex.getErrorCode() == 0); }
/** * Create SQLNonTransientException with message, and SQLState */ @Test public void test3() { SQLNonTransientException ex = new SQLNonTransientException(reason, state); assertTrue(ex.getMessage().equals(reason) && ex.getSQLState().equals(state) && ex.getCause() == null && ex.getErrorCode() == 0); }
private long getSeqValueFromDB(SequenceVal seqVal) throws SQLNonTransientException { if (LOGGER.isDebugEnabled()) { LOGGER.debug("get next segement of sequence from db for sequence:" + seqVal.seqName + " curVal " + seqVal.curVal); } if (seqVal.fetching.compareAndSet(false, true)) { seqVal.dbretVal = null; seqVal.dbfinished = false; seqVal.newValueSetted.set(false); mysqlSeqFetcher.execute(seqVal); } Long[] values = seqVal.waitFinish(); if (values == null) { seqVal.fetching.compareAndSet(true, false); throw new RuntimeException("can't fetch sequence in db,sequence :" + seqVal.seqName + " detail:" + mysqlSeqFetcher.getLastError(seqVal.seqName)); } else if (values[0] == 0) { seqVal.fetching.compareAndSet(true, false); String msg = "sequence," + seqVal.seqName + "has not been set, please check configure in dble_sequence"; LOGGER.info(msg); throw new SQLNonTransientException(msg); } else { if (seqVal.newValueSetted.compareAndSet(false, true)) { seqVal.setCurValue(values[0]); seqVal.maxSegValue = values[1]; return values[0]; } else { return seqVal.nextValue(); } } }