github-actions[bot] commented on code in PR #68301:
URL: https://github.com/apache/doris/pull/68301#discussion_r4068110842
##########
be/src/core/value/timestamptz_value.cpp:
##########
@@ -65,6 +73,14 @@ std::string TimestampTzValue::to_string(const
cctz::time_zone& tz, int scale) co
buffer[len++] = ':';
buffer[len++] = static_cast<char>('0' + offset_mins / 10);
buffer[len++] = '0' + offset_mins % 10;
+ // Historical zones can have sub-minute offsets. Dropping their seconds
changes the
+ // instant represented by the client-visible wall clock and offset when
read back.
+ const int offset_seconds = abs_offset % 60;
Review Comment:
[P2] Update the FE typed-literal parser for the new offset grammar. This
formatter can now return `1890-01-01 08:05:43.123456+08:05:43`, and both BE
parsers accept it, but `DateLiteralUtils` recognizes and strips only a
six-character `+HH:MM` suffix. Nereids column-default validation delegates
TIMESTAMPTZ strings there, so copying this result into a DEFAULT leaves five
colon-separated time parts and is rejected. Also, `ZoneId.of(tzString)` cannot
represent offsets beyond Java's 18-hour limit even though these changed BE
branches accept every offset below 24 hours. Please handle the full BE wire
range in the shared parser and add formatter-to-`ColumnDefinition` round trips
for second-granularity and >18-hour offsets.
##########
be/src/core/data_type_serde/data_type_varbinary_serde.cpp:
##########
@@ -301,6 +305,82 @@ Status
DataTypeVarbinarySerDe::deserialize_one_cell_from_json(IColumn& column, S
return Status::OK();
}
+Status DataTypeVarbinarySerDe::from_string(StringRef& str, IColumn& column,
+ const FormatOptions& options) const
{
+ // Partition structs use the same hex representation as nested VARBINARY
output. Decode it
+ // before appending so arbitrary bytes survive JSON transport instead of
becoming NULL.
+ if (str.size < 2 || str.data[0] != '0' || str.data[1] != 'x' || (str.size
- 2) % 2 != 0 ||
+ str.size - 2 > std::numeric_limits<int>::max()) {
+ return Status::InvalidArgument("Invalid VARBINARY hex representation");
+ }
+ // The INT_MAX guard also makes narrowing to the decoder's 32-bit offset
type safe.
+ const auto hex_size = cast_set<ColumnString::Offset>(str.size - 2);
+ std::string bytes(hex_size / 2, '\0');
+ if (string_hex::hex_decode(str.data + 2, hex_size, bytes.data()) !=
bytes.size()) {
+ return Status::InvalidArgument("Invalid VARBINARY hex representation");
+ }
+ assert_cast<ColumnVarbinary&>(column).insert_data(bytes.data(),
bytes.size());
+ return Status::OK();
+}
+
+Status DataTypeVarbinarySerDe::deserialize_one_cell_from_hive_text(
+ IColumn& column, Slice& slice, const FormatOptions& options,
+ int hive_text_complex_type_delimiter_level) const {
+ // Hive LazyBinary uses lenient Base64 (including URL-safe letters and
whitespace),
+ // falling back to the original bytes for non-Base64 input or an empty
decoding.
+ // Keep this separate from JSON/CSV: those formats do not share Hive's
encoding contract.
+ std::string encoded;
Review Comment:
[P1] Put these full-cell Hive staging buffers behind Doris's checked
allocator. For every valid binary field this reserves `slice.size` in
`encoded`, `base64_decode` then resizes a second `std::string` to the same
size, and `ColumnVarbinary` finally copies the decoded bytes into its arena.
Ordinary `std::string` storage does not run the `Allocator<false>` admission
check, so one large external field can build roughly two input-sized buffers
before the tracked column allocation rejects it; the new write path likewise
materializes both `value.to_string()` and its Base64 output. Please
decode/encode directly into checked destination storage (and avoid the hex
path's equivalent whole-cell temporary), with a limited-memory scan/write test.
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArrayFunctionUtils.java:
##########
@@ -0,0 +1,42 @@
+// 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.doris.nereids.trees.expressions.functions.scalar;
+
+import org.apache.doris.nereids.exceptions.AnalysisException;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.DataType;
+
+/** Argument validation shared by array functions. */
+final class ArrayFunctionUtils {
+ private ArrayFunctionUtils() {
+ }
+
+ static void checkNoVarBinaryArguments(ScalarFunction function) {
+ // Inspect original arguments before coercion can hide unsupported
binary comparison/hash inputs.
+ for (Expression argument : function.getArguments()) {
+ DataType type = argument.getDataType();
+ while (type instanceof ArrayType) {
+ type = ((ArrayType) type).getItemType();
+ }
+ if (type.isVarBinaryType()) {
Review Comment:
[P2] Reject the resolved execution type rather than every original argument.
For `array_contains(ARRAY<STRING>, VARBINARY)`, the FOLLOW signature resolves
the scalar to STRING and the existing implicit cast feeds the supported BE
string kernel; `array_position`, `count_equal`, `array_remove`, and
`array_contains_all` share that pattern. With default new type coercion,
indexed-Any common-type selection likewise resolves mixed
`ARRAY<STRING>`/`ARRAY<VARBINARY>` inputs to STRING for `arrays_overlap`,
`array_except`, and `array_union`, whose BE implementations have `ColumnString`
paths. This guard rejects all of them before coercion, and the new mixed-type
test locks in the regression. Please reject signatures that resolve to
VARBINARY, but allow binary inputs that resolve to supported execution types.
##########
be/src/core/data_type_serde/data_type_varbinary_serde.cpp:
##########
@@ -301,6 +305,82 @@ Status
DataTypeVarbinarySerDe::deserialize_one_cell_from_json(IColumn& column, S
return Status::OK();
}
+Status DataTypeVarbinarySerDe::from_string(StringRef& str, IColumn& column,
+ const FormatOptions& options) const
{
+ // Partition structs use the same hex representation as nested VARBINARY
output. Decode it
+ // before appending so arbitrary bytes survive JSON transport instead of
becoming NULL.
+ if (str.size < 2 || str.data[0] != '0' || str.data[1] != 'x' || (str.size
- 2) % 2 != 0 ||
+ str.size - 2 > std::numeric_limits<int>::max()) {
+ return Status::InvalidArgument("Invalid VARBINARY hex representation");
+ }
+ // The INT_MAX guard also makes narrowing to the decoder's 32-bit offset
type safe.
+ const auto hex_size = cast_set<ColumnString::Offset>(str.size - 2);
+ std::string bytes(hex_size / 2, '\0');
+ if (string_hex::hex_decode(str.data + 2, hex_size, bytes.data()) !=
bytes.size()) {
+ return Status::InvalidArgument("Invalid VARBINARY hex representation");
+ }
+ assert_cast<ColumnVarbinary&>(column).insert_data(bytes.data(),
bytes.size());
+ return Status::OK();
+}
+
+Status DataTypeVarbinarySerDe::deserialize_one_cell_from_hive_text(
Review Comment:
[P1] Propagate the Hive BINARY decoding contract instead of guessing it from
each cell. Hive 4 supports `hive.serialization.decode.binary.as.base64=false`
for raw TEXTFILE values, but FE drops that property, so a configured raw value
such as `test` is silently Base64-decoded here to different bytes. In default
mode Hive 4/current `LazyBinary` also uses the strict Basic decoder with raw
fallback, while this code accepts URL-safe letters/whitespace and truncates a
one-sextet tail (for example Hive preserves `-_8=` but Doris returns `0xfb
0xff`). Please pass the property/version-selected mode through
`TFileAttributes`, use the matching decoder, and cover raw plus Hive 3/4 Base64
cases. See the [Hive TEXTFILE
contract](https://hive.apache.org/docs/latest/language/languagemanual-ddl/#storage-formats)
and [Hive 4
`LazyBinary`](https://github.com/apache/hive/blob/rel/release-4.0.1/serde/src/java/org/apache/hadoop/hive/serde2/lazy/LazyBinary.java#L43-L57).
##########
be/src/exprs/function/cast/cast_to_datetimev2_impl.hpp:
##########
@@ -705,24 +706,47 @@ inline bool
CastToDatetimeV2::from_string_strict_mode_internal(
SET_PARAMS_RET_FALSE_IFN((consume_digit<UInt32, 2>(ptr, end,
part[0])),
"invalid hour offset '{}'",
std::string {ptr, end});
}
- SET_PARAMS_RET_FALSE_IFN(part[0] <= 14, "invalid hour offset
'{}'", part[0]);
+ SET_PARAMS_RET_FALSE_IFN(
+ part[0] < (type == DataTimeCastEnumType::TIMESTAMP_TZ ?
24U : 15U),
Review Comment:
[P1] Apply the offset before rejecting a fractional carry at the local-year
boundary. This branch now admits `+15:00`, but both BE parsers round the local
civil value before parsing/applying that offset. Thus `CAST('9999-12-31
23:59:59.5+15:00' AS TIMESTAMPTZ(0))` tries to carry the local value into year
10000 and errors (or becomes NULL in non-strict mode) before the offset can
produce the valid UTC value `9999-12-31 09:00:00+00:00`. FE folding converts to
UTC before scale rounding and returns that value, so `debug_skip_fold_constant`
changes the result. Please defer this carry/range validation until after offset
conversion and cover folded/non-folded strict and non-strict boundary cases.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]