package adql.query.operand.function; /* * This file is part of ADQLLibrary. * * ADQLLibrary is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ADQLLibrary is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see <http://www.gnu.org/licenses/>. * * Copyright 2011-2015 - UDS/Centre de DonnĂ©es astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institute (ARI) */ import adql.query.ADQLObject; import adql.query.TextPosition; import adql.query.operand.ADQLOperand; /** * It represents any SQL function (COUNT, MAX, MIN, AVG, SUM, etc...). * * @author Grégory Mantelet (CDS;ARI) * @version 1.4 (06/2015) * * @see SQLFunctionType */ public class SQLFunction extends ADQLFunction { /** Type of this SQL function. */ private final SQLFunctionType type; /** The only parameter of this function (may be null). */ private ADQLOperand param = null; /** Distinct values of the parameter ? */ private boolean distinct = false; /** * Creates a SQL function with one parameter. * * @param t Type of the function. * @param operand The only parameter of this function. * @throws NullPointerException If the given is <i>null</i> or if the given operand is <i>null</i> EXCEPT when the given type is {@link SQLFunctionType#COUNT_ALL}. */ public SQLFunction(SQLFunctionType t, ADQLOperand operand) throws NullPointerException{ this(t, operand, false); } /** * Creates a SQL function with one parameter. * * @param t Type of the function. * @param operand The only parameter of this function. * @param distinctValues <i>true</i> if the quantifier DISTINCT must be used, <i>false</i> otherwise (ALL). * @throws NullPointerException If the given is <i>null</i> or if the given operand is <i>null</i> EXCEPT when the given type is {@link SQLFunctionType#COUNT_ALL}. */ public SQLFunction(SQLFunctionType t, ADQLOperand operand, boolean distinctValues) throws NullPointerException{ if (t == null) throw new NullPointerException("Impossible to build a SQLFunction without its type (COUNT, SUM, AVG, ...) !"); else type = t; if (type == SQLFunctionType.COUNT_ALL) param = null; else if (operand == null) throw new NullPointerException("Impossible to build the SQL function \"" + type.name() + "\" without the operand on which it must apply !"); else param = operand; distinct = distinctValues; } /** * Builds a SQL function by copying the given one. * * @param toCopy The SQL function to copy. * @throws Exception If there is an error during the copy. */ public SQLFunction(SQLFunction toCopy) throws Exception{ type = toCopy.type; param = (ADQLOperand)toCopy.param.getCopy(); distinct = toCopy.distinct; setPosition((toCopy.getPosition() == null) ? null : new TextPosition(toCopy.getPosition()));; } /** * Indicates whether values of the parameter must be distinct or not. * * @return <i>true</i> means distinct values, <i>false</i> else. */ public final boolean isDistinct(){ return distinct; } /** * Tells if distinct values of the given parameter must be taken. * * @param distinctValues <i>true</i> means distinct values, <i>false</i> else. */ public void setDistinct(boolean distinctValues){ distinct = distinctValues; setPosition(null); } /** * Gets the type (COUNT, SUM, AVG, ...) of this function. * * @return Its type. */ public final SQLFunctionType getType(){ return type; } @Override public ADQLObject getCopy() throws Exception{ return new SQLFunction(this); } @Override public String getName(){ return type.name(); } @Override public final boolean isNumeric(){ return true; } @Override public final boolean isString(){ return false; } @Override public final boolean isGeometry(){ return false; } @Override public ADQLOperand[] getParameters(){ if (param != null) return new ADQLOperand[]{param}; else return new ADQLOperand[0]; } @Override public int getNbParameters(){ return (type == SQLFunctionType.COUNT_ALL) ? 0 : 1; } @Override public ADQLOperand getParameter(int index) throws ArrayIndexOutOfBoundsException{ if (index < 0 || index >= getNbParameters()) throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + type.name() + "\" !"); else return param; } @Override public ADQLOperand setParameter(int index, ADQLOperand replacer) throws ArrayIndexOutOfBoundsException, NullPointerException, Exception{ if (index < 0 || index >= getNbParameters()) throw new ArrayIndexOutOfBoundsException("No " + index + "-th parameter for the function \"" + type.name() + "\" !"); if (replacer == null) throw new NullPointerException("Impossible to remove the only required parameter of the function \"" + type.name() + "\" !"); ADQLOperand replaced = param; param = replacer; setPosition(null); return replaced; } @Override public String toADQL(){ if (type == SQLFunctionType.COUNT_ALL) return "COUNT(" + (distinct ? "DISTINCT " : "") + "*)"; else return getName() + "(" + (distinct ? "DISTINCT " : "") + param.toADQL() + ")"; } }