Skip to content
This repository was archived by the owner on Oct 9, 2023. It is now read-only.

Commit 6155300

Browse files
Introduce Values to support expressions (#296)
## What is the goal of this PR? Introduce the 'Value' type, which is returned as the result of an expression's computation. This change follows from typedb/typeql#260, which outlines the capabilities of the new expression syntax. Values (representing any of Long, Double, Boolean, String, or DateTime) are returned as part of `ConceptMap` answers and are subtypes of `Concept` for the time being. Their main API is made of the `.get_value()` method and `.get_value_vype()` method, along with all the standard safe downcasting methods to convert a `Concept` into a `Value`, using `Concept.is_value()` and `Concept.as_value()`. We also move the import location of `ValueType` from `attribute_type.py` to `concept.py`. ## What are the changes implemented in this PR? * Introduces the `Value` concept and the required `ValueImpl` that implements it * Refactor `ValueType` to no longer live within `AttributeType` - now it exists in `Concept.ValueType` * Updates the test framework for tests involving values, including the new `ExpressionTest` behaviour scenarios, which we also add to CI
1 parent ea839a8 commit 6155300

File tree

23 files changed

+588
-207
lines changed

23 files changed

+588
-207
lines changed

.factory/automation.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ build:
121121
bazel run @vaticle_dependencies//distribution/artifact:create-netrc
122122
.factory/test-core.sh //tests/behaviour/typeql/language/match/... --test_output=errors
123123
.factory/test-core.sh //tests/behaviour/typeql/language/get/... --test_output=errors
124+
.factory/test-core.sh //tests/behaviour/typeql/language/expression/... --test_output=errors
124125
test-behaviour-match-cluster:
125126
image: vaticle-ubuntu-22.04
126127
type: foreground
@@ -135,6 +136,7 @@ build:
135136
bazel run @vaticle_dependencies//distribution/artifact:create-netrc
136137
.factory/test-cluster.sh //tests/behaviour/typeql/language/match/... --test_output=errors
137138
.factory/test-cluster.sh //tests/behaviour/typeql/language/get/... --test_output=errors
139+
.factory/test-cluster.sh //tests/behaviour/typeql/language/expression/... --test_output=errors
138140
test-behaviour-writable-core:
139141
image: vaticle-ubuntu-22.04
140142
type: foreground

dependencies/vaticle/artifacts.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def vaticle_typedb_artifacts():
2929
artifact_name = "typedb-server-{platform}-{version}.{ext}",
3030
tag_source = deployment["artifact.release"],
3131
commit_source = deployment["artifact.snapshot"],
32-
commit = "0f43f6654dff206d168711d90785d12df4c98b5e",
32+
commit = "cb119c536c44275f58df7b54da033f8fe076cac5",
3333
)
3434

3535
def vaticle_typedb_cluster_artifacts():
@@ -39,5 +39,5 @@ def vaticle_typedb_cluster_artifacts():
3939
artifact_name = "typedb-cluster-all-{platform}-{version}.{ext}",
4040
tag_source = deployment_private["artifact.release"],
4141
commit_source = deployment_private["artifact.snapshot"],
42-
commit = "9b70d31b54ed0162ce5df6ac4ab6180229bd7cb9",
42+
commit = "8044753056dd20b8e6bec6f62036eb0003d4ba06",
4343
)

dependencies/vaticle/repositories.bzl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,19 @@ def vaticle_dependencies():
2525
git_repository(
2626
name = "vaticle_dependencies",
2727
remote = "https://github.com/vaticle/dependencies",
28-
commit = "e0446ffa70cacca89cb1faa2cd6f299c3784d845", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_dependencies
28+
commit = "385716283e1e64245c3679a06054e271a0608ac1", # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_dependencies
2929
)
3030

3131
def vaticle_typedb_common():
3232
git_repository(
3333
name = "vaticle_typedb_common",
3434
remote = "https://github.com/vaticle/typedb-common",
35-
tag = "2.17.0" # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_typedb_common
35+
commit = "9372dfb227d54c6eb631eed02e67f250e55e657e" # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_typedb_common
3636
)
3737

3838
def vaticle_typedb_behaviour():
3939
git_repository(
4040
name = "vaticle_typedb_behaviour",
4141
remote = "https://github.com/vaticle/typedb-behaviour",
42-
commit = "aa675d9052046b1a4ffd45f444854d8735028702" # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_typedb_behaviour
42+
commit = "767bf98fef7383addf42a1ae6e97a44874bb4f0b" # sync-marker: do not remove this comment, this is used for sync-dependencies by @vaticle_typedb_behaviour
4343
)

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535

3636
## Dependencies
3737

38-
typedb-protocol==2.18.0.dev0
38+
typedb-protocol==2.18.0.dev2
3939
grpcio>=1.43.0,<2
4040
protobuf>=3.15.6,<4
4141
parse==1.18.0

tests/behaviour/concept/thing/attribute/attribute_steps.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def step_impl(context: Context, var1: str, var2: str):
4747

4848

4949
@step("attribute {var:Var} has value type: {value_type:ValueType}")
50-
def step_impl(context: Context, var: str, value_type: AttributeType.ValueType):
50+
def step_impl(context: Context, var: str, value_type: ValueType):
5151
assert_that(context.get(var).as_attribute().get_type().get_value_type(), is_(value_type))
5252

5353

tests/behaviour/concept/type/attributetype/attribute_type_steps.py

Lines changed: 35 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -21,94 +21,90 @@
2121

2222
from behave import *
2323
from hamcrest import *
24-
from typedb.client import *
2524

2625
from tests.behaviour.config.parameters import parse_value_type, parse_list, parse_label
2726
from tests.behaviour.context import Context
27+
from typedb.client import *
2828

2929

30-
@step("put attribute type: {type_label}, with value type: {value_type}")
31-
def step_impl(context: Context, type_label: str, value_type: str):
32-
context.tx().concepts().put_attribute_type(type_label, parse_value_type(value_type))
30+
@step("put attribute type: {type_label}, with value type: {value_type:ValueType}")
31+
def step_impl(context: Context, type_label: str, value_type: ValueType):
32+
context.tx().concepts().put_attribute_type(type_label, value_type)
3333

3434

35-
@step("attribute({type_label}) get value type: {value_type}")
36-
def step_impl(context: Context, type_label: str, value_type: str):
35+
@step("attribute({type_label}) get value type: {value_type:ValueType}")
36+
def step_impl(context: Context, type_label: str, value_type: ValueType):
3737
assert_that(context.tx().concepts().get_attribute_type(type_label).get_value_type(),
38-
is_(parse_value_type(value_type)))
38+
is_(value_type))
3939

4040

41-
@step("attribute({type_label}) get supertype value type: {value_type}")
42-
def step_impl(context: Context, type_label: str, value_type: str):
41+
@step("attribute({type_label}) get supertype value type: {value_type:ValueType}")
42+
def step_impl(context: Context, type_label: str, value_type: ValueType):
4343
supertype = context.tx().concepts().get_attribute_type(type_label).as_remote(
4444
context.tx()).get_supertype().as_attribute_type()
45-
assert_that(supertype.get_value_type(), is_(parse_value_type(value_type)))
45+
assert_that(supertype.get_value_type(), is_(value_type))
4646

4747

48-
def attribute_type_as_value_type(context: Context, type_label: str, value_type: AttributeType.ValueType):
48+
def attribute_type_as_value_type(context: Context, type_label: str, value_type: ValueType):
4949
attribute_type = context.tx().concepts().get_attribute_type(type_label)
50-
if value_type is AttributeType.ValueType.OBJECT:
50+
if value_type is ValueType.OBJECT:
5151
return attribute_type
52-
elif value_type is AttributeType.ValueType.BOOLEAN:
52+
elif value_type is ValueType.BOOLEAN:
5353
return attribute_type.as_boolean()
54-
elif value_type is AttributeType.ValueType.LONG:
54+
elif value_type is ValueType.LONG:
5555
return attribute_type.as_long()
56-
elif value_type is AttributeType.ValueType.DOUBLE:
56+
elif value_type is ValueType.DOUBLE:
5757
return attribute_type.as_double()
58-
elif value_type is AttributeType.ValueType.STRING:
58+
elif value_type is ValueType.STRING:
5959
return attribute_type.as_string()
60-
elif value_type is AttributeType.ValueType.DATETIME:
60+
elif value_type is ValueType.DATETIME:
6161
return attribute_type.as_datetime()
6262
else:
6363
raise ValueError("Unrecognised value type: " + str(value_type))
6464

6565

66-
@step("attribute({type_label}) as({value_type}) get subtypes contain")
67-
def step_impl(context: Context, type_label: str, value_type: str):
66+
@step("attribute({type_label}) as({value_type:ValueType}) get subtypes contain")
67+
def step_impl(context: Context, type_label: str, value_type: ValueType):
6868
sub_labels = [parse_label(s) for s in parse_list(context.table)]
69-
attribute_type = attribute_type_as_value_type(context, type_label, parse_value_type(value_type))
69+
attribute_type = attribute_type_as_value_type(context, type_label, value_type)
7070
actuals = list(map(lambda tt: tt.get_label(), attribute_type.as_remote(context.tx()).get_subtypes()))
7171
for sub_label in sub_labels:
7272
assert_that(sub_label, is_in(actuals))
7373

7474

75-
@step("attribute({type_label}) as({value_type}) get subtypes do not contain")
76-
def step_impl(context: Context, type_label: str, value_type: str):
75+
@step("attribute({type_label}) as({value_type:ValueType}) get subtypes do not contain")
76+
def step_impl(context: Context, type_label: str, value_type: ValueType):
7777
sub_labels = [parse_label(s) for s in parse_list(context.table)]
78-
attribute_type = attribute_type_as_value_type(context, type_label, parse_value_type(value_type))
78+
attribute_type = attribute_type_as_value_type(context, type_label, value_type)
7979
actuals = list(map(lambda tt: tt.get_label(), attribute_type.as_remote(context.tx()).get_subtypes()))
8080
for sub_label in sub_labels:
8181
assert_that(sub_label, not_(is_in(actuals)))
8282

8383

84-
@step("attribute({type_label}) as({value_type}) set regex: {regex}")
85-
def step_impl(context: Context, type_label: str, value_type, regex: str):
86-
value_type = parse_value_type(value_type)
87-
assert_that(value_type, is_(AttributeType.ValueType.STRING))
84+
@step("attribute({type_label}) as({value_type:ValueType}) set regex: {regex}")
85+
def step_impl(context: Context, type_label: str, value_type: ValueType, regex: str):
86+
assert_that(value_type, is_(ValueType.STRING))
8887
attribute_type = attribute_type_as_value_type(context, type_label, value_type)
8988
attribute_type.as_remote(context.tx()).set_regex(regex)
9089

9190

92-
@step("attribute({type_label}) as({value_type}) unset regex")
93-
def step_impl(context: Context, type_label: str, value_type):
94-
value_type = parse_value_type(value_type)
95-
assert_that(value_type, is_(AttributeType.ValueType.STRING))
91+
@step("attribute({type_label}) as({value_type:ValueType}) unset regex")
92+
def step_impl(context: Context, type_label: str, value_type: ValueType):
93+
assert_that(value_type, is_(ValueType.STRING))
9694
attribute_type = attribute_type_as_value_type(context, type_label, value_type)
9795
attribute_type.as_remote(context.tx()).set_regex(None)
9896

9997

100-
@step("attribute({type_label}) as({value_type}) get regex: {regex}")
101-
def step_impl(context: Context, type_label: str, value_type, regex: str):
102-
value_type = parse_value_type(value_type)
103-
assert_that(value_type, is_(AttributeType.ValueType.STRING))
98+
@step("attribute({type_label}) as({value_type:ValueType}) get regex: {regex}")
99+
def step_impl(context: Context, type_label: str, value_type: ValueType, regex: str):
100+
assert_that(value_type, is_(ValueType.STRING))
104101
attribute_type = attribute_type_as_value_type(context, type_label, value_type)
105102
assert_that(attribute_type.as_remote(context.tx()).get_regex(), is_(regex))
106103

107104

108-
@step("attribute({type_label}) as({value_type}) does not have any regex")
109-
def step_impl(context: Context, type_label: str, value_type):
110-
value_type = parse_value_type(value_type)
111-
assert_that(value_type, is_(AttributeType.ValueType.STRING))
105+
@step("attribute({type_label}) as({value_type:ValueType}) does not have any regex")
106+
def step_impl(context: Context, type_label: str, value_type: ValueType):
107+
assert_that(value_type, is_(ValueType.STRING))
112108
attribute_type = attribute_type_as_value_type(context, type_label, value_type)
113109
assert_that(attribute_type.as_remote(context.tx()).get_regex(), is_(None))
114110

tests/behaviour/config/parameters.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,13 @@ def parse_var(text: str):
129129

130130

131131
@parse.with_pattern(r"long|double|string|boolean|datetime")
132-
def parse_value_type(value: str) -> AttributeType.ValueType:
132+
def parse_value_type(value: str) -> ValueType:
133133
mapping = {
134-
"long": AttributeType.ValueType.LONG,
135-
"double": AttributeType.ValueType.DOUBLE,
136-
"string": AttributeType.ValueType.STRING,
137-
"boolean": AttributeType.ValueType.BOOLEAN,
138-
"datetime": AttributeType.ValueType.DATETIME
134+
"long": ValueType.LONG,
135+
"double": ValueType.DOUBLE,
136+
"string": ValueType.STRING,
137+
"boolean": ValueType.BOOLEAN,
138+
"datetime": ValueType.DATETIME
139139
}
140140
return mapping[value]
141141

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#
2+
# Copyright (C) 2022 Vaticle
3+
#
4+
# Licensed to the Apache Software Foundation (ASF) under one
5+
# or more contributor license agreements. See the NOTICE file
6+
# distributed with this work for additional information
7+
# regarding copyright ownership. The ASF licenses this file
8+
# to you under the Apache License, Version 2.0 (the
9+
# "License"); you may not use this file except in compliance
10+
# with the License. You may obtain a copy of the License at
11+
#
12+
# http://www.apache.org/licenses/LICENSE-2.0
13+
#
14+
# Unless required by applicable law or agreed to in writing,
15+
# software distributed under the License is distributed on an
16+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
# KIND, either express or implied. See the License for the
18+
# specific language governing permissions and limitations
19+
# under the License.
20+
#
21+
22+
package(default_visibility = ["//tests/behaviour:__subpackages__"])
23+
load("//tools:behave_rule.bzl", "typedb_behaviour_py_test")
24+
load("@vaticle_dependencies//tool/checkstyle:rules.bzl", "checkstyle_test")
25+
26+
typedb_behaviour_py_test(
27+
name = "test",
28+
feats = ["@vaticle_typedb_behaviour//typeql/language:expression.feature"],
29+
background_core = ["//tests/behaviour/background:core"],
30+
background_cluster = ["//tests/behaviour/background:cluster"],
31+
steps = [
32+
"//tests/behaviour/connection:steps",
33+
"//tests/behaviour/connection/database:steps",
34+
"//tests/behaviour/connection/session:steps",
35+
"//tests/behaviour/connection/transaction:steps",
36+
"//tests/behaviour/typeql:steps",
37+
],
38+
deps = [
39+
"//:client_python",
40+
"//tests/behaviour:context",
41+
"//tests/behaviour/util:util",
42+
"//tests/behaviour/config:parameters",
43+
"//tests/behaviour/background",
44+
],
45+
native_typedb_artifact = "//tests:native-typedb-artifact",
46+
native_typedb_cluster_artifact = "//tests:native-typedb-cluster-artifact",
47+
size = "medium",
48+
)
49+
50+
checkstyle_test(
51+
name = "checkstyle",
52+
include = glob(["*"]),
53+
license_type = "apache-header",
54+
size = "small",
55+
)

0 commit comments

Comments
 (0)