Skip to content

Commit 4a279a8

Browse files
TypeQL 3.0 (#342)
## Usage and product changes User-defined functions and structs: ```typeql fun mean_salary($c: company) -> double? : match (company: $c, employee: $_) isa employment, has salary $s; return mean($s); ``` ```typeql struct dated_coordinate: longitude value double, latitude value double, date value datetime; ``` Query pipelines: ``` with fun costliest_printer($employee: employee) -> printer? : match ($printer, $employee) isa print_permission; $printer has cost_per_page $cost; sort $cost desc; return first($printer); match $printer isa printer, has office_number $n, has newly_installed true; $employee isa employee, has office_number $n; put ($employee, $printer) isa print_permission; match $high_cost_printer = costliest_printer($employee), has printer_name $name; not { $printer is $high_cost_printer; }; $employee has contact $address; insert $notice isa queued_email, has recipient $address, has content "Do you still need the printer " + $name + "?"; ``` New undefine syntax allows user to be more precise as to what is being undefined: ```typeql undefine owns age from person; @regex from first-name; as name from person owns first-name; ``` New, more concise delete syntax: ```typeql match $p isa person, has name $n; delete $n of $p; ``` Implement JSON-like string unescaping (closes #106). See [The TypeDB 3.0 Roadmap](<https://typedb.com/blog/typedb-3-roadmap>) for more details!
1 parent fc0a191 commit 4a279a8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+8457
-4170
lines changed

dependencies/maven/artifacts.snapshot

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
@maven//:com_eclipsesource_minimal_json_minimal_json_0_9_5
22
@maven//:com_electronwill_night_config_core_3_6_5
33
@maven//:com_electronwill_night_config_toml_3_6_5
4-
@maven//:com_fasterxml_jackson_core_jackson_annotations_2_10_1
5-
@maven//:com_fasterxml_jackson_core_jackson_core_2_10_1
6-
@maven//:com_fasterxml_jackson_core_jackson_databind_2_10_1
4+
@maven//:com_fasterxml_jackson_core_jackson_annotations_2_16_0
5+
@maven//:com_fasterxml_jackson_core_jackson_core_2_16_0
6+
@maven//:com_fasterxml_jackson_core_jackson_databind_2_16_0
77
@maven//:com_google_code_findbugs_jsr305_3_0_2
88
@maven//:com_google_errorprone_error_prone_annotations_2_3_4
99
@maven//:com_google_guava_failureaccess_1_0_1
1010
@maven//:com_google_guava_guava_30_1_jre
1111
@maven//:com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava
1212
@maven//:com_google_http_client_google_http_client_1_34_2
1313
@maven//:com_google_j2objc_j2objc_annotations_1_3
14+
@maven//:com_vdurmont_semver4j_3_1_0
1415
@maven//:commons_codec_commons_codec_1_13
1516
@maven//:commons_io_commons_io_2_3
1617
@maven//:commons_logging_commons_logging_1_2
@@ -42,5 +43,5 @@
4243
@maven//:org_jsoup_jsoup_1_16_1
4344
@maven//:org_kohsuke_github_api_1_101
4445
@maven//:org_slf4j_slf4j_api_2_0_0
45-
@maven//:org_yaml_snakeyaml_1_25
46+
@maven//:org_yaml_snakeyaml_2_2
4647
@maven//:org_zeroturnaround_zt_exec_1_10

dependencies/vaticle/repositories.bzl

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
77
def vaticle_dependencies():
88
git_repository(
99
name = "vaticle_dependencies",
10-
remote = "https://github.com/dmitrii-ubskii/vaticle-dependencies",
11-
commit = "b13ccddfddcac1d56a029d98e3893f74b267c5ae", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_dependencies
10+
remote = "https://github.com/vaticle/dependencies",
11+
commit = "78d937a49135453965ddd68c51de7f90b8aeba15", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_dependencies
1212
)
1313

1414
def vaticle_typedb_behaviour():

rust/BUILD

+1-8
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,7 @@ checkstyle_test(
8888
name = "checkstyle",
8989
include = glob([
9090
"*",
91-
"builder/**",
92-
"common/**",
93-
"parser/**",
94-
"pattern/**",
95-
"query/**",
96-
"tests/**",
97-
"util/**",
98-
"variable/**",
91+
"*/**",
9992
], exclude = [
10093
"target/**",
10194
"README.md",

rust/annotation.rs

+257
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
/*
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
5+
*/
6+
7+
use std::fmt::{self, Write};
8+
9+
use crate::{
10+
common::{identifier::Identifier, token, Span},
11+
util::write_joined,
12+
value::Literal,
13+
};
14+
15+
#[derive(Debug, Clone, Eq, PartialEq)]
16+
pub enum Annotation {
17+
Abstract(Abstract),
18+
Cardinality(Cardinality),
19+
Cascade(Cascade),
20+
Distinct(Distinct),
21+
Independent(Independent),
22+
Key(Key),
23+
Range(Range),
24+
Regex(Regex),
25+
Subkey(Subkey),
26+
Unique(Unique),
27+
Values(Values),
28+
}
29+
30+
impl fmt::Display for Annotation {
31+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32+
match self {
33+
Self::Abstract(inner) => fmt::Display::fmt(inner, f),
34+
Self::Cardinality(inner) => fmt::Display::fmt(inner, f),
35+
Self::Cascade(inner) => fmt::Display::fmt(inner, f),
36+
Self::Distinct(inner) => fmt::Display::fmt(inner, f),
37+
Self::Independent(inner) => fmt::Display::fmt(inner, f),
38+
Self::Key(inner) => fmt::Display::fmt(inner, f),
39+
Self::Range(inner) => fmt::Display::fmt(inner, f),
40+
Self::Regex(inner) => fmt::Display::fmt(inner, f),
41+
Self::Subkey(inner) => fmt::Display::fmt(inner, f),
42+
Self::Unique(inner) => fmt::Display::fmt(inner, f),
43+
Self::Values(inner) => fmt::Display::fmt(inner, f),
44+
}
45+
}
46+
}
47+
48+
#[derive(Debug, Clone, Eq, PartialEq)]
49+
pub struct Abstract {
50+
span: Option<Span>,
51+
}
52+
53+
impl Abstract {
54+
pub fn new(span: Option<Span>) -> Self {
55+
Self { span }
56+
}
57+
}
58+
59+
impl fmt::Display for Abstract {
60+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61+
write!(f, "@{}", token::Annotation::Abstract)
62+
}
63+
}
64+
65+
#[derive(Debug, Clone, Eq, PartialEq)]
66+
pub struct Cardinality {
67+
span: Option<Span>,
68+
min: Literal,
69+
max: Option<Literal>,
70+
}
71+
72+
impl Cardinality {
73+
pub fn new(span: Option<Span>, min: Literal, max: Option<Literal>) -> Self {
74+
Self { span, min, max }
75+
}
76+
}
77+
78+
impl fmt::Display for Cardinality {
79+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80+
write!(f, "@{}({}..", token::Annotation::Cardinality, self.min)?;
81+
if let Some(max) = &self.max {
82+
write!(f, "{}", max)?;
83+
}
84+
f.write_char(')')?;
85+
Ok(())
86+
}
87+
}
88+
89+
#[derive(Debug, Clone, Eq, PartialEq)]
90+
pub struct Cascade {
91+
span: Option<Span>,
92+
}
93+
94+
impl Cascade {
95+
pub fn new(span: Option<Span>) -> Self {
96+
Self { span }
97+
}
98+
}
99+
100+
impl fmt::Display for Cascade {
101+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102+
write!(f, "@{}", token::Annotation::Cascade)
103+
}
104+
}
105+
106+
#[derive(Debug, Clone, Eq, PartialEq)]
107+
pub struct Distinct {
108+
span: Option<Span>,
109+
}
110+
111+
impl Distinct {
112+
pub fn new(span: Option<Span>) -> Self {
113+
Self { span }
114+
}
115+
}
116+
117+
impl fmt::Display for Distinct {
118+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119+
write!(f, "@{}", token::Annotation::Distinct)
120+
}
121+
}
122+
123+
#[derive(Debug, Clone, Eq, PartialEq)]
124+
pub struct Independent {
125+
span: Option<Span>,
126+
}
127+
128+
impl Independent {
129+
pub fn new(span: Option<Span>) -> Self {
130+
Self { span }
131+
}
132+
}
133+
134+
impl fmt::Display for Independent {
135+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136+
write!(f, "@{}", token::Annotation::Independent)
137+
}
138+
}
139+
140+
#[derive(Debug, Clone, Eq, PartialEq)]
141+
pub struct Key {
142+
span: Option<Span>,
143+
}
144+
145+
impl Key {
146+
pub fn new(span: Option<Span>) -> Self {
147+
Self { span }
148+
}
149+
}
150+
151+
impl fmt::Display for Key {
152+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
153+
write!(f, "@{}", token::Annotation::Key)
154+
}
155+
}
156+
157+
#[derive(Debug, Clone, Eq, PartialEq)]
158+
pub struct Range {
159+
span: Option<Span>,
160+
min: Option<Literal>,
161+
max: Option<Literal>,
162+
}
163+
164+
impl Range {
165+
pub fn new(span: Option<Span>, min: Option<Literal>, max: Option<Literal>) -> Self {
166+
Self { span, min, max }
167+
}
168+
}
169+
170+
impl fmt::Display for Range {
171+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172+
write!(f, "@{}(", token::Annotation::Range)?;
173+
if let Some(min) = &self.min {
174+
write!(f, "{}", min)?;
175+
}
176+
f.write_str("..")?;
177+
if let Some(max) = &self.max {
178+
write!(f, "{}", max)?;
179+
}
180+
f.write_char(')')?;
181+
Ok(())
182+
}
183+
}
184+
185+
#[derive(Debug, Clone, Eq, PartialEq)]
186+
pub struct Regex {
187+
span: Option<Span>,
188+
regex: Literal,
189+
}
190+
191+
impl Regex {
192+
pub fn new(span: Option<Span>, regex: Literal) -> Self {
193+
Self { span, regex }
194+
}
195+
}
196+
197+
impl fmt::Display for Regex {
198+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
199+
write!(f, "@{}({})", token::Annotation::Regex, self.regex)
200+
}
201+
}
202+
203+
#[derive(Debug, Clone, Eq, PartialEq)]
204+
pub struct Subkey {
205+
span: Option<Span>,
206+
ident: Identifier,
207+
}
208+
209+
impl Subkey {
210+
pub fn new(span: Option<Span>, ident: Identifier) -> Self {
211+
Self { span, ident }
212+
}
213+
}
214+
215+
impl fmt::Display for Subkey {
216+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
217+
write!(f, "@{}({})", token::Annotation::Subkey, self.ident)
218+
}
219+
}
220+
221+
#[derive(Debug, Clone, Eq, PartialEq)]
222+
pub struct Unique {
223+
span: Option<Span>,
224+
}
225+
226+
impl Unique {
227+
pub fn new(span: Option<Span>) -> Self {
228+
Self { span }
229+
}
230+
}
231+
232+
impl fmt::Display for Unique {
233+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
234+
write!(f, "@{}", token::Annotation::Unique)
235+
}
236+
}
237+
238+
#[derive(Debug, Clone, Eq, PartialEq)]
239+
pub struct Values {
240+
span: Option<Span>,
241+
values: Vec<Literal>,
242+
}
243+
244+
impl Values {
245+
pub fn new(span: Option<Span>, values: Vec<Literal>) -> Self {
246+
Self { span, values }
247+
}
248+
}
249+
250+
impl fmt::Display for Values {
251+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
252+
write!(f, "@{}(", token::Annotation::Values)?;
253+
write_joined!(f, ", ", &self.values)?;
254+
f.write_char(')')?;
255+
Ok(())
256+
}
257+
}

rust/builder/mod.rs

+24-3
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,33 @@
44
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
55
*/
66

7-
use crate::pattern::Label;
7+
use crate::{common::identifier::Identifier, type_::Label, variable::Variable};
88

99
#[macro_export]
10-
macro_rules! typeql_define {
10+
macro_rules! define {
1111
($($def:expr),* $(,)?) => {
12-
$crate::query::TypeQLDefine::build(vec![$($def.into()),*])
12+
$crate::query::schema::Define::build(vec![$($def.into()),*])
1313
}
1414
}
1515

16+
#[macro_export]
17+
macro_rules! undefine {
18+
($($def:expr),* $(,)?) => {
19+
$crate::query::schema::Undefine::build(vec![$($def.into()),*])
20+
}
21+
}
22+
23+
#[macro_export]
24+
macro_rules! match_ {
25+
($($pattern:expr),* $(,)?) => {
26+
$crate::query::pipeline::stage::Match::build(vec![$($pattern.into()),*])
27+
}
28+
}
29+
30+
pub fn var(name: impl Into<Identifier>) -> Variable {
31+
Variable::Named(None, name.into())
32+
}
33+
34+
pub fn type_(name: impl Into<Identifier>) -> Label {
35+
Label::Identifier(name.into())
36+
}

rust/common/error/mod.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::{error::Error as StdError, fmt};
99
use itertools::Itertools;
1010
use pest::error::{Error as PestError, LineColLocation};
1111

12-
use crate::{error_messages, write_joined};
12+
use crate::{error_messages, util::write_joined};
1313

1414
#[macro_use]
1515
mod macros;
@@ -38,7 +38,7 @@ impl From<Vec<TypeQLError>> for Error {
3838
}
3939

4040
pub(crate) fn syntax_error<T: pest::RuleType>(query: &str, error: PestError<T>) -> TypeQLError {
41-
let (error_line_nr, _) = match error.line_col {
41+
let (error_line_nr, error_col) = match error.line_col {
4242
LineColLocation::Pos((line, col)) => (line, col),
4343
LineColLocation::Span((line, col), _) => (line, col),
4444
};
@@ -55,7 +55,7 @@ pub(crate) fn syntax_error<T: pest::RuleType>(query: &str, error: PestError<T>)
5555
}
5656
})
5757
.join("\n");
58-
TypeQLError::SyntaxErrorDetailed { error_line_nr, formatted_error }
58+
TypeQLError::SyntaxErrorDetailed { error_line_nr, error_col, formatted_error }
5959
}
6060

6161
impl fmt::Display for Error {
@@ -75,10 +75,14 @@ pub fn collect_err(i: impl IntoIterator<Item = Result<(), Error>>) -> Result<(),
7575

7676
error_messages! { TypeQLError
7777
code: "TQL", type: "TypeQL Error",
78-
SyntaxErrorDetailed { error_line_nr: usize, formatted_error: String } =
79-
3: "There is a syntax error near line {error_line_nr}:\n{formatted_error}",
78+
SyntaxErrorDetailed { error_line_nr: usize, error_col: usize, formatted_error: String } =
79+
3: "There is a syntax error at {error_line_nr}:{error_col}:\n{formatted_error}",
8080
InvalidCasting { enum_name: &'static str, variant: &'static str, expected_variant: &'static str, typename: &'static str } =
8181
4: "Enum '{enum_name}::{variant}' does not match '{expected_variant}', and cannot be unwrapped into '{typename}'.",
82+
InvalidLiteral { variant: &'static str, expected_variant: &'static str } =
83+
5: "Attempting to parse a {variant} literal as {expected_variant}",
84+
InvalidStringEscape { escape: String, full_string: String } =
85+
6: "Encountered invalid escape sequence {escape:?} while parsing {full_string:?}.",
8286
/*
8387
MissingPatterns =
8488
5: "The query has not been provided with any patterns.",

0 commit comments

Comments
 (0)