From 44be37843c0599abb64073fe737ce146e30b3aa5 Mon Sep 17 00:00:00 2001 From: Nathan Fox Date: Fri, 23 Jun 2023 12:57:59 -0400 Subject: [PATCH] feat: add metadata support to `set_semantic_meaning` (#17730) The `set_semantic_meaning` function didn't support setting meanings that point to metadata. This will be needed when log namespacing is enabled. --- .../functions/src/set_semantic_meaning.rs | 37 +++++++++++-------- src/transforms/remap.rs | 4 +- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/lib/vector-vrl/functions/src/set_semantic_meaning.rs b/lib/vector-vrl/functions/src/set_semantic_meaning.rs index 1f9d09f122526..26e61c1671f59 100644 --- a/lib/vector-vrl/functions/src/set_semantic_meaning.rs +++ b/lib/vector-vrl/functions/src/set_semantic_meaning.rs @@ -1,14 +1,14 @@ use std::collections::BTreeMap; use std::ops::{Deref, DerefMut}; use vrl::diagnostic::Label; -use vrl::path::OwnedValuePath; +use vrl::path::{OwnedTargetPath, PathPrefix}; use vrl::prelude::*; #[derive(Debug, Default, Clone)] -pub struct MeaningList(pub BTreeMap); +pub struct MeaningList(pub BTreeMap); impl Deref for MeaningList { - type Target = BTreeMap; + type Target = BTreeMap; fn deref(&self) -> &Self::Target { &self.0 @@ -68,36 +68,41 @@ impl Function for SetSemanticMeaning { .expect("meaning not bytes") .into_owned(); - // Semantic meaning can only be assigned to external fields. - if !query.is_external() { + let path = if let Some(path) = query.external_path() { + path + } else { + // Semantic meaning can only be assigned to external fields. let mut labels = vec![Label::primary( - "the target of this semantic meaning is non-external", + "this path must point to an event or metadata", span, )]; if let Some(variable) = query.as_variable() { labels.push(Label::context( - format!("maybe you meant \".{}\"?", variable.ident()), + format!( + "maybe you meant \".{}\" or \"%{}\"?", + variable.ident(), + variable.ident() + ), span, )); } let error = ExpressionError::Error { - message: "semantic meaning defined for non-external target".to_owned(), + message: "semantic meaning is not valid for local variables".to_owned(), labels, notes: vec![], }; return Err(Box::new(error) as Box); - } - - let path = query.path().clone(); + }; - let exists = state - .external - .target_kind() - .at_path(&path) - .contains_any_defined(); + let exists = match path.prefix { + PathPrefix::Event => state.external.target_kind(), + PathPrefix::Metadata => state.external.metadata_kind(), + } + .at_path(&path.path) + .contains_any_defined(); // Reject assigning meaning to non-existing field. if !exists { diff --git a/src/transforms/remap.rs b/src/transforms/remap.rs index 49c84faad97e2..a6b01dbc8844d 100644 --- a/src/transforms/remap.rs +++ b/src/transforms/remap.rs @@ -9,7 +9,7 @@ use std::{ use codecs::MetricTagValues; use lookup::lookup_v2::{parse_value_path, ValuePath}; -use lookup::{metadata_path, owned_value_path, path, OwnedTargetPath, PathPrefix}; +use lookup::{metadata_path, owned_value_path, path, PathPrefix}; use snafu::{ResultExt, Snafu}; use vector_common::TimeZone; use vector_config::configurable_component; @@ -274,7 +274,7 @@ impl TransformConfig for RemapConfig { // Apply any semantic meanings set in the VRL program for (id, path) in meaning { // currently only event paths are supported - new_type_def = new_type_def.with_meaning(OwnedTargetPath::event(path), &id); + new_type_def = new_type_def.with_meaning(path, &id); } new_type_def })