wgtmac commented on code in PR #701:
URL: https://github.com/apache/iceberg-cpp/pull/701#discussion_r3499949188


##########
src/iceberg/table_scan.cc:
##########
@@ -545,11 +574,50 @@ Result<std::vector<std::shared_ptr<FileScanTask>>> 
DataTableScan::PlanFiles() co
       .FilterData(filter())
       .IgnoreDeleted()
       .ColumnsToKeepStats(context_.columns_to_keep_stats)
-      .PlanWith(context_.plan_executor);
+      .PlanWith(context_.plan_executor)
+      .ScanMetrics(scan_metrics);
   if (context_.ignore_residuals) {
     manifest_group->IgnoreResiduals();
   }
-  return manifest_group->PlanFiles();
+  ICEBERG_ASSIGN_OR_RAISE(auto tasks, manifest_group->PlanFiles());
+
+  timed.Stop();
+
+  if (context_.metrics_reporter) {
+    ICEBERG_ASSIGN_OR_RAISE(auto projected_schema, ResolveProjectedSchema());
+    const auto& schema_ptr = projected_schema.get();
+
+    ICEBERG_ASSIGN_OR_RAISE(auto projected_id_set,
+                            GetProjectedIdsVisitor::GetProjectedIds(
+                                *schema_ptr, /*include_struct_ids=*/true));
+    std::vector<int32_t> projected_field_ids(projected_id_set.begin(),
+                                             projected_id_set.end());
+    std::ranges::sort(projected_field_ids);
+
+    std::vector<std::string> projected_field_names;
+    projected_field_names.reserve(projected_field_ids.size());
+    for (int32_t field_id : projected_field_ids) {
+      ICEBERG_ASSIGN_OR_RAISE(auto field_name, 
schema_ptr->FindColumnNameById(field_id));
+      projected_field_names.emplace_back(field_name.value_or(""));

Review Comment:
   `field_id` comes from the projected schema, so failing to resolve its name 
would indicate a schema/cache bug. Emitting an empty field name would hide that 
invariant violation in the scan report; this should return an error instead of 
`value_or("")`.



##########
src/iceberg/expression/sanitize_expression.cc:
##########
@@ -0,0 +1,347 @@
+/*
+ * 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.
+ */
+
+#include "iceberg/expression/sanitize_expression.h"
+
+#include <chrono>
+#include <cmath>
+#include <cstdint>
+#include <format>
+#include <limits>
+#include <regex>
+#include <string>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+#include "iceberg/expression/binder.h"
+#include "iceberg/expression/literal.h"
+#include "iceberg/expression/predicate.h"
+#include "iceberg/expression/term.h"
+#include "iceberg/transform.h"
+#include "iceberg/type.h"
+#include "iceberg/util/bucket_util.h"
+#include "iceberg/util/checked_cast.h"
+#include "iceberg/util/temporal_util.h"
+
+namespace iceberg {
+
+namespace {
+
+std::string SanitizeDate(int32_t days, int32_t today) {
+  std::string is_past = today > days ? "ago" : "from-now";
+  int32_t diff = std::abs(today - days);
+  if (diff == 0) {
+    return "(date-today)";
+  } else if (diff < 90) {
+    return "(date-" + std::to_string(diff) + "-days-" + is_past + ")";
+  }
+
+  return "(date)";
+}
+
+std::string SanitizeTimestamp(int64_t micros, int64_t now) {
+  constexpr int64_t kMicrosPerHour = 60LL * 60LL * 1'000'000LL;
+  constexpr int64_t kFiveMinutesInMicros = 5LL * 60LL * 1'000'000LL;
+  constexpr int64_t kThreeDaysInHours = 3LL * 24LL;
+  constexpr int64_t kNinetyDaysInHours = 90LL * 24LL;
+
+  std::string is_past = now > micros ? "ago" : "from-now";
+  int64_t diff = std::abs(now - micros);

Review Comment:
   This subtraction can overflow before `std::abs` when the sanitized timestamp 
is near the `int64_t` limits. It is an edge case, but using a saturating or 
unsigned distance would avoid undefined behavior in the sanitizer.



-- 
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]

Reply via email to