package com.taobao.tddl.executor.spi; import java.util.ArrayList; import java.util.Collections; import java.util.List; import com.taobao.tddl.common.exception.TddlException; import com.taobao.tddl.common.model.ExtraCmd; import com.taobao.tddl.common.model.Group; import com.taobao.tddl.common.utils.GeneralUtil; import com.taobao.tddl.executor.common.ExecutionContext; import com.taobao.tddl.executor.common.ExecutorContext; import com.taobao.tddl.executor.cursor.Cursor; import com.taobao.tddl.executor.cursor.IAggregateCursor; import com.taobao.tddl.executor.cursor.IBlockNestedLoopCursor; import com.taobao.tddl.executor.cursor.IColumnAliasCursor; import com.taobao.tddl.executor.cursor.ICursorMeta; import com.taobao.tddl.executor.cursor.IInCursor; import com.taobao.tddl.executor.cursor.IIndexNestLoopCursor; import com.taobao.tddl.executor.cursor.ILimitFromToCursor; import com.taobao.tddl.executor.cursor.IMergeCursor; import com.taobao.tddl.executor.cursor.IMergeSortJoinCursor; import com.taobao.tddl.executor.cursor.IRangeCursor; import com.taobao.tddl.executor.cursor.IReverseOrderCursor; import com.taobao.tddl.executor.cursor.ISchematicCursor; import com.taobao.tddl.executor.cursor.ISetOrderCursor; import com.taobao.tddl.executor.cursor.ITempTableSortCursor; import com.taobao.tddl.executor.cursor.ResultCursor; import com.taobao.tddl.executor.cursor.SchematicCursor; import com.taobao.tddl.executor.cursor.impl.AffectRowCursor; import com.taobao.tddl.executor.cursor.impl.AggregateCursor; import com.taobao.tddl.executor.cursor.impl.BlockNestedtLoopCursor; import com.taobao.tddl.executor.cursor.impl.ColumnAliasCursor; import com.taobao.tddl.executor.cursor.impl.InCursor; import com.taobao.tddl.executor.cursor.impl.IndexNestedLoopMgetImpCursor; import com.taobao.tddl.executor.cursor.impl.LimitFromToCursor; import com.taobao.tddl.executor.cursor.impl.MergeCursor; import com.taobao.tddl.executor.cursor.impl.MergeSortedCursors; import com.taobao.tddl.executor.cursor.impl.RangeCursor; import com.taobao.tddl.executor.cursor.impl.ReverseOrderCursor; import com.taobao.tddl.executor.cursor.impl.SetOrderByCursor; import com.taobao.tddl.executor.cursor.impl.SortCursor; import com.taobao.tddl.executor.cursor.impl.SortMergeJoinCursor; import com.taobao.tddl.executor.cursor.impl.TempTableSortCursor; import com.taobao.tddl.executor.cursor.impl.ValueFilterCursor; import com.taobao.tddl.optimizer.core.expression.IColumn; import com.taobao.tddl.optimizer.core.expression.IFilter; import com.taobao.tddl.optimizer.core.expression.IFilter.OPERATION; import com.taobao.tddl.optimizer.core.expression.IFunction; import com.taobao.tddl.optimizer.core.expression.IOrderBy; import com.taobao.tddl.optimizer.core.expression.ISelectable; import com.taobao.tddl.optimizer.core.plan.IDataNodeExecutor; import com.taobao.tddl.optimizer.core.plan.query.IJoin; /** * 默认的cursor工厂 * * @author mengshi.sunmengshi 2013-11-27 下午3:56:20 * @since 5.0.0 */ @SuppressWarnings("rawtypes") public class CursorFactoryDefaultImpl implements ICursorFactory { public CursorFactoryDefaultImpl(){ super(); } 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 IAggregateCursor aggregateCursor(ExecutionContext executionContext, ISchematicCursor cursor, List<IFunction> aggregates, List<IOrderBy> groupBycols, List<ISelectable> allSelectable, boolean isMerge) throws TddlException { try { return new AggregateCursor(cursor, aggregates, groupBycols, allSelectable, isMerge); } catch (Exception e) { closeParentCursor(cursor); throw new TddlException(e); } } @Override public IColumnAliasCursor columnAliasCursor(ExecutionContext executionContext, ISchematicCursor cursor, List<ISelectable> retColumns, String name) throws TddlException { try { return new ColumnAliasCursor(cursor, retColumns, name); } catch (Exception e) { closeParentCursor(cursor); throw new TddlException(e); } } @Override public ValueFilterCursor valueFilterCursor(ExecutionContext executionContext, ISchematicCursor cursor, IFilter filter) throws TddlException { try { return new ValueFilterCursor(cursor, filter, null); } catch (Exception e) { closeParentCursor(cursor); throw new TddlException(e); } } @Override public SortCursor mergeSortedCursor(ExecutionContext executionContext, List<ISchematicCursor> cursors, boolean duplicated) throws TddlException { try { return new MergeSortedCursors(cursors, duplicated); } catch (Exception e) { for (ISchematicCursor cursor : cursors) { closeParentCursor(cursor); } throw new TddlException(e); } } @Override public ITempTableSortCursor tempTableSortCursor(ExecutionContext executionContext, ISchematicCursor cursor, List<IOrderBy> orderBys, boolean sortedDuplicates, long requestID) throws TddlException { try { if ("True".equalsIgnoreCase(GeneralUtil.getExtraCmdString(executionContext.getExtraCmds(), ExtraCmd.ALLOW_TEMPORARY_TABLE))) { IRepository bdbRepo = ExecutorContext.getContext() .getRepositoryHolder() .getOrCreateRepository(Group.GroupType.BDB_JE.name(), Collections.EMPTY_MAP); 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 IReverseOrderCursor reverseOrderCursor(ExecutionContext executionContext, ISchematicCursor cursor) throws TddlException { try { return new ReverseOrderCursor(cursor); } catch (Exception e) { closeParentCursor(cursor); throw new TddlException(e); } } @Override public IMergeCursor mergeCursor(ExecutionContext executionContext, List<ISchematicCursor> cursors, IDataNodeExecutor currentExecotor) throws TddlException { try { return new MergeCursor(cursors, currentExecotor, executionContext); } catch (Exception e) { if (cursors != null) { for (ISchematicCursor iSchematicCursor : cursors) { closeParentCursor(iSchematicCursor); } } throw new TddlException(e); } } @Override public IIndexNestLoopCursor indexNestLoopCursor(ExecutionContext executionContext, ISchematicCursor leftCursor, ISchematicCursor rightCursor, List leftColumns, List rightColumns, List columns, boolean prefix, IJoin executor) throws TddlException { try { return new IndexNestedLoopMgetImpCursor(leftCursor, rightCursor, leftColumns, rightColumns, columns, prefix, executor.getLeftNode().getColumns(), executor.getRightNode().getColumns(), executor); } catch (Exception e) { closeParentCursor(leftCursor); closeParentCursor(rightCursor); throw new TddlException(e); } } @Override public ILimitFromToCursor limitFromToCursor(ExecutionContext executionContext, ISchematicCursor cursor, Long limitFrom, Long limitTo) throws TddlException { try { return new LimitFromToCursor(cursor, limitFrom, limitTo); } catch (Exception e) { closeParentCursor(cursor); throw new TddlException(e); } } @Override public IMergeSortJoinCursor sortMergeJoinCursor(ExecutionContext executionContext, ISchematicCursor left_cursor, ISchematicCursor right_cursor, List left_columns, List right_columns, IJoin join) throws TddlException { try { return new SortMergeJoinCursor(left_cursor, right_cursor, left_columns, right_columns, join); } catch (Exception e) { closeParentCursor(left_cursor); closeParentCursor(right_cursor); throw new TddlException(e); } } @Override public AffectRowCursor affectRowCursor(ExecutionContext executionContext, int affectRow) { return new AffectRowCursor(affectRow); } @Override public ISchematicCursor schematicCursor(ExecutionContext executionContext, Cursor cursor, ICursorMeta meta, List<IOrderBy> orderBys) throws TddlException { try { return new SchematicCursor(cursor, meta, orderBys); } catch (Exception e) { closeParentCursor(cursor); throw new TddlException(e); } } @Override public IInCursor inCursor(ExecutionContext executionContext, Cursor cursor, List<IOrderBy> orderBys, IColumn c, List<Object> v, OPERATION op) { return new InCursor(cursor, orderBys, c, v, op); } @Override public IMergeCursor mergeCursor(ExecutionContext executionContext, List<ISchematicCursor> cursors, ICursorMeta indexMeta, IDataNodeExecutor currentExecotor, List<IOrderBy> orderBys) throws TddlException { try { return new MergeCursor(cursors, indexMeta, currentExecotor, executionContext, orderBys); } catch (Exception e) { if (cursors != null) { for (ISchematicCursor iSchematicCursor : cursors) { closeParentCursor(iSchematicCursor); } } throw new TddlException(e); } } @Override public IBlockNestedLoopCursor blockNestedLoopJoinCursor(ExecutionContext executionContext, ISchematicCursor left_cursor, ISchematicCursor right_cursor, List left_columns, List right_columns, List columns, IJoin join) throws TddlException { try { return new BlockNestedtLoopCursor(left_cursor, right_cursor, left_columns, right_columns, columns, this, join, executionContext, join.getLeftNode().getColumns(), join.getRightNode().getColumns()); } catch (Exception e) { closeParentCursor(left_cursor); closeParentCursor(right_cursor); throw new TddlException(e); } } @Override public IRangeCursor rangeCursor(ExecutionContext executionContext, ISchematicCursor cursor, IFilter lf) throws TddlException { try { return new RangeCursor(cursor, lf); } catch (Exception e) { closeParentCursor(cursor); throw new TddlException(e); } } @Override public ISetOrderCursor setOrderCursor(ExecutionContext executionContext, ISchematicCursor cursor, List<IOrderBy> ordersInRequest) throws TddlException { try { return new SetOrderByCursor(cursor, null, ordersInRequest); } catch (Exception e) { closeParentCursor(cursor); throw new TddlException(e); } } @Override public ResultCursor resultCursor(ExecutionContext context, ISchematicCursor cursor, List<Object> retColumns) throws TddlException { return new ResultCursor(cursor, context, retColumns); } }