[ 
https://issues.apache.org/jira/browse/SPARK-60806?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Ganesha S updated SPARK-60806:
------------------------------
    Description: 
CREATE FUNCTION decides whether a permanent SQL function references a temporary 
function by scanning the unresolved body for called names that match a 
temporary function, not by checking which function each call actually resolves 
to. So it rejects valid functions and accepts invalid ones:
 - Over-rejection: a temporary function that only shares a name with a built-in 
blocks a body calling that built-in.
 - Under-rejection: the scan only matches plain scalar calls, so a body that 
calls a temporary table function, or a temporary function named through 
IDENTIFIER(...), is accepted. The permanent function then only works in the 
session that created it.

*Steps to reproduce (default settings; verified on master):*
{code:java}
-- Over-rejection: the built-in owns abs, yet the body is rejected.
CREATE TEMPORARY FUNCTION abs(x INT) RETURNS INT RETURN 42;
SELECT abs(-1);                                                          -- 1 
(the built-in)
CREATE FUNCTION p_abs() RETURNS INT RETURN abs(-1);                      -- 
INVALID_TEMP_OBJ_REFERENCE
DROP TEMPORARY FUNCTION abs;
-- Under-rejection: permanent functions that depend on temporary functions are 
accepted.
CREATE TEMPORARY FUNCTION temp_tvf() RETURNS TABLE (a INT) RETURN SELECT 1;
CREATE FUNCTION p_tvf() RETURNS TABLE (a INT) RETURN SELECT * FROM temp_tvf();  
-- succeeds
CREATE TEMPORARY FUNCTION temp_fn() RETURNS INT RETURN 1;
CREATE FUNCTION p_id() RETURNS INT RETURN IDENTIFIER('temp_fn')();       -- 
succeeds
SELECT * FROM p_tvf();                                                   -- 1 
(this session only)
SELECT p_id();                                                           -- 1 
(this session only)
-- In any other session (e.g. spark.newSession()):
SELECT * FROM p_tvf();                                                   -- 
UNRESOLVABLE_TABLE_VALUED_FUNCTION
SELECT p_id();                                                           -- 
UNRESOLVED_ROUTINE
Expected behavior:
- p_abs is created and returns 1, because the built-in owns the call.
- p_tvf and p_id fail with INVALID_TEMP_OBJ_REFERENCE.
{code}
 

{*}Proposed fix{*}: as CREATE VIEW already does, reject only the temporary 
functions that analysis of the body actually binds 
(AnalysisContext.referredTempFunctionNames), and report them in sorted order so 
the error is deterministic.

*Compatibility:* rejecting p_tvf and p_id is a behavior change for CREATE 
FUNCTION statements that succeed today. It needs a migration-guide entry, and 
possibly a legacy config to restore the old behavior.

  was:
CREATE FUNCTION decides whether a permanent SQL function references a temporary 
function by scanning the unresolved body for called names that match a 
temporary function, not by checking which function each call actually resolves 
to. So it rejects valid functions and accepts invalid ones:
 - Over-rejection: a temporary function that only shares a name with a built-in 
blocks a body calling that built-in.
 - Under-rejection: the scan only matches plain scalar calls, so a body that 
calls a temporary table function, or a temporary function named through 
IDENTIFIER(...), is accepted. The permanent function then only works in the 
session that created it.

*Steps to reproduce (default settings; verified on master):*

 
{code:java}
-- Over-rejection: the built-in owns abs, yet the body is rejected.
CREATE TEMPORARY FUNCTION abs(x INT) RETURNS INT RETURN 42;
SELECT abs(-1);                                                          -- 1 
(the built-in)
CREATE FUNCTION p_abs() RETURNS INT RETURN abs(-1);                      -- 
INVALID_TEMP_OBJ_REFERENCE
DROP TEMPORARY FUNCTION abs;
-- Under-rejection: permanent functions that depend on temporary functions are 
accepted.
CREATE TEMPORARY FUNCTION temp_tvf() RETURNS TABLE (a INT) RETURN SELECT 1;
CREATE FUNCTION p_tvf() RETURNS TABLE (a INT) RETURN SELECT * FROM temp_tvf();  
-- succeeds
CREATE TEMPORARY FUNCTION temp_fn() RETURNS INT RETURN 1;
CREATE FUNCTION p_id() RETURNS INT RETURN IDENTIFIER('temp_fn')();       -- 
succeeds
SELECT * FROM p_tvf();                                                   -- 1 
(this session only)
SELECT p_id();                                                           -- 1 
(this session only)
-- In any other session (e.g. spark.newSession()):
SELECT * FROM p_tvf();                                                   -- 
UNRESOLVABLE_TABLE_VALUED_FUNCTION
SELECT p_id();                                                           -- 
UNRESOLVED_ROUTINE
Expected behavior:
- p_abs is created and returns 1, because the built-in owns the call.
- p_tvf and p_id fail with INVALID_TEMP_OBJ_REFERENCE.
{code}
 

{*}Proposed fix{*}: as CREATE VIEW already does, reject only the temporary 
functions that analysis of the body actually binds 
(AnalysisContext.referredTempFunctionNames), and report them in sorted order so 
the error is deterministic.

*Compatibility:* rejecting p_tvf and p_id is a behavior change for CREATE 
FUNCTION statements that succeed today. It needs a migration-guide entry, and 
possibly a legacy config to restore the old behavior.


> CREATE FUNCTION should reject only the temporary functions a permanent 
> function's body actually calls
> -----------------------------------------------------------------------------------------------------
>
>                 Key: SPARK-60806
>                 URL: https://issues.apache.org/jira/browse/SPARK-60806
>             Project: Spark
>          Issue Type: Bug
>          Components: SQL
>    Affects Versions: 4.4.0
>            Reporter: Ganesha S
>            Priority: Major
>
> CREATE FUNCTION decides whether a permanent SQL function references a 
> temporary function by scanning the unresolved body for called names that 
> match a temporary function, not by checking which function each call actually 
> resolves to. So it rejects valid functions and accepts invalid ones:
>  - Over-rejection: a temporary function that only shares a name with a 
> built-in blocks a body calling that built-in.
>  - Under-rejection: the scan only matches plain scalar calls, so a body that 
> calls a temporary table function, or a temporary function named through 
> IDENTIFIER(...), is accepted. The permanent function then only works in the 
> session that created it.
> *Steps to reproduce (default settings; verified on master):*
> {code:java}
> -- Over-rejection: the built-in owns abs, yet the body is rejected.
> CREATE TEMPORARY FUNCTION abs(x INT) RETURNS INT RETURN 42;
> SELECT abs(-1);                                                          -- 1 
> (the built-in)
> CREATE FUNCTION p_abs() RETURNS INT RETURN abs(-1);                      -- 
> INVALID_TEMP_OBJ_REFERENCE
> DROP TEMPORARY FUNCTION abs;
> -- Under-rejection: permanent functions that depend on temporary functions 
> are accepted.
> CREATE TEMPORARY FUNCTION temp_tvf() RETURNS TABLE (a INT) RETURN SELECT 1;
> CREATE FUNCTION p_tvf() RETURNS TABLE (a INT) RETURN SELECT * FROM 
> temp_tvf();  -- succeeds
> CREATE TEMPORARY FUNCTION temp_fn() RETURNS INT RETURN 1;
> CREATE FUNCTION p_id() RETURNS INT RETURN IDENTIFIER('temp_fn')();       -- 
> succeeds
> SELECT * FROM p_tvf();                                                   -- 1 
> (this session only)
> SELECT p_id();                                                           -- 1 
> (this session only)
> -- In any other session (e.g. spark.newSession()):
> SELECT * FROM p_tvf();                                                   -- 
> UNRESOLVABLE_TABLE_VALUED_FUNCTION
> SELECT p_id();                                                           -- 
> UNRESOLVED_ROUTINE
> Expected behavior:
> - p_abs is created and returns 1, because the built-in owns the call.
> - p_tvf and p_id fail with INVALID_TEMP_OBJ_REFERENCE.
> {code}
>  
> {*}Proposed fix{*}: as CREATE VIEW already does, reject only the temporary 
> functions that analysis of the body actually binds 
> (AnalysisContext.referredTempFunctionNames), and report them in sorted order 
> so the error is deterministic.
> *Compatibility:* rejecting p_tvf and p_id is a behavior change for CREATE 
> FUNCTION statements that succeed today. It needs a migration-guide entry, and 
> possibly a legacy config to restore the old behavior.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to