Skip to main content

reifydb_engine/expression/
access.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use std::sync::Arc;
5
6use reifydb_core::{
7	error::diagnostic::query::column_not_found, interface::identifier::ColumnShape, value::column::Column,
8};
9use reifydb_rql::expression::AccessShapeExpression;
10use reifydb_type::{error, fragment::Fragment};
11
12use crate::{Result, expression::context::EvalContext};
13
14pub(crate) fn access_lookup(ctx: &EvalContext, expr: &AccessShapeExpression) -> Result<Column> {
15	// Extract primitive name based on the ColumnShape type
16	let source = match &expr.column.shape {
17		ColumnShape::Qualified {
18			name,
19			..
20		} => name,
21		ColumnShape::Alias(alias) => alias,
22	};
23	let column = expr.column.name.text().to_string();
24
25	// Build the full qualified name for aliased columns
26	let qualified_name = format!("{}.{}", source.text(), &column);
27
28	// Find columns - try both qualified name and unqualified name
29	let matching_col = ctx.columns.iter().find(|col| {
30		// First try to match the fully qualified name (for aliased columns)
31		if col.name().text() == qualified_name {
32			return true;
33		}
34
35		// For non-aliased columns, just match on the column name
36		// (but only if this isn't an aliased access)
37		if matches!(&expr.column.shape, ColumnShape::Qualified { .. }) && col.name().text() == column {
38			// Make sure this column doesn't belong to a different source
39			// by checking if it has a dot in the name (qualified)
40			return !col.name().text().contains('.');
41		}
42
43		false
44	});
45
46	if let Some(col) = matching_col {
47		// Extract the column data and preserve it
48		Ok(col.with_new_data(col.data().clone()))
49	} else {
50		// If not found, return an error with proper diagnostic
51		Err(error!(column_not_found(Fragment::Statement {
52			column: expr.column.name.column(),
53			line: expr.column.name.line(),
54			text: Arc::from(format!("{}.{}", source.text(), &column)),
55		})))
56	}
57}