Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enum datatype (v1) #852

Merged
merged 9 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions pages/fundamentals/data-types.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ the supported types. Below is a table of supported data types.
| [`LocalTime`](#localtime) | Time without the timezone. |
| [`LocalDateTime`](#localdatetime) | Date and time without the timezone. |
| [`ZonedDateTime`](#zoneddatetime) | Date and time in a specific timezone. |
| [`Enum`](#enum) | An enumeration value. |

<Callout type="info">

Expand Down Expand Up @@ -664,6 +665,64 @@ ZonedDateTime operations:
| ZonedDateTime - Duration | ZonedDateTime |
| ZonedDateTime - ZonedDateTime | Duration |

### Enum

Unlike other datatypes, enums requires that they are defined first. Each named enum had a set of values it can represent.

<Callout type="info">

To create an Enum:
kgolubic marked this conversation as resolved.
Show resolved Hide resolved

```cypher
CREATE ENUM Status VALUES { Good, Okay, Bad };
```

To see what enums exist use

```cypher
SHOW ENUMS;
```

```plaintext copy=false
┌─────────────────────────┬─────────────────────────┐
│ Enum Name │ Enum Values │
├─────────────────────────┼─────────────────────────┤
│ "Status" │ ["Good", "Okay", "Bad"] │
└─────────────────────────┴─────────────────────────┘
```

</Callout>

**Literals**

Inside a query you can refer to enum values in their literal form `name::value`:

Examples:

```cypher
CREATE (:Machine {status: Status::Good});
CREATE (:Machine {status: Status::Okay});
MATCH (n:Machine) WHERE n.status = Status::Bad RETURN n;
```

**Strings**

The `ToEnum()` function takes string(s) to lookup and return enum value.

Examples:

```cypher
RETURN ToEnum("Status", "Good");
RETURN ToEnum("Status::Okay");
```

<Callout type="info">

Bolt protocol does not understand enums, it is marshalled to the client encoded as a map value.
Updated clients aware of this marshalling will pretty print enum in client side results.
kgolubic marked this conversation as resolved.
Show resolved Hide resolved

</Callout>

## Procedures API

Data types are also used within query modules. Check out the documentation for
Expand Down
2 changes: 2 additions & 0 deletions pages/fundamentals/graph-modeling.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ Another important thing worth considering when modeling a graph is property data

Storing a local datetime takes up fewer resources if saved as a temporal type instead of a string. For example, if we have a “2021-10-05T14:15:00” value and store it as a string, it takes up 3B and at least 1B for each character. Since the string containing the date and time has 19 characters, the local datetime stored as a string will take at least 22B of memory. On the other hand, if that datetime is stored as temporal data in Memgraph, it will take 15B of memory. For more information on how much memory each data type occupies, check the [example with detailed calculation](/fundamentals/storage-memory-usage#the-calculation-in-detail).

Known repeated values are better represented as enums than strings. They take fewer resources and are faster to compare.

### Should I use property or relationship?

Graph property models are not so complicated as they may have appeared, right?
Expand Down
1 change: 1 addition & 0 deletions pages/fundamentals/storage-memory-usage.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ $\texttt{propertySize} = \texttt{basicMetadata} + \texttt{propertyID} + [\texttt
|`TEMPORAL_DATA` | 1B + 1B + 1B + min 1B + min 1B | Basic metadata, property ID, additional metadata, seconds, microseconds. Value of the seconds and microseconds is at least 1B, but probably 4B in most cases due to the large values they store. |
|`ZONED_TEMPORAL_DATA` | `TEMPORAL_DATA` + 1B + min 1B | Like `TEMPORAL_DATA`, but followed by timezone name length (1 byte) and string (1 byte per character). |
|`OFFSET_ZONED_TEMPORAL_DATA` | `TEMPORAL_DATA` + 2B | Like `TEMPORAL_DATA`, but followed by the offset from UTC (in minutes; always 2 bytes). |
|`ENUM` | 1B + 1B + 2B, 4B, 8B or 16B | Basic metadata, property ID and the value depending on required size representation required. |

### Marvel dataset use case

Expand Down
1 change: 1 addition & 0 deletions pages/querying/clauses.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ description: Master the use of clauses in Memgraph for enhanced graph computing.
The **Cypher** language enables users to perform standard database operations by
using the following clauses:

* [`ALTER`](/querying/clauses/alter) - alter existing definitions of [enums](/fundamentals/data-types#enums)
* [`CALL`](/querying/clauses/call) - calls a subquery inside the query
* [`CASE`](/querying/clauses/case) - allows the creation of conditional expressions
* [`CREATE`](/querying/clauses/create) - creates new nodes and relationships
Expand Down
1 change: 1 addition & 0 deletions pages/querying/clauses/_meta.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"alter": "ALTER",
"call": "CALL",
"case": "CASE",
"create": "CREATE",
Expand Down
28 changes: 28 additions & 0 deletions pages/querying/clauses/alter.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
title: ALTER clause
kgolubic marked this conversation as resolved.
Show resolved Hide resolved
description: Learn how to alter existing definitions of enums.
---

import { Callout } from 'nextra/components'

# ALTER clause

The `ALTER` clause is used to alter existing definitions of enums.
kgolubic marked this conversation as resolved.
Show resolved Hide resolved

# 1. Altering an enums

## 1.1 Adding an extra value

Use the following query to add a single value to an existing enum.

```cypher
ALTER ENUM Suit ADD VALUE Joker;
```

## 1.2 Updating a value

Use the following query to change representation of an existing value in an existing enum.

```cypher
ALTER ENUM Suit UPDATE VALUE Joker TO Wild;
```
13 changes: 12 additions & 1 deletion pages/querying/clauses/create.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Callout } from 'nextra/components'

# CREATE clause

The `CREATE` clause is used to create nodes and relationships in a graph.
The `CREATE` clause is used to create nodes and relationships in a graph. Additionally `CREATE` is also used for additional database definitions, such as enums.

<Callout type="info">

Expand All @@ -25,6 +25,7 @@ more details.
2.1. [Creating a relationship between two nodes](#21-creating-a-relationship-between-two-nodes)<br />
2.2. [Creating a relationship with properties](#22-creating-a-relationship-with-properties)<br />
3. [Creating a path](#3-creating-a-path)
4. [Creating an enum](#4-creating-an-enum)

## 1. Creating nodes

Expand Down Expand Up @@ -192,3 +193,13 @@ Output:
| (:Country {name: "Belgium"})-[BORDERS_WITH {length: "30KM"}]->(:Country {name: "Netherlands"}) |
+------------------------------------------------------------------------------------------------+
```

## 4. Creating an enum

To use enums in queries (as values, properties, etc) they first need to be created.

```cypher
CREATE ENUM Suit VALUES { Hearts, Diamonds, Clubs, Spades };
```

[ALTER](/querying/clauses/alter) can be used to modify the enums afterwards.
2 changes: 1 addition & 1 deletion pages/querying/clauses/load-csv.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ if the clause returns only one row. Returning multiple rows before calling the
It's important to note that the parser parses the values as strings.
It's up to the user to convert the parsed row values to the appropriate type.
This can be done using the built-in conversion functions such as `ToInteger`,
`ToFloat`, `ToBoolean` etc. Consult the [documentation](/querying/functions) on the
`ToFloat`, `ToBoolean`, `ToEnum`, etc. Consult the [documentation](/querying/functions) on the
available conversion functions.
</Callout>

Expand Down
4 changes: 3 additions & 1 deletion pages/querying/differences-in-cypher-implementations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,10 @@ Besides implementing openCypher, Memgraph created various language extensions to
- [`DROP GRAPH`](/querying/clauses/drop-graph)
- [MAGE algorithms library](/advanced-algorithms)
- [Custom query modules](/custom-query-modules)

- [`ALTER`](/querying/clauses/alter)

<Callout type="info">

For all other unsupported constructs that you require, please open an issue on our [GitHub repository](https://github.com/memgraph/memgraph/issues).

</Callout>
7 changes: 7 additions & 0 deletions pages/querying/functions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ This section contains the list of supported functions.
| `keys` | `keys(map[Any, Any]\|Node\|Relationship) -> (List[Any])` | Returns all keys of the map. In the case of node or a relationship, returns property keys. |
| `values` | `values(map[Any, Any]\|Node\|Relationship) -> (List[Any])` | Returns all values of the map. In the case of node or a relationship, returns property values. |

### Enum

| Name | Signature | Description |
| --------------- | -------------------------------------------------| ------------------------------------------------------------- |
| `ToEnum` | `ToEnum(value: string) -> (enum)` | Gets enum value matching string of form `name::value`. |
| `ToEnum` | `ToEnum(name: string, value: string) -> (enum)` | Gets enum value passing name and value as separate strings. |


### Math functions

Expand Down