Merge branch 'master' into add-bug-tracking-workflow
This commit is contained in:
commit
b5f5bd80bf
27
.github/workflows/package_all.yaml
vendored
27
.github/workflows/package_all.yaml
vendored
@ -160,6 +160,23 @@ jobs:
|
|||||||
name: debian-11-platform
|
name: debian-11-platform
|
||||||
path: build/output/debian-11/memgraph*.deb
|
path: build/output/debian-11/memgraph*.deb
|
||||||
|
|
||||||
|
fedora-36:
|
||||||
|
runs-on: [self-hosted, DockerMgBuild, X64]
|
||||||
|
timeout-minutes: 60
|
||||||
|
steps:
|
||||||
|
- name: "Set up repository"
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Required because of release/get_version.py
|
||||||
|
- name: "Build package"
|
||||||
|
run: |
|
||||||
|
./release/package/run.sh package fedora-36
|
||||||
|
- name: "Upload package"
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: fedora-36
|
||||||
|
path: build/output/fedora-36/memgraph*.rpm
|
||||||
|
|
||||||
debian-11-arm:
|
debian-11-arm:
|
||||||
runs-on: [self-hosted, DockerMgBuild, ARM64, strange]
|
runs-on: [self-hosted, DockerMgBuild, ARM64, strange]
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
@ -177,8 +194,8 @@ jobs:
|
|||||||
name: debian-11-arm
|
name: debian-11-arm
|
||||||
path: build/output/debian-11-arm/memgraph*.deb
|
path: build/output/debian-11-arm/memgraph*.deb
|
||||||
|
|
||||||
fedora-36:
|
ubuntu-2204-arm:
|
||||||
runs-on: [self-hosted, DockerMgBuild, X64]
|
runs-on: [self-hosted, DockerMgBuild, ARM64, strange]
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
steps:
|
steps:
|
||||||
- name: "Set up repository"
|
- name: "Set up repository"
|
||||||
@ -187,9 +204,9 @@ jobs:
|
|||||||
fetch-depth: 0 # Required because of release/get_version.py
|
fetch-depth: 0 # Required because of release/get_version.py
|
||||||
- name: "Build package"
|
- name: "Build package"
|
||||||
run: |
|
run: |
|
||||||
./release/package/run.sh package fedora-36
|
./release/package/run.sh package ubuntu-22.04-arm
|
||||||
- name: "Upload package"
|
- name: "Upload package"
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: fedora-36
|
name: ubuntu-22.04-arm
|
||||||
path: build/output/fedora-36/memgraph*.rpm
|
path: build/output/ubuntu-22.04-arm/memgraph*.deb
|
||||||
|
@ -4,10 +4,6 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
Build modern, graph-based applications on top of your streaming data in minutes.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/memgraph/memgraph/blob/master/licenses/APL.txt">
|
<a href="https://github.com/memgraph/memgraph/blob/master/licenses/APL.txt">
|
||||||
<img src="https://img.shields.io/badge/license-APL-green" alt="license" title="license"/>
|
<img src="https://img.shields.io/badge/license-APL-green" alt="license" title="license"/>
|
||||||
@ -89,6 +85,7 @@ your browser.
|
|||||||
### macOS
|
### macOS
|
||||||
|
|
||||||
[](https://memgraph.com/docs/memgraph/install-memgraph-on-macos-docker)
|
[](https://memgraph.com/docs/memgraph/install-memgraph-on-macos-docker)
|
||||||
|
[](https://memgraph.com/docs/memgraph/install-memgraph-on-ubuntu)
|
||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
|
96
environment/os/ubuntu-22.04-arm.sh
Executable file
96
environment/os/ubuntu-22.04-arm.sh
Executable file
@ -0,0 +1,96 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
|
source "$DIR/../util.sh"
|
||||||
|
|
||||||
|
check_operating_system "ubuntu-22.04"
|
||||||
|
check_architecture "arm64" "aarch64"
|
||||||
|
|
||||||
|
TOOLCHAIN_BUILD_DEPS=(
|
||||||
|
coreutils gcc g++ build-essential make # generic build tools
|
||||||
|
wget # used for archive download
|
||||||
|
gnupg # used for archive signature verification
|
||||||
|
tar gzip bzip2 xz-utils unzip # used for archive unpacking
|
||||||
|
zlib1g-dev # zlib library used for all builds
|
||||||
|
libexpat1-dev libbabeltrace-dev liblzma-dev python3-dev texinfo # for gdb
|
||||||
|
libcurl4-openssl-dev # for cmake
|
||||||
|
libreadline-dev # for cmake and llvm
|
||||||
|
libffi-dev libxml2-dev # for llvm
|
||||||
|
curl # snappy
|
||||||
|
file
|
||||||
|
git # for thrift
|
||||||
|
libgmp-dev # for gdb
|
||||||
|
gperf # for proxygen
|
||||||
|
libssl-dev
|
||||||
|
libedit-dev libpcre3-dev automake bison # for swig
|
||||||
|
)
|
||||||
|
|
||||||
|
TOOLCHAIN_RUN_DEPS=(
|
||||||
|
make # generic build tools
|
||||||
|
tar gzip bzip2 xz-utils # used for archive unpacking
|
||||||
|
zlib1g # zlib library used for all builds
|
||||||
|
libexpat1 libbabeltrace1 liblzma5 python3 # for gdb
|
||||||
|
libcurl4 # for cmake
|
||||||
|
libreadline8 # for cmake and llvm
|
||||||
|
libffi7 libxml2 # for llvm
|
||||||
|
libssl-dev # for libevent
|
||||||
|
)
|
||||||
|
|
||||||
|
MEMGRAPH_BUILD_DEPS=(
|
||||||
|
git # source code control
|
||||||
|
make pkg-config # build system
|
||||||
|
curl wget # for downloading libs
|
||||||
|
uuid-dev default-jre-headless # required by antlr
|
||||||
|
libreadline-dev # for memgraph console
|
||||||
|
libpython3-dev python3-dev # for query modules
|
||||||
|
libssl-dev
|
||||||
|
libseccomp-dev
|
||||||
|
netcat # tests are using nc to wait for memgraph
|
||||||
|
python3 python3-virtualenv python3-pip # for qa, macro_benchmark and stress tests
|
||||||
|
python3-yaml # for the configuration generator
|
||||||
|
libcurl4-openssl-dev # mg-requests
|
||||||
|
sbcl # for custom Lisp C++ preprocessing
|
||||||
|
doxygen graphviz # source documentation generators
|
||||||
|
mono-runtime mono-mcs zip unzip default-jdk-headless # for driver tests
|
||||||
|
dotnet-sdk-6.0 golang nodejs npm
|
||||||
|
autoconf # for jemalloc code generation
|
||||||
|
libtool # for protobuf code generation
|
||||||
|
)
|
||||||
|
|
||||||
|
list() {
|
||||||
|
echo "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
check() {
|
||||||
|
check_all_dpkg "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
cd "$DIR"
|
||||||
|
apt update
|
||||||
|
# If GitHub Actions runner is installed, append LANG to the environment.
|
||||||
|
# Python related tests doesn't work the LANG export.
|
||||||
|
if [ -d "/home/gh/actions-runner" ]; then
|
||||||
|
echo "LANG=en_US.utf8" >> /home/gh/actions-runner/.env
|
||||||
|
else
|
||||||
|
echo "NOTE: export LANG=en_US.utf8"
|
||||||
|
fi
|
||||||
|
apt install -y wget
|
||||||
|
for pkg in $1; do
|
||||||
|
if [ "$pkg" == dotnet-sdk-6.0 ]; then
|
||||||
|
if ! dpkg -s dotnet-sdk-6.0 2>/dev/null >/dev/null; then
|
||||||
|
wget -nv https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
|
||||||
|
dpkg -i packages-microsoft-prod.deb
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y apt-transport-https dotnet-sdk-6.0
|
||||||
|
fi
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
apt install -y "$pkg"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
deps=$2"[*]"
|
||||||
|
"$1" "${!deps}"
|
@ -51,11 +51,19 @@ CPPCHECK_VERSION=2.6
|
|||||||
LLVM_VERSION=13.0.0
|
LLVM_VERSION=13.0.0
|
||||||
SWIG_VERSION=4.0.2 # used only for LLVM compilation
|
SWIG_VERSION=4.0.2 # used only for LLVM compilation
|
||||||
|
|
||||||
# Check for the dependencies.
|
# Set the right env script
|
||||||
echo "ALL BUILD PACKAGES: $($DIR/../os/$DISTRO.sh list TOOLCHAIN_BUILD_DEPS)"
|
ENV_SCRIPT="$DIR/../os/$DISTRO.sh"
|
||||||
$DIR/../os/$DISTRO.sh check TOOLCHAIN_BUILD_DEPS
|
if [[ "$for_arm" = true ]]; then
|
||||||
echo "ALL RUN PACKAGES: $($DIR/../os/$DISTRO.sh list TOOLCHAIN_RUN_DEPS)"
|
ENV_SCRIPT="$DIR/../os/$DISTRO-arm.sh"
|
||||||
$DIR/../os/$DISTRO.sh check TOOLCHAIN_RUN_DEPS
|
fi
|
||||||
|
|
||||||
|
# Check for the toolchain build dependencies.
|
||||||
|
echo "ALL BUILD PACKAGES: $(${ENV_SCRIPT} list TOOLCHAIN_BUILD_DEPS)"
|
||||||
|
${ENV_SCRIPT} check TOOLCHAIN_BUILD_DEPS
|
||||||
|
|
||||||
|
# Check for the toolchain run dependencies.
|
||||||
|
echo "ALL RUN PACKAGES: $(${ENV_SCRIPT} list TOOLCHAIN_RUN_DEPS)"
|
||||||
|
${ENV_SCRIPT} check TOOLCHAIN_RUN_DEPS
|
||||||
|
|
||||||
# check installation directory
|
# check installation directory
|
||||||
NAME=toolchain-v$TOOLCHAIN_VERSION
|
NAME=toolchain-v$TOOLCHAIN_VERSION
|
||||||
@ -622,7 +630,7 @@ In order to be able to run all of these tools you should install the following
|
|||||||
packages:
|
packages:
|
||||||
|
|
||||||
\`\`\`
|
\`\`\`
|
||||||
$($DIR/../os/$DISTRO.sh list TOOLCHAIN_RUN_DEPS)
|
$($DIR/../os/$ENV_SCRIPT.sh list TOOLCHAIN_RUN_DEPS)
|
||||||
\`\`\`
|
\`\`\`
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
@ -19,13 +19,16 @@ function architecture() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_architecture() {
|
check_architecture() {
|
||||||
|
local ARCH=$(architecture)
|
||||||
for arch in "$@"; do
|
for arch in "$@"; do
|
||||||
if [ "$(architecture)" = "$arch" ]; then
|
if [ "${ARCH}" = "$arch" ]; then
|
||||||
echo "The right architecture!"
|
echo "The right architecture!"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
echo "Not the right architecture!"
|
echo "Not the right architecture!"
|
||||||
|
echo "Expected: $@"
|
||||||
|
echo "Actual: ${ARCH}"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
release/package/arm-builders.yml
Normal file
11
release/package/arm-builders.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
version: "3"
|
||||||
|
|
||||||
|
services:
|
||||||
|
debian-11-arm:
|
||||||
|
build:
|
||||||
|
context: debian-11-arm
|
||||||
|
container_name: "mgbuild_debian-11-arm"
|
||||||
|
ubuntu-2204-arm:
|
||||||
|
build:
|
||||||
|
context: ubuntu-22.04-arm
|
||||||
|
container_name: "mgbuild_ubuntu-22.04-arm"
|
@ -3,7 +3,7 @@
|
|||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
|
|
||||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
SUPPORTED_OS=(centos-7 centos-9 debian-10 debian-11 ubuntu-18.04 ubuntu-20.04 ubuntu-22.04 debian-11-arm fedora-36)
|
SUPPORTED_OS=(centos-7 centos-9 debian-10 debian-11 ubuntu-18.04 ubuntu-20.04 ubuntu-22.04 debian-11-arm fedora-36 ubuntu-22.04-arm)
|
||||||
PROJECT_ROOT="$SCRIPT_DIR/../.."
|
PROJECT_ROOT="$SCRIPT_DIR/../.."
|
||||||
TOOLCHAIN_VERSION="toolchain-v4"
|
TOOLCHAIN_VERSION="toolchain-v4"
|
||||||
ACTIVATE_TOOLCHAIN="source /opt/${TOOLCHAIN_VERSION}/activate"
|
ACTIVATE_TOOLCHAIN="source /opt/${TOOLCHAIN_VERSION}/activate"
|
||||||
@ -76,7 +76,7 @@ make_package () {
|
|||||||
docker exec "$build_container" bash -c "cd /memgraph && git config --global --add safe.directory '*'"
|
docker exec "$build_container" bash -c "cd /memgraph && git config --global --add safe.directory '*'"
|
||||||
docker exec "$build_container" bash -c "cd /memgraph && $ACTIVATE_TOOLCHAIN && ./init"
|
docker exec "$build_container" bash -c "cd /memgraph && $ACTIVATE_TOOLCHAIN && ./init"
|
||||||
docker exec "$build_container" bash -c "cd $container_build_dir && rm -rf ./*"
|
docker exec "$build_container" bash -c "cd $container_build_dir && rm -rf ./*"
|
||||||
if [[ "$os" == "debian-11-arm" ]]; then
|
if [[ "$os" =~ "-arm" ]]; then
|
||||||
docker exec "$build_container" bash -c "cd $container_build_dir && $ACTIVATE_TOOLCHAIN && cmake -DCMAKE_BUILD_TYPE=release -DMG_ARCH="ARM64" $telemetry_id_override_flag .."
|
docker exec "$build_container" bash -c "cd $container_build_dir && $ACTIVATE_TOOLCHAIN && cmake -DCMAKE_BUILD_TYPE=release -DMG_ARCH="ARM64" $telemetry_id_override_flag .."
|
||||||
else
|
else
|
||||||
docker exec "$build_container" bash -c "cd $container_build_dir && $ACTIVATE_TOOLCHAIN && cmake -DCMAKE_BUILD_TYPE=release $telemetry_id_override_flag .."
|
docker exec "$build_container" bash -c "cd $container_build_dir && $ACTIVATE_TOOLCHAIN && cmake -DCMAKE_BUILD_TYPE=release $telemetry_id_override_flag .."
|
||||||
|
17
release/package/ubuntu-22.04-arm/Dockerfile
Normal file
17
release/package/ubuntu-22.04-arm/Dockerfile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
|
ARG TOOLCHAIN_VERSION
|
||||||
|
|
||||||
|
# Stops tzdata interactive configuration.
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN apt update && apt install -y \
|
||||||
|
ca-certificates wget git
|
||||||
|
# Do NOT be smart here and clean the cache because the container is used in the
|
||||||
|
# stateful context.
|
||||||
|
|
||||||
|
RUN wget -q https://s3-eu-west-1.amazonaws.com/deps.memgraph.io/${TOOLCHAIN_VERSION}/${TOOLCHAIN_VERSION}-binaries-ubuntu-22.04-arm64.tar.gz \
|
||||||
|
-O ${TOOLCHAIN_VERSION}-binaries-ubuntu-22.04-arm64.tar.gz \
|
||||||
|
&& tar xzvf ${TOOLCHAIN_VERSION}-binaries-ubuntu-22.04-arm64.tar.gz -C /opt
|
||||||
|
|
||||||
|
ENTRYPOINT ["sleep", "infinity"]
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2022 Memgraph Ltd.
|
// Copyright 2023 Memgraph Ltd.
|
||||||
//
|
//
|
||||||
// Use of this software is governed by the Business Source License
|
// Use of this software is governed by the Business Source License
|
||||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
@ -107,5 +107,37 @@ storage::PropertyValue PropsSetChecked(T *record, const storage::PropertyId &key
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept AccessorWithInitProperties = requires(T accessor,
|
||||||
|
const std::map<storage::PropertyId, storage::PropertyValue> &properties) {
|
||||||
|
{ accessor.InitProperties(properties) } -> std::same_as<storage::Result<bool>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Set property `values` mapped with given `key` on a `record`.
|
||||||
|
///
|
||||||
|
/// @throw QueryRuntimeException if value cannot be set as a property value
|
||||||
|
template <AccessorWithInitProperties T>
|
||||||
|
bool MultiPropsInitChecked(T *record, std::map<storage::PropertyId, storage::PropertyValue> &properties) {
|
||||||
|
try {
|
||||||
|
auto maybe_values = record->InitProperties(properties);
|
||||||
|
if (maybe_values.HasError()) {
|
||||||
|
switch (maybe_values.GetError()) {
|
||||||
|
case storage::Error::SERIALIZATION_ERROR:
|
||||||
|
throw TransactionSerializationException();
|
||||||
|
case storage::Error::DELETED_OBJECT:
|
||||||
|
throw QueryRuntimeException("Trying to set properties on a deleted object.");
|
||||||
|
case storage::Error::PROPERTIES_DISABLED:
|
||||||
|
throw QueryRuntimeException("Can't set property because properties on edges are disabled.");
|
||||||
|
case storage::Error::VERTEX_HAS_EDGES:
|
||||||
|
case storage::Error::NONEXISTENT_OBJECT:
|
||||||
|
throw QueryRuntimeException("Unexpected error when setting a property.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::move(*maybe_values);
|
||||||
|
} catch (const TypedValueException &) {
|
||||||
|
throw QueryRuntimeException("Cannot set properties.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int64_t QueryTimestamp();
|
int64_t QueryTimestamp();
|
||||||
} // namespace memgraph::query
|
} // namespace memgraph::query
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2022 Memgraph Ltd.
|
// Copyright 2023 Memgraph Ltd.
|
||||||
//
|
//
|
||||||
// Use of this software is governed by the Business Source License
|
// Use of this software is governed by the Business Source License
|
||||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
@ -71,6 +71,10 @@ class EdgeAccessor final {
|
|||||||
return impl_.SetProperty(key, value);
|
return impl_.SetProperty(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
storage::Result<bool> InitProperties(const std::map<storage::PropertyId, storage::PropertyValue> &properties) {
|
||||||
|
return impl_.InitProperties(properties);
|
||||||
|
}
|
||||||
|
|
||||||
storage::Result<storage::PropertyValue> RemoveProperty(storage::PropertyId key) {
|
storage::Result<storage::PropertyValue> RemoveProperty(storage::PropertyId key) {
|
||||||
return SetProperty(key, storage::PropertyValue());
|
return SetProperty(key, storage::PropertyValue());
|
||||||
}
|
}
|
||||||
@ -125,6 +129,10 @@ class VertexAccessor final {
|
|||||||
return impl_.SetProperty(key, value);
|
return impl_.SetProperty(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
storage::Result<bool> InitProperties(const std::map<storage::PropertyId, storage::PropertyValue> &properties) {
|
||||||
|
return impl_.InitProperties(properties);
|
||||||
|
}
|
||||||
|
|
||||||
storage::Result<storage::PropertyValue> RemoveProperty(storage::PropertyId key) {
|
storage::Result<storage::PropertyValue> RemoveProperty(storage::PropertyId key) {
|
||||||
return SetProperty(key, storage::PropertyValue());
|
return SetProperty(key, storage::PropertyValue());
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include <cppitertools/chain.hpp>
|
#include <cppitertools/chain.hpp>
|
||||||
#include <cppitertools/imap.hpp>
|
#include <cppitertools/imap.hpp>
|
||||||
|
#include "query/common.hpp"
|
||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
#include "license/license.hpp"
|
#include "license/license.hpp"
|
||||||
@ -208,17 +209,18 @@ VertexAccessor &CreateLocalVertex(const NodeCreationInfo &node_info, Frame *fram
|
|||||||
storage::View::NEW);
|
storage::View::NEW);
|
||||||
// TODO: PropsSetChecked allocates a PropertyValue, make it use context.memory
|
// TODO: PropsSetChecked allocates a PropertyValue, make it use context.memory
|
||||||
// when we update PropertyValue with custom allocator.
|
// when we update PropertyValue with custom allocator.
|
||||||
|
std::map<storage::PropertyId, storage::PropertyValue> properties;
|
||||||
if (const auto *node_info_properties = std::get_if<PropertiesMapList>(&node_info.properties)) {
|
if (const auto *node_info_properties = std::get_if<PropertiesMapList>(&node_info.properties)) {
|
||||||
for (const auto &[key, value_expression] : *node_info_properties) {
|
for (const auto &[key, value_expression] : *node_info_properties) {
|
||||||
PropsSetChecked(&new_node, key, value_expression->Accept(evaluator));
|
properties.emplace(key, value_expression->Accept(evaluator));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto property_map = evaluator.Visit(*std::get<ParameterLookup *>(node_info.properties));
|
auto property_map = evaluator.Visit(*std::get<ParameterLookup *>(node_info.properties));
|
||||||
for (const auto &[key, value] : property_map.ValueMap()) {
|
for (const auto &[key, value] : property_map.ValueMap()) {
|
||||||
auto property_id = dba.NameToProperty(key);
|
properties.emplace(dba.NameToProperty(key), value);
|
||||||
PropsSetChecked(&new_node, property_id, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
MultiPropsInitChecked(&new_node, properties);
|
||||||
|
|
||||||
(*frame)[node_info.symbol] = new_node;
|
(*frame)[node_info.symbol] = new_node;
|
||||||
return (*frame)[node_info.symbol].ValueVertex();
|
return (*frame)[node_info.symbol].ValueVertex();
|
||||||
@ -299,17 +301,18 @@ EdgeAccessor CreateEdge(const EdgeCreationInfo &edge_info, DbAccessor *dba, Vert
|
|||||||
auto maybe_edge = dba->InsertEdge(from, to, edge_info.edge_type);
|
auto maybe_edge = dba->InsertEdge(from, to, edge_info.edge_type);
|
||||||
if (maybe_edge.HasValue()) {
|
if (maybe_edge.HasValue()) {
|
||||||
auto &edge = *maybe_edge;
|
auto &edge = *maybe_edge;
|
||||||
if (const auto *properties = std::get_if<PropertiesMapList>(&edge_info.properties)) {
|
std::map<storage::PropertyId, storage::PropertyValue> properties;
|
||||||
for (const auto &[key, value_expression] : *properties) {
|
if (const auto *edge_info_properties = std::get_if<PropertiesMapList>(&edge_info.properties)) {
|
||||||
PropsSetChecked(&edge, key, value_expression->Accept(*evaluator));
|
for (const auto &[key, value_expression] : *edge_info_properties) {
|
||||||
|
properties.emplace(key, value_expression->Accept(*evaluator));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto property_map = evaluator->Visit(*std::get<ParameterLookup *>(edge_info.properties));
|
auto property_map = evaluator->Visit(*std::get<ParameterLookup *>(edge_info.properties));
|
||||||
for (const auto &[key, value] : property_map.ValueMap()) {
|
for (const auto &[key, value] : property_map.ValueMap()) {
|
||||||
auto property_id = dba->NameToProperty(key);
|
properties.emplace(dba->NameToProperty(key), value);
|
||||||
PropsSetChecked(&edge, property_id, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!properties.empty()) MultiPropsInitChecked(&edge, properties);
|
||||||
|
|
||||||
(*frame)[edge_info.symbol] = edge;
|
(*frame)[edge_info.symbol] = edge;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2022 Memgraph Ltd.
|
// Copyright 2023 Memgraph Ltd.
|
||||||
//
|
//
|
||||||
// Use of this software is governed by the Business Source License
|
// Use of this software is governed by the Business Source License
|
||||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
@ -123,6 +123,24 @@ Result<storage::PropertyValue> EdgeAccessor::SetProperty(PropertyId property, co
|
|||||||
return std::move(current_value);
|
return std::move(current_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<bool> EdgeAccessor::InitProperties(const std::map<storage::PropertyId, storage::PropertyValue> &properties) {
|
||||||
|
utils::MemoryTracker::OutOfMemoryExceptionEnabler oom_exception;
|
||||||
|
if (!config_.properties_on_edges) return Error::PROPERTIES_DISABLED;
|
||||||
|
|
||||||
|
std::lock_guard<utils::SpinLock> guard(edge_.ptr->lock);
|
||||||
|
|
||||||
|
if (!PrepareForWrite(transaction_, edge_.ptr)) return Error::SERIALIZATION_ERROR;
|
||||||
|
|
||||||
|
if (edge_.ptr->deleted) return Error::DELETED_OBJECT;
|
||||||
|
|
||||||
|
if (!edge_.ptr->properties.InitProperties(properties)) return false;
|
||||||
|
for (const auto &[property, _] : properties) {
|
||||||
|
CreateAndLinkDelta(transaction_, edge_.ptr, Delta::SetPropertyTag(), property, PropertyValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Result<std::map<PropertyId, PropertyValue>> EdgeAccessor::ClearProperties() {
|
Result<std::map<PropertyId, PropertyValue>> EdgeAccessor::ClearProperties() {
|
||||||
if (!config_.properties_on_edges) return Error::PROPERTIES_DISABLED;
|
if (!config_.properties_on_edges) return Error::PROPERTIES_DISABLED;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2022 Memgraph Ltd.
|
// Copyright 2023 Memgraph Ltd.
|
||||||
//
|
//
|
||||||
// Use of this software is governed by the Business Source License
|
// Use of this software is governed by the Business Source License
|
||||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
@ -58,6 +58,11 @@ class EdgeAccessor final {
|
|||||||
/// @throw std::bad_alloc
|
/// @throw std::bad_alloc
|
||||||
Result<storage::PropertyValue> SetProperty(PropertyId property, const PropertyValue &value);
|
Result<storage::PropertyValue> SetProperty(PropertyId property, const PropertyValue &value);
|
||||||
|
|
||||||
|
/// Set property values only if property store is empty. Returns `true` if successully set all values,
|
||||||
|
/// `false` otherwise.
|
||||||
|
/// @throw std::bad_alloc
|
||||||
|
Result<bool> InitProperties(const std::map<storage::PropertyId, storage::PropertyValue> &properties);
|
||||||
|
|
||||||
/// Remove all properties and return old values for each removed property.
|
/// Remove all properties and return old values for each removed property.
|
||||||
/// @throw std::bad_alloc
|
/// @throw std::bad_alloc
|
||||||
Result<std::map<PropertyId, PropertyValue>> ClearProperties();
|
Result<std::map<PropertyId, PropertyValue>> ClearProperties();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2022 Memgraph Ltd.
|
// Copyright 2023 Memgraph Ltd.
|
||||||
//
|
//
|
||||||
// Use of this software is governed by the Business Source License
|
// Use of this software is governed by the Business Source License
|
||||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
@ -1053,7 +1053,7 @@ bool PropertyStore::SetProperty(PropertyId property, const PropertyValue &value)
|
|||||||
in_local_buffer = true;
|
in_local_buffer = true;
|
||||||
} else {
|
} else {
|
||||||
// Allocate a new external buffer.
|
// Allocate a new external buffer.
|
||||||
auto alloc_data = new uint8_t[property_size_to_power_of_8];
|
auto *alloc_data = new uint8_t[property_size_to_power_of_8];
|
||||||
auto alloc_size = property_size_to_power_of_8;
|
auto alloc_size = property_size_to_power_of_8;
|
||||||
|
|
||||||
SetSizeData(buffer_, alloc_size, alloc_data);
|
SetSizeData(buffer_, alloc_size, alloc_data);
|
||||||
@ -1144,6 +1144,64 @@ bool PropertyStore::SetProperty(PropertyId property, const PropertyValue &value)
|
|||||||
return !existed;
|
return !existed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PropertyStore::InitProperties(const std::map<storage::PropertyId, storage::PropertyValue> &properties) {
|
||||||
|
uint64_t size = 0;
|
||||||
|
uint8_t *data = nullptr;
|
||||||
|
std::tie(size, data) = GetSizeData(buffer_);
|
||||||
|
if (size != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t property_size = 0;
|
||||||
|
{
|
||||||
|
Writer writer;
|
||||||
|
for (const auto &[property, value] : properties) {
|
||||||
|
if (value.IsNull()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
EncodeProperty(&writer, property, value);
|
||||||
|
property_size = writer.Written();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto property_size_to_power_of_8 = ToPowerOf8(property_size);
|
||||||
|
if (property_size <= sizeof(buffer_) - 1) {
|
||||||
|
// Use the local buffer.
|
||||||
|
buffer_[0] = kUseLocalBuffer;
|
||||||
|
size = sizeof(buffer_) - 1;
|
||||||
|
data = &buffer_[1];
|
||||||
|
} else {
|
||||||
|
// Allocate a new external buffer.
|
||||||
|
auto *alloc_data = new uint8_t[property_size_to_power_of_8];
|
||||||
|
auto alloc_size = property_size_to_power_of_8;
|
||||||
|
|
||||||
|
SetSizeData(buffer_, alloc_size, alloc_data);
|
||||||
|
|
||||||
|
size = alloc_size;
|
||||||
|
data = alloc_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode the property into the data buffer.
|
||||||
|
Writer writer(data, size);
|
||||||
|
|
||||||
|
for (const auto &[property, value] : properties) {
|
||||||
|
if (value.IsNull()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
MG_ASSERT(EncodeProperty(&writer, property, value), "Invalid database state!");
|
||||||
|
writer.Written();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto metadata = writer.WriteMetadata();
|
||||||
|
if (metadata) {
|
||||||
|
// If there is any space left in the buffer we add a tombstone to
|
||||||
|
// indicate that there are no more properties to be decoded.
|
||||||
|
metadata->Set({Type::EMPTY});
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool PropertyStore::ClearProperties() {
|
bool PropertyStore::ClearProperties() {
|
||||||
bool in_local_buffer = false;
|
bool in_local_buffer = false;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2022 Memgraph Ltd.
|
// Copyright 2023 Memgraph Ltd.
|
||||||
//
|
//
|
||||||
// Use of this software is governed by the Business Source License
|
// Use of this software is governed by the Business Source License
|
||||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
@ -59,6 +59,12 @@ class PropertyStore {
|
|||||||
/// @throw std::bad_alloc
|
/// @throw std::bad_alloc
|
||||||
bool SetProperty(PropertyId property, const PropertyValue &value);
|
bool SetProperty(PropertyId property, const PropertyValue &value);
|
||||||
|
|
||||||
|
/// Init property values and return `true` if insertion took place. `false` is
|
||||||
|
/// returned if there exists property in property store and insertion couldn't take place. The time complexity of this
|
||||||
|
/// function is O(n).
|
||||||
|
/// @throw std::bad_alloc
|
||||||
|
bool InitProperties(const std::map<storage::PropertyId, storage::PropertyValue> &properties);
|
||||||
|
|
||||||
/// Remove all properties and return `true` if any removal took place.
|
/// Remove all properties and return `true` if any removal took place.
|
||||||
/// `false` is returned if there were no properties to remove. The time
|
/// `false` is returned if there were no properties to remove. The time
|
||||||
/// complexity of this function is O(1).
|
/// complexity of this function is O(1).
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2022 Memgraph Ltd.
|
// Copyright 2023 Memgraph Ltd.
|
||||||
//
|
//
|
||||||
// Use of this software is governed by the Business Source License
|
// Use of this software is governed by the Business Source License
|
||||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
@ -230,6 +230,23 @@ Result<PropertyValue> VertexAccessor::SetProperty(PropertyId property, const Pro
|
|||||||
return std::move(current_value);
|
return std::move(current_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<bool> VertexAccessor::InitProperties(const std::map<storage::PropertyId, storage::PropertyValue> &properties) {
|
||||||
|
utils::MemoryTracker::OutOfMemoryExceptionEnabler oom_exception;
|
||||||
|
std::lock_guard<utils::SpinLock> guard(vertex_->lock);
|
||||||
|
|
||||||
|
if (!PrepareForWrite(transaction_, vertex_)) return Error::SERIALIZATION_ERROR;
|
||||||
|
|
||||||
|
if (vertex_->deleted) return Error::DELETED_OBJECT;
|
||||||
|
|
||||||
|
if (!vertex_->properties.InitProperties(properties)) return false;
|
||||||
|
for (const auto &[property, value] : properties) {
|
||||||
|
CreateAndLinkDelta(transaction_, vertex_, Delta::SetPropertyTag(), property, PropertyValue());
|
||||||
|
UpdateOnSetProperty(indices_, property, value, vertex_, *transaction_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Result<std::map<PropertyId, PropertyValue>> VertexAccessor::ClearProperties() {
|
Result<std::map<PropertyId, PropertyValue>> VertexAccessor::ClearProperties() {
|
||||||
std::lock_guard<utils::SpinLock> guard(vertex_->lock);
|
std::lock_guard<utils::SpinLock> guard(vertex_->lock);
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2022 Memgraph Ltd.
|
// Copyright 2023 Memgraph Ltd.
|
||||||
//
|
//
|
||||||
// Use of this software is governed by the Business Source License
|
// Use of this software is governed by the Business Source License
|
||||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
@ -68,6 +68,11 @@ class VertexAccessor final {
|
|||||||
/// @throw std::bad_alloc
|
/// @throw std::bad_alloc
|
||||||
Result<PropertyValue> SetProperty(PropertyId property, const PropertyValue &value);
|
Result<PropertyValue> SetProperty(PropertyId property, const PropertyValue &value);
|
||||||
|
|
||||||
|
/// Set property values only if property store is empty. Returns `true` if successully set all values,
|
||||||
|
/// `false` otherwise.
|
||||||
|
/// @throw std::bad_alloc
|
||||||
|
Result<bool> InitProperties(const std::map<storage::PropertyId, storage::PropertyValue> &properties);
|
||||||
|
|
||||||
/// Remove all properties and return the values of the removed properties.
|
/// Remove all properties and return the values of the removed properties.
|
||||||
/// @throw std::bad_alloc
|
/// @throw std::bad_alloc
|
||||||
Result<std::map<PropertyId, PropertyValue>> ClearProperties();
|
Result<std::map<PropertyId, PropertyValue>> ClearProperties();
|
||||||
|
@ -585,12 +585,12 @@ Feature: Functions
|
|||||||
"""
|
"""
|
||||||
When executing query:
|
When executing query:
|
||||||
"""
|
"""
|
||||||
MATCH ()-[r]->() RETURN PROPERTIES(r) AS p
|
MATCH ()-[r]->() RETURN PROPERTIES(r) AS p ORDER BY p.prop;
|
||||||
"""
|
"""
|
||||||
Then the result should be:
|
Then the result should be:
|
||||||
| p |
|
| p |
|
||||||
| {b: true} |
|
|
||||||
| {} |
|
| {} |
|
||||||
|
| {b: true} |
|
||||||
| {c: 123} |
|
| {c: 123} |
|
||||||
|
|
||||||
Scenario: Properties test2:
|
Scenario: Properties test2:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2022 Memgraph Ltd.
|
// Copyright 2023 Memgraph Ltd.
|
||||||
//
|
//
|
||||||
// Use of this software is governed by the Business Source License
|
// Use of this software is governed by the Business Source License
|
||||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
@ -649,3 +649,26 @@ TEST(PropertyStore, IsPropertyEqualTemporalData) {
|
|||||||
ASSERT_FALSE(props.IsPropertyEqual(prop, memgraph::storage::PropertyValue(memgraph::storage::TemporalData{
|
ASSERT_FALSE(props.IsPropertyEqual(prop, memgraph::storage::PropertyValue(memgraph::storage::TemporalData{
|
||||||
memgraph::storage::TemporalType::Date, 30})));
|
memgraph::storage::TemporalType::Date, 30})));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(PropertyStore, SetMultipleProperties) {
|
||||||
|
memgraph::storage::PropertyStore store;
|
||||||
|
std::vector<memgraph::storage::PropertyValue> vec{memgraph::storage::PropertyValue(true),
|
||||||
|
memgraph::storage::PropertyValue(123),
|
||||||
|
memgraph::storage::PropertyValue()};
|
||||||
|
std::map<std::string, memgraph::storage::PropertyValue> map{{"nandare", memgraph::storage::PropertyValue(false)}};
|
||||||
|
const memgraph::storage::TemporalData temporal{memgraph::storage::TemporalType::LocalDateTime, 23};
|
||||||
|
std::map<memgraph::storage::PropertyId, memgraph::storage::PropertyValue> data{
|
||||||
|
{memgraph::storage::PropertyId::FromInt(1), memgraph::storage::PropertyValue(true)},
|
||||||
|
{memgraph::storage::PropertyId::FromInt(2), memgraph::storage::PropertyValue(123)},
|
||||||
|
{memgraph::storage::PropertyId::FromInt(3), memgraph::storage::PropertyValue(123.5)},
|
||||||
|
{memgraph::storage::PropertyId::FromInt(4), memgraph::storage::PropertyValue("nandare")},
|
||||||
|
{memgraph::storage::PropertyId::FromInt(5), memgraph::storage::PropertyValue(vec)},
|
||||||
|
{memgraph::storage::PropertyId::FromInt(6), memgraph::storage::PropertyValue(map)},
|
||||||
|
{memgraph::storage::PropertyId::FromInt(7), memgraph::storage::PropertyValue(temporal)}};
|
||||||
|
|
||||||
|
store.InitProperties(data);
|
||||||
|
|
||||||
|
for (auto &[key, value] : data) {
|
||||||
|
ASSERT_TRUE(store.IsPropertyEqual(key, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user