Line data Source code
1 : //! The vocabulary of the grammar actions. The generated rules module (`grammar/rules_rs`) imports everything from here.
2 :
3 : pub use super::context::{null, IntoNodeList, ParseContext, NO_PARENT};
4 : pub use super::value::{ExprVariant, FromValue, NodeList, Str, Value};
5 : pub use crate::names::NameId;
6 : pub use dashql_buffers::parser::{
7 : AConstType, AttributeKey, CharacterType, ColumnConstraint, CombineModifier, CombineOperation, ConstraintAttribute,
8 : ExpressionOperator, ExtractTarget, GroupByItemType, IntervalType, JoinType, KeyActionCommand, KeyActionTrigger,
9 : KeyMatch, KnownFunction, Node, NodeType, NumericType, OnCommitOption, OrderDirection, OrderNullRule,
10 : RowLockingBlockBehavior, RowLockingStrength, SampleCountUnit, SubqueryQuantifier, SymbolSpan, TableConstraint,
11 : TempType, TrimDirection, WindowBoundDirection, WindowBoundMode, WindowExclusionMode, WindowRangeMode,
12 : };
13 :
14 : /// Attribute keys, as the grammar actions call them
15 : pub type Key = AttributeKey;
16 : /// Expression operators, as the grammar actions call them
17 : pub type ExprFunc = ExpressionOperator;
18 :
19 : /// An empty node list
20 : pub const NO_NODES: &[Node; 0] = &[];
21 :
22 : /// The parser stack as seen by an action
23 : pub trait ReduceStack {
24 : /// The value of the i-th symbol from the top
25 : fn value_at(&self, i: usize) -> Value;
26 : /// The location of the i-th symbol from the top
27 : fn location_at(&self, i: usize) -> SymbolSpan;
28 : }
29 :
30 : /// An action failed
31 : #[derive(Clone, Copy, Debug, PartialEq, Eq)]
32 : pub enum ReduceError {
33 : /// The action raised `YYERROR`
34 : YyError,
35 : }
36 :
37 : /// Set the attribute key of a node
38 402339 : pub fn attr(key: AttributeKey, node: Node) -> Node {
39 402339 : Node::new(node.symbol_span(), node.node_type(), key, node.parent(), node.children_begin_or_value(), node.children_count())
40 402339 : }
41 :
42 : /// An operator
43 777 : pub fn operator_node(loc: SymbolSpan) -> Node {
44 777 : Node::new(&loc, NodeType::OPERATOR, AttributeKey::NONE, NO_PARENT, 0, 0)
45 777 : }
46 :
47 : /// A name from an identifier
48 99796 : pub fn name_from_identifier(loc: SymbolSpan, name: NameId) -> Node {
49 99796 : Node::new(&loc, NodeType::NAME, AttributeKey::NONE, NO_PARENT, name, 0)
50 99796 : }
51 :
52 : /// A boolean
53 3661 : pub fn bool_node(loc: SymbolSpan, v: bool) -> Node {
54 3661 : Node::new(&loc, NodeType::BOOL, AttributeKey::NONE, NO_PARENT, v as u32, 0)
55 3661 : }
56 :
57 : /// A constant literal
58 29018 : pub fn const_node(loc: SymbolSpan, t: AConstType) -> Node {
59 29018 : let node_type = match t {
60 530 : AConstType::NULL_ => NodeType::LITERAL_NULL,
61 17642 : AConstType::INTEGER => NodeType::LITERAL_INTEGER,
62 936 : AConstType::FLOAT => NodeType::LITERAL_FLOAT,
63 9910 : AConstType::STRING => NodeType::LITERAL_STRING,
64 0 : AConstType::INTERVAL => NodeType::LITERAL_INTERVAL,
65 0 : _ => return null(),
66 : };
67 29018 : Node::new(&loc, node_type, AttributeKey::NONE, NO_PARENT, 0, 0)
68 29018 : }
69 :
70 : /// Enums that become enum nodes (`Enum(loc, e)`)
71 : pub trait EnumNodeType: Copy {
72 : const NODE_TYPE: NodeType;
73 : fn value(self) -> u32;
74 : }
75 :
76 : macro_rules! enum_node_types {
77 : ($($t:ident => $node_type:ident),* $(,)?) => {
78 : $(
79 : impl EnumNodeType for $t {
80 : const NODE_TYPE: NodeType = NodeType::$node_type;
81 52483 : fn value(self) -> u32 {
82 52483 : self.0 as u32
83 52483 : }
84 : }
85 : )*
86 : };
87 : }
88 :
89 : enum_node_types! {
90 : AConstType => ENUM_SQL_CONST_TYPE,
91 : CharacterType => ENUM_SQL_CHARACTER_TYPE,
92 : ColumnConstraint => ENUM_SQL_COLUMN_CONSTRAINT,
93 : CombineModifier => ENUM_SQL_COMBINE_MODIFIER,
94 : CombineOperation => ENUM_SQL_COMBINE_OPERATION,
95 : ConstraintAttribute => ENUM_SQL_CONSTRAINT_ATTRIBUTE,
96 : ExpressionOperator => ENUM_SQL_EXPRESSION_OPERATOR,
97 : ExtractTarget => ENUM_SQL_EXTRACT_TARGET,
98 : GroupByItemType => ENUM_SQL_GROUP_BY_ITEM_TYPE,
99 : IntervalType => ENUM_SQL_INTERVAL_TYPE,
100 : JoinType => ENUM_SQL_JOIN_TYPE,
101 : KeyActionCommand => ENUM_SQL_KEY_ACTION_COMMAND,
102 : KeyActionTrigger => ENUM_SQL_KEY_ACTION_TRIGGER,
103 : KeyMatch => ENUM_SQL_KEY_MATCH,
104 : KnownFunction => ENUM_SQL_KNOWN_FUNCTION,
105 : NumericType => ENUM_SQL_NUMERIC_TYPE,
106 : OnCommitOption => ENUM_SQL_ON_COMMIT_OPTION,
107 : OrderDirection => ENUM_SQL_ORDER_DIRECTION,
108 : OrderNullRule => ENUM_SQL_ORDER_NULL_RULE,
109 : RowLockingBlockBehavior => ENUM_SQL_ROW_LOCKING_BLOCK_BEHAVIOR,
110 : RowLockingStrength => ENUM_SQL_ROW_LOCKING_STRENGTH,
111 : SampleCountUnit => ENUM_SQL_SAMPLE_UNIT_TYPE,
112 : SubqueryQuantifier => ENUM_SQL_SUBQUERY_QUANTIFIER,
113 : TableConstraint => ENUM_SQL_TABLE_CONSTRAINT,
114 : TempType => ENUM_SQL_TEMP_TYPE,
115 : TrimDirection => ENUM_SQL_TRIM_TARGET,
116 : WindowBoundDirection => ENUM_SQL_WINDOW_BOUND_DIRECTION,
117 : WindowBoundMode => ENUM_SQL_WINDOW_BOUND_MODE,
118 : WindowExclusionMode => ENUM_SQL_WINDOW_EXCLUSION_MODE,
119 : WindowRangeMode => ENUM_SQL_WINDOW_RANGE_MODE,
120 : }
121 :
122 : /// An enum value
123 52483 : pub fn enum_node<E: EnumNodeType>(loc: SymbolSpan, e: E) -> Node {
124 52483 : Node::new(&loc, E::NODE_TYPE, AttributeKey::NONE, NO_PARENT, e.value(), 0)
125 52483 : }
126 :
127 : /// The span covering all spans (`Loc({..})`)
128 6120 : pub fn loc(spans: &[SymbolSpan]) -> SymbolSpan {
129 18235 : let begin = spans.iter().map(|s| s.offset()).min().unwrap_or(0);
130 18235 : let end = spans.iter().map(|s| s.offset() + s.length()).max().unwrap_or(0);
131 6120 : SymbolSpan::new(begin, end - begin)
132 6120 : }
133 :
134 : /// Merge join types
135 292 : pub fn merge_join(left: JoinType, right: JoinType) -> JoinType {
136 292 : JoinType(left.0 | right.0)
137 292 : }
138 :
139 : /// An index or slice indirection with a single index
140 8 : pub fn indirection_index(ctx: &ParseContext, loc: SymbolSpan, index: Node) -> Node {
141 8 : ctx.object(loc, NodeType::OBJECT_SQL_INDIRECTION_INDEX, &[attr(Key::SQL_INDIRECTION_INDEX_VALUE, index)])
142 8 : }
143 :
144 : /// A slice indirection with bounds
145 59 : pub fn indirection_index_bounds(ctx: &ParseContext, loc: SymbolSpan, lower: Node, upper: Node) -> Node {
146 : // Both bounds are optional, `[:]` stays an object without attributes
147 59 : ctx.object_ex(
148 59 : loc,
149 : NodeType::OBJECT_SQL_INDIRECTION_INDEX,
150 59 : &[attr(Key::SQL_INDIRECTION_INDEX_LOWER_BOUND, lower), attr(Key::SQL_INDIRECTION_INDEX_UPPER_BOUND, upper)],
151 : false,
152 : false,
153 : )
154 59 : }
155 :
156 : /// A temp table name
157 62 : pub fn into_node(ctx: &ParseContext, loc: SymbolSpan, temp_type: Node, name: Node) -> Node {
158 62 : ctx.object(loc, NodeType::OBJECT_SQL_INTO, &[attr(Key::SQL_TEMP_TYPE, temp_type), attr(Key::SQL_TEMP_NAME, name)])
159 62 : }
160 :
161 : /// A column reference
162 50368 : pub fn column_ref(ctx: &ParseContext, loc: SymbolSpan, path: NodeList) -> Node {
163 50368 : let path_nodes = ctx.array(loc, path);
164 50368 : ctx.object(loc, NodeType::OBJECT_SQL_COLUMN_REF, &[attr(Key::SQL_COLUMN_REF_PATH, path_nodes)])
165 50368 : }
166 :
167 : /// An expression without arguments
168 7 : pub fn expr0(ctx: &ParseContext, loc: SymbolSpan, func: Node) -> Node {
169 7 : ctx.object(loc, NodeType::OBJECT_SQL_NARY_EXPRESSION, &[attr(Key::SQL_EXPRESSION_OPERATOR, func)])
170 7 : }
171 :
172 : /// A unary expression
173 287 : pub fn expr1(ctx: &ParseContext, loc: SymbolSpan, func: Node, arg: impl Into<ExprVariant>) -> Node {
174 287 : let args = ctx.expression_array(loc, &[arg.into()]);
175 287 : ctx.object(
176 287 : loc,
177 : NodeType::OBJECT_SQL_NARY_EXPRESSION,
178 287 : &[attr(Key::SQL_EXPRESSION_OPERATOR, func), attr(Key::SQL_EXPRESSION_ARGS, args)],
179 : )
180 287 : }
181 :
182 : /// A postfix expression
183 1 : pub fn expr_postfix(ctx: &ParseContext, loc: SymbolSpan, func: Node, arg: impl Into<ExprVariant>) -> ExprVariant {
184 1 : let args = [arg.into()];
185 1 : if let Some(merged) = ctx.try_merge(loc, func, &args) {
186 0 : return merged;
187 1 : }
188 1 : let postfix = bool_node(loc, true);
189 1 : let args = ctx.expression_array(loc, &args);
190 1 : ExprVariant::Node(ctx.object(
191 1 : loc,
192 1 : NodeType::OBJECT_SQL_NARY_EXPRESSION,
193 1 : &[
194 1 : attr(Key::SQL_EXPRESSION_OPERATOR, func),
195 1 : attr(Key::SQL_EXPRESSION_POSTFIX, postfix),
196 1 : attr(Key::SQL_EXPRESSION_ARGS, args),
197 1 : ],
198 1 : ))
199 1 : }
200 :
201 34052 : fn nary_expr(ctx: &ParseContext, loc: SymbolSpan, func: Node, args: &[ExprVariant]) -> ExprVariant {
202 34052 : if let Some(merged) = ctx.try_merge(loc, func, args) {
203 11923 : return merged;
204 22129 : }
205 22129 : let args = ctx.expression_array(loc, args);
206 22129 : ExprVariant::Node(ctx.object(
207 22129 : loc,
208 22129 : NodeType::OBJECT_SQL_NARY_EXPRESSION,
209 22129 : &[attr(Key::SQL_EXPRESSION_OPERATOR, func), attr(Key::SQL_EXPRESSION_ARGS, args)],
210 22129 : ))
211 34052 : }
212 :
213 : /// A binary expression
214 32546 : pub fn expr2(
215 32546 : ctx: &ParseContext,
216 32546 : loc: SymbolSpan,
217 32546 : func: Node,
218 32546 : left: impl Into<ExprVariant>,
219 32546 : right: impl Into<ExprVariant>,
220 32546 : ) -> ExprVariant {
221 32546 : nary_expr(ctx, loc, func, &[left.into(), right.into()])
222 32546 : }
223 :
224 : /// A ternary expression
225 1506 : pub fn expr3(
226 1506 : ctx: &ParseContext,
227 1506 : loc: SymbolSpan,
228 1506 : func: Node,
229 1506 : arg0: impl Into<ExprVariant>,
230 1506 : arg1: impl Into<ExprVariant>,
231 1506 : arg2: impl Into<ExprVariant>,
232 1506 : ) -> ExprVariant {
233 1506 : nary_expr(ctx, loc, func, &[arg0.into(), arg1.into(), arg2.into()])
234 1506 : }
235 :
236 : /// Negate an expression
237 221 : pub fn negate(ctx: &ParseContext, loc: SymbolSpan, loc_minus: SymbolSpan, value: impl Into<ExprVariant>) -> Node {
238 221 : let op = enum_node(loc_minus, ExpressionOperator::NEGATE);
239 221 : let args = ctx.expression_array(loc, &[value.into()]);
240 221 : ctx.object(
241 221 : loc,
242 : NodeType::OBJECT_SQL_NARY_EXPRESSION,
243 221 : &[attr(Key::SQL_EXPRESSION_OPERATOR, op), attr(Key::SQL_EXPRESSION_ARGS, args)],
244 : )
245 221 : }
246 :
247 : /// A vararg field. Every level wraps the value, not the inner level.
248 81 : pub fn vararg_field(ctx: &ParseContext, loc: SymbolSpan, path: NodeList, value: Node) -> Node {
249 81 : let mut root = value;
250 81 : let keys = ctx.state.borrow().lists_snapshot(path);
251 81 : for key in keys.into_iter().rev() {
252 81 : root = ctx.object(
253 81 : loc,
254 81 : NodeType::OBJECT_EXT_VARARG_FIELD,
255 81 : &[attr(Key::EXT_VARARG_FIELD_KEY, key), attr(Key::EXT_VARARG_FIELD_VALUE, value)],
256 81 : );
257 81 : }
258 81 : root
259 81 : }
|