<?xml version="1.0" encoding="UTF-8"?>
<!--
  Copyright 2002-2004 The Apache Software Foundation

  Licensed 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.
-->

<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN"
          "http://forrest.apache.org/dtd/document-v20.dtd">


<document>
<header>
<title>User Defined Functions</title>
</header>
<body>

<section id="udfs">
<title>Introduction</title>
<p>
Pig provides extensive support for user defined functions (UDFs) as a way to specify custom processing. Pig UDFs can currently be implemented in six languages: Java, Jython, Python, JavaScript, Ruby and Groovy. 
</p>

<p>
The most extensive support is provided for Java functions. You can customize all parts of the processing including data load/store, column transformation, and aggregation. Java functions are also more efficient because they are implemented in the same language as Pig and because additional interfaces are supported such as the <a href="#algebraic-interface">Algebraic Interface</a> and the <a href="#accumulator-interface">Accumulator Interface</a>.
</p>

<p>
Limited support is provided for Jython, Python, JavaScript, Ruby and Groovy functions. These functions are new, still evolving, additions to the system. Currently only the basic interface is supported; load/store functions are not supported. Furthermore, JavaScript, Ruby and Groovy are provided as experimental features because they did not go through the same amount of testing as Java or Jython. At runtime note that Pig will automatically detect the usage of a scripting UDF in the Pig script and will automatically ship the corresponding scripting jar, either Jython, Rhino, JRuby or Groovy-all, to the backend. Python does not require any runtime engine since it invoke python command line and stream data in and out of it.</p>

<p></p>

<p>
Pig also provides support for Piggy Bank, a repository for JAVA UDFs. Through Piggy Bank you can access Java UDFs written by other users and contribute Java UDFs that you have written.
</p>

</section>


<!-- ================================================================== -->
<!-- WRITING UDFS -->

<section id="udf-java">
<title>Writing Java UDFs</title>

<!-- =============================================================== -->
<section id="eval-functions">
<title>Eval Functions</title>

<!-- +++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="eval-functions-use">
<title>How to Use a Simple Eval Function</title>
<p>Eval is the most common type of function. It can be used in <code>FOREACH</code> statements as shown in this script: </p>

<source>
-- myscript.pig
REGISTER myudfs.jar;
A = LOAD 'student_data' AS (name: chararray, age: int, gpa: float);
B = FOREACH A GENERATE myudfs.UPPER(name);
DUMP B;
</source>

<p>The command below can be used to run the script. Note that all examples in this document run in local mode for simplicity 
but the examples can also run in Tez local/Mapreduce/ Tez mode. For more information on how to run Pig, please see the PigTutorial. </p>

<source>
pig -x local myscript.pig
</source>

<p>The first line of the script provides the location of the <code>jar&nbsp;file</code> that contains the UDF. 
(Note that there are no quotes around the jar file. Having quotes would result in a syntax error.) 
To locate the jar file, Pig first checks the <code>classpath</code>. If the jar file can't be found in the classpath, 
Pig assumes that the location is either an absolute path or a path relative to the location from which Pig was invoked. 
If the jar file can't be found, an error will be printed: <code>java.io.IOException:&nbsp;Can't&nbsp;read&nbsp;jar&nbsp;file:&nbsp;myudfs.jar</code>. </p>

<p>Multiple <code>register</code> commands can be used in the same script. If the same fully-qualified function is present in multiple jars, 
the first occurrence will be used consistently with Java semantics. </p>

<p>The name of the UDF has to be fully qualified with the package name or an error will be reported: 
<code>java.io.IOException:&nbsp;Cannot&nbsp;instantiate:UPPER</code>. Also, the function name is case sensitive (UPPER and upper are not the same). 
A UDF can take one or more parameters. The exact signature of the function should be clear from its documentation. </p>

<p>The function provided in this example takes an ASCII string and produces its uppercase version. If you are familiar with column transformation functions 
in SQL, you will recognize that UPPER fits this concept. However, as we will see later in the document, eval functions in Pig go beyond column 
transformation functions and include aggregate and filter functions. </p>

<p>If you are just a user of UDFs, this is most of what you need to know about UDFs to use them in your code.  </p>

</section>

<!-- +++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="eval-functions-write">
<title> How to Write a Simple Eval Function</title>
<p>Let's now look at the implementation of the <code>UPPER</code> UDF. </p>

<source>
1  package myudfs;
2  import java.io.IOException;
3  import org.apache.pig.EvalFunc;
4  import org.apache.pig.data.Tuple;
5
6  public class UPPER extends EvalFunc&lt;String&gt;
7  {
8    public String exec(Tuple input) throws IOException {
9        if (input == null || input.size() == 0 || input.get(0) == null)
10            return null;
11        try{
12            String str = (String)input.get(0);
13           return str.toUpperCase();
14        }catch(Exception e){
15            throw new IOException("Caught exception processing input row ", e);
16        }
17    }
18  }
</source>

<p>Line 1 indicates that the function is part of the <code>myudfs</code> package. The UDF class extends the <code>EvalFunc</code> class which is the base class for all eval functions. It is parameterized with the return type of the UDF which is a Java <code>String</code> in this case. We will look into the <code>EvalFunc</code> class in more detail later, but for now all we need to do is to implement the <code>exec</code> function. This function is invoked on every input tuple. The input into the function is a tuple with input parameters in the order they are passed to the function in the Pig script. In our example, it will contain a single string field corresponding to the student name. </p>
<p>The first thing to decide is what to do with invalid data. This depends on the format of the data. If the data is of type <code>bytearray</code> it means that it has not yet been converted to its proper type. In this case, if the format of the data does not match the expected type, a NULL value should be returned. If, on the other hand, the input data is of another type, this means that the conversion has already happened and the data should be in the correct format. This is the case with our example and that's why it throws an error (line 15.) </p>
<p>Also, note that lines 9-10 check if the input data is null or empty and if so returns null. </p>
<p>The actual function implementation is on lines 12-13 and is self-explanatory. </p>
<p>Now that we have the function implemented, it needs to be compiled and included in a jar. You will need to build <code>pig.jar</code> to compile your UDF. You can use the following set of commands to checkout the code from SVN repository and create pig.jar: </p>

<source>
svn co http://svn.apache.org/repos/asf/pig/trunk
cd trunk
ant
</source>

<p>You should see <code>pig.jar</code> in your current working directory. The set of commands below first compiles the function and then creates a jar file that contains it. </p>

<source>
cd myudfs
javac -cp pig.jar UPPER.java
cd ..
jar -cf myudfs.jar myudfs
</source>

<p>You should now see <code>myudfs.jar</code> in your current working directory. You can use this jar with the script described in the previous section. </p>

</section>

<!-- +++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="aggregate-functions">
<title>Aggregate Functions</title>
<p>Aggregate functions are another common type of eval function. Aggregate functions are usually applied to grouped data, as shown in this script: </p>

<source>
-- myscript2.pig
A = LOAD 'student_data' AS (name: chararray, age: int, gpa: float);
B = GROUP A BY name;
C = FOREACH B GENERATE group, COUNT(A);
DUMP C;
</source>

<p>The script above uses the <code>COUNT</code> function to count the number of students with the same name. There are a couple of things to note about this script. First, even though we are using a function, there is no <code>register</code> command. Second, the function is not qualified with the package name. The reason for both is that <code>COUNT</code> is a <code>builtin</code> function meaning that it comes with the Pig distribution. These are the only two differences between builtins and UDFs. Builtins are discussed in more detail later in this document.  </p>
</section>

<!-- +++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="algebraic-interface">
<title>Algebraic Interface</title>

<p>An aggregate function is an eval function that takes a bag and returns a scalar value. One interesting and useful property of many aggregate functions is that they can be computed incrementally in a distributed fashion. We call these functions <code>algebraic</code>. <code>COUNT</code> is an example of an algebraic function because we can count the number of elements in a subset of the data and then sum the counts to produce a final output. In the Hadoop world, this means that the partial computations can be done by the map and combiner, and the final result can be computed by the reducer. </p>

<p>It is very important for performance to make sure that aggregate functions that are algebraic are implemented as such. Let's look at the implementation of the COUNT function to see what this means. (Error handling and some other code is omitted to save space. The full code can be accessed <a href="http://svn.apache.org/viewvc/pig/trunk/src/org/apache/pig/builtin/COUNT.java?view=markup"> here</a>.)</p>

<source>
public class COUNT extends EvalFunc&lt;Long&gt; implements Algebraic{
    public Long exec(Tuple input) throws IOException {return count(input);}
    public String getInitial() {return Initial.class.getName();}
    public String getIntermed() {return Intermed.class.getName();}
    public String getFinal() {return Final.class.getName();}
    static public class Initial extends EvalFunc&lt;Tuple&gt; {
        public Tuple exec(Tuple input) throws IOException {return TupleFactory.getInstance().newTuple(count(input));}
    }
    static public class Intermed extends EvalFunc&lt;Tuple&gt; {
        public Tuple exec(Tuple input) throws IOException {return TupleFactory.getInstance().newTuple(sum(input));}
    }
    static public class Final extends EvalFunc&lt;Long&gt; {
        public Long exec(Tuple input) throws IOException {return sum(input);}
    }
    static protected Long count(Tuple input) throws ExecException {
        Object values = input.get(0);
        if (values instanceof DataBag) return ((DataBag)values).size();
        else if (values instanceof Map) return new Long(((Map)values).size());
    }
    static protected Long sum(Tuple input) throws ExecException, NumberFormatException {
        DataBag values = (DataBag)input.get(0);
        long sum = 0;
        for (Iterator (Tuple) it = values.iterator(); it.hasNext();) {
            Tuple t = it.next();
            sum += (Long)t.get(0);
        }
        return sum;
    }
}
</source>

<p><code>COUNT</code> implements <code>Algebraic</code> interface which looks like this: </p>

<source>
public interface Algebraic{
    public String getInitial();
    public String getIntermed();
    public String getFinal();
}
</source>

<p>For a function to be algebraic, it needs to implement <code>Algebraic</code> interface that consist of definition of three classes derived from <code>EvalFunc</code>. The contract is that the  <code>exec</code> function of the <code>Initial</code> class is called once and is passed the original input tuple. Its output is a tuple that contains partial results. The <code>exec</code> function of the <code>Intermed</code> class can be called zero or more times and takes as its input a tuple that contains partial results produced by the <code>Initial</code> class or by prior invocations of the <code>Intermed</code> class and produces a tuple with another partial result. Finally, the <code>exec</code> function of the <code>Final</code> class is called and produces the final result as a scalar type. </p>

<p>Here's the way to think about this in the Hadoop world. The <code>exec</code> function of the <code>Initial</code> class is invoked once for each input tuple by the <code>map</code> process and produces partial results. The <code>exec</code> function of the <code>Intermed</code> class is invoked once by each <code>combiner</code> invocation (which can happen zero or more times) and also produces partial results. The <code>exec</code> function of the <code>Final</code> class is invoked once by the reducer and produces the final result. </p>
<p>Take a look at the <code>COUNT</code> implementation to see how this is done. Note that the <code>exec</code> function of the <code>Initial</code> and <code>Intermed</code> classes is parameterized with <code>Tuple</code> and the <code>exec</code> of the <code>Final</code> class is parameterized with the real type of the function, which in the case of the <code>COUNT</code> is <code>Long</code>. Also, note that the fully-qualified name of the class needs to be returned from <code>getInitial</code>, <code>getIntermed</code>, and <code>getFinal</code> methods. </p>
</section>

<!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="accumulator-interface">
<title>Accumulator Interface</title>

<p>In Pig, problems with memory usage can occur when data, which results from a group or cogroup operation, needs to be placed in a bag  and passed in its entirety to a UDF.</p>

<p>This problem is partially addressed by Algebraic UDFs that use the combiner and can deal with data being passed to them incrementally during different processing phases (map, combiner, and reduce). However, there are a number of UDFs that are not Algebraic, don't use the combiner, but still don’t need to be given all data at once. </p>

<p>The new Accumulator interface is designed to decrease memory usage by targeting such UDFs. For the functions that implement this interface, Pig guarantees that the data for the same key is passed continuously but in small increments. To work with incremental data, here is the interface a UDF needs to implement:</p>
<source>
public interface Accumulator &lt;T&gt; {
   /**
    * Process tuples. Each DataBag may contain 0 to many tuples for current key
    */
    public void accumulate(Tuple b) throws IOException;
    /**
     * Called when all tuples from current key have been passed to the accumulator.
     * @return the value for the UDF for this key.
     */
    public T getValue();
    /**
     * Called after getValue() to prepare processing for next key. 
     */
    public void cleanup();
}
</source>

<p>There are several things to note here:</p>

<ol>
	<li>Each UDF must extend the EvalFunc class and implement all necessary functions there.</li>
	<li>If a function is algebraic but can be used in a FOREACH statement with accumulator functions, it needs to implement the Accumulator interface in addition to the Algebraic interface.</li>
	<li>The interface is parameterized with the return type of the function.</li>
	<li>The accumulate function is guaranteed to be called one or more times, passing one or more tuples in a bag, to the UDF. (Note that the tuple that is passed to the accumulator has the same content as the one passed to exec – all the parameters passed to the UDF – one of which should be a bag.)</li>
	<li>The getValue function is called after all the tuples for a particular key have been processed to retrieve the final value.</li>
	<li>The cleanup function is called after getValue but before the next value is processed.</li>
</ol>


<p>Here us a code snippet of the integer version of the MAX function that implements the interface:</p>
<source>
public class IntMax extends EvalFunc&lt;Integer&gt; implements Algebraic, Accumulator&lt;Integer&gt; {
    …….
    /* Accumulator interface */
    
    private Integer intermediateMax = null;
    
    @Override
    public void accumulate(Tuple b) throws IOException {
        try {
            Integer curMax = max(b);
            if (curMax == null) {
                return;
            }
            /* if bag is not null, initialize intermediateMax to negative infinity */
            if (intermediateMax == null) {
                intermediateMax = Integer.MIN_VALUE;
            }
            intermediateMax = java.lang.Math.max(intermediateMax, curMax);
        } catch (ExecException ee) {
            throw ee;
        } catch (Exception e) {
            int errCode = 2106;
            String msg = "Error while computing max in " + this.getClass().getSimpleName();
            throw new ExecException(msg, errCode, PigException.BUG, e);           
        }
    }

    @Override
    public void cleanup() {
        intermediateMax = null;
    }

    @Override
    public Integer getValue() {
        return intermediateMax;
    }
}
</source>
</section>


<!-- +++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="filter-functions">
<title> Filter Functions</title>
<p>Filter functions are eval functions that return a <code>boolean</code> value. Filter functions can be used anywhere a Boolean expression is appropriate, including the <code>FILTER</code> operator or <code>bincond</code> expression. </p>

<p>The example below uses the <code>IsEmpy</code> builtin filter function to implement joins. </p>

<source>
-- inner join
A = LOAD 'student_data' AS (name: chararray, age: int, gpa: float);
B = LOAD 'voter_data' AS (name: chararray, age: int, registration: chararay, contributions: float);
C = COGROUP A BY name, B BY name;
D = FILTER C BY not IsEmpty(A);
E = FILTER D BY not IsEmpty(B);
F = FOREACH E GENERATE flatten(A), flatten(B);
DUMP F;
</source>

<p>Note that, even if filtering is omitted, the same results will be produced because the <code>foreach</code> results is a cross product and cross products get rid of empty bags. However, doing up-front filtering is more efficient since it reduces the input of the cross product. </p>

<source>
-- full outer join
A = LOAD 'student_data' AS (name: chararray, age: int, gpa: float);
B = LOAD 'voter_data' AS (name: chararray, age: int, registration: chararay, contributions: float);
C = COGROUP A BY name, B BY name;
D = FOREACH C GENERATE group, flatten((IsEmpty(A) ? null : A)), flatten((IsEmpty(B) ? null : B));
dump D;
</source>

<p>The implementation of the <code>IsEmpty</code> function looks like this: </p>

<source>
import java.io.IOException;
import java.util.Map;

import org.apache.pig.FilterFunc;
import org.apache.pig.PigException;
import org.apache.pig.backend.executionengine.ExecException;
import org.apache.pig.data.DataBag;
import org.apache.pig.data.Tuple;
import org.apache.pig.data.DataType;

/**
 * Determine whether a bag or map is empty.
 */
public class IsEmpty extends FilterFunc {

    @Override
    public Boolean exec(Tuple input) throws IOException {
        try {
            Object values = input.get(0);
            if (values instanceof DataBag)
                return ((DataBag)values).size() == 0;
            else if (values instanceof Map)
                return ((Map)values).size() == 0;
            else {
                int errCode = 2102;
                String msg = "Cannot test a " +
                DataType.findTypeName(values) + " for emptiness.";
                throw new ExecException(msg, errCode, PigException.BUG);
            }
        } catch (ExecException ee) {
            throw ee;
        }
    }
} 
</source>
</section>

<section id="udf_simulation">
<title>Implement UDF by Simulation</title>
<p>When implementing more advanced types of EvalFuncs, the simpler implementations can be automatically provided by Pig.  Thus if your UDF implements <a href="#algebraic-interface">Algebraic</a> then you will get the Accumulator interface and basic the basic EvalFunc exec method for free.  Similarly, if your UDF implements <a href="#accumulator-interface">Accumulator Interface</a> you will get the basic EvalFunc exec method for free.  You will not get the Algebraic implemenation.  Note that these free implementations are based on simulation, which might not be the most efficient.  If you wish to ensure the efficiency of your Accumulator of EvalFunc exec method, you may still implement them yourself and your implementations will be used.</p>
</section>
<!-- +++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="pig-types">
<title> Pig Types and Native Java Types</title>
<p>The main thing to know about Pig's type system is that Pig uses native Java types for almost all of its types, as shown in this table. </p>


<table>
<tr>
<th>
Pig Type
</th>
<th>
Java Class
</th>
</tr>
<tr>
<td>
<p> bytearray </p>
</td>
<td>
<p> DataByteArray </p>
</td>
</tr>
<tr>
<td>
<p> chararray </p>
</td>
<td>
<p> String </p>
</td>
</tr>
<tr>
<td>
<p> int </p>
</td>
<td>
<p> Integer </p>
</td>
</tr>
<tr>
<td>
<p> long </p>
</td>
<td>
<p> Long </p>
</td>
</tr>
<tr>
<td>
<p> float </p>
</td>
<td>
<p> Float </p>
</td>
</tr>
<tr>
<td>
<p> double </p>
</td>
<td>
<p> Double </p>
</td>
</tr>
<tr>
<td>
<p> boolean </p>
</td>
<td>
<p> Boolean </p>
</td>
</tr>
<tr>
<td>
<p> datetime </p>
</td>
<td>
<p> DateTime </p>
</td>
</tr>
<tr>
<td>
<p> bigdecimal </p>
</td>
<td>
<p> BigDecimal </p>
</td>
</tr>
<tr>
<td>
<p> biginteger </p>
</td>
<td>
<p> BigInteger </p>
</td>
</tr>
<tr>
<td>
<p> tuple </p>
</td>
<td>
<p> Tuple </p>
</td>
</tr>
<tr>
<td>
<p> bag </p>
</td>
<td>
<p> DataBag </p>
</td>
</tr>
<tr>
<td>
<p> map </p>
</td>
<td>
<p> Map&lt;Object, Object&gt; </p>
</td>
</tr>
</table>

<p>All Pig-specific classes are available <a href="http://svn.apache.org/viewvc/pig/trunk/src/org/apache/pig/data/"> here</a>. </p>
<p><code>Tuple</code> and <code>DataBag</code> are different in that they are not concrete classes but rather interfaces. This enables users to extend Pig with their own versions of tuples and bags. As a result, UDFs cannot directly instantiate bags or tuples; they need to go through factory classes: <code>TupleFactory</code> and <code>BagFactory</code>. </p>
<p>The builtin <code>TOKENIZE</code> function shows how bags and tuples are created. A function takes a text string as input and returns a bag of words from the text. (Note that currently Pig bags always contain tuples.) </p>

<source>
package org.apache.pig.builtin;

import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.BagFactory;
import org.apache.pig.data.DataBag;
import org.apache.pig.data.Tuple;
import org.apache.pig.data.TupleFactory;

public class TOKENIZE extends EvalFunc&lt;DataBag&gt; {
    TupleFactory mTupleFactory = TupleFactory.getInstance();
    BagFactory mBagFactory = BagFactory.getInstance();

    public DataBag exec(Tuple input) throws IOException 
        try {
            DataBag output = mBagFactory.newDefaultBag();
            Object o = input.get(0);
            if (!(o instanceof String)) {
                throw new IOException("Expected input to be chararray, but  got " + o.getClass().getName());
            }
            StringTokenizer tok = new StringTokenizer((String)o, " \",()*", false);
            while (tok.hasMoreTokens()) output.add(mTupleFactory.newTuple(tok.nextToken()));
            return output;
        } catch (ExecException ee) {
            // error handling goes here
        }
    }
}
</source>
</section>

<!-- +++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="schemas">
<title>Schemas and Java UDFs</title>

<p>Pig uses type information for validation and performance. It is important for UDFs to participate in type propagation. Our UDFs generally make no effort to communicate their output schema to Pig. This is because Pig can usually figure out this information by using Java's <a href="http://www.oracle.com/technetwork/articles/java/javareflection-1536171.html"> Reflection</a>. If your UDF returns a scalar or a map, no work is required. However, if your UDF returns a tuple or a bag (of tuples), it needs to help Pig figure out the structure of the tuple. </p>
<p>If a UDF returns a tuple or a bag and schema information is not provided, Pig assumes that the tuple contains a single field of type bytearray. If this is not the case, then not specifying the schema can cause failures. We look at this next. </p>
<p>Let's assume that we have UDF <code>Swap</code> that, given a tuple with two fields, swaps their order. Let's assume that the UDF does not specify a schema and look at the scripts below: </p>

<source>
register myudfs.jar;
A = load 'student_data' as (name: chararray, age: int, gpa: float);
B = foreach A generate flatten(myudfs.Swap(name, age)), gpa;
C = foreach B generate $2;
D = limit B 20;
dump D;
</source>

<p>This script will result in the following error cause by line 4 ( <code>C = foreach B generate $2;</code>). </p>

<source>
java.io.IOException: Out of bound access. Trying to access non-existent column: 2. Schema {bytearray,gpa: float} has 2 column(s).
</source>

<p>This is because Pig is only aware of two columns in B while line 4 is requesting the third column of the tuple. (Column indexing in Pig starts with 0.) </p>
<p>The function, including the schema, looks like this: </p>

<source>
package myudfs;
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;
import org.apache.pig.data.TupleFactory;
import org.apache.pig.impl.logicalLayer.schema.Schema;
import org.apache.pig.data.DataType;

public class Swap extends EvalFunc&lt;Tuple&gt; {
    public Tuple exec(Tuple input) throws IOException {
        if (input == null || input.size()   2
            return null;
        try{
            Tuple output = TupleFactory.getInstance().newTuple(2);
            output.set(0, input.get(1));
            output.set(1, input.get(0));
            return output;
        } catch(Exception e){
            System.err.println("Failed to process input; error - " + e.getMessage());
            return null;
        }
    }
    public Schema outputSchema(Schema input) {
        try{
            Schema tupleSchema = new Schema();
            tupleSchema.add(input.getField(1));
            tupleSchema.add(input.getField(0));
            return new Schema(new Schema.FieldSchema(getSchemaName(this.getClass().getName().toLowerCase(), input),tupleSchema, DataType.TUPLE));
        }catch (Exception e){
                return null;
        }
    }
}
</source>

<p>The function creates a schema with a single field (of type <code>FieldSchema) of type tuple</code>. The name of the field is constructed using the <code>getSchemaName</code> function of the <code>EvalFunc</code> class. The name consists of the name of the UDF function, the first parameter passed to it, and a sequence number to guarantee uniqueness. In the previous script, if you replace <code>dump&nbsp;D;</code>  with <code>describe&nbsp;B;</code> , you will see the following output: 
</p>

<source>
B: {myudfs.swap_age_3::age: int,myudfs.swap_age_3::name: chararray,gpa: float}
</source>

<p>The second parameter to the <code>FieldSchema</code> constructor is the schema representing this field, which in this case is a tuple with two fields. The third parameter represents the type of the schema, which in this case is a <code>TUPLE</code>. All supported schema types are defined in the <code>org.apache.pig.data.DataType</code> class. </p>

<source>
public class DataType {
    public static final byte UNKNOWN   =   0;
    public static final byte NULL      =   1;
    public static final byte BOOLEAN   =   5; // internal use only
    public static final byte BYTE      =   6; // internal use only
    public static final byte INTEGER   =  10;
    public static final byte LONG      =  15;
    public static final byte FLOAT     =  20;
    public static final byte DOUBLE    =  25;
    public static final byte DATETIME  =  30;
    public static final byte BYTEARRAY =  50;
    public static final byte CHARARRAY =  55;
    public static final byte BIGINTEGER =  65;
    public static final byte BIGDECIMAL =  70;
    public static final byte MAP       = 100;
    public static final byte TUPLE     = 110;
    public static final byte BAG       = 120;
    public static final byte ERROR     =  -1;
    // more code here
}
</source>

<p>You need to import the <code>org.apache.pig.data.DataType</code> class into your code to define schemas. You also need to import the schema class <code>org.apache.pig.impl.logicalLayer.schema.Schema</code>. </p>
<p>The example above shows how to create an output schema for a tuple. Doing this for a bag is very similar. Let's extend the <code>TOKENIZE</code> function to do that.</p>

<p>As you can see in the example below, this is very similar to the output schema definition in the <code>Swap</code> function. One difference is that instead of reusing input schema, we create a brand new field schema to represent the tokens stored in the bag. The other difference is that the type of the schema created is BAG (not TUPLE). </p>

<source>
package org.apache.pig.builtin;

import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.BagFactory;
import org.apache.pig.data.DataBag;
import org.apache.pig.data.Tuple;
import org.apache.pig.data.TupleFactory;
import org.apache.pig.impl.logicalLayer.schema.Schema;
import org.apache.pig.data.DataType;

public class TOKENIZE extends EvalFunc&lt;DataBag&gt; {
    TupleFactory mTupleFactory = TupleFactory.getInstance();
    BagFactory mBagFactory = BagFactory.getInstance();
    public DataBag exec(Tuple input) throws IOException {
        try {
            DataBag output = mBagFactory.newDefaultBag();
            Object o = input.get(0);
            if ((o instanceof String)) {
                throw new IOException("Expected input to be chararray, but  got " + o.getClass().getName());
            }
            StringTokenizer tok = new StringTokenizer((String)o, " \",()*", false);
            while (tok.hasMoreTokens()) output.add(mTupleFactory.newTuple(tok.nextToken()));
            return output;
        } catch (ExecException ee) {
            // error handling goes here
        }
    }
    public Schema outputSchema(Schema input) {
         try{
             Schema bagSchema = new Schema();
             bagSchema.add(new Schema.FieldSchema("token", DataType.CHARARRAY));

             return new Schema(new Schema.FieldSchema(getSchemaName(this.getClass().getName().toLowerCase(), input),
                                                    bagSchema, DataType.BAG));
         }catch (Exception e){
            return null;
         }
    }
}
</source>
<p></p>
<p>One more note about schemas and UDFs. Users have requested the ability to examine the input schema of the data before processing the data via a UDF. For example, they would like to know how to convert an input tuple to a map such that the keys in the map are the names of the input columns. Currently there is no way to do this. This is a feature we would like to support in the future.</p>

</section>


<!-- +++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="error-handling">
<title> Error Handling</title>

<p>There are several types of errors that can occur in a UDF: </p>
<ol>
<li><p>An error that affects a particular row but is not likely to impact other rows. An example of such an error would be a malformed input value or divide by zero problem. A reasonable handling of this situation would be to emit a warning and return a null value. <code>ABS</code> function in the next section demonstrates this approach. The current approach is to write the warning to <code>stderr</code>. Eventually we would like to pass a logger to the UDFs. Note that returning a NULL value only makes sense if the malformed value is of type <code>bytearray</code>. Otherwise the proper type has been already created and should have an appropriate value. If this is not the case, it is an internal error and should cause the system to fail. Both cases can be seen in the implementation of the <code>ABS</code> function in the next section. </p>
</li>
<li><p>An error that affects the entire processing but can succeed on retry. An example of such a failure is the inability to open a lookup file because the file could not be found. This could be a temporary environmental issue that can go away on retry. A UDF can signal this to Pig by throwing an <code>IOException</code> as with the case of the <code>ABS</code> function below. </p>
</li>
<li><p>An error that affects the entire processing and is not likely to succeed on retry. An example of such a failure is the inability to open a lookup file because of file permission problems. Pig currently does not have a way to handle this case. Hadoop does not have a way to handle this case either. It will be handled the same way as 2 above. </p>
</li>
</ol>

</section>

<!-- +++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="function-overloading">
<title>Function Overloading</title>

<p>Before the type system was available in Pig, all values for the purpose of arithmetic calculations were assumed to be doubles as the safest choice. However, this is not very efficient if the data is actually of type integer or long. (We saw about a 2x slowdown of a query when using double where integer could be used.) Now that Pig supports types we can take advantage of the type information and choose the function that is most efficient for the provided operands. </p>
<p>UDF writers are encouraged to provide type-specific versions of a function if this can result in better performance. On the other hand, we don't want the users of the functions to worry about different functions - the right thing should just happen. Pig allows for this via a function table mechanism as shown in the next example. </p>
<p>This example shows the implementation of the <code>ABS</code> function that returns the absolute value of a numeric value passed to it as input. </p>

<source>
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import org.apache.pig.EvalFunc;
import org.apache.pig.FuncSpec;
import org.apache.pig.data.Tuple;
import org.apache.pig.impl.logicalLayer.FrontendException;
import org.apache.pig.impl.logicalLayer.schema.Schema;
import org.apache.pig.data.DataType;

public class ABS extends EvalFunc&lt;Double&gt; {
    public Double exec(Tuple input) throws IOException {
        if (input == null || input.size() == 0)
            return null;
        Double d;
        try{
            d = DataType.toDouble(input.get(0));
        } catch (NumberFormatException nfe){
            System.err.println("Failed to process input; error - " + nfe.getMessage());
            return null;
        } catch (Exception e){
            throw new IOException("Caught exception processing input row ", e);
        }
        return Math.abs(d);
    }
    public List&lt;FuncSpec&gt; getArgToFuncMapping() throws FrontendException {
        List&lt;FuncSpec&gt; funcList = new ArrayList&lt;FuncSpec&gt;();
        funcList.add(new FuncSpec(this.getClass().getName(), new Schema(new Schema.FieldSchema(null, DataType.BYTEARRAY))));
        funcList.add(new FuncSpec(DoubleAbs.class.getName(),  new Schema(new Schema.FieldSchema(null, DataType.DOUBLE))));
        funcList.add(new FuncSpec(FloatAbs.class.getName(),   new Schema(new Schema.FieldSchema(null, DataType.FLOAT))));
        funcList.add(new FuncSpec(IntAbs.class.getName(),  new Schema(new Schema.FieldSchema(null, DataType.INTEGER))));
        funcList.add(new FuncSpec(LongAbs.class.getName(),  new Schema(new Schema.FieldSchema(null, DataType.LONG))));
        return funcList;
    }
}
</source>

<p>The main thing to notice in this example is the <code>getArgToFuncMapping()</code> method. This method returns a list that contains a mapping from the input schema to the class that should be used to handle it. In this example the main class handles the <code>bytearray</code> input and outsources the rest of the work to other classes implemented in separate files in the same package. The example of one such class is below. This class handles integer input values. </p>

<source>
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;

public class IntAbs extends EvalFunc&lt;Integer&gt; {
    public Integer exec(Tuple input) throws IOException {
        if (input == null || input.size() == 0)
            return null;
        Integer d;
        try{
            d = (Integer)input.get(0);
        } catch (Exception e){
            throw new IOException("Caught exception processing input row ", e);
        }
        return Math.abs(d);
    }
}
</source>


<p>A note on error handling. The <code>ABS</code> class covers the case of the <code>bytearray</code> which means the data has not been converted yet to its actual type. This is why a null value is returned when <code>NumberFormatException</code> is encountered. However, the <code>IntAbs</code> function is only called if the data is already of type <code>Integer</code> which means it has already been converted to the real type and bad format has been dealt with. This is why an exception is thrown if the input can't be cast to <code>Integer</code>. </p>
<p>The example above covers a reasonably simple case where the UDF only takes one parameter and there is a separate function for each parameter type. However, this will not always be the case. If Pig can't find an <code>exact&nbsp;match</code> it tries to do a <code>best&nbsp;match</code>. The rule for the best match is to find the most efficient function that can be used safely. This means that Pig must find the function that, for each input parameter, provides the smallest type that is equal to or greater than the input type. The type progression rules are: <code>int&gt;long&gt;float&gt;double</code>. </p>
<p>For instance, let's consider function <code>MAX</code> which is part of the <code>piggybank</code> described later in this document. Given two values, the function returns the larger value. The function table for <code>MAX</code> looks like this: </p>

<source>
public List&lt;FuncSpec&gt; getArgToFuncMapping() throws FrontendException {
    List&lt;FuncSpec&gt; funcList = new ArrayList&lt;FuncSpec&gt;();
    Util.addToFunctionList(funcList, IntMax.class.getName(), DataType.INTEGER);
    Util.addToFunctionList(funcList, DoubleMax.class.getName(), DataType.DOUBLE);
    Util.addToFunctionList(funcList, FloatMax.class.getName(), DataType.FLOAT);
    Util.addToFunctionList(funcList, LongMax.class.getName(), DataType.LONG);

    return funcList;
}
</source>

<p>The <code>Util.addToFunctionList</code> function is a helper function that adds an entry to the list as the first argument, with the key of the class name passed as the second argument, and the schema containing two fields of the same type as the third argument.  </p>

<p>Let's now see how this function can be used in a Pig script: </p>

<source>
REGISTER piggybank.jar
A = LOAD 'student_data' AS (name: chararray, gpa1: float, gpa2: double);
B = FOREACH A GENERATE name, org.apache.pig.piggybank.evaluation.math.MAX(gpa1, gpa2);
DUMP B;
</source>

<p>In this example, the function gets one parameter of type <code>float</code> and another of type <code>double</code>. The best fit will be the function that takes two double values. Pig makes this choice on the user's behalf by inserting implicit casts for the parameters. Running the script above is equivalent to running the script below: </p>

<source>
A = LOAD 'student_data' AS (name: chararray, gpa1: float, gpa2: double);
B = FOREACH A GENERATE name, org.apache.pig.piggybank.evaluation.math.MAX((double)gpa1, gpa2);
DUMP B;
</source>

<p>A special case of the <code>best&nbsp;fit</code> approach is handling data without a schema specified. The type for this data is interpreted as <code>bytearray</code>. Since the type of the data is not known, there is no way to choose a best fit version. The only time a cast is performed is when the function table contains only a single entry. This works well to maintain backward compatibility.  </p>

<p>Let's revisit the <code>UPPER</code> function from our first example. As it is written now, it would only work if the data passed to it is of type <code>chararray</code>. To make it work with data whose type is not explicitly set, a function table with a single entry needs to be added: </p>

<source>
package myudfs;
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;

public class UPPER extends EvalFunc&lt;String&gt;
{
    public String exec(Tuple input) throws IOException {
        if (input == null || input.size() == 0)
            return null;
        try{
            String str = (String)input.get(0);
            return str.toUpperCase();
        }catch(Exception e){
            System.err.println("WARN: UPPER: failed to process input; error - " + e.getMessage());
            return null;
        }
    }
    public List&lt;FuncSpec&gt; getArgToFuncMapping() throws FrontendException {
        List&lt;FuncSpec&gt; funcList = new ArrayList&lt;FuncSpec&gt;();
        funcList.add(new FuncSpec(this.getClass().getName(), new Schema(new Schema.FieldSchema(null, DataType.CHARARRAY))));
        return funcList;
    }
}
</source>

<p>Now the following script will ran: </p>

<source>
-- this is myscript.pig
REGISTER myudfs.jar;
A = LOAD 'student_data' AS (name, age, gpa);
B = FOREACH A GENERATE myudfs.UPPER(name);
DUMP B;
</source>
<p>Variable-length arguments: </p>
<p>The last input schema field in <code>getArgToFuncMapping()</code> can be marked as vararg, which enables UDF writers to create UDFs that take variable length arguments. This is done by overriding
the <code>getSchemaType()</code> method:
</p>
<source>
@Override
public SchemaType getSchemaType() {
    return SchemaType.VARARG;
}
</source>
<p>For an example see <a href="http://svn.apache.org/viewvc/pig/trunk/src/org/apache/pig/builtin/CONCAT.java?view=markup">CONCAT</a>.</p>
</section>

<section id="counters">
<title>Using Counters</title>
<p>Hadoop counters are easily accessible within EvalFunc by using PigStatusReporter object. Here is one example:</p>
<source>
public class UPPER extends EvalFunc&lt;String&gt;
{
        public String exec(Tuple input) throws IOException {
                if (input == null || input.size() == 0) {
                    PigStatusReporter reporter = PigStatusReporter.getInstance();
                    if (reporter != null) {
                       reporter.incrCounter(PigWarning.UDF_WARNING_1, 1);
                    }
                    return null;
                }
                try{
                        String str = (String)input.get(0);
                        return str.toUpperCase();
                }catch(Exception e){
                    throw new IOException("Caught exception processing input row ", e);
                }
        }
}
</source>
</section>
<section id="access-input-schema">
        <title>Access input schema inside EvalFunc</title>
        <p>Not only inside outputSchema at compile time, input schema is also accessible in exec at runtime. For example:</p>
<source>
public class AddSchema extends EvalFunc&lt;String&gt;
{
        public String exec(Tuple input) throws IOException {
                if (input == null || input.size() == 0)
                    return null;
                String result = "";
                for (int i=0;i&lt;input.size();i++) {
                    result += getInputSchema().getFields().get(i).alias;
                    result += ":";
                    result += input.get(i);
                }
                return result;
        }
}
</source>
</section>
<!-- +++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="reporting-progress">
<title>Reporting Progress</title>

<p>A challenge of running a large shared system is to make sure system resources are used efficiently. One aspect of this challenge is detecting runaway processes that are no longer making progress. Pig uses a heartbeat mechanism for this purpose. If any of the tasks stops sending a heartbeat, the system assumes that it is dead and kills it.   </p>
<p>Most of the time, single-tuple processing within a UDF is very short and does not require a UDF to heartbeat. The same is true for aggregate functions that operate on large bags because bag iteration code takes care of it. However, if you have a function that performs a complex computation that can take an order of minutes to execute, you should add a progress indicator to your code. This is very easy to accomplish. The <code>EvalFunc</code> class provides a <code>progress</code> function that you need to call in your <code>exec</code> method. </p>
<p>For instance, the <code>UPPER</code> function would now look as follows: </p>

<source>
public class UPPER extends EvalFunc&lt;String&gt;
{
        public String exec(Tuple input) throws IOException {
                if (input == null || input.size() == 0)
                return null;
                try{
                        progress();
                        String str = (String)input.get(0);
                        return str.toUpperCase();
                }catch(Exception e){
                    throw new IOException("Caught exception processing input row ", e);
                }
        }
}
</source>
</section>

<!-- +++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="distributed-cache">
	<title>Using Distributed Cache</title>
	<p>Use getCacheFiles or getShipFiles to return a list of HDFS files or local files that need to be shipped to distributed cache. Inside exec method, you can assume that these files already exist in distributed cache. For example:</p>
<source>
public class Udfcachetest extends EvalFunc&lt;String&gt; { 

    public String exec(Tuple input) throws IOException { 
        String concatResult = "";
        FileReader fr = new FileReader("./smallfile1"); 
        BufferedReader d = new BufferedReader(fr);
        concatResult +=d.readLine();
        fr = new FileReader("./smallfile2");
        d = new BufferedReader(fr);
        concatResult +=d.readLine();
        return concatResult;
    } 

    public List&lt;String&gt; getCacheFiles() { 
        List&lt;String&gt; list = new ArrayList&lt;String&gt;(1); 
        list.add("/user/pig/tests/data/small#smallfile1");  // This is hdfs file
        return list; 
    } 

    public List&lt;String&gt; getShipFiles() {
        List&lt;String&gt; list = new ArrayList&lt;String&gt;(1);
        list.add("/home/hadoop/pig/smallfile2");  // This local file
        return list;
    }
} 

a = load '1.txt'; 
b = foreach a generate Udfcachetest(*); 
dump b;
</source>
</section>
<section id="compile-time-eval">
        <title>Compile time evaluation</title>
        <p>If the parameters of the EvalFunc are all constants, Pig could evaluate the result at compile time. The benefit of evaluating at compile time is performance optimization, and enable certain other optimizations at front end (such as partition pruning, which only allow constant not UDF in filter condition). By default, compile time evaluation is disabled in EvalFunc to prevent potential side effect. To enable it, override allowCompileTimeCalculation. For example:</p>
<source>
public class CurrentTime extends EvalFunc&lt;DateTime&gt; {
    public String exec(Tuple input) throws IOException {
        return new DateTime();
    }
    @Override
    public boolean allowCompileTimeCalculation() {
        return true;
    }
}
</source>
</section>
<section id="udf-loadcaster">
<title>Typecasting from bytearrays</title>
<p>Just like <a href="#load-functions">Load Function</a> and <a href="basic.html#pig-streaming-input-output">Streaming</a>,
Java UDF has a getLoadCaster() method that returns
<a href="http://svn.apache.org/viewvc/pig/trunk/src/org/apache/pig/LoadCaster.java?view=markup">LoadCaster</a>
to convert byte arrays to specific types. A UDf implementation should implement this if casts (implicit or explicit) from DataByteArray fields to other types need to be supported. Default implementation returns null and Pig will determine if all parameters passed to the UDF have identical loadcaster and use it when true. </p>
</section>

<section id="tez-jvm-reuse">
        <title>Clean up static variable in Tez</title>
        <p>In Tez, jvm could reuse for other tasks. It is important to cleanup static variable to make sure there is no side effect. Here is one example:</p>
<source>
public class UPPER extends EvalFunc&lt;String&gt;
{
        static boolean initialized = false;
        static {
            JVMReuseManager.getInstance().registerForStaticDataCleanup(UPPER.class);
        }
        public String exec(Tuple input) throws IOException {
            if (!initialized) {
                init();
                initialized = true;
            }
            ......
        }
        @StaticDataCleanup
        public static void staticDataCleanup() {
            initialized = false;
        }
}
</source>
</section>
</section>

<!-- =============================================================== -->
<!-- BEGIN LOAD/STORE FUNCTIONS -->
<section id="load-store-functions">
<title> Load/Store Functions</title>

<p>The load/store UDFs control how data goes into Pig and comes out of Pig. Often, the same function handles both input and output but that does not have to be the case. </p>
<p>
The Pig load/store API is aligned with Hadoop's InputFormat and OutputFormat classes.
This enables you to create new LoadFunc and StoreFunc implementations based on existing Hadoop InputFormat and OutputFormat classes with minimal code. The complexity of reading the data and creating a record lies in the InputFormat while the complexity of writing the data lies in the OutputFormat. This enables Pig to easily read/write data in new storage formats as and when an Hadoop InputFormat and OutputFormat is available for them. </p>
<p>
<strong>Note:</strong> Both the LoadFunc and StoreFunc implementations should use the Hadoop 20 API based classes (InputFormat/OutputFormat and related classes) under the <strong>new</strong> org.apache.hadoop.mapreduce package instead of the old org.apache.hadoop.mapred package. 
</p>

<!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="load-functions">
<title> Load Functions</title>
<p id="loadfunc"><a href="http://svn.apache.org/viewvc/pig/trunk/src/org/apache/pig/LoadFunc.java?view=markup">LoadFunc</a> 
abstract class has three main methods for loading data and for most use cases it would suffice to extend it. There are three other optional interfaces which can be implemented to achieve extended functionality: </p>

<ul>
<li id="LoadMetadata"><a href="http://svn.apache.org/viewvc/pig/trunk/src/org/apache/pig/LoadMetadata.java?view=markup">LoadMetadata</a> 
has methods to deal with metadata - most implementation of loaders don't need to implement this unless they interact with some metadata system. The getSchema() method in this interface provides a way for loader implementations to communicate the schema of the data back to pig. If a loader implementation returns data comprised of fields of real types (rather than DataByteArray fields), it should provide the schema describing the data returned through the getSchema() method. The other methods are concerned with other types of metadata like partition keys and statistics. Implementations can return null return values for these methods if they are not applicable for that implementation.</li>

<li id="LoadPushDown"><a href="http://svn.apache.org/viewvc/pig/trunk/src/org/apache/pig/LoadPushDown.java?view=markup">LoadPushDown</a> 
has methods to push operations from Pig runtime into loader implementations. Currently only the pushProjection() method is called by Pig to communicate to the loader the exact fields that are required in the Pig script. The loader implementation can choose to honor the request (return only those fields required by Pig script) or not honor the request (return all fields in the data). If the loader implementation can efficiently honor the request, it should implement LoadPushDown to improve query performance. (Irrespective of whether the implementation can or cannot honor the request, if the implementation also implements getSchema(), the schema returned in getSchema() should describe the entire tuple of data.)
<ul>
	<li id="pushprojection">pushProjection(): This method tells LoadFunc which fields are required in the Pig script, thus enabling LoadFunc to optimize performance by loading only those fields that are needed. pushProjection() takes a requiredFieldList. requiredFieldList is read only and cannot be changed by LoadFunc. requiredFieldList includes a list of requiredField: each requiredField indicates a field required by the Pig script; each requiredField includes index, alias, type (which is reserved for future use), and subFields. Pig will use the column index requiredField.index to communicate with the LoadFunc about the fields required by the Pig script. If the required field is a map, Pig will optionally pass requiredField.subFields which contains a list of keys that the Pig script needs for the map. For example, if the Pig script needs two keys for the map, "key1" and "key2", the subFields for that map will contain two requiredField; the alias field for the first RequiredField will be "key1" and the alias for the second requiredField will be "key2". LoadFunc will use requiredFieldResponse.requiredFieldRequestHonored to indicate whether the pushProjection() request is honored.
</li>
</ul>
</li>

<li id="loadcaster"><a href="http://svn.apache.org/viewvc/pig/trunk/src/org/apache/pig/LoadCaster.java?view=markup">LoadCaster</a> 
has methods to convert byte arrays to specific types. A loader implementation should implement this if casts (implicit or explicit) from DataByteArray fields to other types need to be supported. </li>

<li id="loadpredicatepushdown"><a href="http://svn.apache.org/viewvc/pig/trunk/src/org/apache/pig/LoadPredicatePushdown.java?view=markup">LoadPredicatePushdown</a> 
 has the methods to push predicates to the loader. It is different than LoadMetadata.setPartitionFilter in that loader may load records which does not satisfy the predicates. In other words, predicates is only a hint. Note this interface is still in development and might change in next version. Currently only OrcStorage implements this interface.</li>

<li id="nonfsloadfunc"><a href="http://svn.apache.org/viewvc/pig/trunk/src/org/apache/pig/NonFSLoadFunc.java?view=markup">NonFSLoadFunc</a> 
 is a marker interface to indicate that a LoadFunc implementation is not a filesystem loader. This is useful for LoadFunc classes that for example supply queries instead of filesystem pathes to the LOAD operator.</li>
</ul>

 <p>The LoadFunc abstract class is the main class to extend for implementing a loader. The methods which need to be overridden are explained below:</p>
 <ul>
 <li id="getInputFormat">getInputFormat(): This method is called by Pig to get the InputFormat used by the loader. The methods in the InputFormat (and underlying RecordReader) are called by Pig in the same manner (and in the same context) as by Hadoop in a MapReduce java program. If the InputFormat is a Hadoop packaged one, the implementation should use the new API based one under org.apache.hadoop.mapreduce. If it is a custom InputFormat, it should be implemented using the new API in org.apache.hadoop.mapreduce.<br></br> <br></br> 
 
 If a custom loader using a text-based InputFormat or a file-based InputFormat would like to read files in all subdirectories under a given input directory recursively, then it should use the PigTextInputFormat and PigFileInputFormat classes provided in org.apache.pig.backend.hadoop.executionengine.mapReduceLayer. The Pig InputFormat classes work around a current limitation in the Hadoop TextInputFormat and FileInputFormat classes which only read one level down from the provided input directory. For example, if the input in the load statement is 'dir1' and there are subdirs 'dir2' and 'dir2/dir3' beneath dir1, the Hadoop TextInputFormat and FileInputFormat classes read the files under 'dir1' only. Using PigTextInputFormat or PigFileInputFormat (or by extending them), the files in all the directories can be read. </li>
 
 <li id="setLocation">setLocation(): This method is called by Pig to communicate the load location to the loader. The loader should use this method to communicate the same information to the underlying InputFormat. This method is called multiple times by pig - implementations should bear this in mind and should ensure there are no inconsistent side effects due to the multiple calls. </li>
 
 <li id="prepareToRead">prepareToRead(): Through this method the RecordReader associated with the InputFormat provided by the LoadFunc is passed to the LoadFunc. The RecordReader can then be used by the implementation in getNext() to return a tuple representing a record of data back to pig. </li>
 
 <li id="getnext">getNext(): The meaning of getNext() has not changed and is called by Pig runtime to get the next tuple in the data - in this method the implementation should use the underlying RecordReader and construct the tuple to return. </li>
 </ul>

 <p id="loadfunc-default">The following methods have default implementations in LoadFunc and should be overridden only if needed: </p>
 <ul>
 <li id="setUdfContextSignature">setUdfContextSignature(): This method will be called by Pig both in the front end and back end to pass a unique signature to the Loader. The signature can be used to store into the UDFContext any information which the Loader needs to store between various method invocations in the front end and back end. A use case is to store RequiredFieldList passed to it in LoadPushDown.pushProjection(RequiredFieldList) for use in the back end before returning tuples in getNext(). The default implementation in LoadFunc has an empty body. This method will be called before other methods. </li>
 
 <li id="relativeToAbsolutePath">relativeToAbsolutePath(): Pig runtime will call this method to allow the Loader to convert a relative load location to an absolute location. The default implementation provided in LoadFunc handles this for FileSystem locations. If the load source is something else, loader implementation may choose to override this.</li>

 <li id="getCacheFiles">getCacheFiles(): Return a list of hdfs files to ship to distributed cache.</li>

 <li id="getShipFiles">getShipFiles(): Return a list of local files to ship to distributed cache.</li>
 </ul>

<p><strong>Example Implementation</strong></p>
<p>
The loader implementation in the example is a loader for text data with line delimiter as '\n' and '\t' as default field delimiter (which can be overridden by passing a different field delimiter in the constructor) - this is similar to current PigStorage loader in Pig. The implementation uses an existing Hadoop supported Inputformat - TextInputFormat - as the underlying InputFormat.
</p>
<source>
public class SimpleTextLoader extends LoadFunc {
    protected RecordReader in = null;
    private byte fieldDel = '\t';
    private ArrayList&lt;Object&gt; mProtoTuple = null;
    private TupleFactory mTupleFactory = TupleFactory.getInstance();
    private static final int BUFFER_SIZE = 1024;

    public SimpleTextLoader() {
    }

    /**
     * Constructs a Pig loader that uses specified character as a field delimiter.
     *
     * @param delimiter
     *            the single byte character that is used to separate fields.
     *            ("\t" is the default.)
     */
    public SimpleTextLoader(String delimiter) {
        this();
        if (delimiter.length() == 1) {
            this.fieldDel = (byte)delimiter.charAt(0);
        } else if (delimiter.length() &gt;  1 &amp; &amp; delimiter.charAt(0) == '\\') {
            switch (delimiter.charAt(1)) {
            case 't':
                this.fieldDel = (byte)'\t';
                break;

            case 'x':
               fieldDel =
                    Integer.valueOf(delimiter.substring(2), 16).byteValue();
               break;

            case 'u':
                this.fieldDel =
                    Integer.valueOf(delimiter.substring(2)).byteValue();
                break;

            default:
                throw new RuntimeException("Unknown delimiter " + delimiter);
            }
        } else {
            throw new RuntimeException("PigStorage delimeter must be a single character");
        }
    }

    @Override
    public Tuple getNext() throws IOException {
        try {
            boolean notDone = in.nextKeyValue();
            if (notDone) {
                return null;
            }
            Text value = (Text) in.getCurrentValue();
            byte[] buf = value.getBytes();
            int len = value.getLength();
            int start = 0;

            for (int i = 0; i &lt; len; i++) {
                if (buf[i] == fieldDel) {
                    readField(buf, start, i);
                    start = i + 1;
                }
            }
            // pick up the last field
            readField(buf, start, len);

            Tuple t =  mTupleFactory.newTupleNoCopy(mProtoTuple);
            mProtoTuple = null;
            return t;
        } catch (InterruptedException e) {
            int errCode = 6018;
            String errMsg = "Error while reading input";
            throw new ExecException(errMsg, errCode,
                    PigException.REMOTE_ENVIRONMENT, e);
        }

    }

    private void readField(byte[] buf, int start, int end) {
        if (mProtoTuple == null) {
            mProtoTuple = new ArrayList&lt;Object&gt;();
        }

        if (start == end) {
            // NULL value
            mProtoTuple.add(null);
        } else {
            mProtoTuple.add(new DataByteArray(buf, start, end));
        }
    }

    @Override
    public InputFormat getInputFormat() {
        return new TextInputFormat();
    }

    @Override
    public void prepareToRead(RecordReader reader, PigSplit split) {
        in = reader;
    }

    @Override
    public void setLocation(String location, Job job)
            throws IOException {
        FileInputFormat.setInputPaths(job, location);
    }
}
</source>

</section>
<!-- END LOAD FUNCTION -->

<!-- =============================================================== -->
<section id="store-functions">
<title> Store Functions</title>

<p id="storefunc"><a href="http://svn.apache.org/viewvc/pig/trunk/src/org/apache/pig/StoreFunc.java?view=markup">StoreFunc</a> 
abstract class has the main methods for storing data and for most use cases it should suffice to extend it. There is an optional interface which can be implemented to achieve extended functionality: </p>
<ul>
<li id="storemetadata"><a href="http://svn.apache.org/viewvc/pig/trunk/src/org/apache/pig/StoreMetadata.java?view=markup">StoreMetadata:</a> 
This interface has methods to interact with metadata systems to store schema and store statistics. This interface is optional and should only be implemented if metadata needs to stored. </li>
<li id="storeresources"><a href="http://svn.apache.org/viewvc/pig/trunk/src/org/apache/pig/StoreResources.java?view=markup">StoreResources:</a> 
This interface has methods to put hdfs files or local files to distributed cache. </li>
<li id="errorhandling"><a href="http://svn.apache.org/viewvc/pig/trunk/src/org/apache/pig/ErrorHandling.java?view=markup">ErrorHandling:</a> 
This interface allow you to skip bad records in both loader and storer so they will not throw exception and terminate the job. You can implement your own error handler by overriding <a href="http://svn.apache.org/viewvc/pig/trunk/src/org/apache/pig/ErrorHandler.java?view=markup">ErrorHandler</a> interface, or use predefined error handler: <a href="http://svn.apache.org/viewvc/pig/trunk/src/org/apache/pig/CounterBasedErrorHandler.java?view=markup">CounterBasedErrorHandler</a>. ErrorHandling can be turned on by setting the property pig.error-handling.enabled to true in pig.properties. Default is false.  CounterBasedErrorHandler uses two settings - pig.error-handling.min.error.records (the minimum number of errors to trigger error handling) and pig.error-handling.error.threshold (percentage of the number of records as a fraction exceeding which error is thrown).</li>
</ul>

<p id="storefunc-override">The methods which need to be overridden in StoreFunc are explained below: </p>
<ul>
<li id="getOutputFormat">getOutputFormat(): This method will be called by Pig to get the OutputFormat used by the storer. The methods in the OutputFormat (and underlying RecordWriter and OutputCommitter) will be called by pig in the same manner (and in the same context) as by Hadoop in a map-reduce java program. If the OutputFormat is a hadoop packaged one, the implementation should use the new API based one under org.apache.hadoop.mapreduce. If it is a custom OutputFormat, it should be implemented using the new API under org.apache.hadoop.mapreduce. The checkOutputSpecs() method of the OutputFormat will be called by pig to check the output location up-front. This method will also be called as part of the Hadoop call sequence when the job is launched. So implementations should ensure that this method can be called multiple times without inconsistent side effects. </li>
<li id="setStoreLocation">setStoreLocation(): This method is called by Pig to communicate the store location to the storer. The storer should use this method to communicate the same information to the underlying OutputFormat. This method is called multiple times by pig - implementations should bear in mind that this method is called multiple times and should ensure there are no inconsistent side effects due to the multiple calls. </li>
<li id="prepareToWrite">prepareToWrite(): Writing of the data is through the OutputFormat provided by the StoreFunc. In prepareToWrite() the RecordWriter associated with the OutputFormat provided by the StoreFunc is passed to the StoreFunc. The RecordWriter can then be used by the implementation in putNext() to write a tuple representing a record of data in a manner expected by the RecordWriter. </li>
<li id="putNext">putNext(): This method is called by Pig runtime to write the next tuple of data - this is the method wherein the implementation will use the underlying RecordWriter to write the Tuple out.</li>
</ul>

<p id="storefunc-default">The following methods have default implementations in StoreFunc and should be overridden only if necessary: </p>
<ul>
<li id="setStoreFuncUDFContextSignature">setStoreFuncUDFContextSignature(): This method will be called by Pig both in the front end and back end to pass a unique signature to the Storer. The signature can be used to store into the UDFContext any information which the Storer needs to store between various method invocations in the front end and back end. The default implementation in StoreFunc has an empty body. This method will be called before other methods. 
</li>
<li id="relToAbsPathForStoreLocation">relToAbsPathForStoreLocation(): Pig runtime will call this method to allow the Storer to convert a relative store location to an absolute location. An implementation is provided in StoreFunc which handles this for FileSystem based locations. </li>
<li id="checkschema">checkSchema(): A Store function should implement this function to check that a given schema describing the data to be written is acceptable to it. The default implementation in StoreFunc has an empty body. This method will be called before any calls to setStoreLocation(). </li>
</ul>

<p><strong>Example Implementation</strong></p>
<p>
The storer implementation in the example is a storer for text data with line delimiter as '\n' and '\t' as default field delimiter (which can be overridden by passing a different field delimiter in the constructor) - this is similar to current PigStorage storer in Pig. The implementation uses an existing Hadoop supported OutputFormat - TextOutputFormat as the underlying OutputFormat. 
</p>

<source>
public class SimpleTextStorer extends StoreFunc {
    protected RecordWriter writer = null;

    private byte fieldDel = '\t';
    private static final int BUFFER_SIZE = 1024;
    private static final String UTF8 = "UTF-8";
    public PigStorage() {
    }

    public PigStorage(String delimiter) {
        this();
        if (delimiter.length() == 1) {
            this.fieldDel = (byte)delimiter.charAt(0);
        } else if (delimiter.length() > 1delimiter.charAt(0) == '\\') {
            switch (delimiter.charAt(1)) {
            case 't':
                this.fieldDel = (byte)'\t';
                break;

            case 'x':
               fieldDel =
                    Integer.valueOf(delimiter.substring(2), 16).byteValue();
               break;
            case 'u':
                this.fieldDel =
                    Integer.valueOf(delimiter.substring(2)).byteValue();
                break;

            default:
                throw new RuntimeException("Unknown delimiter " + delimiter);
            }
        } else {
            throw new RuntimeException("PigStorage delimeter must be a single character");
        }
    }

    ByteArrayOutputStream mOut = new ByteArrayOutputStream(BUFFER_SIZE);

    @Override
    public void putNext(Tuple f) throws IOException {
        int sz = f.size();
        for (int i = 0; i &lt; sz; i++) {
            Object field;
            try {
                field = f.get(i);
            } catch (ExecException ee) {
                throw ee;
            }

            putField(field);

            if (i != sz - 1) {
                mOut.write(fieldDel);
            }
        }
        Text text = new Text(mOut.toByteArray());
        try {
            writer.write(null, text);
            mOut.reset();
        } catch (InterruptedException e) {
            throw new IOException(e);
        }
    }

    @SuppressWarnings("unchecked")
    private void putField(Object field) throws IOException {
        //string constants for each delimiter
        String tupleBeginDelim = "(";
        String tupleEndDelim = ")";
        String bagBeginDelim = "{";
        String bagEndDelim = "}";
        String mapBeginDelim = "[";
        String mapEndDelim = "]";
        String fieldDelim = ",";
        String mapKeyValueDelim = "#";

        switch (DataType.findType(field)) {
        case DataType.NULL:
            break; // just leave it empty

        case DataType.BOOLEAN:
            mOut.write(((Boolean)field).toString().getBytes());
            break;

        case DataType.INTEGER:
            mOut.write(((Integer)field).toString().getBytes());
            break;

        case DataType.LONG:
            mOut.write(((Long)field).toString().getBytes());
            break;

        case DataType.FLOAT:
            mOut.write(((Float)field).toString().getBytes());
            break;

        case DataType.DOUBLE:
            mOut.write(((Double)field).toString().getBytes());
            break;

        case DataType.BYTEARRAY: {
            byte[] b = ((DataByteArray)field).get();
            mOut.write(b, 0, b.length);
            break;
                                 }

        case DataType.CHARARRAY:
            // oddly enough, writeBytes writes a string
            mOut.write(((String)field).getBytes(UTF8));
            break;

        case DataType.MAP:
            boolean mapHasNext = false;
            Map&lt;String, Object&gt; m = (Map&lt;String, Object&gt;)field;
            mOut.write(mapBeginDelim.getBytes(UTF8));
            for(Map.Entry&lt;String, Object&gt; e: m.entrySet()) {
                if(mapHasNext) {
                    mOut.write(fieldDelim.getBytes(UTF8));
                } else {
                    mapHasNext = true;
                }
                putField(e.getKey());
                mOut.write(mapKeyValueDelim.getBytes(UTF8));
                putField(e.getValue());
            }
            mOut.write(mapEndDelim.getBytes(UTF8));
            break;

        case DataType.TUPLE:
            boolean tupleHasNext = false;
            Tuple t = (Tuple)field;
            mOut.write(tupleBeginDelim.getBytes(UTF8));
            for(int i = 0; i &lt; t.size(); ++i) {
                if(tupleHasNext) {
                    mOut.write(fieldDelim.getBytes(UTF8));
                } else {
                    tupleHasNext = true;
                }
                try {
                    putField(t.get(i));
                } catch (ExecException ee) {
                    throw ee;
                }
            }
            mOut.write(tupleEndDelim.getBytes(UTF8));
            break;

        case DataType.BAG:
            boolean bagHasNext = false;
            mOut.write(bagBeginDelim.getBytes(UTF8));
            Iterator&lt;Tuple&gt; tupleIter = ((DataBag)field).iterator();
            while(tupleIter.hasNext()) {
                if(bagHasNext) {
                    mOut.write(fieldDelim.getBytes(UTF8));
                } else {
                    bagHasNext = true;
                }
                putField((Object)tupleIter.next());
            }
            mOut.write(bagEndDelim.getBytes(UTF8));
            break;

        default: {
            int errCode = 2108;
            String msg = "Could not determine data type of field: " + field;
            throw new ExecException(msg, errCode, PigException.BUG);
        }

        }
    }

    @Override
    public OutputFormat getOutputFormat() {
        return new TextOutputFormat&lt;WritableComparable, Text&gt;();
    }

    @Override
    public void prepareToWrite(RecordWriter writer) {
        this.writer = writer;
    }

    @Override
    public void setStoreLocation(String location, Job job) throws IOException {
        job.getConfiguration().set("mapred.textoutputformat.separator", "");
        FileOutputFormat.setOutputPath(job, new Path(location));
        if (location.endsWith(".bz2")) {
            FileOutputFormat.setCompressOutput(job, true);
            FileOutputFormat.setOutputCompressorClass(job,  BZip2Codec.class);
        }  else if (location.endsWith(".gz")) {
            FileOutputFormat.setCompressOutput(job, true);
            FileOutputFormat.setOutputCompressorClass(job, GzipCodec.class);
        }
    }
}
</source>

</section>
<!-- END STORE FUNCTION -->
</section>
<!-- END LOAD/STORE FUNCTIONS -->


<!-- =============================================================== -->
<section id="use-short-names">
<title>Using Short Names</title>

<p>There are two ways to call a Java UDF using a short name. One way is specifying the package to an import list via Java property, and the other is defining an alias of the UDF by DEFINE statement.</p>

<!-- +++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="import-lists">
<title>Import Lists</title>
<p>An import list allows you to specify the package to which a UDF or a group of UDFs belong,
 eliminating the need to qualify the UDF on every call. An import list can be specified via the udf.import.list Java 
 property on the Pig command line: </p>
<source>
pig -Dudf.import.list=com.yahoo.yst.sds.ULT
</source>
<p>You can supply multiple locations as well: </p>
<source>
pig -Dudf.import.list=com.yahoo.yst.sds.ULT:org.apache.pig.piggybank.evaluation
</source>
<p>To make use of import scripts, do the following:</p>
<source>
myscript.pig:
A = load '/data/SDS/data/searcg_US/20090820' using ULTLoader as (s, m, l);
....

command:
pig -cp sds.jar -Dudf.import.list=com.yahoo.yst.sds.ULT myscript.pig 
</source>
</section>

<!-- +++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="define-alias">
<title>Defining Aliases</title>
<p>You can define an alias for a function using <a href="basic.html#define-udfs">DEFINE statement</a>:</p>

<source>
REGISTER piggybank.jar
DEFINE MAXNUM org.apache.pig.piggybank.evaluation.math.MAX;
A = LOAD 'student_data' AS (name: chararray, gpa1: float, gpa2: double);
B = FOREACH A GENERATE name, MAXNUM(gpa1, gpa2);
DUMP B;
</source>

<p>The first parameter of DEFINE statement is an alias of the function. The second parameter is the fully-qualified name of the function. After the statement, you can call the function using the alias instead of the fually-qualified name.</p>

</section>

</section>



<!-- =============================================================== -->
<section>
<title>Advanced Topics</title>

<section id="udf-interfaces">
<title>UDF Interfaces</title>
<p>Java UDFs can be invoked multiple ways. The simplest UDF can just extend EvalFunc, which requires only the exec function to be implemented (see <a href="#eval-functions-write"> How to Write a Simple Eval Function</a>). Every eval UDF must implement this. Additionally, if a function is algebraic, it can implement <code>Algebraic</code> interface to significantly improve query performance in the cases when combiner can be used (see <a href="#algebraic-interface">Algebraic Interface</a>). Finally, a function that can process tuples in an incremental fashion can also implement the Accumulator interface to improve query memory consumption (see <a href="#accumulator-interface">Accumulator Interface</a>).
</p>

<p>The optimizer selects the exact method by which a UDF is invoked based on the UDF type and the query. Note that only a single interface is used at any given time. The optimizer tries to find the most efficient way to execute the function. If a combiner is used and the function implements the Algebraic interface then this interface will be used to invoke the function. If the combiner is not invoked but the accumulator can be used and the function implements Accumulator interface then that interface is used. If neither of the conditions is satisfied then the exec function is used to invoke the UDF. 
</p>
 </section>
 
 <!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="function-instantiation">
<title>Function Instantiation</title>
<p>One problem that users run into is when they make assumption about how many times a constructor for their UDF is called. For instance, they might be creating side files in the store function and doing it in the constructor seems like a good idea. The problem with this approach is that in most cases Pig instantiates functions on the client side to, for instance, examine the schema of the data.  </p>
<p>Users should not make assumptions about how many times a function is instantiated; instead, they should make their code resilient to multiple instantiations. For instance, they could check if the files exist before creating them. </p>
</section>

 
  <!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="udf-configurations">
<title>Passing Configurations to UDFs</title>
<p>The singleton UDFContext class provides two features to UDF writers. First, on the backend, it allows UDFs to get access to the JobConf object, by calling getJobConf. This is only available on the backend (at run time) as the JobConf has not yet been constructed on the front end (during planning time).</p>

<p>Second, it allows UDFs to pass configuration information between instantiations of the UDF on the front and backends. UDFs can store information in a configuration object when they are constructed on the front end, or during other front end calls such as checkSchema. They can then read that information on the backend when exec (for EvalFunc) or getNext (for LoadFunc) is called. Note that information will not be passed between instantiations of the function on the backend. The communication channel only works from front end to back end.</p>

<p>To store information, the UDF calls getUDFProperties. This returns a Properties object which the UDF can record the information in or read the information from. To avoid name space conflicts UDFs are required to provide a signature when obtaining a Properties object. This can be done in two ways. The UDF can provide its Class object (via this.getClass()). In this case, every instantiation of the UDF will be given the same Properties object. The UDF can also provide its Class plus an array of Strings. The UDF can pass its constructor arguments, or some other identifying strings. This allows each instantiation of the UDF to have a different properties object thus avoiding name space collisions between instantiations of the UDF.</p>
</section>

 <!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="udf-monitoring">
<title>Monitoring Long-Running UDFs</title>
<p>Sometimes one may discover that a UDF that executes very quickly in the vast majority of cases turns out to run exceedingly slowly on occasion. This can happen, for example, if a UDF uses complex regular expressions to parse free-form strings, or if a UDF uses some external service to communicate with. As of version 0.8, Pig provides a facility for monitoring the length of time a UDF is executing for every invocation, and terminating its execution if it runs too long. This facility can be turned on using a simple Java annotation:</p>
	
<source>
	import org.apache.pig.builtin.MonitoredUDF;
	
	@MonitoredUDF
	public class MyUDF extends EvalFunc&lt;Integer&gt; {
	  /* implementation goes here */
	}
</source>

<p>Simply annotating your UDF in this way will cause Pig to terminate the UDF's exec() method if it runs for more than 10 seconds, and return the default value of null. The duration of the timeout and the default value can be specified in the annotation, if desired:</p>

<source>
	import org.apache.pig.builtin.MonitoredUDF;
	
	@MonitoredUDF(timeUnit = TimeUnit.MILLISECONDS, duration = 100, intDefault = 10)
	public class MyUDF extends EvalFunc&lt;Integer&gt; {
	  /* implementation goes here */
	}
</source>

<p>intDefault, longDefault, doubleDefault, floatDefault, and stringDefault can be specified in the annotation; the correct default will be chosen based on the return type of the UDF. Custom defaults for tuples and bags are not supported at this time.</p>

<p>If desired, custom logic can also be implemented for error handling by creating a subclass of MonitoredUDFExecutor.ErrorCallback, and overriding its handleError and/or handleTimeout methods. Both of those methods are static, and are passed in the instance of the EvalFunc that produced an exception, as well as an exception, so you may use any state you have in the UDF to process the errors as desired. The default behavior is to increment Hadoop counters every time an error is encountered. Once you have an implementation of the ErrorCallback that performs your custom logic, you can provide it in the annotation:</p>

<source>
	import org.apache.pig.builtin.MonitoredUDF;

	@MonitoredUDF(errorCallback=MySpecialErrorCallback.class)
	public class MyUDF extends EvalFunc&lt;Integer&gt; {
	  /* implementation goes here */
	}
</source>

<p>Currently the MonitoredUDF annotation works with regular and Algebraic UDFs, but has no effect on UDFs that run in the Accumulator mode.</p>

</section>
</section>
</section>


<!-- =============================================================== -->
<section id="jython-udfs">
<title>Writing Jython UDFs</title>

<!-- ++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="register-jython">
<title>Registering the UDF</title>
<p>You can register a Jython script as shown here. This example uses org.apache.pig.scripting.jython.JythonScriptEngine to interpret the Jython script. You can develop and use custom script engines to support multiple programming languages and ways to interpret them. Currently, Pig identifies jython as a keyword and ships the required scriptengine (jython) to interpret it. </p>
<source>
Register 'test.py' using jython as myfuncs;
</source>

<p>The following syntax is also supported, where myfuncs is the namespace created for all the functions inside test.py.</p>
<source>
register 'test.py' using org.apache.pig.scripting.jython.JythonScriptEngine as myfuncs;
</source>


<p>A typical test.py looks like this:</p>
<source>
@outputSchema("word:chararray")
def helloworld():  
  return 'Hello, World'

@outputSchema("word:chararray,num:long")
def complex(word):
  return str(word),len(word)

@outputSchemaFunction("squareSchema")
def square(num):
  return ((num)*(num))

@schemaFunction("squareSchema")
def squareSchema(input):
  return input

# No decorator - bytearray
def concat(str):
  return str+str
</source>

<p>The register statement above registers the Jython functions defined in test.py in Pig’s runtime within the defined namespace (myfuncs here). They can then be referred later on in the pig script as myfuncs.helloworld(), myfuncs.complex(), and myfuncs.square(). An example usage is:</p>

<source>
b = foreach a generate myfuncs.helloworld(), myfuncs.square(3);
</source>


<!-- ++++++++++++++++++++++++++++++++++++++++++++++++ -->
</section>
<section id="python_decorators">
<title>Decorators and Schemas</title>
<p>To annotate a Jython script so that Pig can identify return types, use Jython decorators to define output schema for the script UDF. </p>
<ul>
<li id="outputschema">outputSchema - Defines schema for a script UDF in a format that Pig understands and is able to parse. </li>
<li id="outputfunctionschema">outputFunctionSchema - Defines a script delegate function that defines schema for this function depending upon the input type. This is needed for functions that can accept generic types and perform generic operations on these types. A simple example is square which can accept multiple types. SchemaFunction for this type is a simple identity function (same schema as input). </li>
<li id="schemafunction">schemaFunction - Defines delegate function and is not registered to Pig. </li>
</ul>

<p>When no decorator is specified, Pig assumes the output datatype as bytearray and converts the output generated by script function to bytearray. This is consistent with Pig's behavior in case of Java UDFs. </p>

<p>Sample Schema String - y:{t:(word:chararray,num:long)}, variable names inside a schema string are not used anywhere, they just make the syntax identifiable to the parser. </p>
</section>


<!-- ++++++++++++++++++++++++++++++++++++++++++++++++ -->
 <section>
 <title>Example Scripts</title>
 <p>Simple tasks like string manipulation, mathematical computations, and reorganizing data types can be easily done using Jython scripts without having to develop long and complex UDFs in Java. The overall overhead of using scripting language is much less and development cost is almost negligible. The following UDFs, developed in Jython, can be used with Pig. </p>
 
 <source>
 mySampleLib.py
 ---------------------
 #/usr/bin/python
 
 ##################
 # Math functions #
 ##################
 #square - Square of a number of any data type
 @outputSchemaFunction("squareSchema")
 def square(num):
   return ((num)*(num))
 @schemaFunction("squareSchema")
 def squareSchema(input):
   return input
 
 #Percent- Percentage
 @outputSchema("percent:double")
 def percent(num, total):
   return num * 100 / total
 
 ####################
 # String Functions #
 ####################
 #commaFormat- format a number with commas, 12345-> 12,345
 @outputSchema("numformat:chararray")
 def commaFormat(num):
   return '{:,}'.format(num)
 
 #concatMultiple- concat multiple words
 @outputSchema("onestring:chararray")
 def concatMult4(word1, word2, word3, word4):
   return word1 word2 word3 word4
 
 #######################
 # Data Type Functions #
 #######################
 #collectBag- collect elements of a bag into other bag
 #This is useful UDF after group operation
 @outputSchema("y:bag{t:tuple(len:int,word:chararray)}") 
 def collectBag(bag):
   outBag = []
   for word in bag:
     tup=(len(bag), word[1])
     outBag.append(tup)
   return outBag
 
 # Few comments- 
 # Pig mandates that a bag should be a bag of tuples, Jython UDFs should follow this pattern.
 # Tuples in Jython are immutable, appending to a tuple is not possible.
 </source>
 </section>
 
 <!-- ++++++++++++++++++++++++++++++++++++++++++++++++ -->
 <section id="jython-advanced">
 <title>Advanced Topics</title> 
  <section id="import-modules">
  
<!-- ++++++++++++++++++++ -->
<title>Importing Modules</title>
<p>You can import Jython modules in your Jython script. Pig resolves Jython dependencies recursively, which means Pig will automatically ship all dependent Jython modules to the backend. Jython modules should be found in the jython search path: JYTHON_HOME, JYTHONPATH, or current directory.</p>
</section>

<!-- ++++++++++++++++++++ -->
<section id="combined-scripts">
<title>Combined Scripts</title>
  <p>UDFs and Pig scripts are generally stored in separate files. For testing purposes you can combine the code in a single file - a "combined" script. Note, however, if you then decide to embed this "combined" script in a host language, the language of the UDF must match the host language.</p>
 
 <p>This example combines Jython and Pig. This "combined" script can only be embedded in Jython.</p>
 <p>With Jython you MUST use the <code>if __name__ == '__main__': </code> construct to separate UDFs and control flow. Otherwise the script will result in an error.</p>
 <source>
 #!/usr/bin/jython
from org.apache.pig.scripting import *

@outputSchema("word:chararray")
def helloworld():  
   return 'Hello, World'
  
if __name__ == '__main__':
       P = Pig.compile("""a = load '1.txt' as (a0, a1);
                          b = foreach a generate helloworld();
                          store b into 'myoutput'; """)

result = P.bind().runSingle();
 </source>
   </section>

  </section>
</section>


 <!-- =============================================================== -->
 <section id="js-udfs">
 <title>Writing JavaScript UDFs</title>
 
 <p><strong>Note:</strong> <em>JavaScript UDFs are an experimental feature.</em></p>

<!-- ++++++++++++++++++++++++++++++++++++++++++++++++ -->
 <section id="register-js">
 <title>Registering the UDF</title>
 <p>You can register JavaScript as shown here. This example uses org.apache.pig.scripting.js.JsScriptEngine to interpret JavaScript. You can develop and use custom script engines to support multiple programming languages and ways to interpret them. Currently, Pig identifies js as a keyword and ships the required scriptengine (Rhino) to interpret it. </p>
 <source>
 register 'test.js' using javascript as myfuncs;
 </source>
 
 <p>The following syntax is also supported, where myfuncs is the namespace created for all the functions inside test.js.</p>
 <source>
 register 'test.js' using org.apache.pig.scripting.js.JsScriptEngine as myfuncs;
 </source>

 <p>The register statement above registers the js functions defined in test.js in Pig’s runtime within the defined namespace (myfuncs here). They can then be referred later on in the pig script as myfuncs.helloworld(), myfuncs.complex(), and myfuncs.square(). An example usage is:</p>
 
 <source>
 b = foreach a generate myfuncs.helloworld(), myfuncs.complex($0);
 </source>
 </section>
 
 <!-- ++++++++++++++++++++++++++++++++++++++++++++++++ -->
 <section id="schema-return-types">
 <title>Return Types and Schemas</title>
 <p>Since JavaScript functions are first class objects, you can annotate them by adding attributes. Add an outputSchema attribute to your function so that Pig can identify return types for the script UDF. </p>
 <ul>
 <li>outputSchema - Defines schema for a script udf in a format that Pig understands and is able to parse. </li>
 <li>Sample Schema String - y:{t:(word:chararray,num:long)} <br></br>Variable names inside a schema string are used for type conversion between Pig and JavaScript. Tuples are converted to Objects using the names and vice versa</li>
 </ul>
 </section>
 
 <!-- ++++++++++++++++++++++++++++++++++++++++++++++++ -->
 <section id="js-example">
 <title>Example Scripts</title> 
  <p>A simple JavaScript UDF (udf.js) is shown here.</p>
 <source>
helloworld.outputSchema = "word:chararray";
function helloworld() {
    return 'Hello, World';
}
    
complex.outputSchema = "(word:chararray,num:long)";
function complex(word){
    return {word:word, num:word.length};
}
</source>
 
<p>This Pig script registers the JavaScript UDF (udf.js).</p>
<source>
register 'udf.js' using javascript as myfuncs; 
A = load 'data' as (a0:chararray, a1:int);
B = foreach A generate myfuncs.helloworld(), myfuncs.complex(a0);
... ... 
</source>
  </section>
  
   <!-- ++++++++++++++++++++++++++++++++++++++++++++++++ -->
 <section id="js-advanced">
 <title>Advanced Topics</title> 

 <p>UDFs and Pig scripts are generally stored in separate files. For testing purposes you can combine the code in a single file - a "combined" script. 
 Note, however, if you then decide to embed this "combined" script in a host language, the language of the UDF and the host language must match.</p>
 
 <p>This example combines JavaScript and Pig. This "combined" script can only be embedded in JavaScript.</p>
<p>With JavaScript, the control flow MUST be defined in the main function. Otherwise the script will result in an error.</p>
 <source>
importPackage(Packages.org.apache.pig.scripting.js)
pig = org.apache.pig.scripting.js.JSPig;

helloworld.outputSchema = "word:chararray" 
function helloworld() { 
    return 'Hello, World'; 
}

function main() {
  var P = pig.compile(" a = load '1.txt' as (a0, a1);”+
       “b = foreach a generate helloworld();”+
           “store b into 'myoutput';");

  var result = P.bind().runSingle();
}
 </source>
 
 </section>
</section>

 <!-- =============================================================== -->
 <section id="jruby-udfs">
 <title>Writing Ruby UDFs</title>

 <p><strong>Note:</strong> <em>Ruby UDFs are an experimental feature.</em></p>

<!-- ++++++++++++++++++++++++++++++++++++++++++++++++ -->
 <section id="write-jruby">
 <title>Writing a Ruby UDF</title>
 <p>You must extend PigUdf and define your Ruby UDFs in the class. </p>
 <source>
 require 'pigudf'
 class Myudfs &lt; PigUdf
     def square num
         return nil if num.nil?
         num**2
     end
 end
 </source>
 </section>
 <section id="jruby-schema-return-types">
 <title>Return Types and Schemas</title>
 <p>You have two ways to define the return schema:</p>
 <p>outputSchema - Defines the schema for a UDF in a format that Pig understands. </p>
 <source>
 outputSchema "word:chararray"
 </source>
 <source>
 outputSchema "t:(m:[], t:(name:chararray, age:int, gpa:double), b:{t:(name:chararray, age:int, gpa:double)})"
 </source>
 <p>Schema function</p>
 <source>
 outputSchemaFunction :squareSchema
 def squareSchema input
     input
 end
 </source>
 <p>You need to put outputSchema/outputSchemaFunction statement right before your UDF. The schema function itself can be defined anywhere inside the class.</p>
 </section>
 <section id="register-jruby">
 <title>Registering the UDF</title>
 <p>You can register a Ruby UDF as shown here. </p>
 <source>
 register 'test.rb' using jruby as myfuncs;
 </source>
 <p> This is a shortcut to the complete syntax:</p>
 <source>
 register 'test.rb' using org.apache.pig.scripting.jruby.JrubyScriptEngine as myfuncs;
 </source>
 <p>The <code>register</code> statement above registers the Ruby functions defined in test.rb in Pig’s runtime within the defined namespace (myfuncs in this example). They can then be referred later on in the Pig Latin script as <code>myfuncs.square()</code>. An example usage is:</p>
 <source>
 b = foreach a generate myfuncs.concat($0, $1);
 </source>
 </section>
 <section id="jruby-example">
 <title>Example Scripts</title>
 <p>Here are two complete Ruby UDF samples.</p>
 <source>
 require 'pigudf'
 class Myudfs &lt; PigUdf
 outputSchema "word:chararray"
     def concat *input
         input.inject(:+)
     end
 end
 </source>
 <source>
 require 'pigudf'
 class Myudfs &lt; PigUdf
 outputSchemaFunction :squareSchema
     def square num
         return nil if num.nil?
         num**2
     end
     def squareSchema input
         input
     end
 end
 </source>
 </section>

 <section id="jruby-advanced">
 <title>Advanced Topics</title>
 <p> You can also write Algebraic and Accumulator UDFs using Ruby. You need to extend your class from <code>AlgebraicPigUdf</code> and <code>AccumulatorPigUdf</code> respectively. For an Algebraic UDF, define <code>initial</code>, <code>intermed</code>, and <code>final</code> methods in the class. For an Accumulator UDF, define <code>exec</code> and <code>get</code> methods in the class. Below are example for each type of UDF: </p>
 <source>
 class Count &lt; AlgebraicPigUdf
     output_schema Schema.long
     def initial t
          t.nil? ? 0 : 1
     end
     def intermed t
          return 0 if t.nil?
          t.flatten.inject(:+)
     end
     def final t
         intermed(t)
     end
 end
 </source>
 <source>
 class Sum &lt; AccumulatorPigUdf
     output_schema { |i| i.in.in[0] }
     def exec items
         @sum ||= 0
         @sum += items.flatten.inject(:+)
     end
     def get
         @sum
     end
 end
 </source>
 </section>

</section> 

<!-- =============================================================== -->
<section id="groovy-udfs">
 <title>Writing Groovy UDFs</title>

 <p><strong>Note:</strong> <em>Groovy UDFs are an experimental feature.</em></p>

<!-- ++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="register-groovy">
<title>Registering the UDF</title>
<p>You can register a Groovy script as shown here. This example uses org.apache.pig.scripting.groovy.GroovyScriptEngine to interpret the Groovy script. You can develop and use custom script engines to support multiple programming languages and ways to interpret them. Currently, Pig identifies groovy as a keyword and ships the required scriptengine (groovy-all) to interpret it. </p>
<source>
Register 'test.groovy' using groovy as myfuncs;
</source>

<p>The following syntax is also supported, where myfuncs is the namespace created for all the functions inside test.groovy.</p>
<source>
register 'test.groovy' using org.apache.pig.scripting.groovy.GroovyScriptEngine as myfuncs;
</source>

<p>A registered script can contain multiple UDFs. UDFs can be static or instance methods, an instance of the enclosing class will be created as needed. Only methods for which a return schema is defined will be available in Pig.</p>
</section>

<!-- ++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="groovy-schema-return-types">
<title>Return Types and Schemas</title>
<p>You have two ways to define the return schema, both use annotations:</p>
<p>@OutputSchema annotation - Defines the schema for a UDF in a format that Pig understands.</p>
<source>
import org.apache.pig.builtin.OutputSchema;

class GroovyUDFs {
  @OutputSchema('x:long')
  long square(long x) {
    return x*x;
  }
}
</source>
<source>
outputSchema "t:(m:[], t:(name:chararray, age:int, gpa:double), b:{t:(name:chararray, age:int, gpa:double)})"
</source>
<p>@OutputSchemaFunction annotation - Defines the name of a function which will return the schema at runtime according to the input schema.</p>
<source>
import org.apache.pig.scripting.groovy.OutputSchemaFunction;

class GroovyUDFs {
  @OutputSchemaFunction('squareSchema')
  public static square(x) {
    return x * x;
  }

  public static squareSchema(input) {          
    return input;
  }
}        

</source>
<p>Only methods annotated with either @OutputSchema or @OutputSchemaFunction will be exposed to Pig as UDFs. In the example above, squareSchema will not be available in Pig as a UDF.</p>
</section>

<!-- ++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="groovy-type-conversions">
<title>Type Conversions</title>
<p>The data passed back and forth between Pig and Groovy goes through a conversion process. The following conversions rules are applied:</p>

<p>Pig to Groovy</p>
<ul>
  <li>Tuple: groovy.lang.Tuple</li>
  <li>DataBag: groovy.lang.Tuple containing the bag's size and an iterator on its content</li>
  <li>org.joda.time.DateTime: org.joda.time.DateTime</li>
  <li>Map: java.util.Map</li>
  <li>int/long/float/double: as is</li>
  <li>chararray: String</li>
  <li>bytearray: byte[] (content is copied)</li>
  <li>boolean: boolean</li>
  <li>biginteger: BigInteger</li>
  <li>bigdecimal: BigDecimal</li>
  <li>null: null </li>
</ul>
<p>Anything else raises an exception</p>

<p>Groovy to Pig</p>
<ul>
  <li>Object[]: Tuple</li>
  <li>groovy.lang.Tuple: Tuple</li>
  <li>org.apache.pig.data.Tuple: Tuple</li>
  <li>org.apache.pig.data.DataBag: DataBag</li>
  <li>org.joda.time.DateTime: org.joda.time.DateTime</li>
  <li>java.util.Map: Map</li>
  <li>java.util.List: DataBag</li>
  <li>Byte/Short/Integer: int</li>
  <li>Long: long</li>
  <li>Float: float</li>
  <li>Double: double</li>
  <li>String: chararray</li>
  <li>byte[]: DataByteArray (content is copied)</li>
  <li>Boolean: boolean</li>
  <li>BigInteger: biginteger</li>
  <li>BigDecimal: bigdecimal</li>
  <li>null: null</li>
</ul>
<p>Anything else raises an exception</p>
</section>
<!-- ++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="groovy-advanced">
<title>Advanced Topics</title>
<p>You can also write Algebraic and Accumulator UDFs using Groovy. Both types of UDFs are declared using annotations, a single Groovy file can therefore enclose several Algebraic/Accumulator UDFs, all mixed with regular UDFs.</p>

<p>Algebraic UDFs are declared using three annotations, @AlgebraicInitial, @AlgebraicIntermed and @AlgebraicFinal which are to annotate methods that correspond to the initial, intermed and final steps of an Algebraic UDF. Those annotations have a single parameter which is the name of the Algebraic UDF that will be available in Pig. The methods annotated with @AlgebraicInitial and @AlgebraicIntermed accept a Tuple as parameter and return a Tuple. The return type of the method annotated with @AlgebraicFinal will determine the return type of the Algebraic UDF. Here is an example of an Algebraic UDF named 'sum' defined in Groovy:</p>
 <source>
import org.apache.pig.scripting.groovy.AlgebraicInitial;
import org.apache.pig.scripting.groovy.AlgebraicIntermed;
import org.apache.pig.scripting.groovy.AlgebraicFinal;

class GroovyUDFs {
  @AlgebraicFinal('sum')
  public static long algFinal(Tuple t) {
    long x = 0;
    for (Object o: t[1]) {
      x = x + o;
    }
    return x;
  }
  @AlgebraicInitial('sum')
  public static Tuple algInitial(Tuple t) {
    long x = 0;
    for (Object o: t[1]) {
      x = x + o[0];
    }
    return [x];
  }
  @AlgebraicIntermed('sum')
  public static Tuple algIntermed(Tuple t) {
    long x = 0;
    for (Object o: t[1]) {
      x = x + o;
    }
    return [x];
  }
}
 </source>

<p>Similarly, Accumulator UDFs are declared using the three annotations @AccumulatorAccumulate, @AccumulatorGetValue and @AccumulatorCleanup which are to annotate methods that correspond to the methods accumulate, getValue and cleanup of a Java Accumulator UDF. Those annotations have a single parameter which is the name of the Accumulator UDF that will be available in Pig. The methods annotated with @AccumulatorAccumulate and @AccumulatorCleanup return void. The methods annotated with @AccumulatorGetValue and @AccumulatorCleanup take no parameters. The method annotated with @AccumulatorAccumulate takes a Tuple as parameter. The return schema of the Accumulator UDF is determined by the @OutputSchema or @OutputSchemaFunction annotation used on the method annotated with @AccumulatorGetValue. Note that even though a method annotated with @AccumulatorGetValue has an @OutputSchema or @OutputSchemaFunction annotation, it will not be available in Pig, only the Accumulator UDF to which it belongs will.</p>

<p>Since Accumulator UDFs maintain state, the methods annotated with the @AccumulatorXXX annotations cannot be static. A single instance of the enclosing class will be used when invoking them, thus enabling them to access a single state.</p>

<p>The following example defines an Accumulator UDF named 'sumacc':</p>
 <source>
import org.apache.pig.builtin.OutputSchema;
import org.apache.pig.scripting.groovy.AccumulatorAccumulate;
import org.apache.pig.scripting.groovy.AccumulatorGetValue;
import org.apache.pig.scripting.groovy.AccumulatorCleanup;

class GroovyUDFs {
  private int sum = 0;
  @AccumulatorAccumulate('sumacc')
  public void accuAccumulate(Tuple t) {
    for (Object o: t[1]) {
      sum += o[0]
    }
  }
  @AccumulatorGetValue('sumacc')
  @OutputSchema('sum: long')
  public long accuGetValue() {
    return this.sum;
  }
  @AccumulatorCleanup('sumacc')
  public void accuCleanup() {
    this.sum = 0L;
  }
}  
 </source>
 </section>
</section>

<!-- =============================================================== -->
<section id="python-udfs">
<title>Writing Python UDFs</title>
<p>Here Python UDFs means C Python UDFs. It uses python command line to run the Python UDFs. It is different than Jython, which relies on Jython library. Instead, it streams the data in and out of the python process. The implementation mechanism is completely different than Jython.</p>

<!-- ++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="register-python">
<title>Registering the UDF</title>
<p>You can register a Python script as shown here. </p>
<source>
Register 'test.py' using streaming_python as myfuncs;
</source>

<p>The following syntax is also supported, where myfuncs is the namespace created for all the functions inside test.py.</p>
<source>
register 'test.py' using org.apache.pig.scripting.streaming.python.PythonScriptEngine as myfuncs;
</source>


<p>A typical test.py looks like this:</p>
<source>
from pig_util import outputSchema

@outputSchema("as:int")
def square(num):
    if num == None:
        return None
    return ((num) * (num))

@outputSchema("word:chararray")
def concat(word):
    return word + word
</source>

<p>The register statement above registers the Python functions defined in test.py in Pig’s runtime within the defined namespace (myfuncs here). They can then be referred later on in the pig script as myfuncs.square(), myfuncs.concat(). An example usage is:</p>

<source>
b = foreach a generate myfuncs.concat('hello', 'world'), myfuncs.square(3);
</source>


<!-- ++++++++++++++++++++++++++++++++++++++++++++++++ -->
</section>
<section id="decorators">
<title>Decorators and Schemas</title>
<p>To annotate a Python script so that Pig can identify return types, use Python decorators to define output schema for the script UDF. </p>
<ul>
<li>outputSchema - Defines schema for a script UDF in a format that Pig understands and is able to parse. </li>
</ul>

<p>When no decorator is specified, Pig assumes the output datatype as bytearray and converts the output generated by script function to bytearray. This is consistent with Pig's behavior in case of Java UDFs. </p>

<p>Sample Schema String - words:{(word:chararray)}, variable names inside a schema string are not used anywhere, they just make the syntax identifiable to the parser. </p>
</section>
</section>

<!-- ================================================================== -->
<!-- PIGGYBANK -->
<section id="piggybank">
<title>Piggy Bank</title>
<p>Piggy Bank is a place for Pig users to share the Java UDFs they have written for use with Pig. 
The functions are contributed "as-is." 
If you find a bug in a function, take the time to fix it and contribute the fix to Piggy Bank. 
If you don't find the UDF you need, take the time to write and contribute the function to Piggy Bank.
</p>

<p><strong>Note:</strong> Piggy Bank currently supports Java UDFs. Support for Jython and JavaScript UDFs will be added at a later date.</p>

 <!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="piggbank-access">
<title>Accessing Functions</title>

<p>The Piggy Bank functions are currently distributed in source form. Users are required to checkout the code and build the package themselves. No binary distributions or nightly builds are available at this time. </p>

<p>To build a jar file that contains all available UDFs, follow these steps: </p>
<ul>
<li>Checkout UDF code: <code>svn co http://svn.apache.org/repos/asf/pig/trunk/contrib/piggybank</code> </li>
<li>Add pig.jar to your ClassPath: <code>export CLASSPATH=$CLASSPATH:/path/to/pig.jar</code> </li>
<li>Build the jar file: from directory<code>trunk/contrib/piggybank/java</code> run <code>ant</code>. 
This will generate <code>piggybank.jar</code> in the same directory. </li>
</ul>
<p></p>

<p>To obtain <code>javadoc</code> description of the functions run <code>ant javadoc</code> from directory <code>trunk/contrib/piggybank/java</code>. The documentation is generate in directory <code>trunk/contrib/piggybank/java/build/javadoc</code>.</p>

<p>To use a function, you need to determine which package it belongs to. The top level packages correspond to the function type and currently are: </p>
<ul>
<li>org.apache.pig.piggybank.comparison - for custom comparator used by ORDER operator </li>
<li>org.apache.pig.piggybank.evaluation - for eval functions like aggregates and column transformations </li>
<li>org.apache.pig.piggybank.filtering - for functions used in FILTER operator </li>
<li>org.apache.pig.piggybank.grouping - for grouping functions</li>
<li>org.apache.pig.piggybank.storage - for load/store functions </li>
</ul>
<p></p>

<p>(The exact package of the function can be seen in the javadocs or by navigating the source tree.) </p>

<p>For example, to use the UPPER function: </p>

<source>
REGISTER /public/share/pig/contrib/piggybank/java/piggybank.jar ;
TweetsInaug = FILTER Tweets BY org.apache.pig.piggybank.evaluation.string.UPPER(text) 
    MATCHES '.*(INAUG|OBAMA|BIDEN|CHENEY|BUSH).*' ;
STORE TweetsInaug INTO 'meta/inaug/tweets_inaug' ;
</source>
</section>

 <!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<section id="piggybank-contribute">
<title>Contributing Functions</title>

<p>To contribute a Java function that you have written, do the following:</p>
<ol>
<li>Check the existing javadoc to make sure that the function does not already exist as described in <a href="#piggbank-access">Accessing Functions</a>. </li>
<li>Checkout the UDF code as described in <a href="#piggbank-access">Accessing Functions</a>. </li>
<li>Place your java code in the directory that makes sense for your function. The directory structure currently has two levels: (1) function type, as described in <a href="#piggbank-access">Accessing Functions</a>, and (2) function subtype, for some of the types (like math or string for eval functions). If you think your function requires a new subtype, feel free to add one. </li>
<li>Make sure that your function is well documented and uses the 
<a href="http://docs.oracle.com/javase/6/docs/technotes/tools/solaris/javadoc.html">javadoc</a> style of documentation. </li>
<li>Make sure that your code follows Pig coding conventions described in <a href="https://cwiki.apache.org/confluence/display/PIG/HowToContribute">How to Contribute to Pig</a>.</li>
<li>Make sure that for each function, you add a corresponding test class in the test part of the tree. </li>
<li>Submit your patch following the process described in <a href="https://cwiki.apache.org/confluence/display/PIG/HowToContribute">How to Contribute to Pig</a>. </li>
</ol>
</section>
</section> 


</body>
</document>

