HAWQ-814. Enhance user-defined function by migrating create_function_1 of UDF 
from installcheck to new feature test framework


Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/49fd529a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/49fd529a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/49fd529a

Branch: refs/heads/master
Commit: 49fd529aa01d54199465639060c01577bca06981
Parents: c66cfba
Author: Ruilong Huo <r...@pivotal.io>
Authored: Tue Jun 28 09:49:05 2016 +0800
Committer: Ruilong Huo <r...@pivotal.io>
Committed: Tue Jul 5 09:40:03 2016 +0800

----------------------------------------------------------------------
 src/test/feature/Makefile                       |   12 +-
 src/test/feature/UDF/TestUDF.cpp                |   63 +
 .../feature/UDF/ans/function_basics.ans.orca    | 1088 +++++++++++++++
 .../feature/UDF/ans/function_basics.ans.planner | 1076 +++++++++++++++
 .../UDF/ans/function_creation.ans.source        |   96 ++
 src/test/feature/UDF/ans/function_extension.ans |  183 +++
 .../feature/UDF/ans/function_set_returning.ans  |  287 ++++
 src/test/feature/UDF/lib/Makefile               |   43 +
 src/test/feature/UDF/lib/function.c             | 1245 ++++++++++++++++++
 src/test/feature/UDF/sql/function_basics.sql    |  439 ++++++
 .../UDF/sql/function_creation.sql.source        |   79 ++
 src/test/feature/UDF/sql/function_extension.sql |  123 ++
 .../feature/UDF/sql/function_set_returning.sql  |   93 ++
 src/test/feature/udf/TestUDF.cpp                |   32 -
 src/test/feature/udf/ans/function_basics.ans    | 1088 ---------------
 src/test/feature/udf/ans/function_extension.ans |  183 ---
 .../feature/udf/ans/function_set_returning.ans  |  287 ----
 src/test/feature/udf/sql/function_basics.sql    |  439 ------
 src/test/feature/udf/sql/function_extension.sql |  123 --
 .../feature/udf/sql/function_set_returning.sql  |   93 --
 20 files changed, 4824 insertions(+), 2248 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/49fd529a/src/test/feature/Makefile
----------------------------------------------------------------------
diff --git a/src/test/feature/Makefile b/src/test/feature/Makefile
index 82a3dc3..e97716c 100644
--- a/src/test/feature/Makefile
+++ b/src/test/feature/Makefile
@@ -15,16 +15,22 @@ override LDFLAGS += -L/usr/local/lib -L/usr/lib 
-L$(abs_top_srcdir)/src/test/fea
 PROG = test_main.cpp $(wildcard */*.cpp)
 RM = rm -rf
 
-.PHONY: all distclean clean doc
+.PHONY: all sharelib sharelibclean distclean clean doc
 
-all:
+all: sharelib
        $(MAKE) -C lib all
        $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(PROG) $(LDFLAGS) $(LIBS) -o 
feature-test
 
+sharelib:
+       cd UDF/lib || exit 1; $(MAKE) || exit 2; $(MAKE) clean || exit 3
+
+sharelibclean:
+       cd UDF/lib || exit 1; $(RM) *.o *.so || exit 2
+
 doc:
        doxygen doxygen_template
 
-clean distclean:
+clean distclean: sharelibclean
        $(RM) feature-test
        $(RM) feature-test.dSYM
        $(RM) doc

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/49fd529a/src/test/feature/UDF/TestUDF.cpp
----------------------------------------------------------------------
diff --git a/src/test/feature/UDF/TestUDF.cpp b/src/test/feature/UDF/TestUDF.cpp
new file mode 100755
index 0000000..ce7f158
--- /dev/null
+++ b/src/test/feature/UDF/TestUDF.cpp
@@ -0,0 +1,63 @@
+#include "gtest/gtest.h"
+
+#include "lib/sql_util.h"
+#include "lib/file_replace.h"
+
+
+class TestUDF: public ::testing::Test
+{
+       public:
+               TestUDF() {}
+               ~TestUDF() {}
+};
+
+TEST_F(TestUDF, TestUDFBasics)
+{
+       hawq::test::SQLUtility util;
+       if (util.getGUCValue("optimizer") == "on")
+       {
+               util.execSQLFile("UDF/sql/function_basics.sql",
+                                "UDF/ans/function_basics.ans.orca");
+       }
+       else
+       {
+               util.execSQLFile("UDF/sql/function_basics.sql",
+                                "UDF/ans/function_basics.ans.planner");
+       }
+}
+
+TEST_F(TestUDF, TestUDFCreation)
+{
+       // preprocess source files to get sql/ans files
+       hawq::test::SQLUtility util;
+       std::string d_feature_test_root(util.getTestRootPath());
+       std::string f_sql_tpl(d_feature_test_root + 
"/UDF/sql/function_creation.sql.source");
+       std::string f_ans_tpl(d_feature_test_root + 
"/UDF/ans/function_creation.ans.source");
+       std::string f_sql(d_feature_test_root + 
"/UDF/sql/function_creation.sql");
+       std::string f_ans(d_feature_test_root + 
"/UDF/ans/function_creation.ans");
+
+       hawq::test::FileReplace frep;
+       std::unordered_map<std::string, std::string> strs_src_dst;
+       strs_src_dst["@SHARE_LIBRARY_PATH@"] = d_feature_test_root + 
"/UDF/lib/function.so";
+
+       frep.replace(f_sql_tpl, f_sql, strs_src_dst);
+       frep.replace(f_ans_tpl, f_ans, strs_src_dst);
+
+       // run sql file to get ans file and then diff it with out file
+       util.execSQLFile("UDF/sql/function_creation.sql",
+                        "UDF/ans/function_creation.ans");
+}
+
+TEST_F(TestUDF, TestUDFSetReturning)
+{
+       hawq::test::SQLUtility util;
+       util.execSQLFile("UDF/sql/function_set_returning.sql",
+                        "UDF/ans/function_set_returning.ans");
+}
+
+TEST_F(TestUDF, TestUDFExtension)
+{
+       hawq::test::SQLUtility util;
+       util.execSQLFile("UDF/sql/function_extension.sql",
+                        "UDF/ans/function_extension.ans");
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/49fd529a/src/test/feature/UDF/ans/function_basics.ans.orca
----------------------------------------------------------------------
diff --git a/src/test/feature/UDF/ans/function_basics.ans.orca 
b/src/test/feature/UDF/ans/function_basics.ans.orca
new file mode 100755
index 0000000..ff45af2
--- /dev/null
+++ b/src/test/feature/UDF/ans/function_basics.ans.orca
@@ -0,0 +1,1088 @@
+-- start_ignore
+SET SEARCH_PATH=TestUDF_TestUDFBasics;
+SET
+-- end_ignore
+-- SETUP
+DROP TABLE IF EXISTS foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:5: NOTICE:  table "foo" does not exist, 
skipping
+DROP TABLE
+CREATE TABLE foo AS SELECT * FROM generate_series(1, 10) x;
+SELECT 10
+CREATE FUNCTION f(x INT) RETURNS INT AS $$
+BEGIN
+RETURN x;
+END
+$$ LANGUAGE PLPGSQL;
+CREATE FUNCTION
+-- DDL, CREATE FUNCTION
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT $1' LANGUAGE SQL IMMUTABLE 
STRICT;
+CREATE FUNCTION
+SELECT proname FROM pg_proc WHERE proname = 'g';
+ proname 
+---------
+ g
+(1 row)
+
+SELECT proname FROM gp_dist_random('pg_proc') WHERE proname = 'g';
+ proname 
+---------
+(0 rows)
+
+DROP FUNCTION g(int);
+DROP FUNCTION
+-- DDL, CREATE OR REPLACE FUNCTION
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT $1' LANGUAGE SQL IMMUTABLE 
STRICT;
+CREATE FUNCTION
+SELECT proname FROM pg_proc WHERE proname = 'g';
+ proname 
+---------
+ g
+(1 row)
+
+SELECT proname FROM gp_dist_random('pg_proc') WHERE proname = 'g';
+ proname 
+---------
+(0 rows)
+
+CREATE OR REPLACE FUNCTION g(x INT) RETURNS INT AS $$
+BEGIN
+RETURN (-1) * x;
+END
+$$ LANGUAGE PLPGSQL;
+CREATE FUNCTION
+SELECT proname, prosrc FROM pg_proc WHERE proname = 'g';
+ proname |      prosrc      
+---------+------------------
+ g       |                  
+         : BEGIN            
+         : RETURN (-1) * x; 
+         : END              
+         : 
+(1 row)
+
+SELECT proname, prosrc FROM gp_dist_random('pg_proc') WHERE proname = 'g';
+ proname | prosrc 
+---------+--------
+(0 rows)
+
+DROP FUNCTION g(int);
+DROP FUNCTION
+-- DDL, DROP FUNCTION
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT $1' LANGUAGE SQL IMMUTABLE 
STRICT;
+CREATE FUNCTION
+DROP FUNCTION g(int);
+DROP FUNCTION
+SELECT oid, proname FROM pg_proc WHERE proname = 'g';
+ oid | proname 
+-----+---------
+(0 rows)
+
+SELECT oid, proname FROM gp_dist_random('pg_proc') WHERE proname = 'g';
+ oid | proname 
+-----+---------
+(0 rows)
+
+-- DDL, DROP FUNCTION, NEGATIVE
+DROP FUNCTION g(int);
+psql:/tmp/TestUDF_TestUDFBasics.sql:47: ERROR:  function g(integer) does not 
exist
+-- DDL, CREATE FUNCTION, RECORD
+CREATE FUNCTION foo(int) RETURNS record AS 'SELECT * FROM foo WHERE x=$1' 
LANGUAGE SQL;
+CREATE FUNCTION
+SELECT foo(5);
+ foo 
+-----
+ (5)
+(1 row)
+
+DROP FUNCTION foo(int);
+DROP FUNCTION
+CREATE FUNCTION foo(int) RETURNS foo AS 'SELECT * FROM foo WHERE x=$1' 
LANGUAGE SQL;
+CREATE FUNCTION
+SELECT foo(5);
+ foo 
+-----
+ (5)
+(1 row)
+
+DROP FUNCTION foo(int);
+DROP FUNCTION
+-- DDL, CREATE FUNCTION, SRF
+CREATE FUNCTION g(x setof int) RETURNS INT
+    AS $$ SELECT 1 $$ LANGUAGE SQL;
+CREATE FUNCTION
+DROP FUNCTION g(setof int);
+DROP FUNCTION
+CREATE FUNCTION g() RETURNS setof INT
+    AS $$ SELECT 1 $$ LANGUAGE SQL;
+CREATE FUNCTION
+DROP FUNCTION g();
+DROP FUNCTION
+-- DDL, CREATE FUNCTION, TABLE, NEGATIVE
+CREATE FUNCTION g() RETURNS TABLE(x int)
+    AS $$ SELECT * FROM foo $$ LANGUAGE SQL;
+CREATE FUNCTION
+DROP FUNCTION g();
+DROP FUNCTION
+CREATE FUNCTION g(anytable) RETURNS int
+    AS 'does_not_exist', 'does_not_exist' LANGUAGE C;
+psql:/tmp/TestUDF_TestUDFBasics.sql:76: ERROR:  TABLE functions not supported
+-- DDL, CREATE FUNCTION, SECURITY DEFINER
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT 1' LANGUAGE SQL IMMUTABLE 
SECURITY DEFINER;
+CREATE FUNCTION
+DROP FUNCTION g(int);
+DROP FUNCTION
+-- DDL, ALTER FUNCTION
+-- DDL, STRICT
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT 1' LANGUAGE SQL IMMUTABLE;
+CREATE FUNCTION
+SELECT g(NULL);
+ g 
+---
+ 1
+(1 row)
+
+ALTER FUNCTION g(int) STRICT;
+ALTER FUNCTION
+SELECT g(NULL);
+ g 
+---
+  
+(1 row)
+
+DROP FUNCTION g(int);
+DROP FUNCTION
+-- DDL, ALTER FUNCTION, OWNER
+CREATE ROLE superuser SUPERUSER;
+CREATE ROLE
+CREATE ROLE u1;
+psql:/tmp/TestUDF_TestUDFBasics.sql:97: NOTICE:  resource queue required -- 
using default resource queue "pg_default"
+CREATE ROLE
+SET ROLE superuser;
+SET
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT 1' LANGUAGE SQL IMMUTABLE;
+CREATE FUNCTION
+SELECT a.rolname FROM pg_proc p, pg_authid a where p.proowner = a.oid and 
proname = 'g';
+  rolname  
+-----------
+ superuser
+(1 row)
+
+ALTER FUNCTION g(int) OWNER TO u1;
+ALTER FUNCTION
+SELECT a.rolname FROM pg_proc p, pg_authid a where p.proowner = a.oid and 
proname = 'g';
+ rolname 
+---------
+ u1
+(1 row)
+
+DROP FUNCTION g(int);
+DROP FUNCTION
+RESET ROLE;
+RESET
+DROP ROLE u1;
+DROP ROLE
+DROP ROLE superuser;
+DROP ROLE
+-- DDL, ALTER FUNCTION, RENAME
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT 1' LANGUAGE SQL IMMUTABLE;
+CREATE FUNCTION
+SELECT g(0);
+ g 
+---
+ 1
+(1 row)
+
+ALTER FUNCTION g(int) RENAME TO h;
+ALTER FUNCTION
+SELECT h(0);
+ h 
+---
+ 1
+(1 row)
+
+DROP FUNCTION h(int);
+DROP FUNCTION
+-- DDL, ALTER FUNCTION, SET SCHEMA
+CREATE SCHEMA bar;
+CREATE SCHEMA
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT 1' LANGUAGE SQL IMMUTABLE;
+CREATE FUNCTION
+SELECT g(0);
+ g 
+---
+ 1
+(1 row)
+
+ALTER FUNCTION g(int) SET SCHEMA bar;
+ALTER FUNCTION
+SELECT bar.g(0);
+ g 
+---
+ 1
+(1 row)
+
+DROP SCHEMA bar CASCADE;
+psql:/tmp/TestUDF_TestUDFBasics.sql:125: NOTICE:  drop cascades to function 
bar.g(integer)
+DROP SCHEMA
+-- DDL, ALTER FUNCTION, SECURITY DEFINER
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT 1' LANGUAGE SQL IMMUTABLE;
+CREATE FUNCTION
+ALTER FUNCTION g(int) SECURITY DEFINER;
+ALTER FUNCTION
+DROP FUNCTION g(int); 
+DROP FUNCTION
+-- DCL, GRANT/REVOKE
+-- GRANT { EXECUTE | ALL [ PRIVILEGES ] }
+--    ON FUNCTION funcname ( [ [ argmode ] [ argname ] argtype [, ...] ] ) [, 
...]
+--    TO { username | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ]
+-- REVOKE [ GRANT OPTION FOR ]
+--    { EXECUTE | ALL [ PRIVILEGES ] }
+--    ON FUNCTION funcname ( [ [ argmode ] [ argname ] argtype [, ...] ] ) [, 
...]
+--    FROM { username | GROUP groupname | PUBLIC } [, ...]
+--    [ CASCADE | RESTRICT ]
+-- DCL, GRANT/REVOKE, EXECUTE
+CREATE ROLE superuser SUPERUSER;
+CREATE ROLE
+SET ROLE superuser;
+SET
+CREATE ROLE u1;
+psql:/tmp/TestUDF_TestUDFBasics.sql:149: NOTICE:  resource queue required -- 
using default resource queue "pg_default"
+CREATE ROLE
+GRANT SELECT ON TABLE foo TO u1;
+GRANT
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT $1' LANGUAGE SQL IMMUTABLE 
STRICT;
+CREATE FUNCTION
+SELECT proacl FROM pg_proc where proname = 'g';
+ proacl 
+--------
+ 
+(1 row)
+
+REVOKE ALL ON FUNCTION g(int) FROM PUBLIC;
+REVOKE
+SELECT proacl FROM pg_proc where proname = 'g';
+         proacl          
+-------------------------
+ {superuser=X/superuser}
+(1 row)
+
+SELECT g(1);
+ g 
+---
+ 1
+(1 row)
+
+SELECT count(g(x)) FROM foo;
+ count 
+-------
+    10
+(1 row)
+
+SET ROLE u1;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:158: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:159: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE superuser;
+SET
+GRANT EXECUTE ON FUNCTION g(int) TO u1;
+GRANT
+SELECT proacl FROM pg_proc where proname = 'g';
+                 proacl                 
+----------------------------------------
+ {superuser=X/superuser,u1=X/superuser}
+(1 row)
+
+SET ROLE u1;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:164: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:165: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE superuser;
+SET
+REVOKE EXECUTE ON FUNCTION g(int) FROM u1;
+REVOKE
+SELECT proacl FROM pg_proc where proname = 'g';
+         proacl          
+-------------------------
+ {superuser=X/superuser}
+(1 row)
+
+SET ROLE u1;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:170: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:171: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+RESET ROLE;
+RESET
+DROP FUNCTION g(int);
+DROP FUNCTION
+REVOKE SELECT ON TABLE foo FROM u1;
+REVOKE
+DROP ROLE u1;
+DROP ROLE
+DROP ROLE superuser;
+DROP ROLE
+-- DCL, GRANT/REVOKE, PUBLIC
+CREATE ROLE superuser SUPERUSER;
+CREATE ROLE
+SET ROLE superuser;
+SET
+CREATE ROLE u1;
+psql:/tmp/TestUDF_TestUDFBasics.sql:183: NOTICE:  resource queue required -- 
using default resource queue "pg_default"
+CREATE ROLE
+GRANT SELECT ON TABLE foo TO u1;
+GRANT
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT $1' LANGUAGE SQL IMMUTABLE 
STRICT;
+CREATE FUNCTION
+SELECT proacl FROM pg_proc where proname = 'g';
+ proacl 
+--------
+ 
+(1 row)
+
+REVOKE ALL ON FUNCTION g(int) FROM PUBLIC;
+REVOKE
+SELECT proacl FROM pg_proc where proname = 'g';
+         proacl          
+-------------------------
+ {superuser=X/superuser}
+(1 row)
+
+SELECT g(1);
+ g 
+---
+ 1
+(1 row)
+
+SELECT count(g(x)) FROM foo;
+ count 
+-------
+    10
+(1 row)
+
+SET ROLE u1;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:192: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:193: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE superuser;
+SET
+GRANT EXECUTE ON FUNCTION g(int) TO PUBLIC;
+GRANT
+SELECT proacl FROM pg_proc where proname = 'g';
+                proacl                
+--------------------------------------
+ {superuser=X/superuser,=X/superuser}
+(1 row)
+
+SET ROLE u1;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:198: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:199: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE superuser;
+SET
+REVOKE EXECUTE ON FUNCTION g(int) FROM PUBLIC;
+REVOKE
+SELECT proacl FROM pg_proc where proname = 'g';
+         proacl          
+-------------------------
+ {superuser=X/superuser}
+(1 row)
+
+SET ROLE u1;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:204: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:205: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+RESET ROLE;
+RESET
+DROP FUNCTION g(int);
+DROP FUNCTION
+REVOKE SELECT ON TABLE foo FROM u1;
+REVOKE
+DROP ROLE u1;
+DROP ROLE
+DROP ROLE superuser;
+DROP ROLE
+-- DCL, GRANT/REVOKE, Groups
+CREATE ROLE superuser SUPERUSER;
+CREATE ROLE
+SET ROLE superuser;
+SET
+CREATE ROLE u1;
+psql:/tmp/TestUDF_TestUDFBasics.sql:217: NOTICE:  resource queue required -- 
using default resource queue "pg_default"
+CREATE ROLE
+CREATE ROLE u2 IN GROUP u1;
+psql:/tmp/TestUDF_TestUDFBasics.sql:218: NOTICE:  resource queue required -- 
using default resource queue "pg_default"
+CREATE ROLE
+GRANT SELECT ON TABLE foo TO u1;
+GRANT
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT $1' LANGUAGE SQL IMMUTABLE 
STRICT;
+CREATE FUNCTION
+SELECT proacl FROM pg_proc where proname = 'g';
+ proacl 
+--------
+ 
+(1 row)
+
+REVOKE ALL ON FUNCTION g(int) FROM PUBLIC;
+REVOKE
+SELECT proacl FROM pg_proc where proname = 'g';
+         proacl          
+-------------------------
+ {superuser=X/superuser}
+(1 row)
+
+SELECT g(1);
+ g 
+---
+ 1
+(1 row)
+
+SELECT count(g(x)) FROM foo;
+ count 
+-------
+    10
+(1 row)
+
+SET ROLE u2;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:227: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:228: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE superuser;
+SET
+GRANT EXECUTE ON FUNCTION g(int) TO u1;
+GRANT
+SELECT proacl FROM pg_proc where proname = 'g';
+                 proacl                 
+----------------------------------------
+ {superuser=X/superuser,u1=X/superuser}
+(1 row)
+
+SET ROLE u2;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:233: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:234: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE superuser;
+SET
+REVOKE EXECUTE ON FUNCTION g(int) FROM u1;
+REVOKE
+SELECT proacl FROM pg_proc where proname = 'g';
+         proacl          
+-------------------------
+ {superuser=X/superuser}
+(1 row)
+
+SET ROLE u2;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:239: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:240: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+RESET ROLE;
+RESET
+DROP FUNCTION g(int);
+DROP FUNCTION
+REVOKE SELECT ON TABLE foo FROM u1;
+REVOKE
+DROP ROLE u1;
+DROP ROLE
+DROP ROLE u2;
+DROP ROLE
+DROP ROLE superuser;
+DROP ROLE
+-- DCL, GRANT/REVOKE, WITH GRANT OPTION
+CREATE ROLE superuser SUPERUSER;
+CREATE ROLE
+SET ROLE superuser;
+SET
+CREATE ROLE u1;
+psql:/tmp/TestUDF_TestUDFBasics.sql:253: NOTICE:  resource queue required -- 
using default resource queue "pg_default"
+CREATE ROLE
+CREATE ROLE u2;
+psql:/tmp/TestUDF_TestUDFBasics.sql:254: NOTICE:  resource queue required -- 
using default resource queue "pg_default"
+CREATE ROLE
+GRANT SELECT ON TABLE foo TO PUBLIC;
+GRANT
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT $1' LANGUAGE SQL IMMUTABLE 
STRICT;
+CREATE FUNCTION
+SELECT proacl FROM pg_proc where proname = 'g';
+ proacl 
+--------
+ 
+(1 row)
+
+REVOKE ALL ON FUNCTION g(int) FROM PUBLIC;
+REVOKE
+SELECT proacl FROM pg_proc where proname = 'g';
+         proacl          
+-------------------------
+ {superuser=X/superuser}
+(1 row)
+
+SELECT g(1);
+ g 
+---
+ 1
+(1 row)
+
+SELECT count(g(x)) FROM foo;
+ count 
+-------
+    10
+(1 row)
+
+SET ROLE u2;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:263: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:264: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE superuser;
+SET
+GRANT ALL ON FUNCTION g(int) TO u1 WITH GRANT OPTION;
+GRANT
+SET ROLE u1;
+SET
+GRANT ALL ON FUNCTION g(int) TO u2;
+psql:/tmp/TestUDF_TestUDFBasics.sql:268: ERROR:  function g(integer) does not 
exist
+SELECT proacl FROM pg_proc where proname = 'g';
+                 proacl                  
+-----------------------------------------
+ {superuser=X/superuser,u1=X*/superuser}
+(1 row)
+
+SET ROLE u1;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:271: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:272: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE u2;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:274: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:275: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE superuser;
+SET
+REVOKE ALL ON FUNCTION g(int) FROM u1 CASCADE;
+REVOKE
+SELECT proacl FROM pg_proc where proname = 'g';
+         proacl          
+-------------------------
+ {superuser=X/superuser}
+(1 row)
+
+SET ROLE u1;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:280: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:281: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE u2;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:283: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:284: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+RESET ROLE;
+RESET
+DROP FUNCTION g(int);
+DROP FUNCTION
+REVOKE SELECT ON TABLE foo FROM PUBLIC;
+REVOKE
+DROP ROLE u1;
+DROP ROLE
+DROP ROLE u2;
+DROP ROLE
+DROP ROLE superuser;
+DROP ROLE
+-- DML, CaseExpr
+SELECT CASE WHEN x % 2 = 0 THEN f(x) ELSE 0 END FROM foo ORDER BY x;
+ case 
+------
+    0
+    2
+    0
+    4
+    0
+    6
+    0
+    8
+    0
+   10
+(10 rows)
+
+-- DML, OpExpr
+SELECT f(x) + f(x) FROM foo ORDER BY x;
+ ?column? 
+----------
+        2
+        4
+        6
+        8
+       10
+       12
+       14
+       16
+       18
+       20
+(10 rows)
+
+SELECT f(x) + f(x) + f(x) FROM foo ORDER BY x;
+ ?column? 
+----------
+        3
+        6
+        9
+       12
+       15
+       18
+       21
+       24
+       27
+       30
+(10 rows)
+
+SELECT f(x) + f(x) - f(x) FROM foo ORDER BY x;
+ ?column? 
+----------
+        1
+        2
+        3
+        4
+        5
+        6
+        7
+        8
+        9
+       10
+(10 rows)
+
+-- DML, FuncExpr
+CREATE FUNCTION g(x INT) RETURNS INT AS $$
+BEGIN
+RETURN x;
+END
+$$ LANGUAGE PLPGSQL;
+CREATE FUNCTION
+SELECT g(f(x)) FROM foo ORDER BY x;
+ g  
+----
+  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+(10 rows)
+
+DROP FUNCTION g(int);
+DROP FUNCTION
+-- DML, BoolExpr
+SELECT x % 2 = 0 AND f(x) % 2 = 1 FROM foo ORDER BY x;
+ ?column? 
+----------
+ f
+ f
+ f
+ f
+ f
+ f
+ f
+ f
+ f
+ f
+(10 rows)
+
+-- DML, DistinctExpr
+SELECT x IS DISTINCT FROM f(x) from foo ORDER BY x;
+ ?column? 
+----------
+ f
+ f
+ f
+ f
+ f
+ f
+ f
+ f
+ f
+ f
+(10 rows)
+
+-- DML, PercentileExpr
+SELECT MEDIAN(f(x)) FROM foo;
+ median 
+--------
+    5.5
+(1 row)
+
+-- DML, Complex Expression
+CREATE FUNCTION g(x INT) RETURNS INT AS $$
+BEGIN
+RETURN x;
+END
+$$ LANGUAGE PLPGSQL;
+CREATE FUNCTION
+SELECT CASE
+       WHEN x % 2 = 0 THEN g(g(x)) + g(g(x))
+       WHEN f(x) % 2 = 1 THEN g(g(x)) - g(g(x))
+       END FROM foo ORDER BY x;
+ case 
+------
+    0
+    4
+    0
+    8
+    0
+   12
+    0
+   16
+    0
+   20
+(10 rows)
+
+DROP FUNCTION g(int);
+DROP FUNCTION
+-- DML, Qual
+SELECT x FROM foo WHERE f(x) % 2 = 0 ORDER BY x;
+ x  
+----
+  2
+  4
+  6
+  8
+ 10
+(5 rows)
+
+-- DML, FROM
+SELECT * FROM f(5);
+ f 
+---
+ 5
+(1 row)
+
+-- DML, Grouping
+SELECT DISTINCT f(x) FROM foo ORDER BY f(x);
+ f  
+----
+  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+(10 rows)
+
+SELECT f(x) FROM foo GROUP BY f(x) ORDER BY f(x);
+ f  
+----
+  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+(10 rows)
+
+-- DML, Join
+SELECT a.x FROM foo a, foo b WHERE f(a.x) = f(b.x) ORDER BY x;
+ x  
+----
+  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+(10 rows)
+
+SELECT a.x FROM foo a JOIN foo b ON f(a.x) = f(b.x) ORDER BY x;
+ x  
+----
+  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+(10 rows)
+
+-- DML, Windowing
+SELECT avg(x) OVER (PARTITION BY f(x)) FROM foo ORDER BY x;
+ avg 
+-----
+   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+(10 rows)
+
+-- DML, CTE
+WITH t AS (SELECT x from foo)
+       SELECT f(x) from t ORDER BY x;
+ f  
+----
+  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+(10 rows)
+
+-- DML, InitPlan
+SELECT UNNEST(ARRAY(SELECT x FROM foo)) ORDER BY 1;
+ unnest 
+--------
+      1
+      2
+      3
+      4
+      5
+      6
+      7
+      8
+      9
+     10
+(10 rows)
+
+SELECT UNNEST(ARRAY(SELECT f(1)));
+ unnest 
+--------
+      1
+(1 row)
+
+-- PROPERTIES, VOLATILITY, IMMUTABLE
+CREATE FUNCTION g() RETURNS float AS 'SELECT random();' LANGUAGE SQL IMMUTABLE;
+CREATE FUNCTION
+SELECT COUNT(DISTINCT(g())) > 1 FROM foo;
+ ?column? 
+----------
+ f
+(1 row)
+
+DROP FUNCTION g();
+DROP FUNCTION
+-- PROPERTIES, VOLATILITY, STABLE
+CREATE FUNCTION g() RETURNS float AS 'SELECT random();' LANGUAGE SQL STABLE;
+CREATE FUNCTION
+SELECT COUNT(DISTINCT(g())) > 1 FROM foo;
+ ?column? 
+----------
+ f
+(1 row)
+
+DROP FUNCTION g();
+DROP FUNCTION
+-- PROPERTIES, VOLATILITY, VOLATILE
+CREATE FUNCTION g() RETURNS float AS 'SELECT random();' LANGUAGE SQL VOLATILE;
+CREATE FUNCTION
+SELECT COUNT(DISTINCT(g())) > 1 FROM foo;
+ ?column? 
+----------
+ t
+(1 row)
+
+DROP FUNCTION g();
+DROP FUNCTION
+-----------------
+-- NEGATIVE TESTS
+-----------------
+SELECT h(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:405: ERROR:  function h(integer) does not 
exist
+LINE 1: SELECT h(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+-- DML, InitPlan
+SELECT UNNEST(ARRAY(SELECT f(x) from foo));
+ unnest 
+--------
+      1
+      2
+      3
+      4
+      5
+      6
+      7
+      8
+      9
+     10
+(10 rows)
+
+-- LANGUAGES not yet supported
+-- CREATE LANGUAGE plr;
+-- CREATE LANGUAGE plpython;
+-- CREATE LANGUAGE pljava;
+-- CREATE LANGUAGE plperl;
+-- NESTED FUNCTION
+CREATE FUNCTION inner(int) RETURNS INTEGER AS 'SELECT 1' LANGUAGE SQL 
IMMUTABLE;
+CREATE FUNCTION
+CREATE FUNCTION outer(x INT) RETURNS INT AS $$
+BEGIN
+RETURN inner(x);
+END
+$$ LANGUAGE PLPGSQL;
+CREATE FUNCTION
+SELECT outer(0);
+ outer 
+-------
+     1
+(1 row)
+
+SELECT outer(0) FROM foo;
+ outer 
+-------
+     1
+     1
+     1
+     1
+     1
+     1
+     1
+     1
+     1
+     1
+(10 rows)
+
+DROP FUNCTION outer(int);
+DROP FUNCTION
+DROP FUNCTION inner(int);
+DROP FUNCTION
+-- TEARDOWN
+DROP TABLE foo;
+DROP TABLE
+-- HAWQ-510
+drop table if exists testEntryDB;
+psql:/tmp/TestUDF_TestUDFBasics.sql:435: NOTICE:  table "testentrydb" does not 
exist, skipping
+DROP TABLE
+create table testEntryDB(key int, value int) distributed randomly;
+CREATE TABLE
+insert into testEntryDB values(1, 0);
+INSERT 0 1
+select t2.key, t2.value
+from   (select key, value from testEntryDB where value = 0) as t1,
+       (select generate_series(1,2)::int as key, 0::int as value) as t2
+where  t1.value=t2.value;
+ key | value 
+-----+-------
+   1 |     0
+   2 |     0
+(2 rows)
+
+drop table testEntryDB;
+DROP TABLE

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/49fd529a/src/test/feature/UDF/ans/function_basics.ans.planner
----------------------------------------------------------------------
diff --git a/src/test/feature/UDF/ans/function_basics.ans.planner 
b/src/test/feature/UDF/ans/function_basics.ans.planner
new file mode 100755
index 0000000..763223f
--- /dev/null
+++ b/src/test/feature/UDF/ans/function_basics.ans.planner
@@ -0,0 +1,1076 @@
+-- start_ignore
+SET SEARCH_PATH=TestUDF_TestUDFBasics;
+SET
+-- end_ignore
+-- SETUP
+DROP TABLE IF EXISTS foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:5: NOTICE:  table "foo" does not exist, 
skipping
+DROP TABLE
+CREATE TABLE foo AS SELECT * FROM generate_series(1, 10) x;
+SELECT 10
+CREATE FUNCTION f(x INT) RETURNS INT AS $$
+BEGIN
+RETURN x;
+END
+$$ LANGUAGE PLPGSQL;
+CREATE FUNCTION
+-- DDL, CREATE FUNCTION
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT $1' LANGUAGE SQL IMMUTABLE 
STRICT;
+CREATE FUNCTION
+SELECT proname FROM pg_proc WHERE proname = 'g';
+ proname 
+---------
+ g
+(1 row)
+
+SELECT proname FROM gp_dist_random('pg_proc') WHERE proname = 'g';
+ proname 
+---------
+(0 rows)
+
+DROP FUNCTION g(int);
+DROP FUNCTION
+-- DDL, CREATE OR REPLACE FUNCTION
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT $1' LANGUAGE SQL IMMUTABLE 
STRICT;
+CREATE FUNCTION
+SELECT proname FROM pg_proc WHERE proname = 'g';
+ proname 
+---------
+ g
+(1 row)
+
+SELECT proname FROM gp_dist_random('pg_proc') WHERE proname = 'g';
+ proname 
+---------
+(0 rows)
+
+CREATE OR REPLACE FUNCTION g(x INT) RETURNS INT AS $$
+BEGIN
+RETURN (-1) * x;
+END
+$$ LANGUAGE PLPGSQL;
+CREATE FUNCTION
+SELECT proname, prosrc FROM pg_proc WHERE proname = 'g';
+ proname |      prosrc      
+---------+------------------
+ g       |                  
+         : BEGIN            
+         : RETURN (-1) * x; 
+         : END              
+         : 
+(1 row)
+
+SELECT proname, prosrc FROM gp_dist_random('pg_proc') WHERE proname = 'g';
+ proname | prosrc 
+---------+--------
+(0 rows)
+
+DROP FUNCTION g(int);
+DROP FUNCTION
+-- DDL, DROP FUNCTION
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT $1' LANGUAGE SQL IMMUTABLE 
STRICT;
+CREATE FUNCTION
+DROP FUNCTION g(int);
+DROP FUNCTION
+SELECT oid, proname FROM pg_proc WHERE proname = 'g';
+ oid | proname 
+-----+---------
+(0 rows)
+
+SELECT oid, proname FROM gp_dist_random('pg_proc') WHERE proname = 'g';
+ oid | proname 
+-----+---------
+(0 rows)
+
+-- DDL, DROP FUNCTION, NEGATIVE
+DROP FUNCTION g(int);
+psql:/tmp/TestUDF_TestUDFBasics.sql:47: ERROR:  function g(integer) does not 
exist
+-- DDL, CREATE FUNCTION, RECORD
+CREATE FUNCTION foo(int) RETURNS record AS 'SELECT * FROM foo WHERE x=$1' 
LANGUAGE SQL;
+CREATE FUNCTION
+SELECT foo(5);
+ foo 
+-----
+ (5)
+(1 row)
+
+DROP FUNCTION foo(int);
+DROP FUNCTION
+CREATE FUNCTION foo(int) RETURNS foo AS 'SELECT * FROM foo WHERE x=$1' 
LANGUAGE SQL;
+CREATE FUNCTION
+SELECT foo(5);
+ foo 
+-----
+ (5)
+(1 row)
+
+DROP FUNCTION foo(int);
+DROP FUNCTION
+-- DDL, CREATE FUNCTION, SRF
+CREATE FUNCTION g(x setof int) RETURNS INT
+    AS $$ SELECT 1 $$ LANGUAGE SQL;
+CREATE FUNCTION
+DROP FUNCTION g(setof int);
+DROP FUNCTION
+CREATE FUNCTION g() RETURNS setof INT
+    AS $$ SELECT 1 $$ LANGUAGE SQL;
+CREATE FUNCTION
+DROP FUNCTION g();
+DROP FUNCTION
+-- DDL, CREATE FUNCTION, TABLE, NEGATIVE
+CREATE FUNCTION g() RETURNS TABLE(x int)
+    AS $$ SELECT * FROM foo $$ LANGUAGE SQL;
+CREATE FUNCTION
+DROP FUNCTION g();
+DROP FUNCTION
+CREATE FUNCTION g(anytable) RETURNS int
+    AS 'does_not_exist', 'does_not_exist' LANGUAGE C;
+psql:/tmp/TestUDF_TestUDFBasics.sql:76: ERROR:  TABLE functions not supported
+-- DDL, CREATE FUNCTION, SECURITY DEFINER
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT 1' LANGUAGE SQL IMMUTABLE 
SECURITY DEFINER;
+CREATE FUNCTION
+DROP FUNCTION g(int);
+DROP FUNCTION
+-- DDL, ALTER FUNCTION
+-- DDL, STRICT
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT 1' LANGUAGE SQL IMMUTABLE;
+CREATE FUNCTION
+SELECT g(NULL);
+ g 
+---
+ 1
+(1 row)
+
+ALTER FUNCTION g(int) STRICT;
+ALTER FUNCTION
+SELECT g(NULL);
+ g 
+---
+  
+(1 row)
+
+DROP FUNCTION g(int);
+DROP FUNCTION
+-- DDL, ALTER FUNCTION, OWNER
+CREATE ROLE superuser SUPERUSER;
+CREATE ROLE
+CREATE ROLE u1;
+psql:/tmp/TestUDF_TestUDFBasics.sql:97: NOTICE:  resource queue required -- 
using default resource queue "pg_default"
+CREATE ROLE
+SET ROLE superuser;
+SET
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT 1' LANGUAGE SQL IMMUTABLE;
+CREATE FUNCTION
+SELECT a.rolname FROM pg_proc p, pg_authid a where p.proowner = a.oid and 
proname = 'g';
+  rolname  
+-----------
+ superuser
+(1 row)
+
+ALTER FUNCTION g(int) OWNER TO u1;
+ALTER FUNCTION
+SELECT a.rolname FROM pg_proc p, pg_authid a where p.proowner = a.oid and 
proname = 'g';
+ rolname 
+---------
+ u1
+(1 row)
+
+DROP FUNCTION g(int);
+DROP FUNCTION
+RESET ROLE;
+RESET
+DROP ROLE u1;
+DROP ROLE
+DROP ROLE superuser;
+DROP ROLE
+-- DDL, ALTER FUNCTION, RENAME
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT 1' LANGUAGE SQL IMMUTABLE;
+CREATE FUNCTION
+SELECT g(0);
+ g 
+---
+ 1
+(1 row)
+
+ALTER FUNCTION g(int) RENAME TO h;
+ALTER FUNCTION
+SELECT h(0);
+ h 
+---
+ 1
+(1 row)
+
+DROP FUNCTION h(int);
+DROP FUNCTION
+-- DDL, ALTER FUNCTION, SET SCHEMA
+CREATE SCHEMA bar;
+CREATE SCHEMA
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT 1' LANGUAGE SQL IMMUTABLE;
+CREATE FUNCTION
+SELECT g(0);
+ g 
+---
+ 1
+(1 row)
+
+ALTER FUNCTION g(int) SET SCHEMA bar;
+ALTER FUNCTION
+SELECT bar.g(0);
+ g 
+---
+ 1
+(1 row)
+
+DROP SCHEMA bar CASCADE;
+psql:/tmp/TestUDF_TestUDFBasics.sql:125: NOTICE:  drop cascades to function 
bar.g(integer)
+DROP SCHEMA
+-- DDL, ALTER FUNCTION, SECURITY DEFINER
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT 1' LANGUAGE SQL IMMUTABLE;
+CREATE FUNCTION
+ALTER FUNCTION g(int) SECURITY DEFINER;
+ALTER FUNCTION
+DROP FUNCTION g(int); 
+DROP FUNCTION
+-- DCL, GRANT/REVOKE
+-- GRANT { EXECUTE | ALL [ PRIVILEGES ] }
+--    ON FUNCTION funcname ( [ [ argmode ] [ argname ] argtype [, ...] ] ) [, 
...]
+--    TO { username | GROUP groupname | PUBLIC } [, ...] [ WITH GRANT OPTION ]
+-- REVOKE [ GRANT OPTION FOR ]
+--    { EXECUTE | ALL [ PRIVILEGES ] }
+--    ON FUNCTION funcname ( [ [ argmode ] [ argname ] argtype [, ...] ] ) [, 
...]
+--    FROM { username | GROUP groupname | PUBLIC } [, ...]
+--    [ CASCADE | RESTRICT ]
+-- DCL, GRANT/REVOKE, EXECUTE
+CREATE ROLE superuser SUPERUSER;
+CREATE ROLE
+SET ROLE superuser;
+SET
+CREATE ROLE u1;
+psql:/tmp/TestUDF_TestUDFBasics.sql:149: NOTICE:  resource queue required -- 
using default resource queue "pg_default"
+CREATE ROLE
+GRANT SELECT ON TABLE foo TO u1;
+GRANT
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT $1' LANGUAGE SQL IMMUTABLE 
STRICT;
+CREATE FUNCTION
+SELECT proacl FROM pg_proc where proname = 'g';
+ proacl 
+--------
+ 
+(1 row)
+
+REVOKE ALL ON FUNCTION g(int) FROM PUBLIC;
+REVOKE
+SELECT proacl FROM pg_proc where proname = 'g';
+         proacl          
+-------------------------
+ {superuser=X/superuser}
+(1 row)
+
+SELECT g(1);
+ g 
+---
+ 1
+(1 row)
+
+SELECT count(g(x)) FROM foo;
+ count 
+-------
+    10
+(1 row)
+
+SET ROLE u1;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:158: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:159: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE superuser;
+SET
+GRANT EXECUTE ON FUNCTION g(int) TO u1;
+GRANT
+SELECT proacl FROM pg_proc where proname = 'g';
+                 proacl                 
+----------------------------------------
+ {superuser=X/superuser,u1=X/superuser}
+(1 row)
+
+SET ROLE u1;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:164: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:165: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE superuser;
+SET
+REVOKE EXECUTE ON FUNCTION g(int) FROM u1;
+REVOKE
+SELECT proacl FROM pg_proc where proname = 'g';
+         proacl          
+-------------------------
+ {superuser=X/superuser}
+(1 row)
+
+SET ROLE u1;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:170: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:171: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+RESET ROLE;
+RESET
+DROP FUNCTION g(int);
+DROP FUNCTION
+REVOKE SELECT ON TABLE foo FROM u1;
+REVOKE
+DROP ROLE u1;
+DROP ROLE
+DROP ROLE superuser;
+DROP ROLE
+-- DCL, GRANT/REVOKE, PUBLIC
+CREATE ROLE superuser SUPERUSER;
+CREATE ROLE
+SET ROLE superuser;
+SET
+CREATE ROLE u1;
+psql:/tmp/TestUDF_TestUDFBasics.sql:183: NOTICE:  resource queue required -- 
using default resource queue "pg_default"
+CREATE ROLE
+GRANT SELECT ON TABLE foo TO u1;
+GRANT
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT $1' LANGUAGE SQL IMMUTABLE 
STRICT;
+CREATE FUNCTION
+SELECT proacl FROM pg_proc where proname = 'g';
+ proacl 
+--------
+ 
+(1 row)
+
+REVOKE ALL ON FUNCTION g(int) FROM PUBLIC;
+REVOKE
+SELECT proacl FROM pg_proc where proname = 'g';
+         proacl          
+-------------------------
+ {superuser=X/superuser}
+(1 row)
+
+SELECT g(1);
+ g 
+---
+ 1
+(1 row)
+
+SELECT count(g(x)) FROM foo;
+ count 
+-------
+    10
+(1 row)
+
+SET ROLE u1;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:192: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:193: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE superuser;
+SET
+GRANT EXECUTE ON FUNCTION g(int) TO PUBLIC;
+GRANT
+SELECT proacl FROM pg_proc where proname = 'g';
+                proacl                
+--------------------------------------
+ {superuser=X/superuser,=X/superuser}
+(1 row)
+
+SET ROLE u1;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:198: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:199: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE superuser;
+SET
+REVOKE EXECUTE ON FUNCTION g(int) FROM PUBLIC;
+REVOKE
+SELECT proacl FROM pg_proc where proname = 'g';
+         proacl          
+-------------------------
+ {superuser=X/superuser}
+(1 row)
+
+SET ROLE u1;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:204: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:205: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+RESET ROLE;
+RESET
+DROP FUNCTION g(int);
+DROP FUNCTION
+REVOKE SELECT ON TABLE foo FROM u1;
+REVOKE
+DROP ROLE u1;
+DROP ROLE
+DROP ROLE superuser;
+DROP ROLE
+-- DCL, GRANT/REVOKE, Groups
+CREATE ROLE superuser SUPERUSER;
+CREATE ROLE
+SET ROLE superuser;
+SET
+CREATE ROLE u1;
+psql:/tmp/TestUDF_TestUDFBasics.sql:217: NOTICE:  resource queue required -- 
using default resource queue "pg_default"
+CREATE ROLE
+CREATE ROLE u2 IN GROUP u1;
+psql:/tmp/TestUDF_TestUDFBasics.sql:218: NOTICE:  resource queue required -- 
using default resource queue "pg_default"
+CREATE ROLE
+GRANT SELECT ON TABLE foo TO u1;
+GRANT
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT $1' LANGUAGE SQL IMMUTABLE 
STRICT;
+CREATE FUNCTION
+SELECT proacl FROM pg_proc where proname = 'g';
+ proacl 
+--------
+ 
+(1 row)
+
+REVOKE ALL ON FUNCTION g(int) FROM PUBLIC;
+REVOKE
+SELECT proacl FROM pg_proc where proname = 'g';
+         proacl          
+-------------------------
+ {superuser=X/superuser}
+(1 row)
+
+SELECT g(1);
+ g 
+---
+ 1
+(1 row)
+
+SELECT count(g(x)) FROM foo;
+ count 
+-------
+    10
+(1 row)
+
+SET ROLE u2;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:227: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:228: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE superuser;
+SET
+GRANT EXECUTE ON FUNCTION g(int) TO u1;
+GRANT
+SELECT proacl FROM pg_proc where proname = 'g';
+                 proacl                 
+----------------------------------------
+ {superuser=X/superuser,u1=X/superuser}
+(1 row)
+
+SET ROLE u2;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:233: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:234: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE superuser;
+SET
+REVOKE EXECUTE ON FUNCTION g(int) FROM u1;
+REVOKE
+SELECT proacl FROM pg_proc where proname = 'g';
+         proacl          
+-------------------------
+ {superuser=X/superuser}
+(1 row)
+
+SET ROLE u2;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:239: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:240: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+RESET ROLE;
+RESET
+DROP FUNCTION g(int);
+DROP FUNCTION
+REVOKE SELECT ON TABLE foo FROM u1;
+REVOKE
+DROP ROLE u1;
+DROP ROLE
+DROP ROLE u2;
+DROP ROLE
+DROP ROLE superuser;
+DROP ROLE
+-- DCL, GRANT/REVOKE, WITH GRANT OPTION
+CREATE ROLE superuser SUPERUSER;
+CREATE ROLE
+SET ROLE superuser;
+SET
+CREATE ROLE u1;
+psql:/tmp/TestUDF_TestUDFBasics.sql:253: NOTICE:  resource queue required -- 
using default resource queue "pg_default"
+CREATE ROLE
+CREATE ROLE u2;
+psql:/tmp/TestUDF_TestUDFBasics.sql:254: NOTICE:  resource queue required -- 
using default resource queue "pg_default"
+CREATE ROLE
+GRANT SELECT ON TABLE foo TO PUBLIC;
+GRANT
+CREATE FUNCTION g(int) RETURNS INTEGER AS 'SELECT $1' LANGUAGE SQL IMMUTABLE 
STRICT;
+CREATE FUNCTION
+SELECT proacl FROM pg_proc where proname = 'g';
+ proacl 
+--------
+ 
+(1 row)
+
+REVOKE ALL ON FUNCTION g(int) FROM PUBLIC;
+REVOKE
+SELECT proacl FROM pg_proc where proname = 'g';
+         proacl          
+-------------------------
+ {superuser=X/superuser}
+(1 row)
+
+SELECT g(1);
+ g 
+---
+ 1
+(1 row)
+
+SELECT count(g(x)) FROM foo;
+ count 
+-------
+    10
+(1 row)
+
+SET ROLE u2;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:263: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:264: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE superuser;
+SET
+GRANT ALL ON FUNCTION g(int) TO u1 WITH GRANT OPTION;
+GRANT
+SET ROLE u1;
+SET
+GRANT ALL ON FUNCTION g(int) TO u2;
+psql:/tmp/TestUDF_TestUDFBasics.sql:268: ERROR:  function g(integer) does not 
exist
+SELECT proacl FROM pg_proc where proname = 'g';
+                 proacl                  
+-----------------------------------------
+ {superuser=X/superuser,u1=X*/superuser}
+(1 row)
+
+SET ROLE u1;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:271: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:272: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE u2;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:274: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:275: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE superuser;
+SET
+REVOKE ALL ON FUNCTION g(int) FROM u1 CASCADE;
+REVOKE
+SELECT proacl FROM pg_proc where proname = 'g';
+         proacl          
+-------------------------
+ {superuser=X/superuser}
+(1 row)
+
+SET ROLE u1;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:280: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:281: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+SET ROLE u2;
+SET
+SELECT g(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:283: ERROR:  function g(integer) does not 
exist
+LINE 1: SELECT g(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+SELECT count(g(x)) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:284: ERROR:  relation "foo" does not exist
+LINE 1: SELECT count(g(x)) FROM foo;
+                                ^
+RESET ROLE;
+RESET
+DROP FUNCTION g(int);
+DROP FUNCTION
+REVOKE SELECT ON TABLE foo FROM PUBLIC;
+REVOKE
+DROP ROLE u1;
+DROP ROLE
+DROP ROLE u2;
+DROP ROLE
+DROP ROLE superuser;
+DROP ROLE
+-- DML, CaseExpr
+SELECT CASE WHEN x % 2 = 0 THEN f(x) ELSE 0 END FROM foo ORDER BY x;
+ case 
+------
+    0
+    2
+    0
+    4
+    0
+    6
+    0
+    8
+    0
+   10
+(10 rows)
+
+-- DML, OpExpr
+SELECT f(x) + f(x) FROM foo ORDER BY x;
+ ?column? 
+----------
+        2
+        4
+        6
+        8
+       10
+       12
+       14
+       16
+       18
+       20
+(10 rows)
+
+SELECT f(x) + f(x) + f(x) FROM foo ORDER BY x;
+ ?column? 
+----------
+        3
+        6
+        9
+       12
+       15
+       18
+       21
+       24
+       27
+       30
+(10 rows)
+
+SELECT f(x) + f(x) - f(x) FROM foo ORDER BY x;
+ ?column? 
+----------
+        1
+        2
+        3
+        4
+        5
+        6
+        7
+        8
+        9
+       10
+(10 rows)
+
+-- DML, FuncExpr
+CREATE FUNCTION g(x INT) RETURNS INT AS $$
+BEGIN
+RETURN x;
+END
+$$ LANGUAGE PLPGSQL;
+CREATE FUNCTION
+SELECT g(f(x)) FROM foo ORDER BY x;
+ g  
+----
+  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+(10 rows)
+
+DROP FUNCTION g(int);
+DROP FUNCTION
+-- DML, BoolExpr
+SELECT x % 2 = 0 AND f(x) % 2 = 1 FROM foo ORDER BY x;
+ ?column? 
+----------
+ f
+ f
+ f
+ f
+ f
+ f
+ f
+ f
+ f
+ f
+(10 rows)
+
+-- DML, DistinctExpr
+SELECT x IS DISTINCT FROM f(x) from foo ORDER BY x;
+ ?column? 
+----------
+ f
+ f
+ f
+ f
+ f
+ f
+ f
+ f
+ f
+ f
+(10 rows)
+
+-- DML, PercentileExpr
+SELECT MEDIAN(f(x)) FROM foo;
+ median 
+--------
+    5.5
+(1 row)
+
+-- DML, Complex Expression
+CREATE FUNCTION g(x INT) RETURNS INT AS $$
+BEGIN
+RETURN x;
+END
+$$ LANGUAGE PLPGSQL;
+CREATE FUNCTION
+SELECT CASE
+       WHEN x % 2 = 0 THEN g(g(x)) + g(g(x))
+       WHEN f(x) % 2 = 1 THEN g(g(x)) - g(g(x))
+       END FROM foo ORDER BY x;
+ case 
+------
+    0
+    4
+    0
+    8
+    0
+   12
+    0
+   16
+    0
+   20
+(10 rows)
+
+DROP FUNCTION g(int);
+DROP FUNCTION
+-- DML, Qual
+SELECT x FROM foo WHERE f(x) % 2 = 0 ORDER BY x;
+ x  
+----
+  2
+  4
+  6
+  8
+ 10
+(5 rows)
+
+-- DML, FROM
+SELECT * FROM f(5);
+ f 
+---
+ 5
+(1 row)
+
+-- DML, Grouping
+SELECT DISTINCT f(x) FROM foo ORDER BY f(x);
+ f  
+----
+  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+(10 rows)
+
+SELECT f(x) FROM foo GROUP BY f(x) ORDER BY f(x);
+ f  
+----
+  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+(10 rows)
+
+-- DML, Join
+SELECT a.x FROM foo a, foo b WHERE f(a.x) = f(b.x) ORDER BY x;
+ x  
+----
+  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+(10 rows)
+
+SELECT a.x FROM foo a JOIN foo b ON f(a.x) = f(b.x) ORDER BY x;
+ x  
+----
+  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+(10 rows)
+
+-- DML, Windowing
+SELECT avg(x) OVER (PARTITION BY f(x)) FROM foo ORDER BY x;
+ avg 
+-----
+   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+(10 rows)
+
+-- DML, CTE
+WITH t AS (SELECT x from foo)
+       SELECT f(x) from t ORDER BY x;
+ f  
+----
+  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+(10 rows)
+
+-- DML, InitPlan
+SELECT UNNEST(ARRAY(SELECT x FROM foo)) ORDER BY 1;
+ unnest 
+--------
+      1
+      2
+      3
+      4
+      5
+      6
+      7
+      8
+      9
+     10
+(10 rows)
+
+SELECT UNNEST(ARRAY(SELECT f(1)));
+ unnest 
+--------
+      1
+(1 row)
+
+-- PROPERTIES, VOLATILITY, IMMUTABLE
+CREATE FUNCTION g() RETURNS float AS 'SELECT random();' LANGUAGE SQL IMMUTABLE;
+CREATE FUNCTION
+SELECT COUNT(DISTINCT(g())) > 1 FROM foo;
+ ?column? 
+----------
+ f
+(1 row)
+
+DROP FUNCTION g();
+DROP FUNCTION
+-- PROPERTIES, VOLATILITY, STABLE
+CREATE FUNCTION g() RETURNS float AS 'SELECT random();' LANGUAGE SQL STABLE;
+CREATE FUNCTION
+SELECT COUNT(DISTINCT(g())) > 1 FROM foo;
+ ?column? 
+----------
+ f
+(1 row)
+
+DROP FUNCTION g();
+DROP FUNCTION
+-- PROPERTIES, VOLATILITY, VOLATILE
+CREATE FUNCTION g() RETURNS float AS 'SELECT random();' LANGUAGE SQL VOLATILE;
+CREATE FUNCTION
+SELECT COUNT(DISTINCT(g())) > 1 FROM foo;
+ ?column? 
+----------
+ t
+(1 row)
+
+DROP FUNCTION g();
+DROP FUNCTION
+-----------------
+-- NEGATIVE TESTS
+-----------------
+SELECT h(1);
+psql:/tmp/TestUDF_TestUDFBasics.sql:405: ERROR:  function h(integer) does not 
exist
+LINE 1: SELECT h(1);
+               ^
+HINT:  No function matches the given name and argument types. You may need to 
add explicit type casts.
+-- DML, InitPlan
+SELECT UNNEST(ARRAY(SELECT f(x) from foo));
+ unnest 
+--------
+      1
+      2
+      3
+      4
+      5
+      6
+      7
+      8
+      9
+     10
+(10 rows)
+
+-- LANGUAGES not yet supported
+-- CREATE LANGUAGE plr;
+-- CREATE LANGUAGE plpython;
+-- CREATE LANGUAGE pljava;
+-- CREATE LANGUAGE plperl;
+-- NESTED FUNCTION
+CREATE FUNCTION inner(int) RETURNS INTEGER AS 'SELECT 1' LANGUAGE SQL 
IMMUTABLE;
+CREATE FUNCTION
+CREATE FUNCTION outer(x INT) RETURNS INT AS $$
+BEGIN
+RETURN inner(x);
+END
+$$ LANGUAGE PLPGSQL;
+CREATE FUNCTION
+SELECT outer(0);
+ outer 
+-------
+     1
+(1 row)
+
+SELECT outer(0) FROM foo;
+psql:/tmp/TestUDF_TestUDFBasics.sql:423: ERROR:  function inner(integer) does 
not exist  (seg2 localhost:40000 pid=76055)
+DETAIL:  PL/pgSQL function "outer" line 2 at return
+DROP FUNCTION outer(int);
+DROP FUNCTION
+DROP FUNCTION inner(int);
+DROP FUNCTION
+-- TEARDOWN
+DROP TABLE foo;
+DROP TABLE
+-- HAWQ-510
+drop table if exists testEntryDB;
+psql:/tmp/TestUDF_TestUDFBasics.sql:435: NOTICE:  table "testentrydb" does not 
exist, skipping
+DROP TABLE
+create table testEntryDB(key int, value int) distributed randomly;
+CREATE TABLE
+insert into testEntryDB values(1, 0);
+INSERT 0 1
+select t2.key, t2.value
+from   (select key, value from testEntryDB where value = 0) as t1,
+       (select generate_series(1,2)::int as key, 0::int as value) as t2
+where  t1.value=t2.value;
+ key | value 
+-----+-------
+   1 |     0
+   2 |     0
+(2 rows)
+
+drop table testEntryDB;
+DROP TABLE

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/49fd529a/src/test/feature/UDF/ans/function_creation.ans.source
----------------------------------------------------------------------
diff --git a/src/test/feature/UDF/ans/function_creation.ans.source 
b/src/test/feature/UDF/ans/function_creation.ans.source
new file mode 100755
index 0000000..8524e79
--- /dev/null
+++ b/src/test/feature/UDF/ans/function_creation.ans.source
@@ -0,0 +1,96 @@
+-- start_ignore
+SET SEARCH_PATH=TestUDF_TestUDFCreation;
+SET
+-- end_ignore
+--
+-- CREATE_FUNCTION
+--
+CREATE FUNCTION widget_in(cstring)
+   RETURNS widget
+   AS '@SHARE_LIBRARY_PATH@'
+   LANGUAGE C IMMUTABLE STRICT;
+psql:/tmp/TestUDF_TestUDFCreation.sql:11: NOTICE:  type "widget" is not yet 
defined
+DETAIL:  Creating a shell type definition.
+CREATE FUNCTION
+CREATE FUNCTION widget_out(widget)
+   RETURNS cstring
+   AS '@SHARE_LIBRARY_PATH@'
+   LANGUAGE C IMMUTABLE STRICT;
+psql:/tmp/TestUDF_TestUDFCreation.sql:16: NOTICE:  argument type widget is 
only a shell
+CREATE FUNCTION
+CREATE FUNCTION int44in(cstring)
+   RETURNS city_budget
+   AS '@SHARE_LIBRARY_PATH@'
+   LANGUAGE C IMMUTABLE STRICT;
+psql:/tmp/TestUDF_TestUDFCreation.sql:21: NOTICE:  type "city_budget" is not 
yet defined
+DETAIL:  Creating a shell type definition.
+CREATE FUNCTION
+CREATE FUNCTION int44out(city_budget)
+   RETURNS cstring
+   AS '@SHARE_LIBRARY_PATH@'
+   LANGUAGE C IMMUTABLE STRICT;
+psql:/tmp/TestUDF_TestUDFCreation.sql:26: NOTICE:  argument type city_budget 
is only a shell
+CREATE FUNCTION
+CREATE FUNCTION check_primary_key ()
+       RETURNS trigger
+       AS '@SHARE_LIBRARY_PATH@'
+       LANGUAGE C;
+CREATE FUNCTION
+CREATE FUNCTION check_foreign_key ()
+       RETURNS trigger
+       AS '@SHARE_LIBRARY_PATH@'
+       LANGUAGE C;
+CREATE FUNCTION
+CREATE FUNCTION autoinc ()
+       RETURNS trigger
+       AS '@SHARE_LIBRARY_PATH@'
+       LANGUAGE C;
+CREATE FUNCTION
+CREATE FUNCTION funny_dup17 ()
+        RETURNS trigger
+        AS '@SHARE_LIBRARY_PATH@'
+        LANGUAGE C;
+CREATE FUNCTION
+CREATE FUNCTION ttdummy ()
+        RETURNS trigger
+        AS '@SHARE_LIBRARY_PATH@'
+        LANGUAGE C;
+CREATE FUNCTION
+CREATE FUNCTION set_ttdummy (int4)
+        RETURNS int4
+        AS '@SHARE_LIBRARY_PATH@'
+        LANGUAGE C STRICT;
+CREATE FUNCTION
+-- Things that shouldn't work:
+CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
+    AS 'SELECT ''not an integer'';';
+psql:/tmp/TestUDF_TestUDFCreation.sql:61: ERROR:  return type mismatch in 
function declared to return integer
+DETAIL:  Actual return type is unknown.
+CONTEXT:  SQL function "test1"
+CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
+    AS 'not even SQL';
+psql:/tmp/TestUDF_TestUDFCreation.sql:64: ERROR:  syntax error at or near "not"
+LINE 2:     AS 'not even SQL';
+                ^
+CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
+    AS 'SELECT 1, 2, 3;';
+psql:/tmp/TestUDF_TestUDFCreation.sql:67: ERROR:  return type mismatch in 
function declared to return integer
+DETAIL:  Final SELECT must return exactly one column.
+CONTEXT:  SQL function "test1"
+CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
+    AS 'SELECT $2;';
+psql:/tmp/TestUDF_TestUDFCreation.sql:70: ERROR:  there is no parameter $2
+LINE 2:     AS 'SELECT $2;';
+                       ^
+CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
+    AS 'a', 'b';
+psql:/tmp/TestUDF_TestUDFCreation.sql:73: ERROR:  only one AS item needed for 
language "sql"
+CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C
+    AS 'nosuchfile';
+psql:/tmp/TestUDF_TestUDFCreation.sql:76: ERROR:  could not access file 
"nosuchfile": No such file or directory
+CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C
+    AS '@SHARE_LIBRARY_PATH@', 'nosuchsymbol';
+psql:/tmp/TestUDF_TestUDFCreation.sql:79: ERROR:  could not find function 
"nosuchsymbol" in file "@SHARE_LIBRARY_PATH@"
+CREATE FUNCTION test1 (int) RETURNS int LANGUAGE internal
+    AS 'nosuch';
+psql:/tmp/TestUDF_TestUDFCreation.sql:82: ERROR:  there is no built-in 
function named "nosuch"

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/49fd529a/src/test/feature/UDF/ans/function_extension.ans
----------------------------------------------------------------------
diff --git a/src/test/feature/UDF/ans/function_extension.ans 
b/src/test/feature/UDF/ans/function_extension.ans
new file mode 100755
index 0000000..e1d14f4
--- /dev/null
+++ b/src/test/feature/UDF/ans/function_extension.ans
@@ -0,0 +1,183 @@
+-- start_ignore
+SET SEARCH_PATH=TestUDF_TestUDFExtension;
+SET
+-- end_ignore
+-- -----------------------------------------------------------------
+-- Test extensions to functions (MPP-16060)
+--     1. data access indicators
+-- -----------------------------------------------------------------
+-- test prodataaccess
+create function func1(int, int) returns int as
+$$
+  select $1 + $2;
+$$ language sql immutable contains sql;
+CREATE FUNCTION
+-- check prodataaccess column in pg_proc
+select proname, prodataaccess from pg_proc where proname = 'func1';
+ proname | prodataaccess 
+---------+---------------
+ func1   | c
+(1 row)
+
+-- check prodataaccess in pg_attribute
+select relname, attname, attlen from pg_class c, pg_attribute
+where attname = 'prodataaccess' and attrelid = c.oid and c.relname = 'pg_proc';
+ relname |    attname    | attlen 
+---------+---------------+--------
+ pg_proc | prodataaccess |      1
+(1 row)
+
+create function func2(a anyelement, b anyelement, flag bool)
+returns anyelement as
+$$
+  select $1 + $2;
+$$ language sql reads sql data;
+CREATE FUNCTION
+-- check prodataaccess column in pg_proc
+select proname, prodataaccess from pg_proc where proname = 'func2';
+ proname | prodataaccess 
+---------+---------------
+ func2   | r
+(1 row)
+
+create function func3() returns oid as
+$$
+  select oid from pg_class where relname = 'pg_type';
+$$ language sql modifies sql data volatile;
+CREATE FUNCTION
+-- check prodataaccess column in pg_proc
+select proname, prodataaccess from pg_proc where proname = 'func3';
+ proname | prodataaccess 
+---------+---------------
+ func3   | m
+(1 row)
+
+-- check default value of prodataaccess
+drop function func1(int, int);
+DROP FUNCTION
+create function func1(int, int) returns varchar as $$
+declare
+       v_name varchar(20) DEFAULT 'zzzzz';
+begin
+       select relname from pg_class into v_name where oid=$1;
+       return v_name;
+end;
+$$ language plpgsql;
+CREATE FUNCTION
+select proname, proargnames, prodataaccess from pg_proc where proname = 
'func1';
+ proname | proargnames | prodataaccess 
+---------+-------------+---------------
+ func1   |             | n
+(1 row)
+
+create function func4(int, int) returns int as
+$$
+  select $1 + $2;
+$$ language sql;
+CREATE FUNCTION
+-- check prodataaccess column
+select proname, proargnames, prodataaccess from pg_proc where proname = 
'func4';
+ proname | proargnames | prodataaccess 
+---------+-------------+---------------
+ func4   |             | c
+(1 row)
+
+-- change prodataaccess option
+create or replace function func4(int, int) returns int as
+$$
+  select $1 + $2;
+$$ language sql modifies sql data;
+CREATE FUNCTION
+select proname, proargnames, prodataaccess from pg_proc where proname = 
'func4';
+ proname | proargnames | prodataaccess 
+---------+-------------+---------------
+ func4   |             | m
+(1 row)
+
+-- upper case language name
+create or replace function func5(int) returns int as
+$$
+  select $1;
+$$ language "SQL";
+CREATE FUNCTION
+-- check prodataaccess column
+select proname, proargnames, prodataaccess from pg_proc where proname = 
'func5';
+ proname | proargnames | prodataaccess 
+---------+-------------+---------------
+ func5   |             | c
+(1 row)
+
+-- alter function with data access
+alter function func5(int) reads sql data;
+ALTER FUNCTION
+-- check prodataaccess column
+select proname, proargnames, prodataaccess from pg_proc where proname = 
'func5';
+ proname | proargnames | prodataaccess 
+---------+-------------+---------------
+ func5   |             | r
+(1 row)
+
+-- alter function with data access
+alter function func5(int) modifies sql data;
+ALTER FUNCTION
+-- check prodataaccess column
+select proname, proargnames, prodataaccess from pg_proc where proname = 
'func5';
+ proname | proargnames | prodataaccess 
+---------+-------------+---------------
+ func5   |             | m
+(1 row)
+
+-- alter function with data access
+alter function func5(int) no sql;
+psql:/tmp/TestUDF_TestUDFExtension.sql:90: ERROR:  conflicting options
+HINT:  A SQL function cannot specify NO SQL.
+-- alter function with data access
+alter function func5(int) volatile contains sql;
+ALTER FUNCTION
+alter function func5(int) immutable reads sql data;
+psql:/tmp/TestUDF_TestUDFExtension.sql:95: ERROR:  conflicting options
+HINT:  IMMUTABLE conflicts with READS SQL DATA.
+alter function func5(int) immutable modifies sql data;
+psql:/tmp/TestUDF_TestUDFExtension.sql:96: ERROR:  conflicting options
+HINT:  IMMUTABLE conflicts with MODIFIES SQL DATA.
+-- data_access indicators for plpgsql
+drop function func1(int, int);
+DROP FUNCTION
+create or replace function func1(int, int) returns varchar as $$
+declare
+       v_name varchar(20) DEFAULT 'zzzzz';
+begin
+       select relname from pg_class into v_name where oid=$1;
+       return v_name;
+end;
+$$ language plpgsql reads sql data;
+CREATE FUNCTION
+select proname, proargnames, prodataaccess from pg_proc where proname = 
'func1';
+ proname | proargnames | prodataaccess 
+---------+-------------+---------------
+ func1   |             | r
+(1 row)
+
+-- check conflicts
+drop function func1(int, int);
+DROP FUNCTION
+create function func1(int, int) returns int as
+$$
+  select $1 + $2;
+$$ language sql immutable no sql;
+psql:/tmp/TestUDF_TestUDFExtension.sql:116: ERROR:  conflicting options
+HINT:  A SQL function cannot specify NO SQL.
+create function func1(int, int) returns int as
+$$
+  select $1 + $2;
+$$ language sql immutable reads sql data;
+psql:/tmp/TestUDF_TestUDFExtension.sql:121: ERROR:  conflicting options
+HINT:  IMMUTABLE conflicts with READS SQL DATA.
+drop function func2(anyelement, anyelement, bool);
+DROP FUNCTION
+drop function func3();
+DROP FUNCTION
+drop function func4(int, int);
+DROP FUNCTION
+drop function func5(int);
+DROP FUNCTION

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/49fd529a/src/test/feature/UDF/ans/function_set_returning.ans
----------------------------------------------------------------------
diff --git a/src/test/feature/UDF/ans/function_set_returning.ans 
b/src/test/feature/UDF/ans/function_set_returning.ans
new file mode 100755
index 0000000..4544a2d
--- /dev/null
+++ b/src/test/feature/UDF/ans/function_set_returning.ans
@@ -0,0 +1,287 @@
+-- start_ignore
+SET SEARCH_PATH=TestUDF_TestUDFSetReturning;
+SET
+-- end_ignore
+DROP LANGUAGE IF EXISTS plpythonu CASCADE;
+DROP LANGUAGE
+CREATE LANGUAGE plpythonu;
+CREATE LANGUAGE
+CREATE TABLE foo2(fooid int, f2 int);
+CREATE TABLE
+INSERT INTO foo2 VALUES(1, 11);
+INSERT 0 1
+INSERT INTO foo2 VALUES(2, 22);
+INSERT 0 1
+INSERT INTO foo2 VALUES(1, 111);
+INSERT 0 1
+CREATE FUNCTION foot(int) returns setof foo2 as 'SELECT * FROM foo2 WHERE 
fooid = $1;' LANGUAGE SQL;
+CREATE FUNCTION
+select foot.fooid, foot.f2 from foot(sin(pi()/2)::int) ORDER BY 1,2;
+ fooid | f2  
+-------+-----
+     1 |  11
+     1 | 111
+(2 rows)
+
+CREATE TABLE foo (fooid int, foosubid int, fooname text);
+CREATE TABLE
+INSERT INTO foo VALUES(1,1,'Joe');
+INSERT 0 1
+INSERT INTO foo VALUES(1,2,'Ed');
+INSERT 0 1
+INSERT INTO foo VALUES(2,1,'Mary');
+INSERT 0 1
+CREATE FUNCTION getfoo(int) RETURNS setof int AS 'SELECT fooid FROM foo WHERE 
fooid = $1;' LANGUAGE SQL;
+CREATE FUNCTION
+SELECT * FROM getfoo(1) AS t1;
+ t1 
+----
+  1
+  1
+(2 rows)
+
+CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
+CREATE VIEW
+SELECT * FROM vw_getfoo;
+ getfoo 
+--------
+      1
+      1
+(2 rows)
+
+DROP VIEW vw_getfoo;
+DROP VIEW
+DROP FUNCTION getfoo(int);
+DROP FUNCTION
+DROP FUNCTION foot(int);
+DROP FUNCTION
+DROP TABLE foo2;
+DROP TABLE
+DROP TABLE foo;
+DROP TABLE
+-- setof as a paramater --
+CREATE TYPE numtype as (i int, j int);
+CREATE TYPE
+CREATE FUNCTION g_numtype(x setof numtype) RETURNS setof numtype AS $$ select 
$1; $$ LANGUAGE SQL;
+CREATE FUNCTION
+DROP FUNCTION g_numtype(x setof numtype);
+DROP FUNCTION
+DROP TYPE numtype;
+DROP TYPE
+--
+-- Set functions samples from Madlib
+--
+create function combination(s text) returns setof text[] as $$
+x = s.split(',')
+
+def subset(myset, N):
+   left = []
+   right = []
+   for i in range(0, len(myset)):
+      if ((1 << i) & N) > 0:
+         left.append(myset[i])
+      else:
+         right.append(myset[i])
+   return (', '.join(left), ', '.join(right))
+
+for i in range(1, (1 << len(x)) - 2):
+   yield subset(x, i)
+$$ language plpythonu strict;
+CREATE FUNCTION
+select x[1] || ' => ' || x[2] from combination('a,b,c,d') x;
+   ?column?   
+--------------
+ a => b, c, d
+ b => a, c, d
+ a, b => c, d
+ c => a, b, d
+ a, c => b, d
+ b, c => a, d
+ a, b, c => d
+ d => a, b, c
+ a, d => b, c
+ b, d => a, c
+ a, b, d => c
+ c, d => a, b
+ a, c, d => b
+(13 rows)
+
+CREATE TABLE rules(rule text) distributed by (rule);
+CREATE TABLE
+insert into rules values('a,b,c');
+INSERT 0 1
+insert into rules values('d,e');
+INSERT 0 1
+insert into rules values('f,g,h,i,j');
+INSERT 0 1
+insert into rules values('k,l,m');
+INSERT 0 1
+SELECT rule, combination(rule) from rules order by 1,2;
+   rule    |    combination     
+-----------+--------------------
+ a,b,c     | {a,"b, c"}
+ a,b,c     | {"a, b",c}
+ a,b,c     | {"a, c",b}
+ a,b,c     | {b,"a, c"}
+ a,b,c     | {c,"a, b"}
+ d,e       | {d,e}
+ f,g,h,i,j | {f,"g, h, i, j"}
+ f,g,h,i,j | {"f, g","h, i, j"}
+ f,g,h,i,j | {"f, g, h","i, j"}
+ f,g,h,i,j | {"f, g, h, i",j}
+ f,g,h,i,j | {"f, g, h, j",i}
+ f,g,h,i,j | {"f, g, i","h, j"}
+ f,g,h,i,j | {"f, g, i, j",h}
+ f,g,h,i,j | {"f, g, j","h, i"}
+ f,g,h,i,j | {"f, h","g, i, j"}
+ f,g,h,i,j | {"f, h, i","g, j"}
+ f,g,h,i,j | {"f, h, i, j",g}
+ f,g,h,i,j | {"f, h, j","g, i"}
+ f,g,h,i,j | {"f, i","g, h, j"}
+ f,g,h,i,j | {"f, i, j","g, h"}
+ f,g,h,i,j | {"f, j","g, h, i"}
+ f,g,h,i,j | {g,"f, h, i, j"}
+ f,g,h,i,j | {"g, h","f, i, j"}
+ f,g,h,i,j | {"g, h, i","f, j"}
+ f,g,h,i,j | {"g, h, j","f, i"}
+ f,g,h,i,j | {"g, i","f, h, j"}
+ f,g,h,i,j | {"g, i, j","f, h"}
+ f,g,h,i,j | {"g, j","f, h, i"}
+ f,g,h,i,j | {h,"f, g, i, j"}
+ f,g,h,i,j | {"h, i","f, g, j"}
+ f,g,h,i,j | {"h, i, j","f, g"}
+ f,g,h,i,j | {"h, j","f, g, i"}
+ f,g,h,i,j | {i,"f, g, h, j"}
+ f,g,h,i,j | {"i, j","f, g, h"}
+ f,g,h,i,j | {j,"f, g, h, i"}
+ k,l,m     | {k,"l, m"}
+ k,l,m     | {"k, l",m}
+ k,l,m     | {"k, m",l}
+ k,l,m     | {l,"k, m"}
+ k,l,m     | {m,"k, l"}
+(40 rows)
+
+DROP TABLE IF EXISTS foo;
+psql:/tmp/TestUDF_TestUDFSetReturning.sql:69: NOTICE:  table "foo" does not 
exist, skipping
+DROP TABLE
+CREATE TABLE foo AS SELECT rule, combination(rule) from rules distributed by 
(rule);
+SELECT 40
+-- UDT as argument/return type of set returning UDF
+CREATE TYPE r_type as (a int, b text);
+CREATE TYPE
+CREATE FUNCTION f1(x r_type) returns setof text as $$ SELECT $1.b from 
generate_series(1, $1.a) $$ language sql;
+CREATE FUNCTION
+CREATE FUNCTION f2(x int) returns setof r_type as $$ SELECT i, 'hello'::text 
from generate_series(1, $1) i $$ language sql;
+CREATE FUNCTION
+CREATE FUNCTION f3(x r_type) returns setof r_type as $$ SELECT $1 from 
generate_series(1, $1.a) $$ language sql;
+CREATE FUNCTION
+SELECT f1(row(2, 'hello'));
+  f1   
+-------
+ hello
+ hello
+(2 rows)
+
+SELECT f2(2);
+    f2     
+-----------
+ (1,hello)
+ (2,hello)
+(2 rows)
+
+SELECT f3(row(2,'hello'));
+    f3     
+-----------
+ (2,hello)
+ (2,hello)
+(2 rows)
+
+SELECT * FROM f1(row(2,'hello'));
+  f1   
+-------
+ hello
+ hello
+(2 rows)
+
+SELECT * FROM f2(2);
+ a |   b   
+---+-------
+ 1 | hello
+ 2 | hello
+(2 rows)
+
+SELECT * FROM f3(row(2,'hello'));
+ a |   b   
+---+-------
+ 2 | hello
+ 2 | hello
+(2 rows)
+
+CREATE TABLE t1 as SELECT i from generate_series(1,5) i distributed by (i);
+SELECT 5
+SELECT i, f1(row(i, 'hello')) from t1;
+ i |  f1   
+---+-------
+ 1 | hello
+ 3 | hello
+ 3 | hello
+ 3 | hello
+ 5 | hello
+ 5 | hello
+ 5 | hello
+ 5 | hello
+ 5 | hello
+ 2 | hello
+ 2 | hello
+ 4 | hello
+ 4 | hello
+ 4 | hello
+ 4 | hello
+(15 rows)
+
+SELECT i, f2(i) from t1;
+ i |    f2     
+---+-----------
+ 1 | (1,hello)
+ 3 | (1,hello)
+ 3 | (2,hello)
+ 3 | (3,hello)
+ 5 | (1,hello)
+ 5 | (2,hello)
+ 5 | (3,hello)
+ 5 | (4,hello)
+ 5 | (5,hello)
+ 2 | (1,hello)
+ 2 | (2,hello)
+ 4 | (1,hello)
+ 4 | (2,hello)
+ 4 | (3,hello)
+ 4 | (4,hello)
+(15 rows)
+
+SELECT i, f3(row(i,'hello')) from t1;
+ i |    f3     
+---+-----------
+ 1 | (1,hello)
+ 4 | (4,hello)
+ 4 | (4,hello)
+ 4 | (4,hello)
+ 4 | (4,hello)
+ 3 | (3,hello)
+ 3 | (3,hello)
+ 3 | (3,hello)
+ 5 | (5,hello)
+ 5 | (5,hello)
+ 5 | (5,hello)
+ 5 | (5,hello)
+ 5 | (5,hello)
+ 2 | (2,hello)
+ 2 | (2,hello)
+(15 rows)
+
+CREATE TABLE o1 as SELECT f1(row(i, 'hello')) from t1;
+SELECT 15
+CREATE TABLE o2 as SELECT f2(i) from t1;
+SELECT 15
+CREATE TABLE o3 as SELECT f3(row(i,'hello')) from t1;
+SELECT 15

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/49fd529a/src/test/feature/UDF/lib/Makefile
----------------------------------------------------------------------
diff --git a/src/test/feature/UDF/lib/Makefile 
b/src/test/feature/UDF/lib/Makefile
new file mode 100755
index 0000000..ccbf99b
--- /dev/null
+++ b/src/test/feature/UDF/lib/Makefile
@@ -0,0 +1,43 @@
+top_builddir = ../../../../..
+include $(top_builddir)/src/Makefile.global
+
+OS = $(shell uname)
+
+CXX = gcc 
+CXXFLAGS = -Wall -O1 -g -std=gnu99 -Wmissing-prototypes -Wpointer-arith 
-Wendif-labels -Wformat-security -fno-strict-aliasing -fwrapv -fPIC
+
+CC = gcc
+CFLAGS = -Wall -O1 -g -std=gnu99 -Wmissing-prototypes -Wpointer-arith 
-Wendif-labels -Wformat-security -fno-strict-aliasing -fwrapv -fPIC
+
+CPPFLAGS = -I$(abs_top_srcdir)/src/include
+CPPFLAGS += -I$(abs_top_srcdir)/depends/libhdfs3/build/install$(prefix)/include
+CPPFLAGS += -I$(abs_top_srcdir)/depends/libyarn/build/install$(prefix)/include
+
+LDFLAGS = -L$(libdir)
+LDFLAGS += -L$(abs_top_srcdir)/src/port
+LDFLAGS += -L$(abs_top_builddir)/src/port
+LDFLAGS += -L$(abs_top_srcdir)/depends/libhdfs3/build/install$(prefix)/lib
+LDFLAGS += -L$(abs_top_srcdir)/depends/libyarn/build/install$(prefix)/lib
+
+POSTGRES = $(abs_top_srcdir)/src/backend/postgres
+
+PROG = function.c
+OBJS = function.o
+TARGET = function.so
+
+RM = rm -rf 
+
+all: $(OBJS) $(TARGET)
+
+$(OBJS): $(PROG)
+       $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $(OBJS) $(PROG)
+
+$(TARGET):
+ifeq ($(OS),Darwin)
+       $(CXX) $(CXXFLAGS) -bundle $(OBJS) -bundle_loader $(POSTGRES) 
$(LDFLAGS) -o $@
+else
+       $(CXX) $(CXXFLAGS) -shared $(OBJS) $(LDFLAGS) 
-Wl,-rpath,'$(abs_top_builddir)/lib' -o $@
+endif
+
+clean:
+       $(RM) *.o

Reply via email to