You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by cw...@apache.org on 2011/09/29 20:09:41 UTC

svn commit: r1177382 - in /hive/trunk: ./ cli/src/java/org/apache/hadoop/hive/cli/ pdk/ pdk/scripts/ pdk/src/ pdk/src/java/ pdk/src/java/org/ pdk/src/java/org/apache/ pdk/src/java/org/apache/hive/ pdk/src/java/org/apache/hive/pdk/ pdk/test-plugin/ pdk/...

Author: cws
Date: Thu Sep 29 18:09:40 2011
New Revision: 1177382

URL: http://svn.apache.org/viewvc?rev=1177382&view=rev
Log:
HIVE-2244. Add a Plugin Developer Kit to Hive (John Sichi via cws)

Added:
    hive/trunk/pdk/
    hive/trunk/pdk/build.xml
    hive/trunk/pdk/scripts/
    hive/trunk/pdk/scripts/README
    hive/trunk/pdk/scripts/build-plugin.xml
    hive/trunk/pdk/scripts/class-registration.xsl
    hive/trunk/pdk/src/
    hive/trunk/pdk/src/java/
    hive/trunk/pdk/src/java/org/
    hive/trunk/pdk/src/java/org/apache/
    hive/trunk/pdk/src/java/org/apache/hive/
    hive/trunk/pdk/src/java/org/apache/hive/pdk/
    hive/trunk/pdk/src/java/org/apache/hive/pdk/FunctionExtractor.java
    hive/trunk/pdk/src/java/org/apache/hive/pdk/HivePdkUnitTest.java
    hive/trunk/pdk/src/java/org/apache/hive/pdk/HivePdkUnitTests.java
    hive/trunk/pdk/src/java/org/apache/hive/pdk/PluginTest.java
    hive/trunk/pdk/test-plugin/
    hive/trunk/pdk/test-plugin/build.xml
    hive/trunk/pdk/test-plugin/src/
    hive/trunk/pdk/test-plugin/src/org/
    hive/trunk/pdk/test-plugin/src/org/apache/
    hive/trunk/pdk/test-plugin/src/org/apache/hive/
    hive/trunk/pdk/test-plugin/src/org/apache/hive/pdktest/
    hive/trunk/pdk/test-plugin/src/org/apache/hive/pdktest/Rot13.java
    hive/trunk/pdk/test-plugin/test/
    hive/trunk/pdk/test-plugin/test/cleanup.sql
    hive/trunk/pdk/test-plugin/test/onerow.txt
    hive/trunk/pdk/test-plugin/test/setup.sql
Modified:
    hive/trunk/build.xml
    hive/trunk/cli/src/java/org/apache/hadoop/hive/cli/CliDriver.java

Modified: hive/trunk/build.xml
URL: http://svn.apache.org/viewvc/hive/trunk/build.xml?rev=1177382&r1=1177381&r2=1177382&view=diff
==============================================================================
--- hive/trunk/build.xml (original)
+++ hive/trunk/build.xml Thu Sep 29 18:09:40 2011
@@ -119,7 +119,7 @@
       <subant target="@{target}">
         <property name="build.dir.hive" location="${build.dir.hive}"/>
         <property name="is-offline" value="${is-offline}"/>
-        <filelist dir="." files="ant/build.xml,shims/build.xml,common/build.xml,serde/build.xml,metastore/build.xml,ql/build.xml,contrib/build.xml,service/build.xml,cli/build.xml,jdbc/build.xml,hwi/build.xml,hbase-handler/build.xml,ant/build.xml"/>
+        <filelist dir="." files="ant/build.xml,shims/build.xml,common/build.xml,serde/build.xml,metastore/build.xml,ql/build.xml,contrib/build.xml,service/build.xml,cli/build.xml,jdbc/build.xml,hwi/build.xml,hbase-handler/build.xml,ant/build.xml,pdk/build.xml"/>
       </subant>
     </sequential>
   </macrodef>
@@ -130,7 +130,7 @@
       <subant target="@{target}">
         <property name="build.dir.hive" location="${build.dir.hive}"/>
         <property name="is-offline" value="${is-offline}"/>
-        <filelist dir="." files="shims/build.xml,common/build.xml,serde/build.xml,metastore/build.xml,ql/build.xml,contrib/build.xml,service/build.xml,cli/build.xml,jdbc/build.xml,hwi/build.xml,hbase-handler/build.xml"/>
+        <filelist dir="." files="shims/build.xml,common/build.xml,serde/build.xml,metastore/build.xml,ql/build.xml,contrib/build.xml,service/build.xml,cli/build.xml,jdbc/build.xml,hwi/build.xml,hbase-handler/build.xml,pdk/build.xml"/>
       </subant>
     </sequential>
   </macrodef>
@@ -292,6 +292,7 @@
     <mkdir dir="${target.conf.dir}"/>
     <mkdir dir="${target.bin.dir}"/>
     <mkdir dir="${target.scripts.dir}/metastore/upgrade"/>
+    <mkdir dir="${target.scripts.dir}/pdk"/>
     <mkdir dir="${target.example.dir}"/>
     <mkdir dir="${target.example.dir}/files"/>
     <mkdir dir="${target.example.dir}/queries"/>
@@ -301,6 +302,9 @@
     <copy todir="${target.scripts.dir}/metastore/upgrade">
       <fileset dir="${hive.root}/metastore/scripts/upgrade" excludes="${vcs.excludes}"/>
     </copy>
+    <copy todir="${target.scripts.dir}/pdk">
+      <fileset dir="${hive.root}/pdk/scripts" excludes="${vcs.excludes},README"/>
+    </copy>
     <copy todir="${target.bin.dir}/ext">
       <fileset dir="${hive.root}/bin/ext" excludes="${vcs.excludes}"/>
     </copy>
@@ -373,6 +377,9 @@
     <copy todir="${target.example.dir}/files" preservelastmodified="true" flatten="true">
       <fileset dir="${test.data.dir}/files" includes="*.*" excludes="${vcs.excludes}"/>
     </copy>
+    <copy todir="${target.example.dir}/test-plugin">
+      <fileset dir="${hive.root}/pdk/test-plugin"/>
+    </copy>
     <copy file="${basedir}/README.txt" todir="${target.dir}">
       <filterset>
         <filter token="VERSION" value="${version}"/>
@@ -452,7 +459,6 @@
       </fileset>
       <mapper type="glob" from="*.launchtemplate" to="*.launch"/>
     </move>
-
   </target>
 
   <target name="clean-eclipse-files"
@@ -507,6 +513,7 @@
       <packageset dir="ql/src/gen/thrift/gen-javabean"/>
       <packageset dir="${build.dir.hive}/ql/gen/antlr/gen-java"/>
       <packageset dir="shims/src/common/java"/>
+      <packageset dir="pdk/src/java"/>
 
       <link href="${javadoc.link.java}"/>
 
@@ -691,6 +698,8 @@
           todir="${build.dir.hive}/maven/jars/" />
     <copy file="${build.dir.hive}/shims/hive-shims-${version}.jar"
           todir="${build.dir.hive}/maven/jars/" />
+    <copy file="${build.dir.hive}/pdk/hive-pdk-${version}.jar"
+          todir="${build.dir.hive}/maven/jars/" />
 
     <!-- copy over maven pom files created using the make-pom target and rename to maven convention -->
     <copy file="${build.dir.hive}/anttasks/pom.xml"
@@ -717,6 +726,8 @@
           tofile="${build.dir.hive}/maven/poms/hive-service-${version}.pom" />
     <copy file="${build.dir.hive}/shims/pom.xml"
           tofile="${build.dir.hive}/maven/poms/hive-shims-${version}.pom" />
+    <copy file="${build.dir.hive}/pdk/pom.xml"
+          tofile="${build.dir.hive}/maven/poms/hive-pdk-${version}.pom" />
 
     <!-- copy over licence -->
     <copy file="${hive.root}/LICENSE" todir="${build.dir.hive}/maven/licences/" />
@@ -777,6 +788,9 @@
       <param name="hive.project" value="hwi" />
     </antcall>
     <antcall target="maven-publish-artifact">
+      <param name="hive.project" value="pdk" />
+    </antcall>
+    <antcall target="maven-publish-artifact">
       <param name="hive.project" value="jdbc" />
     </antcall>
     <antcall target="maven-publish-artifact">

Modified: hive/trunk/cli/src/java/org/apache/hadoop/hive/cli/CliDriver.java
URL: http://svn.apache.org/viewvc/hive/trunk/cli/src/java/org/apache/hadoop/hive/cli/CliDriver.java?rev=1177382&r1=1177381&r2=1177382&view=diff
==============================================================================
--- hive/trunk/cli/src/java/org/apache/hadoop/hive/cli/CliDriver.java (original)
+++ hive/trunk/cli/src/java/org/apache/hadoop/hive/cli/CliDriver.java Thu Sep 29 18:09:40 2011
@@ -549,10 +549,15 @@ public class CliDriver {
   }
 
   public static void main(String[] args) throws Exception {
+    int ret = run(args);
+    System.exit(ret);
+  }
+
+  public static int run(String[] args) throws Exception {
 
     OptionsProcessor oproc = new OptionsProcessor();
     if (!oproc.process_stage1(args)) {
-      System.exit(1);
+      return 1;
     }
 
     // NOTE: It is critical to do this here so that log4j is reinitialized
@@ -572,11 +577,11 @@ public class CliDriver {
       ss.out = new PrintStream(System.out, true, "UTF-8");
       ss.err = new PrintStream(System.err, true, "UTF-8");
     } catch (UnsupportedEncodingException e) {
-      System.exit(3);
+      return 3;
     }
 
     if (!oproc.process_stage2(ss)) {
-      System.exit(2);
+      return 2;
     }
 
     if (!ss.getIsSilent()) {
@@ -627,16 +632,16 @@ public class CliDriver {
     cli.processInitFiles(ss);
 
     if (ss.execString != null) {
-      System.exit(cli.processLine(ss.execString));
+      return cli.processLine(ss.execString);
     }
 
     try {
       if (ss.fileName != null) {
-        System.exit(cli.processFile(ss.fileName));
+        return cli.processFile(ss.fileName);
       }
     } catch (FileNotFoundException e) {
       System.err.println("Could not open input file for reading. (" + e.getMessage() + ")");
-      System.exit(3);
+      return 3;
     }
 
     ConsoleReader reader = new ConsoleReader();
@@ -675,7 +680,7 @@ public class CliDriver {
 
     ss.close();
 
-    System.exit(ret);
+    return ret;
   }
 
   /**

Added: hive/trunk/pdk/build.xml
URL: http://svn.apache.org/viewvc/hive/trunk/pdk/build.xml?rev=1177382&view=auto
==============================================================================
--- hive/trunk/pdk/build.xml (added)
+++ hive/trunk/pdk/build.xml Thu Sep 29 18:09:40 2011
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<project name="pdk" default="jar">
+  
+  <property name="src.dir"  location="${basedir}/src/java"/>
+  <import file="../build-common.xml"/>
+
+  <path id="classpath-pdk">
+    <fileset dir="${hive.root}/testlibs" includes="junit-3.8.1.jar"/>
+    <path refid="classpath"/>
+  </path>
+
+  <target name="compile" depends="init, setup">
+    <echo message="Compiling: ${ant.project.name}"/>
+    <javac
+     encoding="${build.encoding}"
+     srcdir="${src.dir}"
+     includes="**/*.java"
+     destdir="${build.classes}"
+     debug="${javac.debug}"
+     deprecation="${javac.deprecation}">
+      <compilerarg line="${javac.args} ${javac.args.warnings}" />
+      <classpath refid="classpath-pdk"/>
+    </javac>
+  </target>
+
+  <target name="test" unless="testcase">
+    <delete quiet="true" dir="${build.dir}/test-plugin"/>
+    <copy todir="${build.dir}/test-plugin">
+      <fileset dir="${basedir}/test-plugin"/>
+    </copy>
+    <ant antfile="${build.dir}/test-plugin/build.xml"
+         target="package" inheritAll="false" inheritRefs="false">
+      <property name="hive.install.dir" value="${build.dir.hive}/dist"/>
+    </ant>
+    <ant antfile="${build.dir}/test-plugin/build.xml"
+         target="test" inheritAll="false" inheritRefs="false">
+      <property name="hive.install.dir" value="${build.dir.hive}/dist"/>
+    </ant>
+  </target>
+
+</project>

Added: hive/trunk/pdk/scripts/README
URL: http://svn.apache.org/viewvc/hive/trunk/pdk/scripts/README?rev=1177382&view=auto
==============================================================================
--- hive/trunk/pdk/scripts/README (added)
+++ hive/trunk/pdk/scripts/README Thu Sep 29 18:09:40 2011
@@ -0,0 +1,3 @@
+Note that this directory contains scripts which are bundled into the
+Plugin Development Kit (rather than used as part of the Hive build
+itself).

Added: hive/trunk/pdk/scripts/build-plugin.xml
URL: http://svn.apache.org/viewvc/hive/trunk/pdk/scripts/build-plugin.xml?rev=1177382&view=auto
==============================================================================
--- hive/trunk/pdk/scripts/build-plugin.xml (added)
+++ hive/trunk/pdk/scripts/build-plugin.xml Thu Sep 29 18:09:40 2011
@@ -0,0 +1,133 @@
+<?xml version="1.0"?>
+
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<project name="hive-plugin-import" default="intended-for-import-only">
+  <dirname property="pdk.script.dir" file="${ant.file.hive-plugin-import}"/>
+  <property name="plugin.dir" location="${basedir}"/>
+  <property name="src.dir" location="${plugin.dir}/src"/>
+  <property name="build.dir" location="${plugin.dir}/build"/>
+  <property name="build.classes" location="${build.dir}/classes"/>
+  <property name="build.metadata" location="${build.dir}/metadata"/>
+  <property name="install.dir" location="${pdk.script.dir}/../.."/>
+  <property name="function.sql.prefix" value=""/>
+  <property name="plugin.jar.basename" 
+            value="${plugin.libname}-${plugin.version}.jar"/>
+
+  <property environment="env"/>
+
+  <path id="plugin.classpath">
+    <fileset dir="${install.dir}" includes="lib/hive-exec-*.jar"/>
+    <fileset dir="${install.dir}" includes="lib/hive-pdk-*.jar"/>
+    <fileset dir="${install.dir}" includes="lib/commons-lang-*.jar"/>
+    <fileset dir="${install.dir}" includes="lib/commons-logging-*.jar"/>
+    <fileset dir="${env.HADOOP_HOME}" includes="hadoop-*-core.jar"/>
+    <pathelement location="${build.classes}"/>
+  </path>
+
+  <path id="plugin.test.classpath">
+    <pathelement path="${install.dir}/conf"/>
+    <fileset dir="${install.dir}" includes="lib/*.jar"/>
+    <fileset dir="${env.HADOOP_HOME}" includes="hadoop-*-core.jar"/>
+    <fileset dir="${build.dir}" includes="${plugin.jar.basename}"/>
+  </path>
+
+  <target name="compile">
+    <mkdir dir="${build.classes}"/>
+    <javac
+       srcdir="${src.dir}"
+       includes="**/*.java"
+       includeantruntime="false"
+       destdir="${build.classes}">
+      <classpath refid="plugin.classpath"/>
+    </javac>
+  </target>
+
+  <target name="jar" depends="compile">
+    <jar
+      jarfile="${build.dir}/${plugin.jar.basename}"
+      basedir="${build.classes}">
+      <manifest>
+        <attribute name="Implementation-Title" value="${plugin.title}"/>
+        <attribute name="Implementation-Version" value="${plugin.version}"/>
+        <attribute name="Implementation-Vendor" value="${plugin.vendor}"/>
+      </manifest>
+    </jar>
+  </target>
+
+  <target name="get-class-list">
+    <path id="class.file.list">
+      <fileset dir="${build.classes}">
+        <include name="**/*.class"/>
+      </fileset>
+    </path>
+    <pathconvert property="class.list"
+                 pathsep=" "
+                 dirsep="."
+                 refid="class.file.list">
+      <map from="${build.classes}/" to=""/>
+      <mapper>
+        <chainedmapper>
+          <globmapper from="*.class" to="*"/>
+        </chainedmapper>
+      </mapper>
+    </pathconvert>
+  </target>
+
+  <target name="extract-functions" depends="compile, get-class-list">
+    <mkdir dir="${build.metadata}"/>
+    <java classname="org.apache.hive.pdk.FunctionExtractor" 
+          classpathref="plugin.classpath" fork="true"
+          output="${build.metadata}/class-info.xml">
+       <arg line="${class.list}" />
+    </java>
+    <xslt style="${pdk.script.dir}/class-registration.xsl"
+      force="true"
+      in="${build.metadata}/class-info.xml"
+      out="${build.metadata}/class-registration.sql">
+      <param name="functionPrefix" expression="${function.sql.prefix}"/>
+    </xslt>
+    <echo file="${build.metadata}/add-jar.sql"
+          message="ADD JAR ${plugin.jar.basename};" />
+  </target>
+
+  <target name="clean">
+    <delete quiet="true" dir="${build.dir}"/>
+  </target>
+
+  <target name="package" depends="jar,extract-functions"/>
+
+  <target name="test" depends="package" unless="testcase">
+    <junit fork="true" printsummary="on" haltonfailure="true"
+           dir="${build.dir}">
+      <classpath refid="plugin.test.classpath"/>
+      <sysproperty key="hive.plugin.root.dir" value="${plugin.dir}"/>
+      <sysproperty key="hive.plugin.class.list" value="${class.list}"/>
+      <env key="HADOOP_HOME" value="${env.HADOOP_HOME}"/>
+      <env key="HIVE_CONF_DIR" value="${install.dir}/conf"/>
+      <env key="HIVE_HOME" value="${install.dir}"/>
+      <env key="HIVE_PLUGIN_ROOT_DIR" value="${plugin.dir}"/>
+      <formatter type="plain"/>
+      <test name="org.apache.hive.pdk.PluginTest" todir="${build.dir}/"/>
+      <assertions>
+        <enable />
+      </assertions>
+    </junit>
+  </target>
+
+</project>

Added: hive/trunk/pdk/scripts/class-registration.xsl
URL: http://svn.apache.org/viewvc/hive/trunk/pdk/scripts/class-registration.xsl?rev=1177382&view=auto
==============================================================================
--- hive/trunk/pdk/scripts/class-registration.xsl (added)
+++ hive/trunk/pdk/scripts/class-registration.xsl Thu Sep 29 18:09:40 2011
@@ -0,0 +1,41 @@
+<?xml version="1.0"?> 
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<xsl:stylesheet 
+  version="2.0" 
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  >
+  <xsl:output method="text" indent="no" />
+
+  <xsl:param name="functionPrefix"/>
+
+  <xsl:template match="Class">
+    <xsl:text>CREATE TEMPORARY FUNCTION </xsl:text>
+    <xsl:value-of select="$functionPrefix"/>
+    <xsl:value-of select="@sqlname"/>
+    <xsl:text> AS '</xsl:text>
+    <xsl:value-of select="@javaname"/>
+    <xsl:text>';</xsl:text>
+    <xsl:text>
+</xsl:text>
+  </xsl:template>
+
+  <xsl:template match="/ | @* | node()">
+    <xsl:apply-templates select="@* | node()" />
+  </xsl:template>
+
+</xsl:stylesheet>

Added: hive/trunk/pdk/src/java/org/apache/hive/pdk/FunctionExtractor.java
URL: http://svn.apache.org/viewvc/hive/trunk/pdk/src/java/org/apache/hive/pdk/FunctionExtractor.java?rev=1177382&view=auto
==============================================================================
--- hive/trunk/pdk/src/java/org/apache/hive/pdk/FunctionExtractor.java (added)
+++ hive/trunk/pdk/src/java/org/apache/hive/pdk/FunctionExtractor.java Thu Sep 29 18:09:40 2011
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hive.pdk;
+
+import org.apache.hadoop.hive.ql.exec.Description;
+
+public class FunctionExtractor {
+  public static void main(String [] args) throws Exception {
+    System.out.println("<ClassList>");
+    for (String arg : args) {
+      Class<?> c = Class.forName(arg);
+      Description d = c.getAnnotation(Description.class);
+      if (d == null) {
+        continue;
+      }
+      System.out.print("    <Class javaname=\"");
+      System.out.print(c.getName());
+      System.out.print("\" sqlname=\"");
+      System.out.print(d.name());
+      System.out.println("\" />");
+    }
+    System.out.println("</ClassList>");
+  }
+}

Added: hive/trunk/pdk/src/java/org/apache/hive/pdk/HivePdkUnitTest.java
URL: http://svn.apache.org/viewvc/hive/trunk/pdk/src/java/org/apache/hive/pdk/HivePdkUnitTest.java?rev=1177382&view=auto
==============================================================================
--- hive/trunk/pdk/src/java/org/apache/hive/pdk/HivePdkUnitTest.java (added)
+++ hive/trunk/pdk/src/java/org/apache/hive/pdk/HivePdkUnitTest.java Thu Sep 29 18:09:40 2011
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hive.pdk;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+/**
+ * Defines one Hive plugin unit test.
+ */
+public @interface HivePdkUnitTest {
+
+  /**
+   * Hive query to run for this test.
+   */
+  String query();
+
+  /**
+   * Expected result from query.
+   */
+  String result();
+}

Added: hive/trunk/pdk/src/java/org/apache/hive/pdk/HivePdkUnitTests.java
URL: http://svn.apache.org/viewvc/hive/trunk/pdk/src/java/org/apache/hive/pdk/HivePdkUnitTests.java?rev=1177382&view=auto
==============================================================================
--- hive/trunk/pdk/src/java/org/apache/hive/pdk/HivePdkUnitTests.java (added)
+++ hive/trunk/pdk/src/java/org/apache/hive/pdk/HivePdkUnitTests.java Thu Sep 29 18:09:40 2011
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hive.pdk;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+/**
+ * Defines a suite of Hive plugin unit tests.
+ */
+public @interface HivePdkUnitTests {
+
+  /**
+   * Hive commands (semicolon-separated) to run as suite cleanup.
+   */
+  String cleanup() default "";
+
+  /**
+   * Hive commands (semicolon-separated) to run as suite setup.
+   */
+  String setup() default "";
+
+  /**
+   * Hive plugin unit tests in this suite.
+   */
+  HivePdkUnitTest[] cases();
+}

Added: hive/trunk/pdk/src/java/org/apache/hive/pdk/PluginTest.java
URL: http://svn.apache.org/viewvc/hive/trunk/pdk/src/java/org/apache/hive/pdk/PluginTest.java?rev=1177382&view=auto
==============================================================================
--- hive/trunk/pdk/src/java/org/apache/hive/pdk/PluginTest.java (added)
+++ hive/trunk/pdk/src/java/org/apache/hive/pdk/PluginTest.java Thu Sep 29 18:09:40 2011
@@ -0,0 +1,200 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hive.pdk;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileReader;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import junit.extensions.TestSetup;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.hadoop.hive.cli.CliDriver;
+
+/**
+ * PluginTest is a test harness for invoking all of the unit tests
+ * annotated on the classes in a plugin.
+ */
+public class PluginTest extends TestCase {
+
+  private HivePdkUnitTest unitTest;
+
+  private PluginTest(HivePdkUnitTest unitTest) {
+    super(unitTest.query());
+    this.unitTest = unitTest;
+  }
+
+  public void runTest() throws Exception {
+    String output = runHive(
+      "-i",
+      "metadata/add-jar.sql",
+      "-e",
+      unitTest.query());
+    assertEquals(unitTest.result(), output);
+  }
+
+  static String runHive(String ... args) throws Exception {
+    ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
+    ByteArrayOutputStream errBytes = new ByteArrayOutputStream();
+    PrintStream outSaved = System.out;
+    PrintStream errSaved = System.err;
+    System.setOut(new PrintStream(outBytes, true));
+    System.setErr(new PrintStream(errBytes, true));
+    try {
+      CliDriver.run(args);
+    } finally {
+      System.setOut(outSaved);
+      System.setErr(errSaved);
+    }
+    ByteArrayInputStream outBytesIn =
+      new ByteArrayInputStream(outBytes.toByteArray());
+    ByteArrayInputStream errBytesIn =
+      new ByteArrayInputStream(errBytes.toByteArray());
+    BufferedReader is =
+      new BufferedReader(new InputStreamReader(outBytesIn));
+    BufferedReader es =
+      new BufferedReader(new InputStreamReader(errBytesIn));
+    StringBuilder output = new StringBuilder();
+    String line;
+    while ((line = is.readLine()) != null) {
+      if (output.length() > 0) {
+        output.append("\n");
+      }
+      output.append(line);
+    }
+    if (output.length() == 0) {
+      output = new StringBuilder();
+      while ((line = es.readLine()) != null) {
+        output.append("\n");
+        output.append(line);
+      }
+    }
+    return output.toString();
+  }
+
+  public static Test suite() throws Exception {
+    String classList = System.getProperty("hive.plugin.class.list");
+    String [] classNames = classList.split(" ");
+    TestSuite suite = new TestSuite("Plugin Tests");
+    for (String className : classNames) {
+      Class<?> c = Class.forName(className);
+      HivePdkUnitTests tests = c.getAnnotation(HivePdkUnitTests.class);
+      if (tests == null) {
+        continue;
+      }
+      TestSuite classSuite = new TestSuite(c.getName());
+      for (HivePdkUnitTest unitTest : tests.cases()) {
+        classSuite.addTest(new PluginTest(unitTest));
+      }
+      suite.addTest(new PluginTestSetup(classSuite, tests));
+    }
+
+    return new PluginGlobalSetup(suite);
+  }
+
+  public static void main(String [] args) throws Exception {
+    junit.textui.TestRunner.run(suite());
+  }
+
+  public static class PluginTestSetup extends TestSetup {
+    String name;
+    HivePdkUnitTests unitTests;
+
+    PluginTestSetup(TestSuite test, HivePdkUnitTests unitTests) {
+      super(test);
+      this.name = test.getName();
+      this.unitTests = unitTests;
+    }
+
+    protected void setUp() throws Exception {
+      String cleanup = unitTests.cleanup();
+      String setup = unitTests.setup();
+      if (cleanup == null) {
+        cleanup = "";
+      }
+      if (setup == null) {
+        setup = "";
+      }
+      if ((cleanup.length() > 0) || (setup.length() > 0)) {
+        String result = runHive(
+          "-e",
+          cleanup + "\n" + setup);
+        if (result.length() > 0) {
+          System.err.println(name + " SETUP:  " + result);
+        }
+      }
+    }
+
+    protected void tearDown() throws Exception {
+      String cleanup = unitTests.cleanup();
+      if (cleanup != null) {
+        String result = runHive(
+          "-e",
+          cleanup);
+        if (result.length() > 0) {
+          System.err.println(name + " TEARDOWN:  " + result);
+        }
+      }
+    }
+  }
+
+  public static class PluginGlobalSetup extends TestSetup {
+    private File testScriptDir;
+
+    PluginGlobalSetup(Test test) {
+      super(test);
+      testScriptDir =
+        new File(System.getProperty("hive.plugin.root.dir"), "test");
+    }
+
+    protected void setUp() throws Exception {
+      String result = runHive(
+        "-i",
+        new File(testScriptDir, "cleanup.sql").toString(),
+        "-i",
+        "metadata/add-jar.sql",
+        "-i",
+        "metadata/class-registration.sql",
+        "-f",
+        new File(testScriptDir, "setup.sql").toString());
+      if (result.length() > 0) {
+        System.err.println("GLOBAL SETUP:  " + result);
+      }
+    }
+
+    protected void tearDown() throws Exception {
+      String result = runHive(
+        "-f",
+        new File(testScriptDir, "cleanup.sql").toString());
+      if (result.length() > 0) {
+        System.err.println("GLOBAL TEARDOWN:  " + result);
+      }
+    }
+  }
+}

Added: hive/trunk/pdk/test-plugin/build.xml
URL: http://svn.apache.org/viewvc/hive/trunk/pdk/test-plugin/build.xml?rev=1177382&view=auto
==============================================================================
--- hive/trunk/pdk/test-plugin/build.xml (added)
+++ hive/trunk/pdk/test-plugin/build.xml Thu Sep 29 18:09:40 2011
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<project name="pdktest" default="package">
+  <property name="plugin.libname" value="pdk-test-udf"/>
+  <property name="plugin.title" value="Hive PDK Test UDF Library"/>
+  <property name="plugin.version" value="0.1"/>
+  <property name="plugin.vendor" value="Apache Software Foundation"/>
+  <property name="function.sql.prefix" value="tp_"/>
+  <import file="${hive.install.dir}/scripts/pdk/build-plugin.xml"/>
+</project>

Added: hive/trunk/pdk/test-plugin/src/org/apache/hive/pdktest/Rot13.java
URL: http://svn.apache.org/viewvc/hive/trunk/pdk/test-plugin/src/org/apache/hive/pdktest/Rot13.java?rev=1177382&view=auto
==============================================================================
--- hive/trunk/pdk/test-plugin/src/org/apache/hive/pdktest/Rot13.java (added)
+++ hive/trunk/pdk/test-plugin/src/org/apache/hive/pdktest/Rot13.java Thu Sep 29 18:09:40 2011
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hive.pdktest;
+
+import org.apache.hive.pdk.HivePdkUnitTest;
+import org.apache.hive.pdk.HivePdkUnitTests;
+
+import org.apache.hadoop.hive.ql.exec.Description;
+import org.apache.hadoop.hive.ql.exec.UDF;
+import org.apache.hadoop.io.Text;
+
+/**
+ * Example UDF for rot13 transformation.
+ */
+@Description(name = "rot13",
+  value = "_FUNC_(str) - Returns str with all characters transposed via rot13",
+  extended = "Example:\n"
+  + "  > SELECT _FUNC_('Facebook') FROM src LIMIT 1;\n" + "  'Snprobbx'")
+@HivePdkUnitTests(
+    setup = "create table rot13_data(s string); "
+    + "insert overwrite table rot13_data select 'Facebook' from onerow;",
+    cleanup = "drop table if exists rot13_data;",
+    cases = {
+      @HivePdkUnitTest(
+        query = "SELECT tp_rot13('Mixed Up!') FROM onerow;",
+        result = "Zvkrq Hc!"),
+      @HivePdkUnitTest(
+        query = "SELECT tp_rot13(s) FROM rot13_data;",
+        result = "Snprobbx")
+    }
+  )
+public class Rot13 extends UDF {
+  private Text t = new Text();
+
+  public Rot13() {
+  }
+
+  public Text evaluate(Text s) {
+    StringBuilder out = new StringBuilder(s.getLength());
+    char[] ca = s.toString().toCharArray();
+    for (char c : ca) {
+      if (c >= 'a' && c <= 'm') {
+        c += 13;
+      } else if (c >= 'n' && c <= 'z') {
+        c -= 13;
+      } else if (c >= 'A' && c <= 'M') {
+        c += 13;
+      } else if (c >= 'N' && c <= 'Z') {
+        c -= 13;
+      }
+      out.append(c);
+    }
+    t.set(out.toString());
+    return t;
+  }
+}

Added: hive/trunk/pdk/test-plugin/test/cleanup.sql
URL: http://svn.apache.org/viewvc/hive/trunk/pdk/test-plugin/test/cleanup.sql?rev=1177382&view=auto
==============================================================================
--- hive/trunk/pdk/test-plugin/test/cleanup.sql (added)
+++ hive/trunk/pdk/test-plugin/test/cleanup.sql Thu Sep 29 18:09:40 2011
@@ -0,0 +1 @@
+drop table if exists onerow;

Added: hive/trunk/pdk/test-plugin/test/onerow.txt
URL: http://svn.apache.org/viewvc/hive/trunk/pdk/test-plugin/test/onerow.txt?rev=1177382&view=auto
==============================================================================
--- hive/trunk/pdk/test-plugin/test/onerow.txt (added)
+++ hive/trunk/pdk/test-plugin/test/onerow.txt Thu Sep 29 18:09:40 2011
@@ -0,0 +1 @@
+plugh

Added: hive/trunk/pdk/test-plugin/test/setup.sql
URL: http://svn.apache.org/viewvc/hive/trunk/pdk/test-plugin/test/setup.sql?rev=1177382&view=auto
==============================================================================
--- hive/trunk/pdk/test-plugin/test/setup.sql (added)
+++ hive/trunk/pdk/test-plugin/test/setup.sql Thu Sep 29 18:09:40 2011
@@ -0,0 +1,3 @@
+create table onerow(s string);
+load data local inpath '${env:HIVE_PLUGIN_ROOT_DIR}/test/onerow.txt'
+overwrite into table onerow;