diff --git a/ibis-server/resources/function_list/mssql.csv b/ibis-server/resources/function_list/mssql.csv index da2daae9b..79a62036b 100644 --- a/ibis-server/resources/function_list/mssql.csv +++ b/ibis-server/resources/function_list/mssql.csv @@ -1,105 +1,12 @@ -function_type,name,return_type,description -aggregate,avg,Numeric,"Returns the average of values in a group." -aggregate,count,Bigint,"Returns the number of items in a group." -aggregate,count_big,Bigint,"Returns the number of items in a group as bigint." -aggregate,grouping,Int,"Returns a bit indicating if row is aggregated or not." -aggregate,grouping_id,Int,"Returns level of grouping." -aggregate,max,Same as input,"Returns the maximum value in a group." -aggregate,min,Same as input,"Returns the minimum value in a group." -aggregate,sum,Numeric,"Returns the sum of all values in a group." -aggregate,stdev,Float,"Returns the statistical standard deviation of values." -aggregate,stdevp,Float,"Returns the population standard deviation." -aggregate,var,Float,"Returns the statistical variance of values." -aggregate,varp,Float,"Returns the population statistical variance." -aggregate,string_agg,String,"Concatenates strings with separator." -aggregate,checksum_agg,Int,"Returns checksum of values." -scalar,abs,Numeric,"Returns absolute value." -scalar,acos,Float,"Returns arc cosine value." -scalar,asin,Float,"Returns arc sine value." -scalar,atan,Float,"Returns arc tangent value." -scalar,atn2,Float,"Returns angle in radians between x-axis and line." -scalar,ceiling,Numeric,"Returns smallest integer greater than number." -scalar,cos,Float,"Returns cosine value." -scalar,cot,Float,"Returns cotangent value." -scalar,degrees,Float,"Converts radians to degrees." -scalar,exp,Float,"Returns exponential value." -scalar,floor,Numeric,"Returns largest integer less than number." -scalar,log,Float,"Returns natural logarithm." -scalar,log10,Float,"Returns base-10 logarithm." -scalar,pi,Float,"Returns value of PI." -scalar,power,Float,"Returns value raised to specified power." -scalar,radians,Float,"Converts degrees to radians." -scalar,rand,Float,"Returns random float between 0 and 1." -scalar,round,Numeric,"Rounds numeric value." -scalar,sign,Int,"Returns sign of number (+1, -1, 0)." -scalar,sin,Float,"Returns sine value." -scalar,sqrt,Float,"Returns square root." -scalar,square,Float,"Returns square of number." -scalar,tan,Float,"Returns tangent value." -scalar,ascii,Int,"Returns ASCII code of leftmost character." -scalar,char,Char,"Returns character with specified ASCII code." -scalar,charindex,Int,"Returns starting position of string." -scalar,concat,String,"Concatenates strings." -scalar,concat_ws,String,"Concatenates strings with separator." -scalar,datalength,Int,"Returns number of bytes used." -scalar,difference,Int,"Returns difference between SOUNDEX values." -scalar,format,String,"Returns formatted value." -scalar,left,String,"Returns leftmost characters." -scalar,len,Int,"Returns number of characters." -scalar,lower,String,"Converts string to lowercase." -scalar,ltrim,String,"Removes leading spaces." -scalar,nchar,String,"Returns Unicode character." -scalar,patindex,Int,"Returns starting position of pattern." -scalar,quotename,String,"Returns delimited identifier." -scalar,replace,String,"Replaces string values." -scalar,replicate,String,"Repeats string value." -scalar,reverse,String,"Returns reverse of string." -scalar,right,String,"Returns rightmost characters." -scalar,rtrim,String,"Removes trailing spaces." -scalar,soundex,String,"Returns SOUNDEX code." -scalar,space,String,"Returns string of spaces." -scalar,str,String,"Returns string from numeric." -scalar,stuff,String,"Deletes and inserts string." -scalar,substring,String,"Returns part of string." -scalar,trim,String,"Removes leading and trailing spaces." -scalar,unicode,Int,"Returns Unicode value." -scalar,upper,String,"Converts string to uppercase." -scalar,cast,Any,"Converts value to specified type." -scalar,convert,Any,"Converts value to specified type." -scalar,coalesce,Same as input,"Returns first non-null value." -scalar,nullif,Same as input,"Returns NULL if values equal." -scalar,isnull,Same as input,"Replaces NULL with specified value." -scalar,iif,Same as input,"Returns value based on Boolean expression." -scalar,choose,Same as input,"Returns item at specified index." -scalar,dateadd,Datetime,"Adds interval to date." -scalar,datediff,Int,"Returns difference between dates." -scalar,datefromparts,Date,"Returns date from parts." -scalar,datename,String,"Returns date part as string." -scalar,datepart,Int,"Returns date part as integer." -scalar,day,Int,"Returns day of month." -scalar,getdate,Datetime,"Returns current date and time." -scalar,getutcdate,Datetime,"Returns current UTC date and time." -scalar,isdate,Int,"Checks if value is valid date." -scalar,month,Int,"Returns month part." -scalar,sysdatetime,Datetime2,"Returns date and time of SQL Server." -scalar,year,Int,"Returns year part." -scalar,current_user,String,"Returns current user name." -scalar,host_name,String,"Returns workstation name." -scalar,isnumeric,Int,"Checks if value is numeric." -scalar,newid,Uniqueidentifier,"Returns new GUID." -scalar,serverproperty,Any,"Returns server property info." -scalar,session_user,String,"Returns session user name." -scalar,system_user,String,"Returns login name." -scalar,user_name,String,"Returns database user name." -window,row_number,Bigint,"Returns sequential row number." -window,rank,Bigint,"Returns rank with gaps." -window,dense_rank,Bigint,"Returns rank without gaps." -window,ntile,Bigint,"Distributes rows into groups." -window,lag,Same as input,"Returns previous row value." -window,lead,Same as input,"Returns next row value." -window,first_value,Same as input,"Returns first value in window." -window,last_value,Same as input,"Returns last value in window." -window,cume_dist,Float,"Returns cumulative distribution." -window,percent_rank,Float,"Returns relative rank of row." -window,percentile_cont,Float,"Returns percentile based on continuous distribution." -window,percentile_disc,Same as input,"Returns percentile based on discrete distribution." +function_type,name,return_type,param_names,param_types,description +scalar,ceil,Numeric,,decimal,"Returns smallest integer greater than number." +scalar,floor,Numeric,,decimal,"Returns largest integer less than number." +scalar,pi,Float,,, "Returns value of PI." +scalar,getdate,Datetime,,, "Returns current date and time." +scalar,getutcdate,Datetime,,, "Returns current UTC date and time." +scalar,sysdatetime,Datetime,,, "Returns date and time of SQL Server." +scalar,host_name,String,,, "Returns workstation name." +scalar,newid,String,,, "Returns new GUID." +scalar,user_name,String,,, "Returns database user name." +scalar,upper,String,,varchar,"Converts string to uppercase." +scalar,lower,String,,varchar,"Converts string to lowercase." diff --git a/ibis-server/tests/routers/v3/connector/mssql/test_functions.py b/ibis-server/tests/routers/v3/connector/mssql/test_functions.py index 5400334e7..85648d254 100644 --- a/ibis-server/tests/routers/v3/connector/mssql/test_functions.py +++ b/ibis-server/tests/routers/v3/connector/mssql/test_functions.py @@ -1,4 +1,5 @@ import base64 +import os import orjson import pytest @@ -8,6 +9,7 @@ from app.main import app from tests.conftest import DATAFUSION_FUNCTION_COUNT, file_path from tests.routers.v3.connector.mssql.conftest import base_url +from tests.util import FunctionCsvParser, SqlTestGenerator manifest = { "catalog": "my_catalog", @@ -57,14 +59,14 @@ def test_function_list(): response = client.get(url=f"{base_url}/functions") assert response.status_code == 200 result = response.json() - assert len(result) == DATAFUSION_FUNCTION_COUNT + 52 - the_func = next(filter(lambda x: x["name"] == "abs", result)) + assert len(result) == DATAFUSION_FUNCTION_COUNT + 6 + the_func = next(filter(lambda x: x["name"] == "floor", result)) assert the_func == { - "name": "abs", - "description": "Returns absolute value.", + "name": "floor", + "description": "Returns largest integer less than number.", "function_type": "scalar", "param_names": None, - "param_types": None, + "param_types": "decimal", "return_type": "Numeric", } @@ -107,3 +109,18 @@ def test_aggregate_function(manifest_str: str, connection_info): "data": [[1]], "dtypes": {"col": "int64"}, } + + def test_functions(manifest_str: str, connection_info): + csv_parser = FunctionCsvParser(os.path.join(function_list_path, "mssql.csv")) + sql_generator = SqlTestGenerator("mssql") + for function in csv_parser.parse(): + sql = sql_generator.generate_sql(function) + response = client.post( + url=f"{base_url}/query", + json={ + "connectionInfo": connection_info, + "manifestStr": manifest_str, + "sql": sql, + }, + ) + assert response.status_code == 200 diff --git a/ibis-server/tests/util/sql_generator.py b/ibis-server/tests/util/sql_generator.py index fb5f73847..2548ddf2f 100644 --- a/ibis-server/tests/util/sql_generator.py +++ b/ibis-server/tests/util/sql_generator.py @@ -28,6 +28,8 @@ def _get_generator(self): return PostgresSqlGenerator() if self.dialect == "mysql": return MySqlGenerator() + if self.dialect == "mssql": + return MSSqlGenerator() raise NotImplementedError(f"Unsupported dialect: {self.dialect}") @staticmethod @@ -164,3 +166,28 @@ def generate_scalar_sql(self, function: Function) -> str: args = self.generate_sample_args(function.param_types) formatted_args = ", ".join(args) return f"SELECT {function.name}({formatted_args})" + + +class MSSqlGenerator(SqlGenerator): + def generate_aggregate_sql(self, function: Function) -> str: + sample_args = self.generate_sample_args(function.param_types) + formatted_args = ", ".join(sample_args) + return f"SELECT {function.name}({formatted_args})" + + def generate_scalar_sql(self, function: Function) -> str: + args = self.generate_sample_args(function.param_types) + formatted_args = ", ".join(args) + return f"SELECT {function.name}({formatted_args})" + + def generate_window_sql(self, function: Function) -> str: + return f""" + SELECT + {function.name}() OVER (ORDER BY id) AS {function.name.lower()} + FROM ( + SELECT 1 AS id, 'A' AS category UNION ALL + SELECT 2 AS id, 'B' AS category UNION ALL + SELECT 3 AS id, 'A' AS category UNION ALL + SELECT 4 AS id, 'B' AS category UNION ALL + SELECT 5 AS id, 'A' AS category + ) AS t + """