001/* 002// This software is subject to the terms of the Eclipse Public License v1.0 003// Agreement, available at the following URL: 004// http://www.eclipse.org/legal/epl-v10.html. 005// You must accept the terms of that agreement to use this software. 006// 007// Copyright (C) 2006-2011 Pentaho 008// All Rights Reserved. 009*/ 010package mondrian.olap.fun; 011 012import mondrian.calc.*; 013import mondrian.calc.impl.AbstractListCalc; 014import mondrian.mdx.ResolvedFunCall; 015import mondrian.olap.*; 016 017import java.util.*; 018 019/** 020 * Definition of the <code>Union</code> MDX function. 021 * 022 * @author jhyde 023 * @since Mar 23, 2006 024 */ 025class UnionFunDef extends FunDefBase { 026 static final String[] ReservedWords = new String[] {"ALL", "DISTINCT"}; 027 028 static final ReflectiveMultiResolver Resolver = 029 new ReflectiveMultiResolver( 030 "Union", 031 "Union(<Set1>, <Set2>[, ALL])", 032 "Returns the union of two sets, optionally retaining duplicates.", 033 new String[] {"fxxx", "fxxxy"}, 034 UnionFunDef.class, 035 ReservedWords); 036 037 public UnionFunDef(FunDef dummyFunDef) { 038 super(dummyFunDef); 039 } 040 041 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 042 String allString = getLiteralArg(call, 2, "DISTINCT", ReservedWords); 043 final boolean all = allString.equalsIgnoreCase("ALL"); 044 // todo: do at validate time 045 checkCompatible(call.getArg(0), call.getArg(1), null); 046 final ListCalc listCalc0 = 047 compiler.compileList(call.getArg(0)); 048 final ListCalc listCalc1 = 049 compiler.compileList(call.getArg(1)); 050 return new AbstractListCalc(call, new Calc[] {listCalc0, listCalc1}) { 051 public TupleList evaluateList(Evaluator evaluator) { 052 TupleList list0 = listCalc0.evaluateList(evaluator); 053 TupleList list1 = listCalc1.evaluateList(evaluator); 054 return union(list0, list1, all); 055 } 056 }; 057 } 058 059 TupleList union(TupleList list0, TupleList list1, final boolean all) { 060 assert list0 != null; 061 assert list1 != null; 062 if (all) { 063 if (list0.isEmpty()) { 064 return list1; 065 } 066 if (list1.isEmpty()) { 067 return list0; 068 } 069 TupleList result = TupleCollections.createList(list0.getArity()); 070 result.addAll(list0); 071 result.addAll(list1); 072 return result; 073 } else { 074 Set<List<Member>> added = new HashSet<List<Member>>(); 075 TupleList result = TupleCollections.createList(list0.getArity()); 076 FunUtil.addUnique(result, list0, added); 077 FunUtil.addUnique(result, list1, added); 078 return result; 079 } 080 } 081} 082 083// End UnionFunDef.java