Skip to main content

hawdb_sql_syntax/
parser.rs

1// Copyright 2026 Nowledge
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::{
16    GraphTable, Identifier, PgqStatement, PostgresSelectSyntax, PostgresStatementSyntax,
17    SyntaxError, Token, TokenKind,
18};
19
20pub(crate) mod expression;
21pub(crate) mod frontend;
22
23pub fn parse_postgres_statement(input: &str) -> Result<PostgresStatementSyntax, SyntaxError> {
24    match frontend::parse(input, "SqlInput")? {
25        frontend::Output::Select(select) => Ok(PostgresStatementSyntax::Select(select)),
26        frontend::Output::Create(create) => {
27            Ok(PostgresStatementSyntax::CreatePropertyGraph(*create))
28        }
29        frontend::Output::Explain { .. } | frontend::Output::GraphTable(_) => {
30            unreachable!("SQL entry excludes standalone GRAPH_TABLE")
31        }
32    }
33}
34
35/// Parses the executable relational SELECT and EXPLAIN SELECT families.
36pub fn parse_relational_statement(
37    input: &str,
38) -> Result<crate::RelationalStatementSyntax, SyntaxError> {
39    match frontend::parse(input, "RelationalStatementInput")? {
40        frontend::Output::Select(select) => Ok(crate::RelationalStatementSyntax::Select(select)),
41        frontend::Output::Explain { analyze, select } => {
42            Ok(crate::RelationalStatementSyntax::Explain { analyze, select })
43        }
44        _ => unreachable!("relational entry returns SELECT or EXPLAIN SELECT"),
45    }
46}
47
48pub fn parse_postgres_select(input: &str) -> Result<PostgresSelectSyntax, SyntaxError> {
49    let frontend::Output::Select(select) = frontend::parse(input, "SelectInput")? else {
50        unreachable!("SELECT entry produces a SELECT AST")
51    };
52    Ok(*select)
53}
54
55pub fn parse_pgq_statement(input: &str) -> Result<PgqStatement, SyntaxError> {
56    let frontend::Output::Create(create) = frontend::parse(input, "PgqInput")? else {
57        unreachable!("PGQ entry produces CREATE PROPERTY GRAPH")
58    };
59    Ok(PgqStatement::CreatePropertyGraph(*create))
60}
61
62pub fn parse_graph_table(input: &str) -> Result<GraphTable, SyntaxError> {
63    let frontend::Output::GraphTable(table) = frontend::parse(input, "GraphTableInput")? else {
64        unreachable!("GRAPH_TABLE entry produces a GRAPH_TABLE AST")
65    };
66    Ok(*table)
67}
68
69const MAX_GRAPH_PATTERN_NESTING: usize = 128;
70pub(crate) const MAX_EXPRESSION_NESTING: usize = 128;
71
72fn identifier_from_token(token: Token) -> Identifier {
73    Identifier {
74        span: token.span,
75        quoted: token.kind == TokenKind::QuotedIdentifier,
76    }
77}