Skip to content

Commit

Permalink
Enum datatype (v1) (#852)
Browse files Browse the repository at this point in the history
* Add information around enums

* Add ALTER to the list of clauses

* Add ALTER to the list of Memgraph's Cypher extension

* Fix incorrect ALTER command

* Update pages/querying/clauses/create.mdx

* Update pages/querying/clauses/alter.mdx

* Update pages/querying/clauses/alter.mdx

* Update graph-modeling.md

* Address PR comments

---------

Co-authored-by: kgolubic <kgolubic@gmail.com>
Co-authored-by: Kruno Golubic <46486712+kgolubic@users.noreply.github.com>
  • Loading branch information
3 people authored Jul 1, 2024
1 parent 800c453 commit 1278cac
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 3 deletions.
61 changes: 61 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,66 @@ 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:

```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">

The Bolt protocol cannot directly handle enums. Therefore, enums are converted
into a map before being sent to the client. Clients that have been updated to
recognize this conversion will convert the map back into a readable enum format
and display it nicely in the client-side results.

</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
description: Learn how to alter existing definitions of enums.
---

import { Callout } from 'nextra/components'

# ALTER clause

The `ALTER` clause is used to change existing definitions of enums.

# 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

0 comments on commit 1278cac

Please sign in to comment.