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