Index: build.xml =================================================================== --- build.xml (revision 1139984) +++ build.xml (working copy) @@ -119,7 +119,7 @@ - + @@ -130,7 +130,7 @@ - + @@ -294,6 +294,7 @@ + @@ -303,6 +304,9 @@ + + + @@ -375,6 +379,9 @@ + + + @@ -509,6 +516,7 @@ + @@ -693,6 +701,8 @@ todir="${build.dir.hive}/maven/jars/" /> + + @@ -779,6 +791,9 @@ + + + Index: pdk/scripts/class-registration.xsl =================================================================== --- pdk/scripts/class-registration.xsl (revision 0) +++ pdk/scripts/class-registration.xsl (revision 0) @@ -0,0 +1,41 @@ + + + + + + + + + CREATE TEMPORARY FUNCTION + + + AS ' + + '; + + + + + + + + + Index: pdk/scripts/build-plugin.xml =================================================================== --- pdk/scripts/build-plugin.xml (revision 0) +++ pdk/scripts/build-plugin.xml (revision 0) @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: pdk/scripts/README =================================================================== --- pdk/scripts/README (revision 0) +++ pdk/scripts/README (revision 0) @@ -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). Index: pdk/src/java/org/apache/hive/pdk/FunctionExtractor.java =================================================================== --- pdk/src/java/org/apache/hive/pdk/FunctionExtractor.java (revision 0) +++ pdk/src/java/org/apache/hive/pdk/FunctionExtractor.java (revision 0) @@ -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(""); + for (String arg : args) { + Class c = Class.forName(arg); + Description d = c.getAnnotation(Description.class); + if (d == null) { + continue; + } + System.out.print(" "); + } + System.out.println(""); + } +} Index: pdk/src/java/org/apache/hive/pdk/HivePdkUnitTest.java =================================================================== --- pdk/src/java/org/apache/hive/pdk/HivePdkUnitTest.java (revision 0) +++ pdk/src/java/org/apache/hive/pdk/HivePdkUnitTest.java (revision 0) @@ -0,0 +1,29 @@ +/** + * 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) +public @interface HivePdkUnitTest { + String query(); + String result(); +} Index: pdk/src/java/org/apache/hive/pdk/HivePdkUnitTests.java =================================================================== --- pdk/src/java/org/apache/hive/pdk/HivePdkUnitTests.java (revision 0) +++ pdk/src/java/org/apache/hive/pdk/HivePdkUnitTests.java (revision 0) @@ -0,0 +1,31 @@ +/** + * 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) +public @interface HivePdkUnitTests { + String cleanup(); + String setup(); + HivePdkUnitTest[] cases(); +} Index: pdk/src/java/org/apache/hive/pdk/PluginTest.java =================================================================== --- pdk/src/java/org/apache/hive/pdk/PluginTest.java (revision 0) +++ pdk/src/java/org/apache/hive/pdk/PluginTest.java (revision 0) @@ -0,0 +1,172 @@ +/** + * 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.File; +import java.io.FileReader; +import java.io.InputStreamReader; +import java.io.IOException; + +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; + +/** + * 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", + "-i", + "metadata/class-registration.sql", + "-e", + unitTest.query()); + assertEquals(unitTest.result(), output); + } + + static String runHive(String ... args) throws Exception { + String hiveHome = System.getProperty("hive.home"); + String testHome = System.getProperty("hive.plugin.test.dir"); + String pluginHome = System.getProperty("hive.plugin.root.dir"); + List argList = new ArrayList(); + argList.add(hiveHome + "/bin/hive"); + argList.addAll(Arrays.asList(args)); + ProcessBuilder pb = new ProcessBuilder(argList); + pb.directory(new File(testHome)); + pb.environment().put("HIVE_HOME", hiveHome); + pb.environment().put("HIVE_PLUGIN_ROOT_DIR", pluginHome); + Process p = pb.start(); + BufferedReader is = + new BufferedReader(new InputStreamReader(p.getInputStream())); + BufferedReader es = + new BufferedReader(new InputStreamReader(p.getErrorStream())); + 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(); + output.append("NO OUTPUT! Error dump:"); + 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 { + HivePdkUnitTests unitTests; + + PluginTestSetup(Test test, HivePdkUnitTests unitTests) { + super(test); + this.unitTests = unitTests; + } + + protected void setUp() throws Exception { + String cleanup = unitTests.cleanup(); + String setup = unitTests.setup(); + if ((cleanup != null) || (setup != null)) { + if (cleanup == null) { + cleanup = ""; + } + if (setup == null) { + setup = ""; + } + runHive( + "-e", + cleanup + "\n" + setup); + } + } + + protected void tearDown() throws Exception { + String cleanup = unitTests.cleanup(); + if (cleanup != null) { + runHive( + "-e", + cleanup); + } + } + } + + public static class PluginGlobalSetup extends TestSetup { + + PluginGlobalSetup(Test test) { + super(test); + } + + protected void setUp() throws Exception { + runHive( + "-i", + "../test/cleanup.sql", + "-f", + "../test/setup.sql"); + } + + protected void tearDown() throws Exception { + runHive( + "-f", + "../test/cleanup.sql"); + } + } +} Index: pdk/test-plugin/test/cleanup.sql =================================================================== --- pdk/test-plugin/test/cleanup.sql (revision 0) +++ pdk/test-plugin/test/cleanup.sql (revision 0) @@ -0,0 +1 @@ +drop table if exists onerow; Index: pdk/test-plugin/test/onerow.txt =================================================================== --- pdk/test-plugin/test/onerow.txt (revision 0) +++ pdk/test-plugin/test/onerow.txt (revision 0) @@ -0,0 +1 @@ +plugh Index: pdk/test-plugin/test/setup.sql =================================================================== --- pdk/test-plugin/test/setup.sql (revision 0) +++ pdk/test-plugin/test/setup.sql (revision 0) @@ -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; Index: pdk/test-plugin/src/org/apache/hive/pdktest/Rot13.java =================================================================== --- pdk/test-plugin/src/org/apache/hive/pdktest/Rot13.java (revision 0) +++ pdk/test-plugin/src/org/apache/hive/pdktest/Rot13.java (revision 0) @@ -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; + } +} Index: pdk/test-plugin/build.xml =================================================================== --- pdk/test-plugin/build.xml (revision 0) +++ pdk/test-plugin/build.xml (revision 0) @@ -0,0 +1,27 @@ + + + + + + + + + + + + Index: pdk/build.xml =================================================================== --- pdk/build.xml (revision 0) +++ pdk/build.xml (revision 0) @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +