use of com.actiontech.dble.plan.common.item.subquery.ItemInSubQuery 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.item.subquery.ItemInSubQuery in project dble by actiontech.
the class PlanUtil method rebuildSubQueryItem.
public static Item rebuildSubQueryItem(Item item) {
if (!item.isWithSubQuery()) {
return item;
}
BoolPtr reBuild = new BoolPtr(false);
if (PlanUtil.isCmpFunc(item)) {
Item res1 = rebuildBoolSubQuery(item, 0, reBuild);
if (res1 != null) {
return res1;
}
Item res2 = rebuildBoolSubQuery(item, 1, reBuild);
if (res2 != null) {
return res2;
}
} else if (item instanceof ItemInSubQuery) {
ItemInSubQuery inSubItem = (ItemInSubQuery) item;
if (inSubItem.getValue().size() == 0) {
return genBoolItem(inSubItem.isNeg());
} else {
List<Item> args = new ArrayList<>(inSubItem.getValue().size() + 1);
args.add(inSubItem.getLeftOperand());
args.addAll(inSubItem.getValue());
return new ItemFuncIn(args, inSubItem.isNeg());
}
} else if (item instanceof ItemExistsSubQuery) {
ItemExistsSubQuery existsSubQuery = (ItemExistsSubQuery) item;
Item result = existsSubQuery.getValue();
if (result == null) {
return genBoolItem(existsSubQuery.isNot());
} else {
return genBoolItem(!existsSubQuery.isNot());
}
} else if (item instanceof ItemCondAnd || item instanceof ItemCondOr) {
for (int index = 0; index < item.getArgCount(); index++) {
Item rebuildItem = rebuildSubQueryItem(item.arguments().get(index));
item.arguments().set(index, rebuildItem);
item.setItemName(null);
}
} else if (item instanceof ItemScalarSubQuery) {
Item result = ((ItemScalarSubQuery) item).getValue();
if (result == null || result.getResultItem() == null) {
return new ItemFuncEqual(new ItemInt(1), new ItemInt(0));
}
return result.getResultItem();
}
if (!reBuild.get() && item instanceof ItemFunc) {
return rebuildSubQueryFuncItem(item);
}
return item;
}
use of com.actiontech.dble.plan.common.item.subquery.ItemInSubQuery in project dble by actiontech.
the class PlanUtil method rebuildSubQueryFuncItem.
private static Item rebuildSubQueryFuncItem(Item item) {
ItemFunc func = (ItemFunc) item;
Item itemTmp = item.cloneItem();
for (int index = 0; index < func.getArgCount(); index++) {
Item arg = item.arguments().get(index);
if (arg instanceof ItemScalarSubQuery) {
Item result = ((ItemScalarSubQuery) arg).getValue();
if (result == null || result.getResultItem() == null) {
itemTmp.arguments().set(index, new ItemNull());
} else {
itemTmp.arguments().set(index, result.getResultItem());
}
} else if (arg instanceof ItemInSubQuery) {
ItemInSubQuery inSubItem = (ItemInSubQuery) arg;
if (inSubItem.getValue().size() == 0) {
itemTmp.arguments().set(index, genBoolItem(inSubItem.isNeg()));
} else {
List<Item> newArgs = new ArrayList<>(inSubItem.getValue().size() + 1);
newArgs.add(inSubItem.getLeftOperand());
newArgs.addAll(inSubItem.getValue());
itemTmp.arguments().set(index, new ItemFuncIn(newArgs, inSubItem.isNeg()));
}
itemTmp.setItemName(null);
return itemTmp;
} else if (arg instanceof ItemFunc) {
itemTmp.arguments().set(index, rebuildSubQueryItem(arg));
}
}
itemTmp.setItemName(null);
return itemTmp;
}
use of com.actiontech.dble.plan.common.item.subquery.ItemInSubQuery in project dble by actiontech.
the class MySQLItemVisitor method endVisit.
@Override
public void endVisit(SQLInSubQueryExpr x) {
boolean isNeg = x.isNot();
Item left = getItem(x.getExpr());
item = new ItemInSubQuery(currentDb, x.getSubQuery().getQuery(), left, isNeg, metaManager);
initName(x);
}
use of com.actiontech.dble.plan.common.item.subquery.ItemInSubQuery in project dble by actiontech.
the class MySQLItemVisitor method handleAnySubQuery.
private void handleAnySubQuery(SQLBinaryOpExpr parent, SQLSelectQuery sqlSelect, boolean isAll) {
SQLBinaryOperator operator = parent.getOperator();
switch(operator) {
case Equality:
if (isAll) {
item = new ItemAllAnySubQuery(currentDb, sqlSelect, operator, true, metaManager);
} else {
Item left = getItem(parent.getLeft());
item = new ItemInSubQuery(currentDb, sqlSelect, left, false, metaManager);
}
break;
case NotEqual:
case LessThanOrGreater:
if (isAll) {
Item left = getItem(parent.getLeft());
item = new ItemInSubQuery(currentDb, sqlSelect, left, true, metaManager);
} else {
item = new ItemAllAnySubQuery(currentDb, sqlSelect, operator, false, metaManager);
}
break;
case LessThan:
case LessThanOrEqual:
case GreaterThan:
case GreaterThanOrEqual:
item = new ItemAllAnySubQuery(currentDb, sqlSelect, operator, isAll, metaManager);
break;
default:
throw new MySQLOutPutException(ErrorCode.ER_OPTIMIZER, "", "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near all");
}
}
Aggregations