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

Add fixed-list,union,map functions #2278

Merged
merged 1 commit into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
25 changes: 20 additions & 5 deletions src/common/type_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include "common/exception/conversion.h"
#include "common/exception/runtime.h"
#include "common/string_utils.h"
#include "common/types/blob.h"
#include "common/vector/value_vector.h"

namespace kuzu {
Expand Down Expand Up @@ -56,6 +56,11 @@ std::string TypeUtils::castValueToString(
}
}

template<>
std::string TypeUtils::toString(const int128_t& val, void* /*valueVector*/) {
return Int128_t::ToString(val);
}

template<>
std::string TypeUtils::toString(const bool& val, void* /*valueVector*/) {
return val ? "True" : "False";
Expand Down Expand Up @@ -86,6 +91,11 @@ std::string TypeUtils::toString(const ku_string_t& val, void* /*valueVector*/) {
return val.getAsString();
}

template<>
std::string TypeUtils::toString(const blob_t& val, void* /*valueVector*/) {
return Blob::toString(val.value.getData(), val.value.len);
}

template<>
std::string TypeUtils::toString(const list_entry_t& val, void* valueVector) {
auto listVector = (ValueVector*)valueVector;
Expand Down Expand Up @@ -168,10 +178,15 @@ std::string TypeUtils::toString(const struct_entry_t& val, void* valVector) {
return result;
}

std::string TypeUtils::prefixConversionExceptionMessage(
const char* data, LogicalTypeID dataTypeID) {
return "Cannot convert string " + std::string(data) + " to " +
LogicalTypeUtils::dataTypeToString(dataTypeID) + ".";
template<>
std::string TypeUtils::toString(const union_entry_t& val, void* valVector) {
auto structVector = (ValueVector*)valVector;
auto unionFieldIdx =
UnionVector::getTagVector(structVector)->getValue<union_field_idx_t>(val.entry.pos);
auto unionFieldVector = UnionVector::getValVector(structVector, unionFieldIdx);
return castValueToString(unionFieldVector->dataType,
unionFieldVector->getData() + unionFieldVector->getNumBytesPerValue() * val.entry.pos,
unionFieldVector);
}

} // namespace common
Expand Down
8 changes: 4 additions & 4 deletions src/common/types/types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -745,8 +745,6 @@ std::vector<LogicalTypeID> LogicalTypeUtils::getIntegerLogicalTypeIDs() {
}

std::vector<LogicalType> LogicalTypeUtils::getAllValidLogicTypes() {
// TODO(Ziyi): Add FIX_LIST,MAP type to allValidTypeID when we support functions on
// FIXED_LIST,MAP.
return std::vector<LogicalType>{LogicalType{LogicalTypeID::INTERNAL_ID},
LogicalType{LogicalTypeID::BOOL}, LogicalType{LogicalTypeID::INT64},
LogicalType{LogicalTypeID::INT32}, LogicalType{LogicalTypeID::INT16},
Expand All @@ -756,9 +754,11 @@ std::vector<LogicalType> LogicalTypeUtils::getAllValidLogicTypes() {
LogicalType{LogicalTypeID::DOUBLE}, LogicalType{LogicalTypeID::STRING},
LogicalType{LogicalTypeID::BLOB}, LogicalType{LogicalTypeID::DATE},
LogicalType{LogicalTypeID::TIMESTAMP}, LogicalType{LogicalTypeID::INTERVAL},
LogicalType{LogicalTypeID::VAR_LIST}, LogicalType{LogicalTypeID::FLOAT},
LogicalType{LogicalTypeID::VAR_LIST}, LogicalType{LogicalTypeID::FIXED_LIST},
LogicalType{LogicalTypeID::MAP}, LogicalType{LogicalTypeID::FLOAT},
LogicalType{LogicalTypeID::SERIAL}, LogicalType{LogicalTypeID::NODE},
LogicalType{LogicalTypeID::REL}, LogicalType{LogicalTypeID::STRUCT}};
LogicalType{LogicalTypeID::REL}, LogicalType{LogicalTypeID::STRUCT},
LogicalType{LogicalTypeID::UNION}};
}

std::vector<std::string> LogicalTypeUtils::parseStructFields(const std::string& structTypeStr) {
Expand Down
54 changes: 51 additions & 3 deletions src/function/vector_cast_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,48 @@ vector_function_definitions CastToIntervalVectorFunction::getDefinitions() {
return result;
}

void castFixedListToString(
ValueVector& param, uint64_t pos, ValueVector& resultVector, uint64_t resultPos) {
resultVector.setNull(resultPos, param.isNull(pos));
if (param.isNull(pos)) {
return;
}
std::string result = "[";
auto numValuesPerList = FixedListType::getNumElementsInList(&param.dataType);
auto childType = FixedListType::getChildType(&param.dataType);
auto values = param.getData() + pos * param.getNumBytesPerValue();
for (auto i = 0u; i < numValuesPerList - 1; ++i) {
// Note: FixedList can only store numeric types and doesn't allow nulls.
result += TypeUtils::castValueToString(*childType, values, nullptr /* vector */);
result += ",";
values += PhysicalTypeUtils::getFixedTypeSize(childType->getPhysicalType());
}
result += TypeUtils::castValueToString(*childType, values, nullptr /* vector */);
result += "]";
resultVector.setValue(resultPos, result);
}

void fixedListCastExecFunction(
const std::vector<std::shared_ptr<ValueVector>>& params, common::ValueVector& result) {
assert(params.size() == 1);
auto param = params[0];
if (param->state->isFlat()) {
castFixedListToString(*param, param->state->selVector->selectedPositions[0], result,
result.state->selVector->selectedPositions[0]);
} else if (param->state->selVector->isUnfiltered()) {
for (auto i = 0u; i < param->state->selVector->selectedSize; i++) {
castFixedListToString(*param, i, result, i);
}
} else {
for (auto i = 0u; i < param->state->selVector->selectedSize; i++) {
castFixedListToString(*param, param->state->selVector->selectedPositions[i], result,
result.state->selVector->selectedPositions[i]);
}
}
}

void CastToStringVectorFunction::getUnaryCastToStringExecFunction(
common::LogicalTypeID typeID, scalar_exec_func& func) {
LogicalTypeID typeID, scalar_exec_func& func) {
switch (typeID) {
case common::LogicalTypeID::BOOL: {
func = UnaryCastExecFunction<bool, ku_string_t, CastToString>;
Expand Down Expand Up @@ -196,7 +236,7 @@ void CastToStringVectorFunction::getUnaryCastToStringExecFunction(
} break;
case common::LogicalTypeID::INT128: {
func = UnaryCastExecFunction<int128_t, ku_string_t, CastToString>;
}
} break;
case common::LogicalTypeID::UINT8: {
func = UnaryCastExecFunction<uint8_t, ku_string_t, CastToString>;
} break;
Expand All @@ -218,20 +258,28 @@ void CastToStringVectorFunction::getUnaryCastToStringExecFunction(
case common::LogicalTypeID::INTERNAL_ID: {
func = UnaryCastExecFunction<internalID_t, ku_string_t, CastToString>;
} break;
case common::LogicalTypeID::BLOB:
case common::LogicalTypeID::BLOB: {
func = UnaryCastExecFunction<blob_t, ku_string_t, CastToString>;
} break;
case common::LogicalTypeID::STRING: {
func = UnaryCastExecFunction<ku_string_t, ku_string_t, CastToString>;
} break;
case common::LogicalTypeID::VAR_LIST: {
func = UnaryCastExecFunction<list_entry_t, ku_string_t, CastToString>;
} break;
case common::LogicalTypeID::FIXED_LIST: {
func = fixedListCastExecFunction;
} break;
case common::LogicalTypeID::MAP: {
func = UnaryCastExecFunction<map_entry_t, ku_string_t, CastToString>;
} break;
case common::LogicalTypeID::NODE:
case common::LogicalTypeID::REL:
case common::LogicalTypeID::STRUCT: {
func = UnaryCastExecFunction<struct_entry_t, ku_string_t, CastToString>;
} break;
case common::LogicalTypeID::UNION: {
func = UnaryCastExecFunction<union_entry_t, ku_string_t, CastToString>;
} break;
// LCOV_EXCL_START
default:
Expand Down
17 changes: 9 additions & 8 deletions src/include/common/type_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@

namespace kuzu {
namespace common {

struct blob_t;

class TypeUtils {

public:
Expand All @@ -37,20 +40,14 @@ class TypeUtils {
memcpy(&pageOffset, ((uint8_t*)&overflowPtr) + 4, 2);
}

static std::string prefixConversionExceptionMessage(const char* data, LogicalTypeID dataTypeID);

private:
static std::string castValueToString(
const LogicalType& dataType, const uint8_t* value, void* vector);
};

template<>
inline std::string TypeUtils::toString(const int128_t& val, void* /*valueVector*/) {
return Int128_t::ToString(val);
}

// Forward declaration of template specializations.
template<>
std::string TypeUtils::toString(const int128_t& val, void* valueVector);
template<>
std::string TypeUtils::toString(const bool& val, void* valueVector);
template<>
std::string TypeUtils::toString(const internalID_t& val, void* valueVector);
Expand All @@ -63,11 +60,15 @@ std::string TypeUtils::toString(const interval_t& val, void* valueVector);
template<>
std::string TypeUtils::toString(const ku_string_t& val, void* valueVector);
template<>
std::string TypeUtils::toString(const blob_t& val, void* valueVector);
template<>
std::string TypeUtils::toString(const list_entry_t& val, void* valueVector);
template<>
std::string TypeUtils::toString(const map_entry_t& val, void* valueVector);
template<>
std::string TypeUtils::toString(const struct_entry_t& val, void* valueVector);
template<>
std::string TypeUtils::toString(const union_entry_t& val, void* valueVector);

} // namespace common
} // namespace kuzu
11 changes: 5 additions & 6 deletions src/include/common/types/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,9 @@ using vector_idx_t = uint32_t;
constexpr vector_idx_t INVALID_VECTOR_IDX = UINT32_MAX;
using block_idx_t = uint64_t;
constexpr block_idx_t INVALID_BLOCK_IDX = UINT64_MAX;
using field_idx_t = uint64_t;
using struct_field_idx_t = uint64_t;
using union_field_idx_t = uint64_t;
constexpr struct_field_idx_t INVALID_STRUCT_FIELD_IDX = UINT64_MAX;
using struct_field_idx_t = uint8_t;
using union_field_idx_t = struct_field_idx_t;
constexpr struct_field_idx_t INVALID_STRUCT_FIELD_IDX = UINT8_MAX;
using row_idx_t = uint64_t;
constexpr row_idx_t INVALID_ROW_IDX = UINT64_MAX;
constexpr uint32_t UNDEFINED_CAST_COST = UINT32_MAX;
Expand Down Expand Up @@ -69,7 +68,7 @@ struct map_entry_t {
};

struct union_entry_t {
int64_t pos;
struct_entry_t entry;
};

enum class KUZU_API LogicalTypeID : uint8_t {
Expand Down Expand Up @@ -396,7 +395,7 @@ struct MapType {
struct UnionType {
static constexpr union_field_idx_t TAG_FIELD_IDX = 0;

static constexpr LogicalTypeID TAG_FIELD_TYPE = LogicalTypeID::INT64;
static constexpr LogicalTypeID TAG_FIELD_TYPE = LogicalTypeID::INT8;

static constexpr char TAG_FIELD_NAME[] = "tag";

Expand Down
5 changes: 5 additions & 0 deletions src/include/common/vector/value_vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,11 @@ class UnionVector {
return StructVector::getFieldVector(vector, UnionType::TAG_FIELD_IDX).get();
}

static inline ValueVector* getValVector(const ValueVector* vector, union_field_idx_t fieldIdx) {
assert(vector->dataType.getLogicalTypeID() == LogicalTypeID::UNION);
return StructVector::getFieldVector(vector, UnionType::getInternalFieldIdx(fieldIdx)).get();
}

static inline void referenceVector(ValueVector* vector, union_field_idx_t fieldIdx,
std::shared_ptr<ValueVector> vectorToReference) {
StructVector::referenceVector(
Expand Down
7 changes: 1 addition & 6 deletions src/include/function/cast/functions/cast_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,10 @@ namespace kuzu {
namespace function {

struct CastToString {
template<typename T>
static inline std::string castToString(T& input, const common::ValueVector& inputVector) {
return common::TypeUtils::toString(input, (void*)&inputVector);
}

template<typename T>
static inline void operation(T& input, common::ku_string_t& result,
common::ValueVector& inputVector, common::ValueVector& resultVector) {
std::string resultStr = castToString(input, inputVector);
std::string resultStr = common::TypeUtils::toString(input, (void*)&inputVector);
if (resultStr.length() > common::ku_string_t::SHORT_STR_LENGTH) {
result.overflowPtr = reinterpret_cast<uint64_t>(
common::StringVector::getInMemOverflowBuffer(&resultVector)
Expand Down
2 changes: 1 addition & 1 deletion src/include/function/union/functions/union_tag.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ struct UnionTag {
common::ValueVector& unionVector, common::ValueVector& tagVector) {
auto tagIdxVector = common::UnionVector::getTagVector(&unionVector);
auto tagIdx = tagIdxVector->getValue<common::union_field_idx_t>(
tagIdxVector->state->selVector->selectedPositions[unionValue.pos]);
tagIdxVector->state->selVector->selectedPositions[unionValue.entry.pos]);
auto tagName = common::UnionType::getFieldName(&unionVector.dataType, tagIdx);
if (tagName.length() > common::ku_string_t::SHORT_STR_LENGTH) {
tag.overflowPtr =
Expand Down
56 changes: 28 additions & 28 deletions test/test_files/copy/copy_to_csv.test
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@

-CASE TinySnbCopyToCSV

-STATEMENT COPY (MATCH (p:person) RETURN [id(p)], p.ID, p.fName, p.gender, p.isStudent, p.age, p.eyeSight, p.birthdate, p.registerTime, p.lastJobDuration, p.workedHours, p.usedNames, p.courseScoresPerTerm, p.height) TO "${DATABASE_PATH}/tinysnb.csv"
-STATEMENT COPY (MATCH (p:person) RETURN [id(p)], p.*) TO "${DATABASE_PATH}/tinysnb.csv"
---- ok
-STATEMENT load from "${DATABASE_PATH}/tinysnb.csv" return *
---- 8
[0:0]|0|Alice|1|True|35|5.000000|1900-01-01|2011-08-20 11:25:30|3 years 2 days 13:02:00|[10,5]|[Aida]|[[10,8],[6,7,8]]|1.731000
[0:1]|2|Bob|2|True|30|5.100000|1900-01-01|2008-11-03 15:25:30.000526|10 years 5 months 13:00:00.000024|[12,8]|[Bobby]|[[8,9],[9,10]]|0.990000
[0:2]|3|Carol|1|False|45|5.000000|1940-06-22|1911-08-20 02:32:21|48:24:11|[4,5]|[Carmen,Fred]|[[8,10]]|1.000000
[0:3]|5|Dan|2|False|20|4.800000|1950-07-23|2031-11-30 12:25:30|10 years 5 months 13:00:00.000024|[1,9]|[Wolfeschlegelstein,Daniel]|[[7,4],[8,8],[9]]|1.300000
[0:4]|7|Elizabeth|1|False|20|4.700000|1980-10-26|1976-12-23 11:21:42|48:24:11|[2]|[Ein]|[[6],[7],[8]]|1.463000
[0:5]|8|Farooq|2|True|25|4.500000|1980-10-26|1972-07-31 13:22:30.678559|00:18:00.024|[3,4,5,6,7]|[Fesdwe]|[[8]]|1.510000
[0:6]|9|Greg|2|False|40|4.900000|1980-10-26|1976-12-23 04:41:42|10 years 5 months 13:00:00.000024|[1]|[Grad]|[[10]]|1.600000
[0:7]|10|Hubert Blaine Wolfeschlegelsteinhausenbergerdorff|2|False|83|4.900000|1990-11-27|2023-02-21 13:25:30|3 years 2 days 13:02:00|[10,11,12,3,4,5,6,7]|[Ad,De,Hi,Kye,Orlan]|[[7],[10],[6,7]]|1.323000
[0:0]|0|Alice|1|True|False|35|5.000000|1900-01-01|2011-08-20 11:25:30|3 years 2 days 13:02:00|[10,5]|[Aida]|[[10,8],[6,7,8]]|[96,54,86,92]|1.731000
[0:1]|2|Bob|2|True|False|30|5.100000|1900-01-01|2008-11-03 15:25:30.000526|10 years 5 months 13:00:00.000024|[12,8]|[Bobby]|[[8,9],[9,10]]|[98,42,93,88]|0.990000
[0:2]|3|Carol|1|False|True|45|5.000000|1940-06-22|1911-08-20 02:32:21|48:24:11|[4,5]|[Carmen,Fred]|[[8,10]]|[91,75,21,95]|1.000000
[0:3]|5|Dan|2|False|True|20|4.800000|1950-07-23|2031-11-30 12:25:30|10 years 5 months 13:00:00.000024|[1,9]|[Wolfeschlegelstein,Daniel]|[[7,4],[8,8],[9]]|[76,88,99,89]|1.300000
[0:4]|7|Elizabeth|1|False|True|20|4.700000|1980-10-26|1976-12-23 11:21:42|48:24:11|[2]|[Ein]|[[6],[7],[8]]|[96,59,65,88]|1.463000
[0:5]|8|Farooq|2|True|False|25|4.500000|1980-10-26|1972-07-31 13:22:30.678559|00:18:00.024|[3,4,5,6,7]|[Fesdwe]|[[8]]|[80,78,34,83]|1.510000
[0:6]|9|Greg|2|False|False|40|4.900000|1980-10-26|1976-12-23 04:41:42|10 years 5 months 13:00:00.000024|[1]|[Grad]|[[10]]|[43,83,67,43]|1.600000
[0:7]|10|Hubert Blaine Wolfeschlegelsteinhausenbergerdorff|2|False|True|83|4.900000|1990-11-27|2023-02-21 13:25:30|3 years 2 days 13:02:00|[10,11,12,3,4,5,6,7]|[Ad,De,Hi,Kye,Orlan]|[[7],[10],[6,7]]|[77,64,100,54]|1.323000

-STATEMENT COPY (MATCH (m:movies) RETURN m.name, m.length, m.note, m.description, m.audience) TO "${DATABASE_PATH}/movies.csv"
-STATEMENT COPY (MATCH (m:movies) RETURN m.*) TO "${DATABASE_PATH}/movies.csv"
---- ok
-STATEMENT load from "${DATABASE_PATH}/movies.csv" return *
---- 3
Sóló cón tu párejâ|126| this is a very very good movie|{rating: 5.300000, stars: 2, views: 152, release: 2011-08-20 11:25:30, film: 2012-05-11, u8: 220, u16: 20, u32: 1, u64: 180, hugedata: 1844674407370955161811111111}|{audience1=52, audience53=42}
The 😂😃🧘🏻‍♂️🌍🌦️🍞🚗 movie|2544| the movie is very very good|{rating: 7.000000, stars: 10, views: 982, release: 2018-11-13 13:33:11, film: 2014-09-12, u8: 12, u16: 120, u32: 55, u64: 1, hugedata: -1844674407370955161511}|{audience1=33}
Roma|298|the movie is very interesting and funny|{rating: 1223.000000, stars: 100, views: 10003, release: 2011-02-11 16:44:22, film: 2013-02-22, u8: 1, u16: 15, u32: 200, u64: 4, hugedata: -15}|{}
Sóló cón tu párejâ|126| this is a very very good movie|{rating: 5.300000, stars: 2, views: 152, release: 2011-08-20 11:25:30, film: 2012-05-11, u8: 220, u16: 20, u32: 1, u64: 180, hugedata: 1844674407370955161811111111}|\xAA\xABinteresting\x0B|{audience1=52, audience53=42}|True
The 😂😃🧘🏻‍♂️🌍🌦️🍞🚗 movie|2544| the movie is very very good|{rating: 7.000000, stars: 10, views: 982, release: 2018-11-13 13:33:11, film: 2014-09-12, u8: 12, u16: 120, u32: 55, u64: 1, hugedata: -1844674407370955161511}|\xAB\xCD|{audience1=33}|8.989000
Roma|298|the movie is very interesting and funny|{rating: 1223.000000, stars: 100, views: 10003, release: 2011-02-11 16:44:22, film: 2013-02-22, u8: 1, u16: 15, u32: 200, u64: 4, hugedata: -15}|pure ascii characters|{}|254.000000


-STATEMENT COPY (MATCH (p:person)-[s:studyAt]->(o:organisation) RETURN p.ID, s.level, s.places, o.ID) TO "${DATABASE_PATH}/studyAt.csv"
Expand All @@ -35,24 +35,24 @@ Roma|298|the movie is very interesting and funny|{rating: 1223.000000, stars: 10
2|120|[anew,jsdnwusklklklwewsd]|1
8|2|[awndsnjwejwen,isuhuwennjnuhuhuwewe]|1

-STATEMENT COPY (MATCH (p:person)-[e:knows]->(p1:person) RETURN p.ID, p1.ID) TO "${DATABASE_PATH}/onehop.csv"
-STATEMENT COPY (MATCH (p:person)-[e:knows]->(p1:person) RETURN p.ID, p1.ID, p.grades, p1.grades) TO "${DATABASE_PATH}/onehop.csv"
---- ok
-STATEMENT load from "${DATABASE_PATH}/onehop.csv" return *
---- 14
0|2
0|3
0|5
2|0
2|3
2|5
3|0
3|2
3|5
5|0
5|2
5|3
7|8
7|9
0|2|[96,54,86,92]|[98,42,93,88]
0|3|[96,54,86,92]|[91,75,21,95]
0|5|[96,54,86,92]|[76,88,99,89]
2|0|[98,42,93,88]|[96,54,86,92]
2|3|[98,42,93,88]|[91,75,21,95]
2|5|[98,42,93,88]|[76,88,99,89]
3|0|[91,75,21,95]|[96,54,86,92]
3|2|[91,75,21,95]|[98,42,93,88]
3|5|[91,75,21,95]|[76,88,99,89]
5|0|[76,88,99,89]|[96,54,86,92]
5|2|[76,88,99,89]|[98,42,93,88]
5|3|[76,88,99,89]|[91,75,21,95]
7|8|[96,59,65,88]|[80,78,34,83]
7|9|[96,59,65,88]|[43,83,67,43]

-CASE CopyToWithNullAndEmptyList
-STATEMENT COPY (RETURN NULL,[],[1,3,NULL,5],[[2,3],[],NULL,[1,5,6]]) TO "${DATABASE_PATH}/nullAndEmptyList.csv"
Expand Down
8 changes: 4 additions & 4 deletions test/test_files/tinysnb/agg/simple.test
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
-CASE AggSimple

-LOG OneHopSimpleAggTest
-STATEMENT MATCH (a:person)-[:knows]->(b:person)-[:knows]->(c:person) RETURN COUNT(a.ID), MIN(a.fName), MAX(c.ID)
-STATEMENT MATCH (a:person)-[:knows]->(b:person)-[:knows]->(c:person) RETURN COUNT(a.ID), MIN(a.fName), MAX(c.ID),count(a.grades)
-PARALLELISM 8
-ENUMERATE
---- 1
36|Alice|5
36|Alice|5|36

-LOG SimpleAvgTest
-STATEMENT MATCH (a:person) RETURN AVG(a.age), AVG(a.eyeSight)
Expand Down Expand Up @@ -250,11 +250,11 @@ False
82

-LOG SimpleAggAvgInt16Test
-STATEMENT MATCH (m:movies) RETURN AVG(m.length)
-STATEMENT MATCH (m:movies) RETURN AVG(m.length), count(m.audience), count(m.grade)
-PARALLELISM 7
-ENUMERATE
---- 1
989.333333
989.333333|3|3

-LOG SimpleAggMaxInt8Test
-STATEMENT MATCH (:person)-[s:studyAt]->(:organisation) RETURN MAX(s.level)
Expand Down
Loading