|
| 1 | +-- Licensed to the Apache Software Foundation (ASF) under one |
| 2 | +-- or more contributor license agreements. See the NOTICE file |
| 3 | +-- distributed with this work for additional information |
| 4 | +-- regarding copyright ownership. The ASF licenses this file |
| 5 | +-- to you under the Apache License, Version 2.0 (the |
| 6 | +-- "License"); you may not use this file except in compliance |
| 7 | +-- with the License. You may obtain a copy of the License at |
| 8 | +-- |
| 9 | +-- http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | +-- |
| 11 | +-- Unless required by applicable law or agreed to in writing, |
| 12 | +-- software distributed under the License is distributed on an |
| 13 | +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 14 | +-- KIND, either express or implied. See the License for the |
| 15 | +-- specific language governing permissions and limitations |
| 16 | +-- under the License. |
| 17 | + |
| 18 | +-- MinSparkVersion: 4.0 |
| 19 | + |
| 20 | +-- Spark 4.0+ widens NextDay's dayOfWeek argument to collated strings, but NextDay resolves it |
| 21 | +-- through DateTimeUtils.getDayOfWeekFromString, which upper-cases with Locale.ROOT and matches a |
| 22 | +-- fixed literal set. That match takes no collation and the result is a DateType, so collation |
| 23 | +-- cannot change the answer. The native kernel reads the argument as raw bytes though, so a |
| 24 | +-- collated dayOfWeek is reported as Incompatible and routed through the JVM codegen dispatcher, |
| 25 | +-- which runs Spark's own doGenCode inside the Comet pipeline. That keeps the projection in Comet |
| 26 | +-- and is measurably faster than the native path: 70ms against 89ms for Spark over 1M rows. See |
| 27 | +-- https://github.com/apache/datafusion-comet/issues/5591. |
| 28 | + |
| 29 | +-- This harness disables ConstantFolding, so `x COLLATE ...` survives as a `Collate` node rather |
| 30 | +-- than folding into a collated literal. Comet has no serde for `Collate`, but that does not matter |
| 31 | +-- here: the dispatcher compiles the whole bound subtree with Spark's own doGenCode, `Collate` |
| 32 | +-- included. That is one reason dispatching covers every spelling of a collated argument. |
| 33 | + |
| 34 | +statement |
| 35 | +CREATE TABLE test_next_day_collated(d date, dow string) USING parquet |
| 36 | + |
| 37 | +statement |
| 38 | +INSERT INTO test_next_day_collated VALUES |
| 39 | + (date('2023-01-01'), 'Monday'), |
| 40 | + (date('2024-02-29'), 'MON'), |
| 41 | + (date('1969-12-31'), 'mo'), |
| 42 | + (date('2024-06-15'), 'notaday'), |
| 43 | + (date('2024-01-01'), NULL), |
| 44 | + (NULL, 'Monday') |
| 45 | + |
| 46 | +-- collated column argument: proves a collated column reaches the Comet operator at all |
| 47 | +query |
| 48 | +SELECT d, next_day(d, dow COLLATE UTF8_LCASE) FROM test_next_day_collated |
| 49 | + |
| 50 | +-- collated literal argument |
| 51 | +query |
| 52 | +SELECT d, next_day(d, 'Monday' COLLATE UTF8_LCASE) FROM test_next_day_collated |
| 53 | + |
| 54 | +-- Spark upper-cases the day name before matching, so all three spellings must agree under a |
| 55 | +-- case-insensitive collation exactly as they do under UTF8_BINARY. |
| 56 | +query |
| 57 | +SELECT next_day(d, 'monday' COLLATE UTF8_LCASE), next_day(d, 'MoNdAy' COLLATE UTF8_LCASE), next_day(d, 'mO' COLLATE UTF8_LCASE) FROM test_next_day_collated |
| 58 | + |
| 59 | +-- a second ICU collation, to show the guard is not UTF8_LCASE-only |
| 60 | +query |
| 61 | +SELECT d, next_day(d, dow COLLATE UNICODE_CI) FROM test_next_day_collated |
| 62 | + |
| 63 | +query |
| 64 | +SELECT next_day(d, 'Monday' COLLATE UNICODE_CI) FROM test_next_day_collated |
| 65 | + |
| 66 | +-- unrecognised day name returns NULL outside ANSI mode (ANSI is covered by next_day_ansi.sql) |
| 67 | +query |
| 68 | +SELECT next_day(date('2024-01-01'), 'notaday' COLLATE UTF8_LCASE) |
| 69 | + |
| 70 | +-- Collation does not introduce trimming: getDayOfWeekFromString matches character for character, |
| 71 | +-- so a padded value is still NULL. Mirrors the whitespace case in next_day.sql. |
| 72 | +query |
| 73 | +SELECT next_day(date('2024-01-01'), ' MO ' COLLATE UTF8_LCASE), next_day(date('2024-01-01'), 'MO ' COLLATE UTF8_LCASE) |
| 74 | + |
| 75 | +-- RTRIM collations are the case where trimming looks plausible: NextDay's inputTypes accept them |
| 76 | +-- (StringTypeWithCollation(supportsTrimCollation = true)), and CollationFactory right-trims when |
| 77 | +-- building a *collation key*. getDayOfWeekFromString never builds one, so a padded day name is |
| 78 | +-- still unmatched and the answer is still NULL, exactly as under UTF8_BINARY. |
| 79 | +query |
| 80 | +SELECT next_day(date('2024-01-01'), 'MON' COLLATE UTF8_BINARY_RTRIM), next_day(date('2024-01-01'), 'MON ' COLLATE UTF8_BINARY_RTRIM) |
| 81 | + |
| 82 | +query |
| 83 | +SELECT next_day(date('2024-01-01'), 'mon' COLLATE UTF8_LCASE_RTRIM), next_day(date('2024-01-01'), 'mon ' COLLATE UTF8_LCASE_RTRIM) |
| 84 | + |
| 85 | +-- literal + literal |
| 86 | +query |
| 87 | +SELECT next_day(date('2023-01-01'), 'Monday' COLLATE UTF8_LCASE), next_day(date('2023-01-01'), 'Sun' COLLATE UNICODE_CI) |
| 88 | + |
| 89 | +-- A NULL-literal dayOfWeek is omitted: NextDay is nullIntolerant, so NullPropagation folds the |
| 90 | +-- whole call to a NULL literal before Comet sees it. The NULL rows in the table above cover |
| 91 | +-- NULL-in-data for both arguments. |
0 commit comments