You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@gluten.apache.org by ch...@apache.org on 2026/01/08 05:37:18 UTC
(incubator-gluten) 02/03: Spark: Copy back 4.1 UT as 4.0 UT
This is an automated email from the ASF dual-hosted git repository.
changchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-gluten.git
commit 1adae584cc759083cd0a525dfefb262cc278a6ba
Author: Chang chen <ch...@apache.org>
AuthorDate: Thu Jan 8 07:18:47 2026 +0800
Spark: Copy back 4.1 UT as 4.0 UT
---
gluten-ut/spark40/pom.xml | 302 +
.../gluten/GlutenColumnarWriteTestSupport.scala | 27 +
.../parquet/GlutenParquetV1FilterSuite2.scala | 28 +
.../gluten/GlutenColumnarWriteTestSupport.scala | 27 +
.../sql-tests/inputs/group-by-ordinal.sql | 96 +
.../sql-tests/inputs/group-by.sql | 266 +
.../sql-tests/inputs/linear-regression.sql | 52 +
.../sql-tests/inputs/misc-functions.sql | 22 +
.../sql-tests/inputs/random.sql | 17 +
.../sql-tests/inputs/table-valued-functions.sql | 126 +
.../sql-tests/inputs/udf/udf-group-by.sql | 156 +
.../sql-tests/results/group-by-ordinal.sql.out | 524 +
.../sql-tests/results/group-by.sql.out | 1123 ++
.../sql-tests/results/linear-regression.sql.out | 276 +
.../sql-tests/results/misc-functions.sql.out | 134 +
.../sql-tests/results/random.sql.out | 115 +
.../results/table-valued-functions.sql.out | 1017 ++
.../sql-tests/results/udf/udf-group-by.sql.out | 689 +
.../backends-velox/sql-tests/inputs/array.sql | 183 +
.../backends-velox/sql-tests/inputs/binary.sql | 8 +
.../sql-tests/inputs/binary_base64.sql | 3 +
.../sql-tests/inputs/binary_basic.sql | 4 +
.../backends-velox/sql-tests/inputs/binary_hex.sql | 3 +
.../sql-tests/inputs/binary_hex_discrete.sql | 3 +
.../backends-velox/sql-tests/inputs/bitwise.sql | 93 +
.../backends-velox/sql-tests/inputs/cast.sql | 179 +
.../inputs/ceil-floor-with-scale-param.sql | 31 +
.../sql-tests/inputs/change-column.sql | 49 +
.../sql-tests/inputs/charvarchar.sql | 128 +
.../backends-velox/sql-tests/inputs/collations.sql | 527 +
.../inputs/column-resolution-aggregate.sql | 33 +
.../sql-tests/inputs/column-resolution-sort.sql | 20 +
.../sql-tests/inputs/columnresolution-negative.sql | 50 +
.../sql-tests/inputs/columnresolution-views.sql | 23 +
.../sql-tests/inputs/columnresolution.sql | 78 +
.../backends-velox/sql-tests/inputs/comments.sql | 119 +
.../backends-velox/sql-tests/inputs/comparator.sql | 13 +
.../sql-tests/inputs/conditional-functions.sql | 38 +
.../backends-velox/sql-tests/inputs/count.sql | 55 +
.../backends-velox/sql-tests/inputs/cross-join.sql | 36 +
.../sql-tests/inputs/csv-functions.sql | 24 +
.../sql-tests/inputs/cte-command.sql | 33 +
.../backends-velox/sql-tests/inputs/cte-legacy.sql | 2 +
.../backends-velox/sql-tests/inputs/cte-nested.sql | 228 +
.../sql-tests/inputs/cte-nonlegacy.sql | 2 +
.../backends-velox/sql-tests/inputs/cte.sql | 184 +
.../sql-tests/inputs/current_database_catalog.sql | 2 +
.../backends-velox/sql-tests/inputs/date.sql | 168 +
.../inputs/datetime-formatting-invalid.sql | 53 +
.../inputs/datetime-formatting-legacy.sql | 2 +
.../sql-tests/inputs/datetime-formatting.sql | 73 +
.../sql-tests/inputs/datetime-legacy.sql | 3 +
.../sql-tests/inputs/datetime-parsing-invalid.sql | 39 +
.../sql-tests/inputs/datetime-parsing-legacy.sql | 2 +
.../sql-tests/inputs/datetime-parsing.sql | 45 +
.../sql-tests/inputs/datetime-special.sql | 10 +
.../inputs/decimalArithmeticOperations.sql | 125 +
.../inputs/describe-part-after-analyze.sql | 34 +
.../sql-tests/inputs/describe-query.sql | 31 +
.../inputs/describe-table-after-alter-table.sql | 29 +
.../backends-velox/sql-tests/inputs/describe.sql | 145 +
.../inputs/double-quoted-identifiers-enabled.sql | 3 +
.../sql-tests/inputs/double-quoted-identifiers.sql | 57 +
.../backends-velox/sql-tests/inputs/except-all.sql | 160 +
.../backends-velox/sql-tests/inputs/except.sql | 76 +
.../sql-tests/inputs/execute-immediate.sql | 149 +
.../sql-tests/inputs/explain-aqe.sql | 4 +
.../sql-tests/inputs/explain-cbo.sql | 27 +
.../backends-velox/sql-tests/inputs/explain.sql | 136 +
.../backends-velox/sql-tests/inputs/extract.sql | 167 +
.../sql-tests/inputs/group-analytics.sql | 93 +
.../sql-tests/inputs/group-by-alias.sql | 58 +
.../sql-tests/inputs/group-by-all-duckdb.sql | 29 +
.../sql-tests/inputs/group-by-all-mosha.sql | 32 +
.../sql-tests/inputs/group-by-all.sql | 85 +
.../sql-tests/inputs/group-by-filter.sql | 179 +
.../sql-tests/inputs/group-by-ordinal.sql | 96 +
.../backends-velox/sql-tests/inputs/group-by.sql | 329 +
.../sql-tests/inputs/grouping_set.sql | 66 +
.../backends-velox/sql-tests/inputs/having.sql | 41 +
.../sql-tests/inputs/higher-order-functions.sql | 105 +
.../backends-velox/sql-tests/inputs/hll.sql | 76 +
.../sql-tests/inputs/identifier-clause.sql | 177 +
.../backends-velox/sql-tests/inputs/ignored.sql | 4 +
.../backends-velox/sql-tests/inputs/ilike-all.sql | 41 +
.../backends-velox/sql-tests/inputs/ilike-any.sql | 41 +
.../backends-velox/sql-tests/inputs/ilike.sql | 39 +
.../sql-tests/inputs/inline-table.sql | 68 +
.../backends-velox/sql-tests/inputs/inner-join.sql | 29 +
.../sql-tests/inputs/intersect-all.sql | 175 +
.../backends-velox/sql-tests/inputs/interval.sql | 387 +
.../sql-tests/inputs/join-empty-relation.sql | 28 +
.../sql-tests/inputs/join-lateral.sql | 559 +
.../sql-tests/inputs/json-functions.sql | 111 +
.../sql-tests/inputs/keywords-enforced.sql | 2 +
.../backends-velox/sql-tests/inputs/keywords.sql | 3 +
.../backends-velox/sql-tests/inputs/like-all.sql | 41 +
.../backends-velox/sql-tests/inputs/like-any.sql | 41 +
.../backends-velox/sql-tests/inputs/limit.sql | 32 +
.../sql-tests/inputs/linear-regression.sql | 52 +
.../sql-tests/inputs/listagg-collations.sql | 14 +
.../backends-velox/sql-tests/inputs/listagg.sql | 41 +
.../backends-velox/sql-tests/inputs/literals.sql | 123 +
.../backends-velox/sql-tests/inputs/map.sql | 17 +
.../sql-tests/inputs/mask-functions.sql | 58 +
.../backends-velox/sql-tests/inputs/math.sql | 92 +
.../sql-tests/inputs/misc-functions.sql | 45 +
.../backends-velox/sql-tests/inputs/mode.sql | 139 +
.../sql-tests/inputs/named-function-arguments.sql | 74 +
.../sql-tests/inputs/natural-join.sql | 77 +
.../sql-tests/inputs/non-excludable-rule.sql | 19 +
.../sql-tests/inputs/nonansi/array.sql | 1 +
.../sql-tests/inputs/nonansi/cast.sql | 1 +
.../inputs/nonansi/conditional-functions.sql | 1 +
.../sql-tests/inputs/nonansi/date.sql | 1 +
.../inputs/nonansi/datetime-parsing-invalid.sql | 2 +
.../sql-tests/inputs/nonansi/datetime-special.sql | 1 +
.../inputs/nonansi/decimalArithmeticOperations.sql | 1 +
.../inputs/nonansi/double-quoted-identifiers.sql | 1 +
.../inputs/nonansi/higher-order-functions.sql | 1 +
.../sql-tests/inputs/nonansi/interval.sql | 1 +
.../sql-tests/inputs/nonansi/keywords.sql | 1 +
.../sql-tests/inputs/nonansi/literals.sql | 2 +
.../sql-tests/inputs/nonansi/map.sql | 1 +
.../sql-tests/inputs/nonansi/math.sql | 1 +
.../inputs/nonansi/parse-schema-string.sql | 1 +
.../sql-tests/inputs/nonansi/string-functions.sql | 1 +
.../sql-tests/inputs/nonansi/timestamp.sql | 1 +
.../sql-tests/inputs/nonansi/try_aggregates.sql | 1 +
.../sql-tests/inputs/nonansi/try_arithmetic.sql | 1 +
.../inputs/nonansi/try_datetime_functions.sql | 1 +
.../sql-tests/inputs/nonansi/try_element_at.sql | 1 +
.../sql-tests/inputs/null-handling.sql | 53 +
.../sql-tests/inputs/null-propagation.sql | 9 +
.../backends-velox/sql-tests/inputs/operators.sql | 105 +
.../sql-tests/inputs/order-by-all.sql | 47 +
.../sql-tests/inputs/order-by-nulls-ordering.sql | 88 +
.../sql-tests/inputs/order-by-ordinal.sql | 36 +
.../backends-velox/sql-tests/inputs/order-by.sql | 34 +
.../backends-velox/sql-tests/inputs/outer-join.sql | 45 +
.../parse-query-correctness-old-behavior.sql | 2 +
.../sql-tests/inputs/parse-query-correctness.sql | 286 +
.../sql-tests/inputs/parse-schema-string.sql | 5 +
.../sql-tests/inputs/percentiles.sql | 429 +
.../sql-tests/inputs/pipe-operators.sql | 1763 +++
.../backends-velox/sql-tests/inputs/pivot.sql | 300 +
.../inputs/postgreSQL/aggregates_part1.sql | 153 +
.../inputs/postgreSQL/aggregates_part2.sql | 218 +
.../inputs/postgreSQL/aggregates_part3.sql | 276 +
.../inputs/postgreSQL/aggregates_part4.sql | 424 +
.../sql-tests/inputs/postgreSQL/boolean.sql | 281 +
.../sql-tests/inputs/postgreSQL/case.sql | 262 +
.../sql-tests/inputs/postgreSQL/comments.sql | 49 +
.../sql-tests/inputs/postgreSQL/create_view.sql | 779 +
.../sql-tests/inputs/postgreSQL/date.sql | 362 +
.../sql-tests/inputs/postgreSQL/float4.sql | 363 +
.../sql-tests/inputs/postgreSQL/float8.sql | 502 +
.../sql-tests/inputs/postgreSQL/groupingsets.sql | 561 +
.../sql-tests/inputs/postgreSQL/insert.sql | 653 +
.../sql-tests/inputs/postgreSQL/int2.sql | 131 +
.../sql-tests/inputs/postgreSQL/int4.sql | 181 +
.../sql-tests/inputs/postgreSQL/int8.sql | 240 +
.../sql-tests/inputs/postgreSQL/interval.sql | 344 +
.../sql-tests/inputs/postgreSQL/join.sql | 2106 +++
.../sql-tests/inputs/postgreSQL/limit.sql | 162 +
.../sql-tests/inputs/postgreSQL/numeric.sql | 1165 ++
.../sql-tests/inputs/postgreSQL/select.sql | 285 +
.../inputs/postgreSQL/select_distinct.sql | 86 +
.../sql-tests/inputs/postgreSQL/select_having.sql | 56 +
.../inputs/postgreSQL/select_implicit.sql | 160 +
.../sql-tests/inputs/postgreSQL/strings.sql | 659 +
.../sql-tests/inputs/postgreSQL/text.sql | 133 +
.../sql-tests/inputs/postgreSQL/timestamp.sql | 252 +
.../sql-tests/inputs/postgreSQL/union.sql | 472 +
.../sql-tests/inputs/postgreSQL/window_part1.sql | 361 +
.../sql-tests/inputs/postgreSQL/window_part2.sql | 303 +
.../sql-tests/inputs/postgreSQL/window_part3.sql | 459 +
.../sql-tests/inputs/postgreSQL/window_part4.sql | 406 +
.../sql-tests/inputs/postgreSQL/with.sql | 1208 ++
.../sql-tests/inputs/pred-pushdown.sql | 12 +
.../sql-tests/inputs/predicate-functions.sql | 120 +
.../sql-tests/inputs/query_regex_column.sql | 52 +
.../backends-velox/sql-tests/inputs/random.sql | 89 +
.../sql-tests/inputs/regexp-functions.sql | 82 +
.../sql-tests/inputs/selectExcept.sql | 78 +
.../sql-tests/inputs/show-create-table.sql | 114 +
.../sql-tests/inputs/show-tables.sql | 43 +
.../sql-tests/inputs/show-tblproperties.sql | 26 +
.../backends-velox/sql-tests/inputs/show-views.sql | 28 +
.../sql-tests/inputs/show_columns.sql | 58 +
.../inputs/sql-compatibility-functions.sql | 27 +
.../sql-tests/inputs/sql-on-files.sql | 32 +
.../sql-tests/inputs/sql-session-variables.sql | 383 +
.../backends-velox/sql-tests/inputs/sql-udf.sql | 989 ++
.../sql-tests/inputs/string-functions.sql | 308 +
.../backends-velox/sql-tests/inputs/struct.sql | 27 +
.../sql-tests/inputs/subexp-elimination.sql | 37 +
.../subquery/exists-subquery/exists-aggregate.sql | 174 +
.../subquery/exists-subquery/exists-basic.sql | 124 +
.../subquery/exists-subquery/exists-count-bug.sql | 43 +
.../inputs/subquery/exists-subquery/exists-cte.sql | 143 +
.../subquery/exists-subquery/exists-having.sql | 91 +
.../exists-subquery/exists-in-join-condition.sql | 95 +
.../exists-subquery/exists-joins-and-set-ops.sql | 321 +
.../exists-subquery/exists-orderby-limit.sql | 289 +
.../exists-subquery/exists-outside-filter.sql | 157 +
.../exists-subquery/exists-within-and-or.sql | 97 +
.../inputs/subquery/in-subquery/in-basic.sql | 18 +
.../inputs/subquery/in-subquery/in-count-bug.sql | 51 +
.../inputs/subquery/in-subquery/in-group-by.sql | 319 +
.../inputs/subquery/in-subquery/in-having.sql | 156 +
.../inputs/subquery/in-subquery/in-joins.sql | 396 +
.../inputs/subquery/in-subquery/in-limit.sql | 384 +
.../subquery/in-subquery/in-multiple-columns.sql | 131 +
.../subquery/in-subquery/in-null-semantics.sql | 68 +
.../inputs/subquery/in-subquery/in-nullability.sql | 15 +
.../inputs/subquery/in-subquery/in-order-by.sql | 206 +
.../subquery/in-subquery/in-set-operations.sql | 582 +
.../in-subquery/in-subquery-in-join-condition.sql | 90 +
.../inputs/subquery/in-subquery/in-with-cte.sql | 291 +
.../inputs/subquery/in-subquery/nested-not-in.sql | 202 +
.../subquery/in-subquery/not-in-group-by.sql | 107 +
.../inputs/subquery/in-subquery/not-in-joins.sql | 171 +
.../not-in-unit-tests-multi-column-literal.sql | 43 +
.../in-subquery/not-in-unit-tests-multi-column.sql | 102 +
.../not-in-unit-tests-single-column-literal.sql | 46 +
.../not-in-unit-tests-single-column.sql | 127 +
.../inputs/subquery/in-subquery/simple-in.sql | 140 +
.../negative-cases/invalid-correlation.sql | 83 +
.../negative-cases/subq-input-typecheck.sql | 62 +
.../nested-scalar-subquery-count-bug.sql | 35 +
.../scalar-subquery/scalar-subquery-count-bug.sql | 160 +
.../scalar-subquery/scalar-subquery-group-by.sql | 46 +
.../scalar-subquery/scalar-subquery-predicate.sql | 545 +
.../scalar-subquery/scalar-subquery-select.sql | 261 +
.../scalar-subquery/scalar-subquery-set-op.sql | 642 +
.../sql-tests/inputs/subquery/subquery-in-from.sql | 15 +
.../inputs/subquery/subquery-nested-data.sql | 50 +
.../sql-tests/inputs/subquery/subquery-offset.sql | 80 +
.../sql-tests/inputs/table-aliases.sql | 38 +
.../sql-tests/inputs/table-valued-functions.sql | 130 +
.../sql-tests/inputs/tablesample-negative.sql | 14 +
.../sql-tests/inputs/timestamp-ltz.sql | 18 +
.../backends-velox/sql-tests/inputs/timestamp.sql | 172 +
.../inputs/timestampNTZ/datetime-special-ansi.sql | 2 +
.../inputs/timestampNTZ/datetime-special.sql | 2 +
.../inputs/timestampNTZ/timestamp-ansi.sql | 2 +
.../sql-tests/inputs/timestampNTZ/timestamp.sql | 2 +
.../backends-velox/sql-tests/inputs/timezone.sql | 15 +
.../sql-tests/inputs/to_from_avro.sql | 21 +
.../backends-velox/sql-tests/inputs/transform.sql | 422 +
.../sql-tests/inputs/try-string-functions.sql | 48 +
.../sql-tests/inputs/try_aggregates.sql | 45 +
.../sql-tests/inputs/try_arithmetic.sql | 88 +
.../backends-velox/sql-tests/inputs/try_cast.sql | 50 +
.../sql-tests/inputs/try_datetime_functions.sql | 6 +
.../sql-tests/inputs/try_element_at.sql | 11 +
.../sql-tests/inputs/try_reflect.sql | 15 +
.../inputs/typeCoercion/native/arrayJoin.sql | 11 +
.../typeCoercion/native/binaryComparison.sql | 287 +
.../inputs/typeCoercion/native/booleanEquality.sql | 122 +
.../typeCoercion/native/caseWhenCoercion.sql | 174 +
.../inputs/typeCoercion/native/concat.sql | 157 +
.../typeCoercion/native/dateTimeOperations.sql | 60 +
.../typeCoercion/native/decimalPrecision.sql | 1448 ++
.../inputs/typeCoercion/native/division.sql | 174 +
.../sql-tests/inputs/typeCoercion/native/elt.sql | 44 +
.../inputs/typeCoercion/native/ifCoercion.sql | 174 +
.../typeCoercion/native/implicitTypeCasts.sql | 72 +
.../inputs/typeCoercion/native/inConversion.sql | 330 +
.../inputs/typeCoercion/native/mapZipWith.sql | 78 +
.../inputs/typeCoercion/native/mapconcat.sql | 92 +
.../inputs/typeCoercion/native/promoteStrings.sql | 364 +
.../native/stringCastAndExpressions.sql | 54 +
.../typeCoercion/native/widenSetOperationTypes.sql | 175 +
.../typeCoercion/native/windowFrameCoercion.sql | 44 +
.../sql-tests/inputs/udaf/udaf-group-analytics.sql | 70 +
.../inputs/udaf/udaf-group-by-ordinal.sql | 88 +
.../sql-tests/inputs/udaf/udaf-group-by.sql | 110 +
.../sql-tests/inputs/udaf/udaf-grouping-set.sql | 47 +
.../backends-velox/sql-tests/inputs/udaf/udaf.sql | 21 +
.../inputs/udf/postgreSQL/udf-aggregates_part1.sql | 153 +
.../inputs/udf/postgreSQL/udf-aggregates_part2.sql | 206 +
.../inputs/udf/postgreSQL/udf-aggregates_part3.sql | 271 +
.../inputs/udf/postgreSQL/udf-aggregates_part4.sql | 421 +
.../sql-tests/inputs/udf/postgreSQL/udf-case.sql | 263 +
.../sql-tests/inputs/udf/postgreSQL/udf-join.sql | 2090 +++
.../inputs/udf/postgreSQL/udf-select_having.sql | 58 +
.../inputs/udf/postgreSQL/udf-select_implicit.sql | 165 +
.../sql-tests/inputs/udf/udf-count.sql | 28 +
.../sql-tests/inputs/udf/udf-cross-join.sql | 37 +
.../sql-tests/inputs/udf/udf-except-all.sql | 162 +
.../sql-tests/inputs/udf/udf-except.sql | 58 +
.../sql-tests/inputs/udf/udf-group-analytics.sql | 63 +
.../sql-tests/inputs/udf/udf-group-by.sql | 156 +
.../sql-tests/inputs/udf/udf-having.sql | 20 +
.../sql-tests/inputs/udf/udf-inline-table.sql | 54 +
.../sql-tests/inputs/udf/udf-inner-join.sql | 17 +
.../sql-tests/inputs/udf/udf-intersect-all.sql | 162 +
.../inputs/udf/udf-join-empty-relation.sql | 30 +
.../sql-tests/inputs/udf/udf-natural-join.sql | 22 +
.../sql-tests/inputs/udf/udf-outer-join.sql | 41 +
.../sql-tests/inputs/udf/udf-pivot.sql | 307 +
.../sql-tests/inputs/udf/udf-special-values.sql | 8 +
.../sql-tests/inputs/udf/udf-udaf.sql | 18 +
.../sql-tests/inputs/udf/udf-union.sql | 56 +
.../sql-tests/inputs/udf/udf-window.sql | 124 +
.../backends-velox/sql-tests/inputs/udtf/udtf.sql | 171 +
.../backends-velox/sql-tests/inputs/union.sql | 68 +
.../backends-velox/sql-tests/inputs/unpivot.sql | 44 +
.../sql-tests/inputs/url-functions.sql | 26 +
.../backends-velox/sql-tests/inputs/using-join.sql | 95 +
.../inputs/variant/named-function-arguments.sql | 6 +
.../inputs/view-schema-binding-config.sql | 172 +
.../sql-tests/inputs/view-schema-binding.sql | 64 +
.../sql-tests/inputs/view-schema-compensation.sql | 90 +
.../sql-tests/inputs/view-schema-evolution.sql | 155 +
.../inputs/view-schema-type-evolution.sql | 90 +
.../inputs/view-with-default-collation.sql | 152 +
.../backends-velox/sql-tests/inputs/window.sql | 485 +
.../sql-tests/inputs/xml-functions.sql | 60 +
.../backends-velox/sql-tests/results/array.sql.out | 900 ++
.../sql-tests/results/binary.sql.out | 51 +
.../sql-tests/results/binary_base64.sql.out | 51 +
.../sql-tests/results/binary_basic.sql.out | 51 +
.../sql-tests/results/binary_hex.sql.out | 51 +
.../sql-tests/results/binary_hex_discrete.sql.out | 51 +
.../sql-tests/results/bitwise.sql.out | 476 +
.../backends-velox/sql-tests/results/cast.sql.out | 2046 +++
.../results/ceil-floor-with-scale-param.sql.out | 321 +
.../sql-tests/results/change-column.sql.out | 341 +
.../sql-tests/results/charvarchar.sql.out | 1273 ++
.../sql-tests/results/collations.sql.out | 5834 +++++++
.../results/column-resolution-aggregate.sql.out | 129 +
.../results/column-resolution-sort.sql.out | 42 +
.../results/columnresolution-negative.sql.out | 535 +
.../results/columnresolution-views.sql.out | 135 +
.../sql-tests/results/columnresolution.sql.out | 440 +
.../sql-tests/results/comments.sql.out | 159 +
.../sql-tests/results/comparator.sql.out | 79 +
.../results/conditional-functions.sql.out | 204 +
.../backends-velox/sql-tests/results/count.sql.out | 214 +
.../sql-tests/results/cross-join.sql.out | 137 +
.../sql-tests/results/csv-functions.sql.out | 286 +
.../sql-tests/results/cte-command.sql.out | 121 +
.../sql-tests/results/cte-legacy.sql.out | 417 +
.../sql-tests/results/cte-nested.sql.out | 389 +
.../sql-tests/results/cte-nonlegacy.sql.out | 461 +
.../backends-velox/sql-tests/results/cte.sql.out | 626 +
.../results/current_database_catalog.sql.out | 7 +
.../backends-velox/sql-tests/results/date.sql.out | 1219 ++
.../results/datetime-formatting-invalid.sql.out | 567 +
.../results/datetime-formatting-legacy.sql.out | 422 +
.../sql-tests/results/datetime-formatting.sql.out | 452 +
.../results/datetime-formatting.sql.out.java21 | 452 +
.../sql-tests/results/datetime-legacy.sql.out | 2480 +++
.../results/datetime-parsing-invalid.sql.out | 467 +
.../results/datetime-parsing-legacy.sql.out | 207 +
.../sql-tests/results/datetime-parsing.sql.out | 207 +
.../sql-tests/results/datetime-special.sql.out | 31 +
.../results/decimalArithmeticOperations.sql.out | 818 +
.../results/describe-part-after-analyze.sql.out | 255 +
.../sql-tests/results/describe-query.sql.out | 199 +
.../describe-table-after-alter-table.sql.out | 163 +
.../sql-tests/results/describe.sql.out | 988 ++
.../double-quoted-identifiers-enabled.sql.out | 483 +
.../results/double-quoted-identifiers.sql.out | 443 +
.../sql-tests/results/except-all.sql.out | 377 +
.../sql-tests/results/except.sql.out | 158 +
.../sql-tests/results/execute-immediate.sql.out | 792 +
.../sql-tests/results/explain-aqe.sql.out | 1232 ++
.../sql-tests/results/explain-cbo.sql.out | 103 +
.../sql-tests/results/explain.sql.out | 1124 ++
.../sql-tests/results/extract.sql.out | 1198 ++
.../sql-tests/results/group-analytics.sql.out | 1356 ++
.../sql-tests/results/group-by-alias.sql.out | 374 +
.../sql-tests/results/group-by-all-duckdb.sql.out | 119 +
.../sql-tests/results/group-by-all-mosha.sql.out | 142 +
.../sql-tests/results/group-by-all.sql.out | 290 +
.../sql-tests/results/group-by-filter.sql.out | 984 ++
.../sql-tests/results/group-by-ordinal.sql.out | 524 +
.../sql-tests/results/group-by.sql.out | 1172 ++
.../sql-tests/results/grouping_set.sql.out | 244 +
.../sql-tests/results/having.sql.out | 154 +
.../results/higher-order-functions.sql.out | 350 +
.../backends-velox/sql-tests/results/hll.sql.out | 269 +
.../sql-tests/results/identifier-clause.sql.out | 1405 ++
.../sql-tests/results/ilike-all.sql.out | 144 +
.../sql-tests/results/ilike-any.sql.out | 150 +
.../backends-velox/sql-tests/results/ilike.sql.out | 208 +
.../sql-tests/results/inline-table.sql.out | 289 +
.../sql-tests/results/inner-join.sql.out | 64 +
.../sql-tests/results/intersect-all.sql.out | 378 +
.../sql-tests/results/interval.sql.out | 3899 +++++
.../sql-tests/results/join-empty-relation.sql.out | 191 +
.../sql-tests/results/join-lateral.sql.out | 1937 +++
.../sql-tests/results/json-functions.sql.out | 807 +
.../sql-tests/results/keywords-enforced.sql.out | 467 +
.../sql-tests/results/keywords.sql.out | 391 +
.../sql-tests/results/like-all.sql.out | 144 +
.../sql-tests/results/like-any.sql.out | 150 +
.../backends-velox/sql-tests/results/limit.sql.out | 204 +
.../sql-tests/results/linear-regression.sql.out | 276 +
.../sql-tests/results/listagg-collations.sql.out | 82 +
.../sql-tests/results/listagg.sql.out | 376 +
.../sql-tests/results/literals.sql.out | 787 +
.../backends-velox/sql-tests/results/map.sql.out | 115 +
.../sql-tests/results/mask-functions.sql.out | 552 +
.../backends-velox/sql-tests/results/math.sql.out | 904 ++
.../sql-tests/results/misc-functions.sql.out | 332 +
.../backends-velox/sql-tests/results/mode.sql.out | 489 +
.../results/named-function-arguments.sql.out | 464 +
.../sql-tests/results/natural-join.sql.out | 342 +
.../sql-tests/results/non-excludable-rule.sql.out | 55 +
.../sql-tests/results/nonansi/array.sql.out | 788 +
.../sql-tests/results/nonansi/cast.sql.out | 1161 ++
.../results/nonansi/conditional-functions.sql.out | 170 +
.../sql-tests/results/nonansi/date.sql.out | 1223 ++
.../nonansi/datetime-parsing-invalid.sql.out | 241 +
.../results/nonansi/datetime-special.sql.out | 31 +
.../nonansi/decimalArithmeticOperations.sql.out | 473 +
.../nonansi/double-quoted-identifiers.sql.out | 443 +
.../results/nonansi/higher-order-functions.sql.out | 350 +
.../sql-tests/results/nonansi/interval.sql.out | 3712 +++++
.../sql-tests/results/nonansi/keywords.sql.out | 391 +
.../sql-tests/results/nonansi/literals.sql.out | 787 +
.../sql-tests/results/nonansi/map.sql.out | 115 +
.../sql-tests/results/nonansi/math.sql.out | 583 +
.../results/nonansi/parse-schema-string.sql.out | 31 +
.../results/nonansi/string-functions.sql.out | 2279 +++
.../sql-tests/results/nonansi/timestamp.sql.out | 1215 ++
.../results/nonansi/try_aggregates.sql.out | 299 +
.../results/nonansi/try_aggregates.sql.out.java21 | 299 +
.../results/nonansi/try_arithmetic.sql.out | 569 +
.../results/nonansi/try_arithmetic.sql.out.java21 | 569 +
.../results/nonansi/try_datetime_functions.sql.out | 56 +
.../results/nonansi/try_element_at.sql.out | 67 +
.../sql-tests/results/null-handling.sql.out | 332 +
.../sql-tests/results/null-propagation.sql.out | 35 +
.../sql-tests/results/operators.sql.out | 699 +
.../sql-tests/results/order-by-all.sql.out | 210 +
.../results/order-by-nulls-ordering.sql.out | 251 +
.../sql-tests/results/order-by-ordinal.sql.out | 182 +
.../sql-tests/results/order-by.sql.out | 194 +
.../sql-tests/results/outer-join.sql.out | 69 +
.../parse-query-correctness-old-behavior.sql.out | 777 +
.../results/parse-query-correctness.sql.out | 765 +
.../sql-tests/results/parse-schema-string.sql.out | 31 +
.../sql-tests/results/percentiles.sql.out | 1190 ++
.../sql-tests/results/pipe-operators.sql.out | 4276 ++++++
.../backends-velox/sql-tests/results/pivot.sql.out | 564 +
.../results/postgreSQL/aggregates_part1.sql.out | 525 +
.../results/postgreSQL/aggregates_part2.sql.out | 300 +
.../results/postgreSQL/aggregates_part3.sql.out | 59 +
.../results/postgreSQL/aggregates_part4.sql.out | 31 +
.../sql-tests/results/postgreSQL/boolean.sql.out | 1108 ++
.../sql-tests/results/postgreSQL/case.sql.out | 406 +
.../sql-tests/results/postgreSQL/comments.sql.out | 71 +
.../results/postgreSQL/create_view.sql.out | 2228 +++
.../sql-tests/results/postgreSQL/date.sql.out | 736 +
.../sql-tests/results/postgreSQL/float4.sql.out | 477 +
.../results/postgreSQL/float4.sql.out.java21 | 477 +
.../sql-tests/results/postgreSQL/float8.sql.out | 914 ++
.../results/postgreSQL/groupingsets.sql.out | 731 +
.../sql-tests/results/postgreSQL/insert.sql.out | 78 +
.../sql-tests/results/postgreSQL/int2.sql.out | 360 +
.../sql-tests/results/postgreSQL/int4.sql.out | 599 +
.../sql-tests/results/postgreSQL/int8.sql.out | 1076 ++
.../results/postgreSQL/int8.sql.out.java21 | 1076 ++
.../sql-tests/results/postgreSQL/interval.sql.out | 361 +
.../sql-tests/results/postgreSQL/join.sql.out | 3799 +++++
.../sql-tests/results/postgreSQL/limit.sql.out | 190 +
.../sql-tests/results/postgreSQL/numeric.sql.out | 5252 +++++++
.../results/postgreSQL/numeric.sql.out.java21 | 5252 +++++++
.../sql-tests/results/postgreSQL/select.sql.out | 539 +
.../results/postgreSQL/select_distinct.sql.out | 222 +
.../results/postgreSQL/select_having.sql.out | 222 +
.../results/postgreSQL/select_implicit.sql.out | 506 +
.../sql-tests/results/postgreSQL/strings.sql.out | 1067 ++
.../sql-tests/results/postgreSQL/text.sql.out | 405 +
.../sql-tests/results/postgreSQL/timestamp.sql.out | 278 +
.../sql-tests/results/postgreSQL/union.sql.out | 798 +
.../results/postgreSQL/window_part1.sql.out | 756 +
.../results/postgreSQL/window_part2.sql.out | 520 +
.../results/postgreSQL/window_part3.sql.out | 563 +
.../results/postgreSQL/window_part4.sql.out | 531 +
.../sql-tests/results/postgreSQL/with.sql.out | 507 +
.../sql-tests/results/pred-pushdown.sql.out | 37 +
.../sql-tests/results/predicate-functions.sql.out | 896 ++
.../sql-tests/results/query_regex_column.sql.out | 422 +
.../sql-tests/results/random.sql.out | 921 ++
.../sql-tests/results/regexp-functions.sql.out | 732 +
.../sql-tests/results/selectExcept.sql.out | 496 +
.../sql-tests/results/show-create-table.sql.out | 451 +
.../sql-tests/results/show-tables.sql.out | 322 +
.../sql-tests/results/show-tblproperties.sql.out | 107 +
.../sql-tests/results/show-views.sql.out | 180 +
.../sql-tests/results/show_columns.sql.out | 273 +
.../results/sql-compatibility-functions.sql.out | 136 +
.../sql-tests/results/sql-on-files.sql.out | 283 +
.../results/sql-session-variables.sql.out | 2337 +++
.../sql-tests/results/sql-udf.sql.out | 5435 +++++++
.../sql-tests/results/string-functions.sql.out | 2347 +++
.../sql-tests/results/struct.sql.out | 87 +
.../sql-tests/results/subexp-elimination.sql.out | 113 +
.../exists-subquery/exists-aggregate.sql.out | 304 +
.../subquery/exists-subquery/exists-basic.sql.out | 211 +
.../exists-subquery/exists-count-bug.sql.out | 159 +
.../subquery/exists-subquery/exists-cte.sql.out | 197 +
.../subquery/exists-subquery/exists-having.sql.out | 147 +
.../exists-in-join-condition.sql.out | 504 +
.../exists-joins-and-set-ops.sql.out | 512 +
.../exists-subquery/exists-orderby-limit.sql.out | 590 +
.../exists-subquery/exists-outside-filter.sql.out | 253 +
.../exists-subquery/exists-within-and-or.sql.out | 153 +
.../results/subquery/in-subquery/in-basic.sql.out | 76 +
.../subquery/in-subquery/in-count-bug.sql.out | 182 +
.../subquery/in-subquery/in-group-by.sql.out | 487 +
.../results/subquery/in-subquery/in-having.sql.out | 214 +
.../results/subquery/in-subquery/in-joins.sql.out | 593 +
.../results/subquery/in-subquery/in-limit.sql.out | 624 +
.../in-subquery/in-multiple-columns.sql.out | 175 +
.../subquery/in-subquery/in-null-semantics.sql.out | 298 +
.../subquery/in-subquery/in-nullability.sql.out | 71 +
.../subquery/in-subquery/in-order-by.sql.out | 325 +
.../subquery/in-subquery/in-set-operations.sql.out | 834 +
.../in-subquery-in-join-condition.sql.out | 466 +
.../subquery/in-subquery/in-with-cte.sql.out | 361 +
.../subquery/in-subquery/nested-not-in.sql.out | 329 +
.../subquery/in-subquery/not-in-group-by.sql.out | 147 +
.../subquery/in-subquery/not-in-joins.sql.out | 226 +
.../not-in-unit-tests-multi-column-literal.sql.out | 45 +
.../not-in-unit-tests-multi-column.sql.out | 117 +
...not-in-unit-tests-single-column-literal.sql.out | 54 +
.../not-in-unit-tests-single-column.sql.out | 128 +
.../results/subquery/in-subquery/simple-in.sql.out | 221 +
.../negative-cases/invalid-correlation.sql.out | 208 +
.../negative-cases/subq-input-typecheck.sql.out | 195 +
.../nested-scalar-subquery-count-bug.sql.out | 125 +
.../scalar-subquery-count-bug.sql.out | 382 +
.../scalar-subquery-group-by.sql.out | 295 +
.../scalar-subquery-predicate.sql.out | 932 ++
.../scalar-subquery/scalar-subquery-select.sql.out | 609 +
.../scalar-subquery/scalar-subquery-set-op.sql.out | 1075 ++
.../results/subquery/subquery-in-from.sql.out | 47 +
.../results/subquery/subquery-nested-data.sql.out | 314 +
.../results/subquery/subquery-offset.sql.out | 222 +
.../sql-tests/results/table-aliases.sql.out | 207 +
.../results/table-valued-functions.sql.out | 1071 ++
.../sql-tests/results/tablesample-negative.sql.out | 73 +
.../sql-tests/results/timestamp-ltz.sql.out | 70 +
.../sql-tests/results/timestamp-ntz.sql.out | 231 +
.../sql-tests/results/timestamp.sql.out | 1222 ++
.../timestampNTZ/datetime-special-ansi.sql.out | 31 +
.../results/timestampNTZ/datetime-special.sql.out | 31 +
.../results/timestampNTZ/timestamp-ansi.sql.out | 1215 ++
.../results/timestampNTZ/timestamp.sql.out | 1191 ++
.../sql-tests/results/timezone.sql.out | 179 +
.../sql-tests/results/to_from_avro.sql.out | 144 +
.../sql-tests/results/transform.sql.out | 849 ++
.../sql-tests/results/try-string-functions.sql.out | 283 +
.../sql-tests/results/try_aggregates.sql.out | 415 +
.../results/try_aggregates.sql.out.java21 | 415 +
.../sql-tests/results/try_arithmetic.sql.out | 705 +
.../sql-tests/results/try_cast.sql.out | 199 +
.../results/try_datetime_functions.sql.out | 56 +
.../sql-tests/results/try_element_at.sql.out | 67 +
.../sql-tests/results/try_reflect.sql.out | 170 +
.../results/typeCoercion/native/arrayJoin.sql.out | 87 +
.../typeCoercion/native/binaryComparison.sql.out | 2551 ++++
.../typeCoercion/native/booleanEquality.sql.out | 2055 +++
.../typeCoercion/native/caseWhenCoercion.sql.out | 2249 +++
.../results/typeCoercion/native/concat.sql.out | 333 +
.../typeCoercion/native/dateTimeOperations.sql.out | 805 +
.../typeCoercion/native/decimalPrecision.sql.out | 15031 +++++++++++++++++++
.../results/typeCoercion/native/division.sql.out | 2455 +++
.../results/typeCoercion/native/elt.sql.out | 112 +
.../results/typeCoercion/native/ifCoercion.sql.out | 2249 +++
.../typeCoercion/native/implicitTypeCasts.sql.out | 351 +
.../typeCoercion/native/inConversion.sql.out | 4525 ++++++
.../results/typeCoercion/native/mapZipWith.sql.out | 242 +
.../results/typeCoercion/native/mapconcat.sql.out | 229 +
.../typeCoercion/native/promoteStrings.sql.out | 3875 +++++
.../native/stringCastAndExpressions.sql.out | 577 +
.../native/widenSetOperationTypes.sql.out | 2569 ++++
.../native/windowFrameCoercion.sql.out | 265 +
.../results/udaf/udaf-group-analytics.sql.out | 1164 ++
.../results/udaf/udaf-group-by-ordinal.sql.out | 443 +
.../sql-tests/results/udaf/udaf-group-by.sql.out | 441 +
.../results/udaf/udaf-grouping-set.sql.out | 175 +
.../sql-tests/results/udaf/udaf.sql.out | 97 +
.../udf/postgreSQL/udf-aggregates_part1.sql.out | 516 +
.../udf/postgreSQL/udf-aggregates_part2.sql.out | 261 +
.../udf/postgreSQL/udf-aggregates_part3.sql.out | 29 +
.../udf/postgreSQL/udf-aggregates_part4.sql.out | 31 +
.../results/udf/postgreSQL/udf-case.sql.out | 395 +
.../results/udf/postgreSQL/udf-join.sql.out | 3745 +++++
.../udf/postgreSQL/udf-select_having.sql.out | 222 +
.../udf/postgreSQL/udf-select_implicit.sql.out | 510 +
.../sql-tests/results/udf/udf-count.sql.out | 52 +
.../sql-tests/results/udf/udf-cross-join.sql.out | 137 +
.../sql-tests/results/udf/udf-except-all.sql.out | 377 +
.../sql-tests/results/udf/udf-except.sql.out | 102 +
.../results/udf/udf-group-analytics.sql.out | 423 +
.../sql-tests/results/udf/udf-group-by.sql.out | 671 +
.../sql-tests/results/udf/udf-having.sql.out | 46 +
.../sql-tests/results/udf/udf-inline-table.sql.out | 233 +
.../sql-tests/results/udf/udf-inner-join.sql.out | 64 +
.../results/udf/udf-intersect-all.sql.out | 338 +
.../results/udf/udf-join-empty-relation.sql.out | 191 +
.../sql-tests/results/udf/udf-natural-join.sql.out | 61 +
.../sql-tests/results/udf/udf-outer-join.sql.out | 85 +
.../sql-tests/results/udf/udf-pivot.sql.out | 531 +
.../results/udf/udf-special-values.sql.out | 59 +
.../sql-tests/results/udf/udf-udaf.sql.out | 97 +
.../sql-tests/results/udf/udf-union.sql.out | 207 +
.../sql-tests/results/udf/udf-window.sql.out | 489 +
.../sql-tests/results/udtf/udtf.sql.out | 1134 ++
.../backends-velox/sql-tests/results/union.sql.out | 248 +
.../sql-tests/results/unpivot.sql.out | 113 +
.../sql-tests/results/url-functions.sql.out | 158 +
.../sql-tests/results/using-join.sql.out | 447 +
.../variant/named-function-arguments.sql.out | 48 +
.../results/view-schema-binding-config.sql.out | 1229 ++
.../sql-tests/results/view-schema-binding.sql.out | 386 +
.../results/view-schema-compensation.sql.out | 593 +
.../results/view-schema-evolution.sql.out | 1113 ++
.../results/view-schema-type-evolution.sql.out | 663 +
.../results/view-with-default-collation.sql.out | 967 ++
.../sql-tests/results/window.sql.out | 1510 ++
.../sql-tests/results/xml-functions.sql.out | 437 +
.../spark40/src/test/resources/log4j2.properties | 39 +
.../org.mockito.plugins.MockMaker | 18 +
.../ClickHouseSQLQueryTestSettings.scala | 276 +
.../utils/clickhouse/ClickHouseTestSettings.scala | 2208 +++
.../utils/velox/VeloxSQLQueryTestSettings.scala | 324 +
.../gluten/utils/velox/VeloxTestSettings.scala | 955 ++
.../org/apache/spark/GlutenSortShuffleSuite.scala | 26 +
...ApproxCountDistinctForIntervalsQuerySuite.scala | 21 +
.../GlutenApproximatePercentileQuerySuite.scala | 26 +
.../sql/GlutenBitmapExpressionsQuerySuite.scala | 21 +
.../sql/GlutenBloomFilterAggregateQuerySuite.scala | 154 +
.../org/apache/spark/sql/GlutenCTEHintSuite.scala | 19 +
.../apache/spark/sql/GlutenCTEInlineSuite.scala | 33 +
.../apache/spark/sql/GlutenCachedTableSuite.scala | 158 +
.../spark/sql/GlutenCharVarcharTestSuite.scala | 70 +
.../spark/sql/GlutenColumnExpressionSuite.scala | 103 +
.../apache/spark/sql/GlutenComplexTypesSuite.scala | 95 +
.../spark/sql/GlutenConfigBehaviorSuite.scala | 19 +
.../sql/GlutenCountMinSketchAggQuerySuite.scala | 22 +
.../apache/spark/sql/GlutenCsvFunctionsSuite.scala | 19 +
.../spark/sql/GlutenDataFrameAggregateSuite.scala | 283 +
.../spark/sql/GlutenDataFrameAsOfJoinSuite.scala | 19 +
.../sql/GlutenDataFrameComplexTypeSuite.scala | 19 +
.../spark/sql/GlutenDataFrameFunctionsSuite.scala | 281 +
.../spark/sql/GlutenDataFrameHintSuite.scala | 19 +
.../spark/sql/GlutenDataFrameImplicitsSuite.scala | 19 +
.../spark/sql/GlutenDataFrameJoinSuite.scala | 24 +
.../sql/GlutenDataFrameNaFunctionsSuite.scala | 19 +
.../spark/sql/GlutenDataFramePivotSuite.scala | 19 +
.../spark/sql/GlutenDataFrameRangeSuite.scala | 19 +
.../spark/sql/GlutenDataFrameSelfJoinSuite.scala | 19 +
.../sql/GlutenDataFrameSessionWindowingSuite.scala | 21 +
.../sql/GlutenDataFrameSetOperationsSuite.scala | 29 +
.../spark/sql/GlutenDataFrameStatSuite.scala | 19 +
.../apache/spark/sql/GlutenDataFrameSuite.scala | 434 +
.../sql/GlutenDataFrameTimeWindowingSuite.scala | 21 +
.../spark/sql/GlutenDataFrameToSchemaSuite.scala | 19 +
.../spark/sql/GlutenDataFrameTungstenSuite.scala | 34 +
.../sql/GlutenDataFrameWindowFramesSuite.scala | 21 +
.../sql/GlutenDataFrameWindowFunctionsSuite.scala | 209 +
.../spark/sql/GlutenDataFrameWriterV2Suite.scala | 19 +
.../spark/sql/GlutenDatasetAggregatorSuite.scala | 19 +
.../apache/spark/sql/GlutenDatasetCacheSuite.scala | 19 +
.../spark/sql/GlutenDatasetOptimizationSuite.scala | 19 +
.../spark/sql/GlutenDatasetPrimitiveSuite.scala | 19 +
.../GlutenDatasetSerializerRegistratorSuite.scala | 21 +
.../org/apache/spark/sql/GlutenDatasetSuite.scala | 62 +
.../spark/sql/GlutenDatasetUnpivotSuite.scala | 19 +
.../spark/sql/GlutenDateFunctionsSuite.scala | 300 +
.../spark/sql/GlutenDeprecatedAPISuite.scala | 19 +
.../sql/GlutenDynamicPartitionPruningSuite.scala | 711 +
.../org/apache/spark/sql/GlutenEmptyInSuite.scala | 19 +
.../spark/sql/GlutenExpressionsSchemaSuite.scala | 19 +
.../spark/sql/GlutenExtraStrategiesSuite.scala | 19 +
.../spark/sql/GlutenFileBasedDataSourceSuite.scala | 275 +
.../org/apache/spark/sql/GlutenFileScanSuite.scala | 19 +
.../spark/sql/GlutenGeneratorFunctionSuite.scala | 28 +
.../spark/sql/GlutenInjectRuntimeFilterSuite.scala | 35 +
.../spark/sql/GlutenIntervalFunctionsSuite.scala | 19 +
.../org/apache/spark/sql/GlutenJoinSuite.scala | 57 +
.../spark/sql/GlutenJsonFunctionsSuite.scala | 132 +
.../spark/sql/GlutenLateralColumnAliasSuite.scala | 20 +
.../spark/sql/GlutenMathFunctionsSuite.scala | 19 +
.../spark/sql/GlutenMetadataCacheSuite.scala | 19 +
.../spark/sql/GlutenMiscFunctionsSuite.scala | 19 +
.../spark/sql/GlutenNestedDataSourceSuite.scala | 21 +
.../apache/spark/sql/GlutenParametersSuite.scala | 19 +
.../spark/sql/GlutenProcessingTimeSuite.scala | 19 +
.../apache/spark/sql/GlutenProductAggSuite.scala | 19 +
...laceNullWithFalseInPredicateEndToEndSuite.scala | 21 +
.../sql/GlutenResolveDefaultColumnsSuite.scala | 21 +
.../sql/GlutenRuntimeNullChecksV2Writes.scala | 19 +
.../spark/sql/GlutenSQLInsertTestSuite.scala | 23 +
.../org/apache/spark/sql/GlutenSQLQuerySuite.scala | 274 +
.../apache/spark/sql/GlutenSQLQueryTestSuite.scala | 794 +
.../sql/GlutenScalaReflectionRelationSuite.scala | 21 +
.../spark/sql/GlutenSerializationSuite.scala | 19 +
.../sql/GlutenSparkSessionExtensionSuite.scala | 55 +
.../sql/GlutenStatisticsCollectionSuite.scala | 76 +
.../spark/sql/GlutenStringFunctionsSuite.scala | 68 +
.../sql/GlutenSubqueryHintPropagationSuite.scala | 21 +
.../org/apache/spark/sql/GlutenSubquerySuite.scala | 55 +
.../GlutenTableOptionsConstantFoldingSuite.scala | 21 +
.../sql/GlutenTypedImperativeAggregateSuite.scala | 21 +
...GlutenUnwrapCastInComparisonEndToEndSuite.scala | 21 +
.../apache/spark/sql/GlutenUrlFunctionsSuite.scala | 19 +
.../spark/sql/GlutenXPathFunctionsSuite.scala | 19 +
.../GlutenArithmeticExpressionSuite.scala | 21 +
.../GlutenBitwiseExpressionsSuite.scala | 21 +
.../expressions/GlutenCastWithAnsiOffSuite.scala | 298 +
.../GlutenCollectionExpressionsSuite.scala | 90 +
.../expressions/GlutenComplexTypeSuite.scala | 21 +
.../GlutenConditionalExpressionSuite.scala | 21 +
.../expressions/GlutenDateExpressionsSuite.scala | 653 +
.../expressions/GlutenDecimalExpressionSuite.scala | 21 +
.../expressions/GlutenDecimalPrecisionSuite.scala | 138 +
.../GlutenGeneratorExpressionSuite.scala | 21 +
.../expressions/GlutenHashExpressionsSuite.scala | 21 +
.../GlutenHigherOrderFunctionsSuite.scala | 21 +
.../GlutenIntervalExpressionsSuite.scala | 21 +
.../expressions/GlutenJsonExpressionsSuite.scala | 21 +
.../expressions/GlutenLiteralExpressionSuite.scala | 21 +
.../expressions/GlutenMathExpressionsSuite.scala | 280 +
.../expressions/GlutenMiscExpressionsSuite.scala | 21 +
.../expressions/GlutenNondeterministicSuite.scala | 21 +
.../expressions/GlutenNullExpressionsSuite.scala | 21 +
.../expressions/GlutenPredicateSuite.scala | 21 +
.../catalyst/expressions/GlutenRandomSuite.scala | 21 +
.../expressions/GlutenRegexpExpressionsSuite.scala | 21 +
.../GlutenSortOrderExpressionsSuite.scala | 21 +
.../expressions/GlutenStringExpressionsSuite.scala | 21 +
.../catalyst/expressions/GlutenTryCastSuite.scala | 225 +
.../catalyst/expressions/GlutenTryEvalSuite.scala | 21 +
.../aggregate/GlutenPercentileSuite.scala | 21 +
...nDataSourceV2DataFrameSessionCatalogSuite.scala | 23 +
.../GlutenDataSourceV2DataFrameSuite.scala | 23 +
.../GlutenDataSourceV2FunctionSuite.scala | 23 +
.../GlutenDataSourceV2SQLSessionCatalogSuite.scala | 23 +
.../sql/connector/GlutenDataSourceV2SQLSuite.scala | 27 +
.../sql/connector/GlutenDataSourceV2Suite.scala | 168 +
.../GlutenDeltaBasedDeleteFromTableSuite.scala | 23 +
.../GlutenDeltaBasedMergeIntoTableSuite.scala | 24 +
...ergeIntoTableUpdateAsDeleteAndInsertSuite.scala | 24 +
...ltaBasedUpdateAsDeleteAndInsertTableSuite.scala | 23 +
.../GlutenDeltaBasedUpdateTableSuite.scala | 23 +
.../GlutenFileDataSourceV2FallBackSuite.scala | 83 +
.../GlutenGroupBasedDeleteFromTableSuite.scala | 27 +
.../GlutenGroupBasedMergeIntoTableSuite.scala | 24 +
.../GlutenKeyGroupedPartitioningSuite.scala | 1825 +++
.../spark/sql/connector/GlutenLocalScanSuite.scala | 21 +
.../connector/GlutenMergeIntoTableSuiteBase.scala | 218 +
.../sql/connector/GlutenMetadataColumnSuite.scala | 21 +
.../GlutenSupportsCatalogOptionsSuite.scala | 23 +
.../GlutenTableCapabilityCheckSuite.scala | 23 +
.../GlutenWriteDistributionAndOrderingSuite.scala | 30 +
.../GlutenQueryCompilationErrorsDSv2Suite.scala | 23 +
.../errors/GlutenQueryCompilationErrorsSuite.scala | 23 +
.../errors/GlutenQueryExecutionErrorsSuite.scala | 36 +
.../sql/errors/GlutenQueryParsingErrorsSuite.scala | 21 +
.../execution/GlutenBroadcastExchangeSuite.scala | 59 +
.../GlutenCoalesceShufflePartitionsSuite.scala | 284 +
.../spark/sql/execution/GlutenExchangeSuite.scala | 27 +
.../sql/execution/GlutenQueryExecutionSuite.scala | 107 +
...utenRemoveRedundantWindowGroupLimitsSuite.scala | 23 +
.../GlutenReplaceHashWithSortAggSuite.scala | 143 +
.../GlutenReuseExchangeAndSubquerySuite.scala | 23 +
.../GlutenSQLAggregateFunctionSuite.scala | 64 +
.../execution/GlutenSQLCollectLimitExecSuite.scala | 264 +
.../execution/GlutenSQLWindowFunctionSuite.scala | 231 +
.../sql/execution/GlutenSameResultSuite.scala | 21 +
.../spark/sql/execution/GlutenSortSuite.scala | 98 +
.../sql/execution/GlutenStreamingQuerySuite.scala | 49 +
.../GlutenTakeOrderedAndProjectSuite.scala | 65 +
.../ClickHouseAdaptiveQueryExecSuite.scala | 1569 ++
.../velox/VeloxAdaptiveQueryExecSuite.scala | 1551 ++
.../datasources/GlutenBucketingUtilsSuite.scala | 21 +
.../GlutenDataSourceStrategySuite.scala | 21 +
.../datasources/GlutenDataSourceSuite.scala | 21 +
.../datasources/GlutenFileFormatWriterSuite.scala | 25 +
.../datasources/GlutenFileIndexSuite.scala | 21 +
.../GlutenFileMetadataStructSuite.scala | 159 +
.../GlutenFileSourceAggregatePushDownSuite.scala | 35 +
.../datasources/GlutenFileSourceCodecSuite.scala | 29 +
...GlutenFileSourceCustomMetadataStructSuite.scala | 23 +
.../GlutenFileSourceStrategySuite.scala | 21 +
.../GlutenHadoopFileLinesReaderSuite.scala | 23 +
.../GlutenPathFilterStrategySuite.scala | 21 +
.../datasources/GlutenPathFilterSuite.scala | 21 +
.../GlutenPruneFileSourcePartitionsSuite.scala | 23 +
.../datasources/GlutenReadSchemaSuite.scala | 155 +
.../datasources/GlutenTableLocationSuite.scala | 21 +
.../datasources/GlutenV1WriteCommandSuite.scala | 268 +
.../binaryfile/GlutenBinaryFileFormatSuite.scala | 21 +
.../execution/datasources/csv/GlutenCSVSuite.scala | 135 +
.../datasources/json/GlutenJsonSuite.scala | 140 +
.../orc/GlutenOrcColumnarBatchReaderSuite.scala | 23 +
.../datasources/orc/GlutenOrcFilterSuite.scala | 22 +
.../orc/GlutenOrcPartitionDiscoverySuite.scala | 27 +
.../datasources/orc/GlutenOrcQuerySuite.scala | 156 +
.../datasources/orc/GlutenOrcSourceSuite.scala | 183 +
.../datasources/orc/GlutenOrcV1FilterSuite.scala | 21 +
.../orc/GlutenOrcV1SchemaPruningSuite.scala | 51 +
.../orc/GlutenOrcV2SchemaPruningSuite.scala | 54 +
.../parquet/GlutenParquetColumnIndexSuite.scala | 21 +
...tenParquetCompressionCodecPrecedenceSuite.scala | 22 +
.../GlutenParquetDeltaByteArrayEncodingSuite.scala | 23 +
.../parquet/GlutenParquetDeltaEncodingSuite.scala | 27 +
...nParquetDeltaLengthByteArrayEncodingSuite.scala | 23 +
.../parquet/GlutenParquetEncodingSuite.scala | 23 +
.../parquet/GlutenParquetFieldIdIOSuite.scala | 42 +
.../parquet/GlutenParquetFileFormatSuite.scala | 27 +
...tenParquetFileMetadataStructRowIndexSuite.scala | 23 +
.../parquet/GlutenParquetFilterSuite.scala | 580 +
.../datasources/parquet/GlutenParquetIOSuite.scala | 30 +
.../GlutenParquetInteroperabilitySuite.scala | 23 +
.../GlutenParquetPartitionDiscoverySuite.scala | 27 +
.../GlutenParquetProtobufCompatibilitySuite.scala | 28 +
.../parquet/GlutenParquetQuerySuite.scala | 55 +
.../parquet/GlutenParquetRebaseDatetimeSuite.scala | 105 +
.../parquet/GlutenParquetRowIndexSuite.scala | 361 +
.../parquet/GlutenParquetSchemaPruningSuite.scala | 88 +
.../parquet/GlutenParquetSchemaSuite.scala | 64 +
.../GlutenParquetThriftCompatibilitySuite.scala | 81 +
.../parquet/GlutenParquetVectorizedSuite.scala | 21 +
.../datasources/text/GlutenTextSuite.scala | 290 +
.../v2/GlutenDataSourceV2StrategySuite.scala | 23 +
.../datasources/v2/GlutenFileTableSuite.scala | 21 +
.../datasources/v2/GlutenV2PredicateSuite.scala | 21 +
.../exchange/GlutenEnsureRequirementsSuite.scala | 28 +
.../exchange/GlutenValidateRequirementsSuite.scala | 23 +
.../execution/joins/GlutenBroadcastJoinSuite.scala | 78 +
.../execution/joins/GlutenExistenceJoinSuite.scala | 21 +
.../sql/execution/joins/GlutenInnerJoinSuite.scala | 36 +
.../sql/execution/joins/GlutenOuterJoinSuite.scala | 36 +
.../python/GlutenBatchEvalPythonExecSuite.scala | 102 +
.../python/GlutenExtractPythonUDFsSuite.scala | 167 +
.../sql/extension/CustomerColumnarPreRules.scala | 47 +
...GlutenCollapseProjectExecTransformerSuite.scala | 126 +
.../extension/GlutenCustomerExtensionSuite.scala | 51 +
.../extension/GlutenSessionExtensionSuite.scala | 56 +
.../TestFileSourceScanExecTransformer.scala | 74 +
.../sql/gluten/GlutenFallbackStrategiesSuite.scala | 258 +
.../spark/sql/gluten/GlutenFallbackSuite.scala | 235 +
.../hive/execution/GlutenHiveSQLQueryCHSuite.scala | 123 +
.../hive/execution/GlutenHiveSQLQuerySuite.scala | 82 +
.../execution/GlutenHiveSQLQuerySuiteBase.scala | 98 +
.../sql/sources/GlutenBucketedReadSuite.scala | 23 +
.../sql/sources/GlutenBucketedWriteSuite.scala | 22 +
.../sources/GlutenCreateTableAsSelectSuite.scala | 23 +
.../sql/sources/GlutenDDLSourceLoadSuite.scala | 22 +
...GlutenDisableUnnecessaryBucketedScanSuite.scala | 27 +
.../sources/GlutenExternalCommandRunnerSuite.scala | 23 +
.../sql/sources/GlutenFilteredScanSuite.scala | 21 +
.../spark/sql/sources/GlutenFiltersSuite.scala | 22 +
.../spark/sql/sources/GlutenInsertSuite.scala | 610 +
.../sql/sources/GlutenPartitionedWriteSuite.scala | 21 +
.../spark/sql/sources/GlutenPathOptionSuite.scala | 21 +
.../spark/sql/sources/GlutenPrunedScanSuite.scala | 21 +
.../sources/GlutenResolvedDataSourceSuite.scala | 21 +
.../spark/sql/sources/GlutenSaveLoadSuite.scala | 21 +
.../spark/sql/sources/GlutenTableScanSuite.scala | 21 +
.../sql/statistics/SparkFunctionStatistics.scala | 218 +
873 files changed, 287402 insertions(+)
diff --git a/gluten-ut/spark40/pom.xml b/gluten-ut/spark40/pom.xml
new file mode 100644
index 0000000000..d169abb888
--- /dev/null
+++ b/gluten-ut/spark40/pom.xml
@@ -0,0 +1,302 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.gluten</groupId>
+ <artifactId>gluten-ut</artifactId>
+ <version>1.6.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>gluten-ut-spark40</artifactId>
+ <packaging>jar</packaging>
+ <name>Gluten Unit Test Spark40</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.gluten</groupId>
+ <artifactId>gluten-ut-common</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.parquet</groupId>
+ <artifactId>parquet-column</artifactId>
+ <version>1.15.2</version>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.parquet</groupId>
+ <artifactId>parquet-common</artifactId>
+ <version>1.15.2</version>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>${commons-lang3.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-llap-common</artifactId>
+ <version>4.0.0</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-common</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-serde</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-llap-client</artifactId>
+ <version>2.3.10</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-common</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-serde</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.hive</groupId>
+ <artifactId>hive-llap-common</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-framework</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>apache-curator</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.zookeeper</groupId>
+ <artifactId>zookeeper</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>net.alchim31.maven</groupId>
+ <artifactId>scala-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.scalastyle</groupId>
+ <artifactId>scalastyle-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>com.diffplug.spotless</groupId>
+ <artifactId>spotless-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.scalatest</groupId>
+ <artifactId>scalatest-maven-plugin</artifactId>
+ <configuration>
+ <junitxml>.</junitxml>
+ </configuration>
+ <executions>
+ <execution>
+ <id>test</id>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>prepare-test-jar</id>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ <phase>test-compile</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ <outputDirectory>target/scala-${scala.binary.version}/classes</outputDirectory>
+ <testOutputDirectory>target/scala-${scala.binary.version}/test-classes</testOutputDirectory>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>backends-clickhouse</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.gluten</groupId>
+ <artifactId>backends-clickhouse</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.celeborn</groupId>
+ <artifactId>celeborn-client-spark-${spark.major.version}-shaded_${scala.binary.version}</artifactId>
+ <version>${celeborn.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.arrow</groupId>
+ <artifactId>arrow-memory-core</artifactId>
+ <version>${arrow.version}</version>
+ <scope>provided</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-common</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-buffer</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.arrow</groupId>
+ <artifactId>arrow-vector</artifactId>
+ <version>${arrow.version}</version>
+ <scope>provided</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-common</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-buffer</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>add-sources</id>
+ <goals>
+ <goal>add-test-source</goal>
+ </goals>
+ <phase>generate-sources</phase>
+ <configuration>
+ <sources>
+ <source>src/test/backends-clickhouse</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>backends-velox</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <dependencies>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter</artifactId>
+ <version>5.9.3</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>net.aichler</groupId>
+ <artifactId>jupiter-interface</artifactId>
+ <version>0.11.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.gluten</groupId>
+ <artifactId>backends-velox</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <!-- log4j -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j2-impl</artifactId>
+ <version>${log4j.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ <version>2.2.220</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>add-sources</id>
+ <goals>
+ <goal>add-test-source</goal>
+ </goals>
+ <phase>generate-sources</phase>
+ <configuration>
+ <sources>
+ <source>src/test/backends-velox</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/gluten-ut/spark40/src/test/backends-clickhouse/org/apache/gluten/GlutenColumnarWriteTestSupport.scala b/gluten-ut/spark40/src/test/backends-clickhouse/org/apache/gluten/GlutenColumnarWriteTestSupport.scala
new file mode 100644
index 0000000000..4258cd891a
--- /dev/null
+++ b/gluten-ut/spark40/src/test/backends-clickhouse/org/apache/gluten/GlutenColumnarWriteTestSupport.scala
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.gluten
+
+import org.apache.spark.sql.execution.{ColumnarWriteFilesExec, SparkPlan}
+
+trait GlutenColumnarWriteTestSupport {
+
+ def checkWriteFilesAndGetChild(sparkPlan: SparkPlan): SparkPlan = {
+ assert(sparkPlan.isInstanceOf[ColumnarWriteFilesExec])
+ sparkPlan.asInstanceOf[ColumnarWriteFilesExec].child
+ }
+}
diff --git a/gluten-ut/spark40/src/test/backends-clickhouse/org/apache/gluten/execution/parquet/GlutenParquetV1FilterSuite2.scala b/gluten-ut/spark40/src/test/backends-clickhouse/org/apache/gluten/execution/parquet/GlutenParquetV1FilterSuite2.scala
new file mode 100644
index 0000000000..5b84888376
--- /dev/null
+++ b/gluten-ut/spark40/src/test/backends-clickhouse/org/apache/gluten/execution/parquet/GlutenParquetV1FilterSuite2.scala
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.gluten.execution.parquet
+
+import org.apache.spark.SparkConf
+import org.apache.spark.sql.execution.datasources.parquet.GlutenParquetV1FilterSuite
+
+
+/** testing use_local_format parquet reader. **/
+class GlutenParquetV1FilterSuite2 extends GlutenParquetV1FilterSuite {
+ override def sparkConf: SparkConf =
+ super.sparkConf
+ .set("spark.gluten.sql.columnar.backend.ch.runtime_config.use_local_format", "true")
+}
diff --git a/gluten-ut/spark40/src/test/backends-velox/org/apache/gluten/GlutenColumnarWriteTestSupport.scala b/gluten-ut/spark40/src/test/backends-velox/org/apache/gluten/GlutenColumnarWriteTestSupport.scala
new file mode 100644
index 0000000000..68c0e1c932
--- /dev/null
+++ b/gluten-ut/spark40/src/test/backends-velox/org/apache/gluten/GlutenColumnarWriteTestSupport.scala
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.gluten
+
+import org.apache.spark.sql.execution.{SparkPlan, ColumnarWriteFilesExec}
+
+trait GlutenColumnarWriteTestSupport {
+
+ def checkWriteFilesAndGetChild(sparkPlan: SparkPlan): SparkPlan = {
+ assert(sparkPlan.isInstanceOf[ColumnarWriteFilesExec])
+ sparkPlan.asInstanceOf[ColumnarWriteFilesExec].child
+ }
+}
diff --git a/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/group-by-ordinal.sql b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/group-by-ordinal.sql
new file mode 100644
index 0000000000..b773396c05
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/group-by-ordinal.sql
@@ -0,0 +1,96 @@
+-- group by ordinal positions
+
+create temporary view data as select * from values
+ (1, 1),
+ (1, 2),
+ (2, 1),
+ (2, 2),
+ (3, 1),
+ (3, 2)
+ as data(a, b);
+
+-- basic case
+select a, sum(b) from data group by 1;
+
+-- constant case
+select 1, 2, sum(b) from data group by 1, 2;
+
+-- duplicate group by column
+select a, 1, sum(b) from data group by a, 1;
+select a, 1, sum(b) from data group by 1, 2;
+
+-- group by a non-aggregate expression's ordinal
+select a, b + 2, count(2) from data group by a, 2;
+
+-- with alias
+select a as aa, b + 2 as bb, count(2) from data group by 1, 2;
+
+-- foldable non-literal: this should be the same as no grouping.
+select sum(b) from data group by 1 + 0;
+
+-- negative cases: ordinal out of range
+select a, b from data group by -1;
+select a, b from data group by 0;
+select a, b from data group by 3;
+
+-- negative case: position is an aggregate expression
+select a, b, sum(b) from data group by 3;
+select a, b, sum(b) + 2 from data group by 3;
+
+-- negative case: nondeterministic expression
+select a, rand(0), sum(b)
+from
+(select /*+ REPARTITION(1) */ a, b from data) group by a, 2;
+
+-- negative case: star
+select * from data group by a, b, 1;
+
+-- group by ordinal followed by order by
+select a, count(a) from (select 1 as a) tmp group by 1 order by 1;
+
+-- group by ordinal followed by having
+select count(a), a from (select 1 as a) tmp group by 2 having a > 0;
+
+-- mixed cases: group-by ordinals and aliases
+select a, a AS k, count(b) from data group by k, 1;
+
+-- can use ordinal in CUBE
+select a, b, count(1) from data group by cube(1, 2);
+
+-- mixed cases: can use ordinal in CUBE
+select a, b, count(1) from data group by cube(1, b);
+
+-- can use ordinal with cube
+select a, b, count(1) from data group by 1, 2 with cube;
+
+-- can use ordinal in ROLLUP
+select a, b, count(1) from data group by rollup(1, 2);
+
+-- mixed cases: can use ordinal in ROLLUP
+select a, b, count(1) from data group by rollup(1, b);
+
+-- can use ordinal with rollup
+select a, b, count(1) from data group by 1, 2 with rollup;
+
+-- can use ordinal in GROUPING SETS
+select a, b, count(1) from data group by grouping sets((1), (2), (1, 2));
+
+-- mixed cases: can use ordinal in GROUPING SETS
+select a, b, count(1) from data group by grouping sets((1), (b), (a, 2));
+
+select a, b, count(1) from data group by a, 2 grouping sets((1), (b), (a, 2));
+
+-- range error
+select a, b, count(1) from data group by a, -1;
+
+select a, b, count(1) from data group by a, 3;
+
+select a, b, count(1) from data group by cube(-1, 2);
+
+select a, b, count(1) from data group by cube(1, 3);
+
+-- turn off group by ordinal
+set spark.sql.groupByOrdinal=false;
+
+-- can now group by negative literal
+select sum(b) from data group by -1;
diff --git a/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/group-by.sql b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/group-by.sql
new file mode 100644
index 0000000000..c35cdb0de2
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/group-by.sql
@@ -0,0 +1,266 @@
+-- Test aggregate operator with codegen on and off.
+--CONFIG_DIM1 spark.sql.codegen.wholeStage=true
+--CONFIG_DIM1 spark.sql.codegen.wholeStage=false,spark.sql.codegen.factoryMode=CODEGEN_ONLY
+--CONFIG_DIM1 spark.sql.codegen.wholeStage=false,spark.sql.codegen.factoryMode=NO_CODEGEN
+
+-- Test data.
+CREATE OR REPLACE TEMPORARY VIEW testData AS SELECT * FROM VALUES
+(1, 1), (1, 2), (2, 1), (2, 2), (3, 1), (3, 2), (null, 1), (3, null), (null, null)
+AS testData(a, b);
+
+-- Aggregate with empty GroupBy expressions.
+SELECT a, COUNT(b) FROM testData;
+SELECT COUNT(a), COUNT(b) FROM testData;
+
+-- Aggregate with non-empty GroupBy expressions.
+SELECT a, COUNT(b) FROM testData GROUP BY a;
+SELECT a, COUNT(b) FROM testData GROUP BY b;
+SELECT COUNT(a), COUNT(b) FROM testData GROUP BY a;
+
+-- Aggregate grouped by literals.
+SELECT 'foo', COUNT(a) FROM testData GROUP BY 1;
+
+-- Aggregate grouped by literals (whole stage code generation).
+SELECT 'foo' FROM testData WHERE a = 0 GROUP BY 1;
+
+-- Aggregate grouped by literals (hash aggregate).
+SELECT 'foo', APPROX_COUNT_DISTINCT(a) FROM testData WHERE a = 0 GROUP BY 1;
+
+-- Aggregate grouped by literals (sort aggregate).
+SELECT 'foo', MAX(STRUCT(a)) FROM testData WHERE a = 0 GROUP BY 1;
+
+-- Aggregate with complex GroupBy expressions.
+SELECT a + b, COUNT(b) FROM testData GROUP BY a + b;
+SELECT a + 2, COUNT(b) FROM testData GROUP BY a + 1;
+SELECT a + 1 + 1, COUNT(b) FROM testData GROUP BY a + 1;
+
+-- struct() in group by
+SELECT count(1) FROM testData GROUP BY struct(a + 0.1 AS aa);
+
+-- Aggregate with nulls.
+SELECT SKEWNESS(a), KURTOSIS(a), MIN(a), MAX(a), AVG(a), VARIANCE(a), STDDEV(a), SUM(a), COUNT(a)
+FROM testData;
+
+-- Aggregate with foldable input and multiple distinct groups.
+SELECT COUNT(DISTINCT b), COUNT(DISTINCT b, c) FROM (SELECT 1 AS a, 2 AS b, 3 AS c) GROUP BY a;
+
+-- Aliases in SELECT could be used in GROUP BY
+SELECT a AS k, COUNT(b) FROM testData GROUP BY k;
+SELECT a AS k, COUNT(b) FROM testData GROUP BY k HAVING k > 1;
+
+-- GROUP BY alias with invalid col in SELECT list
+SELECT a AS k, COUNT(non_existing) FROM testData GROUP BY k;
+
+-- Aggregate functions cannot be used in GROUP BY
+SELECT COUNT(b) AS k FROM testData GROUP BY k;
+
+-- Test data.
+CREATE OR REPLACE TEMPORARY VIEW testDataHasSameNameWithAlias AS SELECT * FROM VALUES
+(1, 1, 3), (1, 2, 1) AS testDataHasSameNameWithAlias(k, a, v);
+SELECT k AS a, COUNT(v) FROM testDataHasSameNameWithAlias GROUP BY a;
+
+-- turn off group by aliases
+set spark.sql.groupByAliases=false;
+
+-- Check analysis exceptions
+SELECT a AS k, COUNT(b) FROM testData GROUP BY k;
+
+-- Aggregate with empty input and non-empty GroupBy expressions.
+SELECT a, COUNT(1) FROM testData WHERE false GROUP BY a;
+
+-- Aggregate with empty input and empty GroupBy expressions.
+SELECT COUNT(1) FROM testData WHERE false;
+SELECT 1 FROM (SELECT COUNT(1) FROM testData WHERE false) t;
+
+-- Aggregate with empty GroupBy expressions and filter on top
+SELECT 1 from (
+ SELECT 1 AS z,
+ MIN(a.x)
+ FROM (select 1 as x) a
+ WHERE false
+) b
+where b.z != b.z;
+
+-- SPARK-24369 multiple distinct aggregations having the same argument set
+SELECT corr(DISTINCT x, y), corr(DISTINCT y, x), count(*)
+ FROM (VALUES (1, 1), (2, 2), (2, 2)) t(x, y);
+
+-- SPARK-25708 HAVING without GROUP BY means global aggregate
+SELECT 1 FROM range(10) HAVING true;
+
+SELECT 1 FROM range(10) HAVING MAX(id) > 0;
+
+SELECT id FROM range(10) HAVING id > 0;
+
+SET spark.sql.legacy.parser.havingWithoutGroupByAsWhere=true;
+
+SELECT 1 FROM range(10) HAVING true;
+
+SELECT 1 FROM range(10) HAVING MAX(id) > 0;
+
+SELECT id FROM range(10) HAVING id > 0;
+
+SET spark.sql.legacy.parser.havingWithoutGroupByAsWhere=false;
+
+-- Test data
+CREATE OR REPLACE TEMPORARY VIEW test_agg AS SELECT * FROM VALUES
+ (1, true), (1, false),
+ (2, true),
+ (3, false), (3, null),
+ (4, null), (4, null),
+ (5, null), (5, true), (5, false) AS test_agg(k, v);
+
+-- empty table
+SELECT every(v), some(v), any(v), bool_and(v), bool_or(v) FROM test_agg WHERE 1 = 0;
+
+-- all null values
+SELECT every(v), some(v), any(v), bool_and(v), bool_or(v) FROM test_agg WHERE k = 4;
+
+-- aggregates are null Filtering
+SELECT every(v), some(v), any(v), bool_and(v), bool_or(v) FROM test_agg WHERE k = 5;
+
+-- group by
+SELECT k, every(v), some(v), any(v), bool_and(v), bool_or(v) FROM test_agg GROUP BY k;
+
+-- having
+SELECT k, every(v) FROM test_agg GROUP BY k HAVING every(v) = false;
+SELECT k, every(v) FROM test_agg GROUP BY k HAVING every(v) IS NULL;
+
+-- basic subquery path to make sure rewrite happens in both parent and child plans.
+SELECT k,
+ Every(v) AS every
+FROM test_agg
+WHERE k = 2
+ AND v IN (SELECT Any(v)
+ FROM test_agg
+ WHERE k = 1)
+GROUP BY k;
+
+-- basic subquery path to make sure rewrite happens in both parent and child plans.
+SELECT k,
+ Every(v) AS every
+FROM test_agg
+WHERE k = 2
+ AND v IN (SELECT Every(v)
+ FROM test_agg
+ WHERE k = 1)
+GROUP BY k;
+
+-- input type checking Int
+SELECT every(1);
+
+-- input type checking Short
+SELECT some(1S);
+
+-- input type checking Long
+SELECT any(1L);
+
+-- input type checking String
+SELECT every("true");
+
+-- input type checking Decimal
+SELECT bool_and(1.0);
+
+-- input type checking double
+SELECT bool_or(1.0D);
+
+-- every/some/any aggregates/bool_and/bool_or are supported as windows expression.
+SELECT k, v, every(v) OVER (PARTITION BY k ORDER BY v) FROM test_agg;
+SELECT k, v, some(v) OVER (PARTITION BY k ORDER BY v) FROM test_agg;
+SELECT k, v, any(v) OVER (PARTITION BY k ORDER BY v) FROM test_agg;
+SELECT k, v, bool_and(v) OVER (PARTITION BY k ORDER BY v) FROM test_agg;
+SELECT k, v, bool_or(v) OVER (PARTITION BY k ORDER BY v) FROM test_agg;
+
+-- Having referencing aggregate expressions is ok.
+SELECT count(*) FROM test_agg HAVING count(*) > 1L;
+SELECT k, max(v) FROM test_agg GROUP BY k HAVING max(v) = true;
+
+-- Aggrgate expressions can be referenced through an alias
+SELECT * FROM (SELECT COUNT(*) AS cnt FROM test_agg) WHERE cnt > 1L;
+
+-- Error when aggregate expressions are in where clause directly
+SELECT count(*) FROM test_agg WHERE count(*) > 1L;
+SELECT count(*) FROM test_agg WHERE count(*) + 1L > 1L;
+SELECT count(*) FROM test_agg WHERE k = 1 or k = 2 or count(*) + 1L > 1L or max(k) > 1;
+
+-- Aggregate with multiple distinct decimal columns
+SELECT AVG(DISTINCT decimal_col), SUM(DISTINCT decimal_col) FROM VALUES (CAST(1 AS DECIMAL(9, 0))) t(decimal_col);
+
+-- SPARK-34581: Don't optimize out grouping expressions from aggregate expressions without aggregate function
+SELECT not(a IS NULL), count(*) AS c
+FROM testData
+GROUP BY a IS NULL;
+
+SELECT if(not(a IS NULL), rand(0), 1), count(*) AS c
+FROM testData
+GROUP BY a IS NULL;
+
+
+-- Histogram aggregates with different numeric input types
+SELECT
+ histogram_numeric(col, 2) as histogram_2,
+ histogram_numeric(col, 3) as histogram_3,
+ histogram_numeric(col, 5) as histogram_5,
+ histogram_numeric(col, 10) as histogram_10
+FROM VALUES
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (11), (12), (13), (14), (15), (16), (17), (18), (19), (20),
+ (21), (22), (23), (24), (25), (26), (27), (28), (29), (30),
+ (31), (32), (33), (34), (35), (3), (37), (38), (39), (40),
+ (41), (42), (43), (44), (45), (46), (47), (48), (49), (50) AS tab(col);
+SELECT histogram_numeric(col, 3) FROM VALUES (1), (2), (3) AS tab(col);
+SELECT histogram_numeric(col, 3) FROM VALUES (1L), (2L), (3L) AS tab(col);
+SELECT histogram_numeric(col, 3) FROM VALUES (1F), (2F), (3F) AS tab(col);
+SELECT histogram_numeric(col, 3) FROM VALUES (1D), (2D), (3D) AS tab(col);
+SELECT histogram_numeric(col, 3) FROM VALUES (1S), (2S), (3S) AS tab(col);
+SELECT histogram_numeric(col, 3) FROM VALUES
+ (CAST(1 AS BYTE)), (CAST(2 AS BYTE)), (CAST(3 AS BYTE)) AS tab(col);
+SELECT histogram_numeric(col, 3) FROM VALUES
+ (CAST(1 AS TINYINT)), (CAST(2 AS TINYINT)), (CAST(3 AS TINYINT)) AS tab(col);
+SELECT histogram_numeric(col, 3) FROM VALUES
+ (CAST(1 AS SMALLINT)), (CAST(2 AS SMALLINT)), (CAST(3 AS SMALLINT)) AS tab(col);
+SELECT histogram_numeric(col, 3) FROM VALUES
+ (CAST(1 AS BIGINT)), (CAST(2 AS BIGINT)), (CAST(3 AS BIGINT)) AS tab(col);
+SELECT histogram_numeric(col, 3) FROM VALUES (TIMESTAMP '2017-03-01 00:00:00'),
+ (TIMESTAMP '2017-04-01 00:00:00'), (TIMESTAMP '2017-05-01 00:00:00') AS tab(col);
+SELECT histogram_numeric(col, 3) FROM VALUES (INTERVAL '100-00' YEAR TO MONTH),
+ (INTERVAL '110-00' YEAR TO MONTH), (INTERVAL '120-00' YEAR TO MONTH) AS tab(col);
+SELECT histogram_numeric(col, 3) FROM VALUES (INTERVAL '12 20:4:0' DAY TO SECOND),
+ (INTERVAL '12 21:4:0' DAY TO SECOND), (INTERVAL '12 22:4:0' DAY TO SECOND) AS tab(col);
+SELECT histogram_numeric(col, 3)
+FROM VALUES (NULL), (NULL), (NULL) AS tab(col);
+SELECT histogram_numeric(col, 3)
+FROM VALUES (CAST(NULL AS DOUBLE)), (CAST(NULL AS DOUBLE)), (CAST(NULL AS DOUBLE)) AS tab(col);
+SELECT histogram_numeric(col, 3)
+FROM VALUES (CAST(NULL AS INT)), (CAST(NULL AS INT)), (CAST(NULL AS INT)) AS tab(col);
+
+-- SPARK-27974: Support ANSI Aggregate Function: array_agg
+SELECT
+ collect_list(col),
+ array_agg(col)
+FROM VALUES
+ (1), (2), (1) AS tab(col);
+SELECT
+ a,
+ collect_list(b),
+ array_agg(b)
+FROM VALUES
+ (1,4),(2,3),(1,4),(2,4) AS v(a,b)
+GROUP BY a;
+
+
+SELECT mode(a), mode(b) FROM testData;
+SELECT a, mode(b) FROM testData GROUP BY a ORDER BY a;
+
+
+-- SPARK-44846: PushFoldableIntoBranches in complex grouping expressions cause bindReference error
+SELECT c * 2 AS d
+FROM (
+ SELECT if(b > 1, 1, b) AS c
+ FROM (
+ SELECT if(a < 0, 0, a) AS b
+ FROM VALUES (-1), (1), (2) AS t1(a)
+ ) t2
+ GROUP BY b
+ ) t3
+GROUP BY c;
diff --git a/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/linear-regression.sql b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/linear-regression.sql
new file mode 100644
index 0000000000..c7cb5bf111
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/linear-regression.sql
@@ -0,0 +1,52 @@
+-- Test data.
+CREATE OR REPLACE TEMPORARY VIEW testRegression AS SELECT * FROM VALUES
+(1, 10, null), (2, 10, 11), (2, 20, 22), (2, 25, null), (2, 30, 35)
+AS testRegression(k, y, x);
+
+-- SPARK-37613: Support ANSI Aggregate Function: regr_count
+SELECT regr_count(y, x) FROM testRegression;
+SELECT regr_count(y, x) FROM testRegression WHERE x IS NOT NULL;
+SELECT k, count(*), regr_count(y, x) FROM testRegression GROUP BY k;
+SELECT k, count(*) FILTER (WHERE x IS NOT NULL), regr_count(y, x) FROM testRegression GROUP BY k;
+
+-- SPARK-37613: Support ANSI Aggregate Function: regr_r2
+SELECT regr_r2(y, x) FROM testRegression;
+SELECT regr_r2(y, x) FROM testRegression WHERE x IS NOT NULL;
+SELECT k, corr(y, x), regr_r2(y, x) FROM testRegression GROUP BY k;
+SELECT k, corr(y, x) FILTER (WHERE x IS NOT NULL), regr_r2(y, x) FROM testRegression GROUP BY k;
+
+-- SPARK-37614: Support ANSI Aggregate Function: regr_avgx & regr_avgy
+SELECT regr_avgx(y, x), regr_avgy(y, x) FROM testRegression;
+SELECT regr_avgx(y, x), regr_avgy(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL;
+SELECT k, avg(x), avg(y), regr_avgx(y, x), regr_avgy(y, x) FROM testRegression GROUP BY k;
+SELECT k, avg(x) FILTER (WHERE x IS NOT NULL AND y IS NOT NULL), avg(y) FILTER (WHERE x IS NOT NULL AND y IS NOT NULL), regr_avgx(y, x), regr_avgy(y, x) FROM testRegression GROUP BY k;
+
+-- SPARK-37672: Support ANSI Aggregate Function: regr_sxx
+SELECT regr_sxx(y, x) FROM testRegression;
+SELECT regr_sxx(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL;
+SELECT k, regr_sxx(y, x) FROM testRegression GROUP BY k;
+SELECT k, regr_sxx(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL GROUP BY k;
+
+-- SPARK-37681: Support ANSI Aggregate Function: regr_sxy
+SELECT regr_sxy(y, x) FROM testRegression;
+SELECT regr_sxy(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL;
+SELECT k, regr_sxy(y, x) FROM testRegression GROUP BY k;
+SELECT k, regr_sxy(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL GROUP BY k;
+
+-- SPARK-37702: Support ANSI Aggregate Function: regr_syy
+SELECT regr_syy(y, x) FROM testRegression;
+SELECT regr_syy(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL;
+SELECT k, regr_syy(y, x) FROM testRegression GROUP BY k;
+SELECT k, regr_syy(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL GROUP BY k;
+
+-- SPARK-39230: Support ANSI Aggregate Function: regr_slope
+SELECT regr_slope(y, x) FROM testRegression;
+SELECT regr_slope(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL;
+SELECT k, regr_slope(y, x) FROM testRegression GROUP BY k;
+SELECT k, regr_slope(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL GROUP BY k;
+
+-- SPARK-37623: Support ANSI Aggregate Function: regr_intercept
+SELECT regr_intercept(y, x) FROM testRegression;
+SELECT regr_intercept(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL;
+SELECT k, regr_intercept(y, x) FROM testRegression GROUP BY k;
+SELECT k, regr_intercept(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL GROUP BY k;
diff --git a/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/misc-functions.sql b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/misc-functions.sql
new file mode 100644
index 0000000000..907ff33000
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/misc-functions.sql
@@ -0,0 +1,22 @@
+-- test for misc functions
+
+-- typeof
+select typeof(null);
+select typeof(true);
+select typeof(1Y), typeof(1S), typeof(1), typeof(1L);
+select typeof(cast(1.0 as float)), typeof(1.0D), typeof(1.2);
+select typeof(date '1986-05-23'), typeof(timestamp '1986-05-23'), typeof(interval '23 days');
+select typeof(x'ABCD'), typeof('SPARK');
+select typeof(array(1, 2)), typeof(map(1, 2)), typeof(named_struct('a', 1, 'b', 'spark'));
+
+-- Spark-32793: Rewrite AssertTrue with RaiseError
+SELECT assert_true(true), assert_true(boolean(1));
+SELECT assert_true(false);
+SELECT assert_true(boolean(0));
+SELECT assert_true(null);
+SELECT assert_true(boolean(null));
+SELECT assert_true(false, 'custom error message');
+
+CREATE TEMPORARY VIEW tbl_misc AS SELECT * FROM (VALUES (1), (8), (2)) AS T(v);
+SELECT raise_error('error message');
+SELECT if(v > 5, raise_error('too big: ' || v), v + 1) FROM tbl_misc;
diff --git a/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/random.sql b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/random.sql
new file mode 100644
index 0000000000..a1aae7b875
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/random.sql
@@ -0,0 +1,17 @@
+-- rand with the seed 0
+SELECT rand(0);
+SELECT rand(cast(3 / 7 AS int));
+SELECT rand(NULL);
+SELECT rand(cast(NULL AS int));
+
+-- rand unsupported data type
+SELECT rand(1.0);
+
+-- randn with the seed 0
+SELECT randn(0L);
+SELECT randn(cast(3 / 7 AS long));
+SELECT randn(NULL);
+SELECT randn(cast(NULL AS long));
+
+-- randn unsupported data type
+SELECT rand('1')
diff --git a/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/table-valued-functions.sql b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/table-valued-functions.sql
new file mode 100644
index 0000000000..79d427bc20
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/table-valued-functions.sql
@@ -0,0 +1,126 @@
+-- unresolved function
+select * from dummy(3);
+
+-- range call with end
+select * from range(6 + cos(3));
+
+-- range call with start and end
+select * from range(5, 10);
+
+-- range call with step
+select * from range(0, 10, 2);
+
+-- range call with numPartitions
+select * from range(0, 10, 1, 200);
+
+-- range call with invalid number of arguments
+select * from range(1, 1, 1, 1, 1);
+
+-- range call with null
+select * from range(1, null);
+
+-- range call with incompatible type
+select * from range(array(1, 2, 3));
+
+-- range call with illegal step
+select * from range(0, 5, 0);
+
+-- range call with a mixed-case function name
+select * from RaNgE(2);
+
+-- range call with alias
+select i from range(0, 2) t(i);
+
+-- explode
+select * from explode(array(1, 2));
+select * from explode(map('a', 1, 'b', 2));
+
+-- explode with empty values
+select * from explode(array());
+select * from explode(map());
+
+-- explode with column aliases
+select * from explode(array(1, 2)) t(c1);
+select * from explode(map('a', 1, 'b', 2)) t(k, v);
+
+-- explode with non-deterministic values
+select * from explode(array(rand(0)));
+
+-- explode with erroneous input
+select * from explode(null);
+select * from explode(null) t(c1);
+select * from explode(1);
+select * from explode(1, 2);
+select * from explode(explode(array(1)));
+select * from explode(array(1, 2)) t(c1, c2);
+
+-- explode_outer
+select * from explode_outer(array(1, 2));
+select * from explode_outer(map('a', 1, 'b', 2));
+select * from explode_outer(array());
+select * from explode_outer(map());
+
+-- table-valued functions with join
+select * from range(2) join explode(array(1, 2));
+select * from range(2) join explode_outer(array());
+
+-- inline
+select * from inline(array(struct(1, 'a'), struct(2, 'b')));
+select * from inline(array(struct(1, 'a'), struct(2, 'b'))) t(x, y);
+select * from inline(array_remove(array(struct(1, 'a')), struct(1, 'a')));
+
+-- inline with erroneous input
+select * from inline(null);
+select * from inline(array(struct(1, 2), struct(2, 3))) t(a, b, c);
+
+-- inline_outer
+select * from inline_outer(array(struct(1, 'a'), struct(2, 'b')));
+select * from inline_outer(array_remove(array(struct(1, 'a')), struct(1, 'a')));
+
+-- posexplode
+select * from posexplode(array());
+select * from posexplode(array(1, 2));
+select * from posexplode(array(1, 2)) t(pos, x);
+select * from posexplode(map());
+select * from posexplode(map('a', 1, 'b', 2));
+select * from posexplode(map('a', 1, 'b', 2)) t(pos, k, v);
+
+-- posexplode with erroneous input
+select * from posexplode(1);
+select * from posexplode(1, 2);
+select * from posexplode(explode(array(1)));
+select * from posexplode(array(1, 2)) t(x);
+
+-- posexplode
+select * from posexplode_outer(array());
+select * from posexplode_outer(array(1, 2));
+select * from posexplode_outer(map());
+select * from posexplode_outer(map('a', 1, 'b', 2));
+
+-- json_tuple
+select * from json_tuple('{"a": 1, "b": 2}', 'a', 'b');
+select * from json_tuple('{"a": 1, "b": 2}', 'a', 'c');
+select * from json_tuple('{"a": 1, "b": 2}', 'a', 'a');
+select * from json_tuple('{"a": 1, "b": 2}', 'a', 'b') AS t(x, y);
+select * from json_tuple('{"a": bad, "b": string}', 'a', 'b');
+
+-- json_tuple with erroneous input
+select * from json_tuple();
+select * from json_tuple('{"a": 1}');
+select * from json_tuple('{"a": 1}', 1);
+select * from json_tuple('{"a": 1}', null);
+select * from json_tuple('{"a": 1, "b": 2}', 'a', 'b') AS t(x);
+
+-- stack
+select * from stack(1, 1, 2, 3);
+select * from stack(2, 1, 2, 3);
+select * from stack(3, 1, 2, 3) t(x);
+select * from stack(4, 1, 2, 3) t(x);
+select * from stack(2, 1, 1.1, 'a', 2, 2.2, 'b') t(a, b, c);
+select * from stack(2, 1, 1.1, null, 2, null, 'b') t(a, b, c);
+
+-- stack with erroneous input
+select * from stack();
+select * from stack(2, 1, 2, 3) t(a, b, c);
+select * from stack(2, 1, '1.1', 'a', 2, 2.2, 'b');
+select * from stack(2, explode(array(1, 2, 3)));
diff --git a/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/udf/udf-group-by.sql b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/udf/udf-group-by.sql
new file mode 100644
index 0000000000..0cc57c97b0
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/inputs/udf/udf-group-by.sql
@@ -0,0 +1,156 @@
+-- This test file was converted from group-by.sql.
+-- Test data.
+CREATE OR REPLACE TEMPORARY VIEW testData AS SELECT * FROM VALUES
+(1, 1), (1, 2), (2, 1), (2, 2), (3, 1), (3, 2), (null, 1), (3, null), (null, null)
+AS testData(a, b);
+
+-- Aggregate with empty GroupBy expressions.
+SELECT udf(a), udf(COUNT(b)) FROM testData;
+SELECT COUNT(udf(a)), udf(COUNT(b)) FROM testData;
+
+-- Aggregate with non-empty GroupBy expressions.
+SELECT udf(a), COUNT(udf(b)) FROM testData GROUP BY a;
+SELECT udf(a), udf(COUNT(udf(b))) FROM testData GROUP BY b;
+SELECT COUNT(udf(a)), COUNT(udf(b)) FROM testData GROUP BY udf(a);
+
+-- Aggregate grouped by literals.
+SELECT 'foo', COUNT(udf(a)) FROM testData GROUP BY 1;
+
+-- Aggregate grouped by literals (whole stage code generation).
+SELECT 'foo' FROM testData WHERE a = 0 GROUP BY udf(1);
+
+-- Aggregate grouped by literals (hash aggregate).
+SELECT 'foo', udf(APPROX_COUNT_DISTINCT(udf(a))) FROM testData WHERE a = 0 GROUP BY udf(1);
+
+-- Aggregate grouped by literals (sort aggregate).
+SELECT 'foo', MAX(STRUCT(udf(a))) FROM testData WHERE a = 0 GROUP BY udf(1);
+
+-- Aggregate with complex GroupBy expressions.
+SELECT udf(a + b), udf(COUNT(b)) FROM testData GROUP BY a + b;
+SELECT udf(a + 2), udf(COUNT(b)) FROM testData GROUP BY a + 1;
+SELECT udf(a + 1) + 1, udf(COUNT(b)) FROM testData GROUP BY udf(a + 1);
+
+-- Aggregate with nulls.
+SELECT SKEWNESS(udf(a)), udf(KURTOSIS(a)), udf(MIN(a)), MAX(udf(a)), udf(AVG(udf(a))), udf(VARIANCE(a)), STDDEV(udf(a)), udf(SUM(a)), udf(COUNT(a))
+FROM testData;
+
+-- Aggregate with foldable input and multiple distinct groups.
+SELECT COUNT(DISTINCT udf(b)), udf(COUNT(DISTINCT b, c)) FROM (SELECT 1 AS a, 2 AS b, 3 AS c) GROUP BY udf(a);
+
+-- Aliases in SELECT could be used in GROUP BY
+SELECT udf(a) AS k, COUNT(udf(b)) FROM testData GROUP BY k;
+SELECT a AS k, udf(COUNT(b)) FROM testData GROUP BY k HAVING k > 1;
+
+-- Aggregate functions cannot be used in GROUP BY
+SELECT udf(COUNT(b)) AS k FROM testData GROUP BY k;
+
+-- Test data.
+CREATE OR REPLACE TEMPORARY VIEW testDataHasSameNameWithAlias AS SELECT * FROM VALUES
+(1, 1, 3), (1, 2, 1) AS testDataHasSameNameWithAlias(k, a, v);
+SELECT k AS a, udf(COUNT(udf(v))) FROM testDataHasSameNameWithAlias GROUP BY udf(a);
+
+-- turn off group by aliases
+set spark.sql.groupByAliases=false;
+
+-- Check analysis exceptions
+SELECT a AS k, udf(COUNT(udf(b))) FROM testData GROUP BY k;
+
+-- Aggregate with empty input and non-empty GroupBy expressions.
+SELECT udf(a), COUNT(udf(1)) FROM testData WHERE false GROUP BY udf(a);
+
+-- Aggregate with empty input and empty GroupBy expressions.
+SELECT udf(COUNT(1)) FROM testData WHERE false;
+SELECT 1 FROM (SELECT udf(COUNT(1)) FROM testData WHERE false) t;
+
+-- Aggregate with empty GroupBy expressions and filter on top
+SELECT 1 from (
+ SELECT 1 AS z,
+ udf(MIN(a.x))
+ FROM (select 1 as x) a
+ WHERE false
+) b
+where b.z != b.z;
+
+-- SPARK-24369 multiple distinct aggregations having the same argument set
+SELECT corr(DISTINCT x, y), udf(corr(DISTINCT y, x)), count(*)
+ FROM (VALUES (1, 1), (2, 2), (2, 2)) t(x, y);
+
+-- SPARK-25708 HAVING without GROUP BY means global aggregate
+SELECT udf(1) FROM range(10) HAVING true;
+
+SELECT udf(udf(1)) FROM range(10) HAVING MAX(id) > 0;
+
+SELECT udf(id) FROM range(10) HAVING id > 0;
+
+-- Test data
+CREATE OR REPLACE TEMPORARY VIEW test_agg AS SELECT * FROM VALUES
+ (1, true), (1, false),
+ (2, true),
+ (3, false), (3, null),
+ (4, null), (4, null),
+ (5, null), (5, true), (5, false) AS test_agg(k, v);
+
+-- empty table
+SELECT udf(every(v)), udf(some(v)), any(v) FROM test_agg WHERE 1 = 0;
+
+-- all null values
+SELECT udf(every(udf(v))), some(v), any(v) FROM test_agg WHERE k = 4;
+
+-- aggregates are null Filtering
+SELECT every(v), udf(some(v)), any(v) FROM test_agg WHERE k = 5;
+
+-- group by
+SELECT udf(k), every(v), udf(some(v)), any(v) FROM test_agg GROUP BY udf(k);
+
+-- having
+SELECT udf(k), every(v) FROM test_agg GROUP BY k HAVING every(v) = false;
+SELECT udf(k), udf(every(v)) FROM test_agg GROUP BY udf(k) HAVING every(v) IS NULL;
+
+-- basic subquery path to make sure rewrite happens in both parent and child plans.
+SELECT udf(k),
+ udf(Every(v)) AS every
+FROM test_agg
+WHERE k = 2
+ AND v IN (SELECT Any(v)
+ FROM test_agg
+ WHERE k = 1)
+GROUP BY udf(k);
+
+-- basic subquery path to make sure rewrite happens in both parent and child plans.
+SELECT udf(udf(k)),
+ Every(v) AS every
+FROM test_agg
+WHERE k = 2
+ AND v IN (SELECT Every(v)
+ FROM test_agg
+ WHERE k = 1)
+GROUP BY udf(udf(k));
+
+-- input type checking Int
+SELECT every(udf(1));
+
+-- input type checking Short
+SELECT some(udf(1S));
+
+-- input type checking Long
+SELECT any(udf(1L));
+
+-- input type checking String
+SELECT udf(every("true"));
+
+-- every/some/any aggregates are supported as windows expression.
+SELECT k, v, every(v) OVER (PARTITION BY k ORDER BY v) FROM test_agg;
+SELECT k, udf(udf(v)), some(v) OVER (PARTITION BY k ORDER BY v) FROM test_agg;
+SELECT udf(udf(k)), v, any(v) OVER (PARTITION BY k ORDER BY v) FROM test_agg;
+
+-- Having referencing aggregate expressions is ok.
+SELECT udf(count(*)) FROM test_agg HAVING count(*) > 1L;
+SELECT k, udf(max(v)) FROM test_agg GROUP BY k HAVING max(v) = true;
+
+-- Aggrgate expressions can be referenced through an alias
+SELECT * FROM (SELECT udf(COUNT(*)) AS cnt FROM test_agg) WHERE cnt > 1L;
+
+-- Error when aggregate expressions are in where clause directly
+SELECT udf(count(*)) FROM test_agg WHERE count(*) > 1L;
+SELECT udf(count(*)) FROM test_agg WHERE count(*) + 1L > 1L;
+SELECT udf(count(*)) FROM test_agg WHERE k = 1 or k = 2 or count(*) + 1L > 1L or max(k) > 1;
diff --git a/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/group-by-ordinal.sql.out b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/group-by-ordinal.sql.out
new file mode 100644
index 0000000000..b968b4e09f
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/group-by-ordinal.sql.out
@@ -0,0 +1,524 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+create temporary view data as select * from values
+ (1, 1),
+ (1, 2),
+ (2, 1),
+ (2, 2),
+ (3, 1),
+ (3, 2)
+ as data(a, b)
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+select a, sum(b) from data group by 1
+-- !query schema
+struct<a:int,sum(b):bigint>
+-- !query output
+1 3
+2 3
+3 3
+
+
+-- !query
+select 1, 2, sum(b) from data group by 1, 2
+-- !query schema
+struct<1:int,2:int,sum(b):bigint>
+-- !query output
+1 2 9
+
+
+-- !query
+select a, 1, sum(b) from data group by a, 1
+-- !query schema
+struct<a:int,1:int,sum(b):bigint>
+-- !query output
+1 1 3
+2 1 3
+3 1 3
+
+
+-- !query
+select a, 1, sum(b) from data group by 1, 2
+-- !query schema
+struct<a:int,1:int,sum(b):bigint>
+-- !query output
+1 1 3
+2 1 3
+3 1 3
+
+
+-- !query
+select a, b + 2, count(2) from data group by a, 2
+-- !query schema
+struct<a:int,(b + 2):int,count(2):bigint>
+-- !query output
+1 3 1
+1 4 1
+2 3 1
+2 4 1
+3 3 1
+3 4 1
+
+
+-- !query
+select a as aa, b + 2 as bb, count(2) from data group by 1, 2
+-- !query schema
+struct<aa:int,bb:int,count(2):bigint>
+-- !query output
+1 3 1
+1 4 1
+2 3 1
+2 4 1
+3 3 1
+3 4 1
+
+
+-- !query
+select sum(b) from data group by 1 + 0
+-- !query schema
+struct<sum(b):bigint>
+-- !query output
+9
+
+
+-- !query
+select a, b from data group by -1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "GROUP_BY_POS_OUT_OF_RANGE",
+ "sqlState" : "42805",
+ "messageParameters" : {
+ "index" : "-1",
+ "size" : "2"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 32,
+ "stopIndex" : 33,
+ "fragment" : "-1"
+ } ]
+}
+
+
+-- !query
+select a, b from data group by 0
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "GROUP_BY_POS_OUT_OF_RANGE",
+ "sqlState" : "42805",
+ "messageParameters" : {
+ "index" : "0",
+ "size" : "2"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 32,
+ "stopIndex" : 32,
+ "fragment" : "0"
+ } ]
+}
+
+
+-- !query
+select a, b from data group by 3
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "GROUP_BY_POS_OUT_OF_RANGE",
+ "sqlState" : "42805",
+ "messageParameters" : {
+ "index" : "3",
+ "size" : "2"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 32,
+ "stopIndex" : 32,
+ "fragment" : "3"
+ } ]
+}
+
+
+-- !query
+select a, b, sum(b) from data group by 3
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "GROUP_BY_POS_AGGREGATE",
+ "sqlState" : "42903",
+ "messageParameters" : {
+ "aggExpr" : "sum(data.b) AS `sum(b)`",
+ "index" : "3"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 40,
+ "stopIndex" : 40,
+ "fragment" : "3"
+ } ]
+}
+
+
+-- !query
+select a, b, sum(b) + 2 from data group by 3
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "GROUP_BY_POS_AGGREGATE",
+ "sqlState" : "42903",
+ "messageParameters" : {
+ "aggExpr" : "(sum(data.b) + CAST(2 AS BIGINT)) AS `(sum(b) + 2)`",
+ "index" : "3"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 44,
+ "stopIndex" : 44,
+ "fragment" : "3"
+ } ]
+}
+
+
+-- !query
+select a, rand(0), sum(b)
+from
+(select /*+ REPARTITION(1) */ a, b from data) group by a, 2
+-- !query schema
+struct<a:int,rand(0):double,sum(b):bigint>
+-- !query output
+1 0.5488135024422883 1
+1 0.7151893651681639 2
+2 0.5448831775801376 2
+2 0.6027633705776989 1
+3 0.4236547969336536 1
+3 0.6458941151817286 2
+
+
+-- !query
+select * from data group by a, b, 1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "STAR_GROUP_BY_POS",
+ "sqlState" : "0A000"
+}
+
+
+-- !query
+select a, count(a) from (select 1 as a) tmp group by 1 order by 1
+-- !query schema
+struct<a:int,count(a):bigint>
+-- !query output
+1 1
+
+
+-- !query
+select count(a), a from (select 1 as a) tmp group by 2 having a > 0
+-- !query schema
+struct<count(a):bigint,a:int>
+-- !query output
+1 1
+
+
+-- !query
+select a, a AS k, count(b) from data group by k, 1
+-- !query schema
+struct<a:int,k:int,count(b):bigint>
+-- !query output
+1 1 2
+2 2 2
+3 3 2
+
+
+-- !query
+select a, b, count(1) from data group by cube(1, 2)
+-- !query schema
+struct<a:int,b:int,count(1):bigint>
+-- !query output
+1 1 1
+1 2 1
+1 NULL 2
+2 1 1
+2 2 1
+2 NULL 2
+3 1 1
+3 2 1
+3 NULL 2
+NULL 1 3
+NULL 2 3
+NULL NULL 6
+
+
+-- !query
+select a, b, count(1) from data group by cube(1, b)
+-- !query schema
+struct<a:int,b:int,count(1):bigint>
+-- !query output
+1 1 1
+1 2 1
+1 NULL 2
+2 1 1
+2 2 1
+2 NULL 2
+3 1 1
+3 2 1
+3 NULL 2
+NULL 1 3
+NULL 2 3
+NULL NULL 6
+
+
+-- !query
+select a, b, count(1) from data group by 1, 2 with cube
+-- !query schema
+struct<a:int,b:int,count(1):bigint>
+-- !query output
+1 1 1
+1 2 1
+1 NULL 2
+2 1 1
+2 2 1
+2 NULL 2
+3 1 1
+3 2 1
+3 NULL 2
+NULL 1 3
+NULL 2 3
+NULL NULL 6
+
+
+-- !query
+select a, b, count(1) from data group by rollup(1, 2)
+-- !query schema
+struct<a:int,b:int,count(1):bigint>
+-- !query output
+1 1 1
+1 2 1
+1 NULL 2
+2 1 1
+2 2 1
+2 NULL 2
+3 1 1
+3 2 1
+3 NULL 2
+NULL NULL 6
+
+
+-- !query
+select a, b, count(1) from data group by rollup(1, b)
+-- !query schema
+struct<a:int,b:int,count(1):bigint>
+-- !query output
+1 1 1
+1 2 1
+1 NULL 2
+2 1 1
+2 2 1
+2 NULL 2
+3 1 1
+3 2 1
+3 NULL 2
+NULL NULL 6
+
+
+-- !query
+select a, b, count(1) from data group by 1, 2 with rollup
+-- !query schema
+struct<a:int,b:int,count(1):bigint>
+-- !query output
+1 1 1
+1 2 1
+1 NULL 2
+2 1 1
+2 2 1
+2 NULL 2
+3 1 1
+3 2 1
+3 NULL 2
+NULL NULL 6
+
+
+-- !query
+select a, b, count(1) from data group by grouping sets((1), (2), (1, 2))
+-- !query schema
+struct<a:int,b:int,count(1):bigint>
+-- !query output
+1 1 1
+1 2 1
+1 NULL 2
+2 1 1
+2 2 1
+2 NULL 2
+3 1 1
+3 2 1
+3 NULL 2
+NULL 1 3
+NULL 2 3
+
+
+-- !query
+select a, b, count(1) from data group by grouping sets((1), (b), (a, 2))
+-- !query schema
+struct<a:int,b:int,count(1):bigint>
+-- !query output
+1 1 1
+1 2 1
+1 NULL 2
+2 1 1
+2 2 1
+2 NULL 2
+3 1 1
+3 2 1
+3 NULL 2
+NULL 1 3
+NULL 2 3
+
+
+-- !query
+select a, b, count(1) from data group by a, 2 grouping sets((1), (b), (a, 2))
+-- !query schema
+struct<a:int,b:int,count(1):bigint>
+-- !query output
+1 1 1
+1 2 1
+1 NULL 2
+2 1 1
+2 2 1
+2 NULL 2
+3 1 1
+3 2 1
+3 NULL 2
+NULL 1 3
+NULL 2 3
+
+
+-- !query
+select a, b, count(1) from data group by a, -1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "GROUP_BY_POS_OUT_OF_RANGE",
+ "sqlState" : "42805",
+ "messageParameters" : {
+ "index" : "-1",
+ "size" : "3"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 45,
+ "stopIndex" : 46,
+ "fragment" : "-1"
+ } ]
+}
+
+
+-- !query
+select a, b, count(1) from data group by a, 3
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "GROUP_BY_POS_AGGREGATE",
+ "sqlState" : "42903",
+ "messageParameters" : {
+ "aggExpr" : "count(1) AS `count(1)`",
+ "index" : "3"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 45,
+ "stopIndex" : 45,
+ "fragment" : "3"
+ } ]
+}
+
+
+-- !query
+select a, b, count(1) from data group by cube(-1, 2)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "GROUP_BY_POS_OUT_OF_RANGE",
+ "sqlState" : "42805",
+ "messageParameters" : {
+ "index" : "-1",
+ "size" : "3"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 47,
+ "stopIndex" : 48,
+ "fragment" : "-1"
+ } ]
+}
+
+
+-- !query
+select a, b, count(1) from data group by cube(1, 3)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "GROUP_BY_POS_AGGREGATE",
+ "sqlState" : "42903",
+ "messageParameters" : {
+ "aggExpr" : "count(1) AS `count(1)`",
+ "index" : "3"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 50,
+ "stopIndex" : 50,
+ "fragment" : "3"
+ } ]
+}
+
+
+-- !query
+set spark.sql.groupByOrdinal=false
+-- !query schema
+struct<key:string,value:string>
+-- !query output
+spark.sql.groupByOrdinal false
+
+
+-- !query
+select sum(b) from data group by -1
+-- !query schema
+struct<sum(b):bigint>
+-- !query output
+9
diff --git a/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/group-by.sql.out b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/group-by.sql.out
new file mode 100644
index 0000000000..a4a3f76fa6
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/group-by.sql.out
@@ -0,0 +1,1123 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW testData AS SELECT * FROM VALUES
+(1, 1), (1, 2), (2, 1), (2, 2), (3, 1), (3, 2), (null, 1), (3, null), (null, null)
+AS testData(a, b)
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT a, COUNT(b) FROM testData
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "MISSING_GROUP_BY",
+ "sqlState" : "42803",
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 1,
+ "stopIndex" : 32,
+ "fragment" : "SELECT a, COUNT(b) FROM testData"
+ } ]
+}
+
+
+-- !query
+SELECT COUNT(a), COUNT(b) FROM testData
+-- !query schema
+struct<count(a):bigint,count(b):bigint>
+-- !query output
+7 7
+
+
+-- !query
+SELECT a, COUNT(b) FROM testData GROUP BY a
+-- !query schema
+struct<a:int,count(b):bigint>
+-- !query output
+1 2
+2 2
+3 2
+NULL 1
+
+
+-- !query
+SELECT a, COUNT(b) FROM testData GROUP BY b
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "MISSING_AGGREGATION",
+ "sqlState" : "42803",
+ "messageParameters" : {
+ "expression" : "\"a\"",
+ "expressionAnyValue" : "\"any_value(a)\""
+ }
+}
+
+
+-- !query
+SELECT COUNT(a), COUNT(b) FROM testData GROUP BY a
+-- !query schema
+struct<count(a):bigint,count(b):bigint>
+-- !query output
+0 1
+2 2
+2 2
+3 2
+
+
+-- !query
+SELECT 'foo', COUNT(a) FROM testData GROUP BY 1
+-- !query schema
+struct<foo:string,count(a):bigint>
+-- !query output
+foo 7
+
+
+-- !query
+SELECT 'foo' FROM testData WHERE a = 0 GROUP BY 1
+-- !query schema
+struct<foo:string>
+-- !query output
+
+
+
+-- !query
+SELECT 'foo', APPROX_COUNT_DISTINCT(a) FROM testData WHERE a = 0 GROUP BY 1
+-- !query schema
+struct<foo:string,approx_count_distinct(a):bigint>
+-- !query output
+
+
+
+-- !query
+SELECT 'foo', MAX(STRUCT(a)) FROM testData WHERE a = 0 GROUP BY 1
+-- !query schema
+struct<foo:string,max(struct(a)):struct<a:int>>
+-- !query output
+
+
+
+-- !query
+SELECT a + b, COUNT(b) FROM testData GROUP BY a + b
+-- !query schema
+struct<(a + b):int,count(b):bigint>
+-- !query output
+2 1
+3 2
+4 2
+5 1
+NULL 1
+
+
+-- !query
+SELECT a + 2, COUNT(b) FROM testData GROUP BY a + 1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "MISSING_AGGREGATION",
+ "sqlState" : "42803",
+ "messageParameters" : {
+ "expression" : "\"a\"",
+ "expressionAnyValue" : "\"any_value(a)\""
+ }
+}
+
+
+-- !query
+SELECT a + 1 + 1, COUNT(b) FROM testData GROUP BY a + 1
+-- !query schema
+struct<((a + 1) + 1):int,count(b):bigint>
+-- !query output
+3 2
+4 2
+5 2
+NULL 1
+
+
+-- !query
+SELECT count(1) FROM testData GROUP BY struct(a + 0.1 AS aa)
+-- !query schema
+struct<count(1):bigint>
+-- !query output
+2
+2
+2
+3
+
+
+-- !query
+SELECT SKEWNESS(a), KURTOSIS(a), MIN(a), MAX(a), AVG(a), VARIANCE(a), STDDEV(a), SUM(a), COUNT(a)
+FROM testData
+-- !query schema
+struct<skewness(a):double,kurtosis(a):double,min(a):int,max(a):int,avg(a):double,variance(a):double,stddev(a):double,sum(a):bigint,count(a):bigint>
+-- !query output
+-0.27238010581457284 -1.5069204152249138 1 3 2.142857142857143 0.8095238095238096 0.8997354108424375 15 7
+
+
+-- !query
+SELECT COUNT(DISTINCT b), COUNT(DISTINCT b, c) FROM (SELECT 1 AS a, 2 AS b, 3 AS c) GROUP BY a
+-- !query schema
+struct<count(DISTINCT b):bigint,count(DISTINCT b, c):bigint>
+-- !query output
+1 1
+
+
+-- !query
+SELECT a AS k, COUNT(b) FROM testData GROUP BY k
+-- !query schema
+struct<k:int,count(b):bigint>
+-- !query output
+1 2
+2 2
+3 2
+NULL 1
+
+
+-- !query
+SELECT a AS k, COUNT(b) FROM testData GROUP BY k HAVING k > 1
+-- !query schema
+struct<k:int,count(b):bigint>
+-- !query output
+2 2
+3 2
+
+
+-- !query
+SELECT a AS k, COUNT(non_existing) FROM testData GROUP BY k
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "UNRESOLVED_COLUMN.WITH_SUGGESTION",
+ "sqlState" : "42703",
+ "messageParameters" : {
+ "objectName" : "`non_existing`",
+ "proposal" : "`testdata`.`a`, `testdata`.`b`"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 22,
+ "stopIndex" : 33,
+ "fragment" : "non_existing"
+ } ]
+}
+
+
+-- !query
+SELECT COUNT(b) AS k FROM testData GROUP BY k
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "GROUP_BY_AGGREGATE",
+ "sqlState" : "42903",
+ "messageParameters" : {
+ "sqlExpr" : "count(testdata.b)"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 8,
+ "stopIndex" : 15,
+ "fragment" : "COUNT(b)"
+ } ]
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW testDataHasSameNameWithAlias AS SELECT * FROM VALUES
+(1, 1, 3), (1, 2, 1) AS testDataHasSameNameWithAlias(k, a, v)
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT k AS a, COUNT(v) FROM testDataHasSameNameWithAlias GROUP BY a
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "MISSING_AGGREGATION",
+ "sqlState" : "42803",
+ "messageParameters" : {
+ "expression" : "\"k\"",
+ "expressionAnyValue" : "\"any_value(k)\""
+ }
+}
+
+
+-- !query
+set spark.sql.groupByAliases=false
+-- !query schema
+struct<key:string,value:string>
+-- !query output
+spark.sql.groupByAliases false
+
+
+-- !query
+SELECT a AS k, COUNT(b) FROM testData GROUP BY k
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "UNRESOLVED_COLUMN.WITH_SUGGESTION",
+ "sqlState" : "42703",
+ "messageParameters" : {
+ "objectName" : "`k`",
+ "proposal" : "`testdata`.`a`, `testdata`.`b`"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 48,
+ "stopIndex" : 48,
+ "fragment" : "k"
+ } ]
+}
+
+
+-- !query
+SELECT a, COUNT(1) FROM testData WHERE false GROUP BY a
+-- !query schema
+struct<a:int,count(1):bigint>
+-- !query output
+
+
+
+-- !query
+SELECT COUNT(1) FROM testData WHERE false
+-- !query schema
+struct<count(1):bigint>
+-- !query output
+0
+
+
+-- !query
+SELECT 1 FROM (SELECT COUNT(1) FROM testData WHERE false) t
+-- !query schema
+struct<1:int>
+-- !query output
+1
+
+
+-- !query
+SELECT 1 from (
+ SELECT 1 AS z,
+ MIN(a.x)
+ FROM (select 1 as x) a
+ WHERE false
+) b
+where b.z != b.z
+-- !query schema
+struct<1:int>
+-- !query output
+
+
+
+-- !query
+SELECT corr(DISTINCT x, y), corr(DISTINCT y, x), count(*)
+ FROM (VALUES (1, 1), (2, 2), (2, 2)) t(x, y)
+-- !query schema
+struct<corr(DISTINCT x, y):double,corr(DISTINCT y, x):double,count(1):bigint>
+-- !query output
+0.9999999999999999 0.9999999999999999 3
+
+
+-- !query
+SELECT 1 FROM range(10) HAVING true
+-- !query schema
+struct<1:int>
+-- !query output
+1
+
+
+-- !query
+SELECT 1 FROM range(10) HAVING MAX(id) > 0
+-- !query schema
+struct<1:int>
+-- !query output
+1
+
+
+-- !query
+SELECT id FROM range(10) HAVING id > 0
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "MISSING_GROUP_BY",
+ "sqlState" : "42803",
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 1,
+ "stopIndex" : 38,
+ "fragment" : "SELECT id FROM range(10) HAVING id > 0"
+ } ]
+}
+
+
+-- !query
+SET spark.sql.legacy.parser.havingWithoutGroupByAsWhere=true
+-- !query schema
+struct<key:string,value:string>
+-- !query output
+spark.sql.legacy.parser.havingWithoutGroupByAsWhere true
+
+
+-- !query
+SELECT 1 FROM range(10) HAVING true
+-- !query schema
+struct<1:int>
+-- !query output
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+
+
+-- !query
+SELECT 1 FROM range(10) HAVING MAX(id) > 0
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "INVALID_WHERE_CONDITION",
+ "sqlState" : "42903",
+ "messageParameters" : {
+ "condition" : "\"(max(id) > 0)\"",
+ "expressionList" : "max(id)"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 1,
+ "stopIndex" : 42,
+ "fragment" : "SELECT 1 FROM range(10) HAVING MAX(id) > 0"
+ } ]
+}
+
+
+-- !query
+SELECT id FROM range(10) HAVING id > 0
+-- !query schema
+struct<id:bigint>
+-- !query output
+1
+2
+3
+4
+5
+6
+7
+8
+9
+
+
+-- !query
+SET spark.sql.legacy.parser.havingWithoutGroupByAsWhere=false
+-- !query schema
+struct<key:string,value:string>
+-- !query output
+spark.sql.legacy.parser.havingWithoutGroupByAsWhere false
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW test_agg AS SELECT * FROM VALUES
+ (1, true), (1, false),
+ (2, true),
+ (3, false), (3, null),
+ (4, null), (4, null),
+ (5, null), (5, true), (5, false) AS test_agg(k, v)
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT every(v), some(v), any(v), bool_and(v), bool_or(v) FROM test_agg WHERE 1 = 0
+-- !query schema
+struct<every(v):boolean,some(v):boolean,any(v):boolean,bool_and(v):boolean,bool_or(v):boolean>
+-- !query output
+NULL NULL NULL NULL NULL
+
+
+-- !query
+SELECT every(v), some(v), any(v), bool_and(v), bool_or(v) FROM test_agg WHERE k = 4
+-- !query schema
+struct<every(v):boolean,some(v):boolean,any(v):boolean,bool_and(v):boolean,bool_or(v):boolean>
+-- !query output
+NULL NULL NULL NULL NULL
+
+
+-- !query
+SELECT every(v), some(v), any(v), bool_and(v), bool_or(v) FROM test_agg WHERE k = 5
+-- !query schema
+struct<every(v):boolean,some(v):boolean,any(v):boolean,bool_and(v):boolean,bool_or(v):boolean>
+-- !query output
+false true true false true
+
+
+-- !query
+SELECT k, every(v), some(v), any(v), bool_and(v), bool_or(v) FROM test_agg GROUP BY k
+-- !query schema
+struct<k:int,every(v):boolean,some(v):boolean,any(v):boolean,bool_and(v):boolean,bool_or(v):boolean>
+-- !query output
+1 false true true false true
+2 true true true true true
+3 false false false false false
+4 NULL NULL NULL NULL NULL
+5 false true true false true
+
+
+-- !query
+SELECT k, every(v) FROM test_agg GROUP BY k HAVING every(v) = false
+-- !query schema
+struct<k:int,every(v):boolean>
+-- !query output
+1 false
+3 false
+5 false
+
+
+-- !query
+SELECT k, every(v) FROM test_agg GROUP BY k HAVING every(v) IS NULL
+-- !query schema
+struct<k:int,every(v):boolean>
+-- !query output
+4 NULL
+
+
+-- !query
+SELECT k,
+ Every(v) AS every
+FROM test_agg
+WHERE k = 2
+ AND v IN (SELECT Any(v)
+ FROM test_agg
+ WHERE k = 1)
+GROUP BY k
+-- !query schema
+struct<k:int,every:boolean>
+-- !query output
+2 true
+
+
+-- !query
+SELECT k,
+ Every(v) AS every
+FROM test_agg
+WHERE k = 2
+ AND v IN (SELECT Every(v)
+ FROM test_agg
+ WHERE k = 1)
+GROUP BY k
+-- !query schema
+struct<k:int,every:boolean>
+-- !query output
+
+
+
+-- !query
+SELECT every(1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "inputSql" : "\"1\"",
+ "inputType" : "\"INT\"",
+ "paramIndex" : "1",
+ "requiredType" : "\"BOOLEAN\"",
+ "sqlExpr" : "\"every(1)\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 8,
+ "stopIndex" : 15,
+ "fragment" : "every(1)"
+ } ]
+}
+
+
+-- !query
+SELECT some(1S)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "inputSql" : "\"1\"",
+ "inputType" : "\"SMALLINT\"",
+ "paramIndex" : "1",
+ "requiredType" : "\"BOOLEAN\"",
+ "sqlExpr" : "\"some(1)\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 8,
+ "stopIndex" : 15,
+ "fragment" : "some(1S)"
+ } ]
+}
+
+
+-- !query
+SELECT any(1L)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "inputSql" : "\"1\"",
+ "inputType" : "\"BIGINT\"",
+ "paramIndex" : "1",
+ "requiredType" : "\"BOOLEAN\"",
+ "sqlExpr" : "\"any(1)\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 8,
+ "stopIndex" : 14,
+ "fragment" : "any(1L)"
+ } ]
+}
+
+
+-- !query
+SELECT every("true")
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "inputSql" : "\"true\"",
+ "inputType" : "\"STRING\"",
+ "paramIndex" : "1",
+ "requiredType" : "\"BOOLEAN\"",
+ "sqlExpr" : "\"every(true)\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 8,
+ "stopIndex" : 20,
+ "fragment" : "every(\"true\")"
+ } ]
+}
+
+
+-- !query
+SELECT bool_and(1.0)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "inputSql" : "\"1.0\"",
+ "inputType" : "\"DECIMAL(2,1)\"",
+ "paramIndex" : "1",
+ "requiredType" : "\"BOOLEAN\"",
+ "sqlExpr" : "\"bool_and(1.0)\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 8,
+ "stopIndex" : 20,
+ "fragment" : "bool_and(1.0)"
+ } ]
+}
+
+
+-- !query
+SELECT bool_or(1.0D)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "inputSql" : "\"1.0\"",
+ "inputType" : "\"DOUBLE\"",
+ "paramIndex" : "1",
+ "requiredType" : "\"BOOLEAN\"",
+ "sqlExpr" : "\"bool_or(1.0)\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 8,
+ "stopIndex" : 20,
+ "fragment" : "bool_or(1.0D)"
+ } ]
+}
+
+
+-- !query
+SELECT k, v, every(v) OVER (PARTITION BY k ORDER BY v) FROM test_agg
+-- !query schema
+struct<k:int,v:boolean,every(v) OVER (PARTITION BY k ORDER BY v ASC NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW):boolean>
+-- !query output
+1 false false
+1 true false
+2 true true
+3 NULL NULL
+3 false false
+4 NULL NULL
+4 NULL NULL
+5 NULL NULL
+5 false false
+5 true false
+
+
+-- !query
+SELECT k, v, some(v) OVER (PARTITION BY k ORDER BY v) FROM test_agg
+-- !query schema
+struct<k:int,v:boolean,some(v) OVER (PARTITION BY k ORDER BY v ASC NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW):boolean>
+-- !query output
+1 false false
+1 true true
+2 true true
+3 NULL NULL
+3 false false
+4 NULL NULL
+4 NULL NULL
+5 NULL NULL
+5 false false
+5 true true
+
+
+-- !query
+SELECT k, v, any(v) OVER (PARTITION BY k ORDER BY v) FROM test_agg
+-- !query schema
+struct<k:int,v:boolean,any(v) OVER (PARTITION BY k ORDER BY v ASC NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW):boolean>
+-- !query output
+1 false false
+1 true true
+2 true true
+3 NULL NULL
+3 false false
+4 NULL NULL
+4 NULL NULL
+5 NULL NULL
+5 false false
+5 true true
+
+
+-- !query
+SELECT k, v, bool_and(v) OVER (PARTITION BY k ORDER BY v) FROM test_agg
+-- !query schema
+struct<k:int,v:boolean,bool_and(v) OVER (PARTITION BY k ORDER BY v ASC NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW):boolean>
+-- !query output
+1 false false
+1 true false
+2 true true
+3 NULL NULL
+3 false false
+4 NULL NULL
+4 NULL NULL
+5 NULL NULL
+5 false false
+5 true false
+
+
+-- !query
+SELECT k, v, bool_or(v) OVER (PARTITION BY k ORDER BY v) FROM test_agg
+-- !query schema
+struct<k:int,v:boolean,bool_or(v) OVER (PARTITION BY k ORDER BY v ASC NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW):boolean>
+-- !query output
+1 false false
+1 true true
+2 true true
+3 NULL NULL
+3 false false
+4 NULL NULL
+4 NULL NULL
+5 NULL NULL
+5 false false
+5 true true
+
+
+-- !query
+SELECT count(*) FROM test_agg HAVING count(*) > 1L
+-- !query schema
+struct<count(1):bigint>
+-- !query output
+10
+
+
+-- !query
+SELECT k, max(v) FROM test_agg GROUP BY k HAVING max(v) = true
+-- !query schema
+struct<k:int,max(v):boolean>
+-- !query output
+1 true
+2 true
+5 true
+
+
+-- !query
+SELECT * FROM (SELECT COUNT(*) AS cnt FROM test_agg) WHERE cnt > 1L
+-- !query schema
+struct<cnt:bigint>
+-- !query output
+10
+
+
+-- !query
+SELECT count(*) FROM test_agg WHERE count(*) > 1L
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "INVALID_WHERE_CONDITION",
+ "sqlState" : "42903",
+ "messageParameters" : {
+ "condition" : "\"(count(1) > 1)\"",
+ "expressionList" : "count(1)"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 1,
+ "stopIndex" : 49,
+ "fragment" : "SELECT count(*) FROM test_agg WHERE count(*) > 1L"
+ } ]
+}
+
+
+-- !query
+SELECT count(*) FROM test_agg WHERE count(*) + 1L > 1L
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "INVALID_WHERE_CONDITION",
+ "sqlState" : "42903",
+ "messageParameters" : {
+ "condition" : "\"((count(1) + 1) > 1)\"",
+ "expressionList" : "count(1)"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 1,
+ "stopIndex" : 54,
+ "fragment" : "SELECT count(*) FROM test_agg WHERE count(*) + 1L > 1L"
+ } ]
+}
+
+
+-- !query
+SELECT count(*) FROM test_agg WHERE k = 1 or k = 2 or count(*) + 1L > 1L or max(k) > 1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "INVALID_WHERE_CONDITION",
+ "sqlState" : "42903",
+ "messageParameters" : {
+ "condition" : "\"(((k = 1) OR (k = 2)) OR (((count(1) + 1) > 1) OR (max(k) > 1)))\"",
+ "expressionList" : "count(1), max(test_agg.k)"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 1,
+ "stopIndex" : 86,
+ "fragment" : "SELECT count(*) FROM test_agg WHERE k = 1 or k = 2 or count(*) + 1L > 1L or max(k) > 1"
+ } ]
+}
+
+
+-- !query
+SELECT AVG(DISTINCT decimal_col), SUM(DISTINCT decimal_col) FROM VALUES (CAST(1 AS DECIMAL(9, 0))) t(decimal_col)
+-- !query schema
+struct<avg(DISTINCT decimal_col):decimal(13,4),sum(DISTINCT decimal_col):decimal(19,0)>
+-- !query output
+1.0000 1
+
+
+-- !query
+SELECT not(a IS NULL), count(*) AS c
+FROM testData
+GROUP BY a IS NULL
+-- !query schema
+struct<(NOT (a IS NULL)):boolean,c:bigint>
+-- !query output
+false 2
+true 7
+
+
+-- !query
+SELECT if(not(a IS NULL), rand(0), 1), count(*) AS c
+FROM testData
+GROUP BY a IS NULL
+-- !query schema
+struct<(IF((NOT (a IS NULL)), rand(0), 1)):double,c:bigint>
+-- !query output
+0.5488135024422883 7
+1.0 2
+
+
+-- !query
+SELECT
+ histogram_numeric(col, 2) as histogram_2,
+ histogram_numeric(col, 3) as histogram_3,
+ histogram_numeric(col, 5) as histogram_5,
+ histogram_numeric(col, 10) as histogram_10
+FROM VALUES
+ (1), (2), (3), (4), (5), (6), (7), (8), (9), (10),
+ (11), (12), (13), (14), (15), (16), (17), (18), (19), (20),
+ (21), (22), (23), (24), (25), (26), (27), (28), (29), (30),
+ (31), (32), (33), (34), (35), (3), (37), (38), (39), (40),
+ (41), (42), (43), (44), (45), (46), (47), (48), (49), (50) AS tab(col)
+-- !query schema
+struct<histogram_2:array<struct<x:int,y:double>>,histogram_3:array<struct<x:int,y:double>>,histogram_5:array<struct<x:int,y:double>>,histogram_10:array<struct<x:int,y:double>>>
+-- !query output
+[{"x":12,"y":26.0},{"x":38,"y":24.0}] [{"x":9,"y":20.0},{"x":25,"y":11.0},{"x":40,"y":19.0}] [{"x":5,"y":11.0},{"x":14,"y":8.0},{"x":22,"y":7.0},{"x":30,"y":10.0},{"x":43,"y":14.0}] [{"x":3,"y":6.0},{"x":8,"y":6.0},{"x":13,"y":4.0},{"x":17,"y":3.0},{"x":20,"y":4.0},{"x":25,"y":6.0},{"x":31,"y":7.0},{"x":39,"y":5.0},{"x":43,"y":4.0},{"x":48,"y":5.0}]
+
+
+-- !query
+SELECT histogram_numeric(col, 3) FROM VALUES (1), (2), (3) AS tab(col)
+-- !query schema
+struct<histogram_numeric(col, 3):array<struct<x:int,y:double>>>
+-- !query output
+[{"x":1,"y":1.0},{"x":2,"y":1.0},{"x":3,"y":1.0}]
+
+
+-- !query
+SELECT histogram_numeric(col, 3) FROM VALUES (1L), (2L), (3L) AS tab(col)
+-- !query schema
+struct<histogram_numeric(col, 3):array<struct<x:bigint,y:double>>>
+-- !query output
+[{"x":1,"y":1.0},{"x":2,"y":1.0},{"x":3,"y":1.0}]
+
+
+-- !query
+SELECT histogram_numeric(col, 3) FROM VALUES (1F), (2F), (3F) AS tab(col)
+-- !query schema
+struct<histogram_numeric(col, 3):array<struct<x:float,y:double>>>
+-- !query output
+[{"x":1.0,"y":1.0},{"x":2.0,"y":1.0},{"x":3.0,"y":1.0}]
+
+
+-- !query
+SELECT histogram_numeric(col, 3) FROM VALUES (1D), (2D), (3D) AS tab(col)
+-- !query schema
+struct<histogram_numeric(col, 3):array<struct<x:double,y:double>>>
+-- !query output
+[{"x":1.0,"y":1.0},{"x":2.0,"y":1.0},{"x":3.0,"y":1.0}]
+
+
+-- !query
+SELECT histogram_numeric(col, 3) FROM VALUES (1S), (2S), (3S) AS tab(col)
+-- !query schema
+struct<histogram_numeric(col, 3):array<struct<x:smallint,y:double>>>
+-- !query output
+[{"x":1,"y":1.0},{"x":2,"y":1.0},{"x":3,"y":1.0}]
+
+
+-- !query
+SELECT histogram_numeric(col, 3) FROM VALUES
+ (CAST(1 AS BYTE)), (CAST(2 AS BYTE)), (CAST(3 AS BYTE)) AS tab(col)
+-- !query schema
+struct<histogram_numeric(col, 3):array<struct<x:tinyint,y:double>>>
+-- !query output
+[{"x":1,"y":1.0},{"x":2,"y":1.0},{"x":3,"y":1.0}]
+
+
+-- !query
+SELECT histogram_numeric(col, 3) FROM VALUES
+ (CAST(1 AS TINYINT)), (CAST(2 AS TINYINT)), (CAST(3 AS TINYINT)) AS tab(col)
+-- !query schema
+struct<histogram_numeric(col, 3):array<struct<x:tinyint,y:double>>>
+-- !query output
+[{"x":1,"y":1.0},{"x":2,"y":1.0},{"x":3,"y":1.0}]
+
+
+-- !query
+SELECT histogram_numeric(col, 3) FROM VALUES
+ (CAST(1 AS SMALLINT)), (CAST(2 AS SMALLINT)), (CAST(3 AS SMALLINT)) AS tab(col)
+-- !query schema
+struct<histogram_numeric(col, 3):array<struct<x:smallint,y:double>>>
+-- !query output
+[{"x":1,"y":1.0},{"x":2,"y":1.0},{"x":3,"y":1.0}]
+
+
+-- !query
+SELECT histogram_numeric(col, 3) FROM VALUES
+ (CAST(1 AS BIGINT)), (CAST(2 AS BIGINT)), (CAST(3 AS BIGINT)) AS tab(col)
+-- !query schema
+struct<histogram_numeric(col, 3):array<struct<x:bigint,y:double>>>
+-- !query output
+[{"x":1,"y":1.0},{"x":2,"y":1.0},{"x":3,"y":1.0}]
+
+
+-- !query
+SELECT histogram_numeric(col, 3) FROM VALUES (TIMESTAMP '2017-03-01 00:00:00'),
+ (TIMESTAMP '2017-04-01 00:00:00'), (TIMESTAMP '2017-05-01 00:00:00') AS tab(col)
+-- !query schema
+struct<histogram_numeric(col, 3):array<struct<x:timestamp,y:double>>>
+-- !query output
+[{"x":2017-03-01 00:00:00,"y":1.0},{"x":2017-04-01 00:00:00,"y":1.0},{"x":2017-05-01 00:00:00,"y":1.0}]
+
+
+-- !query
+SELECT histogram_numeric(col, 3) FROM VALUES (INTERVAL '100-00' YEAR TO MONTH),
+ (INTERVAL '110-00' YEAR TO MONTH), (INTERVAL '120-00' YEAR TO MONTH) AS tab(col)
+-- !query schema
+struct<histogram_numeric(col, 3):array<struct<x:interval year to month,y:double>>>
+-- !query output
+[{"x":100-0,"y":1.0},{"x":110-0,"y":1.0},{"x":120-0,"y":1.0}]
+
+
+-- !query
+SELECT histogram_numeric(col, 3) FROM VALUES (INTERVAL '12 20:4:0' DAY TO SECOND),
+ (INTERVAL '12 21:4:0' DAY TO SECOND), (INTERVAL '12 22:4:0' DAY TO SECOND) AS tab(col)
+-- !query schema
+struct<histogram_numeric(col, 3):array<struct<x:interval day to second,y:double>>>
+-- !query output
+[{"x":12 20:04:00.000000000,"y":1.0},{"x":12 21:04:00.000000000,"y":1.0},{"x":12 22:04:00.000000000,"y":1.0}]
+
+
+-- !query
+SELECT histogram_numeric(col, 3)
+FROM VALUES (NULL), (NULL), (NULL) AS tab(col)
+-- !query schema
+struct<histogram_numeric(col, 3):array<struct<x:double,y:double>>>
+-- !query output
+NULL
+
+
+-- !query
+SELECT histogram_numeric(col, 3)
+FROM VALUES (CAST(NULL AS DOUBLE)), (CAST(NULL AS DOUBLE)), (CAST(NULL AS DOUBLE)) AS tab(col)
+-- !query schema
+struct<histogram_numeric(col, 3):array<struct<x:double,y:double>>>
+-- !query output
+NULL
+
+
+-- !query
+SELECT histogram_numeric(col, 3)
+FROM VALUES (CAST(NULL AS INT)), (CAST(NULL AS INT)), (CAST(NULL AS INT)) AS tab(col)
+-- !query schema
+struct<histogram_numeric(col, 3):array<struct<x:int,y:double>>>
+-- !query output
+NULL
+
+
+-- !query
+SELECT
+ collect_list(col),
+ array_agg(col)
+FROM VALUES
+ (1), (2), (1) AS tab(col)
+-- !query schema
+struct<collect_list(col):array<int>,collect_list(col):array<int>>
+-- !query output
+[1,2,1] [1,2,1]
+
+
+-- !query
+SELECT
+ a,
+ collect_list(b),
+ array_agg(b)
+FROM VALUES
+ (1,4),(2,3),(1,4),(2,4) AS v(a,b)
+GROUP BY a
+-- !query schema
+struct<a:int,collect_list(b):array<int>,collect_list(b):array<int>>
+-- !query output
+1 [4,4] [4,4]
+2 [3,4] [3,4]
+
+
+-- !query
+SELECT mode(a), mode(b) FROM testData
+-- !query schema
+struct<mode(a):int,mode(b):int>
+-- !query output
+3 1
+
+
+-- !query
+SELECT a, mode(b) FROM testData GROUP BY a ORDER BY a
+-- !query schema
+struct<a:int,mode(b):int>
+-- !query output
+NULL 1
+1 1
+2 1
+3 1
+
+
+-- !query
+SELECT c * 2 AS d
+FROM (
+ SELECT if(b > 1, 1, b) AS c
+ FROM (
+ SELECT if(a < 0, 0, a) AS b
+ FROM VALUES (-1), (1), (2) AS t1(a)
+ ) t2
+ GROUP BY b
+ ) t3
+GROUP BY c
+-- !query schema
+struct<d:int>
+-- !query output
+0
+2
diff --git a/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/linear-regression.sql.out b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/linear-regression.sql.out
new file mode 100644
index 0000000000..a73347a2f7
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/linear-regression.sql.out
@@ -0,0 +1,276 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW testRegression AS SELECT * FROM VALUES
+(1, 10, null), (2, 10, 11), (2, 20, 22), (2, 25, null), (2, 30, 35)
+AS testRegression(k, y, x)
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT regr_count(y, x) FROM testRegression
+-- !query schema
+struct<regr_count(y, x):bigint>
+-- !query output
+3
+
+
+-- !query
+SELECT regr_count(y, x) FROM testRegression WHERE x IS NOT NULL
+-- !query schema
+struct<regr_count(y, x):bigint>
+-- !query output
+3
+
+
+-- !query
+SELECT k, count(*), regr_count(y, x) FROM testRegression GROUP BY k
+-- !query schema
+struct<k:int,count(1):bigint,regr_count(y, x):bigint>
+-- !query output
+1 1 0
+2 4 3
+
+
+-- !query
+SELECT k, count(*) FILTER (WHERE x IS NOT NULL), regr_count(y, x) FROM testRegression GROUP BY k
+-- !query schema
+struct<k:int,count(1) FILTER (WHERE (x IS NOT NULL)):bigint,regr_count(y, x):bigint>
+-- !query output
+1 0 0
+2 3 3
+
+
+-- !query
+SELECT regr_r2(y, x) FROM testRegression
+-- !query schema
+struct<regr_r2(y, x):double>
+-- !query output
+0.9976905311778291
+
+
+-- !query
+SELECT regr_r2(y, x) FROM testRegression WHERE x IS NOT NULL
+-- !query schema
+struct<regr_r2(y, x):double>
+-- !query output
+0.9976905311778291
+
+
+-- !query
+SELECT k, corr(y, x), regr_r2(y, x) FROM testRegression GROUP BY k
+-- !query schema
+struct<k:int,corr(y, x):double,regr_r2(y, x):double>
+-- !query output
+1 NULL NULL
+2 0.9988445981121532 0.9976905311778291
+
+
+-- !query
+SELECT k, corr(y, x) FILTER (WHERE x IS NOT NULL), regr_r2(y, x) FROM testRegression GROUP BY k
+-- !query schema
+struct<k:int,corr(y, x) FILTER (WHERE (x IS NOT NULL)):double,regr_r2(y, x):double>
+-- !query output
+1 NULL NULL
+2 0.9988445981121532 0.9976905311778291
+
+
+-- !query
+SELECT regr_avgx(y, x), regr_avgy(y, x) FROM testRegression
+-- !query schema
+struct<regr_avgx(y, x):double,regr_avgy(y, x):double>
+-- !query output
+22.666666666666668 20.0
+
+
+-- !query
+SELECT regr_avgx(y, x), regr_avgy(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL
+-- !query schema
+struct<regr_avgx(y, x):double,regr_avgy(y, x):double>
+-- !query output
+22.666666666666668 20.0
+
+
+-- !query
+SELECT k, avg(x), avg(y), regr_avgx(y, x), regr_avgy(y, x) FROM testRegression GROUP BY k
+-- !query schema
+struct<k:int,avg(x):double,avg(y):double,regr_avgx(y, x):double,regr_avgy(y, x):double>
+-- !query output
+1 NULL 10.0 NULL NULL
+2 22.666666666666668 21.25 22.666666666666668 20.0
+
+
+-- !query
+SELECT k, avg(x) FILTER (WHERE x IS NOT NULL AND y IS NOT NULL), avg(y) FILTER (WHERE x IS NOT NULL AND y IS NOT NULL), regr_avgx(y, x), regr_avgy(y, x) FROM testRegression GROUP BY k
+-- !query schema
+struct<k:int,avg(x) FILTER (WHERE ((x IS NOT NULL) AND (y IS NOT NULL))):double,avg(y) FILTER (WHERE ((x IS NOT NULL) AND (y IS NOT NULL))):double,regr_avgx(y, x):double,regr_avgy(y, x):double>
+-- !query output
+1 NULL NULL NULL NULL
+2 22.666666666666668 20.0 22.666666666666668 20.0
+
+
+-- !query
+SELECT regr_sxx(y, x) FROM testRegression
+-- !query schema
+struct<regr_sxx(y, x):double>
+-- !query output
+288.66666666666663
+
+
+-- !query
+SELECT regr_sxx(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL
+-- !query schema
+struct<regr_sxx(y, x):double>
+-- !query output
+288.66666666666663
+
+
+-- !query
+SELECT k, regr_sxx(y, x) FROM testRegression GROUP BY k
+-- !query schema
+struct<k:int,regr_sxx(y, x):double>
+-- !query output
+1 NULL
+2 288.66666666666663
+
+
+-- !query
+SELECT k, regr_sxx(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL GROUP BY k
+-- !query schema
+struct<k:int,regr_sxx(y, x):double>
+-- !query output
+2 288.66666666666663
+
+
+-- !query
+SELECT regr_sxy(y, x) FROM testRegression
+-- !query schema
+struct<regr_sxy(y, x):double>
+-- !query output
+240.0
+
+
+-- !query
+SELECT regr_sxy(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL
+-- !query schema
+struct<regr_sxy(y, x):double>
+-- !query output
+240.0
+
+
+-- !query
+SELECT k, regr_sxy(y, x) FROM testRegression GROUP BY k
+-- !query schema
+struct<k:int,regr_sxy(y, x):double>
+-- !query output
+1 NULL
+2 240.0
+
+
+-- !query
+SELECT k, regr_sxy(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL GROUP BY k
+-- !query schema
+struct<k:int,regr_sxy(y, x):double>
+-- !query output
+2 240.0
+
+
+-- !query
+SELECT regr_syy(y, x) FROM testRegression
+-- !query schema
+struct<regr_syy(y, x):double>
+-- !query output
+200.0
+
+
+-- !query
+SELECT regr_syy(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL
+-- !query schema
+struct<regr_syy(y, x):double>
+-- !query output
+200.0
+
+
+-- !query
+SELECT k, regr_syy(y, x) FROM testRegression GROUP BY k
+-- !query schema
+struct<k:int,regr_syy(y, x):double>
+-- !query output
+1 NULL
+2 200.0
+
+
+-- !query
+SELECT k, regr_syy(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL GROUP BY k
+-- !query schema
+struct<k:int,regr_syy(y, x):double>
+-- !query output
+2 200.0
+
+
+-- !query
+SELECT regr_slope(y, x) FROM testRegression
+-- !query schema
+struct<regr_slope(y, x):double>
+-- !query output
+0.8314087759815244
+
+
+-- !query
+SELECT regr_slope(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL
+-- !query schema
+struct<regr_slope(y, x):double>
+-- !query output
+0.8314087759815244
+
+
+-- !query
+SELECT k, regr_slope(y, x) FROM testRegression GROUP BY k
+-- !query schema
+struct<k:int,regr_slope(y, x):double>
+-- !query output
+1 NULL
+2 0.8314087759815244
+
+
+-- !query
+SELECT k, regr_slope(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL GROUP BY k
+-- !query schema
+struct<k:int,regr_slope(y, x):double>
+-- !query output
+2 0.8314087759815244
+
+
+-- !query
+SELECT regr_intercept(y, x) FROM testRegression
+-- !query schema
+struct<regr_intercept(y, x):double>
+-- !query output
+1.1547344110854487
+
+
+-- !query
+SELECT regr_intercept(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL
+-- !query schema
+struct<regr_intercept(y, x):double>
+-- !query output
+1.1547344110854487
+
+
+-- !query
+SELECT k, regr_intercept(y, x) FROM testRegression GROUP BY k
+-- !query schema
+struct<k:int,regr_intercept(y, x):double>
+-- !query output
+1 NULL
+2 1.1547344110854487
+
+
+-- !query
+SELECT k, regr_intercept(y, x) FROM testRegression WHERE x IS NOT NULL AND y IS NOT NULL GROUP BY k
+-- !query schema
+struct<k:int,regr_intercept(y, x):double>
+-- !query output
+2 1.1547344110854487
diff --git a/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/misc-functions.sql.out b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/misc-functions.sql.out
new file mode 100644
index 0000000000..d6d1289a5a
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/misc-functions.sql.out
@@ -0,0 +1,134 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+select typeof(null)
+-- !query schema
+struct<typeof(NULL):string>
+-- !query output
+void
+
+
+-- !query
+select typeof(true)
+-- !query schema
+struct<typeof(true):string>
+-- !query output
+boolean
+
+
+-- !query
+select typeof(1Y), typeof(1S), typeof(1), typeof(1L)
+-- !query schema
+struct<typeof(1):string,typeof(1):string,typeof(1):string,typeof(1):string>
+-- !query output
+tinyint smallint int bigint
+
+
+-- !query
+select typeof(cast(1.0 as float)), typeof(1.0D), typeof(1.2)
+-- !query schema
+struct<typeof(CAST(1.0 AS FLOAT)):string,typeof(1.0):string,typeof(1.2):string>
+-- !query output
+float double decimal(2,1)
+
+
+-- !query
+select typeof(date '1986-05-23'), typeof(timestamp '1986-05-23'), typeof(interval '23 days')
+-- !query schema
+struct<typeof(DATE '1986-05-23'):string,typeof(TIMESTAMP '1986-05-23 00:00:00'):string,typeof(INTERVAL '23' DAY):string>
+-- !query output
+date timestamp interval day
+
+
+-- !query
+select typeof(x'ABCD'), typeof('SPARK')
+-- !query schema
+struct<typeof(X'ABCD'):string,typeof(SPARK):string>
+-- !query output
+binary string
+
+
+-- !query
+select typeof(array(1, 2)), typeof(map(1, 2)), typeof(named_struct('a', 1, 'b', 'spark'))
+-- !query schema
+struct<typeof(array(1, 2)):string,typeof(map(1, 2)):string,typeof(named_struct(a, 1, b, spark)):string>
+-- !query output
+array<int> map<int,int> struct<a:int,b:string>
+
+
+-- !query
+SELECT assert_true(true), assert_true(boolean(1))
+-- !query schema
+struct<assert_true(true, 'true' is not true!):void,assert_true(1, 'cast(1 as boolean)' is not true!):void>
+-- !query output
+NULL NULL
+
+
+-- !query
+SELECT assert_true(false)
+-- !query schema
+struct<>
+-- !query output
+org.apache.gluten.exception.GlutenException
+'false' is not true!
+
+
+-- !query
+SELECT assert_true(boolean(0))
+-- !query schema
+struct<>
+-- !query output
+org.apache.gluten.exception.GlutenException
+'cast(0 as boolean)' is not true!
+
+
+-- !query
+SELECT assert_true(null)
+-- !query schema
+struct<>
+-- !query output
+org.apache.gluten.exception.GlutenException
+'null' is not true!
+
+
+-- !query
+SELECT assert_true(boolean(null))
+-- !query schema
+struct<>
+-- !query output
+org.apache.gluten.exception.GlutenException
+'cast(null as boolean)' is not true!
+
+
+-- !query
+SELECT assert_true(false, 'custom error message')
+-- !query schema
+struct<>
+-- !query output
+org.apache.gluten.exception.GlutenException
+custom error message
+
+
+-- !query
+CREATE TEMPORARY VIEW tbl_misc AS SELECT * FROM (VALUES (1), (8), (2)) AS T(v)
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT raise_error('error message')
+-- !query schema
+struct<>
+-- !query output
+org.apache.gluten.exception.GlutenException
+error message
+
+
+-- !query
+SELECT if(v > 5, raise_error('too big: ' || v), v + 1) FROM tbl_misc
+-- !query schema
+struct<>
+-- !query output
+org.apache.gluten.exception.GlutenException
+too big: 8
diff --git a/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/random.sql.out b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/random.sql.out
new file mode 100644
index 0000000000..17e6f871b9
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/random.sql.out
@@ -0,0 +1,115 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+SELECT rand(0)
+-- !query schema
+struct<rand(0):double>
+-- !query output
+0.5488135024422883
+
+
+-- !query
+SELECT rand(cast(3 / 7 AS int))
+-- !query schema
+struct<rand(CAST((3 / 7) AS INT)):double>
+-- !query output
+0.5488135024422883
+
+
+-- !query
+SELECT rand(NULL)
+-- !query schema
+struct<rand(NULL):double>
+-- !query output
+0.5488135024422883
+
+
+-- !query
+SELECT rand(cast(NULL AS int))
+-- !query schema
+struct<rand(CAST(NULL AS INT)):double>
+-- !query output
+0.5488135024422883
+
+
+-- !query
+SELECT rand(1.0)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "inputSql" : "\"1.0\"",
+ "inputType" : "\"DECIMAL(2,1)\"",
+ "paramIndex" : "1",
+ "requiredType" : "(\"INT\" or \"BIGINT\")",
+ "sqlExpr" : "\"rand(1.0)\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 8,
+ "stopIndex" : 16,
+ "fragment" : "rand(1.0)"
+ } ]
+}
+
+
+-- !query
+SELECT randn(0L)
+-- !query schema
+struct<randn(0):double>
+-- !query output
+1.6034991609278433
+
+
+-- !query
+SELECT randn(cast(3 / 7 AS long))
+-- !query schema
+struct<randn(CAST((3 / 7) AS BIGINT)):double>
+-- !query output
+1.6034991609278433
+
+
+-- !query
+SELECT randn(NULL)
+-- !query schema
+struct<randn(NULL):double>
+-- !query output
+1.6034991609278433
+
+
+-- !query
+SELECT randn(cast(NULL AS long))
+-- !query schema
+struct<randn(CAST(NULL AS BIGINT)):double>
+-- !query output
+1.6034991609278433
+
+
+-- !query
+SELECT rand('1')
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "inputSql" : "\"1\"",
+ "inputType" : "\"STRING\"",
+ "paramIndex" : "1",
+ "requiredType" : "(\"INT\" or \"BIGINT\")",
+ "sqlExpr" : "\"rand(1)\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 8,
+ "stopIndex" : 16,
+ "fragment" : "rand('1')"
+ } ]
+}
diff --git a/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/table-valued-functions.sql.out b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/table-valued-functions.sql.out
new file mode 100644
index 0000000000..0d5675fa6f
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/table-valued-functions.sql.out
@@ -0,0 +1,1017 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+select * from dummy(3)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "UNRESOLVABLE_TABLE_VALUED_FUNCTION",
+ "messageParameters" : {
+ "name" : "`dummy`"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 22,
+ "fragment" : "dummy(3)"
+ } ]
+}
+
+
+-- !query
+select * from range(6 + cos(3))
+-- !query schema
+struct<id:bigint>
+-- !query output
+0
+1
+2
+3
+4
+
+
+-- !query
+select * from range(5, 10)
+-- !query schema
+struct<id:bigint>
+-- !query output
+5
+6
+7
+8
+9
+
+
+-- !query
+select * from range(0, 10, 2)
+-- !query schema
+struct<id:bigint>
+-- !query output
+0
+2
+4
+6
+8
+
+
+-- !query
+select * from range(0, 10, 1, 200)
+-- !query schema
+struct<id:bigint>
+-- !query output
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+
+
+-- !query
+select * from range(1, 1, 1, 1, 1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "WRONG_NUM_ARGS.WITHOUT_SUGGESTION",
+ "sqlState" : "42605",
+ "messageParameters" : {
+ "actualNum" : "5",
+ "docroot" : "https://spark.apache.org/docs/latest",
+ "expectedNum" : "[1, 2, 3, 4]",
+ "functionName" : "`range`"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 34,
+ "fragment" : "range(1, 1, 1, 1, 1)"
+ } ]
+}
+
+
+-- !query
+select * from range(1, null)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "functionName" : "`range`",
+ "inputSql" : "\"NULL\"",
+ "inputType" : "\"VOID\"",
+ "paramIndex" : "2",
+ "requiredType" : "\"BIGINT\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 28,
+ "fragment" : "range(1, null)"
+ } ]
+}
+
+
+-- !query
+select * from range(array(1, 2, 3))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "functionName" : "`range`",
+ "inputSql" : "\"array(1, 2, 3)\"",
+ "inputType" : "\"ARRAY<INT>\"",
+ "paramIndex" : "2",
+ "requiredType" : "\"BIGINT\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 35,
+ "fragment" : "range(array(1, 2, 3))"
+ } ]
+}
+
+
+-- !query
+select * from range(0, 5, 0)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "FAILED_FUNCTION_CALL",
+ "sqlState" : "38000",
+ "messageParameters" : {
+ "funcName" : "`range`"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 28,
+ "fragment" : "range(0, 5, 0)"
+ } ]
+}
+
+
+-- !query
+select * from RaNgE(2)
+-- !query schema
+struct<id:bigint>
+-- !query output
+0
+1
+
+
+-- !query
+select i from range(0, 2) t(i)
+-- !query schema
+struct<i:bigint>
+-- !query output
+0
+1
+
+
+-- !query
+select * from explode(array(1, 2))
+-- !query schema
+struct<col:int>
+-- !query output
+1
+2
+
+
+-- !query
+select * from explode(map('a', 1, 'b', 2))
+-- !query schema
+struct<key:string,value:int>
+-- !query output
+a 1
+b 2
+
+
+-- !query
+select * from explode(array())
+-- !query schema
+struct<col:void>
+-- !query output
+
+
+
+-- !query
+select * from explode(map())
+-- !query schema
+struct<key:void,value:void>
+-- !query output
+
+
+
+-- !query
+select * from explode(array(1, 2)) t(c1)
+-- !query schema
+struct<c1:int>
+-- !query output
+1
+2
+
+
+-- !query
+select * from explode(map('a', 1, 'b', 2)) t(k, v)
+-- !query schema
+struct<k:string,v:int>
+-- !query output
+a 1
+b 2
+
+
+-- !query
+select * from explode(array(rand(0)))
+-- !query schema
+struct<col:double>
+-- !query output
+0.5488135024422883
+
+
+-- !query
+select * from explode(null)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "inputSql" : "\"NULL\"",
+ "inputType" : "\"VOID\"",
+ "paramIndex" : "1",
+ "requiredType" : "(\"ARRAY\" or \"MAP\")",
+ "sqlExpr" : "\"explode(NULL)\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 27,
+ "fragment" : "explode(null)"
+ } ]
+}
+
+
+-- !query
+select * from explode(null) t(c1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "inputSql" : "\"NULL\"",
+ "inputType" : "\"VOID\"",
+ "paramIndex" : "1",
+ "requiredType" : "(\"ARRAY\" or \"MAP\")",
+ "sqlExpr" : "\"explode(NULL)\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 33,
+ "fragment" : "explode(null) t(c1)"
+ } ]
+}
+
+
+-- !query
+select * from explode(1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "inputSql" : "\"1\"",
+ "inputType" : "\"INT\"",
+ "paramIndex" : "1",
+ "requiredType" : "(\"ARRAY\" or \"MAP\")",
+ "sqlExpr" : "\"explode(1)\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 24,
+ "fragment" : "explode(1)"
+ } ]
+}
+
+
+-- !query
+select * from explode(1, 2)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "WRONG_NUM_ARGS.WITHOUT_SUGGESTION",
+ "sqlState" : "42605",
+ "messageParameters" : {
+ "actualNum" : "2",
+ "docroot" : "https://spark.apache.org/docs/latest",
+ "expectedNum" : "1",
+ "functionName" : "`explode`"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 27,
+ "fragment" : "explode(1, 2)"
+ } ]
+}
+
+
+-- !query
+select * from explode(explode(array(1)))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "UNSUPPORTED_GENERATOR.NESTED_IN_EXPRESSIONS",
+ "sqlState" : "0A000",
+ "messageParameters" : {
+ "expression" : "\"explode(explode(array(1)))\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 40,
+ "fragment" : "explode(explode(array(1)))"
+ } ]
+}
+
+
+-- !query
+select * from explode(array(1, 2)) t(c1, c2)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "NUM_TABLE_VALUE_ALIASES_MISMATCH",
+ "messageParameters" : {
+ "aliasesNum" : "2",
+ "funcName" : "`explode`",
+ "outColsNum" : "1"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 44,
+ "fragment" : "explode(array(1, 2)) t(c1, c2)"
+ } ]
+}
+
+
+-- !query
+select * from explode_outer(array(1, 2))
+-- !query schema
+struct<col:int>
+-- !query output
+1
+2
+
+
+-- !query
+select * from explode_outer(map('a', 1, 'b', 2))
+-- !query schema
+struct<key:string,value:int>
+-- !query output
+a 1
+b 2
+
+
+-- !query
+select * from explode_outer(array())
+-- !query schema
+struct<col:void>
+-- !query output
+NULL
+
+
+-- !query
+select * from explode_outer(map())
+-- !query schema
+struct<key:void,value:void>
+-- !query output
+NULL NULL
+
+
+-- !query
+select * from range(2) join explode(array(1, 2))
+-- !query schema
+struct<id:bigint,col:int>
+-- !query output
+0 1
+0 2
+1 1
+1 2
+
+
+-- !query
+select * from range(2) join explode_outer(array())
+-- !query schema
+struct<id:bigint,col:void>
+-- !query output
+0 NULL
+1 NULL
+
+
+-- !query
+select * from inline(array(struct(1, 'a'), struct(2, 'b')))
+-- !query schema
+struct<col1:int,col2:string>
+-- !query output
+1 a
+2 b
+
+
+-- !query
+select * from inline(array(struct(1, 'a'), struct(2, 'b'))) t(x, y)
+-- !query schema
+struct<x:int,y:string>
+-- !query output
+1 a
+2 b
+
+
+-- !query
+select * from inline(array_remove(array(struct(1, 'a')), struct(1, 'a')))
+-- !query schema
+struct<col1:int,col2:string>
+-- !query output
+
+
+
+-- !query
+select * from inline(null)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "inputSql" : "\"NULL\"",
+ "inputType" : "\"VOID\"",
+ "paramIndex" : "1",
+ "requiredType" : "\"ARRAY<STRUCT>\"",
+ "sqlExpr" : "\"inline(NULL)\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 26,
+ "fragment" : "inline(null)"
+ } ]
+}
+
+
+-- !query
+select * from inline(array(struct(1, 2), struct(2, 3))) t(a, b, c)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "NUM_TABLE_VALUE_ALIASES_MISMATCH",
+ "messageParameters" : {
+ "aliasesNum" : "3",
+ "funcName" : "`inline`",
+ "outColsNum" : "2"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 66,
+ "fragment" : "inline(array(struct(1, 2), struct(2, 3))) t(a, b, c)"
+ } ]
+}
+
+
+-- !query
+select * from inline_outer(array(struct(1, 'a'), struct(2, 'b')))
+-- !query schema
+struct<col1:int,col2:string>
+-- !query output
+1 a
+2 b
+
+
+-- !query
+select * from inline_outer(array_remove(array(struct(1, 'a')), struct(1, 'a')))
+-- !query schema
+struct<col1:int,col2:string>
+-- !query output
+NULL NULL
+
+
+-- !query
+select * from posexplode(array())
+-- !query schema
+struct<pos:int,col:void>
+-- !query output
+
+
+
+-- !query
+select * from posexplode(array(1, 2))
+-- !query schema
+struct<pos:int,col:int>
+-- !query output
+0 1
+1 2
+
+
+-- !query
+select * from posexplode(array(1, 2)) t(pos, x)
+-- !query schema
+struct<pos:int,x:int>
+-- !query output
+0 1
+1 2
+
+
+-- !query
+select * from posexplode(map())
+-- !query schema
+struct<pos:int,key:void,value:void>
+-- !query output
+
+
+
+-- !query
+select * from posexplode(map('a', 1, 'b', 2))
+-- !query schema
+struct<pos:int,key:string,value:int>
+-- !query output
+0 a 1
+1 b 2
+
+
+-- !query
+select * from posexplode(map('a', 1, 'b', 2)) t(pos, k, v)
+-- !query schema
+struct<pos:int,k:string,v:int>
+-- !query output
+0 a 1
+1 b 2
+
+
+-- !query
+select * from posexplode(1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "inputSql" : "\"1\"",
+ "inputType" : "\"INT\"",
+ "paramIndex" : "1",
+ "requiredType" : "(\"ARRAY\" or \"MAP\")",
+ "sqlExpr" : "\"posexplode(1)\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 27,
+ "fragment" : "posexplode(1)"
+ } ]
+}
+
+
+-- !query
+select * from posexplode(1, 2)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "WRONG_NUM_ARGS.WITHOUT_SUGGESTION",
+ "sqlState" : "42605",
+ "messageParameters" : {
+ "actualNum" : "2",
+ "docroot" : "https://spark.apache.org/docs/latest",
+ "expectedNum" : "1",
+ "functionName" : "`posexplode`"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 30,
+ "fragment" : "posexplode(1, 2)"
+ } ]
+}
+
+
+-- !query
+select * from posexplode(explode(array(1)))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "UNSUPPORTED_GENERATOR.NESTED_IN_EXPRESSIONS",
+ "sqlState" : "0A000",
+ "messageParameters" : {
+ "expression" : "\"posexplode(explode(array(1)))\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 43,
+ "fragment" : "posexplode(explode(array(1)))"
+ } ]
+}
+
+
+-- !query
+select * from posexplode(array(1, 2)) t(x)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "NUM_TABLE_VALUE_ALIASES_MISMATCH",
+ "messageParameters" : {
+ "aliasesNum" : "1",
+ "funcName" : "`posexplode`",
+ "outColsNum" : "2"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 42,
+ "fragment" : "posexplode(array(1, 2)) t(x)"
+ } ]
+}
+
+
+-- !query
+select * from posexplode_outer(array())
+-- !query schema
+struct<pos:int,col:void>
+-- !query output
+NULL NULL
+
+
+-- !query
+select * from posexplode_outer(array(1, 2))
+-- !query schema
+struct<pos:int,col:int>
+-- !query output
+0 1
+1 2
+
+
+-- !query
+select * from posexplode_outer(map())
+-- !query schema
+struct<pos:int,key:void,value:void>
+-- !query output
+NULL NULL NULL
+
+
+-- !query
+select * from posexplode_outer(map('a', 1, 'b', 2))
+-- !query schema
+struct<pos:int,key:string,value:int>
+-- !query output
+0 a 1
+1 b 2
+
+
+-- !query
+select * from json_tuple('{"a": 1, "b": 2}', 'a', 'b')
+-- !query schema
+struct<c0:string,c1:string>
+-- !query output
+1 2
+
+
+-- !query
+select * from json_tuple('{"a": 1, "b": 2}', 'a', 'c')
+-- !query schema
+struct<c0:string,c1:string>
+-- !query output
+1 NULL
+
+
+-- !query
+select * from json_tuple('{"a": 1, "b": 2}', 'a', 'a')
+-- !query schema
+struct<c0:string,c1:string>
+-- !query output
+1 1
+
+
+-- !query
+select * from json_tuple('{"a": 1, "b": 2}', 'a', 'b') AS t(x, y)
+-- !query schema
+struct<x:string,y:string>
+-- !query output
+1 2
+
+
+-- !query
+select * from json_tuple('{"a": bad, "b": string}', 'a', 'b')
+-- !query schema
+struct<c0:string,c1:string>
+-- !query output
+NULL NULL
+
+
+-- !query
+select * from json_tuple()
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "WRONG_NUM_ARGS.WITHOUT_SUGGESTION",
+ "sqlState" : "42605",
+ "messageParameters" : {
+ "actualNum" : "0",
+ "docroot" : "https://spark.apache.org/docs/latest",
+ "expectedNum" : "> 1",
+ "functionName" : "`json_tuple`"
+ }
+}
+
+
+-- !query
+select * from json_tuple('{"a": 1}')
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "WRONG_NUM_ARGS.WITHOUT_SUGGESTION",
+ "sqlState" : "42605",
+ "messageParameters" : {
+ "actualNum" : "1",
+ "docroot" : "https://spark.apache.org/docs/latest",
+ "expectedNum" : "> 1",
+ "functionName" : "`json_tuple`"
+ }
+}
+
+
+-- !query
+select * from json_tuple('{"a": 1}', 1)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.NON_STRING_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "funcName" : "`json_tuple`",
+ "sqlExpr" : "\"json_tuple({\"a\": 1}, 1)\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 39,
+ "fragment" : "json_tuple('{\"a\": 1}', 1)"
+ } ]
+}
+
+
+-- !query
+select * from json_tuple('{"a": 1}', null)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.NON_STRING_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "funcName" : "`json_tuple`",
+ "sqlExpr" : "\"json_tuple({\"a\": 1}, NULL)\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 42,
+ "fragment" : "json_tuple('{\"a\": 1}', null)"
+ } ]
+}
+
+
+-- !query
+select * from json_tuple('{"a": 1, "b": 2}', 'a', 'b') AS t(x)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "NUM_TABLE_VALUE_ALIASES_MISMATCH",
+ "messageParameters" : {
+ "aliasesNum" : "1",
+ "funcName" : "`json_tuple`",
+ "outColsNum" : "2"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 62,
+ "fragment" : "json_tuple('{\"a\": 1, \"b\": 2}', 'a', 'b') AS t(x)"
+ } ]
+}
+
+
+-- !query
+select * from stack(1, 1, 2, 3)
+-- !query schema
+struct<col0:int,col1:int,col2:int>
+-- !query output
+1 2 3
+
+
+-- !query
+select * from stack(2, 1, 2, 3)
+-- !query schema
+struct<col0:int,col1:int>
+-- !query output
+1 2
+3 NULL
+
+
+-- !query
+select * from stack(3, 1, 2, 3) t(x)
+-- !query schema
+struct<x:int>
+-- !query output
+1
+2
+3
+
+
+-- !query
+select * from stack(4, 1, 2, 3) t(x)
+-- !query schema
+struct<x:int>
+-- !query output
+1
+2
+3
+NULL
+
+
+-- !query
+select * from stack(2, 1, 1.1, 'a', 2, 2.2, 'b') t(a, b, c)
+-- !query schema
+struct<a:int,b:decimal(2,1),c:string>
+-- !query output
+1 1.1 a
+2 2.2 b
+
+
+-- !query
+select * from stack(2, 1, 1.1, null, 2, null, 'b') t(a, b, c)
+-- !query schema
+struct<a:int,b:decimal(2,1),c:string>
+-- !query output
+1 1.1 NULL
+2 NULL b
+
+
+-- !query
+select * from stack()
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "WRONG_NUM_ARGS.WITHOUT_SUGGESTION",
+ "sqlState" : "42605",
+ "messageParameters" : {
+ "actualNum" : "0",
+ "docroot" : "https://spark.apache.org/docs/latest",
+ "expectedNum" : "> 1",
+ "functionName" : "`stack`"
+ }
+}
+
+
+-- !query
+select * from stack(2, 1, 2, 3) t(a, b, c)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "NUM_TABLE_VALUE_ALIASES_MISMATCH",
+ "messageParameters" : {
+ "aliasesNum" : "3",
+ "funcName" : "`stack`",
+ "outColsNum" : "2"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 42,
+ "fragment" : "stack(2, 1, 2, 3) t(a, b, c)"
+ } ]
+}
+
+
+-- !query
+select * from stack(2, 1, '1.1', 'a', 2, 2.2, 'b')
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.catalyst.ExtendedAnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.STACK_COLUMN_DIFF_TYPES",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "columnIndex" : "1",
+ "leftParamIndex" : "2",
+ "leftType" : "\"STRING\"",
+ "rightParamIndex" : "5",
+ "rightType" : "\"DECIMAL(2,1)\"",
+ "sqlExpr" : "\"stack(2, 1, 1.1, a, 2, 2.2, b)\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 50,
+ "fragment" : "stack(2, 1, '1.1', 'a', 2, 2.2, 'b')"
+ } ]
+}
+
+
+-- !query
+select * from stack(2, explode(array(1, 2, 3)))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "UNSUPPORTED_GENERATOR.NESTED_IN_EXPRESSIONS",
+ "sqlState" : "0A000",
+ "messageParameters" : {
+ "expression" : "\"stack(2, explode(array(1, 2, 3)))\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 15,
+ "stopIndex" : 47,
+ "fragment" : "stack(2, explode(array(1, 2, 3)))"
+ } ]
+}
diff --git a/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/udf/udf-group-by.sql.out b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/udf/udf-group-by.sql.out
new file mode 100644
index 0000000000..d3735acf0f
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-clickhouse/sql-tests/results/udf/udf-group-by.sql.out
@@ -0,0 +1,689 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW testData AS SELECT * FROM VALUES
+(1, 1), (1, 2), (2, 1), (2, 2), (3, 1), (3, 2), (null, 1), (3, null), (null, null)
+AS testData(a, b)
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT udf(a), udf(COUNT(b)) FROM testData
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "MISSING_GROUP_BY",
+ "sqlState" : "42803",
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 1,
+ "stopIndex" : 42,
+ "fragment" : "SELECT udf(a), udf(COUNT(b)) FROM testData"
+ } ]
+}
+
+
+-- !query
+SELECT COUNT(udf(a)), udf(COUNT(b)) FROM testData
+-- !query schema
+struct<count(udf(a)):bigint,udf(count(b)):bigint>
+-- !query output
+7 7
+
+
+-- !query
+SELECT udf(a), COUNT(udf(b)) FROM testData GROUP BY a
+-- !query schema
+struct<udf(a):int,count(udf(b)):bigint>
+-- !query output
+1 2
+2 2
+3 2
+NULL 1
+
+
+-- !query
+SELECT udf(a), udf(COUNT(udf(b))) FROM testData GROUP BY b
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "MISSING_AGGREGATION",
+ "sqlState" : "42803",
+ "messageParameters" : {
+ "expression" : "\"a\"",
+ "expressionAnyValue" : "\"any_value(a)\""
+ }
+}
+
+
+-- !query
+SELECT COUNT(udf(a)), COUNT(udf(b)) FROM testData GROUP BY udf(a)
+-- !query schema
+struct<count(udf(a)):bigint,count(udf(b)):bigint>
+-- !query output
+0 1
+2 2
+2 2
+3 2
+
+
+-- !query
+SELECT 'foo', COUNT(udf(a)) FROM testData GROUP BY 1
+-- !query schema
+struct<foo:string,count(udf(a)):bigint>
+-- !query output
+foo 7
+
+
+-- !query
+SELECT 'foo' FROM testData WHERE a = 0 GROUP BY udf(1)
+-- !query schema
+struct<foo:string>
+-- !query output
+
+
+
+-- !query
+SELECT 'foo', udf(APPROX_COUNT_DISTINCT(udf(a))) FROM testData WHERE a = 0 GROUP BY udf(1)
+-- !query schema
+struct<foo:string,udf(approx_count_distinct(udf(a))):bigint>
+-- !query output
+
+
+
+-- !query
+SELECT 'foo', MAX(STRUCT(udf(a))) FROM testData WHERE a = 0 GROUP BY udf(1)
+-- !query schema
+struct<foo:string,max(struct(udf(a))):struct<col1:int>>
+-- !query output
+
+
+
+-- !query
+SELECT udf(a + b), udf(COUNT(b)) FROM testData GROUP BY a + b
+-- !query schema
+struct<udf((a + b)):int,udf(count(b)):bigint>
+-- !query output
+2 1
+3 2
+4 2
+5 1
+NULL 1
+
+
+-- !query
+SELECT udf(a + 2), udf(COUNT(b)) FROM testData GROUP BY a + 1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "MISSING_AGGREGATION",
+ "sqlState" : "42803",
+ "messageParameters" : {
+ "expression" : "\"a\"",
+ "expressionAnyValue" : "\"any_value(a)\""
+ }
+}
+
+
+-- !query
+SELECT udf(a + 1) + 1, udf(COUNT(b)) FROM testData GROUP BY udf(a + 1)
+-- !query schema
+struct<(udf((a + 1)) + 1):int,udf(count(b)):bigint>
+-- !query output
+3 2
+4 2
+5 2
+NULL 1
+
+
+-- !query
+SELECT SKEWNESS(udf(a)), udf(KURTOSIS(a)), udf(MIN(a)), MAX(udf(a)), udf(AVG(udf(a))), udf(VARIANCE(a)), STDDEV(udf(a)), udf(SUM(a)), udf(COUNT(a))
+FROM testData
+-- !query schema
+struct<skewness(udf(a)):double,udf(kurtosis(a)):double,udf(min(a)):int,max(udf(a)):int,udf(avg(udf(a))):double,udf(variance(a)):double,stddev(udf(a)):double,udf(sum(a)):bigint,udf(count(a)):bigint>
+-- !query output
+-0.27238010581457284 -1.5069204152249138 1 3 2.142857142857143 0.8095238095238096 0.8997354108424375 15 7
+
+
+-- !query
+SELECT COUNT(DISTINCT udf(b)), udf(COUNT(DISTINCT b, c)) FROM (SELECT 1 AS a, 2 AS b, 3 AS c) GROUP BY udf(a)
+-- !query schema
+struct<count(DISTINCT udf(b)):bigint,udf(count(DISTINCT b, c)):bigint>
+-- !query output
+1 1
+
+
+-- !query
+SELECT udf(a) AS k, COUNT(udf(b)) FROM testData GROUP BY k
+-- !query schema
+struct<k:int,count(udf(b)):bigint>
+-- !query output
+1 2
+2 2
+3 2
+NULL 1
+
+
+-- !query
+SELECT a AS k, udf(COUNT(b)) FROM testData GROUP BY k HAVING k > 1
+-- !query schema
+struct<k:int,udf(count(b)):bigint>
+-- !query output
+2 2
+3 2
+
+
+-- !query
+SELECT udf(COUNT(b)) AS k FROM testData GROUP BY k
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "GROUP_BY_AGGREGATE",
+ "sqlState" : "42903",
+ "messageParameters" : {
+ "sqlExpr" : "CAST(udf(cast(count(b) as string)) AS BIGINT)"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 8,
+ "stopIndex" : 20,
+ "fragment" : "udf(COUNT(b))"
+ } ]
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW testDataHasSameNameWithAlias AS SELECT * FROM VALUES
+(1, 1, 3), (1, 2, 1) AS testDataHasSameNameWithAlias(k, a, v)
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT k AS a, udf(COUNT(udf(v))) FROM testDataHasSameNameWithAlias GROUP BY udf(a)
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "MISSING_AGGREGATION",
+ "sqlState" : "42803",
+ "messageParameters" : {
+ "expression" : "\"k\"",
+ "expressionAnyValue" : "\"any_value(k)\""
+ }
+}
+
+
+-- !query
+set spark.sql.groupByAliases=false
+-- !query schema
+struct<key:string,value:string>
+-- !query output
+spark.sql.groupByAliases false
+
+
+-- !query
+SELECT a AS k, udf(COUNT(udf(b))) FROM testData GROUP BY k
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "UNRESOLVED_COLUMN.WITH_SUGGESTION",
+ "sqlState" : "42703",
+ "messageParameters" : {
+ "objectName" : "`k`",
+ "proposal" : "`testdata`.`a`, `testdata`.`b`"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 58,
+ "stopIndex" : 58,
+ "fragment" : "k"
+ } ]
+}
+
+
+-- !query
+SELECT udf(a), COUNT(udf(1)) FROM testData WHERE false GROUP BY udf(a)
+-- !query schema
+struct<udf(a):int,count(udf(1)):bigint>
+-- !query output
+
+
+
+-- !query
+SELECT udf(COUNT(1)) FROM testData WHERE false
+-- !query schema
+struct<udf(count(1)):bigint>
+-- !query output
+0
+
+
+-- !query
+SELECT 1 FROM (SELECT udf(COUNT(1)) FROM testData WHERE false) t
+-- !query schema
+struct<1:int>
+-- !query output
+1
+
+
+-- !query
+SELECT 1 from (
+ SELECT 1 AS z,
+ udf(MIN(a.x))
+ FROM (select 1 as x) a
+ WHERE false
+) b
+where b.z != b.z
+-- !query schema
+struct<1:int>
+-- !query output
+
+
+
+-- !query
+SELECT corr(DISTINCT x, y), udf(corr(DISTINCT y, x)), count(*)
+ FROM (VALUES (1, 1), (2, 2), (2, 2)) t(x, y)
+-- !query schema
+struct<corr(DISTINCT x, y):double,udf(corr(DISTINCT y, x)):double,count(1):bigint>
+-- !query output
+0.9999999999999999 0.9999999999999999 3
+
+
+-- !query
+SELECT udf(1) FROM range(10) HAVING true
+-- !query schema
+struct<udf(1):int>
+-- !query output
+1
+
+
+-- !query
+SELECT udf(udf(1)) FROM range(10) HAVING MAX(id) > 0
+-- !query schema
+struct<udf(udf(1)):int>
+-- !query output
+1
+
+
+-- !query
+SELECT udf(id) FROM range(10) HAVING id > 0
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "MISSING_GROUP_BY",
+ "sqlState" : "42803",
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 1,
+ "stopIndex" : 43,
+ "fragment" : "SELECT udf(id) FROM range(10) HAVING id > 0"
+ } ]
+}
+
+
+-- !query
+CREATE OR REPLACE TEMPORARY VIEW test_agg AS SELECT * FROM VALUES
+ (1, true), (1, false),
+ (2, true),
+ (3, false), (3, null),
+ (4, null), (4, null),
+ (5, null), (5, true), (5, false) AS test_agg(k, v)
+-- !query schema
+struct<>
+-- !query output
+
+
+
+-- !query
+SELECT udf(every(v)), udf(some(v)), any(v) FROM test_agg WHERE 1 = 0
+-- !query schema
+struct<udf(every(v)):boolean,udf(some(v)):boolean,any(v):boolean>
+-- !query output
+NULL NULL NULL
+
+
+-- !query
+SELECT udf(every(udf(v))), some(v), any(v) FROM test_agg WHERE k = 4
+-- !query schema
+struct<udf(every(udf(v))):boolean,some(v):boolean,any(v):boolean>
+-- !query output
+NULL NULL NULL
+
+
+-- !query
+SELECT every(v), udf(some(v)), any(v) FROM test_agg WHERE k = 5
+-- !query schema
+struct<every(v):boolean,udf(some(v)):boolean,any(v):boolean>
+-- !query output
+false true true
+
+
+-- !query
+SELECT udf(k), every(v), udf(some(v)), any(v) FROM test_agg GROUP BY udf(k)
+-- !query schema
+struct<udf(k):int,every(v):boolean,udf(some(v)):boolean,any(v):boolean>
+-- !query output
+1 false true true
+2 true true true
+3 false false false
+4 NULL NULL NULL
+5 false true true
+
+
+-- !query
+SELECT udf(k), every(v) FROM test_agg GROUP BY k HAVING every(v) = false
+-- !query schema
+struct<udf(k):int,every(v):boolean>
+-- !query output
+1 false
+3 false
+5 false
+
+
+-- !query
+SELECT udf(k), udf(every(v)) FROM test_agg GROUP BY udf(k) HAVING every(v) IS NULL
+-- !query schema
+struct<udf(k):int,udf(every(v)):boolean>
+-- !query output
+4 NULL
+
+
+-- !query
+SELECT udf(k),
+ udf(Every(v)) AS every
+FROM test_agg
+WHERE k = 2
+ AND v IN (SELECT Any(v)
+ FROM test_agg
+ WHERE k = 1)
+GROUP BY udf(k)
+-- !query schema
+struct<udf(k):int,every:boolean>
+-- !query output
+2 true
+
+
+-- !query
+SELECT udf(udf(k)),
+ Every(v) AS every
+FROM test_agg
+WHERE k = 2
+ AND v IN (SELECT Every(v)
+ FROM test_agg
+ WHERE k = 1)
+GROUP BY udf(udf(k))
+-- !query schema
+struct<udf(udf(k)):int,every:boolean>
+-- !query output
+
+
+
+-- !query
+SELECT every(udf(1))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "inputSql" : "\"udf(1)\"",
+ "inputType" : "\"INT\"",
+ "paramIndex" : "1",
+ "requiredType" : "\"BOOLEAN\"",
+ "sqlExpr" : "\"every(udf(1))\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 8,
+ "stopIndex" : 20,
+ "fragment" : "every(udf(1))"
+ } ]
+}
+
+
+-- !query
+SELECT some(udf(1S))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "inputSql" : "\"udf(1)\"",
+ "inputType" : "\"SMALLINT\"",
+ "paramIndex" : "1",
+ "requiredType" : "\"BOOLEAN\"",
+ "sqlExpr" : "\"some(udf(1))\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 8,
+ "stopIndex" : 20,
+ "fragment" : "some(udf(1S))"
+ } ]
+}
+
+
+-- !query
+SELECT any(udf(1L))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "inputSql" : "\"udf(1)\"",
+ "inputType" : "\"BIGINT\"",
+ "paramIndex" : "1",
+ "requiredType" : "\"BOOLEAN\"",
+ "sqlExpr" : "\"any(udf(1))\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 8,
+ "stopIndex" : 19,
+ "fragment" : "any(udf(1L))"
+ } ]
+}
+
+
+-- !query
+SELECT udf(every("true"))
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "DATATYPE_MISMATCH.UNEXPECTED_INPUT_TYPE",
+ "sqlState" : "42K09",
+ "messageParameters" : {
+ "inputSql" : "\"true\"",
+ "inputType" : "\"STRING\"",
+ "paramIndex" : "1",
+ "requiredType" : "\"BOOLEAN\"",
+ "sqlExpr" : "\"every(true)\""
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 12,
+ "stopIndex" : 24,
+ "fragment" : "every(\"true\")"
+ } ]
+}
+
+
+-- !query
+SELECT k, v, every(v) OVER (PARTITION BY k ORDER BY v) FROM test_agg
+-- !query schema
+struct<k:int,v:boolean,every(v) OVER (PARTITION BY k ORDER BY v ASC NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW):boolean>
+-- !query output
+1 false false
+1 true false
+2 true true
+3 NULL NULL
+3 false false
+4 NULL NULL
+4 NULL NULL
+5 NULL NULL
+5 false false
+5 true false
+
+
+-- !query
+SELECT k, udf(udf(v)), some(v) OVER (PARTITION BY k ORDER BY v) FROM test_agg
+-- !query schema
+struct<k:int,udf(udf(v)):boolean,some(v) OVER (PARTITION BY k ORDER BY v ASC NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW):boolean>
+-- !query output
+1 false false
+1 true true
+2 true true
+3 NULL NULL
+3 false false
+4 NULL NULL
+4 NULL NULL
+5 NULL NULL
+5 false false
+5 true true
+
+
+-- !query
+SELECT udf(udf(k)), v, any(v) OVER (PARTITION BY k ORDER BY v) FROM test_agg
+-- !query schema
+struct<udf(udf(k)):int,v:boolean,any(v) OVER (PARTITION BY k ORDER BY v ASC NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW):boolean>
+-- !query output
+1 false false
+1 true true
+2 true true
+3 NULL NULL
+3 false false
+4 NULL NULL
+4 NULL NULL
+5 NULL NULL
+5 false false
+5 true true
+
+
+-- !query
+SELECT udf(count(*)) FROM test_agg HAVING count(*) > 1L
+-- !query schema
+struct<udf(count(1)):bigint>
+-- !query output
+10
+
+
+-- !query
+SELECT k, udf(max(v)) FROM test_agg GROUP BY k HAVING max(v) = true
+-- !query schema
+struct<k:int,udf(max(v)):boolean>
+-- !query output
+1 true
+2 true
+5 true
+
+
+-- !query
+SELECT * FROM (SELECT udf(COUNT(*)) AS cnt FROM test_agg) WHERE cnt > 1L
+-- !query schema
+struct<cnt:bigint>
+-- !query output
+10
+
+
+-- !query
+SELECT udf(count(*)) FROM test_agg WHERE count(*) > 1L
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "INVALID_WHERE_CONDITION",
+ "sqlState" : "42903",
+ "messageParameters" : {
+ "condition" : "\"(count(1) > 1)\"",
+ "expressionList" : "count(1)"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 1,
+ "stopIndex" : 54,
+ "fragment" : "SELECT udf(count(*)) FROM test_agg WHERE count(*) > 1L"
+ } ]
+}
+
+
+-- !query
+SELECT udf(count(*)) FROM test_agg WHERE count(*) + 1L > 1L
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "INVALID_WHERE_CONDITION",
+ "sqlState" : "42903",
+ "messageParameters" : {
+ "condition" : "\"((count(1) + 1) > 1)\"",
+ "expressionList" : "count(1)"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 1,
+ "stopIndex" : 59,
+ "fragment" : "SELECT udf(count(*)) FROM test_agg WHERE count(*) + 1L > 1L"
+ } ]
+}
+
+
+-- !query
+SELECT udf(count(*)) FROM test_agg WHERE k = 1 or k = 2 or count(*) + 1L > 1L or max(k) > 1
+-- !query schema
+struct<>
+-- !query output
+org.apache.spark.sql.AnalysisException
+{
+ "errorClass" : "INVALID_WHERE_CONDITION",
+ "sqlState" : "42903",
+ "messageParameters" : {
+ "condition" : "\"(((k = 1) OR (k = 2)) OR (((count(1) + 1) > 1) OR (max(k) > 1)))\"",
+ "expressionList" : "count(1), max(test_agg.k)"
+ },
+ "queryContext" : [ {
+ "objectType" : "",
+ "objectName" : "",
+ "startIndex" : 1,
+ "stopIndex" : 91,
+ "fragment" : "SELECT udf(count(*)) FROM test_agg WHERE k = 1 or k = 2 or count(*) + 1L > 1L or max(k) > 1"
+ } ]
+}
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/array.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/array.sql
new file mode 100644
index 0000000000..865dc8bac4
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/array.sql
@@ -0,0 +1,183 @@
+-- test cases for array functions
+
+create temporary view data as select * from values
+ ("one", array(11, 12, 13), array(array(111, 112, 113), array(121, 122, 123))),
+ ("two", array(21, 22, 23), array(array(211, 212, 213), array(221, 222, 223)))
+ as data(a, b, c);
+
+select * from data;
+
+-- index into array
+select a, b[0], b[0] + b[1] from data;
+
+-- index into array of arrays
+select a, c[0][0] + c[0][0 + 1] from data;
+
+
+create temporary view primitive_arrays as select * from values (
+ array(true),
+ array(2Y, 1Y),
+ array(2S, 1S),
+ array(2, 1),
+ array(2L, 1L),
+ array(9223372036854775809, 9223372036854775808),
+ array(2.0D, 1.0D),
+ array(float(2.0), float(1.0)),
+ array(date '2016-03-14', date '2016-03-13'),
+ array(timestamp '2016-11-15 20:54:00.000', timestamp '2016-11-12 20:54:00.000')
+) as primitive_arrays(
+ boolean_array,
+ tinyint_array,
+ smallint_array,
+ int_array,
+ bigint_array,
+ decimal_array,
+ double_array,
+ float_array,
+ date_array,
+ timestamp_array
+);
+
+select * from primitive_arrays;
+
+-- array_contains on all primitive types: result should alternate between true and false
+select
+ array_contains(boolean_array, true), array_contains(boolean_array, false),
+ array_contains(tinyint_array, 2Y), array_contains(tinyint_array, 0Y),
+ array_contains(smallint_array, 2S), array_contains(smallint_array, 0S),
+ array_contains(int_array, 2), array_contains(int_array, 0),
+ array_contains(bigint_array, 2L), array_contains(bigint_array, 0L),
+ array_contains(decimal_array, 9223372036854775809), array_contains(decimal_array, 1),
+ array_contains(double_array, 2.0D), array_contains(double_array, 0.0D),
+ array_contains(float_array, float(2.0)), array_contains(float_array, float(0.0)),
+ array_contains(date_array, date '2016-03-14'), array_contains(date_array, date '2016-01-01'),
+ array_contains(timestamp_array, timestamp '2016-11-15 20:54:00.000'), array_contains(timestamp_array, timestamp '2016-01-01 20:54:00.000')
+from primitive_arrays;
+
+-- array_contains on nested arrays
+select array_contains(b, 11), array_contains(c, array(111, 112, 113)) from data;
+
+-- sort_array
+select
+ sort_array(boolean_array),
+ sort_array(tinyint_array),
+ sort_array(smallint_array),
+ sort_array(int_array),
+ sort_array(bigint_array),
+ sort_array(decimal_array),
+ sort_array(double_array),
+ sort_array(float_array),
+ sort_array(date_array),
+ sort_array(timestamp_array)
+from primitive_arrays;
+
+-- sort_array with an invalid string literal for the argument of sort order.
+select sort_array(array('b', 'd'), '1');
+
+-- sort_array with an invalid null literal casted as boolean for the argument of sort order.
+select sort_array(array('b', 'd'), cast(NULL as boolean));
+
+-- size
+select
+ size(boolean_array),
+ size(tinyint_array),
+ size(smallint_array),
+ size(int_array),
+ size(bigint_array),
+ size(decimal_array),
+ size(double_array),
+ size(float_array),
+ size(date_array),
+ size(timestamp_array)
+from primitive_arrays;
+
+-- index out of range for array elements
+select element_at(array(1, 2, 3), 5);
+select element_at(array(1, 2, 3), -5);
+select element_at(array(1, 2, 3), 0);
+
+select elt(4, '123', '456');
+select elt(0, '123', '456');
+select elt(-1, '123', '456');
+select elt(null, '123', '456');
+select elt(null, '123', null);
+select elt(1, '123', null);
+select elt(2, '123', null);
+
+select array(1, 2, 3)[5];
+select array(1, 2, 3)[-1];
+
+-- array_size
+select array_size(array());
+select array_size(array(true));
+select array_size(array(2, 1));
+select array_size(NULL);
+select array_size(map('a', 1, 'b', 2));
+
+-- size(arrays_zip)
+select size(arrays_zip(array(1, 2, 3), array(4), array(7, 8, 9, 10)));
+select size(arrays_zip(array(), array(1, 2, 3), array(4), array(7, 8, 9, 10)));
+select size(arrays_zip(array(1, 2, 3), array(4), null, array(7, 8, 9, 10)));
+
+-- isnotnull(arrays_zip)
+select isnotnull(arrays_zip(array(), array(4), array(7, 8, 9, 10)));
+select isnotnull(arrays_zip(array(1, 2, 3), array(4), array(7, 8, 9, 10)));
+select isnotnull(arrays_zip(array(1, 2, 3), NULL, array(4), array(7, 8, 9, 10)));
+
+-- function get()
+select get(array(1, 2, 3), 0);
+select get(array(1, 2, 3), 3);
+select get(array(1, 2, 3), null);
+select get(array(1, 2, 3), -1);
+
+-- function array_insert()
+select array_insert(array(1, 2, 3), 3, 4);
+select array_insert(array(2, 3, 4), 0, 1);
+select array_insert(array(2, 3, 4), 1, 1);
+select array_insert(array(1, 3, 4), -2, 2);
+select array_insert(array(1, 2, 3), 3, "4");
+select array_insert(cast(NULL as ARRAY<INT>), 1, 1);
+select array_insert(array(1, 2, 3, NULL), cast(NULL as INT), 4);
+select array_insert(array(1, 2, 3, NULL), 4, cast(NULL as INT));
+select array_insert(array(2, 3, NULL, 4), 5, 5);
+select array_insert(array(2, 3, NULL, 4), -5, 1);
+select array_insert(array(1), 2, cast(2 as tinyint));
+
+set spark.sql.legacy.negativeIndexInArrayInsert=true;
+select array_insert(array(1, 3, 4), -2, 2);
+select array_insert(array(2, 3, NULL, 4), -5, 1);
+set spark.sql.legacy.negativeIndexInArrayInsert=false;
+
+-- function array_compact
+select array_compact(id) from values (1) as t(id);
+select array_compact(array("1", null, "2", null));
+select array_compact(array("a", "b", "c"));
+select array_compact(array(1D, null, 2D, null));
+select array_compact(array(array(1, 2, 3, null), null, array(4, null, 6)));
+select array_compact(array(null));
+
+-- function array_append
+select array_append(array(1, 2, 3), 4);
+select array_append(array('a', 'b', 'c'), 'd');
+select array_append(array(1, 2, 3, NULL), NULL);
+select array_append(array('a', 'b', 'c', NULL), NULL);
+select array_append(CAST(null AS ARRAY<String>), 'a');
+select array_append(CAST(null AS ARRAY<String>), CAST(null as String));
+select array_append(array(), 1);
+select array_append(CAST(array() AS ARRAY<String>), CAST(NULL AS String));
+select array_append(array(CAST(NULL AS String)), CAST(NULL AS String));
+
+-- function array_prepend
+select array_prepend(array(1, 2, 3), 4);
+select array_prepend(array('a', 'b', 'c'), 'd');
+select array_prepend(array(1, 2, 3, NULL), NULL);
+select array_prepend(array('a', 'b', 'c', NULL), NULL);
+select array_prepend(CAST(null AS ARRAY<String>), 'a');
+select array_prepend(CAST(null AS ARRAY<String>), CAST(null as String));
+select array_prepend(array(), 1);
+select array_prepend(CAST(array() AS ARRAY<String>), CAST(NULL AS String));
+select array_prepend(array(CAST(NULL AS String)), CAST(NULL AS String));
+
+-- SPARK-45599: Confirm 0.0, -0.0, and NaN are handled appropriately.
+select array_union(array(0.0, -0.0, DOUBLE("NaN")), array(0.0, -0.0, DOUBLE("NaN")));
+select array_distinct(array(0.0, -0.0, -0.0, DOUBLE("NaN"), DOUBLE("NaN")));
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/binary.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/binary.sql
new file mode 100644
index 0000000000..8da97e4663
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/binary.sql
@@ -0,0 +1,8 @@
+--SET spark.sql.binaryOutputStyle=UTF-8
+
+SELECT X'';
+SELECT X'4561736F6E2059616F20323031382D31312D31373A31333A33333A3333';
+SELECT CAST('Spark' as BINARY);
+SELECT array( X'', X'4561736F6E2059616F20323031382D31312D31373A31333A33333A3333', CAST('Spark' as BINARY));
+SELECT to_csv(named_struct('n', 1, 'info', X'4561736F6E2059616F20323031382D31312D31373A31333A33333A3333'));
+select to_xml(named_struct('name', binary('Eason'), 'birth', 2018, 'org', binary('Kindergarten Cop')));
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/binary_base64.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/binary_base64.sql
new file mode 100644
index 0000000000..853eedd517
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/binary_base64.sql
@@ -0,0 +1,3 @@
+--IMPORT binary.sql
+
+--SET spark.sql.binaryOutputStyle=BASE64
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/binary_basic.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/binary_basic.sql
new file mode 100644
index 0000000000..1a5b64bdf7
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/binary_basic.sql
@@ -0,0 +1,4 @@
+--IMPORT binary.sql
+
+--SET spark.sql.binaryOutputStyle=BASIC
+
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/binary_hex.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/binary_hex.sql
new file mode 100644
index 0000000000..7863da737a
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/binary_hex.sql
@@ -0,0 +1,3 @@
+--IMPORT binary.sql
+
+--SET spark.sql.binaryOutputStyle=HEX
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/binary_hex_discrete.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/binary_hex_discrete.sql
new file mode 100644
index 0000000000..282a7634cb
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/binary_hex_discrete.sql
@@ -0,0 +1,3 @@
+--IMPORT binary.sql
+
+--SET spark.sql.binaryOutputStyle=HEX_DISCRETE
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/bitwise.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/bitwise.sql
new file mode 100644
index 0000000000..e080fdd32a
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/bitwise.sql
@@ -0,0 +1,93 @@
+-- test cases for bitwise functions
+
+-- null
+select bit_count(null);
+
+-- boolean
+select bit_count(true);
+select bit_count(false);
+
+-- byte/tinyint
+select bit_count(cast(1 as tinyint));
+select bit_count(cast(2 as tinyint));
+select bit_count(cast(3 as tinyint));
+
+-- short/smallint
+select bit_count(1S);
+select bit_count(2S);
+select bit_count(3S);
+
+-- int
+select bit_count(1);
+select bit_count(2);
+select bit_count(3);
+
+-- long/bigint
+select bit_count(1L);
+select bit_count(2L);
+select bit_count(3L);
+
+-- negative num
+select bit_count(-1L);
+
+-- edge value
+select bit_count(9223372036854775807L);
+select bit_count(-9223372036854775808L);
+
+-- other illegal arguments
+select bit_count("bit count");
+select bit_count('a');
+
+-- test for bit_xor
+--
+CREATE OR REPLACE TEMPORARY VIEW bitwise_test AS SELECT * FROM VALUES
+ (1, 1, 1, 1L),
+ (2, 3, 4, null),
+ (7, 7, 7, 3L) AS bitwise_test(b1, b2, b3, b4);
+
+-- empty case
+SELECT BIT_XOR(b3) AS n1 FROM bitwise_test where 1 = 0;
+
+-- null case
+SELECT BIT_XOR(b4) AS n1 FROM bitwise_test where b4 is null;
+
+-- the suffix numbers show the expected answer
+SELECT
+ BIT_XOR(cast(b1 as tinyint)) AS a4,
+ BIT_XOR(cast(b2 as smallint)) AS b5,
+ BIT_XOR(b3) AS c2,
+ BIT_XOR(b4) AS d2,
+ BIT_XOR(distinct b4) AS e2
+FROM bitwise_test;
+
+-- group by
+SELECT bit_xor(b3) FROM bitwise_test GROUP BY b1 & 1;
+
+--having
+SELECT b1, bit_xor(b2) FROM bitwise_test GROUP BY b1 HAVING bit_and(b2) < 7;
+
+-- window
+SELECT b1, b2, bit_xor(b2) OVER (PARTITION BY b1 ORDER BY b2) FROM bitwise_test;
+
+-- getbit
+select getbit(11L, 3), getbit(11L, 2), getbit(11L, 1), getbit(11L, 0);
+select getbit(11L, 2 + 1), getbit(11L, 3 - 1), getbit(10L + 1, 1 * 1), getbit(cast(11L / 1 AS long), 1 - 1);
+select getbit(11L, 63);
+select getbit(11L, -1);
+select getbit(11L, 64);
+
+SELECT 20181117 >> 2;
+SELECT 20181117 << 2;
+SELECT 20181117 >>> 2;
+SELECT 20181117 > > 2;
+SELECT 20181117 < < 2;
+SELECT 20181117 > >> 2;
+SELECT 20181117 <<< 2;
+SELECT 20181117 >>>> 2;
+select cast(null as array<array<int>>), 20181117 >> 2;
+select cast(null as array<array<int>>), 20181117 >>> 2;
+select cast(null as map<int, array<int>>), 20181117 >> 2;
+
+select 1 << 1 + 2 as plus_over_shift; -- if correct, the result is 8. otherwise, 4
+select 2 >> 1 << 1 as left_to_right; -- if correct, the result is 2. otherwise, 0
+select 1 & 2 >> 1 as shift_over_ampersand; -- if correct, the result is 1. otherwise, 0
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cast.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cast.sql
new file mode 100644
index 0000000000..2bf53f9730
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cast.sql
@@ -0,0 +1,179 @@
+-- cast string representing a valid fractional number to integral should truncate the number
+SELECT CAST('1.23' AS int);
+SELECT CAST('1.23' AS long);
+SELECT CAST('-4.56' AS int);
+SELECT CAST('-4.56' AS long);
+
+-- cast string which are not numbers to numeric types
+SELECT CAST('abc' AS int);
+SELECT CAST('abc' AS long);
+SELECT CAST('abc' AS float);
+SELECT CAST('abc' AS double);
+
+-- cast string representing a very large number to integral should return null
+SELECT CAST('1234567890123' AS int);
+SELECT CAST('12345678901234567890123' AS long);
+
+-- cast empty string to integral should return null
+SELECT CAST('' AS int);
+SELECT CAST('' AS long);
+SELECT CAST('' AS float);
+SELECT CAST('' AS double);
+
+-- cast null to integral should return null
+SELECT CAST(NULL AS int);
+SELECT CAST(NULL AS long);
+
+-- cast invalid decimal string to numeric types
+SELECT CAST('123.a' AS int);
+SELECT CAST('123.a' AS long);
+SELECT CAST('123.a' AS float);
+SELECT CAST('123.a' AS double);
+
+-- '-2147483648' is the smallest int value
+SELECT CAST('-2147483648' AS int);
+SELECT CAST('-2147483649' AS int);
+
+-- '2147483647' is the largest int value
+SELECT CAST('2147483647' AS int);
+SELECT CAST('2147483648' AS int);
+
+-- '-9223372036854775808' is the smallest long value
+SELECT CAST('-9223372036854775808' AS long);
+SELECT CAST('-9223372036854775809' AS long);
+
+-- '9223372036854775807' is the largest long value
+SELECT CAST('9223372036854775807' AS long);
+SELECT CAST('9223372036854775808' AS long);
+
+-- cast string to its binary representation
+SELECT HEX(CAST('abc' AS binary));
+
+-- cast integral values to their corresponding binary representation
+SELECT HEX(CAST(CAST(123 AS byte) AS binary));
+SELECT HEX(CAST(CAST(-123 AS byte) AS binary));
+SELECT HEX(CAST(123S AS binary));
+SELECT HEX(CAST(-123S AS binary));
+SELECT HEX(CAST(123 AS binary));
+SELECT HEX(CAST(-123 AS binary));
+SELECT HEX(CAST(123L AS binary));
+SELECT HEX(CAST(-123L AS binary));
+
+DESC FUNCTION boolean;
+DESC FUNCTION EXTENDED boolean;
+-- TODO: migrate all cast tests here.
+
+-- cast string to interval and interval to string
+SELECT CAST('interval 3 month 1 hour' AS interval);
+SELECT CAST("interval '3-1' year to month" AS interval year to month);
+SELECT CAST("interval '3 00:00:01' day to second" AS interval day to second);
+SELECT CAST(interval 3 month 1 hour AS string);
+SELECT CAST(interval 3 year 1 month AS string);
+SELECT CAST(interval 3 day 1 second AS string);
+
+-- trim string before cast to numeric
+select cast(' 1' as tinyint);
+select cast(' 1\t' as tinyint);
+select cast(' 1' as smallint);
+select cast(' 1' as INT);
+select cast(' 1' as bigint);
+select cast(' 1' as float);
+select cast(' 1 ' as DOUBLE);
+select cast('1.0 ' as DEC);
+select cast('1中文' as tinyint);
+select cast('1中文' as smallint);
+select cast('1中文' as INT);
+select cast('中文1' as bigint);
+select cast('1中文' as bigint);
+
+-- trim string before cast to boolean
+select cast('\t\t true \n\r ' as boolean);
+select cast('\t\n false \t\r' as boolean);
+select cast('\t\n xyz \t\r' as boolean);
+
+select cast('23.45' as decimal(4, 2));
+select cast('123.45' as decimal(4, 2));
+select cast('xyz' as decimal(4, 2));
+
+select cast('2022-01-01' as date);
+select cast('a' as date);
+select cast('2022-01-01 00:00:00' as timestamp);
+select cast('a' as timestamp);
+select cast('2022-01-01 00:00:00' as timestamp_ntz);
+select cast('a' as timestamp_ntz);
+
+select cast(cast('inf' as double) as timestamp);
+select cast(cast('inf' as float) as timestamp);
+
+-- cast ANSI intervals to integrals
+select cast(interval '1' year as tinyint);
+select cast(interval '-10-2' year to month as smallint);
+select cast(interval '1000' month as int);
+select cast(interval -'10.123456' second as tinyint);
+select cast(interval '23:59:59' hour to second as smallint);
+select cast(interval -'1 02:03:04.123' day to second as int);
+select cast(interval '10' day as bigint);
+
+select cast(interval '-1000' month as tinyint);
+select cast(interval '1000000' second as smallint);
+
+-- cast integrals to ANSI intervals
+select cast(1Y as interval year);
+select cast(-122S as interval year to month);
+select cast(ym as interval year to month) from values(-122S) as t(ym);
+select cast(1000 as interval month);
+select cast(-10L as interval second);
+select cast(100Y as interval hour to second);
+select cast(dt as interval hour to second) from values(100Y) as t(dt);
+select cast(-1000S as interval day to second);
+select cast(10 as interval day);
+
+select cast(2147483647 as interval year);
+select cast(-9223372036854775808L as interval day);
+
+-- cast ANSI intervals to decimals
+select cast(interval '-1' year as decimal(10, 0));
+select cast(interval '1.000001' second as decimal(10, 6));
+select cast(interval '08:11:10.001' hour to second as decimal(10, 4));
+select cast(interval '1 01:02:03.1' day to second as decimal(8, 1));
+select cast(interval '10.123' second as decimal(4, 2));
+select cast(interval '10.005' second as decimal(4, 2));
+select cast(interval '10.123' second as decimal(5, 2));
+select cast(interval '10.123' second as decimal(1, 0));
+
+-- cast decimals to ANSI intervals
+select cast(10.123456BD as interval day to second);
+select cast(80.654321BD as interval hour to minute);
+select cast(-10.123456BD as interval year to month);
+select cast(10.654321BD as interval month);
+
+-- cast double colon syntax tests
+SELECT '1.23' :: int;
+SELECT 'abc' :: int;
+SELECT '12345678901234567890123' :: long;
+SELECT '' :: int;
+SELECT NULL :: int;
+SELECT '123.a' :: int;
+SELECT '-2147483648' :: int;
+SELECT HEX('abc' :: binary);
+SELECT HEX((123 :: byte) :: binary);
+SELECT 'interval 3 month 1 hour' :: interval;
+SELECT interval 3 day 1 second :: string;
+select ' 1 ' :: DOUBLE;
+select '1.0 ' :: DEC;
+select '\t\t true \n\r ' :: boolean;
+select '2022-01-01 00:00:00' :: timestamp;
+select interval '-10-2' year to month :: smallint;
+select -10L :: interval second;
+select interval '08:11:10.001' hour to second :: decimal(10, 4);
+select 10.123456BD :: interval day to second;
+
+SELECT '1.23' :: int :: long;
+SELECT '2147483648' :: long :: int;
+SELECT CAST('2147483648' :: long AS int);
+SELECT map(1, '123', 2, '456')[1] :: int;
+
+-- cast double colon syntax negative tests
+SELECT '2147483648' :: BINT;
+SELECT '2147483648' :: SELECT;
+SELECT FALSE IS NOT NULL :: string;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/ceil-floor-with-scale-param.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/ceil-floor-with-scale-param.sql
new file mode 100644
index 0000000000..c05429b3ef
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/ceil-floor-with-scale-param.sql
@@ -0,0 +1,31 @@
+-- Tests different scenarios of ceil and floor functions with scale parameters
+SELECT CEIL(2.5, 0);
+SELECT CEIL(3.5, 0);
+SELECT CEIL(-2.5, 0);
+SELECT CEIL(-3.5, 0);
+SELECT CEIL(-0.35, 1);
+SELECT CEIL(-35, -1);
+SELECT CEIL(-0.1, 0);
+SELECT CEIL(5, 0);
+SELECT CEIL(3.14115, -3);
+SELECT CEIL(9.9, 0);
+SELECT CEIL(CAST(99 AS DECIMAL(2, 0)), -1);
+SELECT CEIL(2.5, null);
+SELECT CEIL(2.5, 'a');
+SELECT CEIL(2.5, 0, 0);
+
+-- Same inputs with floor function
+SELECT FLOOR(2.5, 0);
+SELECT FLOOR(3.5, 0);
+SELECT FLOOR(-2.5, 0);
+SELECT FLOOR(-3.5, 0);
+SELECT FLOOR(-0.35, 1);
+SELECT FLOOR(-35, -1);
+SELECT FLOOR(-0.1, 0);
+SELECT FLOOR(5, 0);
+SELECT FLOOR(3.14115, -3);
+SELECT FLOOR(-9.9, 0);
+SELECT FLOOR(CAST(-99 AS DECIMAL(2, 0)), -1);
+SELECT FLOOR(2.5, null);
+SELECT FLOOR(2.5, 'a');
+SELECT FLOOR(2.5, 0, 0);
\ No newline at end of file
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/change-column.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/change-column.sql
new file mode 100644
index 0000000000..2b57891cfc
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/change-column.sql
@@ -0,0 +1,49 @@
+-- Create the origin table
+CREATE TABLE test_change(a INT, b STRING, c INT) using parquet;
+DESC test_change;
+
+-- ALTER TABLE CHANGE COLUMN must change either type or comment
+ALTER TABLE test_change CHANGE a;
+DESC test_change;
+
+-- Change column name (not supported on v1 table)
+ALTER TABLE test_change RENAME COLUMN a TO a1;
+DESC test_change;
+
+-- Change column dataType (not supported yet)
+ALTER TABLE test_change CHANGE a TYPE STRING;
+DESC test_change;
+
+-- Change column position (not supported yet)
+ALTER TABLE test_change CHANGE a AFTER b;
+ALTER TABLE test_change CHANGE b FIRST;
+DESC test_change;
+
+-- Change column comment
+ALTER TABLE test_change CHANGE a COMMENT 'this is column a';
+ALTER TABLE test_change CHANGE b COMMENT '#*02?`';
+ALTER TABLE test_change CHANGE c COMMENT '';
+DESC test_change;
+
+-- Don't change anything.
+ALTER TABLE test_change CHANGE a TYPE INT;
+ALTER TABLE test_change CHANGE a COMMENT 'this is column a';
+DESC test_change;
+
+-- Change a invalid column
+ALTER TABLE test_change CHANGE invalid_col TYPE INT;
+DESC test_change;
+
+-- Check case insensitivity.
+ALTER TABLE test_change CHANGE A COMMENT 'case insensitivity';
+DESC test_change;
+
+-- Change column can't apply to a temporary/global_temporary view
+CREATE TEMPORARY VIEW temp_view(a, b) AS SELECT 1, "one";
+ALTER TABLE temp_view CHANGE a TYPE INT;
+CREATE GLOBAL TEMPORARY VIEW global_temp_view(a, b) AS SELECT 1, "one";
+ALTER TABLE global_temp.global_temp_view CHANGE a TYPE INT;
+
+-- DROP TEST TABLE
+DROP TABLE test_change;
+DROP VIEW global_temp.global_temp_view;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/charvarchar.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/charvarchar.sql
new file mode 100644
index 0000000000..f5b20f99c8
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/charvarchar.sql
@@ -0,0 +1,128 @@
+create table char_tbl(c char(5), v varchar(6)) using parquet;
+desc formatted char_tbl;
+desc formatted char_tbl c;
+show create table char_tbl;
+
+create table char_tbl2 using parquet as select * from char_tbl;
+show create table char_tbl2;
+desc formatted char_tbl2;
+desc formatted char_tbl2 c;
+
+create table char_tbl3 like char_tbl;
+desc formatted char_tbl3;
+desc formatted char_tbl3 c;
+show create table char_tbl3;
+
+create view char_view as select * from char_tbl;
+desc formatted char_view;
+desc formatted char_view c;
+show create table char_view;
+
+alter table char_tbl rename to char_tbl1;
+desc formatted char_tbl1;
+
+alter table char_tbl1 change column c type char(6);
+alter table char_tbl1 change column c type char(5);
+desc formatted char_tbl1;
+
+alter table char_tbl1 add columns (d char(5));
+desc formatted char_tbl1;
+
+alter view char_view as select * from char_tbl2;
+desc formatted char_view;
+
+alter table char_tbl1 SET TBLPROPERTIES('yes'='no');
+desc formatted char_tbl1;
+
+alter view char_view SET TBLPROPERTIES('yes'='no');
+desc formatted char_view;
+
+alter table char_tbl1 UNSET TBLPROPERTIES('yes');
+desc formatted char_tbl1;
+
+alter view char_view UNSET TBLPROPERTIES('yes');
+desc formatted char_view;
+
+alter table char_tbl1 SET SERDEPROPERTIES('yes'='no');
+desc formatted char_tbl1;
+
+create table char_part(c1 char(5), c2 char(2), v1 varchar(6), v2 varchar(2)) using parquet partitioned by (v2, c2);
+desc formatted char_part;
+
+alter table char_part change column c1 comment 'char comment';
+alter table char_part change column v1 comment 'varchar comment';
+alter table char_part add partition (v2='ke', c2='nt') location 'loc1';
+desc formatted char_part;
+
+alter table char_part partition (v2='ke') rename to partition (v2='nt');
+desc formatted char_part;
+
+alter table char_part partition (v2='ke', c2='nt') set location 'loc2';
+desc formatted char_part;
+
+MSCK REPAIR TABLE char_part;
+desc formatted char_part;
+
+create temporary view str_view as select c, v from values
+ (null, null),
+ (null, 'S'),
+ ('N', 'N '),
+ ('Ne', 'Sp'),
+ ('Net ', 'Spa '),
+ ('NetE', 'Spar'),
+ ('NetEa ', 'Spark '),
+ ('NetEas ', 'Spark'),
+ ('NetEase', 'Spark-') t(c, v);
+
+create table char_tbl4(c7 char(7), c8 char(8), v varchar(6), s string) using parquet;
+insert into char_tbl4 select c, c, v, c from str_view;
+
+select c7, c8, v, s from char_tbl4;
+select c7, c8, v, s from char_tbl4 where c7 = c8;
+select c7, c8, v, s from char_tbl4 where c7 = v;
+select c7, c8, v, s from char_tbl4 where c7 = s;
+select c7, c8, v, s from char_tbl4 where c7 = 'NetEase ';
+select c7, c8, v, s from char_tbl4 where v = 'Spark ';
+select c7, c8, v, s from char_tbl4 order by c7;
+select c7, c8, v, s from char_tbl4 order by v;
+
+select ascii(c7), ascii(c8), ascii(v), ascii(s) from char_tbl4;
+select base64(c7), base64(c8), base64(v), ascii(s) from char_tbl4;
+select bit_length(c7), bit_length(c8), bit_length(v), bit_length(s) from char_tbl4;
+select char_length(c7), char_length(c8), char_length(v), char_length(s) from char_tbl4;
+select octet_length(c7), octet_length(c8), octet_length(v), octet_length(s) from char_tbl4;
+select concat_ws('|', c7, c8), concat_ws('|', c7, v), concat_ws('|', c7, s), concat_ws('|', v, s) from char_tbl4;
+select concat(c7, c8), concat(c7, v), concat(c7, s), concat(v, s) from char_tbl4;
+select like(c7, 'Ne _'), like(c8, 'Ne _') from char_tbl4;
+select like(v, 'Spark_') from char_tbl4;
+select c7 = c8, upper(c7) = upper(c8), lower(c7) = lower(c8) from char_tbl4 where s = 'NetEase';
+select c7 = s, upper(c7) = upper(s), lower(c7) = lower(s) from char_tbl4 where s = 'NetEase';
+select c7 = 'NetEase', upper(c7) = upper('NetEase'), lower(c7) = lower('NetEase') from char_tbl4 where s = 'NetEase';
+select printf('Hey, %s%s%s%s', c7, c8, v, s) from char_tbl4;
+select repeat(c7, 2), repeat(c8, 2), repeat(v, 2), repeat(s, 2) from char_tbl4;
+select replace(c7, 'Net', 'Apache'), replace(c8, 'Net', 'Apache'), replace(v, 'Spark', 'Kyuubi'), replace(s, 'Net', 'Apache') from char_tbl4;
+select rpad(c7, 10), rpad(c8, 5), rpad(v, 5), rpad(s, 5) from char_tbl4;
+select rtrim(c7), rtrim(c8), rtrim(v), rtrim(s) from char_tbl4;
+select split(c7, 'e'), split(c8, 'e'), split(v, 'a'), split(s, 'e') from char_tbl4;
+select substring(c7, 2), substring(c8, 2), substring(v, 3), substring(s, 2) from char_tbl4;
+select left(c7, 2), left(c8, 2), left(v, 3), left(s, 2) from char_tbl4;
+select right(c7, 2), right(c8, 2), right(v, 3), right(s, 2) from char_tbl4;
+set spark.sql.optimizer.excludedRules=org.apache.spark.sql.catalyst.optimizer.ConvertToLocalRelation,org.apache.spark.sql.catalyst.optimizer.NullPropagation;
+select typeof(c7), typeof(c8), typeof(v), typeof(s) from char_tbl4 limit 1;
+set spark.sql.optimizer.excludedRules=org.apache.spark.sql.catalyst.optimizer.ConvertToLocalRelation,org.apache.spark.sql.catalyst.optimizer.ConstantFolding,org.apache.spark.sql.catalyst.optimizer.NullPropagation;
+select cast(c7 as char(1)), cast(c8 as char(10)), cast(v as char(1)), cast(v as varchar(1)), cast(s as char(5)) from char_tbl4;
+
+-- char_tbl has renamed to char_tbl1
+drop table char_tbl1;
+drop table char_tbl2;
+drop table char_tbl3;
+drop table char_tbl4;
+
+-- ascii value for Latin-1 Supplement characters
+select ascii('§'), ascii('÷'), ascii('×10');
+select chr(167), chr(247), chr(215);
+
+-- to_varchar is an alias for to_char
+SELECT to_varchar(78.12, '$99.99');
+SELECT to_varchar(111.11, '99.9');
+SELECT to_varchar(12454.8, '99,999.9S');
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/collations.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/collations.sql
new file mode 100644
index 0000000000..17815ed5dd
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/collations.sql
@@ -0,0 +1,527 @@
+-- test cases for collation support
+
+-- Create a test table with data
+create table t1(utf8_binary string collate utf8_binary, utf8_lcase string collate utf8_lcase) using parquet;
+insert into t1 values('aaa', 'aaa');
+insert into t1 values('AAA', 'AAA');
+insert into t1 values('bbb', 'bbb');
+insert into t1 values('BBB', 'BBB');
+
+-- describe
+describe table t1;
+
+-- group by and count utf8_binary
+select count(*) from t1 group by utf8_binary;
+
+-- group by and count utf8_lcase
+select count(*) from t1 group by utf8_lcase;
+
+-- filter equal utf8_binary
+select * from t1 where utf8_binary = 'aaa';
+
+-- filter equal utf8_lcase
+select * from t1 where utf8_lcase = 'aaa' collate utf8_lcase;
+
+-- filter less then utf8_binary
+select * from t1 where utf8_binary < 'bbb';
+
+-- filter less then utf8_lcase
+select * from t1 where utf8_lcase < 'bbb' collate utf8_lcase;
+
+-- inner join
+select l.utf8_binary, r.utf8_lcase from t1 l join t1 r on l.utf8_lcase = r.utf8_lcase;
+
+-- create second table for anti-join
+create table t2(utf8_binary string collate utf8_binary, utf8_lcase string collate utf8_lcase) using parquet;
+insert into t2 values('aaa', 'aaa');
+insert into t2 values('bbb', 'bbb');
+
+-- anti-join on lcase
+select * from t1 anti join t2 on t1.utf8_lcase = t2.utf8_lcase;
+
+drop table t2;
+drop table t1;
+
+-- set operations
+select col1 collate utf8_lcase from values ('aaa'), ('AAA'), ('bbb'), ('BBB'), ('zzz'), ('ZZZ') except select col1 collate utf8_lcase from values ('aaa'), ('bbb');
+select col1 collate utf8_lcase from values ('aaa'), ('AAA'), ('bbb'), ('BBB'), ('zzz'), ('ZZZ') except all select col1 collate utf8_lcase from values ('aaa'), ('bbb');
+select col1 collate utf8_lcase from values ('aaa'), ('AAA'), ('bbb'), ('BBB'), ('zzz'), ('ZZZ') union select col1 collate utf8_lcase from values ('aaa'), ('bbb');
+select col1 collate utf8_lcase from values ('aaa'), ('AAA'), ('bbb'), ('BBB'), ('zzz'), ('ZZZ') union all select col1 collate utf8_lcase from values ('aaa'), ('bbb');
+select col1 collate utf8_lcase from values ('aaa'), ('bbb'), ('BBB'), ('zzz'), ('ZZZ') intersect select col1 collate utf8_lcase from values ('aaa'), ('bbb');
+
+-- set operations with conflicting collations
+select col1 collate utf8_lcase from values ('aaa'), ('AAA'), ('bbb'), ('BBB'), ('zzz'), ('ZZZ') except select col1 collate unicode_ci from values ('aaa'), ('bbb');
+select col1 collate utf8_lcase from values ('aaa'), ('AAA'), ('bbb'), ('BBB'), ('zzz'), ('ZZZ') except all select col1 collate unicode_ci from values ('aaa'), ('bbb');
+select col1 collate utf8_lcase from values ('aaa'), ('AAA'), ('bbb'), ('BBB'), ('zzz'), ('ZZZ') union select col1 collate unicode_ci from values ('aaa'), ('bbb');
+select col1 collate utf8_lcase from values ('aaa'), ('AAA'), ('bbb'), ('BBB'), ('zzz'), ('ZZZ') union all select col1 collate unicode_ci from values ('aaa'), ('bbb');
+select col1 collate utf8_lcase from values ('aaa'), ('bbb'), ('BBB'), ('zzz'), ('ZZZ') intersect select col1 collate unicode_ci from values ('aaa'), ('bbb');
+
+-- create table with struct field
+create table t1 (c1 struct<utf8_binary: string collate utf8_binary, utf8_lcase: string collate utf8_lcase>) USING PARQUET;
+
+insert into t1 values (named_struct('utf8_binary', 'aaa', 'utf8_lcase', 'aaa'));
+insert into t1 values (named_struct('utf8_binary', 'AAA', 'utf8_lcase', 'AAA'));
+
+-- aggregate against nested field utf8_binary
+select count(*) from t1 group by c1.utf8_binary;
+
+-- aggregate against nested field utf8_lcase
+select count(*) from t1 group by c1.utf8_lcase;
+
+drop table t1;
+
+-- array function tests
+select array_contains(ARRAY('aaa' collate utf8_lcase),'AAA' collate utf8_lcase);
+select array_position(ARRAY('aaa' collate utf8_lcase, 'bbb' collate utf8_lcase),'BBB' collate utf8_lcase);
+
+-- utility
+select nullif('aaa' COLLATE utf8_lcase, 'AAA' COLLATE utf8_lcase);
+select least('aaa' COLLATE utf8_lcase, 'AAA' collate utf8_lcase, 'a' collate utf8_lcase);
+
+-- array operations
+select arrays_overlap(array('aaa' collate utf8_lcase), array('AAA' collate utf8_lcase));
+select array_distinct(array('aaa' collate utf8_lcase, 'AAA' collate utf8_lcase));
+select array_union(array('aaa' collate utf8_lcase), array('AAA' collate utf8_lcase));
+select array_intersect(array('aaa' collate utf8_lcase), array('AAA' collate utf8_lcase));
+select array_except(array('aaa' collate utf8_lcase), array('AAA' collate utf8_lcase));
+
+-- ICU collations (all statements return true)
+select 'a' collate unicode < 'A';
+select 'a' collate unicode_ci = 'A';
+select 'a' collate unicode_ai = 'å';
+select 'a' collate unicode_ci_ai = 'Å';
+select 'a' collate en < 'A';
+select 'a' collate en_ci = 'A';
+select 'a' collate en_ai = 'å';
+select 'a' collate en_ci_ai = 'Å';
+select 'Kypper' collate sv < 'Köpfe';
+select 'Kypper' collate de > 'Köpfe';
+select 'I' collate tr_ci = 'ı';
+
+-- create table for str_to_map
+create table t4 (text string collate utf8_binary, pairDelim string collate utf8_lcase, keyValueDelim string collate utf8_binary) using parquet;
+
+insert into t4 values('a:1,b:2,c:3', ',', ':');
+
+select str_to_map(text, pairDelim, keyValueDelim) from t4;
+select str_to_map(text collate utf8_binary, pairDelim collate utf8_lcase, keyValueDelim collate utf8_binary) from t4;
+select str_to_map(text collate utf8_binary, pairDelim collate utf8_binary, keyValueDelim collate utf8_binary) from t4;
+select str_to_map(text collate unicode_ai, pairDelim collate unicode_ai, keyValueDelim collate unicode_ai) from t4;
+
+drop table t4;
+
+create table t5(s string, utf8_binary string collate utf8_binary, utf8_lcase string collate utf8_lcase) using parquet;
+insert into t5 values ('Spark', 'Spark', 'SQL');
+insert into t5 values ('aaAaAAaA', 'aaAaAAaA', 'aaAaAAaA');
+insert into t5 values ('aaAaAAaA', 'aaAaAAaA', 'aaAaaAaA');
+insert into t5 values ('aaAaAAaA', 'aaAaAAaA', 'aaAaaAaAaaAaaAaAaaAaaAaA');
+insert into t5 values ('bbAbaAbA', 'bbAbAAbA', 'a');
+insert into t5 values ('İo', 'İo', 'İo');
+insert into t5 values ('İo', 'İo', 'İo ');
+insert into t5 values ('İo', 'İo ', 'İo');
+insert into t5 values ('İo', 'İo', 'i̇o');
+insert into t5 values ('efd2', 'efd2', 'efd2');
+insert into t5 values ('Hello, world! Nice day.', 'Hello, world! Nice day.', 'Hello, world! Nice day.');
+insert into t5 values ('Something else. Nothing here.', 'Something else. Nothing here.', 'Something else. Nothing here.');
+insert into t5 values ('kitten', 'kitten', 'sitTing');
+insert into t5 values ('abc', 'abc', 'abc');
+insert into t5 values ('abcdcba', 'abcdcba', 'aBcDCbA');
+
+create table t6(ascii long) using parquet;
+insert into t6 values (97);
+insert into t6 values (66);
+
+create table t7(ascii double) using parquet;
+insert into t7 values (97.52143);
+insert into t7 values (66.421);
+
+create table t8(format string collate utf8_binary, utf8_binary string collate utf8_binary, utf8_lcase string collate utf8_lcase) using parquet;
+insert into t8 values ('%s%s', 'abCdE', 'abCdE');
+
+create table t9(num long) using parquet;
+insert into t9 values (97);
+insert into t9 values (66);
+
+create table t10(utf8_binary string collate utf8_binary, utf8_lcase string collate utf8_lcase) using parquet;
+insert into t10 values ('aaAaAAaA', 'aaAaaAaA');
+insert into t10 values ('efd2', 'efd2');
+
+-- ConcatWs
+select concat_ws(' ', utf8_lcase, utf8_lcase) from t5;
+select concat_ws(' ', utf8_binary, utf8_lcase) from t5;
+select concat_ws(' ' collate utf8_binary, utf8_binary, 'SQL' collate utf8_lcase) from t5;
+select concat_ws(' ' collate utf8_lcase, utf8_binary, 'SQL' collate utf8_lcase) from t5;
+select concat_ws(',', utf8_lcase, 'word'), concat_ws(',', utf8_binary, 'word') from t5;
+select concat_ws(',', utf8_lcase, 'word' collate utf8_binary), concat_ws(',', utf8_binary, 'word' collate utf8_lcase) from t5;
+
+-- Elt
+select elt(2, s, utf8_binary) from t5;
+select elt(2, utf8_binary, utf8_lcase, s) from t5;
+select elt(1, utf8_binary collate utf8_binary, utf8_lcase collate utf8_lcase) from t5;
+select elt(1, utf8_binary collate utf8_binary, utf8_lcase collate utf8_binary) from t5;
+select elt(1, utf8_binary collate utf8_binary, utf8_lcase) from t5;
+select elt(1, utf8_binary, 'word'), elt(1, utf8_lcase, 'word') from t5;
+select elt(1, utf8_binary, 'word' collate utf8_lcase), elt(1, utf8_lcase, 'word' collate utf8_binary) from t5;
+
+-- SplitPart
+select split_part(utf8_binary, utf8_lcase, 3) from t5;
+select split_part(s, utf8_binary, 1) from t5;
+select split_part(utf8_binary collate utf8_binary, s collate utf8_lcase, 1) from t5;
+select split_part(utf8_binary, utf8_lcase collate utf8_binary, 2) from t5;
+select split_part(utf8_binary collate utf8_lcase, utf8_lcase collate utf8_lcase, 2) from t5;
+select split_part(utf8_binary collate unicode_ai, utf8_lcase collate unicode_ai, 2) from t5;
+select split_part(utf8_binary, 'a', 3), split_part(utf8_lcase, 'a', 3) from t5;
+select split_part(utf8_binary, 'a' collate utf8_lcase, 3), split_part(utf8_lcase, 'a' collate utf8_binary, 3) from t5;
+select split_part(utf8_binary, 'a ' collate utf8_lcase_rtrim, 3), split_part(utf8_lcase, 'a' collate utf8_binary, 3) from t5;
+
+-- Contains
+select contains(utf8_binary, utf8_lcase) from t5;
+select contains(s, utf8_binary) from t5;
+select contains(utf8_binary collate utf8_binary, s collate utf8_lcase) from t5;
+select contains(utf8_binary, utf8_lcase collate utf8_binary) from t5;
+select contains(utf8_binary collate utf8_lcase, utf8_lcase collate utf8_lcase) from t5;
+select contains(utf8_binary collate unicode_ai, utf8_lcase collate unicode_ai) from t5;
+select contains(utf8_binary, 'a'), contains(utf8_lcase, 'a') from t5;
+select contains(utf8_binary, 'AaAA' collate utf8_lcase), contains(utf8_lcase, 'AAa' collate utf8_binary) from t5;
+select contains(utf8_binary, 'AaAA ' collate utf8_lcase_rtrim), contains(utf8_lcase, 'AAa ' collate utf8_binary_rtrim) from t5;
+
+-- SubstringIndex
+select substring_index(utf8_binary, utf8_lcase, 2) from t5;
+select substring_index(s, utf8_binary,1) from t5;
+select substring_index(utf8_binary collate utf8_binary, s collate utf8_lcase, 3) from t5;
+select substring_index(utf8_binary, utf8_lcase collate utf8_binary, 2) from t5;
+select substring_index(utf8_binary collate utf8_lcase, utf8_lcase collate utf8_lcase, 2) from t5;
+select substring_index(utf8_binary collate unicode_ai, utf8_lcase collate unicode_ai, 2) from t5;
+select substring_index(utf8_binary, 'a', 2), substring_index(utf8_lcase, 'a', 2) from t5;
+select substring_index(utf8_binary, 'AaAA' collate utf8_lcase, 2), substring_index(utf8_lcase, 'AAa' collate utf8_binary, 2) from t5;
+select substring_index(utf8_binary, 'AaAA ' collate utf8_lcase_rtrim, 2), substring_index(utf8_lcase, 'AAa' collate utf8_binary, 2) from t5;
+
+-- StringInStr
+select instr(utf8_binary, utf8_lcase) from t5;
+select instr(s, utf8_binary) from t5;
+select instr(utf8_binary collate utf8_binary, s collate utf8_lcase) from t5;
+select instr(utf8_binary, utf8_lcase collate utf8_binary) from t5;
+select instr(utf8_binary collate utf8_lcase, utf8_lcase collate utf8_lcase) from t5;
+select instr(utf8_binary collate unicode_ai, utf8_lcase collate unicode_ai) from t5;
+select instr(utf8_binary, 'a'), instr(utf8_lcase, 'a') from t5;
+select instr(utf8_binary, 'AaAA' collate utf8_lcase), instr(utf8_lcase, 'AAa' collate utf8_binary) from t5;
+
+-- FindInSet
+select find_in_set(utf8_binary, utf8_lcase) from t5;
+select find_in_set(s, utf8_binary) from t5;
+select find_in_set(utf8_binary collate utf8_binary, s collate utf8_lcase) from t5;
+select find_in_set(utf8_binary, utf8_lcase collate utf8_binary) from t5;
+select find_in_set(utf8_binary collate utf8_lcase, utf8_lcase collate utf8_lcase) from t5;
+select find_in_set(utf8_binary, 'aaAaaAaA,i̇o'), find_in_set(utf8_lcase, 'aaAaaAaA,i̇o') from t5;
+select find_in_set(utf8_binary, 'aaAaaAaA,i̇o' collate utf8_lcase), find_in_set(utf8_lcase, 'aaAaaAaA,i̇o' collate utf8_binary) from t5;
+select find_in_set(utf8_binary, 'aaAaaAaA,i̇o ' collate utf8_lcase_rtrim), find_in_set(utf8_lcase, 'aaAaaAaA,i̇o' collate utf8_binary) from t5;
+-- StartsWith
+select startswith(utf8_binary, utf8_lcase) from t5;
+select startswith(s, utf8_binary) from t5;
+select startswith(utf8_binary collate utf8_binary, s collate utf8_lcase) from t5;
+select startswith(utf8_binary, utf8_lcase collate utf8_binary) from t5;
+select startswith(utf8_binary collate utf8_lcase, utf8_lcase collate utf8_lcase) from t5;
+select startswith(utf8_binary collate unicode_ai, utf8_lcase collate unicode_ai) from t5;
+select startswith(utf8_binary, 'aaAaaAaA'), startswith(utf8_lcase, 'aaAaaAaA') from t5;
+select startswith(utf8_binary, 'aaAaaAaA' collate utf8_lcase), startswith(utf8_lcase, 'aaAaaAaA' collate utf8_binary) from t5;
+select startswith(utf8_binary, 'aaAaaAaA ' collate utf8_lcase_rtrim), startswith(utf8_lcase, 'aaAaaAaA' collate utf8_binary) from t5;
+
+-- StringTranslate
+select translate(utf8_lcase, utf8_lcase, '12345') from t5;
+select translate(utf8_binary, utf8_lcase, '12345') from t5;
+select translate(utf8_binary, 'aBc' collate utf8_lcase, '12345' collate utf8_binary) from t5;
+select translate(utf8_binary, 'SQL' collate utf8_lcase, '12345' collate utf8_lcase) from t5;
+select translate(utf8_binary, 'SQL' collate unicode_ai, '12345' collate unicode_ai) from t5;
+select translate(utf8_lcase, 'aaAaaAaA', '12345'), translate(utf8_binary, 'aaAaaAaA', '12345') from t5;
+select translate(utf8_lcase, 'aBc' collate utf8_binary, '12345'), translate(utf8_binary, 'aBc' collate utf8_lcase, '12345') from t5;
+select translate(utf8_lcase, 'aBc ' collate utf8_binary_rtrim, '12345'), translate(utf8_binary, 'aBc' collate utf8_lcase, '12345') from t5;
+
+-- Replace
+select replace(utf8_binary, utf8_lcase, 'abc') from t5;
+select replace(s, utf8_binary, 'abc') from t5;
+select replace(utf8_binary collate utf8_binary, s collate utf8_lcase, 'abc') from t5;
+select replace(utf8_binary, utf8_lcase collate utf8_binary, 'abc') from t5;
+select replace(utf8_binary collate utf8_lcase, utf8_lcase collate utf8_lcase, 'abc') from t5;
+select replace(utf8_binary collate unicode_ai, utf8_lcase collate unicode_ai, 'abc') from t5;
+select replace(utf8_binary, 'aaAaaAaA', 'abc'), replace(utf8_lcase, 'aaAaaAaA', 'abc') from t5;
+select replace(utf8_binary, 'aaAaaAaA' collate utf8_lcase, 'abc'), replace(utf8_lcase, 'aaAaaAaA' collate utf8_binary, 'abc') from t5;
+select replace(utf8_binary, 'aaAaaAaA ' collate utf8_lcase_rtrim, 'abc'), replace(utf8_lcase, 'aaAaaAaA' collate utf8_binary, 'abc') from t5;
+
+-- EndsWith
+select endswith(utf8_binary, utf8_lcase) from t5;
+select endswith(s, utf8_binary) from t5;
+select endswith(utf8_binary collate utf8_binary, s collate utf8_lcase) from t5;
+select endswith(utf8_binary, utf8_lcase collate utf8_binary) from t5;
+select endswith(utf8_binary collate utf8_lcase, utf8_lcase collate utf8_lcase) from t5;
+select endswith(utf8_binary collate unicode_ai, utf8_lcase collate unicode_ai) from t5;
+select endswith(utf8_binary, 'aaAaaAaA'), endswith(utf8_lcase, 'aaAaaAaA') from t5;
+select endswith(utf8_binary, 'aaAaaAaA' collate utf8_lcase), endswith(utf8_lcase, 'aaAaaAaA' collate utf8_binary) from t5;
+select endswith(utf8_binary, 'aaAaaAaA ' collate utf8_lcase_rtrim), endswith(utf8_lcase, 'aaAaaAaA' collate utf8_binary) from t5;
+
+-- StringRepeat
+select repeat(utf8_binary, 3), repeat(utf8_lcase, 2) from t5;
+select repeat(utf8_binary collate utf8_lcase, 3), repeat(utf8_lcase collate utf8_binary, 2) from t5;
+
+-- Ascii & UnBase64 string expressions
+select ascii(utf8_binary), ascii(utf8_lcase) from t5;
+select ascii(utf8_binary collate utf8_lcase), ascii(utf8_lcase collate utf8_binary) from t5;
+select unbase64(utf8_binary), unbase64(utf8_lcase) from t10;
+select unbase64(utf8_binary collate utf8_lcase), unbase64(utf8_lcase collate utf8_binary) from t10;
+
+-- Chr
+select chr(ascii) from t6;
+
+-- Base64, Decode
+select base64(utf8_binary), base64(utf8_lcase) from t5;
+select base64(utf8_binary collate utf8_lcase), base64(utf8_lcase collate utf8_binary) from t5;
+select decode(encode(utf8_binary, 'utf-8'), 'utf-8'), decode(encode(utf8_lcase, 'utf-8'), 'utf-8') from t5;
+select decode(encode(utf8_binary collate utf8_lcase, 'utf-8'), 'utf-8'), decode(encode(utf8_lcase collate utf8_binary, 'utf-8'), 'utf-8') from t5;
+
+-- FormatNumber
+select format_number(ascii, '###.###') from t7;
+select format_number(ascii, '###.###' collate utf8_lcase) from t7;
+
+-- Encode, ToBinary
+select encode(utf8_binary, 'utf-8'), encode(utf8_lcase, 'utf-8') from t5;
+select encode(utf8_binary collate utf8_lcase, 'utf-8'), encode(utf8_lcase collate utf8_binary, 'utf-8') from t5;
+select to_binary(utf8_binary, 'utf-8'), to_binary(utf8_lcase, 'utf-8') from t5;
+select to_binary(utf8_binary collate utf8_lcase, 'utf-8'), to_binary(utf8_lcase collate utf8_binary, 'utf-8') from t5;
+
+-- Sentences
+select sentences(utf8_binary), sentences(utf8_lcase) from t5;
+select sentences(utf8_binary collate utf8_lcase), sentences(utf8_lcase collate utf8_binary) from t5;
+
+-- Upper
+select upper(utf8_binary), upper(utf8_lcase) from t5;
+select upper(utf8_binary collate utf8_lcase), upper(utf8_lcase collate utf8_binary) from t5;
+
+-- Lower
+select lower(utf8_binary), lower(utf8_lcase) from t5;
+select lower(utf8_binary collate utf8_lcase), lower(utf8_lcase collate utf8_binary) from t5;
+
+-- InitCap
+select initcap(utf8_binary), initcap(utf8_lcase) from t5;
+select initcap(utf8_binary collate utf8_lcase), initcap(utf8_lcase collate utf8_binary) from t5;
+
+-- Overlay
+select overlay(utf8_binary, utf8_lcase, 2) from t5;
+select overlay(s, utf8_binary,1) from t5;
+select overlay(utf8_binary collate utf8_binary, s collate utf8_lcase, 3) from t5;
+select overlay(utf8_binary, utf8_lcase collate utf8_binary, 2) from t5;
+select overlay(utf8_binary collate utf8_lcase, utf8_lcase collate utf8_lcase, 2) from t5;
+select overlay(utf8_binary, 'a', 2), overlay(utf8_lcase, 'a', 2) from t5;
+select overlay(utf8_binary, 'AaAA' collate utf8_lcase, 2), overlay(utf8_lcase, 'AAa' collate utf8_binary, 2) from t5;
+
+-- FormatString
+select format_string(format, utf8_binary, utf8_lcase) from t8;
+select format_string(format collate utf8_lcase, utf8_lcase, utf8_binary collate utf8_lcase, 3), format_string(format, utf8_lcase collate utf8_binary, utf8_binary) from t8;
+select format_string(format, utf8_binary, utf8_lcase) from t8;
+
+-- SoundEx
+select soundex(utf8_binary), soundex(utf8_lcase) from t5;
+select soundex(utf8_binary collate utf8_lcase), soundex(utf8_lcase collate utf8_binary) from t5;
+
+-- Length, BitLength & OctetLength
+select length(utf8_binary), length(utf8_lcase) from t5;
+select length(utf8_binary collate utf8_lcase), length(utf8_lcase collate utf8_binary) from t5;
+select bit_length(utf8_binary), bit_length(utf8_lcase) from t5;
+select bit_length(utf8_binary collate utf8_lcase), bit_length(utf8_lcase collate utf8_binary) from t5;
+select octet_length(utf8_binary), octet_length(utf8_lcase) from t5;
+select octet_length(utf8_binary collate utf8_lcase), octet_length(utf8_lcase collate utf8_binary) from t5;
+select octet_length(utf8_binary collate utf8_lcase_rtrim), octet_length(utf8_lcase collate utf8_binary_rtrim) from t5;
+
+-- Luhncheck
+select luhn_check(num) from t9;
+
+-- Levenshtein
+select levenshtein(utf8_binary, utf8_lcase) from t5;
+select levenshtein(s, utf8_binary) from t5;
+select levenshtein(utf8_binary collate utf8_binary, s collate utf8_lcase) from t5;
+select levenshtein(utf8_binary, utf8_lcase collate utf8_binary) from t5;
+select levenshtein(utf8_binary collate utf8_lcase, utf8_lcase collate utf8_lcase) from t5;
+select levenshtein(utf8_binary, 'a'), levenshtein(utf8_lcase, 'a') from t5;
+select levenshtein(utf8_binary, 'AaAA' collate utf8_lcase, 3), levenshtein(utf8_lcase, 'AAa' collate utf8_binary, 4) from t5;
+
+-- IsValidUTF8
+select is_valid_utf8(utf8_binary), is_valid_utf8(utf8_lcase) from t5;
+select is_valid_utf8(utf8_binary collate utf8_lcase), is_valid_utf8(utf8_lcase collate utf8_binary) from t5;
+select is_valid_utf8(utf8_binary collate utf8_lcase_rtrim), is_valid_utf8(utf8_lcase collate utf8_binary_rtrim) from t5;
+
+-- MakeValidUTF8
+select make_valid_utf8(utf8_binary), make_valid_utf8(utf8_lcase) from t5;
+select make_valid_utf8(utf8_binary collate utf8_lcase), make_valid_utf8(utf8_lcase collate utf8_binary) from t5;
+select make_valid_utf8(utf8_binary collate utf8_lcase_rtrim), make_valid_utf8(utf8_lcase collate utf8_binary_rtrim) from t5;
+
+-- ValidateUTF8
+select validate_utf8(utf8_binary), validate_utf8(utf8_lcase) from t5;
+select validate_utf8(utf8_binary collate utf8_lcase), validate_utf8(utf8_lcase collate utf8_binary) from t5;
+select validate_utf8(utf8_binary collate utf8_lcase_rtrim), validate_utf8(utf8_lcase collate utf8_binary_rtrim) from t5;
+
+-- TryValidateUTF8
+select try_validate_utf8(utf8_binary), try_validate_utf8(utf8_lcase) from t5;
+select try_validate_utf8(utf8_binary collate utf8_lcase), try_validate_utf8(utf8_lcase collate utf8_binary) from t5;
+select try_validate_utf8(utf8_binary collate utf8_lcase_rtrim), try_validate_utf8(utf8_lcase collate utf8_binary_rtrim) from t5;
+
+-- Left/Right/Substr
+select substr(utf8_binary, 2, 2), substr(utf8_lcase, 2, 2) from t5;
+select substr(utf8_binary collate utf8_lcase, 2, 2), substr(utf8_lcase collate utf8_binary, 2, 2) from t5;
+select right(utf8_binary, 2), right(utf8_lcase, 2) from t5;
+select right(utf8_binary collate utf8_lcase, 2), right(utf8_lcase collate utf8_binary, 2) from t5;
+select left(utf8_binary, '2' collate utf8_lcase), left(utf8_lcase, 2) from t5;
+select left(utf8_binary collate utf8_lcase, 2), left(utf8_lcase collate utf8_binary, 2) from t5;
+
+-- StringRPad
+select rpad(utf8_binary, 8, utf8_lcase) from t5;
+select rpad(s, 8, utf8_binary) from t5;
+select rpad(utf8_binary collate utf8_binary, 8, s collate utf8_lcase) from t5;
+select rpad(utf8_binary, 8, utf8_lcase collate utf8_binary) from t5;
+select rpad(utf8_binary collate utf8_lcase, 8, utf8_lcase collate utf8_lcase) from t5;
+select lpad(utf8_binary collate utf8_binary_rtrim, 8, utf8_lcase collate utf8_binary_rtrim) from t5;
+select rpad(utf8_binary, 8, 'a'), rpad(utf8_lcase, 8, 'a') from t5;
+select rpad(utf8_binary, 8, 'AaAA' collate utf8_lcase), rpad(utf8_lcase, 8, 'AAa' collate utf8_binary) from t5;
+
+-- StringLPad
+select lpad(utf8_binary, 8, utf8_lcase) from t5;
+select lpad(s, 8, utf8_binary) from t5;
+select lpad(utf8_binary collate utf8_binary, 8, s collate utf8_lcase) from t5;
+select lpad(utf8_binary, 8, utf8_lcase collate utf8_binary) from t5;
+select lpad(utf8_binary collate utf8_lcase, 8, utf8_lcase collate utf8_lcase) from t5;
+select lpad(utf8_binary collate utf8_binary_rtrim, 8, utf8_lcase collate utf8_binary_rtrim) from t5;
+select lpad(utf8_binary, 8, 'a'), lpad(utf8_lcase, 8, 'a') from t5;
+select lpad(utf8_binary, 8, 'AaAA' collate utf8_lcase), lpad(utf8_lcase, 8, 'AAa' collate utf8_binary) from t5;
+
+-- Locate
+select locate(utf8_binary, utf8_lcase) from t5;
+select locate(s, utf8_binary) from t5;
+select locate(utf8_binary collate utf8_binary, s collate utf8_lcase) from t5;
+select locate(utf8_binary, utf8_lcase collate utf8_binary) from t5;
+select locate(utf8_binary collate utf8_lcase, utf8_lcase collate utf8_lcase, 3) from t5;
+select locate(utf8_binary collate unicode_ai, utf8_lcase collate unicode_ai, 3) from t5;
+select locate(utf8_binary, 'a'), locate(utf8_lcase, 'a') from t5;
+select locate(utf8_binary, 'AaAA' collate utf8_lcase, 4), locate(utf8_lcase, 'AAa' collate utf8_binary, 4) from t5;
+select locate(utf8_binary, 'AaAA ' collate utf8_binary_rtrim, 4), locate(utf8_lcase, 'AAa ' collate utf8_binary, 4) from t5;
+
+-- StringTrim
+select TRIM(utf8_binary, utf8_lcase) from t5;
+select TRIM(s, utf8_binary) from t5;
+select TRIM(utf8_binary collate utf8_binary, s collate utf8_lcase) from t5;
+select TRIM(utf8_binary, utf8_lcase collate utf8_binary) from t5;
+select TRIM(utf8_binary collate utf8_lcase, utf8_lcase collate utf8_lcase) from t5;
+select TRIM(utf8_binary collate unicode_ai, utf8_lcase collate unicode_ai) from t5;
+select TRIM(utf8_binary collate utf8_binary_rtrim, utf8_lcase collate utf8_binary_rtrim) from t5;
+select TRIM('ABc', utf8_binary), TRIM('ABc', utf8_lcase) from t5;
+select TRIM('ABc' collate utf8_lcase, utf8_binary), TRIM('AAa' collate utf8_binary, utf8_lcase) from t5;
+-- StringTrimBoth
+select BTRIM(utf8_binary, utf8_lcase) from t5;
+select BTRIM(s, utf8_binary) from t5;
+select BTRIM(utf8_binary collate utf8_binary, s collate utf8_lcase) from t5;
+select BTRIM(utf8_binary, utf8_lcase collate utf8_binary) from t5;
+select BTRIM(utf8_binary collate utf8_lcase, utf8_lcase collate utf8_lcase) from t5;
+select BTRIM(utf8_binary collate unicode_ai, utf8_lcase collate unicode_ai) from t5;
+select BTRIM(utf8_binary collate utf8_binary_rtrim, utf8_lcase collate utf8_binary_rtrim) from t5;
+select BTRIM('ABc', utf8_binary), BTRIM('ABc', utf8_lcase) from t5;
+select BTRIM('ABc' collate utf8_lcase, utf8_binary), BTRIM('AAa' collate utf8_binary, utf8_lcase) from t5;
+-- StringTrimLeft
+select LTRIM(utf8_binary, utf8_lcase) from t5;
+select LTRIM(s, utf8_binary) from t5;
+select LTRIM(utf8_binary collate utf8_binary, s collate utf8_lcase) from t5;
+select LTRIM(utf8_binary, utf8_lcase collate utf8_binary) from t5;
+select LTRIM(utf8_binary collate utf8_lcase, utf8_lcase collate utf8_lcase) from t5;
+select LTRIM(utf8_binary collate unicode_ai, utf8_lcase collate unicode_ai) from t5;
+select LTRIM(utf8_binary collate utf8_binary_rtrim, utf8_lcase collate utf8_binary_rtrim) from t5;
+select LTRIM('ABc', utf8_binary), LTRIM('ABc', utf8_lcase) from t5;
+select LTRIM('ABc' collate utf8_lcase, utf8_binary), LTRIM('AAa' collate utf8_binary, utf8_lcase) from t5;
+-- StringTrimRight
+select RTRIM(utf8_binary, utf8_lcase) from t5;
+select RTRIM(s, utf8_binary) from t5;
+select RTRIM(utf8_binary collate utf8_binary, s collate utf8_lcase) from t5;
+select RTRIM(utf8_binary, utf8_lcase collate utf8_binary) from t5;
+select RTRIM(utf8_binary collate utf8_lcase, utf8_lcase collate utf8_lcase) from t5;
+select RTRIM(utf8_binary collate unicode_ai, utf8_lcase collate unicode_ai) from t5;
+select RTRIM(utf8_binary collate utf8_binary_rtrim, utf8_lcase collate utf8_binary_rtrim) from t5;
+select RTRIM('ABc', utf8_binary), RTRIM('ABc', utf8_lcase) from t5;
+select RTRIM('ABc' collate utf8_lcase, utf8_binary), RTRIM('AAa' collate utf8_binary, utf8_lcase) from t5;
+
+-- Implicit aliases to collated expression trees are correctly generated
+
+-- Simple select
+select concat_ws(' ', utf8_lcase, utf8_lcase) from t5;
+
+-- Select by implicit alias
+select `concat_ws(' ' collate UTF8_LCASE, utf8_lcase, utf8_lcase)` from (
+ select concat_ws(' ', utf8_lcase, utf8_lcase) from t5
+);
+
+-- Select by star
+select * from (
+ select concat_ws(' ', utf8_lcase, utf8_lcase) from t5
+);
+
+-- Select by qualified star
+select subq1.* from (
+ select concat_ws(' ', utf8_lcase, utf8_lcase) from t5
+) AS subq1;
+
+-- Implicit alias in CTE output
+with cte as (
+ select concat_ws(' ', utf8_lcase, utf8_lcase) from t5
+)
+select * from cte;
+
+-- Implicit alias in EXISTS subquery output
+select * from values (1) where exists (
+ select concat_ws(' ', utf8_lcase, utf8_lcase) from t5
+);
+
+-- Implicit alias in scalar subquery output
+select (
+ select concat_ws(' ', utf8_lcase, utf8_lcase) from t5 limit 1
+);
+
+-- Scalar subquery with CTE with implicit alias
+select (
+ with cte as (
+ select concat_ws(' ', utf8_lcase, utf8_lcase) from t5
+ )
+ select * from cte limit 1
+);
+
+-- Outer reference to implicit alias
+select * from (
+ select concat_ws(' ', utf8_lcase, utf8_lcase) from t5 limit 1
+)
+where (
+ `concat_ws(' ' collate UTF8_LCASE, utf8_lcase, utf8_lcase)` == 'aaa'
+);
+
+-- Implicit alias reference in Sort
+select lower(`concat_ws(' ' collate UTF8_LCASE, utf8_lcase, utf8_lcase)`) from (
+ select concat_ws(' ', utf8_lcase, utf8_lcase) from t5
+ group by 1
+ order by 1
+);
+
+-- Implciit alias from aggregate in Sort
+select lower(`concat_ws(' ' collate UTF8_LCASE, utf8_lcase, utf8_lcase)`) from (
+ select concat_ws(' ', utf8_lcase, utf8_lcase) from t5
+ group by 1
+ order by max(concat_ws(' ', utf8_lcase, utf8_lcase))
+);
+
+-- Implicit alias in view schema
+create temporary view v1 as (
+ select concat_ws(' ', utf8_lcase, utf8_lcase) from t5
+);
+
+select * from v1;
+
+select `concat_ws(' ' collate UTF8_LCASE, utf8_lcase, utf8_lcase)` from v1;
+
+drop view v1;
+
+drop table t5;
+drop table t6;
+drop table t7;
+drop table t8;
+drop table t9;
+drop table t10;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/column-resolution-aggregate.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/column-resolution-aggregate.sql
new file mode 100644
index 0000000000..4f879fc809
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/column-resolution-aggregate.sql
@@ -0,0 +1,33 @@
+-- Tests covering column resolution priority in Aggregate.
+
+CREATE TEMPORARY VIEW v1 AS VALUES (1, 1, 1), (2, 2, 1) AS t(a, b, k);
+CREATE TEMPORARY VIEW v2 AS VALUES (1, 1, 1), (2, 2, 1) AS t(x, y, all);
+
+-- Relation output columns have higher priority than lateral column alias. This query
+-- should fail as `b` is not in GROUP BY.
+SELECT max(a) AS b, b FROM v1 GROUP BY k;
+
+-- Lateral column alias has higher priority than outer reference.
+SELECT a FROM v1 WHERE (12, 13) IN (SELECT max(x + 10) AS a, a + 1 FROM v2);
+
+-- Relation output columns have higher priority than GROUP BY alias. This query should
+-- fail as `a` is not in GROUP BY.
+SELECT a AS k FROM v1 GROUP BY k;
+
+-- Relation output columns have higher priority than GROUP BY ALL. This query should
+-- fail as `x` is not in GROUP BY.
+SELECT x FROM v2 GROUP BY all;
+
+-- GROUP BY alias has higher priority than GROUP BY ALL, this query fails as `b` is not in GROUP BY.
+SELECT a AS all, b FROM v1 GROUP BY all;
+
+-- GROUP BY alias/ALL does not support lateral column alias.
+SELECT k AS lca, lca + 1 AS col FROM v1 GROUP BY k, col;
+SELECT k AS lca, lca + 1 AS col FROM v1 GROUP BY all;
+
+-- GROUP BY alias still works if it does not directly reference lateral column alias.
+SELECT k AS lca, lca + 1 AS col FROM v1 GROUP BY lca;
+
+-- GROUP BY ALL has higher priority than outer reference. This query should run as `a` and `b` are
+-- in GROUP BY due to the GROUP BY ALL resolution.
+SELECT * FROM v2 WHERE EXISTS (SELECT a, b FROM v1 GROUP BY all);
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/column-resolution-sort.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/column-resolution-sort.sql
new file mode 100644
index 0000000000..2c5b9f9e9d
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/column-resolution-sort.sql
@@ -0,0 +1,20 @@
+--SET spark.sql.leafNodeDefaultParallelism=1
+-- Tests covering column resolution priority in Sort.
+
+CREATE TEMPORARY VIEW v1 AS VALUES (1, 2, 2), (2, 1, 1) AS t(a, b, k);
+CREATE TEMPORARY VIEW v2 AS VALUES (1, 2, 2), (2, 1, 1) AS t(a, b, all);
+
+-- Relation output columns have higher priority than missing reference.
+-- Query will fail if we order by the column `v1.b`, as it's not in GROUP BY.
+-- Actually results are [1, 2] as we order by `max(a) AS b`.
+SELECT max(a) AS b FROM v1 GROUP BY k ORDER BY b;
+
+-- Missing reference has higher priority than ORDER BY ALL.
+-- Results will be [1, 2] if we order by `max(a)`.
+-- Actually results are [2, 1] as we order by the grouping column `v2.all`.
+SELECT max(a) FROM v2 GROUP BY all ORDER BY all;
+
+-- ORDER BY ALL has higher priority than outer reference.
+-- Results will be [1, 1] if we order by outer reference 'v2.all'.
+-- Actually results are [2, 2] as we order by column `v1.b`
+SELECT (SELECT b FROM v1 ORDER BY all LIMIT 1) FROM v2;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/columnresolution-negative.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/columnresolution-negative.sql
new file mode 100644
index 0000000000..d100023b4e
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/columnresolution-negative.sql
@@ -0,0 +1,50 @@
+-- Negative testcases for column resolution
+CREATE DATABASE mydb1;
+USE mydb1;
+CREATE TABLE t1 USING parquet AS SELECT 1 AS i1;
+
+CREATE DATABASE mydb2;
+USE mydb2;
+CREATE TABLE t1 USING parquet AS SELECT 20 AS i1;
+
+-- Negative tests: column resolution scenarios with ambiguous cases in join queries
+SET spark.sql.crossJoin.enabled = true;
+USE mydb1;
+SELECT i1 FROM t1, mydb1.t1;
+SELECT t1.i1 FROM t1, mydb1.t1;
+SELECT mydb1.t1.i1 FROM t1, mydb1.t1;
+SELECT i1 FROM t1, mydb2.t1;
+SELECT t1.i1 FROM t1, mydb2.t1;
+USE mydb2;
+SELECT i1 FROM t1, mydb1.t1;
+SELECT t1.i1 FROM t1, mydb1.t1;
+SELECT i1 FROM t1, mydb2.t1;
+SELECT t1.i1 FROM t1, mydb2.t1;
+SELECT db1.t1.i1 FROM t1, mydb2.t1;
+SET spark.sql.crossJoin.enabled = false;
+
+-- Negative tests
+USE mydb1;
+SELECT mydb1.t1 FROM t1;
+SELECT t1.x.y.* FROM t1;
+SELECT t1 FROM mydb1.t1;
+USE mydb2;
+SELECT mydb1.t1.i1 FROM t1;
+
+-- Negative tests: view cannot resolve column after incompatible schema change
+USE mydb1;
+CREATE VIEW v1 AS SELECT * FROM t1;
+DROP TABLE t1;
+CREATE TABLE t1 USING parquet AS SELECT 1 AS i2;
+SELECT * FROM v1;
+
+-- Negative tests: temp view cannot resolve column after incompatible schema change
+USE mydb2;
+CREATE TEMP VIEW v2 AS SELECT * FROM t1;
+DROP TABLE t1;
+CREATE TABLE t1 USING parquet AS SELECT 1 AS i2;
+SELECT * FROM v2;
+
+-- reset
+DROP DATABASE mydb1 CASCADE;
+DROP DATABASE mydb2 CASCADE;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/columnresolution-views.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/columnresolution-views.sql
new file mode 100644
index 0000000000..83c32a5bf2
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/columnresolution-views.sql
@@ -0,0 +1,23 @@
+-- Tests for qualified column names for the view code-path
+-- Test scenario with Temporary view
+CREATE OR REPLACE TEMPORARY VIEW view1 AS SELECT 2 AS i1;
+SELECT view1.* FROM view1;
+SELECT * FROM view1;
+SELECT view1.i1 FROM view1;
+SELECT i1 FROM view1;
+SELECT a.i1 FROM view1 AS a;
+SELECT i1 FROM view1 AS a;
+-- cleanup
+DROP VIEW view1;
+
+-- Test scenario with Global Temp view
+CREATE OR REPLACE GLOBAL TEMPORARY VIEW view1 as SELECT 1 as i1;
+SELECT * FROM global_temp.view1;
+SELECT global_temp.view1.* FROM global_temp.view1;
+SELECT i1 FROM global_temp.view1;
+SELECT global_temp.view1.i1 FROM global_temp.view1;
+SELECT view1.i1 FROM global_temp.view1;
+SELECT a.i1 FROM global_temp.view1 AS a;
+SELECT i1 FROM global_temp.view1 AS a;
+-- cleanup
+DROP VIEW global_temp.view1;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/columnresolution.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/columnresolution.sql
new file mode 100644
index 0000000000..d001185a73
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/columnresolution.sql
@@ -0,0 +1,78 @@
+-- Tests covering different scenarios with qualified column names
+-- Scenario: column resolution scenarios with datasource table
+CREATE DATABASE mydb1;
+USE mydb1;
+CREATE TABLE t1 USING parquet AS SELECT 1 AS i1;
+
+CREATE DATABASE mydb2;
+USE mydb2;
+CREATE TABLE t1 USING parquet AS SELECT 20 AS i1;
+
+USE mydb1;
+SELECT i1 FROM t1;
+SELECT i1 FROM mydb1.t1;
+SELECT t1.i1 FROM t1;
+SELECT t1.i1 FROM mydb1.t1;
+
+SELECT mydb1.t1.i1 FROM t1;
+SELECT mydb1.t1.i1 FROM mydb1.t1;
+
+USE mydb2;
+SELECT i1 FROM t1;
+SELECT i1 FROM mydb1.t1;
+SELECT t1.i1 FROM t1;
+SELECT t1.i1 FROM mydb1.t1;
+SELECT mydb1.t1.i1 FROM mydb1.t1;
+
+-- Scenario: resolve fully qualified table name in star expansion
+USE mydb1;
+SELECT t1.* FROM t1;
+SELECT mydb1.t1.* FROM mydb1.t1;
+SELECT t1.* FROM mydb1.t1;
+USE mydb2;
+SELECT t1.* FROM t1;
+SELECT mydb1.t1.* FROM mydb1.t1;
+SELECT t1.* FROM mydb1.t1;
+SELECT a.* FROM mydb1.t1 AS a;
+
+-- Scenario: resolve in case of subquery
+
+USE mydb1;
+CREATE TABLE t3 USING parquet AS SELECT * FROM VALUES (4,1), (3,1) AS t3(c1, c2);
+CREATE TABLE t4 USING parquet AS SELECT * FROM VALUES (4,1), (2,1) AS t4(c2, c3);
+
+SELECT * FROM t3 WHERE c1 IN (SELECT c2 FROM t4 WHERE t4.c3 = t3.c2);
+
+SELECT * FROM mydb1.t3 WHERE c1 IN
+ (SELECT mydb1.t4.c2 FROM mydb1.t4 WHERE mydb1.t4.c3 = mydb1.t3.c2);
+
+-- Scenario: column resolution scenarios in join queries
+SET spark.sql.crossJoin.enabled = true;
+
+SELECT mydb1.t1.i1 FROM t1, mydb2.t1;
+
+SELECT mydb1.t1.i1 FROM mydb1.t1, mydb2.t1;
+
+USE mydb2;
+SELECT mydb1.t1.i1 FROM t1, mydb1.t1;
+SET spark.sql.crossJoin.enabled = false;
+
+-- Scenario: Table with struct column
+USE mydb1;
+CREATE TABLE t5(i1 INT, t5 STRUCT<i1:INT, i2:INT>) USING parquet;
+INSERT INTO t5 VALUES(1, (2, 3));
+SELECT t5.i1 FROM t5;
+SELECT t5.t5.i1 FROM t5;
+SELECT t5.t5.i1 FROM mydb1.t5;
+SELECT t5.i1 FROM mydb1.t5;
+SELECT t5.* FROM mydb1.t5;
+SELECT t5.t5.* FROM mydb1.t5;
+SELECT mydb1.t5.t5.i1 FROM mydb1.t5;
+SELECT mydb1.t5.t5.i2 FROM mydb1.t5;
+SELECT mydb1.t5.* FROM mydb1.t5;
+SELECT mydb1.t5.* FROM t5;
+
+-- Cleanup and Reset
+USE default;
+DROP DATABASE mydb1 CASCADE;
+DROP DATABASE mydb2 CASCADE;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/comments.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/comments.sql
new file mode 100644
index 0000000000..da5e57a942
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/comments.sql
@@ -0,0 +1,119 @@
+-- Test comments.
+
+-- the first case of bracketed comment
+--QUERY-DELIMITER-START
+/* This is the first example of bracketed comment.
+SELECT 'ommented out content' AS first;
+*/
+SELECT 'selected content' AS first;
+--QUERY-DELIMITER-END
+
+-- the second case of bracketed comment
+--QUERY-DELIMITER-START
+/* This is the second example of bracketed comment.
+SELECT '/', 'ommented out content' AS second;
+*/
+SELECT '/', 'selected content' AS second;
+--QUERY-DELIMITER-END
+
+-- the third case of bracketed comment
+--QUERY-DELIMITER-START
+/* This is the third example of bracketed comment.
+ *SELECT '*', 'ommented out content' AS third;
+ */
+SELECT '*', 'selected content' AS third;
+--QUERY-DELIMITER-END
+
+-- the first case of empty bracketed comment
+--QUERY-DELIMITER-START
+/**/
+SELECT 'selected content' AS fourth;
+--QUERY-DELIMITER-END
+
+-- the first case of nested bracketed comment
+--QUERY-DELIMITER-START
+/* This is the first example of nested bracketed comment.
+/* I am a nested bracketed comment.*/
+*/
+SELECT 'selected content' AS fifth;
+--QUERY-DELIMITER-END
+
+-- the second case of nested bracketed comment
+--QUERY-DELIMITER-START
+/* This is the second example of nested bracketed comment.
+/* I am a nested bracketed comment.
+ */
+ */
+SELECT 'selected content' AS sixth;
+--QUERY-DELIMITER-END
+
+-- the third case of nested bracketed comment
+--QUERY-DELIMITER-START
+/*
+ * This is the third example of nested bracketed comment.
+ /*
+ * I am a nested bracketed comment.
+ */
+ */
+SELECT 'selected content' AS seventh;
+--QUERY-DELIMITER-END
+
+-- the fourth case of nested bracketed comment
+--QUERY-DELIMITER-START
+/*
+ * This is the fourth example of nested bracketed comment.
+SELECT /* I am a nested bracketed comment.*/ * FROM testData;
+ */
+SELECT 'selected content' AS eighth;
+--QUERY-DELIMITER-END
+
+-- the fifth case of nested bracketed comment
+--QUERY-DELIMITER-START
+SELECT /*
+ * This is the fifth example of nested bracketed comment.
+/* I am a second level of nested bracketed comment.
+/* I am a third level of nested bracketed comment.
+Other information of third level.
+SELECT 'ommented out content' AS ninth;
+*/
+Other information of second level.
+*/
+Other information of first level.
+*/
+'selected content' AS ninth;
+--QUERY-DELIMITER-END
+
+-- the first case of empty nested bracketed comment
+--QUERY-DELIMITER-START
+/*/**/*/
+SELECT 'selected content' AS tenth;
+--QUERY-DELIMITER-END
+
+-- the first case of unclosed bracketed comment
+--QUERY-DELIMITER-START
+/*abc*/
+select 1 as a
+/*
+
+2 as b
+/*abc*/
+, 3 as c
+
+/**/
+;
+--QUERY-DELIMITER-END
+
+-- the second case of unclosed bracketed comment
+--QUERY-DELIMITER-START
+/*abc*/
+select 1 as a
+/*
+
+2 as b
+/*abc*/
+, 3 as c
+
+/**/
+select 4 as d
+;
+--QUERY-DELIMITER-END
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/comparator.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/comparator.sql
new file mode 100644
index 0000000000..70af4f75ac
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/comparator.sql
@@ -0,0 +1,13 @@
+-- binary type
+select x'00' < x'0f';
+select x'00' < x'ff';
+
+-- trim string to numeric
+select '1 ' = 1Y;
+select '\t1 ' = 1Y;
+select '1 ' = 1S;
+select '1 ' = 1;
+select ' 1' = 1L;
+select ' 1' = cast(1.0 as float);
+select ' 1.0 ' = 1.0D;
+select ' 1.0 ' = 1.0BD;
\ No newline at end of file
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/conditional-functions.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/conditional-functions.sql
new file mode 100644
index 0000000000..c7a4b055f0
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/conditional-functions.sql
@@ -0,0 +1,38 @@
+-- Tests for conditional functions
+
+CREATE TABLE conditional_t USING PARQUET AS SELECT c1, c2 FROM VALUES(1d, 0),(2d, 1),(null, 1),(CAST('NaN' AS DOUBLE), 0) AS t(c1, c2);
+
+SELECT nanvl(c2, c1/c2 + c1/c2) FROM conditional_t;
+SELECT nanvl(c2, 1/0) FROM conditional_t;
+SELECT nanvl(1-0, 1/0) FROM conditional_t;
+
+SELECT if(c2 >= 0, 1-0, 1/0) from conditional_t;
+SELECT if(1 == 1, 1, 1/0);
+SELECT if(1 != 1, 1/0, 1);
+
+SELECT coalesce(c2, 1/0) from conditional_t;
+SELECT coalesce(1, 1/0);
+SELECT coalesce(null, 1, 1/0);
+
+SELECT case when c2 >= 0 then 1 else 1/0 end from conditional_t;
+SELECT case when 1 < 2 then 1 else 1/0 end;
+SELECT case when 1 > 2 then 1/0 else 1 end;
+
+SELECT nullifzero(0),
+ nullifzero(cast(0 as tinyint)),
+ nullifzero(cast(0 as bigint)),
+ nullifzero('0'),
+ nullifzero(0.0),
+ nullifzero(1),
+ nullifzero(null);
+
+SELECT nullifzero('abc');
+
+SELECT zeroifnull(null),
+ zeroifnull(1),
+ zeroifnull(cast(1 as tinyint)),
+ zeroifnull(cast(1 as bigint));
+
+SELECT zeroifnull('abc');
+
+DROP TABLE conditional_t;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/count.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/count.sql
new file mode 100644
index 0000000000..644e808cc0
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/count.sql
@@ -0,0 +1,55 @@
+-- Test data.
+CREATE OR REPLACE TEMPORARY VIEW testData AS SELECT * FROM VALUES
+(1, 1), (1, 2), (2, 1), (1, 1), (null, 2), (1, null), (null, null)
+AS testData(a, b);
+
+-- count with single expression
+SELECT
+ count(*), count(1), count(null), count(a), count(b), count(a + b), count((a, b))
+FROM testData;
+
+-- distinct count with single expression
+SELECT
+ count(DISTINCT 1),
+ count(DISTINCT null),
+ count(DISTINCT a),
+ count(DISTINCT b),
+ count(DISTINCT (a + b)),
+ count(DISTINCT (a, b))
+FROM testData;
+
+-- count with multiple expressions
+SELECT count(a, b), count(b, a), count(testData.*, testData.*) FROM testData;
+
+-- distinct count with multiple expressions
+SELECT
+ count(DISTINCT a, b), count(DISTINCT b, a), count(DISTINCT *), count(DISTINCT testData.*, testData.*)
+FROM testData;
+
+-- distinct count with multiple literals
+SELECT count(DISTINCT 3,2);
+SELECT count(DISTINCT 2), count(DISTINCT 2,3);
+SELECT count(DISTINCT 2), count(DISTINCT 3,2);
+SELECT count(DISTINCT a), count(DISTINCT 2,3) FROM testData;
+SELECT count(DISTINCT a), count(DISTINCT 3,2) FROM testData;
+SELECT count(DISTINCT a), count(DISTINCT 2), count(DISTINCT 2,3) FROM testData;
+SELECT count(DISTINCT a), count(DISTINCT 2), count(DISTINCT 3,2) FROM testData;
+SELECT count(distinct 0.8), percentile_approx(distinct a, 0.8) FROM testData;
+
+-- legacy behavior: allow calling function count without parameters
+set spark.sql.legacy.allowParameterlessCount=true;
+set spark.sql.optimizer.excludedRules=org.apache.spark.sql.catalyst.optimizer.ConvertToLocalRelation,org.apache.spark.sql.catalyst.optimizer.ConstantFolding;
+SELECT count() FROM testData;
+
+-- count without expressions
+set spark.sql.legacy.allowParameterlessCount=false;
+set spark.sql.optimizer.excludedRules=org.apache.spark.sql.catalyst.optimizer.ConvertToLocalRelation,org.apache.spark.sql.catalyst.optimizer.ConstantFolding,org.apache.spark.sql.catalyst.optimizer.NullPropagation;
+SELECT count() FROM testData;
+
+-- legacy behavior: allow count(testData.*)
+set spark.sql.legacy.allowStarWithSingleTableIdentifierInCount=true;
+SELECT count(testData.*) FROM testData;
+
+-- count with a single tblName.* as parameter
+set spark.sql.legacy.allowStarWithSingleTableIdentifierInCount=false;
+SELECT count(testData.*) FROM testData;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cross-join.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cross-join.sql
new file mode 100644
index 0000000000..b64197e2bc
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cross-join.sql
@@ -0,0 +1,36 @@
+-- Cross join detection and error checking is done in JoinSuite since explain output is
+-- used in the error message and the ids are not stable. Only positive cases are checked here.
+
+create temporary view nt1 as select * from values
+ ("one", 1),
+ ("two", 2),
+ ("three", 3)
+ as nt1(k, v1);
+
+create temporary view nt2 as select * from values
+ ("one", 1),
+ ("two", 22),
+ ("one", 5)
+ as nt2(k, v2);
+
+-- Cross joins with and without predicates
+SELECT * FROM nt1 cross join nt2;
+SELECT * FROM nt1 cross join nt2 where nt1.k = nt2.k;
+SELECT * FROM nt1 cross join nt2 on (nt1.k = nt2.k);
+SELECT * FROM nt1 cross join nt2 where nt1.v1 = 1 and nt2.v2 = 22;
+
+SELECT a.key, b.key FROM
+(SELECT k key FROM nt1 WHERE v1 < 2) a
+CROSS JOIN
+(SELECT k key FROM nt2 WHERE v2 = 22) b;
+
+-- Join reordering
+create temporary view A(a, va) as select * from nt1;
+create temporary view B(b, vb) as select * from nt1;
+create temporary view C(c, vc) as select * from nt1;
+create temporary view D(d, vd) as select * from nt1;
+
+-- Allowed since cross join with C is explicit
+select * from ((A join B on (a = b)) cross join C) join D on (a = d);
+-- Cross joins with non-equal predicates
+SELECT * FROM nt1 CROSS JOIN nt2 ON (nt1.k > nt2.k);
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/csv-functions.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/csv-functions.sql
new file mode 100644
index 0000000000..01d436534a
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/csv-functions.sql
@@ -0,0 +1,24 @@
+-- from_csv
+select from_csv('1, 3.14', 'a INT, f FLOAT');
+select from_csv('26/08/2015', 'time Timestamp', map('timestampFormat', 'dd/MM/yyyy'));
+-- Check if errors handled
+select from_csv('1', 1);
+select from_csv('1', 'a InvalidType');
+select from_csv('1', 'Array<int>');
+select from_csv('1', 'a INT', named_struct('mode', 'PERMISSIVE'));
+select from_csv('1', 'a INT', map('mode', 1));
+select from_csv();
+-- infer schema of json literal
+select from_csv('1,abc', schema_of_csv('1,abc'));
+select schema_of_csv('1|abc', map('delimiter', '|'));
+select schema_of_csv(null);
+CREATE TEMPORARY VIEW csvTable(csvField, a) AS SELECT * FROM VALUES ('1,abc', 'a');
+SELECT schema_of_csv(csvField) FROM csvTable;
+-- Clean up
+DROP VIEW IF EXISTS csvTable;
+-- to_csv
+select to_csv(named_struct('a', 1, 'b', 2));
+select to_csv(named_struct('time', to_timestamp('2015-08-26', 'yyyy-MM-dd')), map('timestampFormat', 'dd/MM/yyyy'));
+-- Check if errors handled
+select to_csv(named_struct('a', 1, 'b', 2), named_struct('mode', 'PERMISSIVE'));
+select to_csv(named_struct('a', 1, 'b', 2), map('mode', 1));
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cte-command.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cte-command.sql
new file mode 100644
index 0000000000..ee90c2de49
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cte-command.sql
@@ -0,0 +1,33 @@
+-- WITH inside CTE
+CREATE TABLE cte_tbl USING csv AS WITH s AS (SELECT 42 AS col) SELECT * FROM s;
+
+SELECT * FROM cte_tbl;
+
+-- WITH inside CREATE VIEW
+CREATE TEMPORARY VIEW cte_view AS WITH s AS (SELECT 42 AS col) SELECT * FROM s;
+
+SELECT * FROM cte_view;
+
+-- INSERT inside WITH
+WITH s AS (SELECT 43 AS col)
+INSERT INTO cte_tbl SELECT * FROM S;
+
+SELECT * FROM cte_tbl;
+
+-- WITH inside INSERT
+INSERT INTO cte_tbl WITH s AS (SELECT 44 AS col) SELECT * FROM s;
+
+SELECT * FROM cte_tbl;
+
+CREATE TABLE cte_tbl2 (col INT) USING csv;
+-- Multi-INSERT
+WITH s AS (SELECT 45 AS col)
+FROM s
+INSERT INTO cte_tbl SELECT col
+INSERT INTO cte_tbl2 SELECT col;
+
+SELECT * FROM cte_tbl;
+SELECT * FROM cte_tbl2;
+
+DROP TABLE cte_tbl;
+DROP TABLE cte_tbl2;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cte-legacy.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cte-legacy.sql
new file mode 100644
index 0000000000..29dee1a3af
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cte-legacy.sql
@@ -0,0 +1,2 @@
+--SET spark.sql.legacy.ctePrecedencePolicy = legacy
+--IMPORT cte-nested.sql
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cte-nested.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cte-nested.sql
new file mode 100644
index 0000000000..3b2ba1fcdd
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cte-nested.sql
@@ -0,0 +1,228 @@
+-- CTE in CTE definition
+WITH t as (
+ WITH t2 AS (SELECT 1)
+ SELECT * FROM t2
+)
+SELECT * FROM t;
+
+-- CTE in subquery
+SELECT max(c) FROM (
+ WITH t(c) AS (SELECT 1)
+ SELECT * FROM t
+);
+
+-- CTE in subquery expression
+SELECT (
+ WITH t AS (SELECT 1)
+ SELECT * FROM t
+);
+
+-- un-referenced CTE in subquery expression: outer reference in CTE relation
+SELECT (
+ WITH unreferenced AS (SELECT id)
+ SELECT 1
+) FROM range(1);
+
+-- un-referenced CTE in subquery expression: outer reference in CTE main query
+SELECT (
+ WITH unreferenced AS (SELECT 1)
+ SELECT id
+) FROM range(1);
+
+-- Make sure CTE in subquery is scoped to that subquery rather than global
+-- the 2nd half of the union should fail because the cte is scoped to the first half
+SELECT * FROM
+ (
+ WITH cte AS (SELECT * FROM range(10))
+ SELECT * FROM cte WHERE id = 8
+ ) a
+UNION
+SELECT * FROM cte;
+
+-- CTE in CTE definition shadows outer
+WITH
+ t AS (SELECT 1),
+ t2 AS (
+ WITH t AS (SELECT 2)
+ SELECT * FROM t
+ )
+SELECT * FROM t2;
+
+-- CTE in CTE definition shadows outer 2
+WITH
+ t(c) AS (SELECT 1),
+ t2 AS (
+ SELECT (
+ SELECT max(c) FROM (
+ WITH t(c) AS (SELECT 2)
+ SELECT * FROM t
+ )
+ )
+ )
+SELECT * FROM t2;
+
+-- CTE in CTE definition shadows outer 3
+WITH
+ t AS (SELECT 1),
+ t2 AS (
+ WITH t AS (SELECT 2),
+ t2 AS (
+ WITH t AS (SELECT 3)
+ SELECT * FROM t
+ )
+ SELECT * FROM t2
+ )
+SELECT * FROM t2;
+
+-- CTE in subquery shadows outer
+WITH t(c) AS (SELECT 1)
+SELECT max(c) FROM (
+ WITH t(c) AS (SELECT 2)
+ SELECT * FROM t
+);
+
+-- CTE in subquery shadows outer 2
+WITH t(c) AS (SELECT 1)
+SELECT sum(c) FROM (
+ SELECT max(c) AS c FROM (
+ WITH t(c) AS (SELECT 2)
+ SELECT * FROM t
+ )
+);
+
+-- CTE in subquery shadows outer 3
+WITH t(c) AS (SELECT 1)
+SELECT sum(c) FROM (
+ WITH t(c) AS (SELECT 2)
+ SELECT max(c) AS c FROM (
+ WITH t(c) AS (SELECT 3)
+ SELECT * FROM t
+ )
+);
+
+-- CTE in subquery expression shadows outer
+WITH t AS (SELECT 1)
+SELECT (
+ WITH t AS (SELECT 2)
+ SELECT * FROM t
+);
+
+-- CTE in subquery expression shadows outer 2
+WITH t AS (SELECT 1)
+SELECT (
+ SELECT (
+ WITH t AS (SELECT 2)
+ SELECT * FROM t
+ )
+);
+
+-- CTE in subquery expression shadows outer 3
+WITH t AS (SELECT 1)
+SELECT (
+ WITH t AS (SELECT 2)
+ SELECT (
+ WITH t AS (SELECT 3)
+ SELECT * FROM t
+ )
+);
+
+-- CTE in subquery expression shadows outer 4
+WITH t(c) AS (SELECT 1)
+SELECT * FROM t
+WHERE c IN (
+ WITH t(c) AS (SELECT 2)
+ SELECT * FROM t
+);
+
+-- forward name conflict is not a real conflict
+WITH
+ t AS (
+ WITH t2 AS (SELECT 1)
+ SELECT * FROM t2
+ ),
+ t2 AS (SELECT 2)
+SELECT * FROM t;
+
+-- case insensitive name conflicts: in other CTE relations
+WITH
+ abc AS (SELECT 1),
+ t AS (
+ WITH aBc AS (SELECT 2)
+ SELECT * FROM aBC
+ )
+SELECT * FROM t;
+
+-- case insensitive name conflicts: in subquery expressions
+WITH abc AS (SELECT 1)
+SELECT (
+ WITH aBc AS (SELECT 2)
+ SELECT * FROM aBC
+);
+
+-- SPARK-38404: CTE in CTE definition references outer
+WITH
+ t1 AS (SELECT 1),
+ t2 AS (
+ WITH t3 AS (
+ SELECT * FROM t1
+ )
+ SELECT * FROM t3
+ )
+SELECT * FROM t2;
+
+-- CTE nested in CTE main body FROM clause references outer CTE def
+WITH cte_outer AS (
+ SELECT 1
+)
+SELECT * FROM (
+ WITH cte_inner AS (
+ SELECT * FROM cte_outer
+ )
+ SELECT * FROM cte_inner
+);
+
+-- CTE double nested in CTE main body FROM clause references outer CTE def
+WITH cte_outer AS (
+ SELECT 1
+)
+SELECT * FROM (
+ WITH cte_inner AS (
+ SELECT * FROM (
+ WITH cte_inner_inner AS (
+ SELECT * FROM cte_outer
+ )
+ SELECT * FROM cte_inner_inner
+ )
+ )
+ SELECT * FROM cte_inner
+);
+
+-- Invalid reference to invisible CTE def nested CTE def
+WITH cte_outer AS (
+ WITH cte_invisible_inner AS (
+ SELECT 1
+ )
+ SELECT * FROM cte_invisible_inner
+)
+SELECT * FROM (
+ WITH cte_inner AS (
+ SELECT * FROM cte_invisible_inner
+ )
+ SELECT * FROM cte_inner
+);
+
+-- Invalid reference to invisible CTE def nested CTE def (in FROM)
+WITH cte_outer AS (
+ SELECT * FROM (
+ WITH cte_invisible_inner AS (
+ SELECT 1
+ )
+ SELECT * FROM cte_invisible_inner
+ )
+)
+SELECT * FROM (
+ WITH cte_inner AS (
+ SELECT * FROM cte_invisible_inner
+ )
+ SELECT * FROM cte_inner
+);
\ No newline at end of file
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cte-nonlegacy.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cte-nonlegacy.sql
new file mode 100644
index 0000000000..3316f67402
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cte-nonlegacy.sql
@@ -0,0 +1,2 @@
+--SET spark.sql.legacy.ctePrecedencePolicy = EXCEPTION
+--IMPORT cte-nested.sql
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cte.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cte.sql
new file mode 100644
index 0000000000..ecf760ecac
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/cte.sql
@@ -0,0 +1,184 @@
+create temporary view t as select * from values 0, 1, 2 as t(id);
+create temporary view t2 as select * from values 0, 1 as t(id);
+create temporary view t3 as select * from t;
+
+-- WITH clause should not fall into infinite loop by referencing self
+WITH s AS (SELECT 1 FROM s) SELECT * FROM s;
+
+WITH r AS (SELECT (SELECT * FROM r))
+SELECT * FROM r;
+
+-- WITH clause should reference the base table
+WITH t AS (SELECT 1 FROM t) SELECT * FROM t;
+
+-- Table `t` referenced by a view should take precedence over the top CTE `t`
+WITH t AS (SELECT 1) SELECT * FROM t3;
+
+-- WITH clause should not allow cross reference
+WITH s1 AS (SELECT 1 FROM s2), s2 AS (SELECT 1 FROM s1) SELECT * FROM s1, s2;
+
+-- WITH clause should reference the previous CTE
+WITH t1 AS (SELECT * FROM t2), t2 AS (SELECT 2 FROM t1) SELECT * FROM t1 cross join t2;
+
+-- SPARK-18609 CTE with self-join
+WITH CTE1 AS (
+ SELECT b.id AS id
+ FROM T2 a
+ CROSS JOIN (SELECT id AS id FROM T2) b
+)
+SELECT t1.id AS c1,
+ t2.id AS c2
+FROM CTE1 t1
+ CROSS JOIN CTE1 t2;
+
+-- CTE with column alias
+WITH t(x) AS (SELECT 1)
+SELECT * FROM t WHERE x = 1;
+
+-- CTE with multiple column aliases
+WITH t(x, y) AS (SELECT 1, 2)
+SELECT * FROM t WHERE x = 1 AND y = 2;
+
+-- CTE with duplicate column aliases
+WITH t(x, x) AS (SELECT 1, 2)
+SELECT * FROM t;
+
+-- CTE with empty column alias list is not allowed
+WITH t() AS (SELECT 1)
+SELECT * FROM t;
+
+-- CTEs with duplicate names are not allowed
+WITH
+ t(x) AS (SELECT 1),
+ t(x) AS (SELECT 2)
+SELECT * FROM t;
+
+-- invalid CTE relation should fail the query even if it's not referenced
+WITH t AS (SELECT 1 FROM non_existing_table)
+SELECT 2;
+
+-- The following tests are ported from Postgres
+-- Multiple uses are evaluated only once
+SELECT count(*) FROM (
+ WITH q1(x) AS (SELECT random() FROM range(1, 5))
+ SELECT * FROM q1
+ UNION
+ SELECT * FROM q1
+) ss;
+
+-- Deeply nested
+WITH w1(c1) AS
+ (WITH w2(c2) AS
+ (WITH w3(c3) AS
+ (WITH w4(c4) AS
+ (WITH w5(c5) AS
+ (WITH w6(c6) AS
+ (WITH w7(c7) AS
+ (WITH w8(c8) AS
+ (SELECT 1)
+ SELECT * FROM w8)
+ SELECT * FROM w7)
+ SELECT * FROM w6)
+ SELECT * FROM w5)
+ SELECT * FROM w4)
+ SELECT * FROM w3)
+ SELECT * FROM w2)
+SELECT * FROM w1;
+
+-- CTE referencing an outer-level variable, should fail
+SELECT ( WITH cte(foo) AS ( VALUES(id) )
+ SELECT (SELECT foo FROM cte) )
+FROM t;
+
+-- CTE name collision with subquery name
+WITH same_name AS (SELECT 42)
+SELECT * FROM same_name, (SELECT 10) AS same_name;
+
+-- CTE name collision with subquery name, should fail
+WITH same_name(x) AS (SELECT 42)
+SELECT same_name.x FROM (SELECT 10) AS same_name(x), same_name;
+
+set spark.sql.optimizer.excludedRules=org.apache.spark.sql.catalyst.optimizer.ConvertToLocalRelation,org.apache.spark.sql.catalyst.optimizer.NullPropagation;
+-- Test behavior with an unknown-type literal in the WITH
+WITH q AS (SELECT 'foo' AS x)
+SELECT x, typeof(x) FROM q;
+
+set spark.sql.optimizer.excludedRules=org.apache.spark.sql.catalyst.optimizer.ConvertToLocalRelation,org.apache.spark.sql.catalyst.optimizer.ConstantFolding,org.apache.spark.sql.catalyst.optimizer.NullPropagation;
+-- The following tests are ported from ZetaSQL
+-- Alias inside the with hides the underlying column name, should fail
+with cte as (select id as id_alias from t)
+select id from cte;
+
+-- Reference of later WITH, should fail.
+with r1 as (select * from r2),
+ r2 as (select 1)
+select 2;
+
+-- WITH in a table subquery
+SELECT * FROM
+ (WITH q AS (select 1 x) SELECT x+1 AS y FROM q);
+
+-- WITH in an expression subquery
+select (with q as (select 1 x) select * from q);
+
+-- WITH in an IN subquery
+select 1 in (with q as (select 1) select * from q);
+
+-- WITH alias referenced outside its scope, should fail
+SELECT * FROM
+ (WITH q AS (select 1 x) SELECT x+1 AS y FROM q),
+ q;
+
+-- References to CTEs of the same name should be resolved properly
+WITH T1 as (select 1 a)
+select *
+from
+ T1 x,
+ (WITH T1 as (select 2 b) select * from T1) y,
+ T1 z;
+
+-- References to CTEs of the same name should be resolved properly
+WITH TTtt as (select 1 a),
+ `tTTt_2` as (select 2 a)
+select *
+from
+ (WITH TtTt as (select 3 c) select * from ttTT, `tttT_2`);
+
+-- Correlated CTE subquery
+select
+ (WITH q AS (select T.x) select * from q)
+from (select 1 x, 2 y) T;
+
+-- The main query inside WITH can be correlated.
+select
+ (WITH q AS (select 3 z) select x + t.y + z from q)
+from (select 1 x, 2 y) T;
+
+-- A WITH subquery alias is visible inside a WITH clause subquery.
+WITH q1 as (select 1 x)
+select * from
+ (with q2 as (select * from q1) select * from q2);
+
+-- A WITH subquery alias is visible inside a WITH clause subquery, and they have the same name.
+WITH q1 as (select 1 x)
+select * from
+ (with q1 as (select x+1 from q1) select * from q1);
+
+-- The following tests are ported from DuckDB
+-- Duplicate CTE alias, should fail
+with cte1 as (select 42), cte1 as (select 42) select * FROM cte1;
+
+-- Refer to CTE in subquery
+with cte1 as (Select id as j from t)
+select * from cte1 where j = (select max(j) from cte1 as cte2);
+
+-- Nested CTE views that re-use CTE aliases
+with cte AS (SELECT * FROM va) SELECT * FROM cte;
+
+-- Self-refer to non-existent cte, should fail.
+with cte as (select * from cte) select * from cte;
+
+-- Clean up
+DROP VIEW IF EXISTS t;
+DROP VIEW IF EXISTS t2;
+DROP VIEW IF EXISTS t3;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/current_database_catalog.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/current_database_catalog.sql
new file mode 100644
index 0000000000..d7aed6afaa
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/current_database_catalog.sql
@@ -0,0 +1,2 @@
+-- get current_database/current_schema and current_catalog
+select current_database(), current_schema(), current_catalog();
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/date.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/date.sql
new file mode 100644
index 0000000000..c1ae432d63
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/date.sql
@@ -0,0 +1,168 @@
+-- date literals, functions and operations
+
+create temporary view date_view as select '2011-11-11' date_str, '1' int_str;
+
+select date '2019-01-01\t';
+select date '2020-01-01中文';
+
+select make_date(2019, 1, 1), make_date(12, 12, 12);
+-- invalid month
+select make_date(2000, 13, 1);
+-- invalid day
+select make_date(2000, 1, 33);
+
+-- invalid: year field must have at least 4 digits
+select date'015';
+-- invalid: month field can have at most 2 digits
+select date'2021-4294967297-11';
+
+select current_date = current_date;
+-- under ANSI mode, `current_date` can't be a function name.
+select current_date() = current_date();
+select curdate(1);
+
+-- conversions between date and unix_date (number of days from epoch)
+select DATE_FROM_UNIX_DATE(0), DATE_FROM_UNIX_DATE(1000), DATE_FROM_UNIX_DATE(null);
+select UNIX_DATE(DATE('1970-01-01')), UNIX_DATE(DATE('2020-12-04')), UNIX_DATE(null);
+
+select to_date(null), to_date('2016-12-31'), to_date('2016-12-31', 'yyyy-MM-dd');
+
+-- `dayofweek` accepts both date and timestamp ltz/ntz inputs.
+select dayofweek('2007-02-03'), dayofweek('2009-07-30'), dayofweek('2017-05-27'), dayofweek(null),
+ dayofweek('1582-10-15 13:10:15'), dayofweek(timestamp_ltz'1582-10-15 13:10:15'), dayofweek(timestamp_ntz'1582-10-15 13:10:15');
+
+-- `weekday` accepts both date and timestamp ltz/ntz inputs.
+select weekday('2007-02-03'), weekday('2009-07-30'), weekday('2017-05-27'), weekday(null),
+ weekday('1582-10-15 13:10:15'), weekday(timestamp_ltz'1582-10-15 13:10:15'), weekday(timestamp_ntz'1582-10-15 13:10:15');
+
+-- `year` accepts both date and timestamp ltz/ntz inputs.
+select year('1500-01-01'), year('1582-10-15 13:10:15'), year(timestamp_ltz'1582-10-15 13:10:15'), year(timestamp_ntz'1582-10-15 13:10:15');
+
+-- `month` accepts both date and timestamp ltz/ntz inputs.
+select month('1500-01-01'), month('1582-10-15 13:10:15'), month(timestamp_ltz'1582-10-15 13:10:15'), month(timestamp_ntz'1582-10-15 13:10:15');
+
+-- `dayOfYear` accepts both date and timestamp ltz/ntz inputs.
+select dayOfYear('1500-01-01'), dayOfYear('1582-10-15 13:10:15'), dayOfYear(timestamp_ltz'1582-10-15 13:10:15'), dayOfYear(timestamp_ntz'1582-10-15 13:10:15');
+
+-- next_day
+select next_day("2015-07-23", "Mon");
+select next_day("2015-07-23", "xx");
+select next_day("2015-07-23 12:12:12", "Mon");
+-- next_date does not accept timestamp lzt/ntz input
+select next_day(timestamp_ltz"2015-07-23 12:12:12", "Mon");
+select next_day(timestamp_ntz"2015-07-23 12:12:12", "Mon");
+select next_day("xx", "Mon");
+select next_day(null, "Mon");
+select next_day(null, "xx");
+
+-- date add
+select date_add(date'2011-11-11', 1);
+select date_add('2011-11-11', 1);
+select date_add('2011-11-11', 1Y);
+select date_add('2011-11-11', 1S);
+-- invalid cases: the second parameter can only be byte/short/int
+select date_add('2011-11-11', 1L);
+select date_add('2011-11-11', 1.0);
+select date_add('2011-11-11', 1E1);
+-- the second parameter can be a string literal if it can be parsed to int
+select date_add('2011-11-11', '1');
+select date_add('2011-11-11', '1.2');
+-- null input leads to null result.
+select date_add(null, 1);
+select date_add(date'2011-11-11', null);
+-- `date_add` accepts both date and timestamp ltz/ntz inputs (non-ANSI mode).
+select date_add(timestamp_ltz'2011-11-11 12:12:12', 1);
+select date_add(timestamp_ntz'2011-11-11 12:12:12', 1);
+
+-- date sub
+select date_sub(date'2011-11-11', 1);
+select date_sub('2011-11-11', 1);
+select date_sub('2011-11-11', 1Y);
+select date_sub('2011-11-11', 1S);
+-- invalid cases: the second parameter can only be byte/short/int
+select date_sub('2011-11-11', 1L);
+select date_sub('2011-11-11', 1.0);
+select date_sub('2011-11-11', 1E1);
+-- the second parameter can be a string literal if it can be parsed to int
+select date_sub(date'2011-11-11', '1');
+select date_sub(date'2011-11-11', '1.2');
+-- null input leads to null result.
+select date_sub(null, 1);
+select date_sub(date'2011-11-11', null);
+-- `date_sub` accepts both date and timestamp ltz/ntz inputs (non-ANSI mode).
+select date_sub(timestamp_ltz'2011-11-11 12:12:12', 1);
+select date_sub(timestamp_ntz'2011-11-11 12:12:12', 1);
+
+-- date add/sub with non-literal string column
+select date_add('2011-11-11', int_str) from date_view;
+select date_sub('2011-11-11', int_str) from date_view;
+select date_add(date_str, 1) from date_view;
+select date_sub(date_str, 1) from date_view;
+
+-- date +/- number
+select date '2011-11-11' + 1E1;
+select date '2001-09-28' + 7Y;
+select 7S + date '2001-09-28';
+select date '2001-10-01' - 7;
+
+-- date - date
+select date '2001-10-01' - date '2001-09-28';
+-- if one side is string/null literal, promote it to date type.
+select date '2001-10-01' - '2001-09-28';
+select '2001-10-01' - date '2001-09-28';
+select date '2001-09-28' - null;
+select null - date '2019-10-06';
+-- invalid: non-literal string column
+select date_str - date '2001-09-28' from date_view;
+select date '2001-09-28' - date_str from date_view;
+
+-- invalid: date + string literal
+select date'2011-11-11' + '1';
+select '1' + date'2011-11-11';
+
+-- null result: date + null
+select date'2011-11-11' + null;
+select null + date'2011-11-11';
+
+-- date +/- interval and interval + date
+select date '2012-01-01' - interval '2-2' year to month,
+ date '2011-11-11' - interval '2' day,
+ date '2012-01-01' + interval '-2-2' year to month,
+ date '2011-11-11' + interval '-2' month,
+ - interval '2-2' year to month + date '2012-01-01',
+ interval '-2' day + date '2011-11-11';
+
+-- Unsupported narrow text style
+select to_date('26/October/2015', 'dd/MMMMM/yyyy');
+select from_json('{"d":"26/October/2015"}', 'd Date', map('dateFormat', 'dd/MMMMM/yyyy'));
+select from_csv('26/October/2015', 'd Date', map('dateFormat', 'dd/MMMMM/yyyy'));
+
+-- Add a number of units to a timestamp or a date
+select dateadd(MICROSECOND, 1001, timestamp'2022-02-25 01:02:03.123');
+select date_add(MILLISECOND, -1, timestamp'2022-02-25 01:02:03.456');
+select dateadd(SECOND, 58, timestamp'2022-02-25 01:02:03');
+select date_add(MINUTE, -100, date'2022-02-25');
+select dateadd(HOUR, -1, timestamp'2022-02-25 01:02:03');
+select date_add(DAY, 367, date'2022-02-25');
+select dateadd(WEEK, -4, timestamp'2022-02-25 01:02:03');
+select date_add(MONTH, -1, timestamp'2022-02-25 01:02:03');
+select dateadd(QUARTER, 5, date'2022-02-25');
+select date_add(YEAR, 1, date'2022-02-25');
+
+select dateadd('MICROSECOND', 1001, timestamp'2022-02-25 01:02:03.123');
+select date_add('QUARTER', 5, date'2022-02-25');
+
+-- Get the difference between timestamps or dates in the specified units
+select datediff(MICROSECOND, timestamp'2022-02-25 01:02:03.123', timestamp'2022-02-25 01:02:03.124001');
+select date_diff(MILLISECOND, timestamp'2022-02-25 01:02:03.456', timestamp'2022-02-25 01:02:03.455');
+select datediff(SECOND, timestamp'2022-02-25 01:02:03', timestamp'2022-02-25 01:03:01');
+select date_diff(MINUTE, date'2022-02-25', timestamp'2022-02-24 22:20:00');
+select datediff(HOUR, timestamp'2022-02-25 01:02:03', timestamp'2022-02-25 00:02:03');
+select date_diff(DAY, date'2022-02-25', timestamp'2023-02-27 00:00:00');
+select datediff(WEEK, timestamp'2022-02-25 01:02:03', timestamp'2022-01-28 01:02:03');
+select date_diff(MONTH, timestamp'2022-02-25 01:02:03', timestamp'2022-01-25 01:02:03');
+select datediff(QUARTER, date'2022-02-25', date'2023-05-25');
+select date_diff(YEAR, date'2022-02-25', date'2023-02-25');
+
+select date_diff('MILLISECOND', timestamp'2022-02-25 01:02:03.456', timestamp'2022-02-25 01:02:03.455');
+select datediff('YEAR', date'2022-02-25', date'2023-02-25');
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-formatting-invalid.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-formatting-invalid.sql
new file mode 100644
index 0000000000..11bba00e91
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-formatting-invalid.sql
@@ -0,0 +1,53 @@
+--- TESTS FOR DATETIME FORMATTING FUNCTIONS WITH INVALID PATTERNS ---
+
+-- separating this from datetime-formatting.sql, because the text form
+-- for patterns with 5 letters in SimpleDateFormat varies from different JDKs
+select date_format('2018-11-17 13:33:33.333', 'GGGGG');
+-- pattern letter count can not be greater than 6
+select date_format('2018-11-17 13:33:33.333', 'yyyyyyy');
+-- q/L in JDK 8 will fail when the count is more than 2
+select date_format('2018-11-17 13:33:33.333', 'qqqqq');
+select date_format('2018-11-17 13:33:33.333', 'QQQQQ');
+select date_format('2018-11-17 13:33:33.333', 'MMMMM');
+select date_format('2018-11-17 13:33:33.333', 'LLLLL');
+
+select date_format('2018-11-17 13:33:33.333', 'EEEEE');
+select date_format('2018-11-17 13:33:33.333', 'FF');
+select date_format('2018-11-17 13:33:33.333', 'ddd');
+-- DD is invalid if the day-of-year exceeds 100, but it becomes valid in Java 11
+-- select date_format('2018-11-17 13:33:33.333', 'DD');
+select date_format('2018-11-17 13:33:33.333', 'DDDD');
+select date_format('2018-11-17 13:33:33.333', 'HHH');
+select date_format('2018-11-17 13:33:33.333', 'hhh');
+select date_format('2018-11-17 13:33:33.333', 'kkk');
+select date_format('2018-11-17 13:33:33.333', 'KKK');
+select date_format('2018-11-17 13:33:33.333', 'mmm');
+select date_format('2018-11-17 13:33:33.333', 'sss');
+select date_format('2018-11-17 13:33:33.333', 'SSSSSSSSSS');
+select date_format('2018-11-17 13:33:33.333', 'aa');
+select date_format('2018-11-17 13:33:33.333', 'V');
+select date_format('2018-11-17 13:33:33.333', 'zzzzz');
+select date_format('2018-11-17 13:33:33.333', 'XXXXXX');
+select date_format('2018-11-17 13:33:33.333', 'ZZZZZZ');
+select date_format('2018-11-17 13:33:33.333', 'OO');
+select date_format('2018-11-17 13:33:33.333', 'xxxxxx');
+
+select date_format('2018-11-17 13:33:33.333', 'A');
+select date_format('2018-11-17 13:33:33.333', 'n');
+select date_format('2018-11-17 13:33:33.333', 'N');
+select date_format('2018-11-17 13:33:33.333', 'p');
+
+-- disabled week-based patterns
+select date_format('2018-11-17 13:33:33.333', 'Y');
+select date_format('2018-11-17 13:33:33.333', 'w');
+select date_format('2018-11-17 13:33:33.333', 'W');
+select date_format('2018-11-17 13:33:33.333', 'u');
+select date_format('2018-11-17 13:33:33.333', 'e');
+select date_format('2018-11-17 13:33:33.333', 'c');
+
+-- others
+select date_format('2018-11-17 13:33:33.333', 'B');
+select date_format('2018-11-17 13:33:33.333', 'C');
+select date_format('2018-11-17 13:33:33.333', 'I');
+
+
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-formatting-legacy.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-formatting-legacy.sql
new file mode 100644
index 0000000000..19cab61a7e
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-formatting-legacy.sql
@@ -0,0 +1,2 @@
+--SET spark.sql.legacy.timeParserPolicy=LEGACY
+--IMPORT datetime-formatting.sql
\ No newline at end of file
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-formatting.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-formatting.sql
new file mode 100644
index 0000000000..3618bb5c39
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-formatting.sql
@@ -0,0 +1,73 @@
+--- TESTS FOR DATETIME FORMATTING FUNCTIONS ---
+
+create temporary view v as select col from values
+ (timestamp '1582-06-01 11:33:33.123UTC+080000'),
+ (timestamp '1970-01-01 00:00:00.000Europe/Paris'),
+ (timestamp '1970-12-31 23:59:59.999Asia/Srednekolymsk'),
+ (timestamp '1996-04-01 00:33:33.123Australia/Darwin'),
+ (timestamp '2018-11-17 13:33:33.123Z'),
+ (timestamp '2020-01-01 01:33:33.123Asia/Shanghai'),
+ (timestamp '2100-01-01 01:33:33.123America/Los_Angeles') t(col);
+
+select col, date_format(col, 'G GG GGG GGGG'), to_char(col, 'G GG GGG GGGG'), to_varchar(col, 'G GG GGG GGGG') from v;
+
+select col, date_format(col, 'y yy yyy yyyy yyyyy yyyyyy'), to_char(col, 'y yy yyy yyyy yyyyy yyyyyy'), to_varchar(col, 'y yy yyy yyyy yyyyy yyyyyy') from v;
+
+select col, date_format(col, 'q qq'), to_char(col, 'q qq'), to_varchar(col, 'q qq') from v;
+
+select col, date_format(col, 'Q QQ QQQ QQQQ'), to_char(col, 'Q QQ QQQ QQQQ'), to_varchar(col, 'Q QQ QQQ QQQQ') from v;
+
+select col, date_format(col, 'M MM MMM MMMM'), to_char(col, 'M MM MMM MMMM'), to_varchar(col, 'M MM MMM MMMM') from v;
+
+select col, date_format(col, 'L LL'), to_char(col, 'L LL'), to_varchar(col, 'L LL') from v;
+
+select col, date_format(col, 'E EE EEE EEEE'), to_char(col, 'E EE EEE EEEE'), to_varchar(col, 'E EE EEE EEEE') from v;
+
+select col, date_format(col, 'F'), to_char(col, 'F'), to_varchar(col, 'F') from v;
+
+select col, date_format(col, 'd dd'), to_char(col, 'd dd'), to_varchar(col, 'd dd') from v;
+
+select col, date_format(col, 'DD'), to_char(col, 'DD'), to_varchar(col, 'DD') from v where col = timestamp '2100-01-01 01:33:33.123America/Los_Angeles';
+select col, date_format(col, 'D DDD'), to_char(col, 'D DDD'), to_varchar(col, 'D DDD') from v;
+
+select col, date_format(col, 'H HH'), to_char(col, 'H HH'), to_varchar(col, 'H HH') from v;
+
+select col, date_format(col, 'h hh'), to_char(col, 'h hh'), to_varchar(col, 'h hh') from v;
+
+select col, date_format(col, 'k kk'), to_char(col, 'k kk'), to_varchar(col, 'k kk') from v;
+
+select col, date_format(col, 'K KK'), to_char(col, 'K KK'), to_varchar(col, 'K KK') from v;
+
+select col, date_format(col, 'm mm'), to_char(col, 'm mm'), to_varchar(col, 'm mm') from v;
+
+select col, date_format(col, 's ss'), to_char(col, 's ss'), to_varchar(col, 's ss') from v;
+
+select col, date_format(col, 'S SS SSS SSSS SSSSS SSSSSS SSSSSSS SSSSSSSS SSSSSSSSS'), to_char(col, 'S SS SSS SSSS SSSSS SSSSSS SSSSSSS SSSSSSSS SSSSSSSSS'), to_varchar(col, 'S SS SSS SSSS SSSSS SSSSSS SSSSSSS SSSSSSSS SSSSSSSSS') from v;
+
+select col, date_format(col, 'a'), to_char(col, 'a'), to_varchar(col, 'a') from v;
+
+select col, date_format(col, 'VV'), to_char(col, 'VV'), to_varchar(col, 'VV') from v;
+
+select col, date_format(col, 'z zz zzz zzzz'), to_char(col, 'z zz zzz zzzz'), to_varchar(col, 'z zz zzz zzzz') from v;
+
+select col, date_format(col, 'X XX XXX'), to_char(col, 'X XX XXX'), to_varchar(col, 'X XX XXX') from v;
+select col, date_format(col, 'XXXX XXXXX'), to_char(col, 'XXXX XXXXX'), to_varchar(col, 'XXXX XXXXX') from v;
+
+select col, date_format(col, 'Z ZZ ZZZ ZZZZ ZZZZZ'), to_char(col, 'Z ZZ ZZZ ZZZZ ZZZZZ'), to_varchar(col, 'Z ZZ ZZZ ZZZZ ZZZZZ') from v;
+
+select col, date_format(col, 'O OOOO'), to_char(col, 'O OOOO'), to_varchar(col, 'O OOOO') from v;
+
+select col, date_format(col, 'x xx xxx xxxx xxxx xxxxx'), to_char(col, 'x xx xxx xxxx xxxx xxxxx'), to_varchar(col, 'x xx xxx xxxx xxxx xxxxx') from v;
+
+-- optional pattern, but the results won't be optional for formatting
+select col, date_format(col, '[yyyy-MM-dd HH:mm:ss]'), to_char(col, '[yyyy-MM-dd HH:mm:ss]'), to_varchar(col, '[yyyy-MM-dd HH:mm:ss]') from v;
+
+-- literals
+select col, date_format(col, "姚123'GyYqQMLwWuEFDdhHmsSaVzZxXOV'"), to_char(col, "姚123'GyYqQMLwWuEFDdhHmsSaVzZxXOV'"), to_varchar(col, "姚123'GyYqQMLwWuEFDdhHmsSaVzZxXOV'") from v;
+select col, date_format(col, "''"), to_char(col, "''"), to_varchar(col, "''") from v;
+select col, date_format(col, ''), to_char(col, ''), to_varchar(col, '') from v;
+
+-- different datetime types
+select date_format(date'2023-08-18', 'yyyy-MM-dd'), to_char(date'2023-08-18', 'yyyy-MM-dd'), to_varchar(date'2023-08-18', 'yyyy-MM-dd');
+select date_format(timestamp_ltz'2023-08-18 09:13:14.123456Z', 'yyyy-MM-dd HH:mm:ss.SSSSSSZ'), to_char(timestamp_ltz'2023-08-18 09:13:14.123456Z', 'yyyy-MM-dd HH:mm:ss.SSSSSSZ'), to_varchar(timestamp_ltz'2023-08-18 09:13:14.123456Z', 'yyyy-MM-dd HH:mm:ss.SSSSSSZ');
+select date_format(timestamp_ntz'2023-08-18 09:13:14.123456', 'yyyy-MM-dd HH:mm:ss.SSSSSS'), to_char(timestamp_ntz'2023-08-18 09:13:14.123456', 'yyyy-MM-dd HH:mm:ss.SSSSSS'), to_varchar(timestamp_ntz'2023-08-18 09:13:14.123456', 'yyyy-MM-dd HH:mm:ss.SSSSSS');
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-legacy.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-legacy.sql
new file mode 100644
index 0000000000..22b29f3451
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-legacy.sql
@@ -0,0 +1,3 @@
+--SET spark.sql.legacy.timeParserPolicy=LEGACY
+--IMPORT date.sql
+--IMPORT timestamp.sql
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-parsing-invalid.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-parsing-invalid.sql
new file mode 100644
index 0000000000..1f5a9b117c
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-parsing-invalid.sql
@@ -0,0 +1,39 @@
+--- TESTS FOR DATETIME PARSING FUNCTIONS WITH INVALID VALUES ---
+
+-- parsing invalid value with pattern 'y'
+select to_timestamp('294248', 'y'); -- out of year value range [0, 294247]
+select to_timestamp('1', 'yy'); -- the number of digits must be 2 for 'yy'.
+select to_timestamp('-12', 'yy'); -- out of year value range [0, 99] for reduced two digit form
+select to_timestamp('123', 'yy'); -- the number of digits must be 2 for 'yy'.
+select to_timestamp('1', 'yyy'); -- the number of digits must be in [3, 6] for 'yyy'
+
+select to_timestamp('1234567', 'yyyyyyy'); -- the length of 'y' pattern must be less than 7
+
+-- parsing invalid values with pattern 'D'
+select to_timestamp('366', 'D');
+select to_timestamp('9', 'DD');
+select to_timestamp('366', 'DD');
+select to_timestamp('9', 'DDD');
+select to_timestamp('99', 'DDD');
+select to_timestamp('30-365', 'dd-DDD');
+select to_timestamp('11-365', 'MM-DDD');
+select to_timestamp('2019-366', 'yyyy-DDD');
+select to_timestamp('12-30-365', 'MM-dd-DDD');
+select to_timestamp('2020-01-365', 'yyyy-dd-DDD');
+select to_timestamp('2020-10-350', 'yyyy-MM-DDD');
+select to_timestamp('2020-11-31-366', 'yyyy-MM-dd-DDD');
+-- add a special case to test csv, because the legacy formatter it uses is lenient then Spark should
+-- throw SparkUpgradeException
+select from_csv('2018-366', 'date Date', map('dateFormat', 'yyyy-DDD'));
+
+-- Datetime types parse error
+select to_date("2020-01-27T20:06:11.847", "yyyy-MM-dd HH:mm:ss.SSS");
+select to_date("Unparseable", "yyyy-MM-dd HH:mm:ss.SSS");
+select to_timestamp("2020-01-27T20:06:11.847", "yyyy-MM-dd HH:mm:ss.SSS");
+select to_timestamp("Unparseable", "yyyy-MM-dd HH:mm:ss.SSS");
+select unix_timestamp("2020-01-27T20:06:11.847", "yyyy-MM-dd HH:mm:ss.SSS");
+select unix_timestamp("Unparseable", "yyyy-MM-dd HH:mm:ss.SSS");
+select to_unix_timestamp("2020-01-27T20:06:11.847", "yyyy-MM-dd HH:mm:ss.SSS");
+select to_unix_timestamp("Unparseable", "yyyy-MM-dd HH:mm:ss.SSS");
+select cast("Unparseable" as timestamp);
+select cast("Unparseable" as date);
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-parsing-legacy.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-parsing-legacy.sql
new file mode 100644
index 0000000000..ee1afe502a
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-parsing-legacy.sql
@@ -0,0 +1,2 @@
+--SET spark.sql.legacy.timeParserPolicy=LEGACY
+--IMPORT datetime-parsing.sql
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-parsing.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-parsing.sql
new file mode 100644
index 0000000000..f87ae55686
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-parsing.sql
@@ -0,0 +1,45 @@
+--- TESTS FOR DATETIME PARSING FUNCTIONS ---
+
+-- parsing with pattern 'y'.
+-- the range of valid year is [-290307, 294247],
+-- but particularly, some thrift client use java.sql.Timestamp to parse timestamp, which allows
+-- only positive year values less or equal than 9999. So the cases bellow only use [1, 9999] to pass
+-- ThriftServerQueryTestSuite
+select to_timestamp('1', 'y');
+select to_timestamp('009999', 'y');
+
+-- reduced two digit form is used, the range of valid year is 20-[01, 99]
+select to_timestamp('00', 'yy');
+select to_timestamp('99', 'yy');
+
+-- the range of valid year is [-290307, 294247], the number of digits must be in [3, 6] for 'yyy'
+select to_timestamp('001', 'yyy');
+select to_timestamp('009999', 'yyy');
+
+-- the range of valid year is [-9999, 9999], the number of digits must be 4 for 'yyyy'.
+select to_timestamp('0001', 'yyyy');
+select to_timestamp('9999', 'yyyy');
+
+-- the range of valid year is [-99999, 99999], the number of digits must be 5 for 'yyyyy'.
+select to_timestamp('00001', 'yyyyy');
+select to_timestamp('09999', 'yyyyy');
+
+-- the range of valid year is [-290307, 294247], the number of digits must be 6 for 'yyyyyy'.
+select to_timestamp('000001', 'yyyyyy');
+select to_timestamp('009999', 'yyyyyy');
+
+-- parsing with pattern 'D'
+select to_timestamp('9', 'D');
+select to_timestamp('300', 'D');
+select to_timestamp('09', 'DD');
+select to_timestamp('99', 'DD');
+select to_timestamp('100', 'DD');
+select to_timestamp('009', 'DDD');
+select to_timestamp('365', 'DDD');
+select to_timestamp('31-365', 'dd-DDD');
+select to_timestamp('12-365', 'MM-DDD');
+select to_timestamp('2020-365', 'yyyy-DDD');
+select to_timestamp('12-31-365', 'MM-dd-DDD');
+select to_timestamp('2020-30-365', 'yyyy-dd-DDD');
+select to_timestamp('2020-12-350', 'yyyy-MM-DDD');
+select to_timestamp('2020-12-31-366', 'yyyy-MM-dd-DDD');
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-special.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-special.sql
new file mode 100644
index 0000000000..2699274bb7
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/datetime-special.sql
@@ -0,0 +1,10 @@
+-- special date and timestamp values that are not allowed in the SQL standard
+-- these tests are put in this separated file because they don't work in JDBC environment
+
+-- date with year outside [0000-9999]
+select date'999999-03-18', date'-0001-1-28', date'0015';
+select make_date(999999, 3, 18), make_date(-1, 1, 28);
+
+-- timestamp with year outside [0000-9999]
+select timestamp'-1969-12-31 16:00:00', timestamp'-0015-03-18 16:00:00', timestamp'-000001', timestamp'99999-03-18T12:03:17';
+select make_timestamp(-1969, 12, 31, 16, 0, 0.0), make_timestamp(-15, 3, 18, 16, 0, 0.0), make_timestamp(99999, 3, 18, 12, 3, 17.0);
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/decimalArithmeticOperations.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/decimalArithmeticOperations.sql
new file mode 100644
index 0000000000..13bbd9d81b
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/decimalArithmeticOperations.sql
@@ -0,0 +1,125 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one or more
+-- contributor license agreements. See the NOTICE file distributed with
+-- this work for additional information regarding copyright ownership.
+-- The ASF licenses this file to You under the Apache License, Version 2.0
+-- (the "License"); you may not use this file except in compliance with
+-- the License. You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+
+CREATE TEMPORARY VIEW t AS SELECT 1.0 as a, 0.0 as b;
+
+-- division, remainder and pmod by 0 return NULL
+select a / b from t;
+select a % b from t;
+select pmod(a, b) from t;
+
+-- tests for decimals handling in operations
+create table decimals_test(id int, a decimal(38,18), b decimal(38,18)) using parquet;
+
+insert into decimals_test values(1, 100.0, 999.0), (2, 12345.123, 12345.123),
+ (3, 0.1234567891011, 1234.1), (4, 123456789123456789.0, 1.123456789123456789);
+
+-- test decimal operations
+select id, a+b, a-b, a*b, a/b from decimals_test order by id;
+
+-- test operations between decimals and constants
+select id, a*10, b/10 from decimals_test order by id;
+
+-- test operations on constants
+select 10.3 * 3.0;
+select 10.3000 * 3.0;
+select 10.30000 * 30.0;
+select 10.300000000000000000 * 3.000000000000000000;
+select 10.300000000000000000 * 3.0000000000000000000;
+select 2.35E10 * 1.0;
+
+-- arithmetic operations causing an overflow return NULL
+select (5e36BD + 0.1) + 5e36BD;
+select (-4e36BD - 0.1) - 7e36BD;
+select 12345678901234567890.0 * 12345678901234567890.0;
+select 1e35BD / 0.1;
+select 1.2345678901234567890E30BD * 1.2345678901234567890E25BD;
+
+-- arithmetic operations causing a precision loss are truncated
+select 12345678912345678912345678912.1234567 + 9999999999999999999999999999999.12345;
+select 123456789123456789.1234567890 * 1.123456789123456789;
+select 12345678912345.123456789123 / 0.000000012345678;
+
+-- union decimal type
+
+SELECT CAST(20 AS DECIMAL(4, 1))
+UNION ALL
+SELECT CAST(10 AS DECIMAL(3, 1)) + CAST(90 AS DECIMAL(3, 1));
+
+SELECT CAST(20 AS DECIMAL(4, 1))
+UNION ALL
+SELECT CAST(10 AS DECIMAL(3, 1)) - CAST(-90 AS DECIMAL(3, 1));
+
+SELECT CAST(20 AS DECIMAL(4, 1))
+UNION ALL
+SELECT CAST(10 AS DECIMAL(3, 1)) * CAST(10 AS DECIMAL(3, 1));
+
+SELECT CAST(20 AS DECIMAL(4, 1))
+UNION ALL
+SELECT CAST(10 AS DECIMAL(3, 1)) / CAST(10 AS DECIMAL(3, 1));
+
+SELECT CAST(20 AS DECIMAL(4, 1))
+UNION ALL
+SELECT CAST(10 AS DECIMAL(10, 2)) % CAST(3 AS DECIMAL(5, 1));
+
+SELECT CAST(20 AS DECIMAL(4, 1))
+UNION ALL
+SELECT pmod(CAST(10 AS DECIMAL(10, 2)), CAST(3 AS DECIMAL(5, 1)));
+
+SELECT CAST(20 AS DECIMAL(4, 1))
+UNION ALL
+SELECT CAST(10 AS DECIMAL(10, 2)) div CAST(3 AS DECIMAL(5, 1));
+
+-- return NULL instead of rounding, according to old Spark versions' behavior
+set spark.sql.decimalOperations.allowPrecisionLoss=false;
+
+-- test decimal operations
+select /*+ COALESCE(1) */ id, a+b, a-b, a*b, a/b from decimals_test order by id;
+
+-- test operations between decimals and constants
+select id, a*10, b/10 from decimals_test order by id;
+
+-- test operations on constants
+select 10.3 * 3.0;
+select 10.3000 * 3.0;
+select 10.30000 * 30.0;
+select 10.300000000000000000 * 3.000000000000000000;
+select 10.300000000000000000 * 3.0000000000000000000;
+select 2.35E10 * 1.0;
+
+-- arithmetic operations causing an overflow return NULL
+select (5e36BD + 0.1) + 5e36BD;
+select (-4e36BD - 0.1) - 7e36BD;
+select 12345678901234567890.0 * 12345678901234567890.0;
+select 1e35BD / 0.1;
+select 1.2345678901234567890E30BD * 1.2345678901234567890E25BD;
+
+-- arithmetic operations causing a precision loss return NULL
+select 12345678912345678912345678912.1234567 + 9999999999999999999999999999999.12345;
+select 123456789123456789.1234567890 * 1.123456789123456789;
+select 12345678912345.123456789123 / 0.000000012345678;
+
+select 1.0123456789012345678901234567890123456e36BD / 0.1;
+select 1.0123456789012345678901234567890123456e35BD / 1.0;
+select 1.0123456789012345678901234567890123456e34BD / 1.0;
+select 1.0123456789012345678901234567890123456e33BD / 1.0;
+select 1.0123456789012345678901234567890123456e32BD / 1.0;
+select 1.0123456789012345678901234567890123456e31BD / 1.0;
+select 1.0123456789012345678901234567890123456e31BD / 0.1;
+select 1.0123456789012345678901234567890123456e31BD / 10.0;
+
+drop table decimals_test;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/describe-part-after-analyze.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/describe-part-after-analyze.sql
new file mode 100644
index 0000000000..f4239da906
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/describe-part-after-analyze.sql
@@ -0,0 +1,34 @@
+CREATE TABLE t (key STRING, value STRING, ds STRING, hr INT) USING parquet
+ PARTITIONED BY (ds, hr);
+
+INSERT INTO TABLE t PARTITION (ds='2017-08-01', hr=10)
+VALUES ('k1', 100), ('k2', 200), ('k3', 300);
+
+INSERT INTO TABLE t PARTITION (ds='2017-08-01', hr=11)
+VALUES ('k1', 101), ('k2', 201), ('k3', 301), ('k4', 401);
+
+INSERT INTO TABLE t PARTITION (ds='2017-09-01', hr=5)
+VALUES ('k1', 102), ('k2', 202);
+
+DESC EXTENDED t PARTITION (ds='2017-08-01', hr=10);
+
+-- Collect stats for a single partition
+ANALYZE TABLE t PARTITION (ds='2017-08-01', hr=10) COMPUTE STATISTICS;
+
+DESC EXTENDED t PARTITION (ds='2017-08-01', hr=10);
+
+-- Collect stats for 2 partitions
+ANALYZE TABLE t PARTITION (ds='2017-08-01') COMPUTE STATISTICS;
+
+DESC EXTENDED t PARTITION (ds='2017-08-01', hr=10);
+DESC EXTENDED t PARTITION (ds='2017-08-01', hr=11);
+
+-- Collect stats for all partitions
+ANALYZE TABLE t PARTITION (ds, hr) COMPUTE STATISTICS;
+
+DESC EXTENDED t PARTITION (ds='2017-08-01', hr=10);
+DESC EXTENDED t PARTITION (ds='2017-08-01', hr=11);
+DESC EXTENDED t PARTITION (ds='2017-09-01', hr=5);
+
+-- DROP TEST TABLES/VIEWS
+DROP TABLE t;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/describe-query.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/describe-query.sql
new file mode 100644
index 0000000000..f8fbb43ba2
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/describe-query.sql
@@ -0,0 +1,31 @@
+-- Test tables
+CREATE table desc_temp1 (key int COMMENT 'column_comment', val string) USING PARQUET;
+CREATE table desc_temp2 (key int, val string) USING PARQUET;
+
+-- Simple Describe query
+DESC SELECT key, key + 1 as plusone FROM desc_temp1;
+DESC QUERY SELECT * FROM desc_temp2;
+DESC SELECT key, COUNT(*) as count FROM desc_temp1 group by key;
+DESC SELECT 10.00D as col1;
+DESC QUERY SELECT key FROM desc_temp1 UNION ALL select CAST(1 AS DOUBLE);
+DESC QUERY VALUES(1.00D, 'hello') as tab1(col1, col2);
+DESC QUERY FROM desc_temp1 a SELECT *;
+DESC WITH s AS (SELECT 'hello' as col1) SELECT * FROM s;
+DESCRIBE QUERY WITH s AS (SELECT * from desc_temp1) SELECT * FROM s;
+DESCRIBE SELECT * FROM (FROM desc_temp2 select * select *);
+
+-- Error cases.
+DESCRIBE INSERT INTO desc_temp1 values (1, 'val1');
+DESCRIBE INSERT INTO desc_temp1 SELECT * FROM desc_temp2;
+DESCRIBE
+ FROM desc_temp1 a
+ insert into desc_temp1 select *
+ insert into desc_temp2 select *;
+
+-- Explain
+EXPLAIN DESC QUERY SELECT * FROM desc_temp2 WHERE key > 0;
+EXPLAIN EXTENDED DESC WITH s AS (SELECT 'hello' as col1) SELECT * FROM s;
+
+-- cleanup
+DROP TABLE desc_temp1;
+DROP TABLE desc_temp2;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/describe-table-after-alter-table.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/describe-table-after-alter-table.sql
new file mode 100644
index 0000000000..69bff6656c
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/describe-table-after-alter-table.sql
@@ -0,0 +1,29 @@
+CREATE TABLE table_with_comment (a STRING, b INT, c STRING, d STRING) USING parquet COMMENT 'added';
+
+DESC FORMATTED table_with_comment;
+
+-- ALTER TABLE BY MODIFYING COMMENT
+ALTER TABLE table_with_comment SET TBLPROPERTIES("comment"= "modified comment", "type"= "parquet");
+
+DESC FORMATTED table_with_comment;
+
+-- DROP TEST TABLE
+DROP TABLE table_with_comment;
+
+-- CREATE TABLE WITHOUT COMMENT
+CREATE TABLE table_comment (a STRING, b INT) USING parquet;
+
+DESC FORMATTED table_comment;
+
+-- ALTER TABLE BY ADDING COMMENT
+ALTER TABLE table_comment SET TBLPROPERTIES(comment = "added comment");
+
+DESC formatted table_comment;
+
+-- ALTER UNSET PROPERTIES COMMENT
+ALTER TABLE table_comment UNSET TBLPROPERTIES IF EXISTS ('comment');
+
+DESC FORMATTED table_comment;
+
+-- DROP TEST TABLE
+DROP TABLE table_comment;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/describe.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/describe.sql
new file mode 100644
index 0000000000..dbe5bc840b
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/describe.sql
@@ -0,0 +1,145 @@
+CREATE TABLE t (a STRING, b INT, c STRING, d STRING) USING parquet
+ OPTIONS (a '1', b '2', password 'password')
+ PARTITIONED BY (c, d) CLUSTERED BY (a) SORTED BY (b ASC) INTO 2 BUCKETS
+ COMMENT 'table_comment'
+ TBLPROPERTIES (t 'test', password 'password');
+
+CREATE TEMPORARY VIEW temp_v AS SELECT * FROM t;
+
+CREATE TEMPORARY VIEW temp_Data_Source_View
+ USING org.apache.spark.sql.sources.DDLScanSource
+ OPTIONS (
+ From '1',
+ To '10',
+ Table 'test1');
+
+CREATE VIEW v AS SELECT * FROM t;
+
+ALTER TABLE t SET TBLPROPERTIES (e = '3');
+
+ALTER TABLE t ADD PARTITION (c='Us', d=1);
+
+DESCRIBE t;
+
+DESCRIBE EXTENDED t AS JSON;
+
+-- AnalysisException: describe table as json must be extended
+DESCRIBE t AS JSON;
+
+-- AnalysisException: describe col as json unsupported
+DESC FORMATTED t a AS JSON;
+
+DESC default.t;
+
+DESC TABLE t;
+
+DESC FORMATTED t;
+
+DESC EXTENDED t;
+
+ALTER TABLE t UNSET TBLPROPERTIES (e);
+
+DESC EXTENDED t;
+
+ALTER TABLE t UNSET TBLPROPERTIES (comment);
+
+DESC EXTENDED t;
+
+DESC t PARTITION (c='Us', d=1);
+
+DESC EXTENDED t PARTITION (c='Us', d=1) AS JSON;
+
+DESC EXTENDED t PARTITION (c='Us', d=1);
+
+DESC FORMATTED t PARTITION (c='Us', d=1);
+
+DESC EXTENDED t PARTITION (C='Us', D=1);
+
+-- NoSuchPartitionException: Partition not found in table
+DESC t PARTITION (c='Us', d=2);
+
+-- AnalysisException: Partition spec is invalid
+DESC t PARTITION (c='Us');
+
+-- ParseException: PARTITION specification is incomplete
+DESC t PARTITION (c='Us', d);
+
+-- DESC Temp View
+
+DESC temp_v;
+
+DESC TABLE temp_v;
+
+DESC FORMATTED temp_v;
+
+DESC EXTENDED temp_v;
+
+DESC temp_Data_Source_View;
+
+-- AnalysisException DESC PARTITION is not allowed on a temporary view
+DESC temp_v PARTITION (c='Us', d=1);
+
+-- DESC Persistent View
+
+DESC v;
+
+DESC TABLE v;
+
+DESC FORMATTED v;
+
+DESC EXTENDED v;
+
+-- AnalysisException DESC PARTITION is not allowed on a view
+DESC v PARTITION (c='Us', d=1);
+
+-- Explain Describe Table
+EXPLAIN DESC t;
+EXPLAIN DESC EXTENDED t;
+EXPLAIN EXTENDED DESC t;
+EXPLAIN DESCRIBE t b;
+EXPLAIN DESCRIBE t PARTITION (c='Us', d=2);
+EXPLAIN DESCRIBE EXTENDED t PARTITION (c='Us', d=2) AS JSON;
+
+-- Show column default values
+CREATE TABLE d (a STRING DEFAULT 'default-value', b INT DEFAULT 42) USING parquet COMMENT 'table_comment';
+
+DESC d;
+
+DESC EXTENDED d;
+
+DESC TABLE EXTENDED d;
+
+DESC FORMATTED d;
+
+-- Show column default values with newlines in the string
+CREATE TABLE e (a STRING DEFAULT CONCAT('a\n b\n ', 'c\n d'), b INT DEFAULT 42) USING parquet COMMENT 'table_comment';
+
+DESC e;
+
+DESC EXTENDED e;
+
+DESC TABLE EXTENDED e;
+
+DESC FORMATTED e;
+
+CREATE TABLE f USING json PARTITIONED BY (B, C) AS SELECT 'APACHE' A, CAST('SPARK' AS BINARY) B, TIMESTAMP'2018-11-17 13:33:33' C;
+
+DESC FORMATTED f PARTITION (B='SPARK', C=TIMESTAMP'2018-11-17 13:33:33');
+
+DESC TABLE EXTENDED f PARTITION (B='SPARK', C=TIMESTAMP'2018-11-17 13:33:33') AS JSON;
+
+-- DROP TEST TABLES/VIEWS
+
+DROP VIEW temp_v;
+
+DROP VIEW temp_Data_Source_View;
+
+DROP VIEW v;
+
+DROP TABLE t;
+
+DROP TABLE d;
+
+DROP TABLE e;
+
+DROP TABLE f;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/double-quoted-identifiers-enabled.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/double-quoted-identifiers-enabled.sql
new file mode 100644
index 0000000000..9547d011c7
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/double-quoted-identifiers-enabled.sql
@@ -0,0 +1,3 @@
+--SET spark.sql.ansi.doubleQuotedIdentifiers=true
+--IMPORT double-quoted-identifiers.sql
+
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/double-quoted-identifiers.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/double-quoted-identifiers.sql
new file mode 100644
index 0000000000..ffb52b4033
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/double-quoted-identifiers.sql
@@ -0,0 +1,57 @@
+-- All these should error out in the parser
+SELECT 1 FROM "not_exist";
+
+USE SCHEMA "not_exist";
+
+ALTER TABLE "not_exist" ADD COLUMN not_exist int;
+
+ALTER TABLE not_exist ADD COLUMN "not_exist" int;
+
+SELECT 1 AS "not_exist" FROM not_exist;
+
+SELECT 1 FROM not_exist AS X("hello");
+
+SELECT "not_exist"();
+
+SELECT "not_exist".not_exist();
+
+-- All these should error out in analysis
+SELECT 1 FROM `hello`;
+
+USE SCHEMA `not_exist`;
+
+ALTER TABLE `not_exist` ADD COLUMN not_exist int;
+
+ALTER TABLE not_exist ADD COLUMN `not_exist` int;
+
+SELECT 1 AS `not_exist` FROM `not_exist`;
+
+SELECT 1 FROM not_exist AS X(`hello`);
+
+SELECT `not_exist`();
+
+SELECT `not_exist`.not_exist();
+
+-- Strings in various situations all work
+SELECT "hello";
+
+CREATE TEMPORARY VIEW v(c1 COMMENT "hello") AS SELECT 1;
+DROP VIEW v;
+
+SELECT INTERVAL "1" YEAR;
+
+-- Single ticks still work
+SELECT 'hello';
+
+CREATE TEMPORARY VIEW v(c1 COMMENT 'hello') AS SELECT 1;
+DROP VIEW v;
+
+SELECT INTERVAL '1' YEAR;
+
+-- A whole scenario
+CREATE SCHEMA "myschema";
+CREATE TEMPORARY VIEW "myview"("c1") AS
+ WITH "v"("a") AS (SELECT 1) SELECT "a" FROM "v";
+SELECT "a1" AS "a2" FROM "myview" AS "atab"("a1");
+DROP TABLE "myview";
+DROP SCHEMA "myschema";
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/except-all.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/except-all.sql
new file mode 100644
index 0000000000..e28f0721a6
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/except-all.sql
@@ -0,0 +1,160 @@
+CREATE TEMPORARY VIEW tab1 AS SELECT * FROM VALUES
+ (0), (1), (2), (2), (2), (2), (3), (null), (null) AS tab1(c1);
+CREATE TEMPORARY VIEW tab2 AS SELECT * FROM VALUES
+ (1), (2), (2), (3), (5), (5), (null) AS tab2(c1);
+CREATE TEMPORARY VIEW tab3 AS SELECT * FROM VALUES
+ (1, 2),
+ (1, 2),
+ (1, 3),
+ (2, 3),
+ (2, 2)
+ AS tab3(k, v);
+CREATE TEMPORARY VIEW tab4 AS SELECT * FROM VALUES
+ (1, 2),
+ (2, 3),
+ (2, 2),
+ (2, 2),
+ (2, 20)
+ AS tab4(k, v);
+
+-- Basic EXCEPT ALL
+SELECT * FROM tab1
+EXCEPT ALL
+SELECT * FROM tab2;
+
+-- MINUS ALL (synonym for EXCEPT)
+SELECT * FROM tab1
+MINUS ALL
+SELECT * FROM tab2;
+
+-- EXCEPT ALL same table in both branches
+SELECT * FROM tab1
+EXCEPT ALL
+SELECT * FROM tab2 WHERE c1 IS NOT NULL;
+
+-- Empty left relation
+SELECT * FROM tab1 WHERE c1 > 5
+EXCEPT ALL
+SELECT * FROM tab2;
+
+-- Empty right relation
+SELECT * FROM tab1
+EXCEPT ALL
+SELECT * FROM tab2 WHERE c1 > 6;
+
+-- Type Coerced ExceptAll
+SELECT * FROM tab1
+EXCEPT ALL
+SELECT CAST(1 AS BIGINT);
+
+-- Error as types of two side are not compatible
+SELECT * FROM tab1
+EXCEPT ALL
+SELECT array(1);
+
+-- Basic
+SELECT * FROM tab3
+EXCEPT ALL
+SELECT * FROM tab4;
+
+-- Basic
+SELECT * FROM tab4
+EXCEPT ALL
+SELECT * FROM tab3;
+
+-- EXCEPT ALL + INTERSECT
+SELECT * FROM tab4
+EXCEPT ALL
+SELECT * FROM tab3
+INTERSECT DISTINCT
+SELECT * FROM tab4;
+
+-- EXCEPT ALL + EXCEPT
+SELECT * FROM tab4
+EXCEPT ALL
+SELECT * FROM tab3
+EXCEPT DISTINCT
+SELECT * FROM tab4;
+
+-- Chain of set operations
+SELECT * FROM tab3
+EXCEPT ALL
+SELECT * FROM tab4
+UNION ALL
+SELECT * FROM tab3
+EXCEPT DISTINCT
+SELECT * FROM tab4;
+
+-- Mismatch on number of columns across both branches
+SELECT k FROM tab3
+EXCEPT ALL
+SELECT k, v FROM tab4;
+
+-- Chain of set operations
+SELECT * FROM tab3
+EXCEPT ALL
+SELECT * FROM tab4
+UNION
+SELECT * FROM tab3
+EXCEPT DISTINCT
+SELECT * FROM tab4;
+
+-- Using MINUS ALL
+SELECT * FROM tab3
+MINUS ALL
+SELECT * FROM tab4
+UNION
+SELECT * FROM tab3
+MINUS DISTINCT
+SELECT * FROM tab4;
+
+-- Chain of set operations
+SELECT * FROM tab3
+EXCEPT ALL
+SELECT * FROM tab4
+EXCEPT DISTINCT
+SELECT * FROM tab3
+EXCEPT DISTINCT
+SELECT * FROM tab4;
+
+-- Join under except all. Should produce empty resultset since both left and right sets
+-- are same.
+SELECT *
+FROM (SELECT tab3.k,
+ tab4.v
+ FROM tab3
+ JOIN tab4
+ ON tab3.k = tab4.k)
+EXCEPT ALL
+SELECT *
+FROM (SELECT tab3.k,
+ tab4.v
+ FROM tab3
+ JOIN tab4
+ ON tab3.k = tab4.k);
+
+-- Join under except all (2)
+SELECT *
+FROM (SELECT tab3.k,
+ tab4.v
+ FROM tab3
+ JOIN tab4
+ ON tab3.k = tab4.k)
+EXCEPT ALL
+SELECT *
+FROM (SELECT tab4.v AS k,
+ tab3.k AS v
+ FROM tab3
+ JOIN tab4
+ ON tab3.k = tab4.k);
+
+-- Group by under ExceptAll
+SELECT v FROM tab3 GROUP BY v
+EXCEPT ALL
+SELECT k FROM tab4 GROUP BY k;
+
+-- Clean-up
+DROP VIEW IF EXISTS tab1;
+DROP VIEW IF EXISTS tab2;
+DROP VIEW IF EXISTS tab3;
+DROP VIEW IF EXISTS tab4;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/except.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/except.sql
new file mode 100644
index 0000000000..ffdf1f4f3d
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/except.sql
@@ -0,0 +1,76 @@
+-- Tests different scenarios of except operation
+create temporary view t1 as select * from values
+ ("one", 1),
+ ("two", 2),
+ ("three", 3),
+ ("one", NULL)
+ as t1(k, v);
+
+create temporary view t2 as select * from values
+ ("one", 1),
+ ("two", 22),
+ ("one", 5),
+ ("one", NULL),
+ (NULL, 5)
+ as t2(k, v);
+
+
+-- Except operation that will be replaced by left anti join
+SELECT * FROM t1 EXCEPT SELECT * FROM t2;
+
+
+-- Except operation that will be replaced by Filter: SPARK-22181
+SELECT * FROM t1 EXCEPT SELECT * FROM t1 where v <> 1 and v <> 2;
+
+
+-- Except operation that will be replaced by Filter: SPARK-22181
+SELECT * FROM t1 where v <> 1 and v <> 22 EXCEPT SELECT * FROM t1 where v <> 2 and v >= 3;
+
+
+-- Except operation that will be replaced by Filter: SPARK-22181
+SELECT t1.* FROM t1, t2 where t1.k = t2.k
+EXCEPT
+SELECT t1.* FROM t1, t2 where t1.k = t2.k and t1.k != 'one';
+
+
+-- Except operation that will be replaced by left anti join
+SELECT * FROM t2 where v >= 1 and v <> 22 EXCEPT SELECT * FROM t1;
+
+
+-- Except operation that will be replaced by left anti join
+SELECT (SELECT min(k) FROM t2 WHERE t2.k = t1.k) min_t2 FROM t1
+MINUS
+SELECT (SELECT min(k) FROM t2) abs_min_t2 FROM t1 WHERE t1.k = 'one';
+
+
+-- Except operation that will be replaced by left anti join
+SELECT t1.k
+FROM t1
+WHERE t1.v <= (SELECT max(t2.v)
+ FROM t2
+ WHERE t2.k = t1.k)
+MINUS
+SELECT t1.k
+FROM t1
+WHERE t1.v >= (SELECT min(t2.v)
+ FROM t2
+ WHERE t2.k = t1.k);
+
+-- SPARK-32638: corrects references when adding aliases in WidenSetOperationTypes
+CREATE OR REPLACE TEMPORARY VIEW t3 AS VALUES (decimal(1)) tbl(v);
+SELECT t.v FROM (
+ SELECT v FROM t3
+ EXCEPT
+ SELECT v + v AS v FROM t3
+) t;
+
+SELECT SUM(t.v) FROM (
+ SELECT v FROM t3
+ EXCEPT
+ SELECT v + v AS v FROM t3
+) t;
+
+-- Clean-up
+DROP VIEW IF EXISTS t1;
+DROP VIEW IF EXISTS t2;
+DROP VIEW IF EXISTS t3;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/execute-immediate.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/execute-immediate.sql
new file mode 100644
index 0000000000..f7d27c6c0b
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/execute-immediate.sql
@@ -0,0 +1,149 @@
+-- Automatically generated by SQLQueryTestSuite
+-- !query
+CREATE TEMPORARY VIEW tbl_view AS SELECT * FROM VALUES
+ (10, 'name1', named_struct('f1', 1, 's2', named_struct('f2', 101, 'f3', 'a'))),
+ (20, 'name2', named_struct('f1', 2, 's2', named_struct('f2', 202, 'f3', 'b'))),
+ (30, 'name3', named_struct('f1', 3, 's2', named_struct('f2', 303, 'f3', 'c'))),
+ (40, 'name4', named_struct('f1', 4, 's2', named_struct('f2', 404, 'f3', 'd'))),
+ (50, 'name5', named_struct('f1', 5, 's2', named_struct('f2', 505, 'f3', 'e'))),
+ (60, 'name6', named_struct('f1', 6, 's2', named_struct('f2', 606, 'f3', 'f'))),
+ (70, 'name7', named_struct('f1', 7, 's2', named_struct('f2', 707, 'f3', 'g')))
+AS tbl_view(id, name, data);
+CREATE TABLE x (id INT) USING csv;
+
+DECLARE sql_string STRING;
+SET VAR sql_string = 'SELECT * from tbl_view where name = \'name1\'';
+
+-- test commands
+EXECUTE IMMEDIATE 'SET spark.sql.ansi.enabled=true';
+EXECUTE IMMEDIATE 'CREATE TEMPORARY VIEW IDENTIFIER(:tblName) AS SELECT id, name FROM tbl_view' USING 'tbl_view_tmp' as tblName;
+EXECUTE IMMEDIATE 'SELECT * FROM tbl_view_tmp';
+
+EXECUTE IMMEDIATE 'REFRESH TABLE IDENTIFIER(:tblName)' USING 'x' as tblName;
+
+-- test execute immediate without parameters
+EXECUTE IMMEDIATE sql_string;
+EXECUTE IMMEDIATE 'SELECT * from tbl_view where name = \'name1\'';
+
+-- test positional parameters
+SET VAR sql_string = 'SELECT * from tbl_view where name = ? or name = ?';
+DECLARE a STRING;
+SET VAR a = 'name1';
+EXECUTE IMMEDIATE sql_string USING 'name1', 'name3';
+EXECUTE IMMEDIATE sql_string USING a, 'name2';
+EXECUTE IMMEDIATE 'SELECT * from tbl_view where name = ? or name = ?' USING 'name1', 'name3';
+EXECUTE IMMEDIATE 'SELECT * from tbl_view where name = ? or name = ?' USING a, 'name2';
+EXECUTE IMMEDIATE 'SELECT * from tbl_view where name = ? or name = ?' USING (a, 'name2');
+-- test positional command
+EXECUTE IMMEDIATE 'INSERT INTO x VALUES(?)' USING 1;
+SELECT * from x;
+
+-- test named parameters
+SET VAR sql_string = 'SELECT * from tbl_view where name = :first or id = :second';
+DECLARE b INT;
+SET VAR b = 40;
+EXECUTE IMMEDIATE sql_string USING 40 as second, 'name7' as first;
+EXECUTE IMMEDIATE sql_string USING b as second, 'name7' as first;
+EXECUTE IMMEDIATE 'SELECT * from tbl_view where name = :first or id = :second' USING 40 as second, 'name7' as first;
+EXECUTE IMMEDIATE 'SELECT * from tbl_view where name = :first or id = :second' USING 'name7' as first, b as second;
+-- named parameter used multiple times
+EXECUTE IMMEDIATE 'SELECT tbl_view.*, :first as p FROM tbl_view WHERE name = :first' USING 'name7' as first;
+
+-- test named command and setup for next test
+EXECUTE IMMEDIATE 'SET VAR sql_string = ?' USING 'SELECT id from tbl_view where name = :first';
+SELECT sql_string;
+
+-- test into
+DECLARE res_id INT;
+EXECUTE IMMEDIATE sql_string INTO res_id USING 'name7' as first;
+SELECT res_id;
+EXECUTE IMMEDIATE sql_string INTO res_id USING a as first;
+SELECT res_id;
+
+-- test into without using
+SET VAR sql_string = 'SELECT * from tbl_view where name = :first or id = :second';
+EXECUTE IMMEDIATE 'SELECT 42' INTO res_id;
+SELECT res_id;
+
+-- multiple INTOs
+EXECUTE IMMEDIATE 'SELECT id, name FROM tbl_view WHERE id = ?' INTO b, a USING 10;
+SELECT b, a;
+
+-- use AS for using positional params
+EXECUTE IMMEDIATE 'SELECT * FROM tbl_view where id = ? AND name = ?' USING b as first, a;
+
+-- empty query
+EXECUTE IMMEDIATE 'SELECT 42 WHERE 2 = 1' INTO res_id;
+SELECT res_id;
+
+-- implicit casting
+EXECUTE IMMEDIATE 'SELECT \'1707\'' INTO res_id;
+SELECT res_id;
+
+-- test errors
+-- string to int error
+EXECUTE IMMEDIATE 'SELECT \'invalid_cast_error_expected\'' INTO res_id;
+
+-- require query when using INTO
+EXECUTE IMMEDIATE 'INSERT INTO x VALUES (?)' INTO res_id USING 1;
+
+-- use column in using - should fail as we expect variable here
+EXECUTE IMMEDIATE 'SELECT * FROM tbl_view WHERE ? = id' USING id;
+
+-- either positional or named parameters must be used
+EXECUTE IMMEDIATE 'SELECT * FROM tbl_view where ? = id and :first = name' USING 1, 'name2' as first;
+
+-- all paramerers must be named
+EXECUTE IMMEDIATE 'SELECT * FROM tbl_view where :first = name' USING 1, 'name2' as first;
+
+-- internal syntax error
+EXECUTE IMMEDIATE 'SELCT Fa';
+
+-- internal syntax error - test that both parseQuery and parsePlan fail
+EXECUTE IMMEDIATE 'SELCT Fa' INTO res_id;
+
+-- Parameter passed must be STRING
+EXECUTE IMMEDIATE b;
+
+-- test expressions should fail with parser error
+SET VAR sql_string = 'SELECT * from tbl_view where name = :first or id = :second';
+SET VAR a = 'na';
+
+-- expressions not supported - feature not supported
+EXECUTE IMMEDIATE 'SELECT * from tbl_view where name = :first' USING CONCAT(a , "me1") as first;
+EXECUTE IMMEDIATE 'SELECT * from tbl_view where name = :first' USING (SELECT 42) as first, 'name2' as second;
+
+-- INTO variables not matching scalar types
+EXECUTE IMMEDIATE 'SELECT id, name FROM tbl_view WHERE id = ?' INTO a, b USING 10;
+
+-- INTO does not support braces - parser error
+EXECUTE IMMEDIATE 'SELECT id, name FROM tbl_view WHERE id = ?' INTO (a, b) USING 10;
+
+-- Error too many rows
+EXECUTE IMMEDIATE 'SELECT id FROM tbl_view' INTO res_id;
+
+-- Error mismatch cardinality
+EXECUTE IMMEDIATE 'SELECT id, data.f1 FROM tbl_view' INTO res_id;
+EXECUTE IMMEDIATE 'SELECT id FROM tbl_view' INTO res_id, b;
+
+-- duplicate aliases
+EXECUTE IMMEDIATE 'SELECT id FROM tbl_view WHERE id = :first' USING 10 as first, 20 as first;
+
+-- no alias
+DECLARE p = 10;
+EXECUTE IMMEDIATE 'SELECT id FROM tbl_view WHERE id = :p' USING p;
+
+-- mixing literals and named parameters
+EXECUTE IMMEDIATE 'SELECT id FROM tbl_view WHERE id = :p' USING p, 'p';
+
+-- duplicate into entry
+EXECUTE IMMEDIATE 'SELECT id, data.f1 FROM tbl_view WHERE id = 10' INTO res_id, res_id;
+
+-- nested execute immediate
+EXECUTE IMMEDIATE 'EXECUTE IMMEDIATE \'SELECT id FROM tbl_view WHERE id = ? USING 10\'';
+
+-- sqlString is null
+SET VAR sql_string = null;
+EXECUTE IMMEDIATE sql_string;
+
+DROP TABLE x;
\ No newline at end of file
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/explain-aqe.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/explain-aqe.sql
new file mode 100644
index 0000000000..7aef901da4
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/explain-aqe.sql
@@ -0,0 +1,4 @@
+--IMPORT explain.sql
+
+--SET spark.sql.adaptive.enabled=true
+--SET spark.sql.maxMetadataStringLength = 500
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/explain-cbo.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/explain-cbo.sql
new file mode 100644
index 0000000000..eeb2180f7a
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/explain-cbo.sql
@@ -0,0 +1,27 @@
+--SET spark.sql.cbo.enabled=true
+--SET spark.sql.maxMetadataStringLength = 500
+
+CREATE TABLE explain_temp1(a INT, b INT) USING PARQUET;
+CREATE TABLE explain_temp2(c INT, d INT) USING PARQUET;
+
+ANALYZE TABLE explain_temp1 COMPUTE STATISTICS FOR ALL COLUMNS;
+ANALYZE TABLE explain_temp2 COMPUTE STATISTICS FOR ALL COLUMNS;
+
+EXPLAIN COST WITH max_store_sales AS
+(
+ SELECT max(csales) tpcds_cmax
+ FROM (
+ SELECT sum(b) csales
+ FROM explain_temp1 WHERE a < 100
+ ) x
+),
+best_ss_customer AS
+(
+ SELECT c
+ FROM explain_temp2
+ WHERE d > (SELECT * FROM max_store_sales)
+)
+SELECT c FROM best_ss_customer;
+
+DROP TABLE explain_temp1;
+DROP TABLE explain_temp2;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/explain.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/explain.sql
new file mode 100644
index 0000000000..698ca009b4
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/explain.sql
@@ -0,0 +1,136 @@
+--SET spark.sql.codegen.wholeStage = true
+--SET spark.sql.adaptive.enabled = false
+--SET spark.sql.maxMetadataStringLength = 500
+
+-- Test tables
+CREATE table explain_temp1 (key int, val int) USING PARQUET;
+CREATE table explain_temp2 (key int, val int) USING PARQUET;
+CREATE table explain_temp3 (key int, val int) USING PARQUET;
+CREATE table explain_temp4 (key int, val string) USING PARQUET;
+CREATE table explain_temp5 (key int) USING PARQUET PARTITIONED BY(val string);
+
+SET spark.sql.codegen.wholeStage = true;
+
+-- distinct func
+EXPLAIN EXTENDED
+ SELECT sum(distinct val)
+ FROM explain_temp1;
+
+-- single table
+EXPLAIN FORMATTED
+ SELECT key, max(val)
+ FROM explain_temp1
+ WHERE key > 0
+ GROUP BY key
+ ORDER BY key;
+
+EXPLAIN FORMATTED
+ SELECT key, max(val)
+ FROM explain_temp1
+ WHERE key > 0
+ GROUP BY key
+ HAVING max(val) > 0;
+
+-- simple union
+EXPLAIN FORMATTED
+ SELECT key, val FROM explain_temp1 WHERE key > 0
+ UNION
+ SELECT key, val FROM explain_temp1 WHERE key > 1;
+
+-- Join
+EXPLAIN FORMATTED
+ SELECT *
+ FROM explain_temp1 a,
+ explain_temp2 b
+ WHERE a.key = b.key;
+
+EXPLAIN FORMATTED
+ SELECT *
+ FROM explain_temp1 a
+ LEFT OUTER JOIN explain_temp2 b
+ ON a.key = b.key;
+
+-- Subqueries nested.
+EXPLAIN FORMATTED
+ SELECT *
+ FROM explain_temp1
+ WHERE key = (SELECT max(key)
+ FROM explain_temp2
+ WHERE key = (SELECT max(key)
+ FROM explain_temp3
+ WHERE val > 0)
+ AND val = 2)
+ AND val > 3;
+
+EXPLAIN FORMATTED
+ SELECT *
+ FROM explain_temp1
+ WHERE key = (SELECT max(key)
+ FROM explain_temp2
+ WHERE val > 0)
+ OR
+ key = (SELECT avg(key)
+ FROM explain_temp3
+ WHERE val > 0);
+
+-- Reuse subquery
+EXPLAIN FORMATTED
+ SELECT (SELECT Avg(key) FROM explain_temp1) + (SELECT Avg(key) FROM explain_temp1)
+ FROM explain_temp1;
+
+-- CTE + ReuseExchange
+EXPLAIN FORMATTED
+ WITH cte1 AS (
+ SELECT *
+ FROM explain_temp1
+ WHERE key > 10
+ )
+ SELECT * FROM cte1 a, cte1 b WHERE a.key = b.key;
+
+EXPLAIN FORMATTED
+ WITH cte1 AS (
+ SELECT key, max(val)
+ FROM explain_temp1
+ WHERE key > 10
+ GROUP BY key
+ )
+ SELECT * FROM cte1 a, cte1 b WHERE a.key = b.key;
+
+-- A spark plan which has innerChildren other than subquery
+EXPLAIN FORMATTED
+ CREATE VIEW explain_view AS
+ SELECT key, val FROM explain_temp1;
+
+-- HashAggregate
+EXPLAIN FORMATTED
+ SELECT
+ COUNT(val) + SUM(key) as TOTAL,
+ COUNT(key) FILTER (WHERE val > 1)
+ FROM explain_temp1;
+
+-- ObjectHashAggregate
+EXPLAIN FORMATTED
+ SELECT key, sort_array(collect_set(val))[0]
+ FROM explain_temp4
+ GROUP BY key;
+
+-- SortAggregate
+EXPLAIN FORMATTED
+ SELECT key, MIN(val)
+ FROM explain_temp4
+ GROUP BY key;
+
+-- V1 Write
+EXPLAIN EXTENDED INSERT INTO TABLE explain_temp5 SELECT * FROM explain_temp4;
+
+-- cleanup
+DROP TABLE explain_temp1;
+DROP TABLE explain_temp2;
+DROP TABLE explain_temp3;
+DROP TABLE explain_temp4;
+DROP TABLE explain_temp5;
+
+-- SPARK-35479: Format PartitionFilters IN strings in scan nodes
+CREATE table t(v array<string>) USING PARQUET;
+EXPLAIN SELECT * FROM t WHERE v IN (array('a'), null);
+DROP TABLE t;
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/extract.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/extract.sql
new file mode 100644
index 0000000000..5fd3362c69
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/extract.sql
@@ -0,0 +1,167 @@
+CREATE TEMPORARY VIEW t AS select '2011-05-06 07:08:09.1234567' as c, to_timestamp_ntz('2011-05-06 07:08:09.1234567') as ntz, interval 10 year 20 month as i, interval 30 day 40 hour 50 minute 6.7890 second as j;
+
+select extract(year from c), extract(year from ntz), extract(year from i) from t;
+select extract(y from c), extract(y from ntz), extract(y from i) from t;
+select extract(years from c), extract(years from ntz), extract(years from i) from t;
+select extract(yr from c), extract(yr from ntz), extract(yr from i) from t;
+select extract(yrs from c), extract(yrs from ntz), extract(yrs from i) from t;
+
+select extract(yearofweek from c), extract(yearofweek from ntz) from t;
+
+select extract(quarter from c), extract(quarter from ntz) from t;
+select extract(qtr from c), extract(qtr from ntz) from t;
+
+select extract(month from c), extract(month from ntz), extract(month from i) from t;
+select extract(mon from c), extract(mon from ntz), extract(mon from i) from t;
+select extract(mons from c), extract(mons from ntz), extract(mons from i) from t;
+select extract(months from c), extract(months from ntz), extract(months from i) from t;
+
+select extract(week from c), extract(week from ntz) from t;
+select extract(w from c), extract(w from ntz) from t;
+select extract(weeks from c), extract(weeks from ntz) from t;
+
+select extract(day from c), extract(day from ntz), extract(day from j) from t;
+select extract(d from c), extract(d from ntz), extract(d from j) from t;
+select extract(days from c), extract(days from ntz), extract(days from j) from t;
+
+select extract(dayofweek from c), extract(dayofweek from ntz) from t;
+select extract(dow from c), extract(dow from ntz) from t;
+
+select extract(dayofweek_iso from c), extract(dayofweek_iso from ntz) from t;
+select extract(dow_iso from c), extract(dow_iso from ntz) from t;
+
+select extract(doy from c), extract(doy from ntz) from t;
+
+select extract(hour from c), extract(hour from ntz), extract(hour from j) from t;
+select extract(h from c), extract(h from ntz), extract(h from j) from t;
+select extract(hours from c), extract(hours from ntz), extract(hours from j) from t;
+select extract(hr from c), extract(hr from ntz), extract(hr from j) from t;
+select extract(hrs from c), extract(hrs from ntz), extract(hrs from j) from t;
+
+select extract(minute from c), extract(minute from ntz), extract(minute from j) from t;
+select extract(m from c), extract(m from ntz), extract(m from j) from t;
+select extract(min from c), extract(min from ntz), extract(min from j) from t;
+select extract(mins from c), extract(mins from ntz), extract(mins from j) from t;
+select extract(minutes from c), extract(minutes from ntz), extract(minutes from j) from t;
+
+select extract(second from c), extract(second from ntz), extract(second from j) from t;
+select extract(s from c), extract(s from ntz), extract(s from j) from t;
+select extract(sec from c), extract(sec from ntz), extract(sec from j) from t;
+select extract(seconds from c), extract(seconds from ntz), extract(seconds from j) from t;
+select extract(secs from c), extract(secs from ntz), extract(secs from j) from t;
+
+select extract(not_supported from c) from t;
+select extract(not_supported from i) from t;
+select extract(not_supported from j) from t;
+
+select date_part('year', c), date_part('year', ntz), date_part('year', i) from t;
+select date_part('y', c), date_part('y', ntz), date_part('y', i) from t;
+select date_part('years', c), date_part('years', ntz), date_part('years', i) from t;
+select date_part('yr', c), date_part('yr', ntz), date_part('yr', i) from t;
+select date_part('yrs', c), date_part('yrs', ntz), date_part('yrs', i) from t;
+
+select date_part('yearofweek', c), date_part('yearofweek', ntz) from t;
+
+select date_part('quarter', c), date_part('quarter', ntz) from t;
+select date_part('qtr', c), date_part('qtr', ntz) from t;
+
+select date_part('month', c), date_part('month', ntz), date_part('month', i) from t;
+select date_part('mon', c), date_part('mon', ntz), date_part('mon', i) from t;
+select date_part('mons', c), date_part('mons', ntz), date_part('mons', i) from t;
+select date_part('months', c), date_part('months', ntz), date_part('months', i) from t;
+
+select date_part('week', c), date_part('week', ntz) from t;
+select date_part('w', c), date_part('w', ntz) from t;
+select date_part('weeks', c), date_part('weeks', ntz) from t;
+
+select date_part('day', c), date_part('day', ntz), date_part('day', j) from t;
+select date_part('d', c), date_part('d', ntz), date_part('d', j) from t;
+select date_part('days', c), date_part('days', ntz), date_part('days', j) from t;
+
+select date_part('dayofweek', c), date_part('dayofweek', ntz) from t;
+select date_part('dow', c), date_part('dow', ntz) from t;
+
+select date_part('dayofweek_iso', c), date_part('dayofweek_iso', ntz) from t;
+select date_part('dow_iso', c), date_part('dow_iso', ntz) from t;
+
+select date_part('doy', c), date_part('doy', ntz) from t;
+
+select date_part('hour', c), date_part('hour', ntz), date_part('hour', j) from t;
+select date_part('h', c), date_part('h', ntz), date_part('h', j) from t;
+select date_part('hours', c), date_part('hours', ntz), date_part('hours', j) from t;
+select date_part('hr', c), date_part('hr', ntz), date_part('hr', j) from t;
+select date_part('hrs', c), date_part('hrs', ntz), date_part('hrs', j) from t;
+
+select date_part('minute', c), date_part('minute', ntz), date_part('minute', j) from t;
+select date_part('m', c), date_part('m', ntz), date_part('m', j) from t;
+select date_part('min', c), date_part('min', ntz), date_part('min', j) from t;
+select date_part('mins', c), date_part('mins', ntz), date_part('mins', j) from t;
+select date_part('minutes', c), date_part('minutes', ntz), date_part('minutes', j) from t;
+
+select date_part('second', c), date_part('second', ntz), date_part('second', j) from t;
+select date_part('s', c), date_part('s', ntz), date_part('s', j) from t;
+select date_part('sec', c), date_part('sec', ntz), date_part('sec', j) from t;
+select date_part('seconds', c), date_part('seconds', ntz), date_part('seconds', j) from t;
+select date_part('secs', c), date_part('secs', ntz), date_part('secs', j) from t;
+
+select date_part('not_supported', c) from t;
+select date_part(c, c) from t;
+select date_part(null, c) from t;
+
+select date_part(i, i) from t;
+select date_part(null, i) from t;
+
+-- In SPARK-31476, we've supported extract('field', source), too
+select extract('year', c) from t;
+select extract('quarter', c) from t;
+select extract('month', c) from t;
+select extract('week', c) from t;
+select extract('day', c) from t;
+select extract('days', c) from t;
+select extract('dayofweek', c) from t;
+select extract('dow', c) from t;
+select extract('doy', c) from t;
+select extract('hour', c) from t;
+select extract('minute', c) from t;
+select extract('second', c) from t;
+
+select c - j from t;
+select day(c - j) from t;
+select extract(day from c - j) from t;
+select extract(month from to_timestamp(c) - i) from t;
+select extract(second from to_timestamp(c) - j) from t;
+
+-- extract fields from year-month/day-time intervals
+select extract(YEAR from interval '2-1' YEAR TO MONTH);
+select date_part('YEAR', interval '2-1' YEAR TO MONTH);
+select extract(YEAR from -interval '2-1' YEAR TO MONTH);
+select extract(MONTH from interval '2-1' YEAR TO MONTH);
+select date_part('MONTH', interval '2-1' YEAR TO MONTH);
+select extract(MONTH from -interval '2-1' YEAR TO MONTH);
+select date_part(NULL, interval '2-1' YEAR TO MONTH);
+
+-- invalid
+select extract(DAY from interval '2-1' YEAR TO MONTH);
+select date_part('DAY', interval '2-1' YEAR TO MONTH);
+select date_part('not_supported', interval '2-1' YEAR TO MONTH);
+
+select extract(DAY from interval '123 12:34:56.789123123' DAY TO SECOND);
+select date_part('DAY', interval '123 12:34:56.789123123' DAY TO SECOND);
+select extract(DAY from -interval '123 12:34:56.789123123' DAY TO SECOND);
+select extract(HOUR from interval '123 12:34:56.789123123' DAY TO SECOND);
+select date_part('HOUR', interval '123 12:34:56.789123123' DAY TO SECOND);
+select extract(HOUR from -interval '123 12:34:56.789123123' DAY TO SECOND);
+select extract(MINUTE from interval '123 12:34:56.789123123' DAY TO SECOND);
+select date_part('MINUTE', interval '123 12:34:56.789123123' DAY TO SECOND);
+select extract(MINUTE from -interval '123 12:34:56.789123123' DAY TO SECOND);
+select extract(SECOND from interval '123 12:34:56.789123123' DAY TO SECOND);
+select date_part('SECOND', interval '123 12:34:56.789123123' DAY TO SECOND);
+select extract(SECOND from -interval '123 12:34:56.789123123' DAY TO SECOND);
+select date_part(NULL, interval '123 12:34:56.789123123' DAY TO SECOND);
+
+select extract(MONTH from interval '123 12:34:56.789123123' DAY TO SECOND);
+select date_part('not_supported', interval '123 12:34:56.789123123' DAY TO SECOND);
+
+-- alias for date_part
+select datepart('year', c), datepart('year', ntz), datepart('year', i) from t;
+select datepart('DAY', interval '123 12:34:56.789123123' DAY TO SECOND);
diff --git a/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/group-analytics.sql b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/group-analytics.sql
new file mode 100644
index 0000000000..d6381e59e0
--- /dev/null
+++ b/gluten-ut/spark40/src/test/resources/backends-velox/sql-tests/inputs/group-analytics.sql
@@ -0,0 +1,93 @@
+CREATE OR REPLACE TEMPORARY VIEW testData AS SELECT * FROM VALUES
+(1, 1), (1, 2), (2, 1), (2, 2), (3, 1), (3, 2)
... 283553 lines suppressed ...
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@gluten.apache.org
For additional commands, e-mail: commits-help@gluten.apache.org