protected void closeParentCursor(Cursor parentCursor) {
   if (parentCursor != null) {
     List<TddlException> exs = new ArrayList();
     exs = parentCursor.close(exs);
     if (!exs.isEmpty()) throw new RuntimeException(GeneralUtil.mergeException(exs));
   }
 }
  @Override
  public ITempTableSortCursor tempTableSortCursor(
      ExecutionContext executionContext,
      ISchematicCursor cursor,
      List<IOrderBy> orderBys,
      boolean sortedDuplicates,
      long requestID)
      throws TddlException {
    try {
      if (GeneralUtil.getExtraCmdBoolean(
          executionContext.getExtraCmds(), ConnectionProperties.ALLOW_TEMPORARY_TABLE, false)) {

        IRepository bdbRepo =
            ExecutorContext.getContext()
                .getRepositoryHolder()
                .getOrCreateRepository(
                    Group.GroupType.BDB_JE.name(),
                    Collections.EMPTY_MAP,
                    executionContext.getExtraCmds());
        return new TempTableSortCursor(
            this, bdbRepo, cursor, orderBys, sortedDuplicates, requestID, executionContext);
      }

      throw new IllegalStateException("not allow to use temporary table . allow first");

    } catch (Exception e) {
      closeParentCursor(cursor);
      throw new TddlException(e);
    }
  }
  @Override
  public DataType getReturnType() {
    List args = this.function.getArgs();
    List<ISelectable> returnColumns = null;
    if (GeneralUtil.isEmpty(args)) {
      throw new IllegalAccessError("impossible");
    }

    if (args.get(0) instanceof IQueryTree) {
      returnColumns = ((IQueryTree) args.get(0)).getColumns();
    } else if (args.get(0) instanceof QueryTreeNode) {
      returnColumns = ((QueryTreeNode) args.get(0)).getColumnsSelected();
    } else {
      throw new ExecutorException("subQuery is not IQueryTree or QueryTreeNode");
    }

    if (returnColumns.size() != 1) {
      throw new ExecutorException(
          "only one column can be in sub query, sub query is: " + this.getQueryPlan());
    }

    ISelectable returnColumn = returnColumns.get(0);
    return returnColumn.getDataType();
  }