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

test(mssql): test all functions #950

Merged
merged 4 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 12 additions & 105 deletions ibis-server/resources/function_list/mssql.csv
Original file line number Diff line number Diff line change
@@ -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."
27 changes: 22 additions & 5 deletions ibis-server/tests/routers/v3/connector/mssql/test_functions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import base64
import os

import orjson
import pytest
Expand All @@ -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",
Expand Down Expand Up @@ -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",
}

Expand Down Expand Up @@ -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
27 changes: 27 additions & 0 deletions ibis-server/tests/util/sql_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
"""