This is the multi-page printable view of this section.
Click here to print.
Return to the regular view of this page.
User-defined SQL functions
For syntax and parameters for the commands and system table discussed in this section, see the following topics:.
User-defined SQL functions let you define and store commonly-used SQL expressions as a function. User-defined SQL functions are useful for executing complex queries and combining Vertica built-in functions. You simply call the function name you assigned in your query.
A user-defined SQL function can be used anywhere in a query where an ordinary SQL expression can be used, except in a table partition clause or the projection segmentation clause.
For syntax and parameters for the commands and system table discussed in this section, see the following topics:
1 - Creating user-defined SQL functions
A user-defined SQL function can be used anywhere in a query where an ordinary SQL expression can be used, except in the table partition clause or the projection segmentation clause.
A user-defined SQL function can be used anywhere in a query where an ordinary SQL expression can be used, except in the table partition clause or the projection segmentation clause.
To create a SQL function, the user must have CREATE privileges on the schema. To use a SQL function, the user must have USAGE privileges on the schema and EXECUTE privileges on the defined function.
This following statement creates a SQL function called myzeroifnull
that accepts an INTEGER
argument and returns an INTEGER
result.
=> CREATE FUNCTION myzeroifnull(x INT) RETURN INT
AS BEGIN
RETURN (CASE WHEN (x IS NOT NULL) THEN x ELSE 0 END);
END;
You can use the new SQL function (myzeroifnull
) anywhere you use an ordinary SQL expression. For example, create a simple table:
=> CREATE TABLE tabwnulls(col1 INT);
=> INSERT INTO tabwnulls VALUES(1);
=> INSERT INTO tabwnulls VALUES(NULL);
=> INSERT INTO tabwnulls VALUES(0);
=> SELECT * FROM tabwnulls;
a
---
1
0
(3 rows)
Use the myzeroifnull
function in a SELECT
statement, where the function calls col1
from table tabwnulls:
=> SELECT myzeroifnull(col1) FROM tabwnulls;
myzeroifnull
--------------
1
0
0
(3 rows)
Use the myzeroifnull
function in the GROUP BY
clause:
=> SELECT COUNT(*) FROM tabwnulls GROUP BY myzeroifnull(col1);
count
-------
2
1
(2 rows)
If you want to change a user-defined SQL function's body, use the CREATE OR REPLACE
syntax. The following command modifies the CASE expression:
=> CREATE OR REPLACE FUNCTION myzeroifnull(x INT) RETURN INT
AS BEGIN
RETURN (CASE WHEN (x IS NULL) THEN 0 ELSE x END);
END;
To see how this information is stored in the Vertica catalog, see Viewing Information About SQL Functions.
See also
2 - Altering and dropping user-defined SQL functions
Vertica allows multiple functions to share the same name with different argument types.
Vertica allows multiple functions to share the same name with different argument types. Therefore, if you try to alter or drop a SQL function without specifying the argument data type, the system returns an error message to prevent you from dropping the wrong function:
=> DROP FUNCTION myzeroifnull();
ROLLBACK: Function with specified name and parameters does not exist: myzeroifnull
Note
Only a superuser or owner can alter or drop a SQL Function.
Altering a user-defined SQL function
The ALTER FUNCTION (scalar) command lets you assign a new name to a user-defined function, as well as move it to a different schema.
In the previous topic, you created a SQL function called myzeroifnull
. The following command renames the myzeroifnull
function to zerowhennull
:
=> ALTER FUNCTION myzeroifnull(x INT) RENAME TO zerowhennull;
ALTER FUNCTION
This next command moves the renamed function into a new schema called macros
:
=> ALTER FUNCTION zerowhennull(x INT) SET SCHEMA macros;
ALTER FUNCTION
Dropping a SQL function
The DROP FUNCTION command drops a SQL function from the Vertica catalog.
Like with ALTER FUNCTION, you must specify the argument data type or the system returns the following error message:
=> DROP FUNCTION zerowhennull();
ROLLBACK: Function with specified name and parameters does not exist: zerowhennull
Specify the argument type:
=> DROP FUNCTION macros.zerowhennull(x INT);
DROP FUNCTION
Vertica does not check for dependencies, so if you drop a SQL function where other objects reference it (such as views or other SQL Functions), Vertica returns an error when those objects are used, not when the function is dropped.
Tip
To view a list of all user-defined SQL functions on which you have EXECUTE privileges, (which also returns their argument types), query the
V_CATALOG.USER_FUNCTIONS system table.
See also
3 - Managing access to SQL functions
Before a user can execute a user-defined SQL function, he or she must have USAGE privileges on the schema and EXECUTE privileges on the defined function.
Before a user can execute a user-defined SQL function, he or she must have USAGE privileges on the schema and EXECUTE privileges on the defined function. Only the superuser or owner can grant/revoke EXECUTE usage on a function.
To grant EXECUTE privileges to user Fred on the myzeroifnull
function:
=> GRANT EXECUTE ON FUNCTION myzeroifnull (x INT) TO Fred;
To revoke EXECUTE privileges from user Fred on the myzeroifnull
function:
=> REVOKE EXECUTE ON FUNCTION myzeroifnull (x INT) FROM Fred;
See also
4 - Viewing information about user-defined SQL functions
You can access information about user-defined SQL functions on which you have EXECUTE privileges.
You can access information about user-defined SQL functions on which you have EXECUTE privileges. This information is available in system table USER_FUNCTIONS and from the vsql meta-command \df
.
To view all user-defined SQL functions on which you have EXECUTE privileges, query USER_FUNCTIONS:
=> SELECT * FROM USER_FUNCTIONS;
-[ RECORD 1 ]----------+---------------------------------------------------
schema_name | public
function_name | myzeroifnull
function_return_type | Integer
function_argument_type | x Integer
function_definition | RETURN CASE WHEN (x IS NOT NULL) THEN x ELSE 0 END
volatility | immutable
is_strict | f
If you want to change the body of a user-defined SQL function, use the CREATE OR REPLACE syntax. The following command modifies the CASE expression:
=> CREATE OR REPLACE FUNCTION myzeroifnull(x INT) RETURN INT
AS BEGIN
RETURN (CASE WHEN (x IS NULL) THEN 0 ELSE x END);
END;
Now when you query USER_FUNCTIONS, you can see the changes in the function_definition
column:
=> SELECT * FROM USER_FUNCTIONS;
-[ RECORD 1 ]----------+---------------------------------------------------
schema_name | public
function_name | myzeroifnull
function_return_type | Integer
function_argument_type | x Integer
function_definition | RETURN CASE WHEN (x IS NULL) THEN 0 ELSE x END
volatility | immutable
is_strict | f
If you use CREATE OR REPLACE syntax to change only the argument name or argument type (or both), the system maintains both versions of the function. For example, the following command tells the function to accept and return a numeric data type instead of an integer for the myzeroifnull
function:
=> CREATE OR REPLACE FUNCTION myzeroifnull(z NUMERIC) RETURN NUMERIC
AS BEGIN
RETURN (CASE WHEN (z IS NULL) THEN 0 ELSE z END);
END;
Now query the USER_FUNCTIONS table, and you can see the second instance of myzeroifnull
in Record 2, as well as the changes in the function_return_type
, function_argument_type
, and function_definition
columns.
Note
Record 1 still holds the original definition for the myzeroifnull
function:
=> SELECT * FROM USER_FUNCTIONS;
-[ RECORD 1 ]----------+------------------------------------------------------------
schema_name | public
function_name | myzeroifnull
function_return_type | Integer
function_argument_type | x Integer
function_definition | RETURN CASE WHEN (x IS NULL) THEN 0 ELSE x END
volatility | immutable
is_strict | f
-[ RECORD 2 ]----------+------------------------------------------------------------
schema_name | public
function_name | myzeroifnull
function_return_type | Numeric
function_argument_type | z Numeric
function_definition | RETURN (CASE WHEN (z IS NULL) THEN (0) ELSE z END)::numeric
volatility | immutable
is_strict | f
Because Vertica allows functions to share the same name with different argument types, you must specify the argument type when you alter or drop a function. If you do not, the system returns an error message:
=> DROP FUNCTION myzeroifnull();
ROLLBACK: Function with specified name and parameters does not exist: myzeroifnull
5 - Migrating built-in SQL functions
If you have built-in SQL functions from another RDBMS that do not map to a Vertica-supported function, you can migrate them into your Vertica database by using a user-defined SQL function.
If you have built-in SQL functions from another RDBMS that do not map to a Vertica-supported function, you can migrate them into your Vertica database by using a user-defined SQL function.
The example scripts below show how to create user-defined functions for the following DB2 built-in functions:
-
UCASE()
-
LCASE()
-
LOCATE()
-
POSSTR()
UCASE()
This script creates a user-defined SQL function for the UCASE()
function:
=> CREATE OR REPLACE FUNCTION UCASE (x VARCHAR)
RETURN VARCHAR
AS BEGIN
RETURN UPPER(x);
END;
LCASE()
This script creates a user-defined SQL function for the LCASE()
function:
=> CREATE OR REPLACE FUNCTION LCASE (x VARCHAR)
RETURN VARCHAR
AS BEGIN
RETURN LOWER(x);
END;
LOCATE()
This script creates a user-defined SQL function for the LOCATE()
function:
=> CREATE OR REPLACE FUNCTION LOCATE(a VARCHAR, b VARCHAR)
RETURN INT
AS BEGIN
RETURN POSITION(a IN b);
END;
POSSTR()
This script creates a user-defined SQL function for the POSSTR()
function:
=> CREATE OR REPLACE FUNCTION POSSTR(a VARCHAR, b VARCHAR)
RETURN INT
AS BEGIN
RETURN POSITION(b IN a);
END;