package org.yamcs.yarch; import java.util.ArrayList; import java.util.List; /** * @see org.yamcs.yarch.streamsql.SelectExpression * */ public class SelectStream extends AbstractStream implements StreamSubscriber { CompiledExpression whereExp; AbstractStream input; final private List<CompiledExpression> aggInputList; final private List<CompiledExpression> selectList; final private WindowProcessor windowProc; final private boolean hasStars; //used as a marker for the * in "select a,*,b from..." expressions final static public CompiledExpression STAR=new CompiledExpression() { @Override public Object getValue(Tuple tuple) { return null; } @Override public ColumnDefinition getDefinition() { return null; } }; /** * * @param ydb * @param input * @param cWhereClause if null, then no where filtering * @param wp if null, then no windowProcessing (aggInputList is also null in this case) * @param cselectList * @param outputDef //output definition containing the expanded stars * @param minOutputDef //output definition where stars are not included */ public SelectStream(YarchDatabase ydb, AbstractStream input, CompiledExpression cWhereClause, List<CompiledExpression> caggInputList, WindowProcessor wp, List<CompiledExpression> cselectList, TupleDefinition outputDef, TupleDefinition minOutputDef) { super(ydb, input.getName()+"_select", outputDef); this.input=input; input.addSubscriber(this); this.aggInputList=caggInputList; this.whereExp=cWhereClause; this.windowProc=wp; this.selectList=cselectList; boolean hs=false; if(selectList!=null) { for(CompiledExpression ce:selectList) { if(ce==STAR) { hs=true; break; } } } hasStars=hs; } @Override public void onTuple(Stream stream, Tuple t) { if(whereExp!=null) { Boolean v=(Boolean)whereExp.getValue(t); if(!v) return; } if(windowProc!=null) { processWindow(t); } else { processSelectList(t); } } private void processWindow(Tuple tuple) { if(aggInputList!=null) { Object[] v=new Object[aggInputList.size()]; for(int i=0;i<v.length;i++) { v[i]=aggInputList.get(i).getValue(tuple); } tuple=new Tuple(windowProc.aggInputDef,v); } for(Tuple t:windowProc.newData(tuple)) { processSelectList(t); } } private void processSelectList(Tuple tuple) { if(selectList==null) { emitTuple(tuple); return; } ArrayList<Object> v=new ArrayList<Object>(); TupleDefinition tdef=new TupleDefinition(); for(CompiledExpression ce:selectList) { if(ce==STAR) { for(int i=0;i<tuple.size();i++) { tdef.addColumn(tuple.getColumnDefinition(i)); v.add(tuple.getColumn(i)); } } else { tdef.addColumn(ce.getDefinition()); v.add(ce.getValue(tuple)); } } tuple=new Tuple(tdef, v); emitTuple(tuple); } @Override public void streamClosed(Stream stream) { close(); } @Override public void start() { if(input.state==SETUP) input.start(); state=RUNNING; } @Override protected void doClose() { input.close(); //TODO replace with removeSubscriber } }