From ff5e4506d166f16485689e8dda1c5f6733c1e166 Mon Sep 17 00:00:00 2001 From: Keenan Gugeler Date: Wed, 29 Nov 2023 11:30:32 -0500 Subject: [PATCH] tidy: enable cert checks Though we don't aim to be certified in any sense, these checks are still useful. Most of the changes are targeted at cert-err58-cpp, which checks that no errors are thrown during global initialization and the like. The check is helpful to us because it points out cases when it would make sense to use non-allocating globals, like `const char*` or `string_view`. The constructors of one function were changed because when the function names are `const char*`, C++ selects the wrong constructor. Additionally, the constructor arguments were inconsistently ordered. --- .clang-tidy | 5 + src/common/copier_config/copier_config.cpp | 23 +- src/common/types/int128_t.cpp | 1 + src/common/types/types.cpp | 9 +- .../common/copier_config/copier_config.h | 2 +- src/include/common/enums/expression_type.h | 380 +++++++++--------- .../expression/parsed_function_expression.h | 6 +- .../persistent/reader/npy/npy_reader.h | 1 - src/include/storage/index/hash_index_utils.h | 3 + .../storage/storage_structure/in_mem_file.h | 2 +- src/include/transaction/transaction.h | 2 +- .../expression/parsed_function_expression.cpp | 2 +- .../operator/persistent/reader/csv/driver.cpp | 5 +- .../persistent/reader/rdf/rdf_reader.cpp | 4 +- tools/benchmark/benchmark_runner.cpp | 2 +- tools/java_api/src/jni/kuzu_java.cpp | 2 +- tools/shell/embedded_shell.cpp | 46 ++- 17 files changed, 254 insertions(+), 241 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 5dbc5b6c126..c061ccaaaf9 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,4 +1,6 @@ +# Comments go at the top because otherwise clang-tidy interprets them as breaking up our list of checks. # Bugprone exception escape is super unhelpful. +# cert-str34-c is an alias for signed-char-misuse. Checks: -*, @@ -10,6 +12,9 @@ Checks: -bugprone-narrowing-conversions, -bugprone-signed-char-misuse, + cert-*, + -cert-str34-c, + concurrency-*, cppcoreguidelines-virtual-class-destructor, diff --git a/src/common/copier_config/copier_config.cpp b/src/common/copier_config/copier_config.cpp index a21700fa600..20742f9f972 100644 --- a/src/common/copier_config/copier_config.cpp +++ b/src/common/copier_config/copier_config.cpp @@ -1,22 +1,25 @@ #include "common/copier_config/copier_config.h" -#include - #include "common/assert.h" #include "common/exception/copy.h" namespace kuzu { namespace common { -const static std::unordered_map fileTypeMap{{".csv", FileType::CSV}, - {".parquet", FileType::PARQUET}, {".npy", FileType::NPY}, {".ttl", FileType::TURTLE}}; - -FileType FileTypeUtils::getFileTypeFromExtension(const std::string& extension) { - auto entry = fileTypeMap.find(extension); - if (entry == fileTypeMap.end()) { - throw CopyException("Unsupported file type " + extension); +FileType FileTypeUtils::getFileTypeFromExtension(std::string_view extension) { + if (extension == ".csv") { + return FileType::CSV; + } + if (extension == ".parquet") { + return FileType::PARQUET; + } + if (extension == ".npy") { + return FileType::NPY; + } + if (extension == ".ttl") { + return FileType::TURTLE; } - return entry->second; + throw CopyException(std::string("Unsupported file type ").append(extension)); } std::string FileTypeUtils::toString(FileType fileType) { diff --git a/src/common/types/int128_t.cpp b/src/common/types/int128_t.cpp index 748c6b28c69..1c6d2576f82 100644 --- a/src/common/types/int128_t.cpp +++ b/src/common/types/int128_t.cpp @@ -7,6 +7,7 @@ namespace kuzu::common { +// NOLINTNEXTLINE(cert-err58-cpp): This initialization won't actually throw. const int128_t Int128_t::powerOf10[]{ int128_t(1), int128_t(10), diff --git a/src/common/types/types.cpp b/src/common/types/types.cpp index ef74664bdf2..afb428585a5 100644 --- a/src/common/types/types.cpp +++ b/src/common/types/types.cpp @@ -275,12 +275,9 @@ LogicalType::LogicalType(const LogicalType& other) { } LogicalType& LogicalType::operator=(const LogicalType& other) { - typeID = other.typeID; - physicalType = other.physicalType; - if (other.extraTypeInfo != nullptr) { - extraTypeInfo = other.extraTypeInfo->copy(); - } - return *this; + // Reuse the copy constructor and move assignment operator. + LogicalType copy(other); + return *this = std::move(copy); } bool LogicalType::operator==(const LogicalType& other) const { diff --git a/src/include/common/copier_config/copier_config.h b/src/include/common/copier_config/copier_config.h index 2774b54e389..2001e2df9e2 100644 --- a/src/include/common/copier_config/copier_config.h +++ b/src/include/common/copier_config/copier_config.h @@ -43,7 +43,7 @@ struct CSVReaderConfig : public CSVOption { enum class FileType : uint8_t { UNKNOWN = 0, CSV = 1, PARQUET = 2, NPY = 3, TURTLE = 4 }; struct FileTypeUtils { - static FileType getFileTypeFromExtension(const std::string& extension); + static FileType getFileTypeFromExtension(std::string_view extension); static std::string toString(FileType fileType); }; diff --git a/src/include/common/enums/expression_type.h b/src/include/common/enums/expression_type.h index c71447c2b5b..146f581087c 100644 --- a/src/include/common/enums/expression_type.h +++ b/src/include/common/enums/expression_type.h @@ -11,228 +11,228 @@ namespace common { * functions. After binding, expression type should replace function name and used as identifier. */ // aggregate -const std::string COUNT_STAR_FUNC_NAME = "COUNT_STAR"; -const std::string COUNT_FUNC_NAME = "COUNT"; -const std::string SUM_FUNC_NAME = "SUM"; -const std::string AVG_FUNC_NAME = "AVG"; -const std::string MIN_FUNC_NAME = "MIN"; -const std::string MAX_FUNC_NAME = "MAX"; -const std::string COLLECT_FUNC_NAME = "COLLECT"; +const char* const COUNT_STAR_FUNC_NAME = "COUNT_STAR"; +const char* const COUNT_FUNC_NAME = "COUNT"; +const char* const SUM_FUNC_NAME = "SUM"; +const char* const AVG_FUNC_NAME = "AVG"; +const char* const MIN_FUNC_NAME = "MIN"; +const char* const MAX_FUNC_NAME = "MAX"; +const char* const COLLECT_FUNC_NAME = "COLLECT"; // cast -const std::string CAST_FUNC_NAME = "CAST"; -const std::string CAST_DATE_FUNC_NAME = "DATE"; -const std::string CAST_TO_DATE_FUNC_NAME = "TO_DATE"; -const std::string CAST_TO_TIMESTAMP_FUNC_NAME = "TIMESTAMP"; -const std::string CAST_INTERVAL_FUNC_NAME = "INTERVAL"; -const std::string CAST_TO_INTERVAL_FUNC_NAME = "TO_INTERVAL"; -const std::string CAST_STRING_FUNC_NAME = "STRING"; -const std::string CAST_TO_STRING_FUNC_NAME = "TO_STRING"; -const std::string CAST_TO_DOUBLE_FUNC_NAME = "TO_DOUBLE"; -const std::string CAST_TO_FLOAT_FUNC_NAME = "TO_FLOAT"; -const std::string CAST_TO_SERIAL_FUNC_NAME = "TO_SERIAL"; -const std::string CAST_TO_INT64_FUNC_NAME = "TO_INT64"; -const std::string CAST_TO_INT32_FUNC_NAME = "TO_INT32"; -const std::string CAST_TO_INT16_FUNC_NAME = "TO_INT16"; -const std::string CAST_TO_INT8_FUNC_NAME = "TO_INT8"; -const std::string CAST_TO_UINT64_FUNC_NAME = "TO_UINT64"; -const std::string CAST_TO_UINT32_FUNC_NAME = "TO_UINT32"; -const std::string CAST_TO_UINT16_FUNC_NAME = "TO_UINT16"; -const std::string CAST_TO_UINT8_FUNC_NAME = "TO_UINT8"; -const std::string CAST_BLOB_FUNC_NAME = "BLOB"; -const std::string CAST_TO_BLOB_FUNC_NAME = "TO_BLOB"; -const std::string CAST_TO_BOOL_FUNC_NAME = "TO_BOOL"; -const std::string CAST_TO_INT128_FUNC_NAME = "TO_INT128"; +const char* const CAST_FUNC_NAME = "CAST"; +const char* const CAST_DATE_FUNC_NAME = "DATE"; +const char* const CAST_TO_DATE_FUNC_NAME = "TO_DATE"; +const char* const CAST_TO_TIMESTAMP_FUNC_NAME = "TIMESTAMP"; +const char* const CAST_INTERVAL_FUNC_NAME = "INTERVAL"; +const char* const CAST_TO_INTERVAL_FUNC_NAME = "TO_INTERVAL"; +const char* const CAST_STRING_FUNC_NAME = "STRING"; +const char* const CAST_TO_STRING_FUNC_NAME = "TO_STRING"; +const char* const CAST_TO_DOUBLE_FUNC_NAME = "TO_DOUBLE"; +const char* const CAST_TO_FLOAT_FUNC_NAME = "TO_FLOAT"; +const char* const CAST_TO_SERIAL_FUNC_NAME = "TO_SERIAL"; +const char* const CAST_TO_INT64_FUNC_NAME = "TO_INT64"; +const char* const CAST_TO_INT32_FUNC_NAME = "TO_INT32"; +const char* const CAST_TO_INT16_FUNC_NAME = "TO_INT16"; +const char* const CAST_TO_INT8_FUNC_NAME = "TO_INT8"; +const char* const CAST_TO_UINT64_FUNC_NAME = "TO_UINT64"; +const char* const CAST_TO_UINT32_FUNC_NAME = "TO_UINT32"; +const char* const CAST_TO_UINT16_FUNC_NAME = "TO_UINT16"; +const char* const CAST_TO_UINT8_FUNC_NAME = "TO_UINT8"; +const char* const CAST_BLOB_FUNC_NAME = "BLOB"; +const char* const CAST_TO_BLOB_FUNC_NAME = "TO_BLOB"; +const char* const CAST_TO_BOOL_FUNC_NAME = "TO_BOOL"; +const char* const CAST_TO_INT128_FUNC_NAME = "TO_INT128"; // list -const std::string LIST_CREATION_FUNC_NAME = "LIST_CREATION"; -const std::string LIST_RANGE_FUNC_NAME = "RANGE"; -const std::string LIST_EXTRACT_FUNC_NAME = "LIST_EXTRACT"; -const std::string LIST_ELEMENT_FUNC_NAME = "LIST_ELEMENT"; -const std::string LIST_CONCAT_FUNC_NAME = "LIST_CONCAT"; -const std::string LIST_CAT_FUNC_NAME = "LIST_CAT"; -const std::string ARRAY_CONCAT_FUNC_NAME = "ARRAY_CONCAT"; -const std::string ARRAY_CAT_FUNC_NAME = "ARRAY_CAT"; -const std::string LIST_APPEND_FUNC_NAME = "LIST_APPEND"; -const std::string ARRAY_APPEND_FUNC_NAME = "ARRAY_APPEND"; -const std::string ARRAY_PUSH_BACK_FUNC_NAME = "ARRAY_PUSH_BACK"; -const std::string LIST_PREPEND_FUNC_NAME = "LIST_PREPEND"; -const std::string ARRAY_PREPEND_FUNC_NAME = "ARRAY_PREPEND"; -const std::string ARRAY_PUSH_FRONT_FUNC_NAME = "ARRAY_PUSH_FRONT"; -const std::string LIST_POSITION_FUNC_NAME = "LIST_POSITION"; -const std::string LIST_INDEXOF_FUNC_NAME = "LIST_INDEXOF"; -const std::string ARRAY_POSITION_FUNC_NAME = "ARRAY_POSITION"; -const std::string ARRAY_INDEXOF_FUNC_NAME = "ARRAY_INDEXOF"; -const std::string LIST_CONTAINS_FUNC_NAME = "LIST_CONTAINS"; -const std::string LIST_HAS_FUNC_NAME = "LIST_HAS"; -const std::string ARRAY_CONTAINS_FUNC_NAME = "ARRAY_CONTAINS"; -const std::string ARRAY_HAS_FUNC_NAME = "ARRAY_HAS"; -const std::string LIST_SLICE_FUNC_NAME = "LIST_SLICE"; -const std::string ARRAY_SLICE_FUNC_NAME = "ARRAY_SLICE"; -const std::string LIST_SUM_FUNC_NAME = "LIST_SUM"; -const std::string LIST_PRODUCT_FUNC_NAME = "LIST_PRODUCT"; -const std::string LIST_SORT_FUNC_NAME = "LIST_SORT"; -const std::string LIST_REVERSE_SORT_FUNC_NAME = "LIST_REVERSE_SORT"; -const std::string LIST_DISTINCT_FUNC_NAME = "LIST_DISTINCT"; -const std::string LIST_UNIQUE_FUNC_NAME = "LIST_UNIQUE"; -const std::string LIST_ANY_VALUE_FUNC_NAME = "LIST_ANY_VALUE"; +const char* const LIST_CREATION_FUNC_NAME = "LIST_CREATION"; +const char* const LIST_RANGE_FUNC_NAME = "RANGE"; +const char* const LIST_EXTRACT_FUNC_NAME = "LIST_EXTRACT"; +const char* const LIST_ELEMENT_FUNC_NAME = "LIST_ELEMENT"; +const char* const LIST_CONCAT_FUNC_NAME = "LIST_CONCAT"; +const char* const LIST_CAT_FUNC_NAME = "LIST_CAT"; +const char* const ARRAY_CONCAT_FUNC_NAME = "ARRAY_CONCAT"; +const char* const ARRAY_CAT_FUNC_NAME = "ARRAY_CAT"; +const char* const LIST_APPEND_FUNC_NAME = "LIST_APPEND"; +const char* const ARRAY_APPEND_FUNC_NAME = "ARRAY_APPEND"; +const char* const ARRAY_PUSH_BACK_FUNC_NAME = "ARRAY_PUSH_BACK"; +const char* const LIST_PREPEND_FUNC_NAME = "LIST_PREPEND"; +const char* const ARRAY_PREPEND_FUNC_NAME = "ARRAY_PREPEND"; +const char* const ARRAY_PUSH_FRONT_FUNC_NAME = "ARRAY_PUSH_FRONT"; +const char* const LIST_POSITION_FUNC_NAME = "LIST_POSITION"; +const char* const LIST_INDEXOF_FUNC_NAME = "LIST_INDEXOF"; +const char* const ARRAY_POSITION_FUNC_NAME = "ARRAY_POSITION"; +const char* const ARRAY_INDEXOF_FUNC_NAME = "ARRAY_INDEXOF"; +const char* const LIST_CONTAINS_FUNC_NAME = "LIST_CONTAINS"; +const char* const LIST_HAS_FUNC_NAME = "LIST_HAS"; +const char* const ARRAY_CONTAINS_FUNC_NAME = "ARRAY_CONTAINS"; +const char* const ARRAY_HAS_FUNC_NAME = "ARRAY_HAS"; +const char* const LIST_SLICE_FUNC_NAME = "LIST_SLICE"; +const char* const ARRAY_SLICE_FUNC_NAME = "ARRAY_SLICE"; +const char* const LIST_SUM_FUNC_NAME = "LIST_SUM"; +const char* const LIST_PRODUCT_FUNC_NAME = "LIST_PRODUCT"; +const char* const LIST_SORT_FUNC_NAME = "LIST_SORT"; +const char* const LIST_REVERSE_SORT_FUNC_NAME = "LIST_REVERSE_SORT"; +const char* const LIST_DISTINCT_FUNC_NAME = "LIST_DISTINCT"; +const char* const LIST_UNIQUE_FUNC_NAME = "LIST_UNIQUE"; +const char* const LIST_ANY_VALUE_FUNC_NAME = "LIST_ANY_VALUE"; // struct -const std::string STRUCT_PACK_FUNC_NAME = "STRUCT_PACK"; -const std::string STRUCT_EXTRACT_FUNC_NAME = "STRUCT_EXTRACT"; +const char* const STRUCT_PACK_FUNC_NAME = "STRUCT_PACK"; +const char* const STRUCT_EXTRACT_FUNC_NAME = "STRUCT_EXTRACT"; // map -const std::string MAP_CREATION_FUNC_NAME = "MAP"; -const std::string MAP_EXTRACT_FUNC_NAME = "MAP_EXTRACT"; -const std::string ELEMENT_AT_FUNC_NAME = "ELEMENT_AT"; // alias of MAP_EXTRACT -const std::string CARDINALITY_FUNC_NAME = "CARDINALITY"; -const std::string MAP_KEYS_FUNC_NAME = "MAP_KEYS"; -const std::string MAP_VALUES_FUNC_NAME = "MAP_VALUES"; +const char* const MAP_CREATION_FUNC_NAME = "MAP"; +const char* const MAP_EXTRACT_FUNC_NAME = "MAP_EXTRACT"; +const char* const ELEMENT_AT_FUNC_NAME = "ELEMENT_AT"; // alias of MAP_EXTRACT +const char* const CARDINALITY_FUNC_NAME = "CARDINALITY"; +const char* const MAP_KEYS_FUNC_NAME = "MAP_KEYS"; +const char* const MAP_VALUES_FUNC_NAME = "MAP_VALUES"; // union -const std::string UNION_VALUE_FUNC_NAME = "UNION_VALUE"; -const std::string UNION_TAG_FUNC_NAME = "UNION_TAG"; -const std::string UNION_EXTRACT_FUNC_NAME = "UNION_EXTRACT"; +const char* const UNION_VALUE_FUNC_NAME = "UNION_VALUE"; +const char* const UNION_TAG_FUNC_NAME = "UNION_TAG"; +const char* const UNION_EXTRACT_FUNC_NAME = "UNION_EXTRACT"; // comparison -const std::string EQUALS_FUNC_NAME = "EQUALS"; -const std::string NOT_EQUALS_FUNC_NAME = "NOT_EQUALS"; -const std::string GREATER_THAN_FUNC_NAME = "GREATER_THAN"; -const std::string GREATER_THAN_EQUALS_FUNC_NAME = "GREATER_THAN_EQUALS"; -const std::string LESS_THAN_FUNC_NAME = "LESS_THAN"; -const std::string LESS_THAN_EQUALS_FUNC_NAME = "LESS_THAN_EQUALS"; +const char* const EQUALS_FUNC_NAME = "EQUALS"; +const char* const NOT_EQUALS_FUNC_NAME = "NOT_EQUALS"; +const char* const GREATER_THAN_FUNC_NAME = "GREATER_THAN"; +const char* const GREATER_THAN_EQUALS_FUNC_NAME = "GREATER_THAN_EQUALS"; +const char* const LESS_THAN_FUNC_NAME = "LESS_THAN"; +const char* const LESS_THAN_EQUALS_FUNC_NAME = "LESS_THAN_EQUALS"; // arithmetics operators -const std::string ADD_FUNC_NAME = "+"; -const std::string SUBTRACT_FUNC_NAME = "-"; -const std::string MULTIPLY_FUNC_NAME = "*"; -const std::string DIVIDE_FUNC_NAME = "/"; -const std::string MODULO_FUNC_NAME = "%"; -const std::string POWER_FUNC_NAME = "^"; +const char* const ADD_FUNC_NAME = "+"; +const char* const SUBTRACT_FUNC_NAME = "-"; +const char* const MULTIPLY_FUNC_NAME = "*"; +const char* const DIVIDE_FUNC_NAME = "/"; +const char* const MODULO_FUNC_NAME = "%"; +const char* const POWER_FUNC_NAME = "^"; // arithmetics functions -const std::string ABS_FUNC_NAME = "ABS"; -const std::string ACOS_FUNC_NAME = "ACOS"; -const std::string ASIN_FUNC_NAME = "ASIN"; -const std::string ATAN_FUNC_NAME = "ATAN"; -const std::string ATAN2_FUNC_NAME = "ATAN2"; -const std::string BITWISE_XOR_FUNC_NAME = "BITWISE_XOR"; -const std::string BITWISE_AND_FUNC_NAME = "BITWISE_AND"; -const std::string BITWISE_OR_FUNC_NAME = "BITWISE_OR"; -const std::string BITSHIFT_LEFT_FUNC_NAME = "BITSHIFT_LEFT"; -const std::string BITSHIFT_RIGHT_FUNC_NAME = "BITSHIFT_RIGHT"; -const std::string CBRT_FUNC_NAME = "CBRT"; -const std::string CEIL_FUNC_NAME = "CEIL"; -const std::string CEILING_FUNC_NAME = "CEILING"; -const std::string COS_FUNC_NAME = "COS"; -const std::string COT_FUNC_NAME = "COT"; -const std::string DEGREES_FUNC_NAME = "DEGREES"; -const std::string EVEN_FUNC_NAME = "EVEN"; -const std::string FACTORIAL_FUNC_NAME = "FACTORIAL"; -const std::string FLOOR_FUNC_NAME = "FLOOR"; -const std::string GAMMA_FUNC_NAME = "GAMMA"; -const std::string LGAMMA_FUNC_NAME = "LGAMMA"; -const std::string LN_FUNC_NAME = "LN"; -const std::string LOG_FUNC_NAME = "LOG"; -const std::string LOG2_FUNC_NAME = "LOG2"; -const std::string LOG10_FUNC_NAME = "LOG10"; -const std::string NEGATE_FUNC_NAME = "NEGATE"; -const std::string PI_FUNC_NAME = "PI"; -const std::string POW_FUNC_NAME = "POW"; -const std::string RADIANS_FUNC_NAME = "RADIANS"; -const std::string ROUND_FUNC_NAME = "ROUND"; -const std::string SIN_FUNC_NAME = "SIN"; -const std::string SIGN_FUNC_NAME = "SIGN"; -const std::string SQRT_FUNC_NAME = "SQRT"; -const std::string TAN_FUNC_NAME = "TAN"; +const char* const ABS_FUNC_NAME = "ABS"; +const char* const ACOS_FUNC_NAME = "ACOS"; +const char* const ASIN_FUNC_NAME = "ASIN"; +const char* const ATAN_FUNC_NAME = "ATAN"; +const char* const ATAN2_FUNC_NAME = "ATAN2"; +const char* const BITWISE_XOR_FUNC_NAME = "BITWISE_XOR"; +const char* const BITWISE_AND_FUNC_NAME = "BITWISE_AND"; +const char* const BITWISE_OR_FUNC_NAME = "BITWISE_OR"; +const char* const BITSHIFT_LEFT_FUNC_NAME = "BITSHIFT_LEFT"; +const char* const BITSHIFT_RIGHT_FUNC_NAME = "BITSHIFT_RIGHT"; +const char* const CBRT_FUNC_NAME = "CBRT"; +const char* const CEIL_FUNC_NAME = "CEIL"; +const char* const CEILING_FUNC_NAME = "CEILING"; +const char* const COS_FUNC_NAME = "COS"; +const char* const COT_FUNC_NAME = "COT"; +const char* const DEGREES_FUNC_NAME = "DEGREES"; +const char* const EVEN_FUNC_NAME = "EVEN"; +const char* const FACTORIAL_FUNC_NAME = "FACTORIAL"; +const char* const FLOOR_FUNC_NAME = "FLOOR"; +const char* const GAMMA_FUNC_NAME = "GAMMA"; +const char* const LGAMMA_FUNC_NAME = "LGAMMA"; +const char* const LN_FUNC_NAME = "LN"; +const char* const LOG_FUNC_NAME = "LOG"; +const char* const LOG2_FUNC_NAME = "LOG2"; +const char* const LOG10_FUNC_NAME = "LOG10"; +const char* const NEGATE_FUNC_NAME = "NEGATE"; +const char* const PI_FUNC_NAME = "PI"; +const char* const POW_FUNC_NAME = "POW"; +const char* const RADIANS_FUNC_NAME = "RADIANS"; +const char* const ROUND_FUNC_NAME = "ROUND"; +const char* const SIN_FUNC_NAME = "SIN"; +const char* const SIGN_FUNC_NAME = "SIGN"; +const char* const SQRT_FUNC_NAME = "SQRT"; +const char* const TAN_FUNC_NAME = "TAN"; // string -const std::string ARRAY_EXTRACT_FUNC_NAME = "ARRAY_EXTRACT"; -const std::string CONCAT_FUNC_NAME = "CONCAT"; -const std::string CONTAINS_FUNC_NAME = "CONTAINS"; -const std::string ENDS_WITH_FUNC_NAME = "ENDS_WITH"; -const std::string LCASE_FUNC_NAME = "LCASE"; -const std::string LEFT_FUNC_NAME = "LEFT"; -const std::string LENGTH_FUNC_NAME = "LENGTH"; -const std::string LOWER_FUNC_NAME = "LOWER"; -const std::string LPAD_FUNC_NAME = "LPAD"; -const std::string LTRIM_FUNC_NAME = "LTRIM"; -const std::string PREFIX_FUNC_NAME = "PREFIX"; -const std::string REPEAT_FUNC_NAME = "REPEAT"; -const std::string REVERSE_FUNC_NAME = "REVERSE"; -const std::string RIGHT_FUNC_NAME = "RIGHT"; -const std::string RPAD_FUNC_NAME = "RPAD"; -const std::string RTRIM_FUNC_NAME = "RTRIM"; -const std::string STARTS_WITH_FUNC_NAME = "STARTS_WITH"; -const std::string SUBSTR_FUNC_NAME = "SUBSTR"; -const std::string SUBSTRING_FUNC_NAME = "SUBSTRING"; -const std::string SUFFIX_FUNC_NAME = "SUFFIX"; -const std::string TRIM_FUNC_NAME = "TRIM"; -const std::string UCASE_FUNC_NAME = "UCASE"; -const std::string UPPER_FUNC_NAME = "UPPER"; -const std::string REGEXP_FULL_MATCH_FUNC_NAME = "REGEXP_FULL_MATCH"; -const std::string REGEXP_MATCHES_FUNC_NAME = "REGEXP_MATCHES"; -const std::string REGEXP_REPLACE_FUNC_NAME = "REGEXP_REPLACE"; -const std::string REGEXP_EXTRACT_FUNC_NAME = "REGEXP_EXTRACT"; -const std::string REGEXP_EXTRACT_ALL_FUNC_NAME = "REGEXP_EXTRACT_ALL"; -const std::string SIZE_FUNC_NAME = "SIZE"; +const char* const ARRAY_EXTRACT_FUNC_NAME = "ARRAY_EXTRACT"; +const char* const CONCAT_FUNC_NAME = "CONCAT"; +const char* const CONTAINS_FUNC_NAME = "CONTAINS"; +const char* const ENDS_WITH_FUNC_NAME = "ENDS_WITH"; +const char* const LCASE_FUNC_NAME = "LCASE"; +const char* const LEFT_FUNC_NAME = "LEFT"; +const char* const LENGTH_FUNC_NAME = "LENGTH"; +const char* const LOWER_FUNC_NAME = "LOWER"; +const char* const LPAD_FUNC_NAME = "LPAD"; +const char* const LTRIM_FUNC_NAME = "LTRIM"; +const char* const PREFIX_FUNC_NAME = "PREFIX"; +const char* const REPEAT_FUNC_NAME = "REPEAT"; +const char* const REVERSE_FUNC_NAME = "REVERSE"; +const char* const RIGHT_FUNC_NAME = "RIGHT"; +const char* const RPAD_FUNC_NAME = "RPAD"; +const char* const RTRIM_FUNC_NAME = "RTRIM"; +const char* const STARTS_WITH_FUNC_NAME = "STARTS_WITH"; +const char* const SUBSTR_FUNC_NAME = "SUBSTR"; +const char* const SUBSTRING_FUNC_NAME = "SUBSTRING"; +const char* const SUFFIX_FUNC_NAME = "SUFFIX"; +const char* const TRIM_FUNC_NAME = "TRIM"; +const char* const UCASE_FUNC_NAME = "UCASE"; +const char* const UPPER_FUNC_NAME = "UPPER"; +const char* const REGEXP_FULL_MATCH_FUNC_NAME = "REGEXP_FULL_MATCH"; +const char* const REGEXP_MATCHES_FUNC_NAME = "REGEXP_MATCHES"; +const char* const REGEXP_REPLACE_FUNC_NAME = "REGEXP_REPLACE"; +const char* const REGEXP_EXTRACT_FUNC_NAME = "REGEXP_EXTRACT"; +const char* const REGEXP_EXTRACT_ALL_FUNC_NAME = "REGEXP_EXTRACT_ALL"; +const char* const SIZE_FUNC_NAME = "SIZE"; // Date functions. -const std::string DATE_PART_FUNC_NAME = "DATE_PART"; -const std::string DATEPART_FUNC_NAME = "DATEPART"; -const std::string DATE_TRUNC_FUNC_NAME = "DATE_TRUNC"; -const std::string DATETRUNC_FUNC_NAME = "DATETRUNC"; -const std::string DAYNAME_FUNC_NAME = "DAYNAME"; -const std::string GREATEST_FUNC_NAME = "GREATEST"; -const std::string LAST_DAY_FUNC_NAME = "LAST_DAY"; -const std::string LEAST_FUNC_NAME = "LEAST"; -const std::string MAKE_DATE_FUNC_NAME = "MAKE_DATE"; -const std::string MONTHNAME_FUNC_NAME = "MONTHNAME"; +const char* const DATE_PART_FUNC_NAME = "DATE_PART"; +const char* const DATEPART_FUNC_NAME = "DATEPART"; +const char* const DATE_TRUNC_FUNC_NAME = "DATE_TRUNC"; +const char* const DATETRUNC_FUNC_NAME = "DATETRUNC"; +const char* const DAYNAME_FUNC_NAME = "DAYNAME"; +const char* const GREATEST_FUNC_NAME = "GREATEST"; +const char* const LAST_DAY_FUNC_NAME = "LAST_DAY"; +const char* const LEAST_FUNC_NAME = "LEAST"; +const char* const MAKE_DATE_FUNC_NAME = "MAKE_DATE"; +const char* const MONTHNAME_FUNC_NAME = "MONTHNAME"; // Timestamp functions. -const std::string CENTURY_FUNC_NAME = "CENTURY"; -const std::string EPOCH_MS_FUNC_NAME = "EPOCH_MS"; -const std::string TO_TIMESTAMP_FUNC_NAME = "TO_TIMESTAMP"; +const char* const CENTURY_FUNC_NAME = "CENTURY"; +const char* const EPOCH_MS_FUNC_NAME = "EPOCH_MS"; +const char* const TO_TIMESTAMP_FUNC_NAME = "TO_TIMESTAMP"; // Interval functions. -const std::string TO_YEARS_FUNC_NAME = "TO_YEARS"; -const std::string TO_MONTHS_FUNC_NAME = "TO_MONTHS"; -const std::string TO_DAYS_FUNC_NAME = "TO_DAYS"; -const std::string TO_HOURS_FUNC_NAME = "TO_HOURS"; -const std::string TO_MINUTES_FUNC_NAME = "TO_MINUTES"; -const std::string TO_SECONDS_FUNC_NAME = "TO_SECONDS"; -const std::string TO_MILLISECONDS_FUNC_NAME = "TO_MILLISECONDS"; -const std::string TO_MICROSECONDS_FUNC_NAME = "TO_MICROSECONDS"; +const char* const TO_YEARS_FUNC_NAME = "TO_YEARS"; +const char* const TO_MONTHS_FUNC_NAME = "TO_MONTHS"; +const char* const TO_DAYS_FUNC_NAME = "TO_DAYS"; +const char* const TO_HOURS_FUNC_NAME = "TO_HOURS"; +const char* const TO_MINUTES_FUNC_NAME = "TO_MINUTES"; +const char* const TO_SECONDS_FUNC_NAME = "TO_SECONDS"; +const char* const TO_MILLISECONDS_FUNC_NAME = "TO_MILLISECONDS"; +const char* const TO_MICROSECONDS_FUNC_NAME = "TO_MICROSECONDS"; // Node/Rel functions. -const std::string ID_FUNC_NAME = "ID"; -const std::string LABEL_FUNC_NAME = "LABEL"; -const std::string OFFSET_FUNC_NAME = "OFFSET"; +const char* const ID_FUNC_NAME = "ID"; +const char* const LABEL_FUNC_NAME = "LABEL"; +const char* const OFFSET_FUNC_NAME = "OFFSET"; // Path functions -const std::string NODES_FUNC_NAME = "NODES"; -const std::string RELS_FUNC_NAME = "RELS"; -const std::string PROPERTIES_FUNC_NAME = "PROPERTIES"; -const std::string IS_TRAIL_FUNC_NAME = "IS_TRAIL"; -const std::string IS_ACYCLIC_FUNC_NAME = "IS_ACYCLIC"; +const char* const NODES_FUNC_NAME = "NODES"; +const char* const RELS_FUNC_NAME = "RELS"; +const char* const PROPERTIES_FUNC_NAME = "PROPERTIES"; +const char* const IS_TRAIL_FUNC_NAME = "IS_TRAIL"; +const char* const IS_ACYCLIC_FUNC_NAME = "IS_ACYCLIC"; // Blob functions -const std::string OCTET_LENGTH_FUNC_NAME = "OCTET_LENGTH"; -const std::string ENCODE_FUNC_NAME = "ENCODE"; -const std::string DECODE_FUNC_NAME = "DECODE"; +const char* const OCTET_LENGTH_FUNC_NAME = "OCTET_LENGTH"; +const char* const ENCODE_FUNC_NAME = "ENCODE"; +const char* const DECODE_FUNC_NAME = "DECODE"; // TABLE functions -const std::string TABLE_INFO_FUNC_NAME = "TABLE_INFO"; -const std::string DB_VERSION_FUNC_NAME = "DB_VERSION"; -const std::string CURRENT_SETTING_FUNC_NAME = "CURRENT_SETTING"; -const std::string SHOW_TABLES_FUNC_NAME = "SHOW_TABLES"; -const std::string SHOW_CONNECTION_FUNC_NAME = "SHOW_CONNECTION"; -const std::string READ_PARQUET_FUNC_NAME = "READ_PARQUET"; -const std::string READ_NPY_FUNC_NAME = "READ_NPY"; -const std::string READ_CSV_SERIAL_FUNC_NAME = "READ_CSV_SERIAL"; -const std::string READ_CSV_PARALLEL_FUNC_NAME = "READ_CSV_PARALLEL"; -const std::string READ_RDF_FUNC_NAME = "READ_RDF"; -const std::string READ_PANDAS_FUNC_NAME = "READ_PANDAS"; +const char* const TABLE_INFO_FUNC_NAME = "TABLE_INFO"; +const char* const DB_VERSION_FUNC_NAME = "DB_VERSION"; +const char* const CURRENT_SETTING_FUNC_NAME = "CURRENT_SETTING"; +const char* const SHOW_TABLES_FUNC_NAME = "SHOW_TABLES"; +const char* const SHOW_CONNECTION_FUNC_NAME = "SHOW_CONNECTION"; +const char* const READ_PARQUET_FUNC_NAME = "READ_PARQUET"; +const char* const READ_NPY_FUNC_NAME = "READ_NPY"; +const char* const READ_CSV_SERIAL_FUNC_NAME = "READ_CSV_SERIAL"; +const char* const READ_CSV_PARALLEL_FUNC_NAME = "READ_CSV_PARALLEL"; +const char* const READ_RDF_FUNC_NAME = "READ_RDF"; +const char* const READ_PANDAS_FUNC_NAME = "READ_PANDAS"; enum class ExpressionType : uint8_t { diff --git a/src/include/parser/expression/parsed_function_expression.h b/src/include/parser/expression/parsed_function_expression.h index 6bab0aeeba7..63fe777df30 100644 --- a/src/include/parser/expression/parsed_function_expression.h +++ b/src/include/parser/expression/parsed_function_expression.h @@ -23,12 +23,12 @@ class ParsedFunctionExpression : public ParsedExpression { isDistinct{isDistinct}, functionName{std::move(functionName)} {} ParsedFunctionExpression(std::string alias, std::string rawName, - parsed_expression_vector children, bool isDistinct, std::string functionName) + parsed_expression_vector children, std::string functionName, bool isDistinct) : ParsedExpression{common::ExpressionType::FUNCTION, std::move(alias), std::move(rawName), std::move(children)}, isDistinct{isDistinct}, functionName{std::move(functionName)} {} - ParsedFunctionExpression(bool isDistinct, std::string functionName) + ParsedFunctionExpression(std::string functionName, bool isDistinct) : ParsedExpression{common::ExpressionType::FUNCTION}, isDistinct{isDistinct}, functionName{std::move(functionName)} {} @@ -46,7 +46,7 @@ class ParsedFunctionExpression : public ParsedExpression { inline std::unique_ptr copy() const override { return std::make_unique( - alias, rawName, copyChildren(), isDistinct, functionName); + alias, rawName, copyChildren(), functionName, isDistinct); } private: diff --git a/src/include/processor/operator/persistent/reader/npy/npy_reader.h b/src/include/processor/operator/persistent/reader/npy/npy_reader.h index 9b7bdc0f3ea..4bb5b3c0256 100644 --- a/src/include/processor/operator/persistent/reader/npy/npy_reader.h +++ b/src/include/processor/operator/persistent/reader/npy/npy_reader.h @@ -46,7 +46,6 @@ class NpyReader { size_t dataOffset; std::vector shape; common::LogicalTypeID type; - static inline const std::string defaultFieldName = "NPY_FIELD"; }; class NpyMultiFileReader { diff --git a/src/include/storage/index/hash_index_utils.h b/src/include/storage/index/hash_index_utils.h index c4ea883e840..42430bcf736 100644 --- a/src/include/storage/index/hash_index_utils.h +++ b/src/include/storage/index/hash_index_utils.h @@ -15,10 +15,13 @@ using hash_function_t = std::function; using equals_function_t = std::function; +// NOLINTBEGIN(cert-err58-cpp): This is the best way to get the datatype size because it avoids +// refactoring. static const uint32_t NUM_BYTES_FOR_INT64_KEY = storage::StorageUtils::getDataTypeSize(common::LogicalType{common::LogicalTypeID::INT64}); static const uint32_t NUM_BYTES_FOR_STRING_KEY = storage::StorageUtils::getDataTypeSize(common::LogicalType{common::LogicalTypeID::STRING}); +// NOLINTEND(cert-err58-cpp) using in_mem_insert_function_t = std::function; diff --git a/src/include/storage/storage_structure/in_mem_file.h b/src/include/storage/storage_structure/in_mem_file.h index 0d956ff8344..60a657fd89c 100644 --- a/src/include/storage/storage_structure/in_mem_file.h +++ b/src/include/storage/storage_structure/in_mem_file.h @@ -10,7 +10,7 @@ namespace kuzu { namespace storage { -static const std::string IN_MEM_TEMP_FILE_PATH = ""; +static const char* IN_MEM_TEMP_FILE_PATH = ""; // InMemFile holds a collection of in-memory page in the memory. class InMemFile { diff --git a/src/include/transaction/transaction.h b/src/include/transaction/transaction.h index 67f764efe31..2088ffb457a 100644 --- a/src/include/transaction/transaction.h +++ b/src/include/transaction/transaction.h @@ -24,7 +24,7 @@ class Transaction { localStorage = std::make_unique(mm); } - constexpr explicit Transaction(TransactionType transactionType) + constexpr explicit Transaction(TransactionType transactionType) noexcept : type{transactionType}, ID{INVALID_TRANSACTION_ID} {} public: diff --git a/src/parser/expression/parsed_function_expression.cpp b/src/parser/expression/parsed_function_expression.cpp index 29a2d9629df..5da8f0d77cb 100644 --- a/src/parser/expression/parsed_function_expression.cpp +++ b/src/parser/expression/parsed_function_expression.cpp @@ -14,7 +14,7 @@ std::unique_ptr ParsedFunctionExpression::deserialize( deserializer.deserializeValue(isDistinct); std::string functionName; deserializer.deserializeValue(functionName); - return std::make_unique(isDistinct, std::move(functionName)); + return std::make_unique(std::move(functionName), isDistinct); } void ParsedFunctionExpression::serializeInternal(Serializer& serializer) const { diff --git a/src/processor/operator/persistent/reader/csv/driver.cpp b/src/processor/operator/persistent/reader/csv/driver.cpp index d56f05d5214..7594d9aa31b 100644 --- a/src/processor/operator/persistent/reader/csv/driver.cpp +++ b/src/processor/operator/persistent/reader/csv/driver.cpp @@ -92,8 +92,9 @@ void SniffCSVNameAndTypeDriver::addValue(uint64_t, common::column_id_t, std::str try { columnType = LogicalTypeUtils::dataTypeFromString(std::string(value.substr(it + 1))); columnName = std::string(value.substr(0, it)); - } catch (Exception) { // NOLINT(bugprone-empty-catch): This is how we check for a suitable - // datatype name. + } catch (const Exception&) { // NOLINT(bugprone-empty-catch): + // This is how we check for a suitable + // datatype name. // Didn't parse, just use the whole name. } } diff --git a/src/processor/operator/persistent/reader/rdf/rdf_reader.cpp b/src/processor/operator/persistent/reader/rdf/rdf_reader.cpp index c6cf67c6db6..177014ca996 100644 --- a/src/processor/operator/persistent/reader/rdf/rdf_reader.cpp +++ b/src/processor/operator/persistent/reader/rdf/rdf_reader.cpp @@ -42,7 +42,9 @@ RDFReader::~RDFReader() { serd_reader_free(reader); serd_reader_end_stream(counter); serd_reader_free(counter); - fclose(fp); + // Even if the close fails, the stream is in an undefined state. There really isn't anything we + // can do. + (void)fclose(fp); } SerdStatus RDFReader::errorHandle(void* /*handle*/, const SerdError* error) { diff --git a/tools/benchmark/benchmark_runner.cpp b/tools/benchmark/benchmark_runner.cpp index a819494bd81..e200e4945c3 100644 --- a/tools/benchmark/benchmark_runner.cpp +++ b/tools/benchmark/benchmark_runner.cpp @@ -10,7 +10,7 @@ using namespace kuzu::main; namespace kuzu { namespace benchmark { -const std::string BENCHMARK_SUFFIX = ".benchmark"; +const char* BENCHMARK_SUFFIX = ".benchmark"; BenchmarkRunner::BenchmarkRunner( const std::string& datasetPath, std::unique_ptr config) diff --git a/tools/java_api/src/jni/kuzu_java.cpp b/tools/java_api/src/jni/kuzu_java.cpp index 8870cf8b0ab..677e80b2029 100644 --- a/tools/java_api/src/jni/kuzu_java.cpp +++ b/tools/java_api/src/jni/kuzu_java.cpp @@ -186,7 +186,7 @@ JNIEXPORT void JNICALL Java_com_kuzudb_KuzuNative_kuzu_1database_1set_1logging_1 try { Database::setLoggingLevel(lvl); env->ReleaseStringUTFChars(logging_level, lvl); - } catch (ConversionException e) { + } catch (const ConversionException& e) { env->ReleaseStringUTFChars(logging_level, lvl); jclass Exception = env->FindClass("java/lang/Exception"); env->ThrowNew(Exception, e.what()); diff --git a/tools/shell/embedded_shell.cpp b/tools/shell/embedded_shell.cpp index c6c9a59b3b7..416a3a9f3b4 100644 --- a/tools/shell/embedded_shell.cpp +++ b/tools/shell/embedded_shell.cpp @@ -1,6 +1,7 @@ #include "embedded_shell.h" #include +#include #include #include #include @@ -26,19 +27,19 @@ const char* HISTORY_PATH = "history.txt"; // build-in shell command struct ShellCommand { - const std::string HELP = ":help"; - const std::string CLEAR = ":clear"; - const std::string QUIT = ":quit"; - const std::string THREAD = ":thread"; - const std::string LOGGING_LEVEL = ":logging_level"; - const std::string QUERY_TIMEOUT = ":timeout"; - const std::vector commandList = { + const char* HELP = ":help"; + const char* CLEAR = ":clear"; + const char* QUIT = ":quit"; + const char* THREAD = ":thread"; + const char* LOGGING_LEVEL = ":logging_level"; + const char* QUERY_TIMEOUT = ":timeout"; + const std::array commandList = { HELP, CLEAR, QUIT, THREAD, LOGGING_LEVEL, QUERY_TIMEOUT}; } shellCommand; const char* TAB = " "; -const std::vector keywordList = {"CALL", "CREATE", "DELETE", "DETACH", "EXISTS", +const std::array keywordList = {"CALL", "CREATE", "DELETE", "DETACH", "EXISTS", "FOREACH", "LOAD", "MATCH", "MERGE", "OPTIONAL", "REMOVE", "RETURN", "SET", "START", "UNION", "UNWIND", "WITH", "LIMIT", "ORDER", "SKIP", "WHERE", "YIELD", "ASC", "ASCENDING", "ASSERT", "BY", "CSV", "DESC", "DESCENDING", "ON", "ALL", "CASE", "ELSE", "END", "THEN", "WHEN", "AND", @@ -48,9 +49,10 @@ const std::vector keywordList = {"CALL", "CREATE", "DELETE", "DETAC "REQUIRE", "SCALAR", "EXPLAIN", "PROFILE", "HEADERS", "FROM", "FIELDTERMINATOR", "STAR", "MINUS", "COUNT", "PRIMARY", "COPY"}; -const std::string keywordColorPrefix = "\033[32m\033[1m"; -const std::string keywordResetPostfix = "\033[00m"; +const char* keywordColorPrefix = "\033[32m\033[1m"; +const char* keywordResetPostfix = "\033[00m"; +// NOLINTNEXTLINE(cert-err58-cpp): OK to have a global regex, even if the constructor allocates. const std::regex specialChars{R"([-[\]{}()*+?.,\^$|#\s])"}; std::vector nodeTableNames; @@ -90,7 +92,7 @@ void completion(const char* buffer, linenoiseCompletions* lc) { if (buf[0] == ':') { for (auto& command : shellCommand.commandList) { if (regex_search(command, std::regex("^" + buf))) { - linenoiseAddCompletion(lc, command.c_str()); + linenoiseAddCompletion(lc, command); } } return; @@ -208,7 +210,7 @@ EmbeddedShell::EmbeddedShell(const std::string& databasePath, const SystemConfig conn = std::make_unique(database.get()); globalConnection = conn.get(); updateTableNames(); - signal(SIGINT, interruptHandler); + KU_ASSERT(signal(SIGINT, interruptHandler) != SIG_ERR); } void EmbeddedShell::run() { @@ -230,11 +232,11 @@ void EmbeddedShell::run() { free(line); break; } else if (lineStr.rfind(shellCommand.THREAD) == 0) { - setNumThreads(lineStr.substr(shellCommand.THREAD.length())); + setNumThreads(lineStr.substr(strlen(shellCommand.THREAD))); } else if (lineStr.rfind(shellCommand.LOGGING_LEVEL) == 0) { - setLoggingLevel(lineStr.substr(shellCommand.LOGGING_LEVEL.length())); + setLoggingLevel(lineStr.substr(strlen(shellCommand.LOGGING_LEVEL))); } else if (lineStr.rfind(shellCommand.QUERY_TIMEOUT) == 0) { - setQueryTimeout(lineStr.substr(shellCommand.QUERY_TIMEOUT.length())); + setQueryTimeout(lineStr.substr(strlen(shellCommand.QUERY_TIMEOUT))); } else if (!lineStr.empty()) { ss.clear(); ss.str(lineStr); @@ -280,16 +282,16 @@ void EmbeddedShell::setNumThreads(const std::string& numThreadsString) { } void EmbeddedShell::printHelp() { - printf("%s%s %sget command list\n", TAB, shellCommand.HELP.c_str(), TAB); - printf("%s%s %sclear shell\n", TAB, shellCommand.CLEAR.c_str(), TAB); - printf("%s%s %sexit from shell\n", TAB, shellCommand.QUIT.c_str(), TAB); + printf("%s%s %sget command list\n", TAB, shellCommand.HELP, TAB); + printf("%s%s %sclear shell\n", TAB, shellCommand.CLEAR, TAB); + printf("%s%s %sexit from shell\n", TAB, shellCommand.QUIT, TAB); printf("%s%s [num_threads] %sset number of threads for query execution\n", TAB, - shellCommand.THREAD.c_str(), TAB); + shellCommand.THREAD, TAB); printf("%s%s [logging_level] %sset logging level of database, available options: debug, info, " "err\n", - TAB, shellCommand.LOGGING_LEVEL.c_str(), TAB); - printf("%s%s [query_timeout] %sset query timeout in ms\n", TAB, - shellCommand.QUERY_TIMEOUT.c_str(), TAB); + TAB, shellCommand.LOGGING_LEVEL, TAB); + printf( + "%s%s [query_timeout] %sset query timeout in ms\n", TAB, shellCommand.QUERY_TIMEOUT, TAB); } void EmbeddedShell::printExecutionResult(QueryResult& queryResult) const {