/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.garuda.plan.logical.expression; import java.util.ArrayList; import java.util.List; import com.alibaba.garuda.data.DataType; import com.alibaba.garuda.plan.FrontendException; import com.alibaba.garuda.plan.Operator; import com.alibaba.garuda.plan.OperatorPlan; import com.alibaba.garuda.plan.PlanVisitor; import com.alibaba.garuda.plan.logical.relational.LogicalSchema; public class UserFuncExpression extends LogicalExpression { private String signature; private static int sigSeq=0; private boolean viaDefine=false; //this represents whether the function was instantiate via a DEFINE statement or not public UserFuncExpression(OperatorPlan plan) { super("UserFunc", plan); plan.add(this); if (signature == null) { signature = Integer.toString(sigSeq++); } } @Override public void accept(PlanVisitor v) throws FrontendException { } @Override public boolean isEqual(Operator other) throws FrontendException { //For the purpose of optimization rules (specially LogicalExpressionSimplifier) // a non deterministic udf is not equal to another. So returning false for //such cases. // Note that the function is also invoked by implementations of OperatorPlan.isEqual // that function is called from test cases to compare logical plans, and // it will return false even if the plans are clones. if(!this.isDeterministic()) return false; if( other instanceof UserFuncExpression ) { UserFuncExpression exp = (UserFuncExpression)other; List<Operator> mySuccs = getPlan().getSuccessors(this); List<Operator> theirSuccs = other.getPlan().getSuccessors(other); if(mySuccs == null || theirSuccs == null){ if(mySuccs == null && theirSuccs == null){ return true; }else{ //only one of the udfs has null successors return false; } } if (mySuccs.size()!=theirSuccs.size()) return false; for (int i=0;i<mySuccs.size();i++) { if (!mySuccs.get(i).isEqual(theirSuccs.get(i))) return false; } return true; } else { return false; } } public boolean isDeterministic() throws FrontendException{ return false; } public List<LogicalExpression> getArguments() throws FrontendException { List<Operator> successors = null; List<LogicalExpression> args = new ArrayList<LogicalExpression>(); // try { successors = plan.getSuccessors(this); if(successors == null) return args; for(Operator lo : successors){ args.add((LogicalExpression)lo); } // } catch (FrontendException e) { // return args; // } return args; } @Override public LogicalSchema.LogicalFieldSchema getFieldSchema() throws FrontendException { return null; } @Override public LogicalExpression deepCopy(LogicalExpressionPlan lgExpPlan) throws FrontendException { UserFuncExpression copy = null; // try { copy = new UserFuncExpression( lgExpPlan); copy.signature = signature; // Deep copy the input expressions. List<Operator> inputs = plan.getSuccessors( this ); if( inputs != null ) { for( Operator op : inputs ) { LogicalExpression input = (LogicalExpression)op; LogicalExpression inputCopy = input.deepCopy( lgExpPlan ); lgExpPlan.add( inputCopy ); lgExpPlan.connect( copy, inputCopy ); } } // } catch(CloneNotSupportedException e) { // e.printStackTrace(); // } return copy; } public String toString() { StringBuilder msg = new StringBuilder(); msg.append("(Name: " + name + "(" + ")" + " Type: "); if (fieldSchema!=null) msg.append(DataType.findTypeName(fieldSchema.type)); else msg.append("null"); msg.append(" Uid: "); if (fieldSchema!=null) msg.append(fieldSchema.uid); else msg.append("null"); msg.append(")"); return msg.toString(); } public String getSignature() { return signature; } public boolean isViaDefine() { return viaDefine; } }