use of com.actiontech.dble.plan.common.exception.MySQLOutPutException in project dble by actiontech.
the class BaseHandlerBuilder method handleBlockingSubQuery.
protected void handleBlockingSubQuery() {
if (node.getSubQueries().size() == 0) {
return;
}
final ReentrantLock lock = new ReentrantLock();
final Condition finishSubQuery = lock.newCondition();
final AtomicBoolean finished = new AtomicBoolean(false);
final AtomicInteger subNodes = new AtomicInteger(node.getSubQueries().size());
final CopyOnWriteArrayList<ErrorPacket> errorPackets = new CopyOnWriteArrayList<>();
for (ItemSubQuery itemSubQuery : node.getSubQueries()) {
if (itemSubQuery instanceof ItemSingleRowSubQuery) {
final SubQueryHandler tempHandler = new SingleRowSubQueryHandler(getSequenceId(), session, (ItemSingleRowSubQuery) itemSubQuery);
if (isExplain) {
handleSubQueryForExplain(lock, finishSubQuery, finished, subNodes, itemSubQuery.getPlanNode(), tempHandler);
} else {
handleSubQuery(lock, finishSubQuery, finished, subNodes, errorPackets, itemSubQuery.getPlanNode(), tempHandler);
}
} else if (itemSubQuery instanceof ItemInSubQuery) {
final SubQueryHandler tempHandler = new InSubQueryHandler(getSequenceId(), session, (ItemInSubQuery) itemSubQuery);
if (isExplain) {
handleSubQueryForExplain(lock, finishSubQuery, finished, subNodes, itemSubQuery.getPlanNode(), tempHandler);
} else {
handleSubQuery(lock, finishSubQuery, finished, subNodes, errorPackets, itemSubQuery.getPlanNode(), tempHandler);
}
} else if (itemSubQuery instanceof ItemAllAnySubQuery) {
final SubQueryHandler tempHandler = new AllAnySubQueryHandler(getSequenceId(), session, (ItemAllAnySubQuery) itemSubQuery);
if (isExplain) {
handleSubQueryForExplain(lock, finishSubQuery, finished, subNodes, itemSubQuery.getPlanNode(), tempHandler);
} else {
handleSubQuery(lock, finishSubQuery, finished, subNodes, errorPackets, itemSubQuery.getPlanNode(), tempHandler);
}
}
}
lock.lock();
try {
while (!finished.get()) {
finishSubQuery.await();
}
} catch (InterruptedException e) {
LOGGER.info("execute ScalarSubQuery " + e);
ErrorPacket errorPackage = new ErrorPacket();
errorPackage.setErrNo(ErrorCode.ER_UNKNOWN_ERROR);
String errorMsg = e.getMessage() == null ? e.toString() : e.getMessage();
errorPackage.setMessage(errorMsg.getBytes(StandardCharsets.UTF_8));
errorPackets.add(errorPackage);
} finally {
lock.unlock();
}
if (errorPackets.size() > 0) {
throw new MySQLOutPutException(errorPackets.get(0).getErrNo(), "", new String(errorPackets.get(0).getMessage(), StandardCharsets.UTF_8));
}
}
use of com.actiontech.dble.plan.common.exception.MySQLOutPutException in project dble by actiontech.
the class JoinNodeHandlerBuilder method mergeBuild.
@Override
public void mergeBuild() {
try {
this.needWhereHandler = false;
this.canPushDown = !node.existUnPushDownGroup();
PushDownVisitor pdVisitor = new PushDownVisitor(node, true);
MergeBuilder mergeBuilder = new MergeBuilder(session, node, needCommon, pdVisitor);
String sql = null;
if (node.getAst() != null && node.getParent() == null) {
// it's root
pdVisitor.visit();
sql = pdVisitor.getSql().toString();
}
RouteResultsetNode[] rrssArray;
// maybe some node is view
if (sql == null) {
rrssArray = mergeBuilder.construct().getNodes();
} else {
rrssArray = mergeBuilder.constructByStatement(sql, node.getAst()).getNodes();
}
this.needCommon = mergeBuilder.getNeedCommonFlag();
buildMergeHandler(node, rrssArray);
} catch (Exception e) {
throw new MySQLOutPutException(ErrorCode.ER_QUERYHANDLER, "", "join node mergebuild exception!", e);
}
}
use of com.actiontech.dble.plan.common.exception.MySQLOutPutException in project dble by actiontech.
the class ItemField method getMergeNodeColumn.
private Item getMergeNodeColumn(String tmpFieldTable, String tmpFieldName, PlanNode planNode) {
// select union only found in outerfields
Item column;
if (StringUtils.isEmpty(getTableName())) {
PlanNode firstNode = planNode.getChild();
boolean found = false;
for (NamedField coutField : firstNode.getOuterFields().keySet()) {
if (tmpFieldName.equalsIgnoreCase(coutField.getName())) {
if (!found) {
tmpFieldTable = coutField.getTable();
found = true;
} else {
throw new MySQLOutPutException(ErrorCode.ER_BAD_FIELD_ERROR, "(42S22", "Unknown column '" + tmpFieldName + "' in 'order clause'");
}
}
}
column = planNode.getOuterFields().get(new NamedField(tmpFieldTable, tmpFieldName, null));
} else {
throw new MySQLOutPutException(ErrorCode.ER_TABLENAME_NOT_ALLOWED_HERE, "42000", "Table '" + getTableName() + "' from one of the SELECTs cannot be used in global ORDER clause");
}
return column;
}
use of com.actiontech.dble.plan.common.exception.MySQLOutPutException in project dble by actiontech.
the class ItemField method fixFields.
@Override
public Item fixFields(NameResolutionContext context) {
if (this.isWild())
return this;
String tmpFieldTable = null;
String tmpFieldName = getItemName();
PlanNode planNode = context.getPlanNode();
if (context.getPlanNode().type() == PlanNodeType.MERGE) {
return getMergeNodeColumn(tmpFieldTable, tmpFieldName, planNode);
}
Item column = null;
if (context.isFindInSelect()) {
// try to find in selectlist
if (StringUtils.isEmpty(getTableName())) {
for (NamedField namedField : planNode.getOuterFields().keySet()) {
if (StringUtils.equalsIgnoreCase(tmpFieldName, namedField.getName())) {
if (column == null) {
column = planNode.getOuterFields().get(namedField);
} else
throw new MySQLOutPutException(ErrorCode.ER_OPTIMIZER, "42S22", "duplicate column:" + this);
}
}
} else {
tmpFieldTable = getTableName();
column = planNode.getOuterFields().get(new NamedField(tmpFieldTable, tmpFieldName, null));
}
}
if (column != null && context.isSelectFirst()) {
return column;
}
// find from inner fields
Item columnFromMeta = null;
if (StringUtils.isEmpty(getTableName())) {
for (NamedField namedField : planNode.getInnerFields().keySet()) {
if (StringUtils.equalsIgnoreCase(tmpFieldName, namedField.getName())) {
if (columnFromMeta == null) {
tmpFieldTable = namedField.getTable();
NamedField coutField = planNode.getInnerFields().get(new NamedField(tmpFieldTable, tmpFieldName, null));
this.tableName = namedField.getTable();
getReferTables().clear();
this.getReferTables().add(coutField.planNode);
columnFromMeta = this;
} else {
if (planNode.type() == PlanNodeType.JOIN) {
JoinNode jn = (JoinNode) planNode;
if (jn.getUsingFields() != null && jn.getUsingFields().contains(columnFromMeta.getItemName().toLowerCase())) {
continue;
}
}
throw new MySQLOutPutException(ErrorCode.ER_OPTIMIZER, "42S22", "duplicate column:" + this);
}
}
}
} else {
tmpFieldTable = getTableName();
NamedField tmpField = new NamedField(tmpFieldTable, tmpFieldName, null);
if (planNode.getInnerFields().containsKey(tmpField)) {
NamedField coutField = planNode.getInnerFields().get(tmpField);
getReferTables().clear();
getReferTables().add(coutField.planNode);
this.tableName = tmpField.getTable();
columnFromMeta = this;
}
}
if (columnFromMeta != null) {
return columnFromMeta;
} else if (column == null)
throw new MySQLOutPutException(ErrorCode.ER_OPTIMIZER, "42S22", "column " + this + " not found");
else {
return column;
}
}
use of com.actiontech.dble.plan.common.exception.MySQLOutPutException in project dble by actiontech.
the class SubQueryPreProcessor method transformInSubQuery.
private static SubQueryFilter transformInSubQuery(SubQueryFilter qtn, ItemInSubQuery filter, BoolPtr childTransform) {
Item leftColumn = filter.getLeftOperand();
PlanNode query = filter.getPlanNode();
query = findComparisonsSubQueryToJoinNode(query, childTransform);
QueryNode changeQuery = new QueryNode(query);
String alias = AUTOALIAS + query.getPureName();
changeQuery.setAlias(alias);
if (query.getColumnsSelected().size() != 1)
throw new MySQLOutPutException(ErrorCode.ER_OPTIMIZER, "", "only support subquery of one column");
query.setSubQuery(true).setDistinct(true);
final List<Item> newSelects = qtn.query.getColumnsSelected();
SubQueryFilter result = new SubQueryFilter();
Item rightColumn = query.getColumnsSelected().get(0);
qtn.query.setColumnsSelected(new ArrayList<Item>());
String rightJoinName = rightColumn.getAlias();
if (StringUtils.isEmpty(rightJoinName)) {
if (rightColumn instanceof ItemField) {
rightJoinName = rightColumn.getItemName();
} else {
rightColumn.setAlias(AUTONAME);
rightJoinName = AUTONAME;
}
}
ItemField rightJoinColumn = new ItemField(null, alias, rightJoinName);
// rename the left column's table name
result.query = new JoinNode(qtn.query, changeQuery);
// leave origin sql to new join node
result.query.setSql(qtn.query.getSql());
qtn.query.setSql(null);
result.query.select(newSelects);
qtn.query.setSubQuery(false);
if (!qtn.query.getOrderBys().isEmpty()) {
List<Order> orderBys = new ArrayList<>();
orderBys.addAll(qtn.query.getOrderBys());
result.query.setOrderBys(orderBys);
qtn.query.getOrderBys().clear();
}
if (!qtn.query.getGroupBys().isEmpty()) {
List<Order> groupBys = new ArrayList<>();
groupBys.addAll(qtn.query.getGroupBys());
result.query.setGroupBys(groupBys);
qtn.query.getGroupBys().clear();
result.query.having(qtn.query.getHavingFilter());
qtn.query.having(null);
}
if (qtn.query.getLimitFrom() != -1) {
result.query.setLimitFrom(qtn.query.getLimitFrom());
qtn.query.setLimitFrom(-1);
}
if (qtn.query.getLimitTo() != -1) {
result.query.setLimitTo(qtn.query.getLimitTo());
qtn.query.setLimitTo(-1);
}
if (filter.isNeg()) {
((JoinNode) result.query).setLeftOuterJoin().setNotIn(true);
ItemFuncEqual joinFilter = FilterUtils.equal(leftColumn, rightJoinColumn);
((JoinNode) result.query).addJoinFilter(joinFilter);
result.filter = null;
} else {
Item joinFilter = FilterUtils.equal(leftColumn, rightJoinColumn);
result.query.query(joinFilter);
result.filter = joinFilter;
}
result.query.setUpFields();
return result;
}
Aggregations