use super::super::Parser;
use crate::peg::NativeMatch;
use crate::*;
pub(super) enum Value {
Projection(Vec<LabeledExpressionSyntax>),
Expression(Box<ExpressionSyntax>),
Expressions(Vec<ExpressionSyntax>),
OrderItems(Vec<OrderBySyntax>),
Relation(RelationTableSyntax),
Name(QualifiedName),
Alias(Option<TableAlias>),
Pattern(GraphPatternSyntax),
Columns(Vec<GraphTableColumn>),
Vertices(Vec<VertexTableDefinition>),
Edges(Vec<EdgeTableDefinition>),
}
fn run(
input: &str,
tokens: &[Token],
start: usize,
parse: impl FnOnce(&mut Parser<'_>) -> Result<Value, SyntaxError>,
) -> NativeMatch<Value> {
let mut parser = Parser::new(input, tokens);
parser.position = start;
let value = parse(&mut parser);
NativeMatch {
end: parser.position,
value,
}
}
pub(super) fn projection(input: &str, tokens: &[Token], start: usize) -> NativeMatch<Value> {
run(input, tokens, start, |parser| {
parser.parse_select_projection().map(Value::Projection)
})
}
pub(super) fn relation(input: &str, tokens: &[Token], start: usize) -> NativeMatch<Value> {
run(input, tokens, start, |parser| {
if parser.at_select_clause_boundary() {
return Err(parser.unexpected("at least one FROM item"));
}
let begin = parser.current().span.start;
let name = parser.parse_qualified_name()?;
let alias = parser.parse_optional_table_alias()?;
Ok(Value::Relation(RelationTableSyntax {
name,
alias,
span: Span::new(begin, parser.previous_end()),
}))
})
}
pub(super) fn name(input: &str, tokens: &[Token], start: usize) -> NativeMatch<Value> {
run(input, tokens, start, |parser| {
parser.parse_qualified_name().map(Value::Name)
})
}
pub(super) fn alias(input: &str, tokens: &[Token], start: usize) -> NativeMatch<Value> {
run(input, tokens, start, |parser| {
parser.parse_optional_table_alias().map(Value::Alias)
})
}
pub(super) fn pattern(input: &str, tokens: &[Token], start: usize) -> NativeMatch<Value> {
run(input, tokens, start, |parser| {
parser.parse_graph_pattern().map(Value::Pattern)
})
}
pub(super) fn columns(input: &str, tokens: &[Token], start: usize) -> NativeMatch<Value> {
run(input, tokens, start, |parser| {
parser.parse_graph_table_columns().map(Value::Columns)
})
}
pub(super) fn clause_expression(input: &str, tokens: &[Token], start: usize) -> NativeMatch<Value> {
run(input, tokens, start, |parser| {
parser
.parse_select_clause_expression(
super::super::select::SELECT_CLAUSE_KEYWORDS,
"a SELECT clause expression",
)
.map(|value| Value::Expression(Box::new(value)))
})
}
pub(super) fn join_expression(input: &str, tokens: &[Token], start: usize) -> NativeMatch<Value> {
run(input, tokens, start, |parser| {
parser
.parse_select_clause_expression(
super::super::select::JOIN_BOUNDARY_KEYWORDS,
"an expression after JOIN ON",
)
.map(|value| Value::Expression(Box::new(value)))
})
}
pub(super) fn group_expressions(input: &str, tokens: &[Token], start: usize) -> NativeMatch<Value> {
run(input, tokens, start, |parser| {
parser
.parse_select_expression_list(
super::super::select::SELECT_CLAUSE_KEYWORDS,
"an expression list after GROUP BY",
)
.map(Value::Expressions)
})
}
pub(super) fn order_items(input: &str, tokens: &[Token], start: usize) -> NativeMatch<Value> {
run(input, tokens, start, |parser| {
parser.parse_order_by_items().map(Value::OrderItems)
})
}
pub(super) fn vertices(input: &str, tokens: &[Token], start: usize) -> NativeMatch<Value> {
run(input, tokens, start, |parser| {
parser
.parse_nonempty_comma_separated(
TokenKind::RightParen,
Parser::parse_vertex_table_definition,
"at least one vertex table definition",
)
.map(Value::Vertices)
})
}
pub(super) fn edges(input: &str, tokens: &[Token], start: usize) -> NativeMatch<Value> {
run(input, tokens, start, |parser| {
parser
.parse_nonempty_comma_separated(
TokenKind::RightParen,
Parser::parse_edge_table_definition,
"at least one edge table definition",
)
.map(Value::Edges)
})
}