Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 21 additions & 16 deletions lib/vector-vrl/functions/src/set_semantic_meaning.rs
Original file line number Diff line number Diff line change
@@ -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<String, OwnedValuePath>);
pub struct MeaningList(pub BTreeMap<String, OwnedTargetPath>);

impl Deref for MeaningList {
type Target = BTreeMap<String, OwnedValuePath>;
type Target = BTreeMap<String, OwnedTargetPath>;

fn deref(&self) -> &Self::Target {
&self.0
Expand Down Expand Up @@ -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<dyn DiagnosticMessage>);
}

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 {
Expand Down
4 changes: 2 additions & 2 deletions src/transforms/remap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
})
Expand Down