typedb_driver/analyze/conjunction.rs
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20use std::{collections::HashMap, fmt};
21
22use crate::{analyze::VariableAnnotations, concept, IID};
23
24/// Holds the index of the conjunction in a <code>Pipeline</code>'s <code>conjunctions</code> field.
25/// Used as indirection in the representation of a pipeline.
26#[derive(Debug, Clone, Copy, PartialEq)]
27pub struct ConjunctionID(pub usize);
28
29/// A representation of the constraints involved in the query, and types inferred for each variable.
30#[derive(Debug, Clone)]
31pub struct Conjunction {
32 /// The <code>Constraint</code>s in the conjunction.
33 pub constraints: Vec<ConstraintWithSpan>,
34 /// The annotations of each variable in the conjunction.
35 pub variable_annotations: HashMap<Variable, VariableAnnotations>,
36}
37
38/// Tells apart exact variants of constraints from the ones allowing subtype-polymorphism.
39/// e.g. <code>isa!</code> would be represented as an <code>Constraint::Isa</code>
40/// with its exactness field <code>ConstraintExactness::Exact</code>.
41#[repr(C)]
42#[derive(Debug, Clone)]
43pub enum ConstraintExactness {
44 /// Indicates the constraint matches exactly the specified type - e.g. `isa!` or `sub!`
45 Exact,
46 /// Indicates the constraint matches the specified type and its subtypes - e.g. `isa!` or `sub!`
47 Subtypes,
48}
49
50/// The span of a constraint in the <code>source</code> of the <code>AnalyzedQuery</code>.
51#[derive(Debug, Clone)]
52pub struct ConstraintSpan {
53 /// The offset of the first character in the span
54 pub begin: usize,
55 /// The offset after the last character in the span
56 pub end: usize,
57}
58
59#[derive(Debug, Clone)]
60pub struct ConstraintWithSpan {
61 pub constraint: Constraint,
62 pub span: Option<ConstraintSpan>,
63}
64
65/// A representation of a TypeQL constraint.
66#[derive(Debug, Clone)]
67pub enum Constraint {
68 /// <instance> isa(!) <type>
69 Isa { instance: ConstraintVertex, r#type: ConstraintVertex, exactness: ConstraintExactness },
70 /// <owner> has <attribute>
71 Has { owner: ConstraintVertex, attribute: ConstraintVertex, exactness: ConstraintExactness },
72 /// <relation> links (<role>: <player>)
73 Links {
74 relation: ConstraintVertex,
75 player: ConstraintVertex,
76 role: ConstraintVertex,
77 exactness: ConstraintExactness,
78 },
79 /// <subtype> sub(!) <supertype>
80 Sub { subtype: ConstraintVertex, supertype: ConstraintVertex, exactness: ConstraintExactness },
81 /// <owner> owns <attribute>
82 Owns { owner: ConstraintVertex, attribute: ConstraintVertex, exactness: ConstraintExactness },
83 /// <relation> relates <role>
84 Relates { relation: ConstraintVertex, role: ConstraintVertex, exactness: ConstraintExactness },
85 /// <player> plays <role>
86 Plays { player: ConstraintVertex, role: ConstraintVertex, exactness: ConstraintExactness },
87 /// let <assigned> = name(<arguments>)
88 /// e.g. let $x, $y = my_function($a, $b);
89 FunctionCall { name: String, assigned: Vec<ConstraintVertex>, arguments: Vec<ConstraintVertex> },
90 /// let <assigned> = <expression>
91 /// e.g. let $x = $y + 5;
92 /// Here, arguments will be `[$y]`
93 Expression { text: String, assigned: ConstraintVertex, arguments: Vec<ConstraintVertex> },
94 /// <lhs> is <rhs>
95 /// $x is $y
96 Is { lhs: ConstraintVertex, rhs: ConstraintVertex },
97 /// <concept> iid <iid>
98 /// e.g. `$y iid 0x1f0005000000000000012f`
99 Iid { concept: ConstraintVertex, iid: IID },
100 /// <lhs> <comparator> <rhs>
101 /// e.g. `$x < 5`
102 Comparison { lhs: ConstraintVertex, rhs: ConstraintVertex, comparator: Comparator },
103 /// <kind> <type>
104 /// e.g. `entity person`
105 Kind { kind: concept::Kind, r#type: ConstraintVertex },
106 /// <type> label <label>
107 /// e.g. `$t label person`
108 Label { r#type: ConstraintVertex, label: String },
109 /// <attribute_type> value <value_type>
110 /// e.g. $t value string
111 Value { attribute_type: ConstraintVertex, value_type: concept::ValueType },
112 /// { <branches[0]> } or { <branches[1]> } [or ...]
113 Or {
114 /// Index into <code>Pipeline.conjunctions</code>
115 branches: Vec<ConjunctionID>,
116 },
117 /// not { <conjunction> }
118 Not {
119 /// Index into <code>Pipeline.conjunctions</code>
120 conjunction: ConjunctionID,
121 },
122 /// try { <conjunction> }
123 Try {
124 /// Index into <code>Pipeline.conjunctions</code>
125 conjunction: ConjunctionID,
126 },
127}
128
129/// Uniquely identifies a variable in a <code>Pipeline</code>pipeline.
130/// Its name (if any) can be retrieved from the <code>variable_names</code> field in <code>Pipeline</code>
131#[derive(Debug, Hash, Clone, Eq, PartialEq)]
132pub struct Variable(pub u32);
133
134/// The answer to a TypeDB query is a set of concepts which satisfy the <code>Constraints</code> in the query.
135/// A <code>ConstraintVertex</code> is either a variable, or some identifier of the concept.
136///
137/// * A <code>Variable</code> is a vertex the query must match and return.
138/// * A <code>Label</code> uniquely identifies a type
139/// * A <code>Value</code> represents a primitive value literal in TypeDB.
140/// * A <code>NamedRole</code> vertex is used in links & relates constraints, as multiple relations may have roles with the same name.
141/// The types inferred for <code>Variable</code>, <code>Label</code> and <code>NamedRole</code> vertices
142/// can be read from the <code>variable_annotations</code> field of the <code>Conjunction</code> it is in.
143#[derive(Debug, Clone, PartialEq)]
144pub enum ConstraintVertex {
145 Variable(Variable),
146 Label(concept::type_::Type),
147 Value(concept::Value),
148 NamedRole(NamedRole),
149}
150
151/// A <code>NamedRole</code> vertex is used in links & relates constraints, as multiple relations may have roles with the same name.
152#[derive(Debug, Clone)]
153pub struct NamedRole {
154 pub variable: Variable,
155 pub name: String,
156}
157
158impl PartialEq for NamedRole {
159 fn eq(&self, other: &Self) -> bool {
160 self.variable == other.variable // Names will be equal unless they belong to different pipelines
161 }
162}
163
164/// A representation of the comparator used in a comparison constraint.
165#[repr(C)]
166#[derive(Debug, Clone)]
167pub enum Comparator {
168 Equal,
169 NotEqual,
170 LessThan,
171 LessOrEqual,
172 Greater,
173 GreaterOrEqual,
174 Like,
175 Contains,
176}
177
178impl Comparator {
179 /// The symbol representing the comparator in TypeQL
180 pub fn symbol(&self) -> &'static str {
181 match self {
182 Comparator::Equal => "==",
183 Comparator::NotEqual => "!=",
184 Comparator::LessThan => "<",
185 Comparator::LessOrEqual => "<=",
186 Comparator::Greater => ">",
187 Comparator::GreaterOrEqual => ">=",
188 Comparator::Like => "Like",
189 Comparator::Contains => "Contains",
190 }
191 }
192}