Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scalar NULL literal in aggregate functions are not supported (SQLancer) #11749

Closed
2010YOUY01 opened this issue Jul 31, 2024 · 2 comments · Fixed by #11812
Closed

Scalar NULL literal in aggregate functions are not supported (SQLancer) #11749

2010YOUY01 opened this issue Jul 31, 2024 · 2 comments · Fixed by #11812
Labels
bug Something isn't working

Comments

@2010YOUY01
Copy link
Contributor

Describe the bug

Literal scalar NULLs are generally not supported in aggregate functions.
I tried postgres and DuckDB, they all works, it's good to add small patches for NULL literals.

The fix could be:

  1. Find out all available aggregate functions that is not working for null literal
  2. Try to match the behavior of postgres

Reproducer in datafusion-cli

> select min(null);
Internal error: Min/Max accumulator not implemented for type Null.
This was likely caused by a bug in DataFusion's code and we would welcome that you file an bug report in our issue tracker
> select avg(null);
Error during planning: Execution error: User-defined coercion failed with Plan("The function \"avg\" does not support inputs of type Null.") No function matches the given name and argument types 'avg(Null)'. You might need to add explicit type casts.
        Candidate functions:
        avg(UserDefined)

To Reproduce

No response

Expected behavior

No response

Additional context

Found by SQLancer #11030

@2010YOUY01 2010YOUY01 added the bug Something isn't working label Jul 31, 2024
@xinlifoobar
Copy link
Contributor

take

@xinlifoobar
Copy link
Contributor

xinlifoobar commented Aug 5, 2024

I tested it on my machine and even on PostgreSQL the NULL literal support is very random. I limited the change to min/max while there are better error handling in other aggregate functions, e.g., stddev, in datafusion.

postgres=# select version();
                                        version                                        
---------------------------------------------------------------------------------------
 PostgreSQL 16.3 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 14.1.1 20240720, 64-bit
(1 row)

postgres=# select avg(NULL);
ERROR:  function avg(unknown) is not unique
LINE 1: select avg(NULL);
               ^
HINT:  Could not choose a best candidate function. You might need to add explicit type casts.

postgres=# select bit_and(NULL);
ERROR:  function bit_and(unknown) is not unique
LINE 1: select bit_and(NULL);
               ^
HINT:  Could not choose a best candidate function. You might need to add explicit type casts.

postgres=# select bit_or(NULL);
ERROR:  function bit_or(unknown) is not unique
LINE 1: select bit_or(NULL);
               ^
HINT:  Could not choose a best candidate function. You might need to add explicit type casts.

postgres=# select bool_and(NULL);
 bool_and 
----------
 
(1 row)


postgres=# select count(NULL);
 count 
-------
     0
(1 row)


postgres=# select count(DISTINCT NULL);
 count 
-------
     0
(1 row)


postgres=# select every(NULL);
 every 
-------
 
(1 row)


postgres=# select max(NULL);
 max 
-----
 
(1 row)


postgres=# select min(NULL);
 min 
-----
 
(1 row)


postgres=# select sum(NULL);
ERROR:  function sum(unknown) is not unique
LINE 1: select sum(NULL);
               ^
HINT:  Could not choose a best candidate function. You might need to add explicit type casts.

postgres=# select stddev(NULL);
 stddev 
--------
       
(1 row)


postgres=# select corr(NULL, NULL);
 corr 
------
     
(1 row)


postgres=# select covar_pop(NULL, NULL);
 covar_pop 
-----------
          
(1 row)


postgres=# select covar_samp(NULL, NULL);
 covar_samp 
------------
           
(1 row)


postgres=# select regr_avgx(NULL, NULL);
 regr_avgx 
-----------
          
(1 row)


postgres=# select regr_avgy(NULL, NULL);
 regr_avgy 
-----------
          
(1 row)


postgres=# select regr_count(NULL, NULL);
 regr_count 
------------
          0
(1 row)


postgres=# select regr_intercept(NULL, NULL);
 regr_intercept 
----------------
               
(1 row)


postgres=# select regr_r2(NULL, NULL);
 regr_r2 
---------
        
(1 row)


postgres=# select regr_slope(NULL, NULL);
 regr_slope 
------------
           
(1 row)


postgres=# select regr_sxx(NULL, NULL);
 regr_sxx 
----------
         
(1 row)


postgres=# select regr_sxy(NULL, NULL);
 regr_sxy 
----------
         
(1 row)


postgres=# select regr_syy(NULL, NULL);
 regr_syy 
----------
         
(1 row)


postgres=# select stddev_pop(NULL);
 stddev_pop 
------------
           
(1 row)


postgres=# select stddev_samp(NULL);
 stddev_samp 
-------------
            
(1 row)


postgres=# select variance(NULL);
 variance 
----------
         
(1 row)


postgres=# select var_pop(NULL);
 var_pop 
---------
        
(1 row)


postgres=# select var_samp(NULL);
 var_samp 
----------
         
(1 row)



Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants