diff --git a/docs/supported_ops.md b/docs/supported_ops.md index d4e9a101eb1..82db15724f7 100644 --- a/docs/supported_ops.md +++ b/docs/supported_ops.md @@ -5406,7 +5406,7 @@ are limited. NS NS -NS +PS
UTC is only supported TZ for child TIMESTAMP;
unsupported child types BINARY, CALENDAR, ARRAY, UDT
NS @@ -5427,7 +5427,7 @@ are limited. NS NS -NS +PS
UTC is only supported TZ for child TIMESTAMP;
unsupported child types BINARY, CALENDAR, ARRAY, UDT
NS @@ -6298,7 +6298,7 @@ are limited. NS NS -NS +PS
UTC is only supported TZ for child TIMESTAMP;
unsupported child types BINARY, CALENDAR, ARRAY, UDT
NS @@ -6319,7 +6319,7 @@ are limited. NS NS -NS +PS
UTC is only supported TZ for child TIMESTAMP;
unsupported child types BINARY, CALENDAR, ARRAY, UDT
NS @@ -6456,7 +6456,7 @@ are limited. NS NS -NS +PS
UTC is only supported TZ for child TIMESTAMP;
unsupported child types BINARY, CALENDAR, ARRAY, UDT
NS @@ -6477,7 +6477,7 @@ are limited. NS NS -NS +PS
UTC is only supported TZ for child TIMESTAMP;
unsupported child types BINARY, CALENDAR, ARRAY, UDT
NS @@ -7847,7 +7847,7 @@ are limited. NS NS -NS +PS
UTC is only supported TZ for child TIMESTAMP;
unsupported child types BINARY, CALENDAR, ARRAY, UDT
NS @@ -7868,7 +7868,7 @@ are limited. NS NS -NS +PS
UTC is only supported TZ for child TIMESTAMP;
unsupported child types BINARY, CALENDAR, ARRAY, UDT
NS @@ -8005,7 +8005,7 @@ are limited. NS NS -NS +PS
UTC is only supported TZ for child TIMESTAMP;
unsupported child types BINARY, CALENDAR, ARRAY, UDT
NS @@ -8026,7 +8026,7 @@ are limited. NS NS -NS +PS
UTC is only supported TZ for child TIMESTAMP;
unsupported child types BINARY, CALENDAR, ARRAY, UDT
NS diff --git a/integration_tests/src/main/python/cmp_test.py b/integration_tests/src/main/python/cmp_test.py index 3bc99d85a8c..adfad336f18 100644 --- a/integration_tests/src/main/python/cmp_test.py +++ b/integration_tests/src/main/python/cmp_test.py @@ -20,7 +20,7 @@ from pyspark.sql.types import * import pyspark.sql.functions as f -@pytest.mark.parametrize('data_gen', eq_gens_with_decimal_gen, ids=idfn) +@pytest.mark.parametrize('data_gen', eq_gens_with_decimal_gen + struct_gens_sample_with_decimal128_no_list, ids=idfn) def test_eq(data_gen): (s1, s2) = gen_scalars(data_gen, 2, force_no_nulls=not isinstance(data_gen, NullGen)) data_type = data_gen.data_type @@ -34,16 +34,23 @@ def test_eq(data_gen): @pytest.mark.skipif(is_before_spark_330(), reason='DayTimeInterval is not supported before Pyspark 3.3.0') def test_eq_for_interval(): - data_gen = DayTimeIntervalGen() - (s1, s2) = gen_scalars(data_gen, 2, force_no_nulls=not isinstance(data_gen, NullGen)) - data_type = data_gen.data_type - assert_gpu_and_cpu_are_equal_collect( - lambda spark : binary_op_df(spark, data_gen).select( - f.col('a') == s1, - s2 == f.col('b'), - f.lit(None).cast(data_type) == f.col('a'), - f.col('b') == f.lit(None).cast(data_type), - f.col('a') == f.col('b'))) + def test_func(data_gen): + (s1, s2) = gen_scalars(data_gen, 2, force_no_nulls=not isinstance(data_gen, NullGen)) + data_type = data_gen.data_type + assert_gpu_and_cpu_are_equal_collect( + lambda spark : binary_op_df(spark, data_gen).select( + f.col('a') == s1, + s2 == f.col('b'), + f.lit(None).cast(data_type) == f.col('a'), + f.col('b') == f.lit(None).cast(data_type), + f.col('a') == f.col('b'))) + # DayTimeIntervalType not supported inside Structs -- issue #6184 + # data_gens = [DayTimeIntervalGen(), + # StructGen([['child0', StructGen([['child2', DayTimeIntervalGen()]])], ['child1', short_gen]])] + data_gens = [DayTimeIntervalGen()] + for data_gen in data_gens: + test_func(data_gen) + @pytest.mark.parametrize('data_gen', eq_gens_with_decimal_gen, ids=idfn) def test_eq_ns(data_gen): @@ -70,7 +77,7 @@ def test_eq_ns_for_interval(): f.col('b').eqNullSafe(f.lit(None).cast(data_type)), f.col('a').eqNullSafe(f.col('b')))) -@pytest.mark.parametrize('data_gen', eq_gens_with_decimal_gen, ids=idfn) +@pytest.mark.parametrize('data_gen', eq_gens_with_decimal_gen + struct_gens_sample_with_decimal128_no_list, ids=idfn) def test_ne(data_gen): (s1, s2) = gen_scalars(data_gen, 2, force_no_nulls=not isinstance(data_gen, NullGen)) data_type = data_gen.data_type @@ -84,18 +91,24 @@ def test_ne(data_gen): @pytest.mark.skipif(is_before_spark_330(), reason='DayTimeInterval is not supported before Pyspark 3.3.0') def test_ne_for_interval(): - data_gen = DayTimeIntervalGen() - (s1, s2) = gen_scalars(data_gen, 2, force_no_nulls=not isinstance(data_gen, NullGen)) - data_type = data_gen.data_type - assert_gpu_and_cpu_are_equal_collect( - lambda spark : binary_op_df(spark, data_gen).select( - f.col('a') != s1, - s2 != f.col('b'), - f.lit(None).cast(data_type) != f.col('a'), - f.col('b') != f.lit(None).cast(data_type), - f.col('a') != f.col('b'))) + def test_func(data_gen): + (s1, s2) = gen_scalars(data_gen, 2, force_no_nulls=not isinstance(data_gen, NullGen)) + data_type = data_gen.data_type + assert_gpu_and_cpu_are_equal_collect( + lambda spark : binary_op_df(spark, data_gen).select( + f.col('a') != s1, + s2 != f.col('b'), + f.lit(None).cast(data_type) != f.col('a'), + f.col('b') != f.lit(None).cast(data_type), + f.col('a') != f.col('b'))) + # DayTimeIntervalType not supported inside Structs -- issue #6184 + # data_gens = [DayTimeIntervalGen(), + # StructGen([['child0', StructGen([['child2', DayTimeIntervalGen()]])], ['child1', short_gen]])] + data_gens = [DayTimeIntervalGen()] + for data_gen in data_gens: + test_func(data_gen) -@pytest.mark.parametrize('data_gen', orderable_gens, ids=idfn) +@pytest.mark.parametrize('data_gen', orderable_gens + struct_gens_sample_with_decimal128_no_list, ids=idfn) def test_lt(data_gen): (s1, s2) = gen_scalars(data_gen, 2, force_no_nulls=not isinstance(data_gen, NullGen)) data_type = data_gen.data_type @@ -109,18 +122,24 @@ def test_lt(data_gen): @pytest.mark.skipif(is_before_spark_330(), reason='DayTimeInterval is not supported before Pyspark 3.3.0') def test_lt_for_interval(): - data_gen = DayTimeIntervalGen() - (s1, s2) = gen_scalars(data_gen, 2, force_no_nulls=not isinstance(data_gen, NullGen)) - data_type = data_gen.data_type - assert_gpu_and_cpu_are_equal_collect( - lambda spark : binary_op_df(spark, data_gen).select( - f.col('a') < s1, - s2 < f.col('b'), - f.lit(None).cast(data_type) < f.col('a'), - f.col('b') < f.lit(None).cast(data_type), - f.col('a') < f.col('b'))) + def test_func(data_gen): + (s1, s2) = gen_scalars(data_gen, 2, force_no_nulls=not isinstance(data_gen, NullGen)) + data_type = data_gen.data_type + assert_gpu_and_cpu_are_equal_collect( + lambda spark : binary_op_df(spark, data_gen).select( + f.col('a') < s1, + s2 < f.col('b'), + f.lit(None).cast(data_type) < f.col('a'), + f.col('b') < f.lit(None).cast(data_type), + f.col('a') < f.col('b'))) + # DayTimeIntervalType not supported inside Structs -- issue #6184 + # data_gens = [DayTimeIntervalGen(), + # StructGen([['child0', StructGen([['child2', DayTimeIntervalGen()]])], ['child1', short_gen]])] + data_gens = [DayTimeIntervalGen()] + for data_gen in data_gens: + test_func(data_gen) -@pytest.mark.parametrize('data_gen', orderable_gens, ids=idfn) +@pytest.mark.parametrize('data_gen', orderable_gens + struct_gens_sample_with_decimal128_no_list, ids=idfn) def test_lte(data_gen): (s1, s2) = gen_scalars(data_gen, 2, force_no_nulls=not isinstance(data_gen, NullGen)) data_type = data_gen.data_type @@ -134,16 +153,22 @@ def test_lte(data_gen): @pytest.mark.skipif(is_before_spark_330(), reason='DayTimeInterval is not supported before Pyspark 3.3.0') def test_lte_for_interval(): - data_gen = DayTimeIntervalGen() - (s1, s2) = gen_scalars(data_gen, 2, force_no_nulls=not isinstance(data_gen, NullGen)) - data_type = data_gen.data_type - assert_gpu_and_cpu_are_equal_collect( - lambda spark : binary_op_df(spark, data_gen).select( - f.col('a') <= s1, - s2 <= f.col('b'), - f.lit(None).cast(data_type) <= f.col('a'), - f.col('b') <= f.lit(None).cast(data_type), - f.col('a') <= f.col('b'))) + def test_func(data_gen): + (s1, s2) = gen_scalars(data_gen, 2, force_no_nulls=not isinstance(data_gen, NullGen)) + data_type = data_gen.data_type + assert_gpu_and_cpu_are_equal_collect( + lambda spark : binary_op_df(spark, data_gen).select( + f.col('a') <= s1, + s2 <= f.col('b'), + f.lit(None).cast(data_type) <= f.col('a'), + f.col('b') <= f.lit(None).cast(data_type), + f.col('a') <= f.col('b'))) + # DayTimeIntervalType not supported inside Structs -- issue #6184 + # data_gens = [DayTimeIntervalGen(), + # StructGen([['child0', StructGen([['child2', DayTimeIntervalGen()]])], ['child1', short_gen]])] + data_gens = [DayTimeIntervalGen()] + for data_gen in data_gens: + test_func(data_gen) @pytest.mark.parametrize('data_gen', orderable_gens, ids=idfn) @@ -160,18 +185,24 @@ def test_gt(data_gen): @pytest.mark.skipif(is_before_spark_330(), reason='DayTimeInterval is not supported before Pyspark 3.3.0') def test_gt_interval(): - data_gen = DayTimeIntervalGen() - (s1, s2) = gen_scalars(data_gen, 2, force_no_nulls=not isinstance(data_gen, NullGen)) - data_type = data_gen.data_type - assert_gpu_and_cpu_are_equal_collect( - lambda spark : binary_op_df(spark, data_gen).select( - f.col('a') > s1, - s2 > f.col('b'), - f.lit(None).cast(data_type) > f.col('a'), - f.col('b') > f.lit(None).cast(data_type), - f.col('a') > f.col('b'))) + def test_func(data_gen): + (s1, s2) = gen_scalars(data_gen, 2, force_no_nulls=not isinstance(data_gen, NullGen)) + data_type = data_gen.data_type + assert_gpu_and_cpu_are_equal_collect( + lambda spark : binary_op_df(spark, data_gen).select( + f.col('a') > s1, + s2 > f.col('b'), + f.lit(None).cast(data_type) > f.col('a'), + f.col('b') > f.lit(None).cast(data_type), + f.col('a') > f.col('b'))) + # DayTimeIntervalType not supported inside Structs -- issue #6184 + # data_gens = [DayTimeIntervalGen(), + # StructGen([['child0', StructGen([['child2', DayTimeIntervalGen()]])], ['child1', short_gen]])] + data_gens = [DayTimeIntervalGen()] + for data_gen in data_gens: + test_func(data_gen) -@pytest.mark.parametrize('data_gen', orderable_gens, ids=idfn) +@pytest.mark.parametrize('data_gen', orderable_gens + struct_gens_sample_with_decimal128_no_list, ids=idfn) def test_gte(data_gen): (s1, s2) = gen_scalars(data_gen, 2, force_no_nulls=not isinstance(data_gen, NullGen)) data_type = data_gen.data_type @@ -185,16 +216,22 @@ def test_gte(data_gen): @pytest.mark.skipif(is_before_spark_330(), reason='DayTimeInterval is not supported before Pyspark 3.3.0') def test_gte_for_interval(): - data_gen = DayTimeIntervalGen() - (s1, s2) = gen_scalars(data_gen, 2, force_no_nulls=not isinstance(data_gen, NullGen)) - data_type = data_gen.data_type - assert_gpu_and_cpu_are_equal_collect( - lambda spark : binary_op_df(spark, data_gen).select( - f.col('a') >= s1, - s2 >= f.col('b'), - f.lit(None).cast(data_type) >= f.col('a'), - f.col('b') >= f.lit(None).cast(data_type), - f.col('a') >= f.col('b'))) + def test_func(data_gen): + (s1, s2) = gen_scalars(data_gen, 2, force_no_nulls=not isinstance(data_gen, NullGen)) + data_type = data_gen.data_type + assert_gpu_and_cpu_are_equal_collect( + lambda spark : binary_op_df(spark, data_gen).select( + f.col('a') >= s1, + s2 >= f.col('b'), + f.lit(None).cast(data_type) >= f.col('a'), + f.col('b') >= f.lit(None).cast(data_type), + f.col('a') >= f.col('b'))) + # DayTimeIntervalType not supported inside Structs -- issue #6184 + # data_gens = [DayTimeIntervalGen(), + # StructGen([['child0', StructGen([['child2', DayTimeIntervalGen()]])], ['child1', short_gen]])] + data_gens = [DayTimeIntervalGen()] + for data_gen in data_gens: + test_func(data_gen) @pytest.mark.parametrize('data_gen', eq_gens_with_decimal_gen + array_gens_sample + struct_gens_sample + map_gens_sample, ids=idfn) def test_isnull(data_gen): diff --git a/integration_tests/src/main/python/data_gen.py b/integration_tests/src/main/python/data_gen.py index e9057b77d6b..ce5a92571ca 100644 --- a/integration_tests/src/main/python/data_gen.py +++ b/integration_tests/src/main/python/data_gen.py @@ -953,11 +953,16 @@ def gen_scalars_for_sql(data_gen, count, seed=0, force_no_nulls=False): nonempty_struct_gens_sample = [all_basic_struct_gen, StructGen([['child0', byte_gen], ['child1', all_basic_struct_gen]]), StructGen([['child0', ArrayGen(short_gen)], ['child1', double_gen]])] +nonempty_struct_gens_sample_no_list = [all_basic_struct_gen, + StructGen([['child0', byte_gen], ['child1', all_basic_struct_gen]]), + StructGen([['child0', short_gen], ['child1', double_gen]])] struct_gens_sample = nonempty_struct_gens_sample + [StructGen([])] +struct_gens_sample_no_list = nonempty_struct_gens_sample_no_list + [StructGen([])] struct_gen_decimal128 = StructGen( [['child' + str(ind), sub_gen] for ind, sub_gen in enumerate([decimal_gen_128bit])]) struct_gens_sample_with_decimal128 = struct_gens_sample + [struct_gen_decimal128] +struct_gens_sample_with_decimal128_no_list = struct_gens_sample_no_list + [struct_gen_decimal128] simple_string_to_string_map_gen = MapGen(StringGen(pattern='key_[0-9]', nullable=False), StringGen(), max_length=10) diff --git a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuOverrides.scala b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuOverrides.scala index 0b094588c30..e98562de148 100644 --- a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuOverrides.scala +++ b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuOverrides.scala @@ -1971,11 +1971,11 @@ object GpuOverrides extends Logging { ExprChecks.binaryProjectAndAst( TypeSig.comparisonAstTypes, TypeSig.BOOLEAN, TypeSig.BOOLEAN, - ("lhs", TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + - GpuTypeShims.additionalPredicateSupportedTypes, + ("lhs", (TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + + GpuTypeShims.additionalPredicateSupportedTypes + TypeSig.STRUCT).nested(), TypeSig.comparable), - ("rhs", TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + - GpuTypeShims.additionalPredicateSupportedTypes, + ("rhs", (TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + + GpuTypeShims.additionalPredicateSupportedTypes + TypeSig.STRUCT).nested(), TypeSig.comparable)), (a, conf, p, r) => new BinaryAstExprMeta[EqualTo](a, conf, p, r) { override def convertToGpu(lhs: Expression, rhs: Expression): GpuExpression = @@ -1986,11 +1986,11 @@ object GpuOverrides extends Logging { ExprChecks.binaryProjectAndAst( TypeSig.comparisonAstTypes, TypeSig.BOOLEAN, TypeSig.BOOLEAN, - ("lhs", TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + - GpuTypeShims.additionalPredicateSupportedTypes, + ("lhs", (TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + + GpuTypeShims.additionalPredicateSupportedTypes + TypeSig.STRUCT).nested(), TypeSig.orderable), - ("rhs", TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + - GpuTypeShims.additionalPredicateSupportedTypes, + ("rhs", (TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + + GpuTypeShims.additionalPredicateSupportedTypes + TypeSig.STRUCT).nested(), TypeSig.orderable)), (a, conf, p, r) => new BinaryAstExprMeta[GreaterThan](a, conf, p, r) { override def convertToGpu(lhs: Expression, rhs: Expression): GpuExpression = @@ -2001,11 +2001,11 @@ object GpuOverrides extends Logging { ExprChecks.binaryProjectAndAst( TypeSig.comparisonAstTypes, TypeSig.BOOLEAN, TypeSig.BOOLEAN, - ("lhs", TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + - GpuTypeShims.additionalPredicateSupportedTypes, + ("lhs", (TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + + GpuTypeShims.additionalPredicateSupportedTypes + TypeSig.STRUCT).nested(), TypeSig.orderable), - ("rhs", TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + - GpuTypeShims.additionalPredicateSupportedTypes, + ("rhs", (TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + + GpuTypeShims.additionalPredicateSupportedTypes + TypeSig.STRUCT).nested(), TypeSig.orderable)), (a, conf, p, r) => new BinaryAstExprMeta[GreaterThanOrEqual](a, conf, p, r) { override def convertToGpu(lhs: Expression, rhs: Expression): GpuExpression = @@ -2051,11 +2051,11 @@ object GpuOverrides extends Logging { ExprChecks.binaryProjectAndAst( TypeSig.comparisonAstTypes, TypeSig.BOOLEAN, TypeSig.BOOLEAN, - ("lhs", TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + - GpuTypeShims.additionalPredicateSupportedTypes, + ("lhs", (TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + + GpuTypeShims.additionalPredicateSupportedTypes + TypeSig.STRUCT).nested(), TypeSig.orderable), - ("rhs", TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + - GpuTypeShims.additionalPredicateSupportedTypes, + ("rhs", (TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + + GpuTypeShims.additionalPredicateSupportedTypes + TypeSig.STRUCT).nested(), TypeSig.orderable)), (a, conf, p, r) => new BinaryAstExprMeta[LessThan](a, conf, p, r) { override def convertToGpu(lhs: Expression, rhs: Expression): GpuExpression = @@ -2066,11 +2066,11 @@ object GpuOverrides extends Logging { ExprChecks.binaryProjectAndAst( TypeSig.comparisonAstTypes, TypeSig.BOOLEAN, TypeSig.BOOLEAN, - ("lhs", TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + - GpuTypeShims.additionalPredicateSupportedTypes, + ("lhs", (TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + + GpuTypeShims.additionalPredicateSupportedTypes + TypeSig.STRUCT).nested(), TypeSig.orderable), - ("rhs", TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + - GpuTypeShims.additionalPredicateSupportedTypes, + ("rhs", (TypeSig.commonCudfTypes + TypeSig.NULL + TypeSig.DECIMAL_128 + + GpuTypeShims.additionalPredicateSupportedTypes + TypeSig.STRUCT).nested(), TypeSig.orderable)), (a, conf, p, r) => new BinaryAstExprMeta[LessThanOrEqual](a, conf, p, r) { override def convertToGpu(lhs: Expression, rhs: Expression): GpuExpression = diff --git a/tools/src/main/resources/supportedExprs.csv b/tools/src/main/resources/supportedExprs.csv index 1ae14023b5d..2290cf8f34a 100644 --- a/tools/src/main/resources/supportedExprs.csv +++ b/tools/src/main/resources/supportedExprs.csv @@ -167,8 +167,8 @@ EndsWith,S, ,None,project,result,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA, EqualNullSafe,S,`<=>`,None,project,lhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,NS,NS EqualNullSafe,S,`<=>`,None,project,rhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,NS,NS EqualNullSafe,S,`<=>`,None,project,result,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -EqualTo,S,`=`; `==`,None,project,lhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,NS,NS -EqualTo,S,`=`; `==`,None,project,rhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,NS,NS +EqualTo,S,`=`; `==`,None,project,lhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,PS,NS +EqualTo,S,`=`; `==`,None,project,rhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,PS,NS EqualTo,S,`=`; `==`,None,project,result,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA EqualTo,S,`=`; `==`,None,AST,lhs,S,S,S,S,S,NS,NS,S,PS,NS,NS,NS,NS,NS,NS,NA,NS,NS EqualTo,S,`=`; `==`,None,AST,rhs,S,S,S,S,S,NS,NS,S,PS,NS,NS,NS,NS,NS,NS,NA,NS,NS @@ -204,14 +204,14 @@ GetStructField,S, ,None,project,result,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,PS,PS,PS,N GetTimestamp,S, ,None,project,timeExp,NA,NA,NA,NA,NA,NA,NA,S,PS,S,NA,NA,NA,NA,NA,NA,NA,NA GetTimestamp,S, ,None,project,format,NA,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA GetTimestamp,S, ,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA,NA -GreaterThan,S,`>`,None,project,lhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,NS,NS -GreaterThan,S,`>`,None,project,rhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,NS,NS +GreaterThan,S,`>`,None,project,lhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,PS,NS +GreaterThan,S,`>`,None,project,rhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,PS,NS GreaterThan,S,`>`,None,project,result,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA GreaterThan,S,`>`,None,AST,lhs,S,S,S,S,S,NS,NS,S,PS,NS,NS,NS,NS,NS,NS,NA,NS,NS GreaterThan,S,`>`,None,AST,rhs,S,S,S,S,S,NS,NS,S,PS,NS,NS,NS,NS,NS,NS,NA,NS,NS GreaterThan,S,`>`,None,AST,result,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -GreaterThanOrEqual,S,`>=`,None,project,lhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,NS,NS -GreaterThanOrEqual,S,`>=`,None,project,rhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,NS,NS +GreaterThanOrEqual,S,`>=`,None,project,lhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,PS,NS +GreaterThanOrEqual,S,`>=`,None,project,rhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,PS,NS GreaterThanOrEqual,S,`>=`,None,project,result,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA GreaterThanOrEqual,S,`>=`,None,AST,lhs,S,S,S,S,S,NS,NS,S,PS,NS,NS,NS,NS,NS,NS,NA,NS,NS GreaterThanOrEqual,S,`>=`,None,AST,rhs,S,S,S,S,S,NS,NS,S,PS,NS,NS,NS,NS,NS,NS,NA,NS,NS @@ -267,14 +267,14 @@ Least,S,`least`,None,project,param,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,NS,NS Least,S,`least`,None,project,result,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,NS,NS Length,S,`length`; `character_length`; `char_length`,None,project,input,NA,NA,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NS,NA,NA,NA,NA,NA Length,S,`length`; `character_length`; `char_length`,None,project,result,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -LessThan,S,`<`,None,project,lhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,NS,NS -LessThan,S,`<`,None,project,rhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,NS,NS +LessThan,S,`<`,None,project,lhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,PS,NS +LessThan,S,`<`,None,project,rhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,PS,NS LessThan,S,`<`,None,project,result,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA LessThan,S,`<`,None,AST,lhs,S,S,S,S,S,NS,NS,S,PS,NS,NS,NS,NS,NS,NS,NA,NS,NS LessThan,S,`<`,None,AST,rhs,S,S,S,S,S,NS,NS,S,PS,NS,NS,NS,NS,NS,NS,NA,NS,NS LessThan,S,`<`,None,AST,result,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA -LessThanOrEqual,S,`<=`,None,project,lhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,NS,NS -LessThanOrEqual,S,`<=`,None,project,rhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,NS,NS +LessThanOrEqual,S,`<=`,None,project,lhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,PS,NS +LessThanOrEqual,S,`<=`,None,project,rhs,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,NS,NA,PS,NS LessThanOrEqual,S,`<=`,None,project,result,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA LessThanOrEqual,S,`<=`,None,AST,lhs,S,S,S,S,S,NS,NS,S,PS,NS,NS,NS,NS,NS,NS,NA,NS,NS LessThanOrEqual,S,`<=`,None,AST,rhs,S,S,S,S,S,NS,NS,S,PS,NS,NS,NS,NS,NS,NS,NA,NS,NS