diff --git a/.clang-format b/.clang-format index 18cc04e5e6..4b2eab71f5 100644 --- a/.clang-format +++ b/.clang-format @@ -1,6 +1,5 @@ --- Language: Cpp -# BasedOnStyle: Google AccessModifierOffset: -1 AlignAfterOpenBracket: Align AlignConsecutiveAssignments: false @@ -36,8 +35,6 @@ BreakBeforeBinaryOperators: None BreakBeforeBraces: Attach BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false -# BreakAfterJavaFieldAnnotations: false -# BreakStringLiterals: true ColumnLimit: 120 CommentPragmas: '^ IWYU pragma:' ConstructorInitializerAllOnOneLineOrOnePerLine: true @@ -56,12 +53,9 @@ IncludeCategories: Priority: 2 - Regex: '.*' Priority: 3 -# IncludeIsMainRegex: '([-_](test|unittest))?$' IndentCaseLabels: true IndentWidth: 2 IndentWrappedFunctionNames: false -# JavaScriptQuotes: Leave -# JavaScriptWrapImports: true # InsertBraces: true TODO(anyone): enable when clang15 is widely used. KeepEmptyLinesAtTheStartOfBlocks: false MacroBlockBegin: '' @@ -79,6 +73,7 @@ PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 200 PointerAlignment: Left ReflowComments: false +SeparateDefinitionBlocks: Always SortIncludes: true SpaceAfterCStyleCast: false SpaceBeforeAssignmentOperators: true diff --git a/.clang-tidy b/.clang-tidy index 887513705b..7f8611094e 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,50 +1,108 @@ -HeaderFilterRegex: '.*cpp$' # https://gitlab.kitware.com/cmake/cmake/issues/20058 - -Checks: '*,-*-default-arguments*,-*braces-around-statements,-google-build-using-namespace,-clang-analyzer-security.insecureAPI.rand,-readability-implicit-bool-conversion,-cppcoreguidelines-pro-type-reinterpret-cast,-readability-misleading-indentation,-modernize-pass-by-value,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-type-static-cast-downcast,-misc-unused-parameters,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-hicpp-no-array-decay,-readability-named-parameter,-cert-dcl58-cpp,-clang-analyzer-optin.cplusplus.VirtualCall,-modernize-avoid-bind,-hicpp-no-assembler,-cppcoreguidelines-pro-type-vararg,-hicpp-vararg,-cert-env33-c,-misc-macro-parentheses,-readability-else-after-return,-fuchsia-overloaded-operator,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-google-runtime-references,-cert-err58-cpp,-llvm-include-order,-clang-analyzer-cplusplus.NewDelete*,-cert-msc32-c,-cert-msc51-cpp,-fuchsia-statically-constructed-objects,-bugprone-exception-escape,-*-uppercase-literal-suffix,-cert-dcl16-c,-*-magic-numbers,-*-non-private-member-variables-in-classes,-modernize-use-trailing-return-type,-clang-diagnostic-unknown-warning-option,-modernize-use-nodiscard,-cppcoreguidelines-init-variables' +Checks: ' + *, + -*-default-arguments*, + -*braces-around-statements, + -google-build-using-namespace, + -clang-analyzer-security.insecureAPI.rand, + -readability-implicit-bool-conversion, + -cppcoreguidelines-pro-type-reinterpret-cast, + -readability-misleading-indentation, + -modernize-pass-by-value, + -cppcoreguidelines-pro-bounds-constant-array-index, + -cppcoreguidelines-pro-type-static-cast-downcast, + -misc-unused-parameters, + -cppcoreguidelines-pro-bounds-array-to-pointer-decay, + -hicpp-no-array-decay, + -readability-named-parameter, + -cert-dcl58-cpp, + -clang-analyzer-optin.cplusplus.VirtualCall, + -modernize-avoid-bind, + -hicpp-no-assembler, + -cppcoreguidelines-pro-type-vararg, + -hicpp-vararg, + -cert-env33-c, + -misc-macro-parentheses, + -readability-else-after-return, + -fuchsia-overloaded-operator, + -cppcoreguidelines-pro-bounds-pointer-arithmetic, + -google-runtime-references, + -cert-err58-cpp, + -llvm-include-order, + -clang-analyzer-cplusplus.NewDelete*, + -cert-msc32-c, + -cert-msc51-cpp, + -fuchsia-statically-constructed-objects, + -bugprone-exception-escape, + -*-uppercase-literal-suffix, + -cert-dcl16-c, + -*-magic-numbers, + -*-non-private-member-variables-in-classes, + -modernize-use-trailing-return-type, + -clang-diagnostic-unknown-warning-option, + -modernize-use-nodiscard, + -cppcoreguidelines-init-variables, + -llvmlibc-*, + -altera-*, + -abseil-*, + -readability-use-anyofallof, + -readability-identifier-naming, + -misc-no-recursion, + -bugprone-easily-swappable-parameters, + -readability-function-cognitive-complexity + ' WarningsAsErrors: '*' # Explanation of disabled checks: -# *-default-arguments* We do use default arguments (and like them) -# *braces-around-statements We do allow then blocks without braces if they are in the same line -# google-build-using-namespace While we discourage its use, in some cases, using namespace makes sense -# clang-analyzer-security.insecureAPI.rand We don't care about cryptographically unsafe rand() calls -# readability-implicit-bool-conversion Doesn't like if(map.count(foo)) -# cppcoreguidelines-pro-type-reinterpret-cast We use reinterpret_cast -# readability-misleading-indentation Doesn't like if constexpr -# modernize-pass-by-value We don't trust people to properly use std::move -# cppcoreguidelines-pro-bounds-constant-array-index Weird stuff. "do not use array subscript when the index is not an integer constant expression"?! -# cppcoreguidelines-pro-type-static-cast-downcast We do allow static downcasts for performance reasons -# misc-unused-parameters We don't care about unused parameters -# cppcoreguidelines-pro-bounds-array-to-pointer-decay Weird stuff - it doesn't like `description_mode == DescriptionMode::MultiLine` -# hicpp-no-array-decay (same) -# readability-named-parameter Unused parameters don't need names -# cert-dcl58-cpp Adding a hash function to std is perfectly legal: https://en.cppreference.com/w/cpp/language/extending_std -# clang-analyzer-optin.cplusplus.VirtualCall false positive in boost::lexical_cast -# modernize-avoid-bind meh, bind isn't thaaaat bad -# hicpp-no-assembler Sometimes we need assembler... -# cppcoreguidelines-pro-type-vararg We use old C functions for ncurses -# hicpp-vararg (same) -# cert-env33-c Yes, we do call system() -# misc-macro-parentheses Causes weird problems with BOOST_PP_TUPLE_ELEM -# readability-else-after-return "do not use 'else' after 'return'" - no idea who originally came up with that... -# fuchsia-overloaded-operator We are not supposed to overload operator()?! -# cppcoreguidelines-pro-bounds-pointer-arithmetic Doesn't like DebugAssert -# google-runtime-references Doesn't like mutable references -# cert-err58-cpp We reeeeeally don't care about uncaught exceptions -# llvm-include-order Handled by cpplint.py which is way faster -# clang-analyzer-cplusplus.NewDelete* False positives with shared_ptr::operator= -# cert-msc32-c, -cert-msc51-cpp Ok, so our generated tables are not cryptographically safe -# fuchsia-statically-constructed-objects We have too many static objects -# bugprone-exception-escape We throw exceptions in many places (even destructors) and are completely fine with std::terminate -# *-uppercase-literal-suffix Don't really care if it's 1.0f or 1.0F -# cert-dcl16-c (same) -# *-magic-numbers Too many false positives -# *-non-private-member-variables-in-classes We like making things public -# modernize-use-trailing-return-type https://clang.llvm.org/extra/clang-tidy/checks/modernize-use-trailing-return-type.html - no that is way too weird -# clang-diagnostic-unknown-warning-option Don't complain about gcc warning options -# modernize-use-nodiscard Don't want to tag everything [[nodiscard]] -# cppcoreguidelines-init-variables If a variable is only declared and initialized in two different branches, we do not want to initialize it first +# - *-default-arguments* We do use default arguments (and like them) +# - google-build-using-namespace While we discourage its use, in some cases, using namespace makes sense +# - clang-analyzer-security.insecureAPI.rand We don't care about cryptographically unsafe rand() calls +# - readability-implicit-bool-conversion Doesn't like if(map.count(foo)) +# - cppcoreguidelines-pro-type-reinterpret-cast We use reinterpret_cast +# - readability-misleading-indentation Doesn't like if constexpr +# - modernize-pass-by-value We don't trust people to properly use std::move +# - cppcoreguidelines-pro-bounds-constant-array-index Weird stuff. "do not use array subscript when the index is not an integer constant expression"?! +# - cppcoreguidelines-pro-type-static-cast-downcast We do allow static downcasts for performance reasons +# - misc-unused-parameters We don't care about unused parameters +# - cppcoreguidelines-pro-bounds-array-to-pointer-decay Weird stuff - it doesn't like `description_mode == DescriptionMode::MultiLine` +# - hicpp-no-array-decay (same) +# - readability-named-parameter Unused parameters don't need names +# - cert-dcl58-cpp Adding a hash function to std is perfectly legal: https://en.cppreference.com/w/cpp/language/extending_std +# - clang-analyzer-optin.cplusplus.VirtualCall false positive in boost::lexical_cast +# - modernize-avoid-bind meh, bind isn't thaaaat bad +# - hicpp-no-assembler Sometimes we need assembler... +# - cppcoreguidelines-pro-type-vararg We use old C functions for ncurses +# - hicpp-vararg (same) +# - cert-env33-c Yes, we do call system() +# - misc-macro-parentheses Causes weird problems with BOOST_PP_TUPLE_ELEM +# - readability-else-after-return "do not use 'else' after 'return'" - no idea who originally came up with that... +# - fuchsia-overloaded-operator We are not supposed to overload operator()?! +# - cppcoreguidelines-pro-bounds-pointer-arithmetic Doesn't like DebugAssert +# - google-runtime-references Doesn't like mutable references +# - cert-err58-cpp We reeeeeally don't care about uncaught exceptions +# - llvm-include-order Handled by cpplint.py which is way faster +# - clang-analyzer-cplusplus.NewDelete* False positives with shared_ptr::operator= +# - cert-msc32-c, -cert-msc51-cpp Ok, so our generated tables are not cryptographically safe +# - fuchsia-statically-constructed-objects We have too many static objects +# - bugprone-exception-escape We throw exceptions in many places (even destructors) and are completely fine with std::terminate +# - *-uppercase-literal-suffix Don't really care if it's 1.0f or 1.0F +# - cert-dcl16-c (same) +# - *-magic-numbers Too many false positives +# - *-non-private-member-variables-in-classes We like making things public +# - modernize-use-trailing-return-type https://clang.llvm.org/extra/clang-tidy/checks/modernize-use-trailing-return-type.html - no that is way too weird +# - clang-diagnostic-unknown-warning-option Don't complain about gcc warning options +# - modernize-use-nodiscard Don't want to tag everything [[nodiscard]] +# - cppcoreguidelines-init-variables If a variable is only declared and initialized in two different branches, we do not want to initialize it first +# - -llvmlibc-* LLVM-internal development guidelines. +# - altera-* Checks related to OpenCL programming for FPGAs. +# - abseil-* Checks related to Google's abseil library (not used in Hyrise). +# - readability-use-anyofallof We prefer `for (auto item : items)` over `std::ranges::all_of()` with a lambda. +# - readability-identifier-naming Error spamming on non-Hyrise code. LLVM Bug. TODO(anyone): test renabling with newer LLVM versions which fixes +# https://github.com/llvm/llvm-project/issues/46097 +# - misc-no-recursion Ignore general recommendation to avoid recursion, which we commonly use when working with query plans. +# - bugprone-easily-swappable-parameters Ignore issues with swapple parameters as we found them to be of no help. +# - readability-function-cognitive-complexity When appropriate, long functions with a sequential data flow (which is sometimes easier to read) are fine. In many +# places, the rule catches functions where the code could be improved, but will likely not be due to a lack of time. CheckOptions: @@ -143,3 +201,10 @@ CheckOptions: - key: readability-identifier-naming.VariableCase value: lower_case + + # Iff(!) the context is clear, 'it' for iterator, 'op' for operator, or 'fd' for functional dependency are fine. + - key: readability-identifier-length.IgnoredParameterNames + value: "^(it|fd|op)$" + - key: readability-identifier-length.IgnoredVariableNames + value: "^(it|fd|op)$" + diff --git a/.gitmodules b/.gitmodules index b78b588227..2f869414a2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -21,7 +21,7 @@ url = https://github.com/skarupke/flat_hash_map.git [submodule "third_party/googletest"] path = third_party/googletest - url = https://github.com/abseil/googletest.git + url = https://github.com/google/googletest.git [submodule "third_party/jcch-dbgen"] path = third_party/jcch-dbgen url = https://github.com/mrks/dbgen.JCC-H.git diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index 5b92127172..faf6f9a91f 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -4,9 +4,9 @@ | ------------------------- | ---------------- | -------- | ------------------------------------- | | autoconf | >= 2.69 | All | No | | boost | >= 1.70.0 | All | No | -| clang | >= 9.0 | All | Yes, if gcc installed | -| clang-format | >= 9.0 | All | Yes (formatting) | -| clang-tidy | >= 9.0 | All | Yes (linting) | +| clang | >= 11.0 | All | Yes, if gcc installed | +| clang-format | >= 11.0 | All | Yes (formatting) | +| clang-tidy | >= 11.0 | All | Yes (linting) | | coreutils | any | Mac | Yes (scripts) | | cmake | >= 3.9 | All | No | | dos2unix | any | All | Yes (linting) | @@ -20,11 +20,11 @@ | parallel | any | All | Yes | | pexpect | >= 4 | All | Yes (tests in CI) | | postgresql-server-dev-all | >= 154 | Linux | No | -| python | 3 | All | Yes (linting and tests in CI) | +| python | >= 3.6 | All | Yes (linting and tests in CI) | | readline | >= 7 | All | No | | sqlite3 | >= 3 | All | No | | tbb/libtbb-dev | any | All | No | | valgrind | any | All | Yes, memory checking in CI | -For dependencies that are integrated in our build process via git submodules, please check .gitmodules \ No newline at end of file +For dependencies that are integrated in our build process via git submodules, please check .gitmodules diff --git a/Dockerfile b/Dockerfile index 1e45ace8cb..726c788591 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,28 +2,28 @@ # You need to build and push it manually, see the wiki for details: # https://github.com/hyrise/hyrise/wiki/Docker-Image -FROM ubuntu:20.04 +FROM ubuntu:22.04 ENV DEBIAN_FRONTEND noninteractive RUN apt-get update \ && apt-get install -y \ autoconf \ bash-completion \ bc \ - clang-9 \ - clang-10 \ - clang-format-9 \ - clang-format-10 \ - clang-tidy-9 \ - clang-tidy-10 \ + clang-11 \ + clang-14 \ + clang-format-14 \ + clang-tidy-14 \ cmake \ curl \ dos2unix \ g++-9 \ + g++-11 \ gcc-9 \ + gcc-11 \ gcovr \ git \ graphviz \ - libboost1.71-all-dev \ + libboost-all-dev \ libhwloc-dev \ libncurses5-dev \ libnuma-dev \ @@ -44,6 +44,7 @@ RUN apt-get update \ valgrind \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \ - && ln -sf /usr/bin/llvm-symbolizer-3.8 /usr/bin/llvm-symbolizer + && ln -sf /usr/bin/llvm-symbolizer-14 /usr/bin/llvm-symbolizer \ + && pip3 install scipy pandas matplotlib # preload large Python packages (installs numpy and others) ENV HYRISE_HEADLESS_SETUP=true diff --git a/Jenkinsfile b/Jenkinsfile index 3906af00ac..371c769e98 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,7 +1,7 @@ import org.jenkinsci.plugins.pipeline.modeldefinition.Utils full_ci = env.BRANCH_NAME == 'master' || pullRequest.labels.contains('FullCI') -tests_excluded_in_sanitizer_builds = '--gtest_filter=-SQLiteTestRunnerEncodings/*:TPCDSTableGeneratorTest.GenerateAndStoreRowCounts:TPCHTableGeneratorTest.RowCountsMediumScaleFactor' +tests_excluded_in_sanitizer_builds = '--gtest_filter=-SQLiteTestRunnerEncodings/*:TPCDSTableGeneratorTest.GenerateAndStoreRowCounts:TPCHTableGeneratorTest.RowCountsMediumScaleFactor:*.TestTransactionConflicts' try { node { @@ -55,7 +55,7 @@ try { // The empty '' results in using the default registry: https://index.docker.io/v1/ docker.withRegistry('', 'docker') { - def hyriseCI = docker.image('hyrise/hyrise-ci:20.04'); + def hyriseCI = docker.image('hyrise/hyrise-ci:22.04'); hyriseCI.pull() // LSAN (executed as part of ASAN) requires elevated privileges. Therefore, we had to add --cap-add SYS_PTRACE. @@ -81,13 +81,16 @@ try { // We don't use unity builds with GCC 9 as it triggers https://github.com/google/googletest/issues/3552 unity = '-DCMAKE_UNITY_BUILD=ON' - - // Note that clang 9 is still the default version installed by install_dependencies.sh. This is so that we do - // not unnecessarily require Ubuntu 20.04. If you want to upgrade to -10, please update install_dependencies.sh, - // DEPENDENCIES.md, clang_tidy_wrapper.sh, and the documentation (README, Wiki). - clang = '-DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_COMPILER=clang++-10' - clang9 = '-DCMAKE_C_COMPILER=clang-9 -DCMAKE_CXX_COMPILER=clang++-9' + + // With Hyrise, we aim to support the most recent compiler versions and do not invest a lot of work to + // support older versions. We test the oldest LLVM version shipped with Ubuntu 22.04 (i.e., LLVM 11) and + // GCC 9 (oldest version supported by Hyrise). We execute at least debug runs for them. + // If you want to upgrade compiler versions, please update install_dependencies.sh, DEPENDENCIES.md, and + // the documentation (README, Wiki). + clang = '-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++' + clang11 = '-DCMAKE_C_COMPILER=clang-11 -DCMAKE_CXX_COMPILER=clang++-11' gcc = '-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++' + gcc9 = '-DCMAKE_C_COMPILER=gcc-9 -DCMAKE_CXX_COMPILER=g++-9' debug = '-DCMAKE_BUILD_TYPE=Debug' release = '-DCMAKE_BUILD_TYPE=Release' @@ -99,16 +102,17 @@ try { sh "mkdir clang-debug && cd clang-debug && ${cmake} ${debug} ${clang} ${unity} .. && make -j libjemalloc-build" // Configure the rest in parallel - sh "mkdir clang-debug-tidy && cd clang-debug-tidy && ${cmake} ${debug} ${clang} ${unity} -DENABLE_CLANG_TIDY=ON .. &\ + sh "mkdir clang-debug-tidy && cd clang-debug-tidy && ${cmake} ${debug} ${clang} -DENABLE_CLANG_TIDY=ON .. &\ mkdir clang-debug-unity-odr && cd clang-debug-unity-odr && ${cmake} ${debug} ${clang} ${unity} -DCMAKE_UNITY_BUILD_BATCH_SIZE=0 .. &\ mkdir clang-debug-disable-precompile-headers && cd clang-debug-disable-precompile-headers && ${cmake} ${debug} ${clang} -DCMAKE_DISABLE_PRECOMPILE_HEADERS=On .. &\ mkdir clang-debug-addr-ub-sanitizers && cd clang-debug-addr-ub-sanitizers && ${cmake} ${debug} ${clang} -DENABLE_ADDR_UB_SANITIZATION=ON .. &\ - mkdir clang-release-addr-ub-sanitizers && cd clang-release-addr-ub-sanitizers && ${cmake} ${release} ${clang} -DENABLE_ADDR_UB_SANITIZATION=ON .. &\ + mkdir clang-release-addr-ub-sanitizers && cd clang-release-addr-ub-sanitizers && ${cmake} ${release} ${clang} ${unity} -DENABLE_ADDR_UB_SANITIZATION=ON .. &\ mkdir clang-release && cd clang-release && ${cmake} ${release} ${clang} .. &\ mkdir clang-relwithdebinfo-thread-sanitizer && cd clang-relwithdebinfo-thread-sanitizer && ${cmake} ${relwithdebinfo} ${clang} -DENABLE_THREAD_SANITIZATION=ON .. &\ mkdir gcc-debug && cd gcc-debug && ${cmake} ${debug} ${gcc} .. &\ mkdir gcc-release && cd gcc-release && ${cmake} ${release} ${gcc} .. &\ - mkdir clang-9-debug && cd clang-9-debug && ${cmake} ${debug} ${clang9} ${unity} .. &\ + mkdir clang-11-debug && cd clang-11-debug && ${cmake} ${debug} ${clang11} .. &\ + mkdir gcc-9-debug && cd gcc-9-debug && ${cmake} ${debug} ${gcc9} .. &\ wait" } @@ -117,16 +121,21 @@ try { sh "cd clang-debug && make all -j \$(( \$(nproc) / 4))" sh "./clang-debug/hyriseTest clang-debug" } - }, clang9Debug: { - stage("clang-9-debug") { - sh "cd clang-9-debug && make all -j \$(( \$(nproc) / 4))" - sh "./clang-9-debug/hyriseTest clang-9-debug" + }, clang11Debug: { + stage("clang-11-debug") { + sh "cd clang-11-debug && make all -j \$(( \$(nproc) / 4))" + sh "./clang-11-debug/hyriseTest clang-11-debug" } }, gccDebug: { stage("gcc-debug") { sh "cd gcc-debug && make all -j \$(( \$(nproc) / 4))" sh "cd gcc-debug && ./hyriseTest" } + }, gcc9Debug: { + stage("gcc-9-debug") { + sh "cd gcc-9-debug && make all -j \$(( \$(nproc) / 4))" + sh "cd gcc-9-debug && ./hyriseTest" + } }, lint: { stage("Linting") { sh ''' @@ -138,7 +147,7 @@ try { parallel clangRelease: { stage("clang-release") { if (env.BRANCH_NAME == 'master' || full_ci) { - sh "cd clang-release && make all -j \$(( \$(nproc) / 6))" + sh "cd clang-release && make all -j \$(( \$(nproc) / 10))" sh "./clang-release/hyriseTest clang-release" sh "./clang-release/hyriseSystemTest clang-release" sh "./scripts/test/hyriseConsole_test.py clang-release" @@ -188,7 +197,7 @@ try { stage("clang-debug-unity-odr") { if (env.BRANCH_NAME == 'master' || full_ci) { // Check if unity builds work even if everything is batched into a single compilation unit. This helps prevent ODR (one definition rule) issues. - sh "cd clang-debug-unity-odr && make all -j \$(( \$(nproc) / 3))" + sh "cd clang-debug-unity-odr && make all -j \$(( \$(nproc) / 10))" } else { Utils.markStageSkippedForConditional("clangDebugUnityODR") } @@ -197,7 +206,8 @@ try { stage("clang-debug:tidy") { if (env.BRANCH_NAME == 'master' || full_ci) { // We do not run tidy checks on the src/test folder, so there is no point in running the expensive clang-tidy for those files - sh "cd clang-debug-tidy && make hyrise_impl hyriseBenchmarkFileBased hyriseBenchmarkTPCH hyriseBenchmarkTPCDS hyriseBenchmarkJoinOrder hyriseConsole hyriseServer -k -j \$(( \$(nproc) / 6))" + // As clang-tidy is the slowest step, we allow it to use more parallel jobs. + sh "cd clang-debug-tidy && make hyrise_impl hyriseBenchmarkFileBased hyriseBenchmarkTPCH hyriseBenchmarkTPCDS hyriseBenchmarkJoinOrder hyriseConsole hyriseServer -k -j \$(( \$(nproc) / 5))" } else { Utils.markStageSkippedForConditional("clangDebugTidy") } @@ -206,7 +216,7 @@ try { stage("clang-debug:disable-precompile-headers") { if (env.BRANCH_NAME == 'master' || full_ci) { // Check if builds work even when precompile headers is turned off. Executing the binaries is unnecessary as the observed errors are missing includes. - sh "cd clang-debug-disable-precompile-headers && make hyriseTest hyriseBenchmarkFileBased hyriseBenchmarkTPCH hyriseBenchmarkTPCDS hyriseBenchmarkJoinOrder hyriseConsole hyriseServer -k -j \$(( \$(nproc) / 6))" + sh "cd clang-debug-disable-precompile-headers && make hyriseTest hyriseBenchmarkFileBased hyriseBenchmarkTPCH hyriseBenchmarkTPCDS hyriseBenchmarkJoinOrder hyriseConsole hyriseServer -k -j \$(( \$(nproc) / 10))" } else { Utils.markStageSkippedForConditional("clangDebugDisablePrecompileHeaders") } @@ -214,7 +224,7 @@ try { }, clangDebugAddrUBSanitizers: { stage("clang-debug:addr-ub-sanitizers") { if (env.BRANCH_NAME == 'master' || full_ci) { - sh "cd clang-debug-addr-ub-sanitizers && make hyriseTest hyriseSystemTest hyriseBenchmarkTPCH hyriseBenchmarkTPCC -j \$(( \$(nproc) / 6))" + sh "cd clang-debug-addr-ub-sanitizers && make hyriseTest hyriseSystemTest hyriseBenchmarkTPCH hyriseBenchmarkTPCC -j \$(( \$(nproc) / 10))" sh "LSAN_OPTIONS=suppressions=resources/.lsan-ignore.txt ASAN_OPTIONS=suppressions=resources/.asan-ignore.txt ./clang-debug-addr-ub-sanitizers/hyriseTest clang-debug-addr-ub-sanitizers" sh "LSAN_OPTIONS=suppressions=resources/.lsan-ignore.txt ASAN_OPTIONS=suppressions=resources/.asan-ignore.txt ./clang-debug-addr-ub-sanitizers/hyriseSystemTest ${tests_excluded_in_sanitizer_builds} clang-debug-addr-ub-sanitizers" sh "LSAN_OPTIONS=suppressions=resources/.lsan-ignore.txt ASAN_OPTIONS=suppressions=resources/.asan-ignore.txt ./clang-debug-addr-ub-sanitizers/hyriseBenchmarkTPCH -s .01 --verify -r 1" @@ -225,7 +235,7 @@ try { }, gccRelease: { if (env.BRANCH_NAME == 'master' || full_ci) { stage("gcc-release") { - sh "cd gcc-release && make all -j \$(( \$(nproc) / 6))" + sh "cd gcc-release && make all -j \$(( \$(nproc) / 10))" sh "./gcc-release/hyriseTest gcc-release" sh "./gcc-release/hyriseSystemTest gcc-release" sh "./scripts/test/hyriseConsole_test.py gcc-release" @@ -241,7 +251,7 @@ try { }, clangReleaseAddrUBSanitizers: { stage("clang-release:addr-ub-sanitizers") { if (env.BRANCH_NAME == 'master' || full_ci) { - sh "cd clang-release-addr-ub-sanitizers && make hyriseTest hyriseSystemTest hyriseBenchmarkTPCH hyriseBenchmarkTPCC -j \$(( \$(nproc) / 6))" + sh "cd clang-release-addr-ub-sanitizers && make hyriseTest hyriseSystemTest hyriseBenchmarkTPCH hyriseBenchmarkTPCC -j \$(( \$(nproc) / 10))" sh "LSAN_OPTIONS=suppressions=resources/.lsan-ignore.txt ASAN_OPTIONS=suppressions=resources/.asan-ignore.txt ./clang-release-addr-ub-sanitizers/hyriseTest clang-release-addr-ub-sanitizers" sh "LSAN_OPTIONS=suppressions=resources/.lsan-ignore.txt ASAN_OPTIONS=suppressions=resources/.asan-ignore.txt ./clang-release-addr-ub-sanitizers/hyriseSystemTest ${tests_excluded_in_sanitizer_builds} clang-release-addr-ub-sanitizers" sh "LSAN_OPTIONS=suppressions=resources/.lsan-ignore.txt ASAN_OPTIONS=suppressions=resources/.asan-ignore.txt ./clang-release-addr-ub-sanitizers/hyriseBenchmarkTPCH -s .01 --verify -r 100 --scheduler --clients 10" @@ -253,7 +263,7 @@ try { }, clangRelWithDebInfoThreadSanitizer: { stage("clang-relwithdebinfo:thread-sanitizer") { if (env.BRANCH_NAME == 'master' || full_ci) { - sh "cd clang-relwithdebinfo-thread-sanitizer && make hyriseTest hyriseSystemTest hyriseBenchmarkTPCH -j \$(( \$(nproc) / 6))" + sh "cd clang-relwithdebinfo-thread-sanitizer && make hyriseTest hyriseSystemTest hyriseBenchmarkTPCH -j \$(( \$(nproc) / 10))" sh "TSAN_OPTIONS=\"history_size=7 suppressions=resources/.tsan-ignore.txt\" ./clang-relwithdebinfo-thread-sanitizer/hyriseTest clang-relwithdebinfo-thread-sanitizer" sh "TSAN_OPTIONS=\"history_size=7 suppressions=resources/.tsan-ignore.txt\" ./clang-relwithdebinfo-thread-sanitizer/hyriseSystemTest ${tests_excluded_in_sanitizer_builds} clang-relwithdebinfo-thread-sanitizer" sh "TSAN_OPTIONS=\"history_size=7 suppressions=resources/.tsan-ignore.txt\" ./clang-relwithdebinfo-thread-sanitizer/hyriseBenchmarkTPCH -s .01 --verify -r 100 --scheduler --clients 10" @@ -288,13 +298,15 @@ try { parallel memcheckReleaseTest: { stage("memcheckReleaseTest") { - // Runs separately as it depends on clang-release to be built + // Runs after the other sanitizers as it depends on gcc-release to be built. With #2402, valgrind now + // uses the GCC build instead of the clang build as there are issues with valgrind and the debug symbols + // of clang 14 (https://bugs.kde.org/show_bug.cgi?id=452758). if (env.BRANCH_NAME == 'master' || full_ci) { sh "mkdir ./clang-release-memcheck-test" // If this shows a leak, try --leak-check=full, which is slower but more precise - sh "valgrind --tool=memcheck --error-exitcode=1 --gen-suppressions=all --num-callers=25 --suppressions=resources/.valgrind-ignore.txt ./clang-release/hyriseTest clang-release-memcheck-test --gtest_filter=-NUMAMemoryResourceTest.BasicAllocate" - sh "valgrind --tool=memcheck --error-exitcode=1 --gen-suppressions=all --num-callers=25 --suppressions=resources/.valgrind-ignore.txt ./clang-release/hyriseBenchmarkTPCH -s .01 -r 1 --scheduler --cores 10" - sh "valgrind --tool=memcheck --error-exitcode=1 --gen-suppressions=all --num-callers=25 --suppressions=resources/.valgrind-ignore.txt ./clang-release/hyriseBenchmarkTPCC -s 1 --scheduler --cores 10" + sh "valgrind --tool=memcheck --error-exitcode=1 --gen-suppressions=all --num-callers=25 --suppressions=resources/.valgrind-ignore.txt ./gcc-release/hyriseTest clang-release-memcheck-test --gtest_filter=-NUMAMemoryResourceTest.BasicAllocate" + sh "valgrind --tool=memcheck --error-exitcode=1 --gen-suppressions=all --num-callers=25 --suppressions=resources/.valgrind-ignore.txt ./gcc-release/hyriseBenchmarkTPCH -s .01 -r 1 --scheduler --cores 10" + sh "valgrind --tool=memcheck --error-exitcode=1 --gen-suppressions=all --num-callers=25 --suppressions=resources/.valgrind-ignore.txt ./gcc-release/hyriseBenchmarkTPCC -s 1 --scheduler --cores 10" } else { Utils.markStageSkippedForConditional("memcheckReleaseTest") } diff --git a/README.md b/README.md index ccb3e2aece..5adf66bf42 100644 --- a/README.md +++ b/README.md @@ -69,8 +69,8 @@ You can find definitions of most of the terms and abbreviations used in the code The [Step by Step Guide](https://github.com/hyrise/hyrise/wiki/Step-by-Step-Guide) is a good starting point to get to know Hyrise. ## Native Setup -You can install the dependencies on your own or use the install_dependencies.sh script (**recommended**) which installs all of the therein listed dependencies and submodules. -The install script was tested under macOS Big Sur (10.16) and Ubuntu 20.10 (apt-get). +You can install the dependencies on your own or use the `install_dependencies.sh` script (**recommended**) which installs all of the therein listed dependencies and submodules. +The install script was tested under macOS Monterey (12.4) and Ubuntu 22.04. See [dependencies](DEPENDENCIES.md) for a detailed list of dependencies to use with `brew install` or `apt-get install`, depending on your platform. As compilers, we generally use the most recent version of clang and gcc (Linux only). Please make sure that the system compiler points to the most recent version or use cmake (see below) accordingly. Older versions may work, but are neither tested nor supported. diff --git a/install_dependencies.sh b/install_dependencies.sh index 9df6427572..c5ee6f1bad 100755 --- a/install_dependencies.sh +++ b/install_dependencies.sh @@ -1,14 +1,6 @@ #!/bin/bash if [[ -z $HYRISE_HEADLESS_SETUP ]]; then - BOOST_INSTALLED=$(dpkg-query -W --showformat='${Status}\n' libboost1.67-dev 2>/dev/null | grep "install ok installed") - if [ "" != "$BOOST_INSTALLED" ]; then - read -p 'libboost1.67-dev is installed but 1.70 is required. Ok to remove 1.67-dev? [y|n] ' -n 1 -r < /dev/tty - echo - if echo $REPLY | grep -E '^[Yy]$' > /dev/null; then - sudo apt-get remove libboost1.67-dev - fi - fi read -p 'This script installs the dependencies of Hyrise. It might upgrade already installed packages. Continue? [y|n] ' -n 1 -r < /dev/tty else REPLY="y" @@ -57,18 +49,8 @@ if echo $REPLY | grep -E '^[Yy]$' > /dev/null; then if [ -f /etc/lsb-release ] && cat /etc/lsb-release | grep DISTRIB_ID | grep Ubuntu >/dev/null; then echo "Installing dependencies (this may take a while)..." if sudo apt-get update >/dev/null; then - sudo apt-get install --no-install-recommends -y software-properties-common lsb-release - if [[ "$(lsb_release -sr)" < "20.04" ]]; then - # Ubuntu versions before 20.04 do not have a compatible boost version. Manually retrieve it - sudo add-apt-repository -y ppa:mhier/libboost-latest - sudo apt-get update - sudo apt-get install --no-install-recommends -y libboost1.70-dev - else - sudo apt-get install --no-install-recommends -y libboost1.71-all-dev - fi - # Packages added here should also be added to the Dockerfile - sudo apt-get install --no-install-recommends -y autoconf bash-completion bc clang-9 clang-format-9 clang-tidy-9 cmake curl dos2unix g++-9 gcc-9 gcovr git graphviz libhwloc-dev libncurses5-dev libnuma-dev libnuma1 libpq-dev libreadline-dev libsqlite3-dev libtbb-dev lld man parallel postgresql-server-dev-all python3 python3-pip valgrind & + sudo apt-get install --no-install-recommends -y autoconf bash-completion bc clang-11 clang-14 clang-format-14 clang-tidy-14 cmake curl dos2unix g++-9 gcc-9 g++-11 gcc-11 gcovr git graphviz libboost-all-dev libhwloc-dev libncurses5-dev libnuma-dev libnuma1 libpq-dev libreadline-dev libsqlite3-dev libtbb-dev lld man parallel postgresql-server-dev-all python3 python3-pip valgrind & if ! git submodule update --jobs 5 --init --recursive; then echo "Error during git fetching submodules." @@ -87,8 +69,9 @@ if echo $REPLY | grep -E '^[Yy]$' > /dev/null; then exit 1 fi - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 90 --slave /usr/bin/g++ g++ /usr/bin/g++-9 - sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-9 90 --slave /usr/bin/clang++ clang++ /usr/bin/clang++-9 --slave /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-9 --slave /usr/bin/llvm-profdata llvm-profdata /usr/bin/llvm-profdata-9 --slave /usr/bin/llvm-cov llvm-cov /usr/bin/llvm-cov-9 --slave /usr/bin/clang-format clang-format /usr/bin/clang-format-9 + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 90 --slave /usr/bin/g++ g++ /usr/bin/g++-11 + # we use llvm-profdata-11 and llvm-cov-11 due to an unresolved issue with coverage under clang14 (https://github.com/llvm/llvm-project/issues/54907) + sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-14 90 --slave /usr/bin/clang++ clang++ /usr/bin/clang++-14 --slave /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-14 --slave /usr/bin/llvm-profdata llvm-profdata /usr/bin/llvm-profdata-11 --slave /usr/bin/llvm-cov llvm-cov /usr/bin/llvm-cov-11 --slave /usr/bin/clang-format clang-format /usr/bin/clang-format-14 else echo "Error during installation." exit 1 diff --git a/resources/.valgrind-ignore.txt b/resources/.valgrind-ignore.txt index 989a23f5af..99b29e8ff7 100644 --- a/resources/.valgrind-ignore.txt +++ b/resources/.valgrind-ignore.txt @@ -61,9 +61,18 @@ fun:_ZN7hyrise14encode_segmentENS_12EncodingTypeENS_6detail8DataTypeERKSt10shared_ptrIKNS_16BaseValueSegmentEESt8optionalINS_21VectorCompressionTypeEE } +# Within LZ4 segments, an std::optional storing an index is conditionally accessed when set. The check is not directly +# on the std::optional, but via an indirection (see variable `use_caching` which is only true, when the std::optional +# is set). Valgrind appears to misinterpret this conditional access. +{ + + Memcheck:Cond + fun:_ZNK6hyrise10LZ4SegmentINSt7__cxx1112basic_stringIcSt11char_traitsIcEN5boost9container3pmr21polymorphic_allocatorIcEEEEE10decompressERKNS_11ChunkOffsetESt8optionalImERSt6vectorIcSaIcEE +} + # Similar to the suppression introduced via https://github.com/hyrise/hyrise/pull/1851#issuecomment-618937388, we need -# to suppress a conditional jump check. We removed the previous suppression as it has not been triggered by -# GoogleTest anymore. +# to suppress a conditional jump check. We removed the previous suppression as it has not been triggered by GoogleTest +# anymore. { Memcheck:Cond diff --git a/scripts/benchmark_multithreaded.py b/scripts/benchmark_multithreaded.py index a3eab76e59..86ab3141ff 100755 --- a/scripts/benchmark_multithreaded.py +++ b/scripts/benchmark_multithreaded.py @@ -137,13 +137,13 @@ def get_formatted_queries(args): def is_square(n): - return n**0.5 == int(n**0.5) + return n ** 0.5 == int(n ** 0.5) def get_subplot_row_and_column_count(num_plots): while not is_square(num_plots): num_plots += 1 - return num_plots**0.5 + return num_plots ** 0.5 def run_benchmarks(args, hyrise_args, core_counts, result_dir): diff --git a/scripts/clang_tidy_wrapper.sh b/scripts/clang_tidy_wrapper.sh index c295e4ce51..231a3b5b19 100755 --- a/scripts/clang_tidy_wrapper.sh +++ b/scripts/clang_tidy_wrapper.sh @@ -11,12 +11,13 @@ file_relative_to_source=${file//$cmake_source_dir/} # Remove the sou file_relative_to_source=${file_relative_to_source/..\/src/src} # Remove `../src`, which gets added by Ninja if grep "$file_relative_to_source" $cmake_source_dir/.clang-tidy-ignore > /dev/null; then - echo "clang-tidy: Ignoring $file_relative_to_source" - exit 0 + echo "clang-tidy: Ignoring $file_relative_to_source" + exit 0 else - if [ -x /usr/local/bin/brew ]; then - exec $(brew --prefix llvm)/bin/clang-tidy $file $@ - else - exec clang-tidy-10 $file $@ - fi + which brew > /dev/null + if [[ $? != 0 ]] ; then + exec clang-tidy $file $@ + else + exec $(brew --prefix llvm)/bin/clang-tidy $file $@ + fi fi diff --git a/scripts/compare_benchmarks.py b/scripts/compare_benchmarks.py index 19527415a5..734ababab9 100755 --- a/scripts/compare_benchmarks.py +++ b/scripts/compare_benchmarks.py @@ -176,7 +176,8 @@ def double_vertical_separators(lines, vertical_separators_to_duplicate): new_successful_durations = np.array([run["duration"] for run in new["successful_runs"]], dtype=np.float64) old_unsuccessful_durations = np.array([run["duration"] for run in old["unsuccessful_runs"]], dtype=np.float64) new_unsuccessful_durations = np.array([run["duration"] for run in new["unsuccessful_runs"]], dtype=np.float64) - old_avg_successful_duration = np.mean(old_successful_durations) # defaults to np.float64 for int input + # np.mean() defaults to np.float64 for int input + old_avg_successful_duration = np.mean(old_successful_durations) new_avg_successful_duration = np.mean(new_successful_durations) total_runtime_old += old_avg_successful_duration if not math.isnan(old_avg_successful_duration) else 0.0 @@ -217,8 +218,8 @@ def double_vertical_separators(lines, vertical_separators_to_duplicate): table_data.append( [ name, - f"{(old_avg_successful_duration / 1e6):>7.1f}" if old_avg_successful_duration else "nan", - f"{(new_avg_successful_duration / 1e6):>7.1f}" if new_avg_successful_duration else "nan", + f"{(old_avg_successful_duration / 1e6):>7.2f}" if old_avg_successful_duration else "nan", + f"{(new_avg_successful_duration / 1e6):>7.2f}" if new_avg_successful_duration else "nan", diff_duration_formatted + note if not math.isnan(diff_duration) else "", f'{old["items_per_second"]:>8.2f}', f'{new["items_per_second"]:>8.2f}', @@ -239,27 +240,32 @@ def double_vertical_separators(lines, vertical_separators_to_duplicate): float(new_data["summary"]["total_duration"]) / 1e9 ) - old_avg_unsuccessful_duration = np.mean(old_unsuccessful_durations) - new_avg_unsuccessful_duration = np.mean(new_unsuccessful_durations) + old_avg_unsuccessful_duration_str = ( + f"{(np.mean(old_unsuccessful_durations) / 1e6):>7.2f}" if len(old_unsuccessful_durations) > 0 else "nan" + ) + new_avg_unsuccessful_duration_str = ( + f"{(np.mean(new_unsuccessful_durations) / 1e6):>7.2f}" if len(new_unsuccessful_durations) > 0 else "nan" + ) + if len(old_unsuccessful_durations) > 0 and len(new_unsuccessful_durations) > 0: - diff_throughput_unsuccessful = float(new_unsuccessful_per_second / old_unsuccessful_per_second) - diff_duration_unsuccessful = new_avg_unsuccessful_duration / old_avg_unsuccessful_duration + diff_throughput_unsuccessful_str = format_diff( + new_unsuccessful_per_second / old_unsuccessful_per_second + ) + diff_duration_unsuccessful_str = format_diff( + np.mean(new_unsuccessful_durations) / np.mean(old_unsuccessful_durations) + ) else: - diff_throughput_unsuccessful = float("nan") - diff_duration_unsuccessful = float("nan") + diff_throughput_unsuccessful_str = " " + diff_duration_unsuccessful_str = " " unsuccessful_info = [ " unsucc.:", - f"{(old_avg_unsuccessful_duration / 1e6):>7.1f}" - if not math.isnan(old_avg_unsuccessful_duration) - else "nan", - f"{(new_avg_unsuccessful_duration / 1e6):>7.1f}" - if not math.isnan(new_avg_unsuccessful_duration) - else "nan", - format_diff(diff_duration_unsuccessful) + " " if not math.isnan(diff_duration_unsuccessful) else " ", + old_avg_unsuccessful_duration_str, + new_avg_unsuccessful_duration_str, + diff_duration_unsuccessful_str + " ", # space added to align diff with "note" char (see above) f"{old_unsuccessful_per_second:>.2f}", f"{new_unsuccessful_per_second:>.2f}", - format_diff(diff_throughput_unsuccessful) + " " if not math.isnan(diff_throughput_unsuccessful) else " ", + diff_throughput_unsuccessful_str + " " ] unsuccessful_info_colored = [colored(text, attrs=["dark"]) for text in unsuccessful_info] @@ -270,8 +276,8 @@ def double_vertical_separators(lines, vertical_separators_to_duplicate): table_data.append( [ "Sum", - f"{(total_runtime_old / 1e6):>7.1f}", - f"{(total_runtime_new / 1e6):>7.1f}", + f"{(total_runtime_old / 1e6):>7.2f}", + f"{(total_runtime_new / 1e6):>7.2f}", color_diff(total_runtime_new / total_runtime_old, True) + " ", ] ) diff --git a/scripts/compare_benchmarks_multithreaded.py b/scripts/compare_benchmarks_multithreaded.py index 743c1746e4..d3f4b45e7e 100755 --- a/scripts/compare_benchmarks_multithreaded.py +++ b/scripts/compare_benchmarks_multithreaded.py @@ -30,13 +30,13 @@ def get_parser(): def is_square(n): - return n**0.5 == int(n**0.5) + return n ** 0.5 == int(n ** 0.5) def get_subplot_row_and_column_count(num_plots): while not is_square(num_plots): num_plots += 1 - return num_plots**0.5 + return num_plots ** 0.5 def plot_performance(flipped_results, n_rows_cols, numa_borders, max_cores): diff --git a/scripts/coverage.sh b/scripts/coverage.sh index a19c7594d9..174ac6480a 100755 --- a/scripts/coverage.sh +++ b/scripts/coverage.sh @@ -41,10 +41,12 @@ if [[ "$unamestr" == 'Darwin' ]]; then path_to_compiler="$(brew --prefix llvm)/bin/" fi -cmake -DCMAKE_CXX_COMPILER_LAUNCHER=$launcher -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=${path_to_compiler}clang -DCMAKE_CXX_COMPILER=${path_to_compiler}clang++ -DENABLE_COVERAGE=ON .. +# We use clang 11 for the coverage check as clang 14 (the default clang version for Ubuntu 22.04) has an unresolved +# issue (see https://github.com/llvm/llvm-project/issues/54907). +cmake -DCMAKE_CXX_COMPILER_LAUNCHER=$launcher -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=${path_to_compiler}clang-11 -DCMAKE_CXX_COMPILER=${path_to_compiler}clang++-11 -DENABLE_COVERAGE=ON .. cores=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu) -make hyriseTest -j $((cores / 2)) +make hyriseTest -j $((cores / 10)) cd - rm -fr coverage; mkdir coverage diff --git a/scripts/test/compareBenchmarkScriptTest.py b/scripts/test/compareBenchmarkScriptTest.py index afc88eba00..95fade6bb8 100644 --- a/scripts/test/compareBenchmarkScriptTest.py +++ b/scripts/test/compareBenchmarkScriptTest.py @@ -1,25 +1,53 @@ #!/usr/bin/env python3 import json +import math +import re import subprocess # This helper test class takes two JSON result files, runs the compare_benchmarks.py script, and checks that the output # is as expected. It is called from benchmark tests such as hyriseBenchmarkTPCC_test.py. -# The next two functions check for string matches instead of using math.isclose() since extracting values from -# ANSI-colored text turned out to be too cumbersome. +# Function removes any ANSI escape sequences, which we use for color coding. +# Gratefully taken from https://stackoverflow.com/a/14693789/1147726 +def clean_ansi_escape_sequences(input_string): + ansi_escape = re.compile( + r""" + \x1B # ESC + (?: # 7-bit C1 Fe (except CSI) + [@-Z\\-_] + | # or [ for CSI, followed by a control sequence + \[ + [0-?]* # Parameter bytes + [ -/]* # Intermediate bytes + [@-~] # Final byte + ) + """, + re.VERBOSE, + ) + return ansi_escape.sub("", input_string) + + +# As different precisions are used (i.e., precision for rounded latencies is different from rounding precision of +# throughputs), string comparisons with rounding are hard when we don't want to assume known precisions. We thus clean +# the strings from the colour coding, parse the strings as floats, and use math.isclose(). def assert_latency_equals(item_count, runtimes, latency_string): if item_count == 0: assert "nan" in latency_string return + avg_latency = sum(runtimes) / item_count / 1_000_000 - assert str(round(avg_latency, 1)) in latency_string + latency_string_cleaned = clean_ansi_escape_sequences(latency_string) + + assert math.isclose(float(latency_string_cleaned), avg_latency, abs_tol=0.1) def assert_throughput_equals(item_count, duration, throughput_string): throughput = item_count / duration * 1_000_000_000 - assert str(round(throughput, 2)) in throughput_string + throughput_string_cleaned = clean_ansi_escape_sequences(throughput_string) + + assert math.isclose(float(throughput_string_cleaned), throughput, abs_tol=0.1) class CompareBenchmarkScriptTest: diff --git a/src/benchmark/benchmark_playground.cpp b/src/benchmark/benchmark_playground.cpp index b63ee5b039..9e48596816 100644 --- a/src/benchmark/benchmark_playground.cpp +++ b/src/benchmark/benchmark_playground.cpp @@ -42,11 +42,12 @@ class BenchmarkPlaygroundFixture : public MicroBenchmarkBasicFixture { // The "TableScan" will scan for one value (2), so it will select 25%. _vec.resize(1'000'000); std::generate(_vec.begin(), _vec.end(), []() { - static ValueT v = 0; - v = (v + 1) % 4; - return v; + static ValueT value = 0; + value = (value + 1) % 4; + return value; }); } + void TearDown(::benchmark::State& state) override { MicroBenchmarkBasicFixture::TearDown(state); } @@ -65,9 +66,9 @@ BENCHMARK_F(BenchmarkPlaygroundFixture, BM_Playground_Reference)(benchmark::Stat std::vector result; benchmark::DoNotOptimize(result.data()); // Do not optimize out the vector const auto size = _vec.size(); - for (size_t i = 0; i < size; ++i) { - if (_vec[i] == 2) { - result.push_back(i); + for (auto index = size_t{0}; index < size; ++index) { + if (_vec[index] == 2) { + result.push_back(index); benchmark::ClobberMemory(); // Force that record to be written to memory } } @@ -86,9 +87,9 @@ BENCHMARK_F(BenchmarkPlaygroundFixture, BM_Playground_PreAllocate)(benchmark::St // pre-allocate result vector result.reserve(250'000); const auto size = _vec.size(); - for (size_t i = 0; i < size; ++i) { - if (_vec[i] == 2) { - result.push_back(i); + for (auto index = size_t{0}; index < size; ++index) { + if (_vec[index] == 2) { + result.push_back(index); benchmark::ClobberMemory(); // Force that record to be written to memory } } diff --git a/src/benchmark/join_order_benchmark.cpp b/src/benchmark/join_order_benchmark.cpp index d4bf6edc76..c3c859b413 100644 --- a/src/benchmark/join_order_benchmark.cpp +++ b/src/benchmark/join_order_benchmark.cpp @@ -18,7 +18,7 @@ * Its 113 queries are obtained from the "third_party/join-order-benchmark" submodule */ -using namespace hyrise; // NOLINT +using namespace hyrise; // NOLINT using namespace std::string_literals; // NOLINT /** diff --git a/src/benchmark/micro_benchmark_utils.cpp b/src/benchmark/micro_benchmark_utils.cpp index c0902c8640..f94300bf64 100644 --- a/src/benchmark/micro_benchmark_utils.cpp +++ b/src/benchmark/micro_benchmark_utils.cpp @@ -1,14 +1,15 @@ #include "micro_benchmark_utils.hpp" +#include + namespace hyrise { void micro_benchmark_clear_cache() { - std::vector clear = std::vector(); - clear.resize(500 * 1000 * 1000, 42); - for (size_t i = 0; i < clear.size(); i++) { - clear[i] += 1; + constexpr auto ITEM_COUNT = 500 * 1000 * 1000; + auto clear = std::vector(ITEM_COUNT, 42); + for (auto index = size_t{0}; index < ITEM_COUNT; ++index) { + clear[index] += 1; } - clear.resize(0); } } // namespace hyrise diff --git a/src/benchmark/operators/join_benchmark.cpp b/src/benchmark/operators/join_benchmark.cpp index d89625a54c..2ddeefb743 100644 --- a/src/benchmark/operators/join_benchmark.cpp +++ b/src/benchmark/operators/join_benchmark.cpp @@ -24,8 +24,9 @@ constexpr auto TABLE_SIZE_BIG = size_t{10'000'000}; void clear_cache() { std::vector clear = std::vector(); clear.resize(500 * 1000 * 1000, 42); - for (uint i = 0; i < clear.size(); i++) { - clear[i] += 1; + const auto clear_cache_size = clear.size(); + for (auto index = size_t{0}; index < clear_cache_size; index++) { + clear[index] += 1; } clear.resize(0); } @@ -47,7 +48,7 @@ std::shared_ptr generate_table(const size_t number_of_rows) { const auto chunk = table->get_chunk(chunk_id); Assert(chunk, "Physically deleted chunk should not reach this point, see get_chunk / #1686."); - for (ColumnID column_id{0}; column_id < chunk->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < chunk->column_count(); ++column_id) { chunk->create_index(std::vector{column_id}); } } diff --git a/src/benchmark/operators/table_scan_sorted_benchmark.cpp b/src/benchmark/operators/table_scan_sorted_benchmark.cpp index 4bb8aacbe5..037161bd27 100644 --- a/src/benchmark/operators/table_scan_sorted_benchmark.cpp +++ b/src/benchmark/operators/table_scan_sorted_benchmark.cpp @@ -264,6 +264,7 @@ class StartUp { registerTableScanSortedBenchmarks(); } }; + StartUp startup; } // namespace diff --git a/src/benchmark/operators/union_positions_benchmark.cpp b/src/benchmark/operators/union_positions_benchmark.cpp index fa9cb44dc4..f6724d09ae 100644 --- a/src/benchmark/operators/union_positions_benchmark.cpp +++ b/src/benchmark/operators/union_positions_benchmark.cpp @@ -110,6 +110,7 @@ void BM_UnionPositions(::benchmark::State& state) { // NOLINT set_union->execute(); } } + BENCHMARK(BM_UnionPositions); /** @@ -135,5 +136,6 @@ void BM_UnionPositionsBaseLine(::benchmark::State& state) { // NOLINT std::set_union(left.begin(), left.end(), right.begin(), right.end(), std::back_inserter(result)); } } + BENCHMARK(BM_UnionPositionsBaseLine); } // namespace hyrise diff --git a/src/benchmark/tpch_table_generator_benchmark.cpp b/src/benchmark/tpch_table_generator_benchmark.cpp index 7fdf73bc55..867deea231 100644 --- a/src/benchmark/tpch_table_generator_benchmark.cpp +++ b/src/benchmark/tpch_table_generator_benchmark.cpp @@ -17,6 +17,7 @@ static void BM_TPCHTableGenerator(benchmark::State& state) { // NOLINT Hyrise::reset(); } } + BENCHMARK(BM_TPCHTableGenerator); } // namespace hyrise diff --git a/src/benchmarklib/benchmark_config.cpp b/src/benchmarklib/benchmark_config.cpp index 7b9e5360b2..6f50b14f08 100644 --- a/src/benchmarklib/benchmark_config.cpp +++ b/src/benchmarklib/benchmark_config.cpp @@ -29,7 +29,7 @@ BenchmarkConfig::BenchmarkConfig(const BenchmarkMode init_benchmark_mode, const metrics(init_metrics) {} BenchmarkConfig BenchmarkConfig::get_default_config() { - return BenchmarkConfig(); + return BenchmarkConfig{}; } } // namespace hyrise diff --git a/src/benchmarklib/benchmark_runner.cpp b/src/benchmarklib/benchmark_runner.cpp index 4968522ded..103d7dd440 100644 --- a/src/benchmarklib/benchmark_runner.cpp +++ b/src/benchmarklib/benchmark_runner.cpp @@ -515,7 +515,7 @@ cxxopts::Options BenchmarkRunner::get_basic_cli_options(const std::string& bench nlohmann::json BenchmarkRunner::create_context(const BenchmarkConfig& config) { // Generate YY-MM-DD hh:mm::ss auto current_time = std::time(nullptr); - auto local_time = *std::localtime(¤t_time); + auto local_time = *std::localtime(¤t_time); // NOLINT(concurrency-mt-unsafe) - not called in parallel std::stringstream timestamp_stream; timestamp_stream << std::put_time(&local_time, "%Y-%m-%d %H:%M:%S"); diff --git a/src/benchmarklib/benchmark_table_encoder.cpp b/src/benchmarklib/benchmark_table_encoder.cpp index 2fee5e3c07..d2734e21ed 100644 --- a/src/benchmarklib/benchmark_table_encoder.cpp +++ b/src/benchmarklib/benchmark_table_encoder.cpp @@ -71,7 +71,7 @@ bool BenchmarkTableEncoder::encode(const std::string& table_name, const std::sha ChunkEncodingSpec chunk_encoding_spec; - for (ColumnID column_id{0}; column_id < table->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < table->column_count(); ++column_id) { // Check if a column specific encoding was specified if (table_has_custom_encoding) { const auto& column_name = table->column_name(column_id); diff --git a/src/benchmarklib/cli_config_parser.cpp b/src/benchmarklib/cli_config_parser.cpp index a5035b2142..726346be1f 100644 --- a/src/benchmarklib/cli_config_parser.cpp +++ b/src/benchmarklib/cli_config_parser.cpp @@ -164,7 +164,7 @@ EncodingConfig CLIConfigParser::parse_encoding_config(const std::string& encodin const auto encoding_spec_from_json = [](const nlohmann::json& json_spec) { Assert(json_spec.count("encoding"), "Need to specify encoding type."); - const auto encoding_str = json_spec["encoding"]; + const auto& encoding_str = json_spec["encoding"]; const auto compression_str = json_spec.value("compression", ""); return EncodingConfig::encoding_spec_from_strings(encoding_str, compression_str); }; diff --git a/src/benchmarklib/encoding_config.cpp b/src/benchmarklib/encoding_config.cpp index ddd544a3c7..3ee943e483 100644 --- a/src/benchmarklib/encoding_config.cpp +++ b/src/benchmarklib/encoding_config.cpp @@ -85,7 +85,7 @@ nlohmann::json EncodingConfig::to_json() const { } // This is intentionally limited to 80 chars per line, as cxxopts does this too and it looks bad otherwise. -const char* EncodingConfig::description = R"( +const char* const EncodingConfig::description = R"( ====================== Encoding Configuration ====================== diff --git a/src/benchmarklib/encoding_config.hpp b/src/benchmarklib/encoding_config.hpp index a8b72e593e..9c721c6c83 100644 --- a/src/benchmarklib/encoding_config.hpp +++ b/src/benchmarklib/encoding_config.hpp @@ -37,7 +37,7 @@ class EncodingConfig { nlohmann::json to_json() const; - static const char* description; + static const char* const description; }; } // namespace hyrise diff --git a/src/benchmarklib/jcch/jcch_benchmark_item_runner.cpp b/src/benchmarklib/jcch/jcch_benchmark_item_runner.cpp index 9fccba7d3d..e8de28d6c1 100644 --- a/src/benchmarklib/jcch/jcch_benchmark_item_runner.cpp +++ b/src/benchmarklib/jcch/jcch_benchmark_item_runner.cpp @@ -56,6 +56,10 @@ void JCCHBenchmarkItemRunner::_load_params() { Assert(std::filesystem::exists(dbgen_queries_path), std::string{"Query templates not found at "} + dbgen_queries_path); + // NOLINTBEGIN(concurrency-mt-unsafe) + // clang-tidy complains that system() is not thread-safe. We can ignore this warning, because _load_params is only + // called in the constructor once. + // Create local directory and copy query templates if needed const auto local_queries_dir_created = std::filesystem::create_directory(local_queries_path); Assert(std::filesystem::exists(local_queries_path), "Creating JCC-H queries folder failed"); @@ -76,6 +80,7 @@ void JCCHBenchmarkItemRunner::_load_params() { auto ret = system(cmd.str().c_str()); Assert(!ret, "Calling qgen failed"); } + // NOLINTEND(concurrency-mt-unsafe) std::cout << " (" << timer.lap_formatted() << ")" << std::endl; } @@ -264,8 +269,8 @@ bool JCCHBenchmarkItemRunner::_on_execute_item(const BenchmarkItemID item_id, Be case 16 - 1: { parameters.emplace_back("'"s + raw_params_iter->at(0) + "'"); parameters.emplace_back("'"s + raw_params_iter->at(1) + "'"); - for (auto i = 0; i < 8; ++i) { - parameters.emplace_back(raw_params_iter->at(2 + i)); + for (auto index = size_t{0}; index < 8; ++index) { + parameters.emplace_back(raw_params_iter->at(2 + index)); } break; } @@ -324,12 +329,12 @@ bool JCCHBenchmarkItemRunner::_on_execute_item(const BenchmarkItemID item_id, Be case 22 - 1: { // We need the same country code twice - have a look at the query - for (auto i = 0; i < 7; ++i) { - parameters.emplace_back("'"s + raw_params_iter->at(i) + "'"); + for (auto index = size_t{0}; index < 7; ++index) { + parameters.emplace_back("'"s + raw_params_iter->at(index) + "'"); } - for (auto i = 0; i < 7; ++i) { - parameters.emplace_back("'"s + raw_params_iter->at(i) + "'"); + for (auto index = size_t{0}; index < 7; ++index) { + parameters.emplace_back("'"s + raw_params_iter->at(index) + "'"); } break; } diff --git a/src/benchmarklib/jcch/jcch_table_generator.cpp b/src/benchmarklib/jcch/jcch_table_generator.cpp index 7b5d8b0e15..8593592570 100644 --- a/src/benchmarklib/jcch/jcch_table_generator.cpp +++ b/src/benchmarklib/jcch/jcch_table_generator.cpp @@ -23,6 +23,10 @@ JCCHTableGenerator::JCCHTableGenerator(const std::string& dbgen_path, const std: std::unordered_map JCCHTableGenerator::generate() { const auto tables_path = _path + "/tables/"; + // NOLINTBEGIN(concurrency-mt-unsafe) + // clang-tidy complains that system() is not thread-safe. We ignore this warning as we expect that users will not call + // the JCCH table generator in parallel. + // Check if table data has already been generated (and converted to .bin by the FileBasedTableGenerator) if (!std::filesystem::exists(tables_path + "/customer.bin")) { Timer timer; @@ -85,6 +89,8 @@ std::unordered_map JCCHTableGenerator::generate Assert(!ret, "Removing csv/csv.json files failed"); } + // NOLINTEND(concurrency-mt-unsafe) + return generated_tables; } diff --git a/src/benchmarklib/synthetic_table_generator.cpp b/src/benchmarklib/synthetic_table_generator.cpp index c7ab82dead..1c45d7f639 100644 --- a/src/benchmarklib/synthetic_table_generator.cpp +++ b/src/benchmarklib/synthetic_table_generator.cpp @@ -161,9 +161,9 @@ std::shared_ptr SyntheticTableGenerator::generate_table( **/ values.push_back(static_cast(column_data_distribution.min_value)); values.push_back(static_cast(column_data_distribution.max_value)); - for (auto row_offset = size_t{0}; row_offset < chunk_size - 2; ++row_offset) { + for (auto row_offset = ChunkOffset{0}; row_offset < chunk_size - 2; ++row_offset) { // bounds check - if (chunk_index * chunk_size + (row_offset + 1) > num_rows - 2) { + if (static_cast(chunk_index * chunk_size) + row_offset + 1 > num_rows - 2) { break; } values.push_back(generate_value_by_distribution_type()); diff --git a/src/benchmarklib/tpcc/procedures/tpcc_delivery.cpp b/src/benchmarklib/tpcc/procedures/tpcc_delivery.cpp index 3d8161832d..f1a1b069ce 100644 --- a/src/benchmarklib/tpcc/procedures/tpcc_delivery.cpp +++ b/src/benchmarklib/tpcc/procedures/tpcc_delivery.cpp @@ -6,14 +6,12 @@ namespace hyrise { TPCCDelivery::TPCCDelivery(const int num_warehouses, BenchmarkSQLExecutor& sql_executor) - : AbstractTPCCProcedure(sql_executor) { + : AbstractTPCCProcedure(sql_executor), ol_delivery_d{static_cast(std::time(nullptr))} { std::uniform_int_distribution<> warehouse_dist{1, num_warehouses}; w_id = warehouse_dist(_random_engine); std::uniform_int_distribution<> carrier_dist{1, 10}; o_carrier_id = carrier_dist(_random_engine); - - ol_delivery_d = static_cast(std::time(nullptr)); } bool TPCCDelivery::_on_execute() { diff --git a/src/benchmarklib/tpcc/procedures/tpcc_new_order.cpp b/src/benchmarklib/tpcc/procedures/tpcc_new_order.cpp index 069665a6f4..5025578c59 100644 --- a/src/benchmarklib/tpcc/procedures/tpcc_new_order.cpp +++ b/src/benchmarklib/tpcc/procedures/tpcc_new_order.cpp @@ -7,15 +7,13 @@ namespace hyrise { TPCCNewOrder::TPCCNewOrder(const int num_warehouses, BenchmarkSQLExecutor& sql_executor) - : AbstractTPCCProcedure(sql_executor) { + : AbstractTPCCProcedure(sql_executor), c_id{static_cast(_tpcc_random_generator.nurand(1023, 1, 3000))} { std::uniform_int_distribution<> warehouse_dist{1, num_warehouses}; w_id = warehouse_dist(_random_engine); std::uniform_int_distribution<> district_dist{1, 10}; d_id = district_dist(_random_engine); - c_id = static_cast(_tpcc_random_generator.nurand(1023, 1, 3000)); - std::uniform_int_distribution<> num_items_dist{5, 15}; ol_cnt = num_items_dist(_random_engine); diff --git a/src/benchmarklib/tpcc/procedures/tpcc_payment.cpp b/src/benchmarklib/tpcc/procedures/tpcc_payment.cpp index cf44472a5b..ebde9d3e90 100644 --- a/src/benchmarklib/tpcc/procedures/tpcc_payment.cpp +++ b/src/benchmarklib/tpcc/procedures/tpcc_payment.cpp @@ -13,10 +13,11 @@ TPCCPayment::TPCCPayment(const int num_warehouses, BenchmarkSQLExecutor& sql_exe std::uniform_int_distribution<> district_dist{1, 10}; d_id = district_dist(_random_engine); + c_w_id = w_id; // NOLINT(cppcoreguidelines-prefer-member-initializer) + c_d_id = d_id; // NOLINT(cppcoreguidelines-prefer-member-initializer) + // Use home warehouse in 85% of cases, otherwise select a random one std::uniform_int_distribution<> home_warehouse_dist{1, 100}; - c_w_id = w_id; - c_d_id = d_id; if (num_warehouses > 2 && home_warehouse_dist(_random_engine) > 85) { // Choose remote warehouse do { diff --git a/src/benchmarklib/tpcc/tpcc_table_generator.cpp b/src/benchmarklib/tpcc/tpcc_table_generator.cpp index 3cb617dff3..8a06a9199b 100644 --- a/src/benchmarklib/tpcc/tpcc_table_generator.cpp +++ b/src/benchmarklib/tpcc/tpcc_table_generator.cpp @@ -32,22 +32,24 @@ std::shared_ptr
TPCCTableGenerator::generate_item_table() { /** * indices[0] = item */ - std::vector segments_by_chunk; - TableColumnDefinitions column_definitions; + auto segments_by_chunk = std::vector{}; + auto column_definitions = TableColumnDefinitions{}; auto original_ids = _random_gen.select_unique_ids(NUM_ITEMS / 10, NUM_ITEMS); _add_column(segments_by_chunk, column_definitions, "I_ID", cardinalities, - [&](std::vector indices) { return indices[0] + 1; }); + [&](const std::vector& indices) { return indices[0] + 1; }); _add_column(segments_by_chunk, column_definitions, "I_IM_ID", cardinalities, - [&](std::vector) { return _random_gen.random_number(1, 10000); }); - _add_column(segments_by_chunk, column_definitions, "I_NAME", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(14, 24)}; }); - _add_column(segments_by_chunk, column_definitions, "I_PRICE", cardinalities, [&](std::vector) { - return static_cast(_random_gen.random_number(100, 10000)) / 100.f; - }); + [&](const std::vector& /*indices*/) { return _random_gen.random_number(1, 10'000); }); _add_column( - segments_by_chunk, column_definitions, "I_DATA", cardinalities, [&](std::vector indices) { + segments_by_chunk, column_definitions, "I_NAME", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(14, 24)}; }); + _add_column(segments_by_chunk, column_definitions, "I_PRICE", cardinalities, + [&](const std::vector& /*indices*/) { + return static_cast(_random_gen.random_number(100, 10'000)) / 100.f; + }); + _add_column( + segments_by_chunk, column_definitions, "I_DATA", cardinalities, [&](const std::vector& indices) { std::string data = _random_gen.astring(26, 50); bool is_original = original_ids.find(indices[0]) != original_ids.end(); if (is_original) { @@ -74,30 +76,37 @@ std::shared_ptr
TPCCTableGenerator::generate_warehouse_table() { /** * indices[0] = warehouse */ - std::vector segments_by_chunk; - TableColumnDefinitions column_definitions; + auto segments_by_chunk = std::vector{}; + auto column_definitions = TableColumnDefinitions{}; _add_column(segments_by_chunk, column_definitions, "W_ID", cardinalities, - [&](std::vector indices) { return indices[0] + 1; }); - _add_column(segments_by_chunk, column_definitions, "W_NAME", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(6, 10)}; }); - _add_column(segments_by_chunk, column_definitions, "W_STREET_1", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(10, 20)}; }); - _add_column(segments_by_chunk, column_definitions, "W_STREET_2", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(10, 20)}; }); - _add_column(segments_by_chunk, column_definitions, "W_CITY", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(10, 20)}; }); - _add_column(segments_by_chunk, column_definitions, "W_STATE", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(2, 2)}; }); + [&](const std::vector& indices) { return indices[0] + 1; }); + _add_column( + segments_by_chunk, column_definitions, "W_NAME", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(6, 10)}; }); + _add_column( + segments_by_chunk, column_definitions, "W_STREET_1", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(10, 20)}; }); + _add_column( + segments_by_chunk, column_definitions, "W_STREET_2", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(10, 20)}; }); + _add_column( + segments_by_chunk, column_definitions, "W_CITY", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(10, 20)}; }); + _add_column( + segments_by_chunk, column_definitions, "W_STATE", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(2, 2)}; }); _add_column(segments_by_chunk, column_definitions, "W_ZIP", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.zip_code()}; }); - _add_column(segments_by_chunk, column_definitions, "W_TAX", cardinalities, [&](std::vector) { - return static_cast(_random_gen.random_number(0, 2000)) / 10000.f; - }); - _add_column(segments_by_chunk, column_definitions, "W_YTD", cardinalities, [&](std::vector) { - return CUSTOMER_YTD * NUM_CUSTOMERS_PER_DISTRICT * NUM_DISTRICTS_PER_WAREHOUSE; - }); + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.zip_code()}; }); + _add_column(segments_by_chunk, column_definitions, "W_TAX", cardinalities, + [&](const std::vector& /*indices*/) { + return static_cast(_random_gen.random_number(0, 2'000)) / 10'000.f; + }); + _add_column(segments_by_chunk, column_definitions, "W_YTD", cardinalities, + [&](const std::vector& /*indices*/) { + return CUSTOMER_YTD * NUM_CUSTOMERS_PER_DISTRICT * NUM_DISTRICTS_PER_WAREHOUSE; + }); auto table = std::make_shared
(column_definitions, TableType::Data, _benchmark_config->chunk_size, UseMvcc::Yes); @@ -117,31 +126,32 @@ std::shared_ptr
TPCCTableGenerator::generate_stock_table() { * indices[0] = warehouse * indices[1] = stock */ - std::vector segments_by_chunk; - TableColumnDefinitions column_definitions; + auto segments_by_chunk = std::vector{}; + auto column_definitions = TableColumnDefinitions{}; auto original_ids = _random_gen.select_unique_ids(NUM_ITEMS / 10, NUM_ITEMS); _add_column(segments_by_chunk, column_definitions, "S_I_ID", cardinalities, - [&](std::vector indices) { return indices[1] + 1; }); + [&](const std::vector& indices) { return indices[1] + 1; }); _add_column(segments_by_chunk, column_definitions, "S_W_ID", cardinalities, - [&](std::vector indices) { return indices[0] + 1; }); + [&](const std::vector& indices) { return indices[0] + 1; }); _add_column(segments_by_chunk, column_definitions, "S_QUANTITY", cardinalities, - [&](std::vector) { return _random_gen.random_number(10, 100); }); + [&](const std::vector& /*indices*/) { return _random_gen.random_number(10, 100); }); for (auto district_i = int32_t{1}; district_i <= 10; district_i++) { std::stringstream district_i_str; district_i_str << std::setw(2) << std::setfill('0') << district_i; - _add_column(segments_by_chunk, column_definitions, "S_DIST_" + district_i_str.str(), cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(24, 24)}; }); + _add_column( + segments_by_chunk, column_definitions, "S_DIST_" + district_i_str.str(), cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(24, 24)}; }); } _add_column(segments_by_chunk, column_definitions, "S_YTD", cardinalities, - [&](std::vector) { return 0; }); + [&](const std::vector& /*indices*/) { return 0; }); _add_column(segments_by_chunk, column_definitions, "S_ORDER_CNT", cardinalities, - [&](std::vector) { return 0; }); + [&](const std::vector& /*indices*/) { return 0; }); _add_column(segments_by_chunk, column_definitions, "S_REMOTE_CNT", cardinalities, - [&](std::vector) { return 0; }); + [&](const std::vector& /*indices*/) { return 0; }); _add_column( - segments_by_chunk, column_definitions, "S_DATA", cardinalities, [&](std::vector indices) { + segments_by_chunk, column_definitions, "S_DATA", cardinalities, [&](const std::vector& indices) { std::string data = _random_gen.astring(26, 50); bool is_original = original_ids.find(indices[1]) != original_ids.end(); if (is_original) { @@ -170,33 +180,39 @@ std::shared_ptr
TPCCTableGenerator::generate_district_table() { * indices[0] = warehouse * indices[1] = district */ - std::vector segments_by_chunk; - TableColumnDefinitions column_definitions; + auto segments_by_chunk = std::vector{}; + auto column_definitions = TableColumnDefinitions{}; _add_column(segments_by_chunk, column_definitions, "D_ID", cardinalities, - [&](std::vector indices) { return indices[1] + 1; }); + [&](const std::vector& indices) { return indices[1] + 1; }); _add_column(segments_by_chunk, column_definitions, "D_W_ID", cardinalities, - [&](std::vector indices) { return indices[0] + 1; }); - _add_column(segments_by_chunk, column_definitions, "D_NAME", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(6, 10)}; }); - _add_column(segments_by_chunk, column_definitions, "D_STREET_1", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(10, 20)}; }); - _add_column(segments_by_chunk, column_definitions, "D_STREET_2", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(10, 20)}; }); - _add_column(segments_by_chunk, column_definitions, "D_CITY", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(10, 20)}; }); - _add_column(segments_by_chunk, column_definitions, "D_STATE", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(2, 2)}; }); + [&](const std::vector& indices) { return indices[0] + 1; }); + _add_column( + segments_by_chunk, column_definitions, "D_NAME", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(6, 10)}; }); + _add_column( + segments_by_chunk, column_definitions, "D_STREET_1", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(10, 20)}; }); + _add_column( + segments_by_chunk, column_definitions, "D_STREET_2", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(10, 20)}; }); + _add_column( + segments_by_chunk, column_definitions, "D_CITY", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(10, 20)}; }); + _add_column( + segments_by_chunk, column_definitions, "D_STATE", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(2, 2)}; }); _add_column(segments_by_chunk, column_definitions, "D_ZIP", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.zip_code()}; }); - _add_column(segments_by_chunk, column_definitions, "D_TAX", cardinalities, [&](std::vector) { - return static_cast(_random_gen.random_number(0, 2000)) / 10000.f; - }); + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.zip_code()}; }); + _add_column(segments_by_chunk, column_definitions, "D_TAX", cardinalities, + [&](const std::vector& /*indices*/) { + return static_cast(_random_gen.random_number(0, 2'000)) / 10'000.f; + }); _add_column(segments_by_chunk, column_definitions, "D_YTD", cardinalities, - [&](std::vector) { return CUSTOMER_YTD * NUM_CUSTOMERS_PER_DISTRICT; }); + [&](const std::vector& /*indices*/) { return CUSTOMER_YTD * NUM_CUSTOMERS_PER_DISTRICT; }); _add_column(segments_by_chunk, column_definitions, "D_NEXT_O_ID", cardinalities, - [&](std::vector) { return NUM_ORDERS_PER_DISTRICT + 1; }); + [&](const std::vector& /*indices*/) { return NUM_ORDERS_PER_DISTRICT + 1; }); auto table = std::make_shared
(column_definitions, TableType::Data, _benchmark_config->chunk_size, UseMvcc::Yes); @@ -217,57 +233,66 @@ std::shared_ptr
TPCCTableGenerator::generate_customer_table() { * indices[1] = district * indices[2] = customer */ - std::vector segments_by_chunk; - TableColumnDefinitions column_definitions; + auto segments_by_chunk = std::vector{}; + auto column_definitions = TableColumnDefinitions{}; auto original_ids = _random_gen.select_unique_ids(NUM_ITEMS / 10, NUM_ITEMS); _add_column(segments_by_chunk, column_definitions, "C_ID", cardinalities, - [&](std::vector indices) { return indices[2] + 1; }); + [&](const std::vector& indices) { return indices[2] + 1; }); _add_column(segments_by_chunk, column_definitions, "C_D_ID", cardinalities, - [&](std::vector indices) { return indices[1] + 1; }); + [&](const std::vector& indices) { return indices[1] + 1; }); _add_column(segments_by_chunk, column_definitions, "C_W_ID", cardinalities, - [&](std::vector indices) { return indices[0] + 1; }); - _add_column(segments_by_chunk, column_definitions, "C_FIRST", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(8, 16)}; }); + [&](const std::vector& indices) { return indices[0] + 1; }); + _add_column( + segments_by_chunk, column_definitions, "C_FIRST", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(8, 16)}; }); _add_column(segments_by_chunk, column_definitions, "C_MIDDLE", cardinalities, - [&](std::vector) { return pmr_string{"OE"}; }); - _add_column(segments_by_chunk, column_definitions, "C_LAST", cardinalities, - [&](std::vector indices) { return pmr_string{_random_gen.last_name(indices[2])}; }); - _add_column(segments_by_chunk, column_definitions, "C_STREET_1", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(10, 20)}; }); - _add_column(segments_by_chunk, column_definitions, "C_STREET_2", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(10, 20)}; }); - _add_column(segments_by_chunk, column_definitions, "C_CITY", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(10, 20)}; }); - _add_column(segments_by_chunk, column_definitions, "C_STATE", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(2, 2)}; }); + [&](const std::vector& /*indices*/) { return pmr_string{"OE"}; }); + _add_column( + segments_by_chunk, column_definitions, "C_LAST", cardinalities, + [&](const std::vector& indices) { return pmr_string{_random_gen.last_name(indices[2])}; }); + _add_column( + segments_by_chunk, column_definitions, "C_STREET_1", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(10, 20)}; }); + _add_column( + segments_by_chunk, column_definitions, "C_STREET_2", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(10, 20)}; }); + _add_column( + segments_by_chunk, column_definitions, "C_CITY", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(10, 20)}; }); + _add_column( + segments_by_chunk, column_definitions, "C_STATE", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(2, 2)}; }); _add_column(segments_by_chunk, column_definitions, "C_ZIP", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.zip_code()}; }); - _add_column(segments_by_chunk, column_definitions, "C_PHONE", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.nstring(16, 16)}; }); + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.zip_code()}; }); + _add_column( + segments_by_chunk, column_definitions, "C_PHONE", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.nstring(16, 16)}; }); _add_column(segments_by_chunk, column_definitions, "C_SINCE", cardinalities, - [&](std::vector) { return _current_date; }); + [&](const std::vector& /*indices*/) { return _current_date; }); _add_column(segments_by_chunk, column_definitions, "C_CREDIT", cardinalities, - [&](std::vector indices) { + [&](const std::vector& indices) { bool is_original = original_ids.find(indices[2]) != original_ids.end(); return pmr_string{is_original ? "BC" : "GC"}; }); _add_column(segments_by_chunk, column_definitions, "C_CREDIT_LIM", cardinalities, - [&](std::vector) { return 50000; }); - _add_column(segments_by_chunk, column_definitions, "C_DISCOUNT", cardinalities, [&](std::vector) { - return static_cast(_random_gen.random_number(0, 5000)) / 10000.f; - }); + [&](const std::vector& /*indices*/) { return 50'000; }); + _add_column(segments_by_chunk, column_definitions, "C_DISCOUNT", cardinalities, + [&](const std::vector& /*indices*/) { + return static_cast(_random_gen.random_number(0, 5'000)) / 10'000.f; + }); _add_column(segments_by_chunk, column_definitions, "C_BALANCE", cardinalities, - [&](std::vector) { return -CUSTOMER_YTD; }); + [&](const std::vector& /*indices*/) { return -CUSTOMER_YTD; }); _add_column(segments_by_chunk, column_definitions, "C_YTD_PAYMENT", cardinalities, - [&](std::vector) { return CUSTOMER_YTD; }); + [&](const std::vector& /*indices*/) { return CUSTOMER_YTD; }); _add_column(segments_by_chunk, column_definitions, "C_PAYMENT_CNT", cardinalities, - [&](std::vector) { return 1; }); + [&](const std::vector& /*indices*/) { return 1; }); _add_column(segments_by_chunk, column_definitions, "C_DELIVERY_CNT", cardinalities, - [&](std::vector) { return 0; }); - _add_column(segments_by_chunk, column_definitions, "C_DATA", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(300, 500)}; }); + [&](const std::vector& /*indices*/) { return 0; }); + _add_column( + segments_by_chunk, column_definitions, "C_DATA", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(300, 500)}; }); auto table = std::make_shared
(column_definitions, TableType::Data, _benchmark_config->chunk_size, UseMvcc::Yes); @@ -291,25 +316,26 @@ std::shared_ptr
TPCCTableGenerator::generate_history_table() { * indices[2] = customer * indices[3] = history */ - std::vector segments_by_chunk; - TableColumnDefinitions column_definitions; + auto segments_by_chunk = std::vector{}; + auto column_definitions = TableColumnDefinitions{}; _add_column(segments_by_chunk, column_definitions, "H_C_ID", cardinalities, - [&](std::vector indices) { return indices[2] + 1; }); + [&](const std::vector& indices) { return indices[2] + 1; }); _add_column(segments_by_chunk, column_definitions, "H_C_D_ID", cardinalities, - [&](std::vector indices) { return indices[1] + 1; }); + [&](const std::vector& indices) { return indices[1] + 1; }); _add_column(segments_by_chunk, column_definitions, "H_C_W_ID", cardinalities, - [&](std::vector indices) { return indices[0] + 1; }); + [&](const std::vector& indices) { return indices[0] + 1; }); _add_column(segments_by_chunk, column_definitions, "H_D_ID", cardinalities, - [&](std::vector indices) { return indices[1] + 1; }); + [&](const std::vector& indices) { return indices[1] + 1; }); _add_column(segments_by_chunk, column_definitions, "H_W_ID", cardinalities, - [&](std::vector indices) { return indices[0] + 1; }); + [&](const std::vector& indices) { return indices[0] + 1; }); _add_column(segments_by_chunk, column_definitions, "H_DATE", cardinalities, - [&](std::vector) { return _current_date; }); + [&](const std::vector& /*indices*/) { return _current_date; }); _add_column(segments_by_chunk, column_definitions, "H_AMOUNT", cardinalities, - [&](std::vector) { return 10.f; }); - _add_column(segments_by_chunk, column_definitions, "H_DATA", cardinalities, - [&](std::vector) { return pmr_string{_random_gen.astring(12, 24)}; }); + [&](const std::vector& /*indices*/) { return 10.f; }); + _add_column( + segments_by_chunk, column_definitions, "H_DATA", cardinalities, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(12, 24)}; }); auto table = std::make_shared
(column_definitions, TableType::Data, _benchmark_config->chunk_size, UseMvcc::Yes); @@ -331,35 +357,35 @@ std::shared_ptr
TPCCTableGenerator::generate_order_table( * indices[1] = district * indices[2] = order */ - std::vector segments_by_chunk; - TableColumnDefinitions column_definitions; + auto segments_by_chunk = std::vector{}; + auto column_definitions = TableColumnDefinitions{}; // TODO(anyone): generate a new customer permutation for each district and warehouse. Currently they all have the // same permutation auto customer_permutation = _random_gen.permutation(0, NUM_CUSTOMERS_PER_DISTRICT); _add_column(segments_by_chunk, column_definitions, "O_ID", cardinalities, - [&](std::vector indices) { return indices[2] + 1; }); + [&](const std::vector& indices) { return indices[2] + 1; }); _add_column(segments_by_chunk, column_definitions, "O_D_ID", cardinalities, - [&](std::vector indices) { return indices[1] + 1; }); + [&](const std::vector& indices) { return indices[1] + 1; }); _add_column(segments_by_chunk, column_definitions, "O_W_ID", cardinalities, - [&](std::vector indices) { return indices[0] + 1; }); + [&](const std::vector& indices) { return indices[0] + 1; }); _add_column(segments_by_chunk, column_definitions, "O_C_ID", cardinalities, - [&](std::vector indices) { return customer_permutation[indices[2]] + 1; }); + [&](const std::vector& indices) { return customer_permutation[indices[2]] + 1; }); _add_column(segments_by_chunk, column_definitions, "O_ENTRY_D", cardinalities, - [&](std::vector) { return _current_date; }); + [&](const std::vector& /*indices*/) { return _current_date; }); _add_column(segments_by_chunk, column_definitions, "O_CARRIER_ID", cardinalities, - [&](std::vector indices) { + [&](const std::vector& indices) { return indices[2] + 1 <= NUM_ORDERS_PER_DISTRICT - NUM_NEW_ORDERS_PER_DISTRICT ? std::optional{_random_gen.random_number(1, 10)} : std::nullopt; }); _add_column( segments_by_chunk, column_definitions, "O_OL_CNT", cardinalities, - [&](std::vector indices) { return order_line_counts[indices[0]][indices[1]][indices[2]]; }); + [&](const std::vector& indices) { return order_line_counts[indices[0]][indices[1]][indices[2]]; }); _add_column(segments_by_chunk, column_definitions, "O_ALL_LOCAL", cardinalities, - [&](std::vector) { return 1; }); + [&](const std::vector& /*indices*/) { return 1; }); auto table = std::make_shared
(column_definitions, TableType::Data, _benchmark_config->chunk_size, UseMvcc::Yes); @@ -371,18 +397,18 @@ std::shared_ptr
TPCCTableGenerator::generate_order_table( return table; } -TPCCTableGenerator::OrderLineCounts TPCCTableGenerator::generate_order_line_counts() { - OrderLineCounts v(_num_warehouses); - for (auto& v_per_warehouse : v) { - v_per_warehouse.resize(NUM_DISTRICTS_PER_WAREHOUSE); - for (auto& v_per_district : v_per_warehouse) { - v_per_district.resize(NUM_ORDERS_PER_DISTRICT); - for (auto& v_per_order : v_per_district) { - v_per_order = _random_gen.random_number(5, 15); +TPCCTableGenerator::OrderLineCounts TPCCTableGenerator::generate_order_line_counts() const { + auto order_line_counts = OrderLineCounts(_num_warehouses); + for (auto& counts_per_warehouse : order_line_counts) { + counts_per_warehouse.resize(NUM_DISTRICTS_PER_WAREHOUSE); + for (auto& counts_per_district : counts_per_warehouse) { + counts_per_district.resize(NUM_ORDERS_PER_DISTRICT); + for (auto& count_per_order : counts_per_district) { + count_per_order = _random_gen.random_number(5, 15); } } } - return v; + return order_line_counts; } /** @@ -392,15 +418,15 @@ TPCCTableGenerator::OrderLineCounts TPCCTableGenerator::generate_order_line_coun */ template std::vector> TPCCTableGenerator::_generate_inner_order_line_column( - std::vector indices, TPCCTableGenerator::OrderLineCounts order_line_counts, - const std::function(std::vector)>& generator_function) { + const std::vector& indices, TPCCTableGenerator::OrderLineCounts order_line_counts, + const std::function(const std::vector&)>& generator_function) { auto order_line_count = order_line_counts[indices[0]][indices[1]][indices[2]]; - std::vector> values; + auto values = std::vector>{}; values.reserve(order_line_count); - for (size_t i = 0; i < order_line_count; i++) { + for (auto index = size_t{0}; index < order_line_count; index++) { auto copied_indices = indices; - copied_indices.push_back(i); + copied_indices.push_back(index); values.push_back(generator_function(copied_indices)); } @@ -411,9 +437,9 @@ template void TPCCTableGenerator::_add_order_line_column( std::vector& segments_by_chunk, TableColumnDefinitions& column_definitions, std::string name, std::shared_ptr> cardinalities, TPCCTableGenerator::OrderLineCounts order_line_counts, - const std::function(std::vector)>& generator_function) { - const std::function>(std::vector)> wrapped_generator_function = - [&](std::vector indices) { + const std::function(const std::vector&)>& generator_function) { + const std::function>(const std::vector&)> wrapped_generator_function = + [&](const std::vector& indices) { return _generate_inner_order_line_column(indices, order_line_counts, generator_function); }; _add_column(segments_by_chunk, column_definitions, name, cardinalities, wrapped_generator_function); @@ -430,39 +456,41 @@ std::shared_ptr
TPCCTableGenerator::generate_order_line_table( * indices[2] = order * indices[3] = order_line_size */ - std::vector segments_by_chunk; - TableColumnDefinitions column_definitions; + auto segments_by_chunk = std::vector{}; + auto column_definitions = TableColumnDefinitions{}; _add_order_line_column(segments_by_chunk, column_definitions, "OL_O_ID", cardinalities, order_line_counts, - [&](std::vector indices) { return indices[2] + 1; }); + [&](const std::vector& indices) { return indices[2] + 1; }); _add_order_line_column(segments_by_chunk, column_definitions, "OL_D_ID", cardinalities, order_line_counts, - [&](std::vector indices) { return indices[1] + 1; }); + [&](const std::vector& indices) { return indices[1] + 1; }); _add_order_line_column(segments_by_chunk, column_definitions, "OL_W_ID", cardinalities, order_line_counts, - [&](std::vector indices) { return indices[0] + 1; }); + [&](const std::vector& indices) { return indices[0] + 1; }); _add_order_line_column(segments_by_chunk, column_definitions, "OL_NUMBER", cardinalities, order_line_counts, - [&](std::vector indices) { return indices[3] + 1; }); - _add_order_line_column(segments_by_chunk, column_definitions, "OL_I_ID", cardinalities, order_line_counts, - [&](std::vector) { return _random_gen.random_number(1, NUM_ITEMS); }); + [&](const std::vector& indices) { return indices[3] + 1; }); + _add_order_line_column( + segments_by_chunk, column_definitions, "OL_I_ID", cardinalities, order_line_counts, + [&](const std::vector& /*indices*/) { return _random_gen.random_number(1, NUM_ITEMS); }); _add_order_line_column(segments_by_chunk, column_definitions, "OL_SUPPLY_W_ID", cardinalities, - order_line_counts, [&](std::vector indices) { return indices[0] + 1; }); + order_line_counts, + [&](const std::vector& indices) { return indices[0] + 1; }); _add_order_line_column(segments_by_chunk, column_definitions, "OL_DELIVERY_D", cardinalities, - order_line_counts, [&](std::vector indices) { + order_line_counts, [&](const std::vector& indices) { return indices[2] + 1 <= NUM_ORDERS_PER_DISTRICT - NUM_NEW_ORDERS_PER_DISTRICT ? std::optional{_current_date} : std::nullopt; }); _add_order_line_column(segments_by_chunk, column_definitions, "OL_QUANTITY", cardinalities, - order_line_counts, [&](std::vector) { return 5; }); + order_line_counts, [&](const std::vector& /*indices*/) { return 5; }); _add_order_line_column(segments_by_chunk, column_definitions, "OL_AMOUNT", cardinalities, order_line_counts, - [&](std::vector indices) { + [&](const std::vector& indices) { return indices[2] < NUM_ORDERS_PER_DISTRICT - NUM_NEW_ORDERS_PER_DISTRICT ? 0.f : static_cast(_random_gen.random_number(1, 999999)) / 100.f; }); - _add_order_line_column(segments_by_chunk, column_definitions, "OL_DIST_INFO", cardinalities, - order_line_counts, - [&](std::vector) { return pmr_string{_random_gen.astring(24, 24)}; }); + _add_order_line_column( + segments_by_chunk, column_definitions, "OL_DIST_INFO", cardinalities, order_line_counts, + [&](const std::vector& /*indices*/) { return pmr_string{_random_gen.astring(24, 24)}; }); auto table = std::make_shared
(column_definitions, TableType::Data, _benchmark_config->chunk_size, UseMvcc::Yes); @@ -483,17 +511,17 @@ std::shared_ptr
TPCCTableGenerator::generate_new_order_table() { * indices[1] = district * indices[2] = new_order */ - std::vector segments_by_chunk; - TableColumnDefinitions column_definitions; + auto segments_by_chunk = std::vector{}; + auto column_definitions = TableColumnDefinitions{}; _add_column(segments_by_chunk, column_definitions, "NO_O_ID", cardinalities, - [&](std::vector indices) { + [&](const std::vector& indices) { return indices[2] + 1 + NUM_ORDERS_PER_DISTRICT - NUM_NEW_ORDERS_PER_DISTRICT; }); _add_column(segments_by_chunk, column_definitions, "NO_D_ID", cardinalities, - [&](std::vector indices) { return indices[1] + 1; }); + [&](const std::vector& indices) { return indices[1] + 1; }); _add_column(segments_by_chunk, column_definitions, "NO_W_ID", cardinalities, - [&](std::vector indices) { return indices[0] + 1; }); + [&](const std::vector& indices) { return indices[0] + 1; }); auto table = std::make_shared
(column_definitions, TableType::Data, _benchmark_config->chunk_size, UseMvcc::Yes); diff --git a/src/benchmarklib/tpcc/tpcc_table_generator.hpp b/src/benchmarklib/tpcc/tpcc_table_generator.hpp index ad2d4335e6..f6da0d6c1f 100644 --- a/src/benchmarklib/tpcc/tpcc_table_generator.hpp +++ b/src/benchmarklib/tpcc/tpcc_table_generator.hpp @@ -41,7 +41,7 @@ class TPCCTableGenerator : public AbstractTableGenerator { using OrderLineCounts = std::vector>>; - OrderLineCounts generate_order_line_counts(); + OrderLineCounts generate_order_line_counts() const; std::shared_ptr
generate_order_table(const OrderLineCounts& order_line_counts); @@ -59,14 +59,14 @@ class TPCCTableGenerator : public AbstractTableGenerator { template std::vector> _generate_inner_order_line_column( - std::vector indices, OrderLineCounts order_line_counts, - const std::function(std::vector)>& generator_function); + const std::vector& indices, OrderLineCounts order_line_counts, + const std::function(const std::vector&)>& generator_function); template void _add_order_line_column(std::vector& segments_by_chunk, TableColumnDefinitions& column_definitions, std::string name, std::shared_ptr> cardinalities, OrderLineCounts order_line_counts, - const std::function(std::vector)>& generator_function); + const std::function(const std::vector&)>& generator_function); // Used to generate not only random numbers, but also non-uniform numbers and random last names as defined by the // TPC-C Specification. @@ -103,7 +103,7 @@ class TPCCTableGenerator : public AbstractTableGenerator { template void _add_column(std::vector& segments_by_chunk, TableColumnDefinitions& column_definitions, std::string name, std::shared_ptr> cardinalities, - const std::function>(std::vector)>& generator_function) { + const std::function>(const std::vector&)>& generator_function) { const auto chunk_size = _benchmark_config->chunk_size; bool is_first_column = column_definitions.size() == 0; @@ -126,9 +126,9 @@ class TPCCTableGenerator : public AbstractTableGenerator { /** * The loop over all records that the final column of the table will contain, e.g. loop_count = 30 000 for CUSTOMER */ - size_t row_index = 0; + auto row_index = size_t{0}; - for (size_t loop_index = 0; loop_index < loop_count; loop_index++) { + for (auto loop_index = size_t{0}; loop_index < loop_count; ++loop_index) { std::vector indices(cardinalities->size()); /** @@ -142,7 +142,7 @@ class TPCCTableGenerator : public AbstractTableGenerator { * WAREHOUSE_ID | DISTRICT_ID | CUSTOMER_ID * indices[0] | indices[1] | indices[2] */ - for (size_t loop = 0; loop < cardinalities->size(); loop++) { + for (auto loop = size_t{0}; loop < cardinalities->size(); ++loop) { auto divisor = std::accumulate(std::begin(*cardinalities) + loop + 1, std::end(*cardinalities), 1u, std::multiplies()); indices[loop] = (loop_index / divisor) % cardinalities->at(loop); @@ -156,7 +156,7 @@ class TPCCTableGenerator : public AbstractTableGenerator { * and iterate it to add to the output segment. */ auto values = generator_function(indices); - for (auto& value : values) { + for (const auto& value : values) { if (value) { data.emplace_back(std::move(*value)); } else { @@ -187,7 +187,7 @@ class TPCCTableGenerator : public AbstractTableGenerator { null_values = {}; null_values.reserve(chunk_size); } - row_index++; + ++row_index; } } @@ -200,7 +200,7 @@ class TPCCTableGenerator : public AbstractTableGenerator { segments_by_chunk.emplace_back(); segments_by_chunk.back().emplace_back(value_segment); } else { - ChunkID chunk_id{static_cast(row_index / chunk_size)}; + ChunkID chunk_id{static_cast(row_index / chunk_size)}; segments_by_chunk[chunk_id].emplace_back(value_segment); } } @@ -223,9 +223,11 @@ class TPCCTableGenerator : public AbstractTableGenerator { template void _add_column(std::vector& segments_by_chunk, TableColumnDefinitions& column_definitions, std::string name, std::shared_ptr> cardinalities, - const std::function)>& generator_function) { - const std::function(std::vector)> wrapped_generator_function = - [generator_function](std::vector indices) { return std::vector({generator_function(indices)}); }; + const std::function&)>& generator_function) { + const std::function(const std::vector&)> wrapped_generator_function = + [generator_function](const std::vector& indices) { + return std::vector({generator_function(indices)}); + }; _add_column(segments_by_chunk, column_definitions, name, cardinalities, wrapped_generator_function); } @@ -241,9 +243,9 @@ class TPCCTableGenerator : public AbstractTableGenerator { template void _add_column(std::vector& segments_by_chunk, TableColumnDefinitions& column_definitions, std::string name, std::shared_ptr> cardinalities, - const std::function(std::vector)>& generator_function) { - const std::function>(std::vector)> wrapped_generator_function = - [generator_function](std::vector indices) { + const std::function(const std::vector&)>& generator_function) { + const std::function>(const std::vector&)> wrapped_generator_function = + [generator_function](const std::vector& indices) { return std::vector>({generator_function(indices)}); }; _add_column(segments_by_chunk, column_definitions, name, cardinalities, wrapped_generator_function); diff --git a/src/benchmarklib/tpcds/tpcds_table_generator.cpp b/src/benchmarklib/tpcds/tpcds_table_generator.cpp index c1b371751b..b52f7fe2da 100644 --- a/src/benchmarklib/tpcds/tpcds_table_generator.cpp +++ b/src/benchmarklib/tpcds/tpcds_table_generator.cpp @@ -58,12 +58,13 @@ void init_tpcds_tools(uint32_t scale_factor, int rng_seed) { // init_rand from genrand.c, adapted { - auto n_seed = get_int(rng_seed_string.data()); - auto skip = INT_MAX / MAX_COLUMN; - for (auto i = 0; i < MAX_COLUMN; i++) { - Streams[i].nInitialSeed = static_cast(static_cast(n_seed) + skip * i); - Streams[i].nSeed = static_cast(static_cast(n_seed) + skip * i); - Streams[i].nUsed = 0; + const auto n_seed = get_int(rng_seed_string.data()); + const auto skip = INT_MAX / MAX_COLUMN; + for (auto index = 0; index < MAX_COLUMN; ++index) { + const auto seed = n_seed + skip * index; + Streams[index].nInitialSeed = seed; + Streams[index].nSeed = seed; + Streams[index].nUsed = 0; } } @@ -76,7 +77,7 @@ void init_tpcds_tools(uint32_t scale_factor, int rng_seed) { auto distributions_value = std::string{"resources/benchmark/tpcds/tpcds.idx"}; set_str(distributions_string.data(), distributions_value.data()); - for (auto table_id = 0; table_id <= MAX_TABLE; table_id++) { + for (auto table_id = int{0}; table_id <= MAX_TABLE; ++table_id) { resetSeeds(table_id); RNGReset(table_id); } @@ -117,12 +118,13 @@ std::pair prepare_for_table(int table_id) { } pmr_string boolean_to_string(bool boolean) { - return pmr_string(1, boolean ? 'Y' : 'N'); + return {boolean ? "Y" : "N"}; } pmr_string zip_to_string(int32_t zip) { auto result = pmr_string(5, '?'); - std::snprintf(result.data(), result.size() + 1, "%05d", zip); + const auto snprintf_rc = std::snprintf(result.data(), result.size() + 1, "%05d", zip); + Assert(snprintf_rc > 0, "Unexpected string to parse."); return result; } @@ -136,7 +138,9 @@ std::optional resolve_date_id(int column_id, ds_key_t date_id) { jtodt(&date, static_cast(date_id)); auto result = pmr_string(10, '?'); - std::snprintf(result.data(), result.size() + 1, "%4d-%02d-%02d", date.year, date.month, date.day); + const auto snprintf_rc = + std::snprintf(result.data(), result.size() + 1, "%4d-%02d-%02d", date.year, date.month, date.day); + Assert(snprintf_rc > 0, "Unexpected string to parse."); return result; } @@ -301,56 +305,77 @@ std::unordered_map TPCDSTableGenerator::generat std::shared_ptr
TPCDSTableGenerator::_generate_table(const std::string& table_name) const { if (table_name == "call_center") { return generate_call_center(); - } else if (table_name == "catalog_page") { + } + if (table_name == "catalog_page") { return generate_catalog_page(); - } else if (table_name == "customer_address") { + } + if (table_name == "customer_address") { return generate_customer_address(); - } else if (table_name == "customer") { + } + if (table_name == "customer") { return generate_customer(); - } else if (table_name == "customer_demographics") { + } + if (table_name == "customer_demographics") { return generate_customer_demographics(); - } else if (table_name == "date_dim") { + } + if (table_name == "date_dim") { return generate_date_dim(); - } else if (table_name == "household_demographics") { + } + if (table_name == "household_demographics") { return generate_household_demographics(); - } else if (table_name == "income_band") { + } + if (table_name == "income_band") { return generate_income_band(); - } else if (table_name == "inventory") { + } + if (table_name == "inventory") { return generate_inventory(); - } else if (table_name == "item") { + } + if (table_name == "item") { return generate_item(); - } else if (table_name == "promotion") { + } + if (table_name == "promotion") { return generate_promotion(); - } else if (table_name == "reason") { + } + if (table_name == "reason") { return generate_reason(); - } else if (table_name == "ship_mode") { + } + if (table_name == "ship_mode") { return generate_ship_mode(); - } else if (table_name == "store") { + } + if (table_name == "store") { return generate_store(); - } else if (table_name == "time_dim") { + } + if (table_name == "time_dim") { return generate_time_dim(); - } else if (table_name == "warehouse") { + } + if (table_name == "warehouse") { return generate_warehouse(); - } else if (table_name == "web_page") { + } + if (table_name == "web_page") { return generate_web_page(); - } else if (table_name == "web_site") { + } + if (table_name == "web_site") { return generate_web_site(); - } else { - Fail("Unexpected table name: " + table_name); } + + Fail("Unexpected table name: " + table_name); } std::pair, std::shared_ptr
> TPCDSTableGenerator::_generate_sales_and_returns_tables( const std::string& sales_table_name) const { if (sales_table_name == "catalog_sales") { return generate_catalog_sales_and_returns(); - } else if (sales_table_name == "store_sales") { + } + + if (sales_table_name == "store_sales") { return generate_store_sales_and_returns(); - } else if (sales_table_name == "web_sales") { + } + + if (sales_table_name == "web_sales") { return generate_web_sales_and_returns(); - } else { - Fail("Unexpected sales table name: " + sales_table_name); } + + Fail("Unexpected sales table name: " + sales_table_name); } std::shared_ptr
TPCDSTableGenerator::generate_call_center(ds_key_t max_rows) const { @@ -362,10 +387,10 @@ std::shared_ptr
TPCDSTableGenerator::generate_call_center(ds_key_t max_ro auto call_center = CALL_CENTER_TBL{}; call_center.cc_closed_date_id = ds_key_t{-1}; - for (auto i = ds_key_t{0}; i < call_center_count; i++) { + for (auto call_center_index = ds_key_t{0}; call_center_index < call_center_count; ++call_center_index) { // mk_w_call_center needs a pointer to the previous result of mk_w_call_center to add "update entries" for the // same call center - mk_w_call_center(&call_center, call_center_first + i); + mk_w_call_center(&call_center, call_center_first + call_center_index); tpcds_row_stop(CALL_CENTER); call_center_builder.append_row( @@ -408,10 +433,12 @@ std::shared_ptr
TPCDSTableGenerator::generate_catalog_page(ds_key_t max_r catalog_page_column_names, static_cast(catalog_page_count)}; auto catalog_page = CATALOG_PAGE_TBL{}; - std::snprintf(catalog_page.cp_department, sizeof(catalog_page.cp_department), "%s", "DEPARTMENT"); - for (auto i = ds_key_t{0}; i < catalog_page_count; i++) { + const auto snprintf_rc = + std::snprintf(catalog_page.cp_department, sizeof(catalog_page.cp_department), "%s", "DEPARTMENT"); + Assert(snprintf_rc > 0, "Unexpected string to parse."); + for (auto catalog_page_index = ds_key_t{0}; catalog_page_index < catalog_page_count; ++catalog_page_index) { // need a pointer to the previous result of mk_w_catalog_page, because cp_department is only set once - mk_w_catalog_page(&catalog_page, catalog_page_first + i); + mk_w_catalog_page(&catalog_page, catalog_page_first + catalog_page_index); tpcds_row_stop(CATALOG_PAGE); catalog_page_builder.append_row(catalog_page.cp_catalog_page_sk, catalog_page.cp_catalog_page_id, @@ -439,17 +466,18 @@ std::pair, std::shared_ptr
> TPCDSTableGenerator::g auto catalog_returns_builder = TableBuilder{_benchmark_config->chunk_size, catalog_returns_column_types, catalog_returns_column_names}; - for (auto i = ds_key_t{0}; i < catalog_sales_count; i++) { + for (auto catalog_sale_index = ds_key_t{0}; catalog_sale_index < catalog_sales_count; ++catalog_sale_index) { auto catalog_sales = W_CATALOG_SALES_TBL{}; auto catalog_returns = W_CATALOG_RETURNS_TBL{}; - // modified call to mk_w_catalog_sales(&catalog_sales, catalog_sales_first + i, &catalog_returns, &was_returned); + // modified call to mk_w_catalog_sales(&catalog_sales, catalog_sales_first + catalog_sale_index, + // &catalog_returns, &was_returned); { - mk_w_catalog_sales_master(&catalog_sales, catalog_sales_first + i, 0); - int n_lineitems; + mk_w_catalog_sales_master(&catalog_sales, catalog_sales_first + catalog_sale_index, 0); + auto n_lineitems = int{0}; genrand_integer(&n_lineitems, DIST_UNIFORM, 4, 14, 0, CS_ORDER_NUMBER); - for (auto j = 1; j <= n_lineitems; j++) { - int was_returned = 0; + for (auto lineitem_index = int{0}; lineitem_index < n_lineitems; ++lineitem_index) { + auto was_returned = int{0}; mk_w_catalog_sales_detail(&catalog_sales, 0, &catalog_returns, &was_returned); if (catalog_sales_builder.row_count() < static_cast(max_rows)) { @@ -539,9 +567,10 @@ std::shared_ptr
TPCDSTableGenerator::generate_customer_address(ds_key_t m TableBuilder{_benchmark_config->chunk_size, customer_address_column_types, customer_address_column_names, static_cast(customer_address_count)}; - for (auto i = ds_key_t{0}; i < customer_address_count; i++) { - const auto customer_address = - call_dbgen_mk(customer_address_first + i); + for (auto customer_address_index = ds_key_t{0}; customer_address_index < customer_address_count; + ++customer_address_index) { + const auto customer_address = call_dbgen_mk( + customer_address_first + customer_address_index); customer_address_builder.append_row( customer_address.ca_addr_sk, customer_address.ca_addr_id, @@ -568,8 +597,8 @@ std::shared_ptr
TPCDSTableGenerator::generate_customer(ds_key_t max_rows) auto customer_builder = TableBuilder{_benchmark_config->chunk_size, customer_column_types, customer_column_names, static_cast(customer_count)}; - for (auto i = ds_key_t{0}; i < customer_count; i++) { - const auto customer = call_dbgen_mk(customer_first + i); + for (auto customer_index = ds_key_t{0}; customer_index < customer_count; ++customer_index) { + const auto customer = call_dbgen_mk(customer_first + customer_index); customer_builder.append_row( customer.c_customer_sk, customer.c_customer_id, resolve_key(C_CURRENT_CDEMO_SK, customer.c_current_cdemo_sk), @@ -597,10 +626,11 @@ std::shared_ptr
TPCDSTableGenerator::generate_customer_demographics(ds_ke TableBuilder{_benchmark_config->chunk_size, customer_demographics_column_types, customer_demographics_column_names, static_cast(customer_demographics_count)}; - for (auto i = ds_key_t{0}; i < customer_demographics_count; i++) { + for (auto customer_demographic = ds_key_t{0}; customer_demographic < customer_demographics_count; + ++customer_demographic) { const auto customer_demographics = call_dbgen_mk( - customer_demographics_first + i); + customer_demographics_first + customer_demographic); customer_demographics_builder.append_row( customer_demographics.cd_demo_sk, resolve_string(CD_GENDER, customer_demographics.cd_gender), @@ -623,8 +653,8 @@ std::shared_ptr
TPCDSTableGenerator::generate_date_dim(ds_key_t max_rows) auto date_builder = TableBuilder{_benchmark_config->chunk_size, date_column_types, date_column_names, static_cast(date_count)}; - for (auto i = ds_key_t{0}; i < date_count; i++) { - const auto date = call_dbgen_mk(date_first + i); + for (auto date_index = ds_key_t{0}; date_index < date_count; ++date_index) { + const auto date = call_dbgen_mk(date_first + date_index); auto quarter_name = pmr_string{std::to_string(date.d_year) + "Q" + std::to_string(date.d_qoy)}; @@ -661,10 +691,11 @@ std::shared_ptr
TPCDSTableGenerator::generate_household_demographics(ds_k TableBuilder{_benchmark_config->chunk_size, household_demographics_column_types, household_demographics_column_names, static_cast(household_demographics_count)}; - for (auto i = ds_key_t{0}; i < household_demographics_count; i++) { + for (auto household_demographic = ds_key_t{0}; household_demographic < household_demographics_count; + ++household_demographic) { const auto household_demographics = call_dbgen_mk( - household_demographics_first + i); + household_demographics_first + household_demographic); household_demographics_builder.append_row( household_demographics.hd_demo_sk, @@ -685,8 +716,9 @@ std::shared_ptr
TPCDSTableGenerator::generate_income_band(ds_key_t max_ro auto income_band_builder = TableBuilder{_benchmark_config->chunk_size, income_band_column_types, income_band_column_names, static_cast(income_band_count)}; - for (auto i = ds_key_t{0}; i < income_band_count; i++) { - const auto income_band = call_dbgen_mk(income_band_first + i); + for (auto income_band_index = ds_key_t{0}; income_band_index < income_band_count; ++income_band_index) { + const auto income_band = + call_dbgen_mk(income_band_first + income_band_index); income_band_builder.append_row(income_band.ib_income_band_id, resolve_integer(IB_LOWER_BOUND, income_band.ib_lower_bound), @@ -703,8 +735,9 @@ std::shared_ptr
TPCDSTableGenerator::generate_inventory(ds_key_t max_rows auto inventory_builder = TableBuilder{_benchmark_config->chunk_size, inventory_column_types, inventory_column_names, static_cast(inventory_count)}; - for (auto i = ds_key_t{0}; i < inventory_count; i++) { - const auto inventory = call_dbgen_mk(inventory_first + i); + for (auto inventory_index = ds_key_t{0}; inventory_index < inventory_count; ++inventory_index) { + const auto inventory = + call_dbgen_mk(inventory_first + inventory_index); inventory_builder.append_row(inventory.inv_date_sk, inventory.inv_item_sk, inventory.inv_warehouse_sk, resolve_integer(INV_QUANTITY_ON_HAND, inventory.inv_quantity_on_hand)); @@ -720,8 +753,8 @@ std::shared_ptr
TPCDSTableGenerator::generate_item(ds_key_t max_rows) con auto item_builder = TableBuilder{_benchmark_config->chunk_size, item_column_types, item_column_names, static_cast(item_count)}; - for (auto i = ds_key_t{0}; i < item_count; i++) { - const auto item = call_dbgen_mk(item_first + i); + for (auto item_index = ds_key_t{0}; item_index < item_count; ++item_index) { + const auto item = call_dbgen_mk(item_first + item_index); item_builder.append_row( item.i_item_sk, item.i_item_id, resolve_date_id(I_REC_START_DATE_ID, item.i_rec_start_date_id), @@ -747,8 +780,9 @@ std::shared_ptr
TPCDSTableGenerator::generate_promotion(ds_key_t max_rows auto promotion_builder = TableBuilder{_benchmark_config->chunk_size, promotion_column_types, promotion_column_names, static_cast(promotion_count)}; - for (auto i = ds_key_t{0}; i < promotion_count; i++) { - const auto promotion = call_dbgen_mk(promotion_first + i); + for (auto promotion_index = ds_key_t{0}; promotion_index < promotion_count; ++promotion_index) { + const auto promotion = + call_dbgen_mk(promotion_first + promotion_index); promotion_builder.append_row( promotion.p_promo_sk, promotion.p_promo_id, resolve_key(P_START_DATE_ID, promotion.p_start_date_id), @@ -777,8 +811,8 @@ std::shared_ptr
TPCDSTableGenerator::generate_reason(ds_key_t max_rows) c auto reason_builder = TableBuilder{_benchmark_config->chunk_size, reason_column_types, reason_column_names, static_cast(reason_count)}; - for (auto i = ds_key_t{0}; i < reason_count; i++) { - const auto reason = call_dbgen_mk(reason_first + i); + for (auto reason_index = ds_key_t{0}; reason_index < reason_count; ++reason_index) { + const auto reason = call_dbgen_mk(reason_first + reason_index); reason_builder.append_row(reason.r_reason_sk, reason.r_reason_id, resolve_string(R_REASON_DESCRIPTION, reason.r_reason_description)); @@ -794,8 +828,9 @@ std::shared_ptr
TPCDSTableGenerator::generate_ship_mode(ds_key_t max_rows auto ship_mode_builder = TableBuilder{_benchmark_config->chunk_size, ship_mode_column_types, ship_mode_column_names, static_cast(ship_mode_count)}; - for (auto i = ds_key_t{0}; i < ship_mode_count; i++) { - const auto ship_mode = call_dbgen_mk(ship_mode_first + i); + for (auto ship_mode_index = ds_key_t{0}; ship_mode_index < ship_mode_count; ++ship_mode_index) { + const auto ship_mode = + call_dbgen_mk(ship_mode_first + ship_mode_index); ship_mode_builder.append_row(ship_mode.sm_ship_mode_sk, ship_mode.sm_ship_mode_id, @@ -814,8 +849,8 @@ std::shared_ptr
TPCDSTableGenerator::generate_store(ds_key_t max_rows) co auto store_builder = TableBuilder{_benchmark_config->chunk_size, store_column_types, store_column_names, static_cast(store_count)}; - for (auto i = ds_key_t{0}; i < store_count; i++) { - const auto store = call_dbgen_mk(store_first + i); + for (auto store_index = ds_key_t{0}; store_index < store_count; ++store_index) { + const auto store = call_dbgen_mk(store_first + store_index); store_builder.append_row( store.store_sk, store.store_id, @@ -856,18 +891,18 @@ std::pair, std::shared_ptr
> TPCDSTableGenerator::g auto store_returns_builder = TableBuilder{_benchmark_config->chunk_size, store_returns_column_types, store_returns_column_names}; - for (auto i = ds_key_t{0}; i < store_sales_count; i++) { + for (auto store_sale = ds_key_t{0}; store_sale < store_sales_count; ++store_sale) { auto store_sales = W_STORE_SALES_TBL{}; auto store_returns = W_STORE_RETURNS_TBL{}; - // modified call to mk_w_store_sales(&store_sales, store_sales_first + i, &store_returns, &was_returned) + // modified call to mk_w_store_sales(&store_sales, store_sales_first + store_sale, &store_returns, &was_returned) { - mk_w_store_sales_master(&store_sales, store_sales_first + i, 0); + mk_w_store_sales_master(&store_sales, store_sales_first + store_sale, 0); - int n_lineitems; + auto n_lineitems = int{0}; genrand_integer(&n_lineitems, DIST_UNIFORM, 8, 16, 0, SS_TICKET_NUMBER); - for (auto j = 1; j <= n_lineitems; j++) { - int was_returned = 0; + for (auto lineitem_index = int{0}; lineitem_index < n_lineitems; ++lineitem_index) { + auto was_returned = int{0}; mk_w_store_sales_detail(&store_sales, 0, &store_returns, &was_returned); if (store_sales_builder.row_count() < static_cast(max_rows)) { @@ -936,8 +971,8 @@ std::shared_ptr
TPCDSTableGenerator::generate_time_dim(ds_key_t max_rows) auto time_builder = TableBuilder{_benchmark_config->chunk_size, time_column_types, time_column_names, static_cast(time_count)}; - for (auto i = ds_key_t{0}; i < time_count; i++) { - const auto time = call_dbgen_mk(time_first + i); + for (auto time_index = ds_key_t{0}; time_index < time_count; ++time_index) { + const auto time = call_dbgen_mk(time_first + time_index); time_builder.append_row(time.t_time_sk, time.t_time_id, resolve_integer(T_TIME, time.t_time), resolve_integer(T_HOUR, time.t_hour), resolve_integer(T_MINUTE, time.t_minute), @@ -956,8 +991,9 @@ std::shared_ptr
TPCDSTableGenerator::generate_warehouse(ds_key_t max_rows auto warehouse_builder = TableBuilder{_benchmark_config->chunk_size, warehouse_column_types, warehouse_column_names, static_cast(warehouse_count)}; - for (auto i = ds_key_t{0}; i < warehouse_count; i++) { - const auto warehouse = call_dbgen_mk(warehouse_first + i); + for (auto warehouse_index = ds_key_t{0}; warehouse_index < warehouse_count; ++warehouse_index) { + const auto warehouse = + call_dbgen_mk(warehouse_first + warehouse_index); warehouse_builder.append_row( warehouse.w_warehouse_sk, warehouse.w_warehouse_id, @@ -986,8 +1022,8 @@ std::shared_ptr
TPCDSTableGenerator::generate_web_page(ds_key_t max_rows) auto web_page_builder = TableBuilder{_benchmark_config->chunk_size, web_page_column_types, web_page_column_names, static_cast(web_page_count)}; - for (auto i = ds_key_t{0}; i < web_page_count; i++) { - const auto web_page = call_dbgen_mk(web_page_first + i); + for (auto web_page_index = ds_key_t{0}; web_page_index < web_page_count; ++web_page_index) { + const auto web_page = call_dbgen_mk(web_page_first + web_page_index); web_page_builder.append_row( web_page.wp_page_sk, web_page.wp_page_id, resolve_date_id(WP_REC_START_DATE_ID, web_page.wp_rec_start_date_id), @@ -1014,18 +1050,18 @@ std::pair, std::shared_ptr
> TPCDSTableGenerator::g auto web_returns_builder = TableBuilder{_benchmark_config->chunk_size, web_returns_column_types, web_returns_column_names}; - for (auto i = ds_key_t{0}; i < web_sales_count; i++) { + for (auto web_sales_index = ds_key_t{0}; web_sales_index < web_sales_count; ++web_sales_index) { auto web_sales = W_WEB_SALES_TBL{}; auto web_returns = W_WEB_RETURNS_TBL{}; - // modified call to mk_w_web_sales(&web_sales, web_sales_first + i, &web_returns, &was_returned); + // modified call to mk_w_web_sales(&web_sales, web_sales_first + web_sales_index, &web_returns, &was_returned); { - mk_w_web_sales_master(&web_sales, web_sales_first + i, 0); + mk_w_web_sales_master(&web_sales, web_sales_first + web_sales_index, 0); - int n_lineitems; + auto n_lineitems = int{0}; genrand_integer(&n_lineitems, DIST_UNIFORM, 8, 16, 9, WS_ORDER_NUMBER); - for (auto j = 1; j <= n_lineitems; j++) { - int was_returned = 0; + for (auto lineitem_index = int{0}; lineitem_index < n_lineitems; ++lineitem_index) { + auto was_returned = 0; mk_w_web_sales_detail(&web_sales, 0, &web_returns, &was_returned, 0); if (web_sales_builder.row_count() < static_cast(max_rows)) { @@ -1112,10 +1148,11 @@ std::shared_ptr
TPCDSTableGenerator::generate_web_site(ds_key_t max_rows) auto web_site = W_WEB_SITE_TBL{}; static_assert(sizeof(web_site.web_class) == 51); - std::snprintf(web_site.web_class, sizeof(web_site.web_class), "%s", "Unknown"); - for (auto i = ds_key_t{0}; i < web_site_count; i++) { + const auto snprintf_rc = std::snprintf(web_site.web_class, sizeof(web_site.web_class), "%s", "Unknown"); + Assert(snprintf_rc > 0, "Unexpected string to parse."); + for (auto web_site_index = ds_key_t{0}; web_site_index < web_site_count; ++web_site_index) { // mk_w_web_site needs a pointer to the previous result because it expects values set previously to still be there - mk_w_web_site(&web_site, web_site_first + i); + mk_w_web_site(&web_site, web_site_first + web_site_index); tpcds_row_stop(WEB_SITE); web_site_builder.append_row( diff --git a/src/benchmarklib/tpch/tpch_benchmark_item_runner.cpp b/src/benchmarklib/tpch/tpch_benchmark_item_runner.cpp index 9216293c58..8dac67ac89 100644 --- a/src/benchmarklib/tpch/tpch_benchmark_item_runner.cpp +++ b/src/benchmarklib/tpch/tpch_benchmark_item_runner.cpp @@ -366,8 +366,8 @@ std::string TPCHBenchmarkItemRunner::_build_query(const BenchmarkItemID item_id) parameters.emplace_back("'Brand#"s + std::to_string(brand) + "'"); parameters.emplace_back("'"s + partial_type + "%'"); - for (auto i = 0; i < 8; ++i) { - parameters.emplace_back(std::to_string(sizes_copy[i])); + for (auto parameter_index = size_t{0}; parameter_index < 8; ++parameter_index) { + parameters.emplace_back(std::to_string(sizes_copy[parameter_index])); } break; } @@ -440,12 +440,11 @@ std::string TPCHBenchmarkItemRunner::_build_query(const BenchmarkItemID item_id) std::shuffle(country_codes_copy.begin(), country_codes_copy.end(), random_engine); // We need the same country code twice - have a look at the query - for (auto i = 0; i < 7; ++i) { - parameters.emplace_back("'"s + std::to_string(country_codes_copy[i]) + "'"); + for (auto parameter_index = size_t{0}; parameter_index < 7; ++parameter_index) { + parameters.emplace_back("'"s + std::to_string(country_codes_copy[parameter_index]) + "'"); } - - for (auto i = 0; i < 7; ++i) { - parameters.emplace_back("'"s + std::to_string(country_codes_copy[i]) + "'"); + for (auto parameter_index = size_t{0}; parameter_index < 7; ++parameter_index) { + parameters.emplace_back("'"s + std::to_string(country_codes_copy[parameter_index]) + "'"); } break; } @@ -513,18 +512,18 @@ std::string TPCHBenchmarkItemRunner::_substitute_placeholders(const BenchmarkIte std::stringstream sql; sql << "EXECUTE TPCH" << (item_id + 1) << " (" << boost::algorithm::join(parameter_values, ", ") << ")"; return sql.str(); - } else { - // Take the SQL query (from tpch_queries.cpp) and replace one placeholder (question mark) after another - auto query_template = std::string{tpch_queries.find(item_id + 1)->second}; - - for (const auto& parameter_value : parameter_values) { - boost::replace_first(query_template, "?", parameter_value); - } + } - Assert(query_template.find('?') == std::string::npos, "Unreplaced Placeholder"); + // Take the SQL query (from tpch_queries.cpp) and replace one placeholder (question mark) after another + auto query_template = std::string{tpch_queries.find(item_id + 1)->second}; - return query_template; + for (const auto& parameter_value : parameter_values) { + boost::replace_first(query_template, "?", parameter_value); } + + Assert(query_template.find('?') == std::string::npos, "Unreplaced Placeholder"); + + return query_template; } } // namespace hyrise diff --git a/src/benchmarklib/tpch/tpch_table_generator.cpp b/src/benchmarklib/tpch/tpch_table_generator.cpp index 532e144c77..f307ce7dc9 100644 --- a/src/benchmarklib/tpch/tpch_table_generator.cpp +++ b/src/benchmarklib/tpch/tpch_table_generator.cpp @@ -15,8 +15,8 @@ extern "C" { #include "table_builder.hpp" #include "utils/timer.hpp" -extern char** asc_date; -extern seed_t seed[]; // NOLINT +extern const char** asc_date; // NOLINT +extern seed_t seed[]; // NOLINT #pragma clang diagnostic ignored "-Wshorten-64-to-32" #pragma clang diagnostic ignored "-Wfloat-conversion" @@ -51,14 +51,12 @@ const auto region_column_types = boost::hana::tuple< int32_t, pmr_stri const auto region_column_names = boost::hana::make_tuple("r_regionkey", "r_name", "r_comment"); // NOLINT // clang-format on -std::unordered_map> tpch_table_to_dbgen_id = { - {TPCHTable::Part, PART}, {TPCHTable::PartSupp, PSUPP}, {TPCHTable::Supplier, SUPP}, - {TPCHTable::Customer, CUST}, {TPCHTable::Orders, ORDER}, {TPCHTable::LineItem, LINE}, - {TPCHTable::Nation, NATION}, {TPCHTable::Region, REGION}}; +const std::unordered_map> tpch_table_to_dbgen_id = { + {TPCHTable::Part, PART}, {TPCHTable::PartSupp, PSUPP}, {TPCHTable::Supplier, SUPP}, {TPCHTable::Customer, CUST}, + {TPCHTable::Orders, ORDER}, {TPCHTable::LineItem, LINE}, {TPCHTable::Nation, NATION}, {TPCHTable::Region, REGION}}; template -DSSType call_dbgen_mk(size_t idx, MKRetType (*mk_fn)(DSS_HUGE, DSSType* val, Args...), TPCHTable table, - Args... args) { +DSSType call_dbgen_mk(size_t idx, MKRetType (*mk_fn)(DSS_HUGE, DSSType* val, Args...), TPCHTable table, Args... args) { /** * Preserve calling scheme (row_start(); mk...(); row_stop(); as in dbgen's gen_tbl()) */ @@ -97,7 +95,7 @@ void dbgen_cleanup() { if (asc_date) { for (size_t idx = 0; idx < TOTDATE; ++idx) { - free(asc_date[idx]); // NOLINT + free((void*)asc_date[idx]); // NOLINT } free(asc_date); // NOLINT } @@ -108,7 +106,7 @@ void dbgen_cleanup() { namespace hyrise { -std::unordered_map tpch_table_names = { +const std::unordered_map tpch_table_names = { {TPCHTable::Part, "part"}, {TPCHTable::PartSupp, "partsupp"}, {TPCHTable::Supplier, "supplier"}, {TPCHTable::Customer, "customer"}, {TPCHTable::Orders, "orders"}, {TPCHTable::LineItem, "lineitem"}, {TPCHTable::Nation, "nation"}, {TPCHTable::Region, "region"}}; diff --git a/src/benchmarklib/tpch/tpch_table_generator.hpp b/src/benchmarklib/tpch/tpch_table_generator.hpp index 9d9dde9db3..2eec7b19af 100644 --- a/src/benchmarklib/tpch/tpch_table_generator.hpp +++ b/src/benchmarklib/tpch/tpch_table_generator.hpp @@ -20,7 +20,7 @@ class Table; enum class TPCHTable { Part, PartSupp, Supplier, Customer, Orders, LineItem, Nation, Region }; -extern std::unordered_map tpch_table_names; +extern const std::unordered_map tpch_table_names; /** * Wrapper around the official tpch-dbgen tool, making it directly generate hyrise::Table instances without having diff --git a/src/bin/console/console.cpp b/src/bin/console/console.cpp index 36da3dced3..0436e76117 100644 --- a/src/bin/console/console.cpp +++ b/src/bin/console/console.cpp @@ -73,15 +73,15 @@ namespace { * The known caveats of goto/longjmp aside, this will probably also cause problems (queries continuing to run in the * background) when the scheduler/multithreading is enabled. */ -sigjmp_buf jmp_env; +sigjmp_buf jmp_env; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) // Returns a string containing a timestamp of the current date and time std::string current_timestamp() { - auto t = std::time(nullptr); - auto tm = *std::localtime(&t); + auto time = std::time(nullptr); + const auto local_time = *std::localtime(&time); // NOLINT(concurrency-mt-unsafe) - not called concurrently std::ostringstream oss; - oss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S"); + oss << std::put_time(&local_time, "%Y-%m-%d %H:%M:%S"); return oss.str(); } @@ -122,7 +122,6 @@ namespace hyrise { Console::Console() : _prompt("> "), - _multiline_input(""), _out(std::cout.rdbuf()), _log("console.log", std::ios_base::app | std::ios_base::out), _verbose(false), @@ -394,7 +393,7 @@ void Console::out(const std::shared_ptr& table, const PrintFlags fl stream.str(stream_backup); static bool pagination_disabled = false; - if (!fits_on_one_page && !std::getenv("TERM") && !pagination_disabled) { + if (!fits_on_one_page && !std::getenv("TERM") && !pagination_disabled) { // NOLINT(concurrency-mt-unsafe) out("Your TERM environment variable is not set - most likely because you are running the console from an IDE. " "Pagination is disabled.\n\n"); pagination_disabled = true; @@ -555,7 +554,7 @@ int Console::_load_table(const std::string& args) { const auto filepath = std::filesystem::path{arguments.at(0)}; const auto tablename = arguments.size() >= 2 ? arguments.at(1) : std::string{filepath.stem()}; - out("Loading " + std::string(filepath) + " into table \"" + tablename + "\"\n"); + out("Loading " + filepath.string() + " into table \"" + tablename + "\"\n"); if (Hyrise::get().storage_manager.has_table(tablename)) { out("Table \"" + tablename + "\" already existed. Replacing it.\n"); @@ -720,10 +719,8 @@ int Console::_visualize(const std::string& input) { const auto sql = boost::algorithm::join(input_words, " "); // If no SQL is provided, use the last execution. Else, create a new pipeline. - if (!sql.empty()) { - if (!_initialize_pipeline(sql)) { - return ReturnCode::Error; - } + if (!sql.empty() && !_initialize_pipeline(sql)) { + return ReturnCode::Error; } // If there is no pipeline (i.e., neither was SQL passed in with the visualize command, @@ -794,6 +791,7 @@ int Console::_visualize(const std::string& input) { } break; } + // NOLINTBEGIN(concurrency-mt-unsafe) - system() is not thread-safe, but it's not used concurrently here. auto scripts_dir = std::string{"./scripts/"}; auto ret = system((scripts_dir + "planviz/is_iterm2.sh 2>/dev/null").c_str()); if (ret != 0) { @@ -812,6 +810,7 @@ int Console::_visualize(const std::string& input) { auto cmd = scripts_dir + "/planviz/imgcat.sh " + img_filename; ret = system(cmd.c_str()); Assert(ret == 0, "Printing the image using ./scripts/imgcat.sh failed."); + // NOLINTEND(concurrency-mt-unsafe) return ReturnCode::Ok; } @@ -852,7 +851,9 @@ int Console::_exec_script(const std::string& script_file) { if (!script.good()) { out("Error: Script file '" + filepath + "' does not exist.\n"); return ReturnCode::Error; - } else if (!is_regular_file(filepath)) { + } + + if (!is_regular_file(filepath)) { out("Error: '" + filepath + "' is not a regular file.\n"); return ReturnCode::Error; } @@ -1000,12 +1001,11 @@ char* Console::_command_generator(const char* text, int state, const std::vector it = commands.begin(); } - while (it != commands.end()) { + for (; it != commands.end(); ++it) { const auto& command = *it; - ++it; if (command.find(text) != std::string::npos) { auto completion = new char[command.size()]; // NOLINT (legacy API) - snprintf(completion, command.size() + 1, "%s", command.c_str()); + static_cast(snprintf(completion, command.size() + 1, "%s", command.c_str())); return completion; } } @@ -1043,7 +1043,7 @@ int main(int argc, char** argv) { auto& console = hyrise::Console::get(); // Bind CTRL-C to behaviour specified in Console::handle_signal - std::signal(SIGINT, &hyrise::Console::handle_signal); + static_cast(std::signal(SIGINT, &hyrise::Console::handle_signal)); console.set_prompt("> "); console.set_logfile("console.log"); diff --git a/src/bin/console/pagination.cpp b/src/bin/console/pagination.cpp index 264dbb4a4d..36361f0b0c 100644 --- a/src/bin/console/pagination.cpp +++ b/src/bin/console/pagination.cpp @@ -4,7 +4,7 @@ #include #include -constexpr auto CURSES_CTRL_C = (uint('c') & 31u); +constexpr auto CURSES_CTRL_C = static_cast('c') & uint32_t{31}; namespace hyrise { diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index cdf928253e..4bb9f34ab7 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -652,6 +652,7 @@ set( set( LIBRARIES + compact_vector lz4 magic_enum sqlparser @@ -707,14 +708,13 @@ if(NOT APPLE) # Add the jemalloc headers to Hyrise so that we can use jemalloc-specific functions. # We need to use a path relative to CMAKE_CURRENT_BINARY_DIR instead of using CMAKE_BINARY_DIR because Hyrise might # not be the top-level CMake project (e.g., if it is used as a submodule in a Hyrise plugin repository). - target_include_directories(hyrise_impl PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/../../third_party/jemalloc/include) + target_include_directories(hyrise_impl SYSTEM PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/../../third_party/jemalloc/include) endif() target_link_libraries_system( hyrise_impl ${BOOST_LIBS} - compact_vector cpp-btree cxxopts flat-hash-map diff --git a/src/lib/cost_estimation/abstract_cost_estimator.cpp b/src/lib/cost_estimation/abstract_cost_estimator.cpp index c574a85de6..3453465876 100644 --- a/src/lib/cost_estimation/abstract_cost_estimator.cpp +++ b/src/lib/cost_estimation/abstract_cost_estimator.cpp @@ -43,15 +43,15 @@ Cost AbstractCostEstimator::estimate_plan_cost(const std::shared_ptrleft_input()) { - bfs_queue.push(current_node->left_input()); - } - - if (current_node->right_input()) { - bfs_queue.push(current_node->right_input()); - } + } + + cost += estimate_node_cost(current_node); + if (current_node->left_input()) { + bfs_queue.push(current_node->left_input()); + } + + if (current_node->right_input()) { + bfs_queue.push(current_node->right_input()); } } diff --git a/src/lib/expression/abstract_expression.cpp b/src/lib/expression/abstract_expression.cpp index 72398d22c8..1e6a273e13 100644 --- a/src/lib/expression/abstract_expression.cpp +++ b/src/lib/expression/abstract_expression.cpp @@ -100,9 +100,9 @@ std::string AbstractExpression::_enclose_argument(const AbstractExpression& argu if (static_cast>(argument._precedence()) >= static_cast>(_precedence())) { return "("s + argument.description(mode) + ")"; - } else { - return argument.description(mode); } + + return argument.description(mode); } } // namespace hyrise diff --git a/src/lib/expression/evaluation/expression_evaluator.cpp b/src/lib/expression/evaluation/expression_evaluator.cpp index d1cfbe8688..d0acd01f2d 100644 --- a/src/lib/expression/evaluation/expression_evaluator.cpp +++ b/src/lib/expression/evaluation/expression_evaluator.cpp @@ -115,18 +115,19 @@ std::shared_ptr rewrite_in_list_expression(const InExpressio } std::shared_ptr rewritten_expression; + const auto type_compatible_element_count = type_compatible_elements.size(); if (in_expression.is_negated()) { // a NOT IN (1,2,3) --> a != 1 AND a != 2 AND a != 3 rewritten_expression = not_equals_(in_expression.value(), type_compatible_elements.front()); - for (auto element_idx = size_t{1}; element_idx < type_compatible_elements.size(); ++element_idx) { + for (auto element_idx = size_t{1}; element_idx < type_compatible_element_count; ++element_idx) { const auto equals_element = not_equals_(in_expression.value(), type_compatible_elements[element_idx]); rewritten_expression = and_(rewritten_expression, equals_element); } } else { // a IN (1,2,3) --> a == 1 OR a == 2 OR a == 3 rewritten_expression = equals_(in_expression.value(), type_compatible_elements.front()); - for (auto element_idx = size_t{1}; element_idx < type_compatible_elements.size(); ++element_idx) { + for (auto element_idx = size_t{1}; element_idx < type_compatible_element_count; ++element_idx) { const auto equals_element = equals_(in_expression.value(), type_compatible_elements[element_idx]); rewritten_expression = or_(rewritten_expression, equals_element); } @@ -363,14 +364,15 @@ ExpressionEvaluator::_evaluate_is_null_expression(con pmr_vector result_values; _resolve_to_expression_result_view(*expression.operand(), [&](const auto& view) { - result_values.resize(view.size()); + const auto view_size = static_cast(view.size()); + result_values.resize(view_size); if (expression.predicate_condition == PredicateCondition::IsNull) { - for (auto chunk_offset = ChunkOffset{0}; chunk_offset < static_cast(view.size()); ++chunk_offset) { + for (auto chunk_offset = ChunkOffset{0}; chunk_offset < view_size; ++chunk_offset) { result_values[chunk_offset] = view.is_null(chunk_offset); } } else { // PredicateCondition::IsNotNull - for (auto chunk_offset = ChunkOffset{0}; chunk_offset < static_cast(view.size()); ++chunk_offset) { + for (auto chunk_offset = ChunkOffset{0}; chunk_offset < view_size; ++chunk_offset) { result_values[chunk_offset] = !view.is_null(chunk_offset); } } @@ -463,13 +465,13 @@ ExpressionEvaluator::_evaluate_in_expression(const In right_values_idx++; } - result_values.resize(left_view.size(), in_expression.is_negated()); + const auto left_view_size = static_cast(left_view.size()); + result_values.resize(left_view_size, in_expression.is_negated()); if (left_view.is_nullable()) { - result_nulls.resize(left_view.size()); + result_nulls.resize(left_view_size); } - for (auto chunk_offset = ChunkOffset{0}; chunk_offset < static_cast(left_view.size()); - ++chunk_offset) { + for (auto chunk_offset = ChunkOffset{0}; chunk_offset < left_view_size; ++chunk_offset) { if (left_view.is_nullable() && left_view.is_null(chunk_offset)) { result_nulls[chunk_offset] = true; continue; @@ -493,8 +495,9 @@ ExpressionEvaluator::_evaluate_in_expression(const In // Nope, it is a list with diverse types - falling back to rewrite of expression: return evaluate_expression_to_result(*rewrite_in_list_expression(in_expression)); + } - } else if (right_expression.type == ExpressionType::PQPSubquery) { + if (right_expression.type == ExpressionType::PQPSubquery) { const auto* subquery_expression = dynamic_cast(&right_expression); Assert(subquery_expression, "Expected PQPSubqueryExpression"); @@ -515,7 +518,7 @@ ExpressionEvaluator::_evaluate_in_expression(const In const auto result_size = _result_size(left_view.size(), subquery_results.size()); result_values.resize(result_size); - // TODO(moritz) The InExpression doesn't in all cases need to return a nullable + // TODO(anybody): The InExpression does not, in all cases, need to return a nullable. result_nulls.resize(result_size); for (auto chunk_offset = ChunkOffset{0}; chunk_offset < static_cast(result_size); @@ -526,9 +529,9 @@ ExpressionEvaluator::_evaluate_in_expression(const In const auto& list = *subquery_results[subquery_results.size() == 1 ? 0 : chunk_offset]; auto list_contains_null = false; + const auto list_size = static_cast(list.size()); - for (auto list_element_idx = ChunkOffset{0}; list_element_idx < static_cast(list.size()); - ++list_element_idx) { + for (auto list_element_idx = ChunkOffset{0}; list_element_idx < list_size; ++list_element_idx) { // `a IN (x,y,z)` is supposed to have the same semantics as `a = x OR a = y OR a = z`, so we use `Equals` // here as well. EqualsEvaluator{}(result_values[chunk_offset], list.value(list_element_idx), @@ -726,19 +729,18 @@ ExpressionEvaluator::_evaluate_exists_expression(cons const auto subquery_result_tables = _evaluate_subquery_expression_to_tables(*subquery_expression); - pmr_vector result_values(subquery_result_tables.size()); + const auto subquery_result_table_count = static_cast(subquery_result_tables.size()); + pmr_vector result_values(subquery_result_table_count); switch (exists_expression.exists_expression_type) { case ExistsExpressionType::Exists: - for (auto chunk_offset = ChunkOffset{0}; chunk_offset < static_cast(subquery_result_tables.size()); - ++chunk_offset) { + for (auto chunk_offset = ChunkOffset{0}; chunk_offset < subquery_result_table_count; ++chunk_offset) { result_values[chunk_offset] = subquery_result_tables[chunk_offset]->row_count() > 0; } break; case ExistsExpressionType::NotExists: - for (auto chunk_offset = ChunkOffset{0}; chunk_offset < static_cast(subquery_result_tables.size()); - ++chunk_offset) { + for (auto chunk_offset = ChunkOffset{0}; chunk_offset < subquery_result_table_count; ++chunk_offset) { result_values[chunk_offset] = subquery_result_tables[chunk_offset]->row_count() == 0; } break; @@ -775,10 +777,10 @@ std::shared_ptr> ExpressionEvaluator::_evaluate_value_o pmr_vector nulls{}; nulls.emplace_back(true); return std::make_shared>(pmr_vector{{Result{}}}, nulls); - } else { - Assert(value.type() == typeid(Result), "Can't evaluate ValueExpression to requested type Result"); - return std::make_shared>(pmr_vector{{boost::get(value)}}); } + + Assert(value.type() == typeid(Result), "Can't evaluate ValueExpression to requested type Result"); + return std::make_shared>(pmr_vector{{boost::get(value)}}); } template @@ -794,9 +796,8 @@ std::shared_ptr> ExpressionEvaluator::_evaluate_functio case FunctionType::Concatenate: return _evaluate_concatenate(expression.arguments); } - } else { - Fail("Function can only be evaluated to a string"); } + Fail("Function can only be evaluated to a string"); } Fail("Invalid enum value"); } @@ -847,7 +848,7 @@ std::shared_ptr> ExpressionEvaluator::_evaluate_extract auto values = pmr_vector(from_result.size()); from_result.as_view([&](const auto& from_view) { - const auto from_view_size = from_view.size(); + const auto from_view_size = static_cast(from_view.size()); for (auto chunk_offset = ChunkOffset{0}; chunk_offset < from_view_size; ++chunk_offset) { if (!from_view.is_null(chunk_offset)) { const auto& value = std::string{from_view.value(chunk_offset)}; @@ -877,9 +878,9 @@ std::shared_ptr> ExpressionEvaluator::_evaluate_unary_m using ArgumentType = typename std::decay_t::Type; if constexpr (!std::is_same_v && std::is_same_v) { - values.resize(argument_result.size()); - for (auto chunk_offset = ChunkOffset{0}; chunk_offset < static_cast(argument_result.size()); - ++chunk_offset) { + const auto argument_result_count = static_cast(argument_result.size()); + values.resize(argument_result_count); + for (auto chunk_offset = ChunkOffset{0}; chunk_offset < argument_result_count; ++chunk_offset) { // NOTE: Actual negation happens in this line values[chunk_offset] = -argument_result.values[chunk_offset]; } @@ -901,12 +902,12 @@ std::shared_ptr> ExpressionEvaluator::_evaluate_subquer // One ExpressionResult per row. Each ExpressionResult should have a single value const auto subquery_results = _prune_tables_to_expression_results(subquery_result_tables); - pmr_vector result_values(subquery_results.size()); - pmr_vector result_nulls; + const auto subquery_result_count = static_cast(subquery_results.size()); + auto result_values = pmr_vector(subquery_result_count); + auto result_nulls = pmr_vector{}; // Materialize values - for (auto chunk_offset = ChunkOffset{0}; chunk_offset < static_cast(subquery_results.size()); - ++chunk_offset) { + for (auto chunk_offset = ChunkOffset{0}; chunk_offset < subquery_result_count; ++chunk_offset) { Assert(subquery_results[chunk_offset]->size() == 1, "Expected precisely one row to be returned from SelectExpression"); result_values[chunk_offset] = subquery_results[chunk_offset]->value(0); @@ -917,9 +918,8 @@ std::shared_ptr> ExpressionEvaluator::_evaluate_subquer [&](const auto& expression_result) { return expression_result->is_nullable(); }); if (nullable) { - result_nulls.resize(subquery_results.size()); - for (auto chunk_offset = ChunkOffset{0}; chunk_offset < static_cast(subquery_results.size()); - ++chunk_offset) { + result_nulls.resize(subquery_result_count); + for (auto chunk_offset = ChunkOffset{0}; chunk_offset < subquery_result_count; ++chunk_offset) { result_nulls[chunk_offset] = subquery_results[chunk_offset]->is_null(0); } } @@ -937,10 +937,10 @@ std::vector> ExpressionEvaluator::_evaluate_subquer DebugAssert(table_iter != _uncorrelated_subquery_results->cend(), "All uncorrelated PQPSubqueryExpression should be cached if cache is present"); return {table_iter->second}; - } else { - // If a subquery is uncorrelated, it has the same result for all rows, so we just execute it for the first row - return {_evaluate_subquery_expression_for_row(expression, ChunkOffset{0})}; } + + // If a subquery is uncorrelated, it has the same result for all rows, so we just execute it for the first row + return {_evaluate_subquery_expression_for_row(expression, ChunkOffset{0})}; } // Make sure all columns (i.e. segments) that are parameters are materialized @@ -979,7 +979,8 @@ std::shared_ptr ExpressionEvaluator::_evaluate_subquery_expression_ std::unordered_map parameters; - for (auto parameter_idx = size_t{0}; parameter_idx < expression.parameters.size(); ++parameter_idx) { + const auto expression_parameter_count = expression.parameters.size(); + for (auto parameter_idx = size_t{0}; parameter_idx < expression_parameter_count; ++parameter_idx) { const auto& parameter_id_column_id = expression.parameters[parameter_idx]; const auto parameter_id = parameter_id_column_id.first; const auto column_id = parameter_id_column_id.second; @@ -1311,48 +1312,49 @@ std::shared_ptr> ExpressionEvaluator::_evaluate_binary_ } template -void ExpressionEvaluator::_resolve_to_expression_result_view(const AbstractExpression& expression, const Functor& fn) { +void ExpressionEvaluator::_resolve_to_expression_result_view(const AbstractExpression& expression, + const Functor& functor) { _resolve_to_expression_result(expression, - [&](const auto& result) { result.as_view([&](const auto& view) { fn(view); }); }); + [&](const auto& result) { result.as_view([&](const auto& view) { functor(view); }); }); } template void ExpressionEvaluator::_resolve_to_expression_result_views(const AbstractExpression& left_expression, const AbstractExpression& right_expression, - const Functor& fn) { - _resolve_to_expression_results(left_expression, right_expression, - [&](const auto& left_result, const auto& right_result) { - left_result.as_view([&](const auto& left_view) { - right_result.as_view([&](const auto& right_view) { fn(left_view, right_view); }); - }); - }); + const Functor& functor) { + _resolve_to_expression_results( + left_expression, right_expression, [&](const auto& left_result, const auto& right_result) { + left_result.as_view([&](const auto& left_view) { + right_result.as_view([&](const auto& right_view) { functor(left_view, right_view); }); + }); + }); } template void ExpressionEvaluator::_resolve_to_expression_results(const AbstractExpression& left_expression, const AbstractExpression& right_expression, - const Functor& fn) { + const Functor& functor) { _resolve_to_expression_result(left_expression, [&](const auto& left_result) { - _resolve_to_expression_result(right_expression, [&](const auto& right_result) { fn(left_result, right_result); }); + _resolve_to_expression_result(right_expression, + [&](const auto& right_result) { functor(left_result, right_result); }); }); } template -void ExpressionEvaluator::_resolve_to_expression_result(const AbstractExpression& expression, const Functor& fn) { +void ExpressionEvaluator::_resolve_to_expression_result(const AbstractExpression& expression, const Functor& functor) { Assert(expression.type != ExpressionType::List, "Can't resolve ListExpression to ExpressionResult"); if (expression.data_type() == DataType::Null) { // resolve_data_type() doesn't support Null, so we have handle it explicitly ExpressionResult null_value_result{{NullValue{}}, {true}}; - fn(null_value_result); - + functor(null_value_result); } else { resolve_data_type(expression.data_type(), [&](const auto data_type_t) { using ExpressionDataType = typename decltype(data_type_t)::type; const auto expression_result = evaluate_expression_to_result(expression); - fn(*expression_result); + functor(*expression_result); }); } } @@ -1381,27 +1383,30 @@ pmr_vector ExpressionEvaluator::_evaluate_default_null_logic(const pmr_vec const pmr_vector& right) { if (left.size() == right.size()) { pmr_vector nulls(left.size()); - std::transform(left.begin(), left.end(), right.begin(), nulls.begin(), [](auto l, auto r) { return l || r; }); + std::transform(left.begin(), left.end(), right.begin(), nulls.begin(), + [](const auto lhs, const auto rhs) { return lhs || rhs; }); return nulls; - } else if (left.size() > right.size()) { + } + + if (left.size() > right.size()) { DebugAssert(right.size() <= 1, "Operand should have either the same row count as the other, 1 row (to represent a literal), or no " "rows (to represent a non-nullable operand)"); if (!right.empty() && right.front()) { return pmr_vector({true}); - } else { - return left; - } - } else { - DebugAssert(left.size() <= 1, - "Operand should have either the same row count as the other, 1 row (to represent a literal), or no " - "rows (to represent a non-nullable operand)"); - if (!left.empty() && left.front()) { - return pmr_vector({true}); - } else { - return right; } + + return left; } + + DebugAssert(left.size() <= 1, + "Operand should have either the same row count as the other, 1 row (to represent a literal), or no " + "rows (to represent a non-nullable operand)"); + if (!left.empty() && left.front()) { + return pmr_vector({true}); + } + + return right; } void ExpressionEvaluator::_materialize_segment_if_not_yet_materialized(const ColumnID column_id) { @@ -1554,7 +1559,8 @@ std::shared_ptr> ExpressionEvaluator::_evaluate_con // 2 - Compute the number of output rows auto result_size = argument_results.empty() ? size_t{0} : argument_results.front()->size(); - for (auto argument_idx = size_t{1}; argument_idx < argument_results.size(); ++argument_idx) { + const auto argument_result_count = argument_results.size(); + for (auto argument_idx = size_t{1}; argument_idx < argument_result_count; ++argument_idx) { result_size = _result_size(result_size, argument_results[argument_idx]->size()); } @@ -1601,7 +1607,8 @@ std::vector>> ExpressionEvaluator::_pru std::vector>> results(tables.size()); - for (auto table_idx = size_t{0}; table_idx < tables.size(); ++table_idx) { + const auto table_count = tables.size(); + for (auto table_idx = size_t{0}; table_idx < table_count; ++table_idx) { const auto& table = tables[table_idx]; Assert(table->column_count() == 1, "Expected precisely one column from Subquery"); diff --git a/src/lib/expression/evaluation/expression_evaluator.hpp b/src/lib/expression/evaluation/expression_evaluator.hpp index 5feeb244fb..b123d19e9a 100644 --- a/src/lib/expression/evaluation/expression_evaluator.hpp +++ b/src/lib/expression/evaluation/expression_evaluator.hpp @@ -157,18 +157,18 @@ class ExpressionEvaluator final { const AbstractExpression& left_expression, const AbstractExpression& right_expression); template - void _resolve_to_expression_result_view(const AbstractExpression& expression, const Functor& fn); + void _resolve_to_expression_result_view(const AbstractExpression& expression, const Functor& functor); template void _resolve_to_expression_result_views(const AbstractExpression& left_expression, - const AbstractExpression& right_expression, const Functor& fn); + const AbstractExpression& right_expression, const Functor& functor); template void _resolve_to_expression_results(const AbstractExpression& left_expression, - const AbstractExpression& right_expression, const Functor& fn); + const AbstractExpression& right_expression, const Functor& functor); template - void _resolve_to_expression_result(const AbstractExpression& expression, const Functor& fn); + void _resolve_to_expression_result(const AbstractExpression& expression, const Functor& functor); /** * Compute the number of rows that any kind expression produces, given the number of rows in its parameters diff --git a/src/lib/expression/evaluation/expression_result_views.hpp b/src/lib/expression/evaluation/expression_result_views.hpp index 673df651d7..3dad008c3c 100644 --- a/src/lib/expression/evaluation/expression_result_views.hpp +++ b/src/lib/expression/evaluation/expression_result_views.hpp @@ -121,7 +121,7 @@ class ExpressionResultLiteral { } size_t size() const { - return 1u; + return 1; } const T& value(const size_t /*value*/) const { diff --git a/src/lib/expression/evaluation/like_matcher.cpp b/src/lib/expression/evaluation/like_matcher.cpp index 822e4ea070..0b3142a58b 100644 --- a/src/lib/expression/evaluation/like_matcher.cpp +++ b/src/lib/expression/evaluation/like_matcher.cpp @@ -76,54 +76,55 @@ LikeMatcher::AllPatternVariant LikeMatcher::pattern_string_to_pattern_variant(co tokens[1] == PatternToken{Wildcard::AnyChars}) { // Pattern has the form 'hello%' return StartsWithPattern{std::get(tokens[0])}; + } - } else if (tokens.size() == 2 && tokens[0] == PatternToken{Wildcard::AnyChars} && - std::holds_alternative(tokens[1])) { + if (tokens.size() == 2 && tokens[0] == PatternToken{Wildcard::AnyChars} && + std::holds_alternative(tokens[1])) { // Pattern has the form '%hello' return EndsWithPattern{std::get(tokens[1])}; + } - } else if (tokens.size() == 3 && tokens[0] == PatternToken{Wildcard::AnyChars} && - std::holds_alternative(tokens[1]) && tokens[2] == PatternToken{Wildcard::AnyChars}) { + if (tokens.size() == 3 && tokens[0] == PatternToken{Wildcard::AnyChars} && + std::holds_alternative(tokens[1]) && tokens[2] == PatternToken{Wildcard::AnyChars}) { // Pattern has the form '%hello%' return ContainsPattern{std::get(tokens[1])}; + } - } else { - /** - * Pattern is either MultipleContainsPattern, e.g., '%hello%world%how%are%you%' or we fall back to - * using a regex matcher. - * - * A MultipleContainsPattern begins and ends with '%' and contains only strings and '%'. - */ - - // Pick ContainsMultiple or Regex - auto pattern_is_contains_multiple = true; // Set to false if tokens don't match %(, string, %)* pattern - auto strings = std::vector{}; // arguments used for ContainsMultiple, if it gets used - auto expect_any_chars = true; // If true, expect '%', if false, expect a string - - // Check if the tokens match the layout expected for MultipleContainsPattern - or break and set - // pattern_is_contains_multiple to false once they don't - for (const auto& token : tokens) { - if (expect_any_chars && token != PatternToken{Wildcard::AnyChars}) { - pattern_is_contains_multiple = false; - break; - } - if (!expect_any_chars && !std::holds_alternative(token)) { - pattern_is_contains_multiple = false; - break; - } - if (!expect_any_chars) { - strings.emplace_back(std::get(token)); - } - - expect_any_chars = !expect_any_chars; + /** + * Pattern is either MultipleContainsPattern, e.g., '%hello%world%how%are%you%' or we fall back to + * using a regex matcher. + * + * A MultipleContainsPattern begins and ends with '%' and contains only strings and '%'. + */ + + // Pick ContainsMultiple or Regex + auto pattern_is_contains_multiple = true; // Set to false if tokens don't match %(, string, %)* pattern + auto strings = std::vector{}; // arguments used for ContainsMultiple, if it gets used + auto expect_any_chars = true; // If true, expect '%', if false, expect a string + + // Check if the tokens match the layout expected for MultipleContainsPattern - or break and set + // pattern_is_contains_multiple to false once they don't + for (const auto& token : tokens) { + if (expect_any_chars && token != PatternToken{Wildcard::AnyChars}) { + pattern_is_contains_multiple = false; + break; } - - if (pattern_is_contains_multiple) { - return MultipleContainsPattern{strings}; - } else { - return std::regex(sql_like_to_regex(pattern)); + if (!expect_any_chars && !std::holds_alternative(token)) { + pattern_is_contains_multiple = false; + break; + } + if (!expect_any_chars) { + strings.emplace_back(std::get(token)); } + + expect_any_chars = !expect_any_chars; } + + if (pattern_is_contains_multiple) { + return MultipleContainsPattern{strings}; + } + + return std::regex(sql_like_to_regex(pattern)); } std::string LikeMatcher::sql_like_to_regex(pmr_string sql_like) { diff --git a/src/lib/expression/evaluation/like_matcher.hpp b/src/lib/expression/evaluation/like_matcher.hpp index b815e04fe7..90d690243a 100644 --- a/src/lib/expression/evaluation/like_matcher.hpp +++ b/src/lib/expression/evaluation/like_matcher.hpp @@ -65,14 +65,17 @@ class LikeMatcher { struct StartsWithPattern final { pmr_string string; }; + // '%hello' struct EndsWithPattern final { pmr_string string; }; + // '%hello%' struct ContainsPattern final { pmr_string string; }; + // '%hello%world%nice%weather%' struct MultipleContainsPattern final { std::vector strings; diff --git a/src/lib/expression/expression_functional.cpp b/src/lib/expression/expression_functional.cpp index 1791a2c703..14ff21afdb 100644 --- a/src/lib/expression/expression_functional.cpp +++ b/src/lib/expression/expression_functional.cpp @@ -49,6 +49,7 @@ std::shared_ptr not_exists_(const std::shared_ptr interval_(const int64_t duration, const DatetimeComponent unit) { // NOLINT - clang-tidy doesn't like the suffix return std::make_shared(duration, unit); } + // clang-format on } // namespace hyrise::expression_functional diff --git a/src/lib/expression/expression_utils.cpp b/src/lib/expression/expression_utils.cpp index f9f92aa39e..d0b8a7f138 100644 --- a/src/lib/expression/expression_utils.cpp +++ b/src/lib/expression/expression_utils.cpp @@ -26,11 +26,12 @@ bool expressions_equal(const std::vector>& e bool expressions_equal_to_expressions_in_different_lqp( const std::vector>& expressions_left, const std::vector>& expressions_right, const LQPNodeMapping& node_mapping) { - if (expressions_left.size() != expressions_right.size()) { + const auto expressions_left_count = expressions_left.size(); + if (expressions_left_count != expressions_right.size()) { return false; } - for (auto expression_idx = size_t{0}; expression_idx < expressions_left.size(); ++expression_idx) { + for (auto expression_idx = size_t{0}; expression_idx < expressions_left_count; ++expression_idx) { const auto& expression_left = *expressions_left[expression_idx]; const auto& expression_right = *expressions_right[expression_idx]; @@ -79,9 +80,9 @@ void expression_deep_replace(std::shared_ptr& expression, if (replacement_iter != mapping.end()) { sub_expression = replacement_iter->second; return ExpressionVisitation::DoNotVisitArguments; - } else { - return ExpressionVisitation::VisitArguments; } + + return ExpressionVisitation::VisitArguments; }); } @@ -247,7 +248,8 @@ std::shared_ptr inflate_logical_expressions( inflated = expressions.front(); } - for (auto expression_idx = size_t{1}; expression_idx < expressions.size(); ++expression_idx) { + const auto expression_count = expressions.size(); + for (auto expression_idx = size_t{1}; expression_idx < expression_count; ++expression_idx) { inflated = std::make_shared(logical_operator, inflated, expressions[expression_idx]); } @@ -263,16 +265,16 @@ void expression_set_parameters(const std::shared_ptr& expres if (value_iter != parameters.end()) { correlated_parameter_expression->set_value(value_iter->second); } - return ExpressionVisitation::DoNotVisitArguments; - } else if (const auto pqp_subquery_expression = std::dynamic_pointer_cast(sub_expression); - pqp_subquery_expression) { - pqp_subquery_expression->pqp->set_parameters(parameters); + } + if (const auto pqp_subquery_expression = std::dynamic_pointer_cast(sub_expression); + pqp_subquery_expression) { + pqp_subquery_expression->pqp->set_parameters(parameters); return ExpressionVisitation::DoNotVisitArguments; - } else { - return ExpressionVisitation::VisitArguments; } + + return ExpressionVisitation::VisitArguments; }); } @@ -332,9 +334,13 @@ std::optional expression_get_value_or_parameter(const AbstractEx if (const auto* correlated_parameter_expression = dynamic_cast(&expression)) { DebugAssert(correlated_parameter_expression->value(), "CorrelatedParameterExpression doesn't have a value set"); return *correlated_parameter_expression->value(); - } else if (expression.type == ExpressionType::Value) { + } + + if (expression.type == ExpressionType::Value) { return static_cast(expression).value; - } else if (expression.type == ExpressionType::Cast) { + } + + if (expression.type == ExpressionType::Cast) { const auto& cast_expression = static_cast(expression); Assert(expression.data_type() != DataType::Null, "Cast as NULL is undefined"); // More complicated casts should be resolved by ExpressionEvaluator. @@ -361,6 +367,7 @@ std::optional expression_get_value_or_parameter(const AbstractEx }); return result; } + return std::nullopt; } diff --git a/src/lib/expression/pqp_subquery_expression.cpp b/src/lib/expression/pqp_subquery_expression.cpp index 0b040a569b..fad8fb05ea 100644 --- a/src/lib/expression/pqp_subquery_expression.cpp +++ b/src/lib/expression/pqp_subquery_expression.cpp @@ -25,9 +25,9 @@ std::shared_ptr PQPSubqueryExpression::_on_deep_copy( if (_data_type_info) { return std::make_shared(pqp->deep_copy(copied_ops), _data_type_info->data_type, _data_type_info->nullable, parameters); - } else { - return std::make_shared(pqp->deep_copy(copied_ops), parameters); } + + return std::make_shared(pqp->deep_copy(copied_ops), parameters); } DataType PQPSubqueryExpression::data_type() const { diff --git a/src/lib/import_export/binary/binary_parser.cpp b/src/lib/import_export/binary/binary_parser.cpp index dfc91553a1..607047a265 100644 --- a/src/lib/import_export/binary/binary_parser.cpp +++ b/src/lib/import_export/binary/binary_parser.cpp @@ -37,7 +37,7 @@ template pmr_compact_vector BinaryParser::_read_values_compact_vector(std::ifstream& file, const size_t count) { const auto bit_width = _read_value(file); auto values = pmr_compact_vector(bit_width, count); - file.read(reinterpret_cast(values.get()), values.bytes()); + file.read(reinterpret_cast(values.get()), static_cast(values.bytes())); return values; } @@ -58,8 +58,9 @@ pmr_vector BinaryParser::_read_values(std::ifstream& file, const siz template <> pmr_vector BinaryParser::_read_values(std::ifstream& file, const size_t count) { pmr_vector readable_bools(count); - file.read(reinterpret_cast(readable_bools.data()), readable_bools.size() * sizeof(BoolAsByteType)); - return pmr_vector(readable_bools.begin(), readable_bools.end()); + file.read(reinterpret_cast(readable_bools.data()), + static_cast(readable_bools.size() * sizeof(BoolAsByteType))); + return {readable_bools.begin(), readable_bools.end()}; } pmr_vector BinaryParser::_read_string_values(std::ifstream& file, const size_t count) { @@ -67,12 +68,11 @@ pmr_vector BinaryParser::_read_string_values(std::ifstream& file, co const auto total_length = std::accumulate(string_lengths.cbegin(), string_lengths.cend(), static_cast(0)); const auto buffer = _read_values(file, total_length); - pmr_vector values(count); - size_t start = 0; - - for (size_t i = 0; i < count; ++i) { - values[i] = pmr_string(buffer.data() + start, buffer.data() + start + string_lengths[i]); - start += string_lengths[i]; + auto values = pmr_vector{count}; + auto start = size_t{0}; + for (auto index = size_t{0}; index < count; ++index) { + values[index] = pmr_string{buffer.data() + start, buffer.data() + start + string_lengths[index]}; + start += string_lengths[index]; } return values; @@ -93,8 +93,8 @@ std::pair, ChunkID> BinaryParser::_read_header(std::ifstr const auto column_nullables = _read_values(file, column_count); const auto column_names = _read_string_values(file, column_count); - TableColumnDefinitions output_column_definitions; - for (ColumnID column_id{0}; column_id < column_count; ++column_id) { + auto output_column_definitions = TableColumnDefinitions{}; + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { const auto data_type = data_type_to_string.right.at(std::string{column_data_types[column_id]}); output_column_definitions.emplace_back(std::string{column_names[column_id]}, data_type, column_nullables[column_id]); @@ -118,7 +118,7 @@ void BinaryParser::_import_chunk(std::ifstream& file, std::shared_ptr
& ta } Segments output_segments; - for (ColumnID column_id{0}; column_id < table->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < table->column_count(); ++column_id) { output_segments.push_back( _import_segment(file, row_count, table->column_data_type(column_id), table->column_is_nullable(column_id))); } @@ -229,12 +229,12 @@ std::shared_ptr> BinaryParser::_import_frame_of_refer ChunkOffset row_count) { const auto compressed_vector_type_id = _read_value(file); const auto block_count = _read_value(file); - const auto block_minima = pmr_vector(_read_values(file, block_count)); + const auto block_minima = _read_values(file, block_count); const auto null_values_stored = _read_value(file); std::optional> null_values; if (null_values_stored) { - null_values = pmr_vector(_read_values(file, row_count)); + null_values = _read_values(file, row_count); } auto offset_values = _import_offset_value_vector(file, row_count, compressed_vector_type_id); @@ -255,19 +255,19 @@ std::shared_ptr> BinaryParser::_import_lz4_segment(std::ifstream& pmr_vector> lz4_blocks(block_count); for (uint32_t block_index = 0; block_index < block_count; ++block_index) { - lz4_blocks[block_index] = pmr_vector(_read_values(file, lz4_block_sizes[block_index])); + lz4_blocks[block_index] = _read_values(file, lz4_block_sizes[block_index]); } const auto null_values_size = _read_value(file); std::optional> null_values; if (null_values_size != 0) { - null_values = pmr_vector(_read_values(file, null_values_size)); + null_values = _read_values(file, null_values_size); } else { null_values = std::nullopt; } const auto dictionary_size = _read_value(file); - auto dictionary = pmr_vector(_read_values(file, dictionary_size)); + auto dictionary = _read_values(file, dictionary_size); const auto string_offsets_size = _read_value(file); @@ -276,15 +276,15 @@ std::shared_ptr> BinaryParser::_import_lz4_segment(std::ifstream& return std::make_shared>(std::move(lz4_blocks), std::move(null_values), std::move(dictionary), std::move(string_offsets), block_size, last_block_size, compressed_size, num_elements); - } else { - if (std::is_same::value) { - return std::make_shared>(std::move(lz4_blocks), std::move(null_values), std::move(dictionary), - nullptr, block_size, last_block_size, compressed_size, num_elements); - } else { - return std::make_shared>(std::move(lz4_blocks), std::move(null_values), std::move(dictionary), - block_size, last_block_size, compressed_size, num_elements); - } } + + if (std::is_same::value) { + return std::make_shared>(std::move(lz4_blocks), std::move(null_values), std::move(dictionary), + nullptr, block_size, last_block_size, compressed_size, num_elements); + } + + return std::make_shared>(std::move(lz4_blocks), std::move(null_values), std::move(dictionary), + block_size, last_block_size, compressed_size, num_elements); } std::shared_ptr BinaryParser::_import_attribute_vector( @@ -326,7 +326,7 @@ std::unique_ptr BinaryParser::_import_offset_value_v std::shared_ptr BinaryParser::_import_fixed_string_vector(std::ifstream& file, const size_t count) { const auto string_length = _read_value(file); pmr_vector values(string_length * count); - file.read(values.data(), values.size()); + file.read(values.data(), static_cast(values.size())); return std::make_shared(std::move(values), string_length); } diff --git a/src/lib/import_export/binary/binary_writer.cpp b/src/lib/import_export/binary/binary_writer.cpp index 4c69d2ef98..85e098d239 100644 --- a/src/lib/import_export/binary/binary_writer.cpp +++ b/src/lib/import_export/binary/binary_writer.cpp @@ -66,7 +66,7 @@ void export_values(std::ofstream& ofstream, const std::vector& values) } void export_values(std::ofstream& ofstream, const FixedStringVector& values) { - ofstream.write(values.data(), values.size() * values.string_length()); + ofstream.write(values.data(), static_cast(values.size() * values.string_length())); } // specialized implementation for string values @@ -91,7 +91,7 @@ void export_value(std::ofstream& ofstream, const T& value) { void export_compact_vector(std::ofstream& ofstream, const pmr_compact_vector& values) { export_value(ofstream, static_cast(values.bits())); - ofstream.write(reinterpret_cast(values.get()), values.bytes()); + ofstream.write(reinterpret_cast(values.get()), static_cast(values.bytes())); } } // namespace @@ -121,7 +121,7 @@ void BinaryWriter::_write_header(const Table& table, std::ofstream& ofstream) { pmr_vector columns_are_nullable(table.column_count()); // Transform column types and copy column names in order to write them to the file. - for (ColumnID column_id{0}; column_id < table.column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < table.column_count(); ++column_id) { column_types[column_id] = data_type_to_string.left.at(table.column_data_type(column_id)); column_names[column_id] = table.column_name(column_id); columns_are_nullable[column_id] = table.column_is_nullable(column_id); @@ -145,7 +145,7 @@ void BinaryWriter::_write_chunk(const Table& table, std::ofstream& ofstream, con } // Iterating over all segments of this chunk and exporting them - for (ColumnID column_id{0}; column_id < chunk->column_count(); column_id++) { + for (auto column_id = ColumnID{0}; column_id < chunk->column_count(); column_id++) { resolve_data_and_segment_type(*chunk->get_segment(column_id), [&](const auto data_type_t, const auto& resolved_segment) { _write_segment(resolved_segment, table.column_is_nullable(column_id), ofstream); diff --git a/src/lib/import_export/csv/csv_converter.cpp b/src/lib/import_export/csv/csv_converter.cpp index 58ad5d3e1f..39f116c013 100644 --- a/src/lib/import_export/csv/csv_converter.cpp +++ b/src/lib/import_export/csv/csv_converter.cpp @@ -18,12 +18,12 @@ void BaseCsvConverter::unescape(std::string& field, const ParseConfig& config) { bool escaped = false; // The start and end ranges leave out the surrounding quotes. std::copy_if(field.begin() + 1, field.end() - 1, std::back_inserter(unescaped_string), - [&escaped, &config](const char c) { + [&escaped, &config](const char character) { bool do_copy = true; // If escape character is found the first time, don't copy, // and set 'escaped' to true for the next character - if (c == config.escape && !escaped) { + if (character == config.escape && !escaped) { do_copy = false; escaped = true; } else { diff --git a/src/lib/import_export/csv/csv_parser.cpp b/src/lib/import_export/csv/csv_parser.cpp index 13cbb835f7..ed0509869f 100644 --- a/src/lib/import_export/csv/csv_parser.cpp +++ b/src/lib/import_export/csv/csv_parser.cpp @@ -197,7 +197,7 @@ size_t CsvParser::_parse_into_chunk(std::string_view csv_chunk, const std::vecto }); } - Assert(field_ends.size() == row_count * column_count, "Unexpected number of fields"); + Assert(field_ends.size() == static_cast(row_count) * column_count, "Unexpected number of fields"); size_t start = 0; size_t row_id = 0; diff --git a/src/lib/import_export/file_type.cpp b/src/lib/import_export/file_type.cpp index bf7a30120a..26f195fa35 100755 --- a/src/lib/import_export/file_type.cpp +++ b/src/lib/import_export/file_type.cpp @@ -25,11 +25,16 @@ FileType file_type_from_filename(const std::string& filename) { boost::algorithm::to_lower(extension); if (extension == ".csv") { return FileType::Csv; - } else if (extension == ".tbl") { + } + + if (extension == ".tbl") { return FileType::Tbl; - } else if (extension == ".bin") { + } + + if (extension == ".bin") { return FileType::Binary; } + Fail("Unknown file extension " + extension); } diff --git a/src/lib/logical_query_plan/abstract_lqp_node.cpp b/src/lib/logical_query_plan/abstract_lqp_node.cpp index 467bcda0b6..8256d84ad3 100644 --- a/src/lib/logical_query_plan/abstract_lqp_node.cpp +++ b/src/lib/logical_query_plan/abstract_lqp_node.cpp @@ -96,9 +96,9 @@ size_t AbstractLQPNode::hash() const { boost::hash_combine(hash, node->type); boost::hash_combine(hash, node->_on_shallow_hash()); return LQPVisitation::VisitInputs; - } else { - return LQPVisitation::DoNotVisitInputs; } + + return LQPVisitation::DoNotVisitInputs; }); return hash; @@ -170,11 +170,13 @@ size_t AbstractLQPNode::input_count() const { LQPInputSide AbstractLQPNode::get_input_side(const std::shared_ptr& output) const { if (output->_inputs[0].get() == this) { return LQPInputSide::Left; - } else if (output->_inputs[1].get() == this) { + } + + if (output->_inputs[1].get() == this) { return LQPInputSide::Right; - } else { - Fail("Specified output node is not actually an output node of this node."); } + + Fail("Specified output node is not actually an output node of this node."); } std::vector AbstractLQPNode::get_input_sides() const { @@ -226,7 +228,8 @@ std::vector AbstractLQPNode::output_relations() const { const auto outputs = this->outputs(); const auto input_sides = get_input_sides(); - for (size_t output_idx = 0; output_idx < output_relations.size(); ++output_idx) { + const auto output_relation_count = output_relations.size(); + for (auto output_idx = size_t{0}; output_idx < output_relation_count; ++output_idx) { output_relations[output_idx] = LQPOutputRelation{outputs[output_idx], input_sides[output_idx]}; } @@ -255,8 +258,8 @@ std::vector> AbstractLQPNode::output_express } std::optional AbstractLQPNode::find_column_id(const AbstractExpression& expression) const { - const auto& output_expressions = this->output_expressions(); - return find_expression_idx(expression, output_expressions); + const auto& expressions_of_output = output_expressions(); + return find_expression_idx(expression, expressions_of_output); } ColumnID AbstractLQPNode::get_column_id(const AbstractExpression& expression) const { @@ -341,10 +344,10 @@ std::vector AbstractLQPNode::non_trivial_functional_depend if (left_input()) { Assert(!right_input(), "Expected single input node for implicit FD forwarding. Please override this function."); return left_input()->non_trivial_functional_dependencies(); - } else { - // e.g. StoredTableNode or StaticTableNode cannot provide any non-trivial FDs - return {}; } + + // e.g. StoredTableNode or StaticTableNode cannot provide any non-trivial FDs + return {}; } bool AbstractLQPNode::operator==(const AbstractLQPNode& rhs) const { @@ -359,8 +362,8 @@ bool AbstractLQPNode::operator!=(const AbstractLQPNode& rhs) const { } std::shared_ptr AbstractLQPNode::_deep_copy_impl(LQPNodeMapping& node_mapping) const { - std::shared_ptr copied_left_input; - std::shared_ptr copied_right_input; + auto copied_left_input = std::shared_ptr{}; + auto copied_right_input = std::shared_ptr{}; if (left_input()) { copied_left_input = left_input()->_deep_copy_impl(node_mapping); diff --git a/src/lib/logical_query_plan/aggregate_node.cpp b/src/lib/logical_query_plan/aggregate_node.cpp index 25325934b9..5ea9102df4 100644 --- a/src/lib/logical_query_plan/aggregate_node.cpp +++ b/src/lib/logical_query_plan/aggregate_node.cpp @@ -15,6 +15,11 @@ #include "types.hpp" #include "utils/assert.hpp" +namespace { +using NodeExpressionsDifferenceType = + typename std::iterator_traits::difference_type; +} // namespace + namespace hyrise { AggregateNode::AggregateNode(const std::vector>& group_by_expressions, @@ -31,7 +36,7 @@ AggregateNode::AggregateNode(const std::vector(group_by_expressions.size())); } std::string AggregateNode::description(const DescriptionMode mode) const { @@ -68,7 +73,8 @@ std::vector> AggregateNode::output_expressio // that reference the ANY'd column. auto output_expressions = node_expressions; - for (auto expression_idx = aggregate_expressions_begin_idx; expression_idx < output_expressions.size(); + const auto output_expression_count = output_expressions.size(); + for (auto expression_idx = aggregate_expressions_begin_idx; expression_idx < output_expression_count; ++expression_idx) { auto& output_expression = output_expressions[expression_idx]; DebugAssert(output_expression->type == ExpressionType::Aggregate, @@ -170,10 +176,12 @@ size_t AggregateNode::_on_shallow_hash() const { std::shared_ptr AggregateNode::_on_shallow_copy(LQPNodeMapping& node_mapping) const { const auto group_by_expressions = std::vector>{ - node_expressions.begin(), node_expressions.begin() + aggregate_expressions_begin_idx}; + node_expressions.begin(), + node_expressions.begin() + static_cast(aggregate_expressions_begin_idx)}; const auto aggregate_expressions = std::vector>{ - node_expressions.begin() + aggregate_expressions_begin_idx, node_expressions.end()}; + node_expressions.begin() + static_cast(aggregate_expressions_begin_idx), + node_expressions.end()}; return std::make_shared( expressions_copy_and_adapt_to_different_lqp(group_by_expressions, node_mapping), diff --git a/src/lib/logical_query_plan/join_node.cpp b/src/lib/logical_query_plan/join_node.cpp index 282fd55e90..f2509caf0d 100644 --- a/src/lib/logical_query_plan/join_node.cpp +++ b/src/lib/logical_query_plan/join_node.cpp @@ -125,11 +125,14 @@ std::shared_ptr JoinNode::_output_unique_constraints( std::copy(right_unique_constraints->begin(), right_unique_constraints->end(), std::back_inserter(*unique_constraints)); return unique_constraints; + } - } else if (left_operand_is_unique) { + if (left_operand_is_unique) { // Uniqueness on the left prevents duplication of records on the right return right_unique_constraints; - } else if (right_operand_is_unique) { + } + + if (right_operand_is_unique) { // Uniqueness on the right prevents duplication of records on the left return left_unique_constraints; } @@ -220,11 +223,11 @@ bool JoinNode::is_column_nullable(const ColumnID column_id) const { if (column_is_from_left_input) { return left_input()->is_column_nullable(column_id); - } else { - ColumnID right_column_id = - static_cast(column_id - static_cast(left_input_column_count)); - return right_input()->is_column_nullable(right_column_id); } + + ColumnID right_column_id = + static_cast(column_id - static_cast(left_input_column_count)); + return right_input()->is_column_nullable(right_column_id); } const std::vector>& JoinNode::join_predicates() const { diff --git a/src/lib/logical_query_plan/lqp_translator.cpp b/src/lib/logical_query_plan/lqp_translator.cpp index 691ad2d676..57d3d1433d 100644 --- a/src/lib/logical_query_plan/lqp_translator.cpp +++ b/src/lib/logical_query_plan/lqp_translator.cpp @@ -372,11 +372,14 @@ std::shared_ptr LQPTranslator::_translate_join_node( return; } + // NOLINTBEGIN(bugprone-use-after-move, hicpp-invalid-access-moved) + // clang-tidy complains about the move in the loop as it does not recognize the early out above. if (JoinOperator::supports({join_node->join_mode, primary_join_predicate.predicate_condition, left_data_type, right_data_type, !secondary_join_predicates.empty()})) { join_operator = std::make_shared(left_input_operator, right_input_operator, join_node->join_mode, primary_join_predicate, std::move(secondary_join_predicates)); } + // NOLINTEND(bugprone-use-after-move, hicpp-invalid-access-moved) }); Assert(join_operator, "No operator implementation available for join '"s + join_node->description() + "'"); diff --git a/src/lib/logical_query_plan/lqp_utils.cpp b/src/lib/logical_query_plan/lqp_utils.cpp index d16e206f19..f160cd8baa 100644 --- a/src/lib/logical_query_plan/lqp_utils.cpp +++ b/src/lib/logical_query_plan/lqp_utils.cpp @@ -191,7 +191,8 @@ void lqp_replace_node(const std::shared_ptr& original_node, /** * Tie the replacement_node with this nodes outputs. */ - for (size_t output_idx = 0; output_idx < outputs.size(); ++output_idx) { + const auto output_count = outputs.size(); + for (auto output_idx = size_t{0}; output_idx < output_count; ++output_idx) { outputs[output_idx]->set_input(input_sides[output_idx], replacement_node); } @@ -223,7 +224,8 @@ void lqp_remove_node(const std::shared_ptr& node, const AllowRi * Tie this node's previous outputs with this nodes previous left input * If left_input is nullptr, still call set_input so this node will get untied from the LQP. */ - for (size_t output_idx = 0; output_idx < outputs.size(); ++output_idx) { + const auto output_count = outputs.size(); + for (auto output_idx = size_t{0}; output_idx < output_count; ++output_idx) { outputs[output_idx]->set_input(input_sides[output_idx], left_input); } } @@ -351,9 +353,9 @@ std::shared_ptr lqp_subplan_to_boolean_expression_impl( auto left_input_expression = lqp_subplan_to_boolean_expression_impl(begin->left_input(), end, expression); if (left_input_expression) { return left_input_expression; - } else { - return expression; } + + return expression; } case LQPNodeType::Union: { @@ -364,9 +366,9 @@ std::shared_ptr lqp_subplan_to_boolean_expression_impl( if (left_input_expression && right_input_expression) { const auto or_expression = or_(left_input_expression, right_input_expression); return subsequent_expression ? and_(or_expression, *subsequent_expression) : or_expression; - } else { - return nullptr; } + + return nullptr; } case LQPNodeType::Projection: @@ -413,9 +415,9 @@ std::vector> lqp_find_leaves(const std::shared_ visit_lqp(lqp, [&](const auto& node) { if (node->input_count() > 0) { return LQPVisitation::VisitInputs; - } else { - nodes.emplace_back(node); } + + nodes.emplace_back(node); return LQPVisitation::DoNotVisitInputs; }); @@ -518,6 +520,7 @@ void remove_invalid_fds(const std::shared_ptr& lqp, std:: if (fds.empty()) { return; } + const auto& output_expressions = lqp->output_expressions(); const auto& output_expressions_set = ExpressionUnorderedSet{output_expressions.cbegin(), output_expressions.cend()}; @@ -591,7 +594,9 @@ std::shared_ptr find_diamond_origin_node(const std::shared_ptr< is_diamond = false; } return LQPVisitation::DoNotVisitInputs; - } else if (!diamond_node->left_input()) { + } + + if (!diamond_node->left_input()) { // The traversal ends because we reached a MockNode, StoredTableNode or StaticTableNode. Since we did not find a // node with multiple outputs yet, union_root_node cannot be considered the root of a diamond. is_diamond = false; diff --git a/src/lib/logical_query_plan/sort_node.cpp b/src/lib/logical_query_plan/sort_node.cpp index 8c47e4f389..fde8266b2b 100644 --- a/src/lib/logical_query_plan/sort_node.cpp +++ b/src/lib/logical_query_plan/sort_node.cpp @@ -24,11 +24,12 @@ std::string SortNode::description(const DescriptionMode mode) const { stream << "[Sort] "; - for (auto expression_idx = ColumnID{0}; expression_idx < node_expressions.size(); ++expression_idx) { + const auto node_expression_count = node_expressions.size(); + for (auto expression_idx = ColumnID{0}; expression_idx < node_expression_count; ++expression_idx) { stream << node_expressions[expression_idx]->description(expression_mode) << " "; stream << "(" << sort_modes[expression_idx] << ")"; - if (expression_idx + 1u < node_expressions.size()) { + if (expression_idx + 1u < node_expression_count) { stream << ", "; } } @@ -40,7 +41,7 @@ std::shared_ptr SortNode::unique_constraints() const { } size_t SortNode::_on_shallow_hash() const { - size_t hash{0}; + auto hash = size_t{0}; for (const auto& sort_mode : sort_modes) { boost::hash_combine(hash, sort_mode); } diff --git a/src/lib/logical_query_plan/stored_table_node.cpp b/src/lib/logical_query_plan/stored_table_node.cpp index bcaf6f6850..f31cf0515f 100644 --- a/src/lib/logical_query_plan/stored_table_node.cpp +++ b/src/lib/logical_query_plan/stored_table_node.cpp @@ -151,10 +151,10 @@ std::vector StoredTableNode::indexes_statistics() const { if (!updated_column_id) { // Indexed column was pruned - remove index from statistics return true; - } else { - // Update column id - original_column_id = *updated_column_id; } + + // Update column id + original_column_id = *updated_column_id; } return false; }), diff --git a/src/lib/memory/boost_default_memory_resource.cpp b/src/lib/memory/boost_default_memory_resource.cpp index 478fa93db3..d75023525d 100644 --- a/src/lib/memory/boost_default_memory_resource.cpp +++ b/src/lib/memory/boost_default_memory_resource.cpp @@ -7,14 +7,18 @@ namespace boost::container::pmr { -class default_resource_impl : public memory_resource { // NOLINT(readability-identifier-naming) +// We discourage manual memory management in Hyrise (such as malloc, or new), but in case of allocator/memory resource +// implementations, it is fine. +// NOLINTBEGIN(cppcoreguidelines-no-malloc,cppcoreguidelines-owning-memory,hicpp-no-malloc) + +class default_resource_impl : public memory_resource { public: void* do_allocate(std::size_t bytes, std::size_t alignment) override { - return std::malloc(bytes); // NOLINT(cppcoreguidelines-owning-memory,cppcoreguidelines-no-malloc,hicpp-no-malloc) + return std::malloc(bytes); } - void do_deallocate(void* p, std::size_t bytes, std::size_t alignment) override { - std::free(p); // NOLINT(cppcoreguidelines-owning-memory,cppcoreguidelines-no-malloc,hicpp-no-malloc) + void do_deallocate(void* pointer, std::size_t bytes, std::size_t alignment) override { + std::free(pointer); } [[nodiscard]] bool do_is_equal(const memory_resource& other) const BOOST_NOEXCEPT override { @@ -26,7 +30,9 @@ memory_resource* get_default_resource() BOOST_NOEXCEPT { // Yes, this leaks. We have had SO many problems with the default memory resource going out of scope // before the other things were cleaned up that we decided to live with the leak, rather than // running into races over and over again. - static auto* default_resource_instance = new default_resource_impl(); // NOLINT(cppcoreguidelines-owning-memory) + + // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables,bugprone-unhandled-exception-at-new) + static auto* default_resource_instance = new default_resource_impl(); return default_resource_instance; } @@ -34,9 +40,11 @@ memory_resource* new_delete_resource() BOOST_NOEXCEPT { return get_default_resource(); } -memory_resource* set_default_resource(memory_resource* r) BOOST_NOEXCEPT { +memory_resource* set_default_resource(memory_resource* resource) BOOST_NOEXCEPT { // Do nothing return get_default_resource(); } } // namespace boost::container::pmr + +// NOLINTEND(cppcoreguidelines-no-malloc,cppcoreguidelines-owning-memory,hicpp-no-malloc) diff --git a/src/lib/null_value.hpp b/src/lib/null_value.hpp index eb4d0c4be8..92762c8840 100644 --- a/src/lib/null_value.hpp +++ b/src/lib/null_value.hpp @@ -60,6 +60,7 @@ inline size_t hash_value(const NullValue& /*value*/) { #if !defined(BOOST_NO_IOSTREAM) BOOST_TEMPLATED_STREAM_TEMPLATE(E, T) + inline BOOST_TEMPLATED_STREAM(ostream, E, T) & operator<<(BOOST_TEMPLATED_STREAM(ostream, E, T) & out, const NullValue&) { out << "NULL"; diff --git a/src/lib/operators/abstract_aggregate_operator.cpp b/src/lib/operators/abstract_aggregate_operator.cpp index 5b007ed74c..748d9abbff 100644 --- a/src/lib/operators/abstract_aggregate_operator.cpp +++ b/src/lib/operators/abstract_aggregate_operator.cpp @@ -8,10 +8,11 @@ namespace hyrise { AbstractAggregateOperator::AbstractAggregateOperator( - const std::shared_ptr& in, const std::vector>& aggregates, + const std::shared_ptr& input_operator, + const std::vector>& aggregates, const std::vector& groupby_column_ids, std::unique_ptr init_performance_data) - : AbstractReadOnlyOperator(OperatorType::Aggregate, in, nullptr, std::move(init_performance_data)), + : AbstractReadOnlyOperator(OperatorType::Aggregate, input_operator, nullptr, std::move(init_performance_data)), _aggregates{aggregates}, _groupby_column_ids{groupby_column_ids} { /* @@ -26,6 +27,7 @@ AbstractAggregateOperator::AbstractAggregateOperator( const std::vector>& AbstractAggregateOperator::aggregates() const { return _aggregates; } + const std::vector& AbstractAggregateOperator::groupby_column_ids() const { return _groupby_column_ids; } diff --git a/src/lib/operators/abstract_aggregate_operator.hpp b/src/lib/operators/abstract_aggregate_operator.hpp index 042895991f..32a69402da 100644 --- a/src/lib/operators/abstract_aggregate_operator.hpp +++ b/src/lib/operators/abstract_aggregate_operator.hpp @@ -129,7 +129,7 @@ class AggregateFunctionBuilder& in, + AbstractAggregateOperator(const std::shared_ptr& input_operator, const std::vector>& aggregates, const std::vector& groupby_column_ids, std::unique_ptr performance_data = diff --git a/src/lib/operators/abstract_join_operator.cpp b/src/lib/operators/abstract_join_operator.cpp index 9a2db717e0..77392fd8fe 100644 --- a/src/lib/operators/abstract_join_operator.cpp +++ b/src/lib/operators/abstract_join_operator.cpp @@ -100,7 +100,7 @@ std::shared_ptr
AbstractJoinOperator::_build_output_table(std::vectorcolumn_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < left_in_table->column_count(); ++column_id) { const auto nullable = (left_may_produce_null || left_in_table->column_is_nullable(column_id)); output_column_definitions.emplace_back(left_in_table->column_name(column_id), left_in_table->column_data_type(column_id), nullable); @@ -108,7 +108,7 @@ std::shared_ptr
AbstractJoinOperator::_build_output_table(std::vectorcolumn_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < right_in_table->column_count(); ++column_id) { const auto nullable = (right_may_produce_null || right_in_table->column_is_nullable(column_id)); output_column_definitions.emplace_back(right_in_table->column_name(column_id), right_in_table->column_data_type(column_id), nullable); diff --git a/src/lib/operators/abstract_operator.cpp b/src/lib/operators/abstract_operator.cpp index d933be0a04..579ec138ae 100644 --- a/src/lib/operators/abstract_operator.cpp +++ b/src/lib/operators/abstract_operator.cpp @@ -45,9 +45,9 @@ AbstractOperator::~AbstractOperator() { */ if constexpr (HYRISE_DEBUG) { auto transaction_context = _transaction_context.has_value() ? _transaction_context->lock() : nullptr; - bool aborted = transaction_context ? transaction_context->aborted() : false; - bool left_has_executed = _left_input ? _left_input->executed() : false; - bool right_has_executed = _right_input ? _right_input->executed() : false; + auto aborted = transaction_context ? transaction_context->aborted() : false; + auto left_has_executed = _left_input ? _left_input->executed() : false; + auto right_has_executed = _right_input ? _right_input->executed() : false; Assert(executed() || aborted || !left_has_executed || !right_has_executed || _consumer_count == 0, "Operator did not execute, but at least one input operator has."); } @@ -183,6 +183,7 @@ void AbstractOperator::clear_output() { if (_never_clear_output) { return; } + _transition_to(OperatorState::ExecutedAndCleared); _output = nullptr; } @@ -313,11 +314,11 @@ void AbstractOperator::set_parameters(const std::unordered_mapset_parameters(parameters); } - if (right_input()) { mutable_right_input()->set_parameters(parameters); } diff --git a/src/lib/operators/aggregate_hash.cpp b/src/lib/operators/aggregate_hash.cpp index 14bcff661d..b510e573be 100644 --- a/src/lib/operators/aggregate_hash.cpp +++ b/src/lib/operators/aggregate_hash.cpp @@ -141,11 +141,12 @@ AggregateKey& get_aggregate_key([[maybe_unused]] KeysPerChunk& key namespace hyrise { -AggregateHash::AggregateHash(const std::shared_ptr& in, +AggregateHash::AggregateHash(const std::shared_ptr& input_operator, const std::vector>& aggregates, const std::vector& groupby_column_ids) - : AbstractAggregateOperator(in, aggregates, groupby_column_ids, + : AbstractAggregateOperator(input_operator, aggregates, groupby_column_ids, std::make_unique>()) { + // NOLINTNEXTLINE - clang-tidy wants _has_aggregate_functions in the member initializer list _has_aggregate_functions = !_aggregates.empty() && !std::all_of(_aggregates.begin(), _aggregates.end(), [](const auto aggregate_expression) { return aggregate_expression->aggregate_function == AggregateFunction::Any; @@ -444,19 +445,19 @@ KeysPerChunk AggregateHash::_partition_by_groupby_keys() { } else { // We need to generate an ID that is unique for the value. In some cases, we can use an optimization, // in others, we can't. We need to somehow track whether we have found an ID or not. For this, we - // first set `id` to its maximum value. If after all branches it is still that max value, no optimized - // ID generation was applied and we need to generate the ID using the value->ID map. - auto id = std::numeric_limits::max(); + // first set `value_id` to its maximum value. If after all branches it is still that max value, no + // optimized ID generation was applied and we need to generate the ID using the value->ID map. + auto value_id = std::numeric_limits::max(); if constexpr (std::is_same_v) { const auto& string = position.value(); if (string.size() < 5) { static_assert(std::is_same_v, "Calculation only valid for uint64_t"); - const auto char_to_uint = [](const char in, const uint bits) { + const auto char_to_uint = [](const char char_in, const uint32_t bits) { // chars may be signed or unsigned. For the calculation as described below, we need signed // chars. - return static_cast(*reinterpret_cast(&in)) << bits; + return static_cast(*reinterpret_cast(&char_in)) << bits; }; switch (string.size()) { @@ -475,36 +476,36 @@ KeysPerChunk AggregateHash::_partition_by_groupby_keys() { // more complicated. case 0: { - id = uint64_t{1}; + value_id = uint64_t{1}; } break; case 1: { - id = uint64_t{2} + char_to_uint(string[0], 0); + value_id = uint64_t{2} + char_to_uint(string[0], 0); } break; case 2: { - id = uint64_t{258} + char_to_uint(string[1], 8) + char_to_uint(string[0], 0); + value_id = uint64_t{258} + char_to_uint(string[1], 8) + char_to_uint(string[0], 0); } break; case 3: { - id = uint64_t{65'794} + char_to_uint(string[2], 16) + char_to_uint(string[1], 8) + - char_to_uint(string[0], 0); + value_id = uint64_t{65'794} + char_to_uint(string[2], 16) + char_to_uint(string[1], 8) + + char_to_uint(string[0], 0); } break; case 4: { - id = uint64_t{16'843'010} + char_to_uint(string[3], 24) + char_to_uint(string[2], 16) + - char_to_uint(string[1], 8) + char_to_uint(string[0], 0); + value_id = uint64_t{16'843'010} + char_to_uint(string[3], 24) + char_to_uint(string[2], 16) + + char_to_uint(string[1], 8) + char_to_uint(string[0], 0); } break; } } } - if (id == std::numeric_limits::max()) { + if (value_id == std::numeric_limits::max()) { // Could not take the shortcut above, either because we don't have a string or because it is too // long auto inserted = id_map.try_emplace(position.value(), id_counter); - id = inserted.first->second; + value_id = inserted.first->second; // if the id_map didn't have the value as a key and a new element was inserted if (inserted.second) { @@ -513,9 +514,9 @@ KeysPerChunk AggregateHash::_partition_by_groupby_keys() { } if constexpr (std::is_same_v) { - keys[chunk_offset] = id; + keys[chunk_offset] = value_id; } else { - keys[chunk_offset][group_column_index] = id; + keys[chunk_offset][group_column_index] = value_id; } } @@ -591,7 +592,8 @@ void AggregateHash::_aggregate() { * created on. We do this here, and not in the per-chunk-loop below, because there might be no Chunks in the input * and _write_aggregate_output() needs these contexts anyway. */ - for (ColumnID aggregate_idx{0}; aggregate_idx < _aggregates.size(); ++aggregate_idx) { + const auto aggregate_count = _aggregates.size(); + for (auto aggregate_idx = ColumnID{0}; aggregate_idx < aggregate_count; ++aggregate_idx) { const auto& aggregate = _aggregates[aggregate_idx]; const auto& pqp_column = static_cast(*aggregate->argument()); diff --git a/src/lib/operators/aggregate_hash.hpp b/src/lib/operators/aggregate_hash.hpp index e5612a1713..021400b8d1 100644 --- a/src/lib/operators/aggregate_hash.hpp +++ b/src/lib/operators/aggregate_hash.hpp @@ -138,7 +138,7 @@ using DistinctAggregateType = int8_t; class AggregateHash : public AbstractAggregateOperator { public: - AggregateHash(const std::shared_ptr& in, + AggregateHash(const std::shared_ptr& input_operator, const std::vector>& aggregates, const std::vector& groupby_column_ids); diff --git a/src/lib/operators/aggregate_sort.cpp b/src/lib/operators/aggregate_sort.cpp index 41af368d97..28cfa8f043 100644 --- a/src/lib/operators/aggregate_sort.cpp +++ b/src/lib/operators/aggregate_sort.cpp @@ -40,10 +40,10 @@ std::shared_ptr sort_table_by_column_ids(const std::shared_ptr& in, +AggregateSort::AggregateSort(const std::shared_ptr& input_operator, const std::vector>& aggregates, const std::vector& groupby_column_ids) - : AbstractAggregateOperator(in, aggregates, groupby_column_ids) {} + : AbstractAggregateOperator(input_operator, aggregates, groupby_column_ids) {} const std::string& AggregateSort::name() const { static const auto name = std::string{"AggregateSort"}; @@ -74,7 +74,7 @@ void AggregateSort::_aggregate_values(const std::set& group_boundaries, c auto aggregator = AggregateFunctionBuilder().get_aggregate_function(); // We already know beforehand how many aggregate values (=group-by-combinations) we have to calculate - const size_t num_groups = group_boundaries.size() + 1; + const auto num_groups = group_boundaries.size() + 1; // Vectors to store aggregate values (and if they are NULL) for later usage in value segments auto aggregate_results = pmr_vector(num_groups); @@ -83,19 +83,19 @@ void AggregateSort::_aggregate_values(const std::set& group_boundaries, c // Variables needed for the aggregates. Not all variables are needed for all aggregates // Row counts per group, ex- and including null values. Needed for count (/*) and average - uint64_t value_count = 0u; - uint64_t value_count_with_null = 0u; + auto value_count = uint64_t{0}; + auto value_count_with_null = uint64_t{0}; // All unique values found. Needed for count distinct - std::unordered_set unique_values; + auto unique_values = std::unordered_set{}; // The number of the current group-by-combination. Used as offset when storing values - uint64_t aggregate_group_index = 0u; + auto aggregate_group_index = uint64_t{0}; const auto chunk_count = sorted_table->chunk_count(); AggregateAccumulator accumulator{}; - ChunkID current_chunk_id{0}; + auto current_chunk_id = ChunkID{0}; if (aggregate_function == AggregateFunction::Count && input_column_id == INVALID_COLUMN_ID) { /* * Special COUNT(*) implementation. @@ -111,7 +111,7 @@ void AggregateSort::_aggregate_values(const std::set& group_boundaries, c value_count_with_null = group_boundary.chunk_offset - current_group_begin_pointer.chunk_offset; } else { // Group is spread over multiple chunks - uint64_t count = 0; + auto count = uint64_t{0}; count += sorted_table->get_chunk(current_group_begin_pointer.chunk_id)->size() - current_group_begin_pointer.chunk_offset; for (auto chunk_id = ChunkID{current_group_begin_pointer.chunk_id + 1}; chunk_id < group_boundary.chunk_id; @@ -334,7 +334,7 @@ std::shared_ptr
AggregateSort::_sort_table_chunk_wise(const std::shared_p reference_segments.reserve(column_count); // Create actual ReferenceSegment objects. - for (ColumnID column_id{0}; column_id < column_count; ++column_id) { + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { auto ref_segment_out = std::make_shared(input_table, column_id, pos_list); reference_segments.push_back(ref_segment_out); } diff --git a/src/lib/operators/aggregate_sort.hpp b/src/lib/operators/aggregate_sort.hpp index fb38ffc453..bad0e79357 100644 --- a/src/lib/operators/aggregate_sort.hpp +++ b/src/lib/operators/aggregate_sort.hpp @@ -61,7 +61,7 @@ namespace hyrise { */ class AggregateSort : public AbstractAggregateOperator { public: - AggregateSort(const std::shared_ptr& in, + AggregateSort(const std::shared_ptr& input_operator, const std::vector>& aggregates, const std::vector& groupby_column_ids); diff --git a/src/lib/operators/change_meta_table.hpp b/src/lib/operators/change_meta_table.hpp index 0971353452..85c1dd812d 100644 --- a/src/lib/operators/change_meta_table.hpp +++ b/src/lib/operators/change_meta_table.hpp @@ -40,7 +40,9 @@ class ChangeMetaTable : public AbstractReadWriteOperator { const std::shared_ptr& copied_right_input, std::unordered_map>& copied_ops) const override; void _on_set_parameters(const std::unordered_map& parameters) override; + void _on_commit_records(const CommitID cid) override {} + void _on_rollback_records() override {} private: diff --git a/src/lib/operators/export.cpp b/src/lib/operators/export.cpp index 973cd90c06..7409eba2b0 100644 --- a/src/lib/operators/export.cpp +++ b/src/lib/operators/export.cpp @@ -9,9 +9,9 @@ namespace hyrise { -Export::Export(const std::shared_ptr& in, const std::string& filename, +Export::Export(const std::shared_ptr& input_operator, const std::string& filename, const FileType& file_type) - : AbstractReadOnlyOperator(OperatorType::Export, in), _filename(filename), _file_type(file_type) { + : AbstractReadOnlyOperator(OperatorType::Export, input_operator), _filename(filename), _file_type(file_type) { if (_file_type == FileType::Auto) { _file_type = file_type_from_filename(filename); } diff --git a/src/lib/operators/export.hpp b/src/lib/operators/export.hpp index accc94013f..9e061bda00 100644 --- a/src/lib/operators/export.hpp +++ b/src/lib/operators/export.hpp @@ -27,7 +27,7 @@ class Export : public AbstractReadOnlyOperator { * @param filename Path to the output file. * @param file_type Optional. Type indicating the file format. If not present, it is guessed by the filename. */ - explicit Export(const std::shared_ptr& in, const std::string& filename, + explicit Export(const std::shared_ptr& input_operator, const std::string& filename, const FileType& file_type = FileType::Auto); const std::string& name() const final; diff --git a/src/lib/operators/index_scan.cpp b/src/lib/operators/index_scan.cpp index 35495625ba..6e653f91ab 100644 --- a/src/lib/operators/index_scan.cpp +++ b/src/lib/operators/index_scan.cpp @@ -16,10 +16,10 @@ namespace hyrise { -IndexScan::IndexScan(const std::shared_ptr& in, const SegmentIndexType index_type, +IndexScan::IndexScan(const std::shared_ptr& input_operator, const SegmentIndexType index_type, const std::vector& left_column_ids, const PredicateCondition predicate_condition, const std::vector& right_values, const std::vector& right_values2) - : AbstractReadOnlyOperator{OperatorType::IndexScan, in}, + : AbstractReadOnlyOperator{OperatorType::IndexScan, input_operator}, _index_type{index_type}, _left_column_ids{left_column_ids}, _predicate_condition{predicate_condition}, diff --git a/src/lib/operators/index_scan.hpp b/src/lib/operators/index_scan.hpp index 041bea44e1..ddda4e1807 100644 --- a/src/lib/operators/index_scan.hpp +++ b/src/lib/operators/index_scan.hpp @@ -21,7 +21,7 @@ class AbstractTask; */ class IndexScan : public AbstractReadOnlyOperator { public: - IndexScan(const std::shared_ptr& in, const SegmentIndexType index_type, + IndexScan(const std::shared_ptr& input_operator, const SegmentIndexType index_type, const std::vector& left_column_ids, const PredicateCondition predicate_condition, const std::vector& right_values, const std::vector& right_values2 = {}); diff --git a/src/lib/operators/insert.cpp b/src/lib/operators/insert.cpp index ea4546ac2b..501e49af0c 100644 --- a/src/lib/operators/insert.cpp +++ b/src/lib/operators/insert.cpp @@ -86,7 +86,7 @@ std::shared_ptr Insert::_on_execute(std::shared_ptrtarget_chunk_size() > 0, "Expected target chunk size of target table to be greater than zero"); - for (ColumnID column_id{0}; column_id < _target_table->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < _target_table->column_count(); ++column_id) { // This is not really a strong limitation, we just did not want the compile time of all type combinations. // If you really want this, it should be only a couple of lines to implement. Assert(left_input_table()->column_data_type(column_id) == _target_table->column_data_type(column_id), diff --git a/src/lib/operators/insert.hpp b/src/lib/operators/insert.hpp index c30abe8348..8679686da7 100644 --- a/src/lib/operators/insert.hpp +++ b/src/lib/operators/insert.hpp @@ -45,6 +45,7 @@ class Insert : public AbstractReadWriteOperator { ChunkOffset begin_chunk_offset{}; ChunkOffset end_chunk_offset{}; }; + std::vector _target_chunk_ranges; std::shared_ptr
_target_table; diff --git a/src/lib/operators/join_hash.cpp b/src/lib/operators/join_hash.cpp index c78ebda189..fb26dbd06e 100644 --- a/src/lib/operators/join_hash.cpp +++ b/src/lib/operators/join_hash.cpp @@ -196,7 +196,7 @@ std::shared_ptr JoinHash::_on_execute() { _impl = std::make_unique>( *this, build_input_table, probe_input_table, _mode, adjusted_column_ids, _primary_predicate.predicate_condition, output_column_order, *_radix_bits, join_hash_performance_data, - std::move(adjusted_secondary_predicates)); + adjusted_secondary_predicates); } else { Fail("Cannot join String with non-String column"); } @@ -221,8 +221,7 @@ class JoinHash::JoinHashImpl : public AbstractReadOnlyOperatorImpl { const std::shared_ptr& probe_input_table, const JoinMode mode, const ColumnIDPair& column_ids, const PredicateCondition predicate_condition, const OutputColumnOrder output_column_order, const size_t radix_bits, - JoinHash::PerformanceData& performance_data, - std::vector secondary_predicates = {}) + JoinHash::PerformanceData& performance_data, std::vector& secondary_predicates) : _join_hash(join_hash), _build_input_table(build_input_table), _probe_input_table(probe_input_table), @@ -231,7 +230,7 @@ class JoinHash::JoinHashImpl : public AbstractReadOnlyOperatorImpl { _predicate_condition(predicate_condition), _performance_data(performance_data), _output_column_order(output_column_order), - _secondary_predicates(std::move(secondary_predicates)), + _secondary_predicates(secondary_predicates), _radix_bits(radix_bits) {} protected: @@ -244,7 +243,7 @@ class JoinHash::JoinHashImpl : public AbstractReadOnlyOperatorImpl { OutputColumnOrder _output_column_order; - const std::vector _secondary_predicates; + const std::vector& _secondary_predicates; std::shared_ptr
_output_table; @@ -494,9 +493,9 @@ class JoinHash::JoinHashImpl : public AbstractReadOnlyOperatorImpl { // simple heuristic: half of the rows of the probe side will match const size_t result_rows_per_partition = _probe_input_table->row_count() > 0 ? _probe_input_table->row_count() / partition_count / 2 : 0; - for (size_t i = 0; i < partition_count; i++) { - build_side_pos_lists[i].reserve(result_rows_per_partition); - probe_side_pos_lists[i].reserve(result_rows_per_partition); + for (auto partition_index = size_t{0}; partition_index < partition_count; ++partition_index) { + build_side_pos_lists[partition_index].reserve(result_rows_per_partition); + probe_side_pos_lists[partition_index].reserve(result_rows_per_partition); } Timer timer_probing; diff --git a/src/lib/operators/join_hash/join_hash_steps.hpp b/src/lib/operators/join_hash/join_hash_steps.hpp index 43a70bf3f7..06718cd0e3 100644 --- a/src/lib/operators/join_hash/join_hash_steps.hpp +++ b/src/lib/operators/join_hash/join_hash_steps.hpp @@ -136,14 +136,15 @@ class PosHashTable { // Rewrite the SmallPosLists into one giant UnifiedPosList (see above). void finalize() { _offset_hash_table.shrink_to_fit(); + const auto hash_table_size = _offset_hash_table.size(); if (_mode == JoinHashBuildMode::AllPositions) { _unified_pos_list = UnifiedPosList{}; // Resize so that we can store the start offset of each range as well as the final end offset. - _unified_pos_list->offsets.resize(_offset_hash_table.size() + 1); + _unified_pos_list->offsets.resize(hash_table_size + 1); auto total_size = size_t{0}; - for (auto hash_table_idx = size_t{0}; hash_table_idx < _offset_hash_table.size(); ++hash_table_idx) { + for (auto hash_table_idx = size_t{0}; hash_table_idx < hash_table_size; ++hash_table_idx) { _unified_pos_list->offsets[hash_table_idx] = total_size; total_size += _small_pos_lists[hash_table_idx].size(); } @@ -151,7 +152,7 @@ class PosHashTable { _unified_pos_list->pos_list.resize(total_size); auto offset = size_t{0}; - for (auto hash_table_idx = size_t{0}; hash_table_idx < _offset_hash_table.size(); ++hash_table_idx) { + for (auto hash_table_idx = size_t{0}; hash_table_idx < hash_table_size; ++hash_table_idx) { std::copy(_small_pos_lists[hash_table_idx].begin(), _small_pos_lists[hash_table_idx].end(), _unified_pos_list->pos_list.begin() + offset); offset += _small_pos_lists[hash_table_idx].size(); @@ -609,8 +610,8 @@ RadixContainer partition_by_radix(const RadixContainer& radix_container, if constexpr (keep_null_values) { for (auto output_partition_idx = size_t{0}; output_partition_idx < output_partition_count; ++output_partition_idx) { jobs.emplace_back(std::make_shared([&, output_partition_idx]() { - for (auto element_idx = size_t{0}; element_idx < output[output_partition_idx].null_values.size(); - ++element_idx) { + const auto null_value_count = output[output_partition_idx].null_values.size(); + for (auto element_idx = size_t{0}; element_idx < null_value_count; ++element_idx) { output[output_partition_idx].null_values[element_idx] = null_values_as_char[output_partition_idx][element_idx]; } @@ -793,9 +794,11 @@ void probe_semi_anti(const RadixContainer& probe_radix_containe std::vector& pos_lists, const Table& build_table, const Table& probe_table, const std::vector& secondary_join_predicates) { std::vector> jobs; - jobs.reserve(probe_radix_container.size()); - for (size_t partition_idx = 0; partition_idx < probe_radix_container.size(); ++partition_idx) { + const auto probe_radix_container_count = probe_radix_container.size(); + jobs.reserve(probe_radix_container_count); + + for (auto partition_idx = size_t{0}; partition_idx < probe_radix_container_count; ++partition_idx) { // Skip empty partitions to avoid empty output chunks if (probe_radix_container[partition_idx].elements.empty()) { continue; diff --git a/src/lib/operators/join_helper/join_output_writing.hpp b/src/lib/operators/join_helper/join_output_writing.hpp index ca76ff29fd..e7a618235d 100644 --- a/src/lib/operators/join_helper/join_output_writing.hpp +++ b/src/lib/operators/join_helper/join_output_writing.hpp @@ -38,7 +38,7 @@ inline PosListsByChunk setup_pos_lists_by_chunk(const std::shared_ptrcolumn_count(); // For every column, for every chunk - for (ColumnID column_id{0}; column_id < input_columns_count; ++column_id) { + for (auto column_id = ColumnID{0}; column_id < input_columns_count; ++column_id) { // Get all the input pos lists so that we only have to pointer cast the segments once auto pos_list_ptrs = std::make_shared(input_table->chunk_count()); auto pos_lists_iter = pos_list_ptrs->begin(); @@ -81,7 +81,7 @@ inline void write_output_segments(Segments& output_segments, const std::shared_p // Add segments from input table to output chunk // for every column for every row in pos_list: get corresponding PosList of input_pos_list_ptrs_sptrs_by_segments // and add it to new_pos_list which is added to output_segments - for (ColumnID column_id{0}; column_id < input_table->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < input_table->column_count(); ++column_id) { if (input_table->type() == TableType::References) { if (input_table->chunk_count() > 0) { const auto& input_table_pos_lists = input_pos_list_ptrs_sptrs_by_segments[column_id]; diff --git a/src/lib/operators/join_index.cpp b/src/lib/operators/join_index.cpp index ff34ad11e5..60e571c3f7 100644 --- a/src/lib/operators/join_index.cpp +++ b/src/lib/operators/join_index.cpp @@ -539,7 +539,7 @@ void JoinIndex::_write_output_segments(Segments& output_segments, const std::sha const std::shared_ptr& pos_list) { // Add segments from table to output chunk const auto column_count = input_table->column_count(); - for (ColumnID column_id{0}; column_id < column_count; ++column_id) { + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { std::shared_ptr segment; if (input_table->type() == TableType::References) { diff --git a/src/lib/operators/join_nested_loop.cpp b/src/lib/operators/join_nested_loop.cpp index e9ceb3d69a..78a7e9584c 100644 --- a/src/lib/operators/join_nested_loop.cpp +++ b/src/lib/operators/join_nested_loop.cpp @@ -336,7 +336,7 @@ void JoinNestedLoop::_join_two_untyped_segments(const AbstractSegment& abstract_ void JoinNestedLoop::_write_output_chunk(Segments& segments, const std::shared_ptr& input_table, const std::shared_ptr& pos_list) { // Add segments from table to output chunk - for (ColumnID column_id{0}; column_id < input_table->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < input_table->column_count(); ++column_id) { std::shared_ptr segment; if (input_table->type() == TableType::References) { diff --git a/src/lib/operators/join_sort_merge.cpp b/src/lib/operators/join_sort_merge.cpp index f41917504f..1e78705be5 100644 --- a/src/lib/operators/join_sort_merge.cpp +++ b/src/lib/operators/join_sort_merge.cpp @@ -164,8 +164,10 @@ class JoinSortMerge::JoinSortMergeImpl : public AbstractReadOnlyOperatorImpl { // The TablePosition is a utility struct that is used to define a specific position in a sorted input table. struct TableRange; + struct TablePosition { TablePosition() = default; + TablePosition(size_t init_cluster, size_t init_index) : cluster{init_cluster}, index{init_index} {} size_t cluster; @@ -183,6 +185,7 @@ class JoinSortMerge::JoinSortMergeImpl : public AbstractReadOnlyOperatorImpl { // a start position to an end position. struct TableRange { TableRange(TablePosition start_position, TablePosition end_position) : start(start_position), end(end_position) {} + TableRange(size_t cluster, size_t start_index, size_t end_index) : start{TablePosition(cluster, start_index)}, end{TablePosition(cluster, end_index)} {} diff --git a/src/lib/operators/join_sort_merge/column_materializer.hpp b/src/lib/operators/join_sort_merge/column_materializer.hpp index 001d7a9eb7..d98b256d7c 100644 --- a/src/lib/operators/join_sort_merge/column_materializer.hpp +++ b/src/lib/operators/join_sort_merge/column_materializer.hpp @@ -22,6 +22,7 @@ namespace hyrise { template struct MaterializedValue { MaterializedValue() = default; + MaterializedValue(RowID row, T v) : row_id{row}, value{v} {} RowID row_id; @@ -40,6 +41,7 @@ using MaterializedSegmentList = std::vector>; template struct Subsample { explicit Subsample(ChunkOffset sample_count) : samples_to_collect(sample_count), samples(sample_count) {} + const ChunkOffset samples_to_collect; std::vector samples; }; diff --git a/src/lib/operators/join_sort_merge/radix_cluster_sort.hpp b/src/lib/operators/join_sort_merge/radix_cluster_sort.hpp index a78dc43dfd..fd5c7dddc6 100644 --- a/src/lib/operators/join_sort_merge/radix_cluster_sort.hpp +++ b/src/lib/operators/join_sort_merge/radix_cluster_sort.hpp @@ -89,6 +89,7 @@ class RadixClusterSort { cluster_histogram.resize(cluster_count); insert_position.resize(cluster_count); } + // Used to count the number of entries for each cluster from a specific chunk // Example cluster_histogram[3] = 5 // -> 5 values from the chunk belong in cluster 3 @@ -105,6 +106,7 @@ class RadixClusterSort { struct TableInformation { TableInformation(size_t chunk_count, size_t cluster_count) : cluster_histogram(cluster_count, 0), chunk_information(chunk_count, ChunkInformation(cluster_count)) {} + // Used to count the number of entries for each cluster from the whole table std::vector cluster_histogram; std::vector chunk_information; diff --git a/src/lib/operators/join_verification.cpp b/src/lib/operators/join_verification.cpp index c9b672d8bd..aa87cc54de 100644 --- a/src/lib/operators/join_verification.cpp +++ b/src/lib/operators/join_verification.cpp @@ -6,9 +6,9 @@ namespace { template -std::vector concatenate(const std::vector& l, const std::vector& r) { - auto result = l; - result.insert(result.end(), r.begin(), r.end()); +std::vector concatenate(const std::vector& left, const std::vector& right) { + auto result = left; + result.insert(result.end(), right.begin(), right.end()); return result; } @@ -166,8 +166,8 @@ bool JoinVerification::_tuples_match(const Tuple& tuple_left, const Tuple& tuple bool JoinVerification::_evaluate_predicate(const OperatorJoinPredicate& predicate, const Tuple& tuple_left, const Tuple& tuple_right) const { auto result = false; - const auto variant_left = tuple_left[predicate.column_ids.first]; - const auto variant_right = tuple_right[predicate.column_ids.second]; + const auto& variant_left = tuple_left[predicate.column_ids.first]; + const auto& variant_right = tuple_right[predicate.column_ids.second]; if (variant_is_null(variant_left) || variant_is_null(variant_right)) { // AntiNullAsTrue is the only JoinMode that treats null-booleans as TRUE, all others treat it as FALSE diff --git a/src/lib/operators/limit.cpp b/src/lib/operators/limit.cpp index 35d9bdc812..9a28866d69 100644 --- a/src/lib/operators/limit.cpp +++ b/src/lib/operators/limit.cpp @@ -13,9 +13,9 @@ namespace hyrise { -Limit::Limit(const std::shared_ptr& in, +Limit::Limit(const std::shared_ptr& input_operator, const std::shared_ptr& row_count_expression) - : AbstractReadOnlyOperator(OperatorType::Limit, in), _row_count_expression(row_count_expression) {} + : AbstractReadOnlyOperator(OperatorType::Limit, input_operator), _row_count_expression(row_count_expression) {} const std::string& Limit::name() const { static const auto name = std::string{"Limit"}; diff --git a/src/lib/operators/limit.hpp b/src/lib/operators/limit.hpp index 5dbf0ef60a..80d996b624 100644 --- a/src/lib/operators/limit.hpp +++ b/src/lib/operators/limit.hpp @@ -11,7 +11,7 @@ namespace hyrise { // operator to limit the input to n rows class Limit : public AbstractReadOnlyOperator { public: - Limit(const std::shared_ptr& in, + Limit(const std::shared_ptr& input_operator, const std::shared_ptr& row_count_expression); const std::string& name() const override; diff --git a/src/lib/operators/operator_join_predicate.cpp b/src/lib/operators/operator_join_predicate.cpp index 4a45238cd1..30e1959795 100644 --- a/src/lib/operators/operator_join_predicate.cpp +++ b/src/lib/operators/operator_join_predicate.cpp @@ -77,12 +77,12 @@ bool OperatorJoinPredicate::is_flipped() const { return flipped; } -bool operator<(const OperatorJoinPredicate& l, const OperatorJoinPredicate& r) { - return std::tie(l.column_ids, l.predicate_condition) < std::tie(r.column_ids, r.predicate_condition); +bool operator<(const OperatorJoinPredicate& lhs, const OperatorJoinPredicate& rhs) { + return std::tie(lhs.column_ids, lhs.predicate_condition) < std::tie(rhs.column_ids, rhs.predicate_condition); } -bool operator==(const OperatorJoinPredicate& l, const OperatorJoinPredicate& r) { - return std::tie(l.column_ids, l.predicate_condition) == std::tie(r.column_ids, r.predicate_condition); +bool operator==(const OperatorJoinPredicate& lhs, const OperatorJoinPredicate& rhs) { + return std::tie(lhs.column_ids, lhs.predicate_condition) == std::tie(rhs.column_ids, rhs.predicate_condition); } } // namespace hyrise diff --git a/src/lib/operators/operator_scan_predicate.cpp b/src/lib/operators/operator_scan_predicate.cpp index 343a5545de..dcf7505d06 100644 --- a/src/lib/operators/operator_scan_predicate.cpp +++ b/src/lib/operators/operator_scan_predicate.cpp @@ -77,9 +77,9 @@ std::optional> OperatorScanPredicate::from_ex if (is_column_id(*argument_a)) { return std::vector{ OperatorScanPredicate{boost::get(*argument_a), predicate_condition}}; - } else { - return std::nullopt; } + + return std::nullopt; } Assert(predicate->arguments.size() > 1, "Expect non-unary PredicateExpression to have two or more arguments"); diff --git a/src/lib/operators/print.cpp b/src/lib/operators/print.cpp index d8d8def961..7070f1cbc8 100644 --- a/src/lib/operators/print.cpp +++ b/src/lib/operators/print.cpp @@ -34,8 +34,8 @@ bool has_print_ignore_chunk_boundaries_flag(const PrintFlags flags) { namespace hyrise { -Print::Print(const std::shared_ptr& in, const PrintFlags flags, std::ostream& out) - : AbstractReadOnlyOperator(OperatorType::Print, in), _flags(flags), _out(out) {} +Print::Print(const std::shared_ptr& input_operator, const PrintFlags flags, std::ostream& out) + : AbstractReadOnlyOperator(OperatorType::Print, input_operator), _flags(flags), _out(out) {} const std::string& Print::name() const { static const auto name = std::string{"Print"}; @@ -57,8 +57,8 @@ void Print::print(const std::shared_ptr& table, const PrintFlags fl Print(table_wrapper, flags, out).execute(); } -void Print::print(const std::shared_ptr& in, const PrintFlags flags, std::ostream& out) { - Print(in, flags, out).execute(); +void Print::print(const std::shared_ptr& op, const PrintFlags flags, std::ostream& out) { + Print(op, flags, out).execute(); } void Print::print(const std::string& sql, const PrintFlags flags, std::ostream& out) { @@ -77,25 +77,26 @@ void Print::print(const std::string& sql, const PrintFlags flags, std::ostream& std::shared_ptr Print::_on_execute() { PerformanceWarningDisabler pwd; - auto widths = _column_string_widths(_min_cell_width, _max_cell_width, left_input_table()); + const auto widths = _column_string_widths(_min_cell_width, _max_cell_width, left_input_table()); + const auto column_count = left_input_table()->column_count(); // print column headers _out << "=== Columns" << std::endl; - for (ColumnID column_id{0}; column_id < left_input_table()->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { _out << "|" << std::setw(widths[column_id]) << left_input_table()->column_name(column_id) << std::setw(0); } if (has_print_mvcc_flag(_flags)) { _out << "|| MVCC "; } _out << "|" << std::endl; - for (ColumnID column_id{0}; column_id < left_input_table()->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { _out << "|" << std::setw(widths[column_id]) << left_input_table()->column_data_type(column_id) << std::setw(0); } if (has_print_mvcc_flag(_flags)) { _out << "||_BEGIN|_END |_TID "; } _out << "|" << std::endl; - for (ColumnID column_id{0}; column_id < left_input_table()->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { const auto nullable = left_input_table()->column_is_nullable(column_id); _out << "|" << std::setw(widths[column_id]) << (nullable ? "null" : "not null") << std::setw(0); } @@ -106,7 +107,7 @@ std::shared_ptr Print::_on_execute() { // print each chunk const auto chunk_count = left_input_table()->chunk_count(); - for (ChunkID chunk_id{0}; chunk_id < chunk_count; ++chunk_id) { + for (auto chunk_id = ChunkID{0}; chunk_id < chunk_count; ++chunk_id) { const auto chunk = left_input_table()->get_chunk(chunk_id); if (!chunk) { continue; @@ -121,7 +122,7 @@ std::shared_ptr Print::_on_execute() { } // print the encoding information - for (ColumnID column_id{0}; column_id < chunk->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { const auto column_width = widths[column_id]; const auto& segment = chunk->get_segment(column_id); _out << "|" << std::setw(column_width) << std::left << _segment_type(segment) << std::right << std::setw(0); @@ -133,9 +134,10 @@ std::shared_ptr Print::_on_execute() { } // print the rows in the chunk - for (auto chunk_offset = ChunkOffset{0}; chunk_offset < chunk->size(); ++chunk_offset) { + const auto chunk_size = chunk->size(); + for (auto chunk_offset = ChunkOffset{0}; chunk_offset < chunk_size; ++chunk_offset) { _out << "|"; - for (ColumnID column_id{0}; column_id < chunk->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { // well yes, we use AbstractSegment::operator[] here, but since Print is not an operation that should // be part of a regular query plan, let's keep things simple here auto column_width = widths[column_id]; @@ -171,22 +173,25 @@ std::shared_ptr Print::_on_execute() { // `min` and `max` can be used to limit the width of the columns - however, every column fits at least the column's name std::vector Print::_column_string_widths(uint16_t min, uint16_t max, const std::shared_ptr& table) const { - std::vector widths(table->column_count()); + const auto column_count = table->column_count(); + std::vector widths(column_count); // calculate the length of the column name - for (ColumnID column_id{0}; column_id < table->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { widths[column_id] = std::max(min, static_cast(table->column_name(column_id).size())); } // go over all rows and find the maximum length of the printed representation of a value, up to max const auto chunk_count = left_input_table()->chunk_count(); - for (ChunkID chunk_id{0}; chunk_id < chunk_count; ++chunk_id) { + for (auto chunk_id = ChunkID{0}; chunk_id < chunk_count; ++chunk_id) { const auto chunk = left_input_table()->get_chunk(chunk_id); if (!chunk) { continue; } - for (ColumnID column_id{0}; column_id < chunk->column_count(); ++column_id) { - for (auto chunk_offset = ChunkOffset{0}; chunk_offset < chunk->size(); ++chunk_offset) { + const auto column_count = chunk->column_count(); + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { + const auto chunk_size = chunk->size(); + for (auto chunk_offset = ChunkOffset{0}; chunk_offset < chunk_size; ++chunk_offset) { std::ostringstream stream; stream << (*chunk->get_segment(column_id))[chunk_offset]; auto cell_length = static_cast(stream.str().size()); diff --git a/src/lib/operators/print.hpp b/src/lib/operators/print.hpp index f77d69e690..242ee33011 100644 --- a/src/lib/operators/print.hpp +++ b/src/lib/operators/print.hpp @@ -21,14 +21,14 @@ enum class PrintFlags : uint32_t { None = 0u, Mvcc = 1u << 0u, IgnoreChunkBounda */ class Print : public AbstractReadOnlyOperator { public: - explicit Print(const std::shared_ptr& in, const PrintFlags flags = PrintFlags::None, - std::ostream& out = std::cout); + explicit Print(const std::shared_ptr& input_operator, + const PrintFlags flags = PrintFlags::None, std::ostream& out = std::cout); const std::string& name() const override; static void print(const std::shared_ptr& table, const PrintFlags flags = PrintFlags::None, std::ostream& out = std::cout); - static void print(const std::shared_ptr& in, const PrintFlags flags = PrintFlags::None, + static void print(const std::shared_ptr& op, const PrintFlags flags = PrintFlags::None, std::ostream& out = std::cout); // Convenience method to print the result of an SQL query diff --git a/src/lib/operators/product.cpp b/src/lib/operators/product.cpp index 3e9b38b8b8..19827519c3 100644 --- a/src/lib/operators/product.cpp +++ b/src/lib/operators/product.cpp @@ -22,12 +22,14 @@ std::shared_ptr Product::_on_execute() { TableColumnDefinitions column_definitions; // add columns from left table to output - for (ColumnID column_id{0}; column_id < left_input_table()->column_count(); ++column_id) { + const auto left_input_column_count = left_input_table()->column_count(); + for (auto column_id = ColumnID{0}; column_id < left_input_column_count; ++column_id) { column_definitions.emplace_back(left_input_table()->column_definitions()[column_id]); } // add columns from right table to output - for (ColumnID column_id{0}; column_id < right_input_table()->column_count(); ++column_id) { + const auto right_input_column_count = right_input_table()->column_count(); + for (auto column_id = ColumnID{0}; column_id < right_input_column_count; ++column_id) { column_definitions.emplace_back(right_input_table()->column_definitions()[column_id]); } @@ -35,11 +37,11 @@ std::shared_ptr Product::_on_execute() { auto chunk_count_left_table = left_input_table()->chunk_count(); auto chunk_count_right_table = right_input_table()->chunk_count(); - for (ChunkID chunk_id_left = ChunkID{0}; chunk_id_left < chunk_count_left_table; ++chunk_id_left) { + for (auto chunk_id_left = ChunkID{0}; chunk_id_left < chunk_count_left_table; ++chunk_id_left) { const auto chunk_left = left_input_table()->get_chunk(chunk_id_left); Assert(chunk_left, "Physically deleted chunk should not reach this point, see get_chunk / #1686."); - for (ChunkID chunk_id_right = ChunkID{0}; chunk_id_right < chunk_count_right_table; ++chunk_id_right) { + for (auto chunk_id_right = ChunkID{0}; chunk_id_right < chunk_count_right_table; ++chunk_id_right) { const auto chunk_right = right_input_table()->get_chunk(chunk_id_right); Assert(chunk_right, "Physically deleted chunk should not reach this point, see get_chunk / #1686."); @@ -77,7 +79,8 @@ void Product::_add_product_of_two_chunks(const std::shared_ptr
& output, C // duplication auto table = is_left_side ? left_input_table() : right_input_table(); - for (ColumnID column_id{0}; column_id < chunk_in->column_count(); ++column_id) { + const auto column_count = chunk_in->column_count(); + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { std::shared_ptr referenced_table; ColumnID referenced_segment; std::shared_ptr pos_list_in; @@ -92,17 +95,20 @@ void Product::_add_product_of_two_chunks(const std::shared_ptr
& output, C referenced_segment = column_id; } - // see if we can reuse a PosList that we already calculated - important to use a reference here so that the map - // gets updated accordingly + // See if we can reuse a PosList that we already calculated - important to use a reference here so that the map + // gets updated accordingly. auto& pos_list_out = (is_left_side ? calculated_pos_lists_left : calculated_pos_lists_right)[pos_list_in]; if (!pos_list_out) { // can't reuse + const auto left_chunk_size = chunk_left->size(); + const auto right_chunk_size = chunk_right->size(); + const auto pos_list_size = static_cast(left_chunk_size) * right_chunk_size; pos_list_out = std::make_shared(); - pos_list_out->reserve(chunk_left->size() * chunk_right->size()); - for (size_t i = 0; i < chunk_left->size() * chunk_right->size(); ++i) { + pos_list_out->reserve(pos_list_size); + for (auto pos_list_index = size_t{0}; pos_list_index < pos_list_size; ++pos_list_index) { // size_t is sufficient here, because ChunkOffset::max is 2^32 and (2^32 * 2^32 = 2^64) - auto offset = is_left_side ? static_cast(i / chunk_right->size()) - : static_cast(i % chunk_right->size()); + auto offset = is_left_side ? static_cast(pos_list_index / right_chunk_size) + : static_cast(pos_list_index % right_chunk_size); if (pos_list_in) { pos_list_out->emplace_back((*pos_list_in)[offset]); } else { diff --git a/src/lib/operators/projection.cpp b/src/lib/operators/projection.cpp index 49625e1a4a..e2f212a367 100644 --- a/src/lib/operators/projection.cpp +++ b/src/lib/operators/projection.cpp @@ -344,7 +344,8 @@ std::shared_ptr
Projection::dummy_table() { ExpressionUnorderedSet Projection::_determine_forwarded_columns(const TableType table_type) const { // First gather all forwardable PQP column expressions. auto forwarded_pqp_columns = ExpressionUnorderedSet{}; - for (auto column_id = ColumnID{0}; column_id < expressions.size(); ++column_id) { + const auto expression_count = expressions.size(); + for (auto column_id = ColumnID{0}; column_id < expression_count; ++column_id) { const auto& expression = expressions[column_id]; if (expression->type == ExpressionType::PQPColumn) { forwarded_pqp_columns.emplace(expression); @@ -356,7 +357,7 @@ ExpressionUnorderedSet Projection::_determine_forwarded_columns(const TableType // forwarded column does not need to be accessed via its position list later. And since the following operator might // have optimizations for accessing an encoded segment, we always forward for data tables. if (table_type == TableType::References) { - for (auto column_id = ColumnID{0}; column_id < expressions.size(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < expression_count; ++column_id) { const auto& expression = expressions[column_id]; if (expression->type == ExpressionType::PQPColumn) { diff --git a/src/lib/operators/sort.cpp b/src/lib/operators/sort.cpp index 0d91274f21..b35b68e0b7 100644 --- a/src/lib/operators/sort.cpp +++ b/src/lib/operators/sort.cpp @@ -7,6 +7,12 @@ namespace { using namespace hyrise; // NOLINT +// Ceiling of integer division +size_t div_ceil(const size_t lhs, const ChunkOffset rhs) { + DebugAssert(rhs > 0, "Divisor must be larger than 0."); + return (lhs + rhs - 1u) / rhs; +} + // Given an unsorted_table and a pos_list that defines the output order, this materializes all columns in the table, // creating chunks of output_chunk_size rows at maximum. std::shared_ptr
write_materialized_output_table(const std::shared_ptr& unsorted_table, @@ -19,8 +25,6 @@ std::shared_ptr
write_materialized_output_table(const std::shared_ptrrow_count(), "Mismatching size of input table and PosList"); @@ -136,8 +140,6 @@ std::shared_ptr
write_reference_output_table(const std::shared_ptrtype() == TableType::References; const auto column_count = output_table->column_count(); - // Ceiling of integer division - const auto div_ceil = [](auto x, auto y) { return (x + y - 1u) / y; }; const auto output_chunk_count = div_ceil(input_pos_list.size(), output_chunk_size); Assert(input_pos_list.size() == unsorted_table->row_count(), "Mismatching size of input table and PosList"); @@ -189,7 +191,8 @@ std::shared_ptr
write_reference_output_table(const std::shared_ptr write_reference_output_table(const std::shared_ptr& in, const std::vector& sort_definitions, - const ChunkOffset output_chunk_size, const ForceMaterialization force_materialization) - : AbstractReadOnlyOperator(OperatorType::Sort, in, nullptr, +Sort::Sort(const std::shared_ptr& input_operator, + const std::vector& sort_definitions, const ChunkOffset output_chunk_size, + const ForceMaterialization force_materialization) + : AbstractReadOnlyOperator(OperatorType::Sort, input_operator, nullptr, std::make_unique>()), _sort_definitions(sort_definitions), _output_chunk_size(output_chunk_size), @@ -265,9 +269,9 @@ std::shared_ptr Sort::_on_execute() { if (input_table->row_count() == 0) { if (_force_materialization == ForceMaterialization::Yes && input_table->type() == TableType::References) { return Table::create_dummy_table(input_table->column_definitions()); - } else { - return input_table; } + + return input_table; } std::shared_ptr
sorted_table; @@ -386,8 +390,9 @@ class Sort::SortImpl { // 2. After we got our ValueRowID Map we sort the map by the value of the pair const auto sort_with_comparator = [&](auto comparator) { - std::stable_sort(_row_id_value_vector.begin(), _row_id_value_vector.end(), - [comparator](RowIDValuePair a, RowIDValuePair b) { return comparator(a.second, b.second); }); + std::stable_sort( + _row_id_value_vector.begin(), _row_id_value_vector.end(), + [comparator](RowIDValuePair lhs, RowIDValuePair rhs) { return comparator(lhs.second, rhs.second); }); }; if (_sort_mode == SortMode::Ascending) { sort_with_comparator(std::less<>{}); diff --git a/src/lib/operators/sort.hpp b/src/lib/operators/sort.hpp index 37a455b118..0df34625f4 100644 --- a/src/lib/operators/sort.hpp +++ b/src/lib/operators/sort.hpp @@ -25,7 +25,8 @@ class Sort : public AbstractReadOnlyOperator { enum class OperatorSteps : uint8_t { MaterializeSortColumns, Sort, TemporaryResultWriting, WriteOutput }; - Sort(const std::shared_ptr& in, const std::vector& sort_definitions, + Sort(const std::shared_ptr& input_operator, + const std::vector& sort_definitions, const ChunkOffset output_chunk_size = Chunk::DEFAULT_SIZE, const ForceMaterialization force_materialization = ForceMaterialization::No); diff --git a/src/lib/operators/table_scan.cpp b/src/lib/operators/table_scan.cpp index 9dd4f9dd69..250e3865c2 100644 --- a/src/lib/operators/table_scan.cpp +++ b/src/lib/operators/table_scan.cpp @@ -40,9 +40,9 @@ namespace hyrise { -TableScan::TableScan(const std::shared_ptr& in, +TableScan::TableScan(const std::shared_ptr& input_operator, const std::shared_ptr& predicate) - : AbstractReadOnlyOperator{OperatorType::TableScan, in, nullptr, std::make_unique()}, + : AbstractReadOnlyOperator{OperatorType::TableScan, input_operator, nullptr, std::make_unique()}, _predicate(predicate) { /** * Register as a consumer for all uncorrelated subqueries. @@ -117,8 +117,8 @@ std::shared_ptr TableScan::_on_execute() { jobs.reserve(in_table->chunk_count() - excluded_chunk_set.size()); const auto chunk_count = in_table->chunk_count(); - for (ChunkID chunk_id{0u}; chunk_id < chunk_count; ++chunk_id) { - if (excluded_chunk_set.count(chunk_id)) { + for (auto chunk_id = ChunkID{0}; chunk_id < chunk_count; ++chunk_id) { + if (excluded_chunk_set.contains(chunk_id)) { continue; } const auto chunk_in = in_table->get_chunk(chunk_id); @@ -132,8 +132,9 @@ std::shared_ptr TableScan::_on_execute() { return; } + const auto column_count = in_table->column_count(); Segments out_segments; - out_segments.reserve(in_table->column_count()); + out_segments.reserve(column_count); /** * matches_out contains a list of row IDs into this chunk. If this is not a reference table, we can directly use @@ -148,14 +149,14 @@ std::shared_ptr TableScan::_on_execute() { if (in_table->type() == TableType::References) { if (matches_out->size() == chunk_in->size()) { // Shortcut - the entire input reference segment matches, so we can simply forward that chunk - for (ColumnID column_id{0u}; column_id < in_table->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { const auto segment_in = chunk_in->get_segment(column_id); out_segments.emplace_back(segment_in); } } else { auto filtered_pos_lists = std::map, std::shared_ptr>{}; - for (ColumnID column_id{0u}; column_id < in_table->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { const auto segment_in = chunk_in->get_segment(column_id); auto ref_segment_in = std::dynamic_pointer_cast(segment_in); @@ -180,7 +181,7 @@ std::shared_ptr TableScan::_on_execute() { keep_chunk_sort_order = false; } - size_t offset = 0; + auto offset = size_t{0}; for (const auto& match : *matches_out) { const auto row_id = (*pos_list_in)[match.chunk_offset]; (*filtered_pos_list)[offset] = row_id; @@ -202,7 +203,7 @@ std::shared_ptr TableScan::_on_execute() { std::make_shared(chunk_id, chunk_in->size())) : static_cast>(matches_out); - for (auto column_id = ColumnID{0u}; column_id < in_table->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { const auto ref_segment_out = std::make_shared(in_table, column_id, output_pos_list); out_segments.push_back(ref_segment_out); } diff --git a/src/lib/operators/table_scan.hpp b/src/lib/operators/table_scan.hpp index e9a022f23c..8ed662ae45 100644 --- a/src/lib/operators/table_scan.hpp +++ b/src/lib/operators/table_scan.hpp @@ -21,7 +21,8 @@ class TableScan : public AbstractReadOnlyOperator { friend class LQPTranslatorTest; public: - TableScan(const std::shared_ptr& in, const std::shared_ptr& predicate); + TableScan(const std::shared_ptr& input_operator, + const std::shared_ptr& predicate); const std::shared_ptr& predicate() const; diff --git a/src/lib/operators/table_scan/abstract_table_scan_impl.hpp b/src/lib/operators/table_scan/abstract_table_scan_impl.hpp index 8a7e3175ba..f129643bbe 100644 --- a/src/lib/operators/table_scan/abstract_table_scan_impl.hpp +++ b/src/lib/operators/table_scan/abstract_table_scan_impl.hpp @@ -134,15 +134,15 @@ class AbstractTableScanImpl { {} // clang-format off #pragma omp simd reduction(|:mask) safelen(BLOCK_SIZE) // clang-format on - for (size_t i = 0; i < BLOCK_SIZE; ++i) { + for (auto index = size_t{0}; index < BLOCK_SIZE; ++index) { // Fill `mask` with 1s at positions where the condition is fulfilled const auto& left = *left_it; if constexpr (std::is_same_v) { - mask |= ((!CheckForNull | !left.is_null()) && func(left)) << i; + mask |= ((!CheckForNull | !left.is_null()) && func(left)) << index; } else { const auto& right = *right_it; - mask |= ((!CheckForNull | (!left.is_null() && !right.is_null())) & func(left, right)) << i; + mask |= ((!CheckForNull | (!left.is_null() && !right.is_null())) & func(left, right)) << index; } ++left_it; @@ -171,8 +171,8 @@ class AbstractTableScanImpl { {} // clang-format off #pragma omp simd safelen(BLOCK_SIZE) // clang-format on - for (size_t i = 0; i < BLOCK_SIZE; ++i) { - offsets[i] = first_offset + static_cast(i); + for (auto index = size_t{0}; index < BLOCK_SIZE; ++index) { + offsets[index] = first_offset + static_cast(index); } left_it_for_offsets += BLOCK_SIZE; @@ -183,8 +183,8 @@ class AbstractTableScanImpl { {} // clang-format off #pragma omp simd safelen(BLOCK_SIZE) // clang-format on - for (auto i = size_t{0}; i < BLOCK_SIZE; ++i) { - offsets[i] = left_it_for_offsets->chunk_offset(); + for (auto index = size_t{0}; index < BLOCK_SIZE; ++index) { + offsets[index] = left_it_for_offsets->chunk_offset(); ++left_it_for_offsets; } } @@ -192,9 +192,9 @@ class AbstractTableScanImpl { // Now write the matches into matches_out. #ifndef __AVX512VL__ // "Slow" path for non-AVX512VL systems - for (auto i = size_t{0}; i < BLOCK_SIZE; ++i) { - if (mask >> i & 1) { - matches_out[matches_out_index++].chunk_offset = offsets[i]; + for (auto index = size_t{0}; index < BLOCK_SIZE; ++index) { + if (mask >> index & 1) { + matches_out[matches_out_index++].chunk_offset = offsets[index]; } } @@ -217,8 +217,8 @@ class AbstractTableScanImpl { {} // clang-format off #pragma omp simd safelen(BLOCK_SIZE) // clang-format on - for (auto i = size_t{0}; i < BLOCK_SIZE; ++i) { - matches_out[matches_out_index + i].chunk_offset = (reinterpret_cast(&offsets_simd))[i]; + for (auto index = size_t{0}; index < BLOCK_SIZE; ++index) { + matches_out[matches_out_index + index].chunk_offset = (reinterpret_cast(&offsets_simd))[index]; } // Count the number of matches and increase the index of the next write to matches_out accordingly diff --git a/src/lib/operators/table_scan/column_is_null_table_scan_impl.cpp b/src/lib/operators/table_scan/column_is_null_table_scan_impl.cpp index c523a621b7..0d84cf1a64 100644 --- a/src/lib/operators/table_scan/column_is_null_table_scan_impl.cpp +++ b/src/lib/operators/table_scan/column_is_null_table_scan_impl.cpp @@ -53,12 +53,12 @@ std::shared_ptr ColumnIsNullTableScanImpl::scan_chunk(const ChunkI void ColumnIsNullTableScanImpl::_scan_generic_segment(const AbstractSegment& segment, const ChunkID chunk_id, RowIDPosList& matches) const { - segment_with_iterators(segment, [&](auto it, [[maybe_unused]] const auto end) { + segment_with_iterators(segment, [&](auto iter, [[maybe_unused]] const auto end) { // This may also be called for a ValueSegment if `segment` is a ReferenceSegment pointing to a single ValueSegment. const auto invert = _predicate_condition == PredicateCondition::IsNotNull; const auto functor = [&](const auto& value) { return invert ^ value.is_null(); }; - _scan_with_iterators(functor, it, end, chunk_id, matches); + _scan_with_iterators(functor, iter, end, chunk_id, matches); }); } @@ -69,7 +69,8 @@ void ColumnIsNullTableScanImpl::_scan_generic_sorted_segment(const AbstractSegme segment_with_iterators(segment, [&](auto begin, auto end) { if (is_nulls_first) { const auto first_not_null = std::lower_bound( - begin, end, bool{}, [](const auto& segment_position, const auto& _) { return segment_position.is_null(); }); + begin, end, bool{}, + [](const auto& segment_position, const auto& /*end*/) { return segment_position.is_null(); }); if (predicate_is_null) { end = first_not_null; } else { @@ -78,7 +79,8 @@ void ColumnIsNullTableScanImpl::_scan_generic_sorted_segment(const AbstractSegme } else { // NULLs last. const auto first_null = std::lower_bound( - begin, end, bool{}, [](const auto& segment_position, const auto& _) { return !segment_position.is_null(); }); + begin, end, bool{}, + [](const auto& segment_position, const auto& /*end*/) { return !segment_position.is_null(); }); if (predicate_is_null) { begin = first_null; } else { @@ -112,7 +114,8 @@ void ColumnIsNullTableScanImpl::_scan_value_segment(const BaseValueSegment& segm const auto invert = _predicate_condition == PredicateCondition::IsNotNull; const auto functor = [&](const auto& value) { return invert ^ value.is_null(); }; - iterable.with_iterators([&](auto it, auto end) { _scan_with_iterators(functor, it, end, chunk_id, matches); }); + iterable.with_iterators( + [&](auto iter, auto end) { _scan_with_iterators(functor, iter, end, chunk_id, matches); }); } bool ColumnIsNullTableScanImpl::_matches_all(const BaseValueSegment& segment) const { diff --git a/src/lib/operators/table_scan/column_like_table_scan_impl.cpp b/src/lib/operators/table_scan/column_like_table_scan_impl.cpp index d97f0fcca6..0958846abd 100644 --- a/src/lib/operators/table_scan/column_like_table_scan_impl.cpp +++ b/src/lib/operators/table_scan/column_like_table_scan_impl.cpp @@ -47,16 +47,16 @@ void ColumnLikeTableScanImpl::_scan_non_reference_segment( void ColumnLikeTableScanImpl::_scan_generic_segment( const AbstractSegment& segment, const ChunkID chunk_id, RowIDPosList& matches, const std::shared_ptr& position_filter) const { - segment_with_iterators_filtered(segment, position_filter, [&](auto it, [[maybe_unused]] const auto end) { + segment_with_iterators_filtered(segment, position_filter, [&](auto iter, [[maybe_unused]] const auto end) { // Don't instantiate this for ReferenceSegments to save compile time as ReferenceSegments are handled // via position_filter - if constexpr (!is_reference_segment_iterable_v) { - using ColumnDataType = typename decltype(it)::ValueType; + if constexpr (!is_reference_segment_iterable_v) { + using ColumnDataType = typename decltype(iter)::ValueType; if constexpr (std::is_same_v) { _matcher.resolve(_invert_results, [&](const auto& resolved_matcher) { const auto functor = [&](const auto& position) { return resolved_matcher(position.value()); }; - _scan_with_iterators(functor, it, end, chunk_id, matches); + _scan_with_iterators(functor, iter, end, chunk_id, matches); }); } else { Fail("Can only handle strings"); @@ -90,9 +90,9 @@ void ColumnLikeTableScanImpl::_scan_dictionary_segment(const BaseDictionarySegme // LIKE matches all rows, but we still need to check for NULL if (match_count == dictionary_matches.size()) { - attribute_vector_iterable.with_iterators(position_filter, [&](auto it, auto end) { + attribute_vector_iterable.with_iterators(position_filter, [&](auto iter, auto end) { static const auto always_true = [](const auto&) { return true; }; - _scan_with_iterators(always_true, it, end, chunk_id, matches); + _scan_with_iterators(always_true, iter, end, chunk_id, matches); }); return; @@ -108,8 +108,8 @@ void ColumnLikeTableScanImpl::_scan_dictionary_segment(const BaseDictionarySegme return dictionary_matches[position.value()]; }; - attribute_vector_iterable.with_iterators(position_filter, [&](auto it, auto end) { - _scan_with_iterators(dictionary_lookup, it, end, chunk_id, matches); + attribute_vector_iterable.with_iterators(position_filter, [&](auto iter, auto end) { + _scan_with_iterators(dictionary_lookup, iter, end, chunk_id, matches); }); } diff --git a/src/lib/operators/table_scan/column_vs_column_table_scan_impl.cpp b/src/lib/operators/table_scan/column_vs_column_table_scan_impl.cpp index 1eaa4876fb..1bcd410941 100644 --- a/src/lib/operators/table_scan/column_vs_column_table_scan_impl.cpp +++ b/src/lib/operators/table_scan/column_vs_column_table_scan_impl.cpp @@ -170,6 +170,7 @@ ColumnVsColumnTableScanImpl::_typed_scan_chunk_with_iterators(ChunkID chunk_id, if (condition_was_flipped) { const auto erased_comparator = conditionally_erase_comparator_type(comparator, right_it, left_it); + // NOLINTNEXTLINE(readability-suspicious-call-argument) - flipped arguments by intention AbstractTableScanImpl::_scan_with_iterators(erased_comparator, right_it, right_end, chunk_id, *matches_out, left_it); } else { diff --git a/src/lib/operators/table_scan/column_vs_value_table_scan_impl.hpp b/src/lib/operators/table_scan/column_vs_value_table_scan_impl.hpp index 4559483901..44641b312f 100644 --- a/src/lib/operators/table_scan/column_vs_value_table_scan_impl.hpp +++ b/src/lib/operators/table_scan/column_vs_value_table_scan_impl.hpp @@ -80,6 +80,7 @@ class ColumnVsValueTableScanImpl : public AbstractDereferencedColumnTableScanImp Fail("Unsupported comparison type encountered"); } } + /**@}*/ private: const bool _column_is_nullable; diff --git a/src/lib/operators/union_all.cpp b/src/lib/operators/union_all.cpp index 7bdbd53eb2..8a21f62e7f 100644 --- a/src/lib/operators/union_all.cpp +++ b/src/lib/operators/union_all.cpp @@ -40,7 +40,7 @@ std::shared_ptr UnionAll::_on_execute() { Segments output_segments; // iterating over all segments of the current chunk - for (ColumnID column_id{0}; column_id < input->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < input->column_count(); ++column_id) { output_segments.push_back(chunk->get_segment(column_id)); } @@ -53,6 +53,7 @@ std::shared_ptr UnionAll::_on_execute() { return std::make_shared
(left_input_table()->column_definitions(), left_input_table()->type(), std::move(output_chunks)); } + std::shared_ptr UnionAll::_on_deep_copy( const std::shared_ptr& copied_left_input, const std::shared_ptr& copied_right_input, diff --git a/src/lib/operators/validate.cpp b/src/lib/operators/validate.cpp index 2fe3543391..3591e82e7b 100644 --- a/src/lib/operators/validate.cpp +++ b/src/lib/operators/validate.cpp @@ -55,8 +55,8 @@ bool Validate::_is_entire_chunk_visible(const std::shared_ptr& chun return snapshot_commit_id >= max_begin_cid && chunk->invalid_row_count() == 0; } -Validate::Validate(const std::shared_ptr& in) - : AbstractReadOnlyOperator(OperatorType::Validate, in) {} +Validate::Validate(const std::shared_ptr& input_operator) + : AbstractReadOnlyOperator(OperatorType::Validate, input_operator) {} const std::string& Validate::name() const { static const auto name = std::string{"Validate"}; @@ -80,8 +80,8 @@ std::shared_ptr Validate::_on_execute(std::shared_ptrphase() == TransactionPhase::Active, "Transaction is not active anymore."); - const auto in_table = left_input_table(); - const auto chunk_count = in_table->chunk_count(); + const auto input_table = left_input_table(); + const auto chunk_count = input_table->chunk_count(); const auto our_tid = transaction_context->transaction_id(); const auto snapshot_commit_id = transaction_context->snapshot_commit_id(); @@ -111,7 +111,7 @@ std::shared_ptr Validate::_on_execute(std::shared_ptrget_chunk(job_end_chunk_id); + const auto chunk = input_table->get_chunk(job_end_chunk_id); Assert(chunk, "Physically deleted chunk should not reach this point, see get_chunk / #1686."); // Small chunks are bundled together to avoid unnecessary scheduling overhead. @@ -122,12 +122,12 @@ std::shared_ptr Validate::_on_execute(std::shared_ptr([=, this, &output_chunks, &output_mutex] { - _validate_chunks(in_table, job_start_chunk_id, job_end_chunk_id, our_tid, snapshot_commit_id, output_chunks, - output_mutex); + _validate_chunks(input_table, job_start_chunk_id, job_end_chunk_id, our_tid, snapshot_commit_id, + output_chunks, output_mutex); })); // Prepare next job @@ -140,10 +140,10 @@ std::shared_ptr Validate::_on_execute(std::shared_ptrschedule_and_wait_for_tasks(jobs); - return std::make_shared
(in_table->column_definitions(), TableType::References, std::move(output_chunks)); + return std::make_shared
(input_table->column_definitions(), TableType::References, std::move(output_chunks)); } -void Validate::_validate_chunks(const std::shared_ptr& in_table, const ChunkID chunk_id_start, +void Validate::_validate_chunks(const std::shared_ptr& input_table, const ChunkID chunk_id_start, const ChunkID chunk_id_end, const TransactionID our_tid, const CommitID snapshot_commit_id, std::vector>& output_chunks, std::mutex& output_mutex) const { @@ -155,7 +155,7 @@ void Validate::_validate_chunks(const std::shared_ptr& in_table, co auto entirely_visible_chunks_table = std::shared_ptr{}; // used only for sanity check for (auto chunk_id = chunk_id_start; chunk_id <= chunk_id_end; ++chunk_id) { - const auto chunk_in = in_table->get_chunk(chunk_id); + const auto chunk_in = input_table->get_chunk(chunk_id); Assert(chunk_in, "Physically deleted chunk should not reach this point, see get_chunk / #1686."); const auto expected_number_of_valid_rows = chunk_in->size() - chunk_in->invalid_row_count(); @@ -242,7 +242,7 @@ void Validate::_validate_chunks(const std::shared_ptr& in_table, co } // Construct the actual ReferenceSegment objects and add them to the chunk. - for (ColumnID column_id{0}; column_id < chunk_in->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < chunk_in->column_count(); ++column_id) { const auto reference_segment = std::static_pointer_cast(chunk_in->get_segment(column_id)); const auto referenced_column_id = reference_segment->referenced_column_id(); @@ -252,7 +252,7 @@ void Validate::_validate_chunks(const std::shared_ptr& in_table, co // Otherwise we have a non-reference Segment and simply iterate over all rows to build a poslist. } else { - referenced_table = in_table; + referenced_table = input_table; DebugAssert(chunk_in->has_mvcc_data(), "Trying to use Validate on a table that has no MVCC data"); @@ -275,7 +275,7 @@ void Validate::_validate_chunks(const std::shared_ptr& in_table, co } // Create actual ReferenceSegment objects. - for (ColumnID column_id{0}; column_id < chunk_in->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < chunk_in->column_count(); ++column_id) { auto ref_segment_out = std::make_shared(referenced_table, column_id, pos_list_out); output_segments.push_back(ref_segment_out); } diff --git a/src/lib/operators/validate.hpp b/src/lib/operators/validate.hpp index 8e951d201b..64bd5f8256 100644 --- a/src/lib/operators/validate.hpp +++ b/src/lib/operators/validate.hpp @@ -20,7 +20,7 @@ class Validate : public AbstractReadOnlyOperator { friend class OperatorsValidateTest; public: - explicit Validate(const std::shared_ptr& in); + explicit Validate(const std::shared_ptr& input_operator); const std::string& name() const override; @@ -29,7 +29,7 @@ class Validate : public AbstractReadOnlyOperator { const CommitID begin_cid, const CommitID end_cid); private: - void _validate_chunks(const std::shared_ptr& in_table, const ChunkID chunk_id_start, + void _validate_chunks(const std::shared_ptr& input_table, const ChunkID chunk_id_start, const ChunkID chunk_id_end, const TransactionID our_tid, const CommitID snapshot_commit_id, std::vector>& output_chunks, std::mutex& output_mutex) const; diff --git a/src/lib/optimizer/join_ordering/enumerate_ccp.cpp b/src/lib/optimizer/join_ordering/enumerate_ccp.cpp index f066a372ab..50b609b9ad 100644 --- a/src/lib/optimizer/join_ordering/enumerate_ccp.cpp +++ b/src/lib/optimizer/join_ordering/enumerate_ccp.cpp @@ -47,14 +47,14 @@ std::vector> EnumerateCcp::ope * each vertex (_enumerate_csg_recursive()). * For each subgraph, a search for complement subgraphs is started (_enumerate_cmp()). */ - for (size_t reverse_vertex_idx = 0; reverse_vertex_idx < _num_vertices; ++reverse_vertex_idx) { + for (auto reverse_vertex_idx = size_t{0}; reverse_vertex_idx < _num_vertices; ++reverse_vertex_idx) { const auto forward_vertex_idx = _num_vertices - reverse_vertex_idx - 1; auto start_vertex_set = JoinGraphVertexSet(_num_vertices); start_vertex_set.set(forward_vertex_idx); _enumerate_cmp(start_vertex_set); - std::vector csgs; + auto csgs = std::vector{}; _enumerate_csg_recursive(csgs, start_vertex_set, _exclusion_set(forward_vertex_idx)); for (const auto& csg : csgs) { _enumerate_cmp(csg); @@ -65,15 +65,15 @@ std::vector> EnumerateCcp::ope // Assert that the algorithm didn't create duplicates and that all created ccps contain only previously enumerated // subsets, i.e., that the enumeration order is correct - std::set enumerated_subsets; - std::set> enumerated_ccps; + auto enumerated_subsets = std::set{}; + auto enumerated_ccps = std::set>{}; for (auto csg_cmp_pair : _csg_cmp_pairs) { // Components must be either single-vertex or must have been enumerated as the vertex set of a previously // enumerated CCP - Assert(csg_cmp_pair.first.count() == 1 || enumerated_subsets.count(csg_cmp_pair.first) != 0, + Assert(csg_cmp_pair.first.count() == 1 || enumerated_subsets.contains(csg_cmp_pair.first), "CSG not yet enumerated"); - Assert(csg_cmp_pair.second.count() == 1 || enumerated_subsets.count(csg_cmp_pair.second) != 0, + Assert(csg_cmp_pair.second.count() == 1 || enumerated_subsets.contains(csg_cmp_pair.second), "CSG not yet enumerated"); enumerated_subsets.emplace(csg_cmp_pair.first | csg_cmp_pair.second); @@ -126,6 +126,7 @@ void EnumerateCcp::_enumerate_cmp(const JoinGraphVertexSet& primary_vertex_set) reverse_vertex_indices.emplace_back(current_vertex_idx); } while ((current_vertex_idx = neighborhood.find_next(current_vertex_idx)) != JoinGraphVertexSet::npos); + // NOLINTNEXTLINE(modernize-loop-convert) for (auto iter = reverse_vertex_indices.rbegin(); iter != reverse_vertex_indices.rend(); ++iter) { auto cmp_vertex_set = JoinGraphVertexSet(_num_vertices); cmp_vertex_set.set(*iter); @@ -207,17 +208,18 @@ std::vector EnumerateCcp::_non_empty_subsets(const JoinGraph std::vector subsets; - const auto s = vertex_set.to_ulong(); + const auto set_ulong = vertex_set.to_ulong(); - // s1 is the current subset subset [sic]. `s & -s` initializes it to the least significant bit in `s`. E.g., if - // s is 011000, this initializes s1 to 001000. - auto s1 = s & -s; + // subset_ulong is the current subset subset [sic]. `set_ulong & -set_ulong` initializes it to the least significant + // bit in `set_ulong`. E.g., if set_ulong is 011000, this initializes subset_ulong to 001000. + auto subset_ulong = set_ulong & -set_ulong; - while (s1 != s) { - subsets.emplace_back(_num_vertices, s1); - // This assigns to s1 the next subset of s. Somehow, this bit magic is binary incrementing s1, but only within the - // bits set in s. So, if s is 01101 and s1 is 00101, s1 will be updated to 01000. - s1 = s & (s1 - s); + while (subset_ulong != set_ulong) { + subsets.emplace_back(_num_vertices, subset_ulong); + // This assigns to subset_ulong the next subset of set_ulong. Somehow, this bit magic is binary incrementing + // subset_ulong, but only within the bits set in set_ulong. So, if set_ulong is 01101 and subset_ulong is 00101, + // subset_ulong will be updated to 01000. + subset_ulong = set_ulong & (subset_ulong - set_ulong); } subsets.emplace_back(vertex_set); diff --git a/src/lib/optimizer/join_ordering/greedy_operator_ordering.cpp b/src/lib/optimizer/join_ordering/greedy_operator_ordering.cpp index 23d6d8c014..b24161d81e 100644 --- a/src/lib/optimizer/join_ordering/greedy_operator_ordering.cpp +++ b/src/lib/optimizer/join_ordering/greedy_operator_ordering.cpp @@ -23,8 +23,9 @@ std::shared_ptr GreedyOperatorOrdering::operator()( * vertex. During the algorithm, vertex clusters are consecutively joined. */ auto vertex_clusters = std::map>{}; - for (auto vertex_idx = size_t{0}; vertex_idx < join_graph.vertices.size(); ++vertex_idx) { - auto vertex_set = JoinGraphVertexSet{join_graph.vertices.size()}; + const auto vertex_count = join_graph.vertices.size(); + for (auto vertex_idx = size_t{0}; vertex_idx < vertex_count; ++vertex_idx) { + auto vertex_set = JoinGraphVertexSet{vertex_count}; vertex_set.set(vertex_idx); vertex_clusters.emplace(vertex_set, join_graph.vertices[vertex_idx]); } @@ -39,7 +40,8 @@ std::shared_ptr GreedyOperatorOrdering::operator()( */ auto uncorrelated_predicates = std::vector>{}; auto remaining_edge_indices = std::vector{}; - for (auto edge_idx = size_t{0}; edge_idx < join_graph.edges.size(); ++edge_idx) { + const auto edge_count = join_graph.edges.size(); + for (auto edge_idx = size_t{0}; edge_idx < edge_count; ++edge_idx) { const auto& edge = join_graph.edges[edge_idx]; if (edge.vertex_set.none()) { @@ -58,7 +60,7 @@ std::shared_ptr GreedyOperatorOrdering::operator()( * cardinality * */ - auto plan_by_edge = std::vector{join_graph.edges.size()}; + auto plan_by_edge = std::vector{edge_count}; for (const auto& edge_idx : remaining_edge_indices) { plan_by_edge[edge_idx] = _build_plan_for_edge(join_graph.edges[edge_idx], vertex_clusters, cost_estimator); } @@ -87,7 +89,7 @@ std::shared_ptr GreedyOperatorOrdering::operator()( * While doing so, remove all the individual vertex clusters connected by the edge from the set of * vertex_clusters - we will add a new vertex cluster comprised of all of them afterwards */ - auto joined_vertex_set = JoinGraphVertexSet{join_graph.vertices.size()}; + auto joined_vertex_set = JoinGraphVertexSet{vertex_count}; for (auto vertex_cluster_iter = vertex_clusters.begin(); vertex_cluster_iter != vertex_clusters.end();) { if ((vertex_cluster_iter->first & lowest_cardinality_edge.vertex_set).any()) { joined_vertex_set |= vertex_cluster_iter->first; @@ -144,18 +146,18 @@ GreedyOperatorOrdering::PlanCardinalityPair GreedyOperatorOrdering::_build_plan_ edge.predicates, cost_estimator); return {plan, cardinality_estimator->estimate_cardinality(plan)}; + } - } else { - // Local edges and hyperedges - auto plan = vertex_clusters.at(joined_clusters.front()); - - for (auto joined_cluster_idx = size_t{1}; joined_cluster_idx < joined_clusters.size(); ++joined_cluster_idx) { - plan = JoinNode::make(JoinMode::Cross, plan, vertex_clusters.at(joined_clusters[joined_cluster_idx])); - } + // Local edges and hyperedges + auto plan = vertex_clusters.at(joined_clusters.front()); - plan = _add_predicates_to_plan(plan, edge.predicates, cost_estimator); - return {plan, cardinality_estimator->estimate_cardinality(plan)}; + const auto joined_cluster_count = joined_clusters.size(); + for (auto joined_cluster_idx = size_t{1}; joined_cluster_idx < joined_cluster_count; ++joined_cluster_idx) { + plan = JoinNode::make(JoinMode::Cross, plan, vertex_clusters.at(joined_clusters[joined_cluster_idx])); } + + plan = _add_predicates_to_plan(plan, edge.predicates, cost_estimator); + return {plan, cardinality_estimator->estimate_cardinality(plan)}; } } // namespace hyrise diff --git a/src/lib/optimizer/join_ordering/join_graph_builder.cpp b/src/lib/optimizer/join_ordering/join_graph_builder.cpp index 3f0a28d56a..a6f5579646 100644 --- a/src/lib/optimizer/join_ordering/join_graph_builder.cpp +++ b/src/lib/optimizer/join_ordering/join_graph_builder.cpp @@ -97,12 +97,12 @@ JoinGraphBuilder::PredicateParseResult JoinGraphBuilder::_parse_predicate( if (base_node->output_count() > 1) { return {base_node, left_predicate}; - } else { - const auto parse_result_right = _parse_predicate(base_node); - const auto and_predicate = and_(left_predicate, parse_result_right.predicate); - - return {parse_result_right.base_node, and_predicate}; } + + const auto parse_result_right = _parse_predicate(base_node); + const auto and_predicate = and_(left_predicate, parse_result_right.predicate); + + return {parse_result_right.base_node, and_predicate}; } break; default: diff --git a/src/lib/optimizer/join_ordering/join_graph_builder.hpp b/src/lib/optimizer/join_ordering/join_graph_builder.hpp index 000b60a1fc..89e90258f1 100644 --- a/src/lib/optimizer/join_ordering/join_graph_builder.hpp +++ b/src/lib/optimizer/join_ordering/join_graph_builder.hpp @@ -46,6 +46,7 @@ class JoinGraphBuilder final { * Traverse the LQP recursively identifying predicates and vertices along the way */ void _traverse(const std::shared_ptr& node); + /** * A subgraph in the LQP consisting of PredicateNodes can be translated into a single complex predicate * diff --git a/src/lib/optimizer/strategy/between_composition_rule.cpp b/src/lib/optimizer/strategy/between_composition_rule.cpp index 9d98f42894..bf744f50a3 100644 --- a/src/lib/optimizer/strategy/between_composition_rule.cpp +++ b/src/lib/optimizer/strategy/between_composition_rule.cpp @@ -22,11 +22,17 @@ using namespace hyrise; // NOLINT PredicateCondition get_between_predicate_condition(bool left_inclusive, bool right_inclusive) { if (left_inclusive && right_inclusive) { return PredicateCondition::BetweenInclusive; - } else if (left_inclusive && !right_inclusive) { + } + + if (left_inclusive && !right_inclusive) { return PredicateCondition::BetweenUpperExclusive; - } else if (!left_inclusive && right_inclusive) { + } + + if (!left_inclusive && right_inclusive) { return PredicateCondition::BetweenLowerExclusive; - } else if (!left_inclusive && !right_inclusive) { + } + + if (!left_inclusive && !right_inclusive) { return PredicateCondition::BetweenExclusive; } Fail("Unreachable Case"); @@ -152,7 +158,7 @@ void BetweenCompositionRule::_substitute_predicates_with_between_expressions(con for (const auto& expression : expressions) { const auto boundary = std::make_shared(_get_boundary(expression, id_counter)); - id_counter++; + ++id_counter; if (boundary->type != ColumnBoundaryType::None) { if (boundary->boundary_is_column_expression) { const auto inverse_boundary = std::make_shared(_create_inverse_boundary(boundary)); @@ -323,7 +329,7 @@ void BetweenCompositionRule::_substitute_predicates_with_between_expressions(con * **/ BetweenCompositionRule::ColumnBoundary BetweenCompositionRule::_get_boundary( - const std::shared_ptr& expression, const size_t id) { + const std::shared_ptr& expression, const size_t expression_id) { auto type = ColumnBoundaryType::None; const auto left_column_expression = std::dynamic_pointer_cast(expression->left_operand()); auto value_expression = std::dynamic_pointer_cast(expression->right_operand()); @@ -347,62 +353,57 @@ BetweenCompositionRule::ColumnBoundary BetweenCompositionRule::_get_boundary( default: break; } - return { - left_column_expression, value_expression, type, false, id, - }; - } else { - value_expression = std::dynamic_pointer_cast(expression->left_operand()); - const auto right_column_expression = std::dynamic_pointer_cast(expression->right_operand()); - - // Case: "ValueExpression [CONDITION] ColumnExpression" will be checked + return {left_column_expression, value_expression, type, false, expression_id}; + } + + value_expression = std::dynamic_pointer_cast(expression->left_operand()); + const auto right_column_expression = std::dynamic_pointer_cast(expression->right_operand()); + + // Case: "ValueExpression [CONDITION] ColumnExpression" will be checked + // Boundary type will be set according to this order + if (value_expression && right_column_expression) { + switch (expression->predicate_condition) { + case PredicateCondition::GreaterThanEquals: + type = ColumnBoundaryType::UpperBoundaryInclusive; + break; + case PredicateCondition::LessThanEquals: + type = ColumnBoundaryType::LowerBoundaryInclusive; + break; + case PredicateCondition::GreaterThan: + type = ColumnBoundaryType::UpperBoundaryExclusive; + break; + case PredicateCondition::LessThan: + type = ColumnBoundaryType::LowerBoundaryExclusive; + break; + default: + break; + } + return {right_column_expression, value_expression, type, false, expression_id}; + } + + if (left_column_expression && right_column_expression) { + // Case: "ColumnExpression [CONDITION] ColumnExpression" will be checked // Boundary type will be set according to this order - if (value_expression && right_column_expression) { - switch (expression->predicate_condition) { - case PredicateCondition::GreaterThanEquals: - type = ColumnBoundaryType::UpperBoundaryInclusive; - break; - case PredicateCondition::LessThanEquals: - type = ColumnBoundaryType::LowerBoundaryInclusive; - break; - case PredicateCondition::GreaterThan: - type = ColumnBoundaryType::UpperBoundaryExclusive; - break; - case PredicateCondition::LessThan: - type = ColumnBoundaryType::LowerBoundaryExclusive; - break; - default: - break; - } - return { - right_column_expression, value_expression, type, false, id, - }; - } else if (left_column_expression && right_column_expression) { - // Case: "ColumnExpression [CONDITION] ColumnExpression" will be checked - // Boundary type will be set according to this order - switch (expression->predicate_condition) { - case PredicateCondition::LessThanEquals: - type = ColumnBoundaryType::UpperBoundaryInclusive; - break; - case PredicateCondition::GreaterThanEquals: - type = ColumnBoundaryType::LowerBoundaryInclusive; - break; - case PredicateCondition::LessThan: - type = ColumnBoundaryType::UpperBoundaryExclusive; - break; - case PredicateCondition::GreaterThan: - type = ColumnBoundaryType::LowerBoundaryExclusive; - break; - default: - break; - } - return { - left_column_expression, right_column_expression, type, true, id, - }; + switch (expression->predicate_condition) { + case PredicateCondition::LessThanEquals: + type = ColumnBoundaryType::UpperBoundaryInclusive; + break; + case PredicateCondition::GreaterThanEquals: + type = ColumnBoundaryType::LowerBoundaryInclusive; + break; + case PredicateCondition::LessThan: + type = ColumnBoundaryType::UpperBoundaryExclusive; + break; + case PredicateCondition::GreaterThan: + type = ColumnBoundaryType::LowerBoundaryExclusive; + break; + default: + break; } + return {left_column_expression, right_column_expression, type, true, expression_id}; } - return { - nullptr, nullptr, ColumnBoundaryType::None, false, id, - }; + + return {nullptr, nullptr, ColumnBoundaryType::None, false, expression_id}; } BetweenCompositionRule::ColumnBoundary BetweenCompositionRule::_create_inverse_boundary( diff --git a/src/lib/optimizer/strategy/chunk_pruning_rule.cpp b/src/lib/optimizer/strategy/chunk_pruning_rule.cpp index 47eab12b7b..55bad2bb7d 100644 --- a/src/lib/optimizer/strategy/chunk_pruning_rule.cpp +++ b/src/lib/optimizer/strategy/chunk_pruning_rule.cpp @@ -402,8 +402,8 @@ std::set ChunkPruningRule::_intersect_chunk_ids(const std::vector chunk_id_set = chunk_id_sets.at(0); - for (size_t set_idx = 1; set_idx < chunk_id_sets.size(); ++set_idx) { - auto current_chunk_id_set = chunk_id_sets.at(set_idx); + for (auto set_idx = size_t{1}; set_idx < chunk_id_sets.size(); ++set_idx) { + const auto& current_chunk_id_set = chunk_id_sets.at(set_idx); if (current_chunk_id_set.empty()) { return {}; } diff --git a/src/lib/optimizer/strategy/join_predicate_ordering_rule.cpp b/src/lib/optimizer/strategy/join_predicate_ordering_rule.cpp index 0f460b07d1..3050817a37 100644 --- a/src/lib/optimizer/strategy/join_predicate_ordering_rule.cpp +++ b/src/lib/optimizer/strategy/join_predicate_ordering_rule.cpp @@ -42,8 +42,9 @@ void JoinPredicateOrderingRule::_apply_to_plan_without_subqueries( } // Sort predicates by ascending join selectivity. - std::sort(node->node_expressions.begin(), node->node_expressions.end(), - [&](const auto& a, const auto& b) { return predicate_cardinalities[a] < predicate_cardinalities[b]; }); + std::sort(node->node_expressions.begin(), node->node_expressions.end(), [&](const auto& lhs, const auto& rhs) { + return predicate_cardinalities[lhs] < predicate_cardinalities[rhs]; + }); // Semi and anti joins are currently only implemented by hash joins. These need an equals comparison as the primary // join predicate. Check that one exists and move it to the front. diff --git a/src/lib/optimizer/strategy/predicate_placement_rule.cpp b/src/lib/optimizer/strategy/predicate_placement_rule.cpp index 0cb3cd5a0f..ce3f84cb9e 100644 --- a/src/lib/optimizer/strategy/predicate_placement_rule.cpp +++ b/src/lib/optimizer/strategy/predicate_placement_rule.cpp @@ -60,11 +60,14 @@ void PredicatePlacementRule::_push_down_traversal(const std::shared_ptrtype == LQPNodeType::Predicate) { const auto predicate_node = std::static_pointer_cast(barrier_node); return !_is_expensive_predicate(predicate_node->predicate()); - } else if (barrier_node->type == LQPNodeType::Join) { + } + + if (barrier_node->type == LQPNodeType::Join) { const auto join_mode = std::static_pointer_cast(barrier_node)->join_mode; return join_mode == JoinMode::Semi || join_mode == JoinMode::AntiNullAsTrue || join_mode == JoinMode::AntiNullAsFalse; } + return false; }(); @@ -187,8 +190,8 @@ void PredicatePlacementRule::_push_down_traversal(const std::shared_ptr> left_disjunction{}; - std::vector> right_disjunction{}; + auto left_disjunction = std::vector>{}; + auto right_disjunction = std::vector>{}; // Tracks whether we had to abort the search for one of the sides as an inner_conjunction was found that // did not cover the side. @@ -200,8 +203,8 @@ void PredicatePlacementRule::_push_down_traversal(const std::shared_ptr> left_conjunction{}; - std::vector> right_conjunction{}; + auto left_conjunction = std::vector>{}; + auto right_conjunction = std::vector>{}; // Fill left/right_conjunction const auto inner_conjunction = @@ -419,6 +422,7 @@ std::vector> PredicatePlacementRule::_pull_up_t if (!current_node) { return {}; } + const auto input_node = current_node->input(input_side); if (!input_node) { return {}; @@ -452,10 +456,10 @@ std::vector> PredicatePlacementRule::_pull_up_t join_node->join_mode == JoinMode::Semi || join_node->join_mode == JoinMode::AntiNullAsTrue || join_node->join_mode == JoinMode::AntiNullAsFalse) { return candidate_nodes; - } else { - _insert_nodes(current_node, input_side, candidate_nodes); - return {}; } + + _insert_nodes(current_node, input_side, candidate_nodes); + return {}; } break; case LQPNodeType::Alias: @@ -515,9 +519,8 @@ bool PredicatePlacementRule::_is_expensive_predicate(const std::shared_ptris_correlated()) { predicate_contains_correlated_subquery = true; return ExpressionVisitation::DoNotVisitArguments; - } else { - return ExpressionVisitation::VisitArguments; } + return ExpressionVisitation::VisitArguments; }); return predicate_contains_correlated_subquery; } diff --git a/src/lib/optimizer/strategy/stored_table_column_alignment_rule.cpp b/src/lib/optimizer/strategy/stored_table_column_alignment_rule.cpp index 478c136c3c..f5665799ec 100644 --- a/src/lib/optimizer/strategy/stored_table_column_alignment_rule.cpp +++ b/src/lib/optimizer/strategy/stored_table_column_alignment_rule.cpp @@ -30,8 +30,7 @@ struct StoredTableNodeSharedPtrHash final { // Modified equals evaluation code for StoredTableNodes where column pruning information is omitted. Struct is used to // enable hash-based containers containing std::shared_ptr. struct StoredTableNodeSharedPtrEqual final { - size_t operator()(const std::shared_ptr& lhs, - const std::shared_ptr& rhs) const { + size_t operator()(const std::shared_ptr& lhs, const std::shared_ptr& rhs) const { DebugAssert(std::is_sorted(lhs->pruned_chunk_ids().cbegin(), lhs->pruned_chunk_ids().cend()), "Expected sorted vector of ChunkIDs"); DebugAssert(std::is_sorted(rhs->pruned_chunk_ids().cbegin(), rhs->pruned_chunk_ids().cend()), diff --git a/src/lib/optimizer/strategy/subquery_to_join_rule.cpp b/src/lib/optimizer/strategy/subquery_to_join_rule.cpp index 7bae16a24e..2df79282ad 100644 --- a/src/lib/optimizer/strategy/subquery_to_join_rule.cpp +++ b/src/lib/optimizer/strategy/subquery_to_join_rule.cpp @@ -31,6 +31,9 @@ namespace { using namespace hyrise; // NOLINT +using NodeExpressionsDifferenceType = + typename std::iterator_traits::difference_type; + /** * Calculates which input LQPs of a node are safe to pull predicates from. * @@ -478,7 +481,8 @@ std::shared_ptr SubqueryToJoinRule::adapt_aggregate_node( const std::shared_ptr& node, const std::vector>& required_output_expressions) { std::vector> group_by_expressions( - node->node_expressions.cbegin(), node->node_expressions.cbegin() + node->aggregate_expressions_begin_idx); + node->node_expressions.cbegin(), node->node_expressions.cbegin() + static_cast( + node->aggregate_expressions_begin_idx)); ExpressionUnorderedSet original_group_by_expressions(group_by_expressions.cbegin(), group_by_expressions.cend()); const auto not_found_it = original_group_by_expressions.cend(); @@ -489,7 +493,9 @@ std::shared_ptr SubqueryToJoinRule::adapt_aggregate_node( } std::vector> aggregate_expressions( - node->node_expressions.cbegin() + node->aggregate_expressions_begin_idx, node->node_expressions.cend()); + node->node_expressions.cbegin() + + static_cast(node->aggregate_expressions_begin_idx), + node->node_expressions.cend()); return AggregateNode::make(group_by_expressions, aggregate_expressions); } diff --git a/src/lib/scheduler/abstract_task.cpp b/src/lib/scheduler/abstract_task.cpp index 9d7bc76856..a8c00f6669 100644 --- a/src/lib/scheduler/abstract_task.cpp +++ b/src/lib/scheduler/abstract_task.cpp @@ -44,8 +44,8 @@ std::string AbstractTask::description() const { return _description.empty() ? "{Task with id: " + std::to_string(_id.load()) + "}" : _description; } -void AbstractTask::set_id(TaskID id) { - _id = id; +void AbstractTask::set_id(TaskID task_id) { + _id = task_id; } void AbstractTask::set_as_predecessor_of(const std::shared_ptr& successor) { diff --git a/src/lib/scheduler/abstract_task.hpp b/src/lib/scheduler/abstract_task.hpp index 9902f1dd41..6310495710 100644 --- a/src/lib/scheduler/abstract_task.hpp +++ b/src/lib/scheduler/abstract_task.hpp @@ -116,7 +116,7 @@ class AbstractTask : public std::enable_shared_from_this { * Task ids are determined on scheduling, no one else but the Scheduler should have any reason to call this * @param id id, unique during the lifetime of the program, of the task */ - void set_id(TaskID id); + void set_id(TaskID task_id); /** * Make this Task the dependency of another diff --git a/src/lib/scheduler/node_queue_scheduler.cpp b/src/lib/scheduler/node_queue_scheduler.cpp index 9f1748704d..af8e65a0d8 100644 --- a/src/lib/scheduler/node_queue_scheduler.cpp +++ b/src/lib/scheduler/node_queue_scheduler.cpp @@ -23,7 +23,7 @@ NodeQueueScheduler::~NodeQueueScheduler() { if (HYRISE_DEBUG && _active) { // We cannot throw an exception because destructors are noexcept by default. std::cerr << "NodeQueueScheduler::finish() wasn't called prior to destroying it" << std::endl; - std::exit(EXIT_FAILURE); + std::exit(EXIT_FAILURE); // NOLINT(concurrency-mt-unsafe) } } diff --git a/src/lib/scheduler/task_queue.cpp b/src/lib/scheduler/task_queue.cpp index 94aca938ee..eec956d5b4 100644 --- a/src/lib/scheduler/task_queue.cpp +++ b/src/lib/scheduler/task_queue.cpp @@ -53,9 +53,9 @@ std::shared_ptr TaskQueue::steal() { if (queue.try_pop(task)) { if (task->is_stealable()) { return task; - } else { - queue.push(task); } + + queue.push(task); } } return nullptr; diff --git a/src/lib/scheduler/worker.cpp b/src/lib/scheduler/worker.cpp index c8ffb174e9..2ae9a07843 100644 --- a/src/lib/scheduler/worker.cpp +++ b/src/lib/scheduler/worker.cpp @@ -23,7 +23,7 @@ namespace { * On worker threads, this references the Worker running on this thread, on all other threads, this is empty. * Uses a weak_ptr, because otherwise the ref-count of it would not reach zero within the main() scope of the program. */ -thread_local std::weak_ptr this_thread_worker; +thread_local std::weak_ptr this_thread_worker; // NOLINT (clang-tidy wants this const) } // namespace // The sleep time was determined experimentally @@ -35,8 +35,8 @@ std::shared_ptr Worker::get_this_thread_worker() { return ::this_thread_worker.lock(); } -Worker::Worker(const std::shared_ptr& queue, WorkerID id, CpuID cpu_id) - : _queue(queue), _id(id), _cpu_id(cpu_id) { +Worker::Worker(const std::shared_ptr& queue, WorkerID worker_id, CpuID cpu_id) + : _queue(queue), _id(worker_id), _cpu_id(cpu_id) { // Generate a random distribution from 0-99 for later use, see below _random.resize(100); std::iota(_random.begin(), _random.end(), 0); @@ -221,11 +221,11 @@ void Worker::_set_affinity() { cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(_cpu_id, &cpuset); - auto rc = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); - if (rc != 0) { - // This is not an Assert(), though maybe it should be. Not being able to pin the threads doesn't make the DB - // unfunctional, but probably slower - std::cerr << "Error calling pthread_setaffinity_np: " << rc << std::endl; + const auto return_code = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (return_code != 0) { + // This is not an Assert(), though maybe it should be. Not being able to pin the threads doesn't make the database + // unfunctional, but probably slower. + std::cerr << "Error calling pthread_setaffinity_np (return code: " << return_code << ")." << std::endl; } #endif } diff --git a/src/lib/scheduler/worker.hpp b/src/lib/scheduler/worker.hpp index 2c968e9aee..92c732bb1a 100644 --- a/src/lib/scheduler/worker.hpp +++ b/src/lib/scheduler/worker.hpp @@ -23,7 +23,7 @@ class Worker : public std::enable_shared_from_this, private Noncopyable public: static std::shared_ptr get_this_thread_worker(); - Worker(const std::shared_ptr& queue, WorkerID id, CpuID cpu_id); + Worker(const std::shared_ptr& queue, WorkerID worker_id, CpuID cpu_id); /** * Unique ID of a worker. Currently not in use, but really helpful for debugging. diff --git a/src/lib/server/postgres_protocol_handler.cpp b/src/lib/server/postgres_protocol_handler.cpp index 9008687c4e..c8f2d6e540 100644 --- a/src/lib/server/postgres_protocol_handler.cpp +++ b/src/lib/server/postgres_protocol_handler.cpp @@ -18,10 +18,10 @@ uint32_t PostgresProtocolHandler::read_startup_packet_header() { if (protocol_version == SSL_REQUEST_CODE) { _ssl_deny(); return read_startup_packet_header(); - } else { - // Subtract uint32_t twice, since both packet length and protocol version have been read already - return body_length - 2 * LENGTH_FIELD_SIZE; } + + // Subtract uint32_t twice since both the packet length and protocol version have been read already. + return body_length - 2 * LENGTH_FIELD_SIZE; } template @@ -150,7 +150,7 @@ std::pair PostgresProtocolHandler::read_pa // The number of parameter data types specified (can be zero). These data types are ignored currently. const auto data_types_specified = _read_buffer.template get_value(); - for (auto i = 0; i < data_types_specified; i++) { + for (auto data_type_id = 0; data_type_id < data_types_specified; ++data_type_id) { // Specifies the object ID of the parameter data type. // Placing a zero here is equivalent to leaving the type unspecified. /*auto data_type = */ _read_buffer.template get_value(); @@ -193,21 +193,21 @@ PreparedStatementDetails PostgresProtocolHandler::read_bind_packet() const auto statement_name = _read_buffer.get_string(); const auto num_format_codes = _read_buffer.template get_value(); - for (auto i = 0; i < num_format_codes; i++) { + for (auto format_code_index = 0; format_code_index < num_format_codes; ++format_code_index) { Assert(_read_buffer.template get_value() == 0, "Assuming all parameters to be in text format (0)"); } const auto num_parameter_values = _read_buffer.template get_value(); std::vector parameter_values; - for (auto i = 0; i < num_parameter_values; ++i) { + for (auto parameter_value = 0; parameter_value < num_parameter_values; ++parameter_value) { const auto parameter_value_length = _read_buffer.template get_value(); parameter_values.emplace_back(pmr_string{_read_buffer.get_string(parameter_value_length, HasNullTerminator::No)}); } const auto num_result_column_format_codes = _read_buffer.template get_value(); - for (auto i = 0; i < num_result_column_format_codes; i++) { + for (auto format_code = 0; format_code < num_result_column_format_codes; ++format_code) { Assert(_read_buffer.template get_value() == 0, "Assuming all result columns to be in text format (0)"); } @@ -228,20 +228,20 @@ std::string PostgresProtocolHandler::read_execute_packet() { } template -void PostgresProtocolHandler::send_error_message(const ErrorMessage& error_message) { +void PostgresProtocolHandler::send_error_message(const ErrorMessages& error_messages) { _write_buffer.template put_value(PostgresMessageType::ErrorResponse); // Calculate size of error message strings - auto string_length_sum = 0; - for (const auto& kv : error_message) { - string_length_sum += kv.second.size() + 1u /* null terminator */; + auto string_length_sum = size_t{0}; + for (const auto& error_message : error_messages) { + string_length_sum += error_message.second.size() + 1ul /* null terminator */; } - const auto packet_size = LENGTH_FIELD_SIZE + error_message.size() * sizeof(PostgresMessageType) + string_length_sum + + const auto packet_size = LENGTH_FIELD_SIZE + error_messages.size() * sizeof(PostgresMessageType) + string_length_sum + 1u /* null terminator */; _write_buffer.template put_value(static_cast(packet_size)); - for (const auto& [message_type, content] : error_message) { + for (const auto& [message_type, content] : error_messages) { _write_buffer.template put_value(message_type); _write_buffer.put_string(content); } diff --git a/src/lib/server/postgres_protocol_handler.hpp b/src/lib/server/postgres_protocol_handler.hpp index b33f89a75d..a663417d3d 100644 --- a/src/lib/server/postgres_protocol_handler.hpp +++ b/src/lib/server/postgres_protocol_handler.hpp @@ -9,7 +9,7 @@ namespace hyrise { -using ErrorMessage = std::unordered_map; +using ErrorMessages = std::unordered_map; // This struct stores a prepared statement's name, its portal used and the specified parameters. struct PreparedStatementDetails { @@ -62,7 +62,7 @@ class PostgresProtocolHandler { std::string read_execute_packet(); // Send error message to client if there is an error during parsing or execution - void send_error_message(const ErrorMessage& error_message); + void send_error_message(const ErrorMessages& error_messages); // Additional (optional) message containing execution times of different components (such as translator or optimizer) void send_execution_info(const std::string& execution_information); diff --git a/src/lib/server/query_handler.cpp b/src/lib/server/query_handler.cpp index 85364ab849..4502655d82 100644 --- a/src/lib/server/query_handler.cpp +++ b/src/lib/server/query_handler.cpp @@ -37,11 +37,11 @@ std::pair> QueryHandle } } else if (pipeline_status == SQLPipelineStatus::Failure) { const std::string failed_statement = sql_pipeline.failed_pipeline_statement()->get_sql_string(); - execution_info.error_message = {{PostgresMessageType::HumanReadableError, - "Transaction conflict, transaction was rolled back. Following statements might " - "have still been sent and executed. Failed statement: " + - failed_statement}, - {PostgresMessageType::SqlstateCodeError, TRANSACTION_CONFLICT}}; + execution_info.error_messages = {{PostgresMessageType::HumanReadableError, + "Transaction conflict, transaction was rolled back. Following statements might " + "have still been sent and executed. Failed statement: " + + failed_statement}, + {PostgresMessageType::SqlstateCodeError, TRANSACTION_CONFLICT}}; } return {execution_info, sql_pipeline.transaction_context()}; } @@ -81,8 +81,9 @@ std::shared_ptr QueryHandler::bind_prepared_plan(const Prepare const auto prepared_plan = Hyrise::get().storage_manager.get_prepared_plan(statement_details.statement_name); - auto parameter_expressions = std::vector>{statement_details.parameters.size()}; - for (auto parameter_idx = size_t{0}; parameter_idx < statement_details.parameters.size(); ++parameter_idx) { + const auto parameter_count = statement_details.parameters.size(); + auto parameter_expressions = std::vector>{parameter_count}; + for (auto parameter_idx = size_t{0}; parameter_idx < parameter_count; ++parameter_idx) { parameter_expressions[parameter_idx] = std::make_shared(statement_details.parameters[parameter_idx]); } diff --git a/src/lib/server/query_handler.hpp b/src/lib/server/query_handler.hpp index baf8a00114..23ec6a9783 100644 --- a/src/lib/server/query_handler.hpp +++ b/src/lib/server/query_handler.hpp @@ -16,7 +16,7 @@ struct ExecutionInformation { // the root operator's type. OperatorType root_operator_type; std::string pipeline_metrics; - ErrorMessage error_message; + ErrorMessages error_messages; std::optional custom_command_complete_message; }; diff --git a/src/lib/server/read_buffer.cpp b/src/lib/server/read_buffer.cpp index a513391c76..28003c4877 100644 --- a/src/lib/server/read_buffer.cpp +++ b/src/lib/server/read_buffer.cpp @@ -22,8 +22,8 @@ bool ReadBuffer::full() const { template std::string ReadBuffer::get_string() { - auto string_end = RingBufferIterator(_data); - std::string result; + auto string_end = RingBufferIterator{_data}; + auto result = std::string{}; // First, use bytes available in buffer if (size() != 0) { @@ -88,7 +88,7 @@ void ReadBuffer::_receive_if_necessary(const size_t bytes_required) boost::system::error_code error_code; // We cannot forward an iterator to the read system call. Hence, we need to use raw pointers. Therefore, we need to // distinguish between reading into continuous memory or partially read the data. - if (std::distance(&*_start_position, &*_current_position) < 0 || &*_start_position == &_data[0]) { + if (std::distance(&*_start_position, &*_current_position) < 0 || &*_start_position == _data.data()) { bytes_read = boost::asio::read(*_socket, boost::asio::buffer(&*_current_position, maximum_readable_size), boost::asio::transfer_at_least(bytes_required - size()), error_code); } else { diff --git a/src/lib/server/result_serializer.cpp b/src/lib/server/result_serializer.cpp index 3ee49b58bd..3a19995291 100644 --- a/src/lib/server/result_serializer.cpp +++ b/src/lib/server/result_serializer.cpp @@ -17,7 +17,8 @@ void ResultSerializer::send_table_description( postgres_protocol_handler->send_row_description_header(column_name_length_sum, static_cast(table->column_count())); - for (ColumnID column_id{0u}; column_id < table->column_count(); ++column_id) { + const auto column_count = table->column_count(); + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { uint32_t object_id = 0; int16_t type_width = 0; @@ -73,7 +74,7 @@ void ResultSerializer::send_query_response( // Iterate over each row in chunk for (auto chunk_offset = ChunkOffset{0}; chunk_offset < chunk_size; ++chunk_offset) { - auto string_length_sum = 0; + auto string_length_sum = uint32_t{0}; // Iterate over each attribute in row for (auto segment_id = ColumnID{0}; segment_id < column_count; segment_id++) { const auto attribute_value = (*segments[segment_id])[chunk_offset]; @@ -81,7 +82,7 @@ void ResultSerializer::send_query_response( const auto string_value = lossy_variant_cast(attribute_value); if (string_value.has_value()) { // Sum up string lengths for a row to save an extra loop during serialization - string_length_sum += string_value.value().size(); + string_length_sum += static_cast(string_value.value().size()); } values_as_strings[segment_id] = string_value; } @@ -94,9 +95,9 @@ std::string ResultSerializer::build_command_complete_message(const ExecutionInfo const uint64_t row_count) { if (execution_information.custom_command_complete_message) { return execution_information.custom_command_complete_message.value(); - } else { - return build_command_complete_message(execution_information.root_operator_type, row_count); } + + return build_command_complete_message(execution_information.root_operator_type, row_count); } std::string ResultSerializer::build_command_complete_message(const OperatorType root_operator_type, diff --git a/src/lib/server/session.cpp b/src/lib/server/session.cpp index 4d1fb435ca..3e9471f1c3 100644 --- a/src/lib/server/session.cpp +++ b/src/lib/server/session.cpp @@ -30,8 +30,8 @@ void Session::run() { } catch (const std::exception& e) { std::cerr << "Exception in session with client port " << _socket->remote_endpoint().port() << ":" << std::endl << e.what() << std::endl; - const auto error_message = ErrorMessage{{PostgresMessageType::HumanReadableError, e.what()}}; - _postgres_protocol_handler->send_error_message(error_message); + const auto error_messages = ErrorMessages{{PostgresMessageType::HumanReadableError, e.what()}}; + _postgres_protocol_handler->send_error_message(error_messages); _postgres_protocol_handler->send_ready_for_query(); // In case of an error, an error message has to be send to the client followed by a "ReadyForQuery" message. // Messages that have already been received are processed further. A "sync" message makes the server send another @@ -112,8 +112,8 @@ void Session::_handle_simple_query() { std::tie(execution_information, _transaction_context) = QueryHandler::execute_pipeline(query, _send_execution_info, _transaction_context); - if (!execution_information.error_message.empty()) { - _postgres_protocol_handler->send_error_message(execution_information.error_message); + if (!execution_information.error_messages.empty()) { + _postgres_protocol_handler->send_error_message(execution_information.error_messages); } else { uint64_t row_count = 0; // If there is no result table, e.g. after an INSERT command, we cannot send row data. Otherwise, the result table diff --git a/src/lib/sql/sql_identifier.cpp b/src/lib/sql/sql_identifier.cpp index 3f83c1982c..a3ae17cdc3 100644 --- a/src/lib/sql/sql_identifier.cpp +++ b/src/lib/sql/sql_identifier.cpp @@ -12,12 +12,12 @@ bool SQLIdentifier::operator==(const SQLIdentifier& rhs) const { } std::string SQLIdentifier::as_string() const { - std::stringstream ss; + std::stringstream sstream; if (table_name) { - ss << *table_name << "."; + sstream << *table_name << "."; } - ss << column_name; - return ss.str(); + sstream << column_name; + return sstream.str(); } } // namespace hyrise diff --git a/src/lib/sql/sql_identifier_resolver_proxy.cpp b/src/lib/sql/sql_identifier_resolver_proxy.cpp index 1cec63557b..cf7d9d1cfa 100644 --- a/src/lib/sql/sql_identifier_resolver_proxy.cpp +++ b/src/lib/sql/sql_identifier_resolver_proxy.cpp @@ -29,10 +29,10 @@ std::shared_ptr SQLIdentifierResolverProxy::resolve_identifi } return std::make_shared(parameter_id, *expression); - } else { - if (_outer_context_proxy) { - return _outer_context_proxy->resolve_identifier_relaxed(identifier); - } + } + + if (_outer_context_proxy) { + return _outer_context_proxy->resolve_identifier_relaxed(identifier); } return nullptr; diff --git a/src/lib/sql/sql_pipeline_statement.cpp b/src/lib/sql/sql_pipeline_statement.cpp index c9763a47a8..44a5e430e7 100644 --- a/src/lib/sql/sql_pipeline_statement.cpp +++ b/src/lib/sql/sql_pipeline_statement.cpp @@ -117,7 +117,7 @@ const std::shared_ptr& SQLPipelineStatement::get_optimized_logi // Handle logical query plan if statement has been cached if (lqp_cache) { if (const auto cached_plan = lqp_cache->try_get(_sql_string)) { - const auto plan = *cached_plan; + const auto& plan = *cached_plan; DebugAssert(plan, "Optimized logical query plan retrieved from cache is empty."); // MVCC-enabled and MVCC-disabled LQPs will evict each other if (lqp_is_validated(plan) == (_use_mvcc == UseMvcc::Yes)) { diff --git a/src/lib/sql/sql_translator.cpp b/src/lib/sql/sql_translator.cpp index b5b4db7f5a..6111b4db1d 100644 --- a/src/lib/sql/sql_translator.cpp +++ b/src/lib/sql/sql_translator.cpp @@ -349,7 +349,8 @@ void SQLTranslator::_translate_hsql_with_description(hsql::WithDescription& desc // Save mappings: ColumnID -> ColumnName std::unordered_map column_names; const auto output_expressions = lqp->output_expressions(); - for (auto column_id = ColumnID{0}; column_id < output_expressions.size(); ++column_id) { + const auto output_expression_count = output_expressions.size(); + for (auto column_id = ColumnID{0}; column_id < output_expression_count; ++column_id) { for (const auto& identifier : with_translator._inflated_select_list_elements[column_id].identifiers) { column_names.insert_or_assign(column_id, identifier.column_name); } @@ -358,7 +359,7 @@ void SQLTranslator::_translate_hsql_with_description(hsql::WithDescription& desc // Store resolved WithDescription / temporary view const auto lqp_view = std::make_shared(lqp, column_names); // A WITH description masks a preceding WITH description if their aliases are identical - AssertInput(_with_descriptions.count(desc.alias) == 0, "Invalid redeclaration of WITH alias."); + AssertInput(!_with_descriptions.contains(desc.alias), "Invalid redeclaration of WITH alias."); _with_descriptions.emplace(desc.alias, lqp_view); } @@ -616,8 +617,9 @@ SQLTranslator::TableSourceState SQLTranslator::_translate_table_origin(const hsq // Add all named columns to the IdentifierContext const auto output_expressions = lqp_view->lqp->output_expressions(); - for (auto column_id = ColumnID{0}; column_id < output_expressions.size(); ++column_id) { - const auto expression = output_expressions[column_id]; + const auto output_expression_count = output_expressions.size(); + for (auto column_id = ColumnID{0}; column_id < output_expression_count; ++column_id) { + const auto& expression = output_expressions[column_id]; const auto column_name_iter = lqp_view->column_names.find(column_id); if (column_name_iter != lqp_view->column_names.end()) { @@ -640,8 +642,9 @@ SQLTranslator::TableSourceState SQLTranslator::_translate_table_origin(const hsq * Add all named columns from the view to the IdentifierContext */ const auto output_expressions = view->lqp->output_expressions(); - for (auto column_id = ColumnID{0}; column_id < output_expressions.size(); ++column_id) { - const auto expression = output_expressions[column_id]; + const auto output_expression_count = output_expressions.size(); + for (auto column_id = ColumnID{0}; column_id < output_expression_count; ++column_id) { + const auto& expression = output_expressions[column_id]; const auto column_name_iter = view->column_names.find(column_id); if (column_name_iter != view->column_names.end()) { @@ -681,11 +684,12 @@ SQLTranslator::TableSourceState SQLTranslator::_translate_table_origin(const hsq } const auto output_expressions = lqp->output_expressions(); - Assert(identifiers.size() == output_expressions.size(), + const auto output_expression_count = output_expressions.size(); + Assert(identifiers.size() == output_expression_count, "There have to be as many identifier lists as output expressions"); - for (auto select_list_element_idx = size_t{0}; select_list_element_idx < output_expressions.size(); + for (auto select_list_element_idx = size_t{0}; select_list_element_idx < output_expression_count; ++select_list_element_idx) { - const auto subquery_expression = output_expressions[select_list_element_idx]; + const auto& subquery_expression = output_expressions[select_list_element_idx]; // Make sure each column from the Subquery has a name if (identifiers.empty()) { @@ -711,13 +715,14 @@ SQLTranslator::TableSourceState SQLTranslator::_translate_table_origin(const hsq if (hsql_table_ref.alias && hsql_table_ref.alias->columns) { const auto& output_expressions = lqp->output_expressions(); - AssertInput(hsql_table_ref.alias->columns->size() == output_expressions.size(), + const auto table_ref_alias_column_count = hsql_table_ref.alias->columns->size(); + AssertInput(table_ref_alias_column_count == output_expressions.size(), "Must specify a name for exactly each column"); - Assert(hsql_table_ref.alias->columns->size() == select_list_elements.size(), + Assert(table_ref_alias_column_count == select_list_elements.size(), "There have to be as many aliases as output expressions"); std::set> renamed_expressions; - for (auto column_id = ColumnID{0}; column_id < hsql_table_ref.alias->columns->size(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < table_ref_alias_column_count; ++column_id) { const auto& expression = output_expressions[column_id]; if (renamed_expressions.find(expression) == renamed_expressions.end()) { @@ -948,7 +953,8 @@ SQLTranslator::TableSourceState SQLTranslator::_translate_natural_join(const hsq } // Add remaining join predicates as normal predicates - for (auto join_predicate_idx = size_t{1}; join_predicate_idx < join_predicates.size(); ++join_predicate_idx) { + const auto join_predicate_count = join_predicates.size(); + for (auto join_predicate_idx = size_t{1}; join_predicate_idx < join_predicate_count; ++join_predicate_idx) { lqp = PredicateNode::make(join_predicates[join_predicate_idx], lqp); } @@ -968,7 +974,8 @@ SQLTranslator::TableSourceState SQLTranslator::_translate_cross_product(const st auto result_table_source_state = _translate_table_ref(*tables.front()); - for (auto table_idx = size_t{1}; table_idx < tables.size(); ++table_idx) { + const auto table_count = tables.size(); + for (auto table_idx = size_t{1}; table_idx < table_count; ++table_idx) { auto table_source_state = _translate_table_ref(*tables[table_idx]); result_table_source_state.lqp = JoinNode::make(JoinMode::Cross, result_table_source_state.lqp, table_source_state.lqp); @@ -1089,8 +1096,9 @@ void SQLTranslator::_translate_select_groupby_having(const hsql::SelectStatement if (!pre_aggregate_expressions.empty()) { const auto& output_expressions = _current_lqp->output_expressions(); const auto any_expression_not_yet_available = std::any_of( - pre_aggregate_expressions.begin(), pre_aggregate_expressions.end(), - [&](const auto& expression) { return find_expression_idx(*expression, output_expressions) ? false : true; }); + pre_aggregate_expressions.cbegin(), pre_aggregate_expressions.cend(), [&](const auto& expression) { + return !static_cast(find_expression_idx(*expression, output_expressions)); + }); if (any_expression_not_yet_available) { _current_lqp = ProjectionNode::make(pre_aggregate_expressions, _current_lqp); @@ -1198,11 +1206,13 @@ void SQLTranslator::_translate_set_operation(const hsql::SetOperation& set_opera const auto right_input_lqp = nested_set_translator._translate_select_statement(*set_operator.nestedSelectStatement); const auto right_output_expressions = right_input_lqp->output_expressions(); - AssertInput(left_output_expressions.size() == right_output_expressions.size(), + const auto left_output_expression_count = left_output_expressions.size(); + const auto right_output_expression_count = right_output_expressions.size(); + AssertInput(left_output_expression_count == right_output_expression_count, "Mismatching number of input columns for set operation"); // Check to see if both input LQPs use the same data type for each column - for (auto expression_idx = ColumnID{0}; expression_idx < left_output_expressions.size(); ++expression_idx) { + for (auto expression_idx = ColumnID{0}; expression_idx < left_output_expression_count; ++expression_idx) { const auto& left_expression = left_output_expressions[expression_idx]; const auto& right_expression = right_output_expressions[expression_idx]; @@ -1240,16 +1250,16 @@ void SQLTranslator::_translate_order_by(const std::vector> expressions(order_list.size()); - std::vector sort_modes(order_list.size()); - for (auto expression_idx = size_t{0}; expression_idx < order_list.size(); ++expression_idx) { + const auto order_list_size = order_list.size(); + auto expressions = std::vector>(order_list_size); + auto sort_modes = std::vector(order_list_size); + for (auto expression_idx = size_t{0}; expression_idx < order_list_size; ++expression_idx) { const auto& order_description = order_list[expression_idx]; expressions[expression_idx] = _translate_hsql_expr(*order_description->expr, _sql_identifier_resolver); sort_modes[expression_idx] = order_type_to_sort_mode.at(order_description->type); } _current_lqp = _add_expressions_if_unavailable(_current_lqp, expressions); - _current_lqp = SortNode::make(expressions, sort_modes, _current_lqp); // If any Expressions were added to perform the sorting, remove them again @@ -1307,14 +1317,16 @@ std::shared_ptr SQLTranslator::_translate_create_view(const hsq if (create_statement.viewColumns) { // The CREATE VIEW statement has renamed the columns: CREATE VIEW myview (foo, bar) AS SELECT ... - AssertInput(create_statement.viewColumns->size() == output_expressions.size(), + const auto view_column_count = create_statement.viewColumns->size(); + AssertInput(view_column_count == output_expressions.size(), "Number of Columns in CREATE VIEW does not match SELECT statement"); - for (auto column_id = ColumnID{0}; column_id < create_statement.viewColumns->size(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < view_column_count; ++column_id) { column_names.insert_or_assign(column_id, (*create_statement.viewColumns)[column_id]); } } else { - for (auto column_id = ColumnID{0}; column_id < output_expressions.size(); ++column_id) { + const auto output_expression_count = output_expressions.size(); + for (auto column_id = ColumnID{0}; column_id < output_expression_count; ++column_id) { for (const auto& identifier : _inflated_select_list_elements[column_id].identifiers) { column_names.insert_or_assign(column_id, identifier.column_name); } @@ -1681,7 +1693,8 @@ std::shared_ptr SQLTranslator::_translate_hsql_expr( case hsql::kExprFunctionRef: { // convert to upper-case to find mapping - std::transform(name.begin(), name.end(), name.begin(), [](const auto c) { return std::toupper(c); }); + std::transform(name.cbegin(), name.cend(), name.begin(), + [](const auto character) { return std::toupper(character); }); // Some SQL functions have aliases, which we map to one unique identifier here. static const std::unordered_map function_aliases{{{"SUBSTRING"}, {"SUBSTR"}}}; @@ -1787,9 +1800,9 @@ std::shared_ptr SQLTranslator::_translate_hsql_expr( } return std::make_shared(function_iter->second, arguments); - } else { - FailInput("Couldn't resolve function '"s + name + "'"); } + + FailInput("Couldn't resolve function '"s + name + "'"); } case hsql::kExprOperator: { @@ -1825,7 +1838,9 @@ std::shared_ptr SQLTranslator::_translate_hsql_expr( if (is_binary_predicate_condition(predicate_condition)) { Assert(left && right, "Unexpected SQLParserResult. Didn't receive two arguments for binary_expression"); return std::make_shared(predicate_condition, left, right); - } else if (predicate_condition == PredicateCondition::BetweenInclusive) { + } + + if (predicate_condition == PredicateCondition::BetweenInclusive) { Assert(expr.exprList && expr.exprList->size() == 2, "Expected two arguments for BETWEEN"); return between_inclusive_(left, _translate_hsql_expr(*(*expr.exprList)[0], sql_identifier_resolver), _translate_hsql_expr(*(*expr.exprList)[1], sql_identifier_resolver)); @@ -1847,21 +1862,20 @@ std::shared_ptr SQLTranslator::_translate_hsql_expr( // `a IN (SELECT ...)` const auto subquery = _translate_hsql_subquery(*expr.select, sql_identifier_resolver); return in_(left, subquery); + } - } else { - // `a IN (x, y, z)` - std::vector> arguments; - - AssertInput(expr.exprList && !expr.exprList->empty(), "IN clauses with an empty list are invalid"); + // `a IN (x, y, z)` + std::vector> arguments; - arguments.reserve(expr.exprList->size()); - for (const auto* hsql_argument : *expr.exprList) { - arguments.emplace_back(_translate_hsql_expr(*hsql_argument, sql_identifier_resolver)); - } + AssertInput(expr.exprList && !expr.exprList->empty(), "IN clauses with an empty list are invalid"); - const auto array = std::make_shared(arguments); - return in_(left, array); + arguments.reserve(expr.exprList->size()); + for (const auto* hsql_argument : *expr.exprList) { + arguments.emplace_back(_translate_hsql_expr(*hsql_argument, sql_identifier_resolver)); } + + const auto array = std::make_shared(arguments); + return in_(left, array); } case hsql::kOpIsNull: @@ -2030,22 +2044,26 @@ std::shared_ptr SQLTranslator::_inverse_predicate(const Abst return std::make_shared( inverse_predicate_condition(binary_predicate_expression->predicate_condition), binary_predicate_expression->left_operand(), binary_predicate_expression->right_operand()); - } else if (const auto* const is_null_expression = dynamic_cast(&expression); - is_null_expression) { + } + + if (const auto* const is_null_expression = dynamic_cast(&expression); + is_null_expression) { // NOT (IS NULL ...) -> IS NOT NULL ... return std::make_shared(inverse_predicate_condition(is_null_expression->predicate_condition), is_null_expression->operand()); - } else if (const auto* const between_expression = dynamic_cast(&expression); - between_expression) { + } + + if (const auto* const between_expression = dynamic_cast(&expression); + between_expression) { // a BETWEEN b AND c -> a < b OR a > c return or_(less_than_(between_expression->value(), between_expression->lower_bound()), greater_than_(between_expression->value(), between_expression->upper_bound())); - } else { - const auto* in_expression = dynamic_cast(&expression); - Assert(in_expression, "Expected InExpression"); - return std::make_shared(inverse_predicate_condition(in_expression->predicate_condition), - in_expression->value(), in_expression->set()); } + + const auto* in_expression = dynamic_cast(&expression); + Assert(in_expression, "Expected InExpression"); + return std::make_shared(inverse_predicate_condition(in_expression->predicate_condition), + in_expression->value(), in_expression->set()); } break; case ExpressionType::Logical: { @@ -2113,16 +2131,11 @@ SQLTranslator::TableSourceState::TableSourceState( void SQLTranslator::TableSourceState::append(TableSourceState&& rhs) { for (auto& table_name_and_elements : rhs.elements_by_table_name) { - const auto unique = elements_by_table_name.count(table_name_and_elements.first) == 0; + const auto unique = !elements_by_table_name.contains(table_name_and_elements.first); AssertInput(unique, "Table Name '"s + table_name_and_elements.first + "' in FROM clause is not unique"); } - // This should be ::merge, but that is not yet supported by clang. - // elements_by_table_name.merge(std::move(rhs.elements_by_table_name)); - for (auto& kv : rhs.elements_by_table_name) { - elements_by_table_name.try_emplace(kv.first, std::move(kv.second)); - } - + elements_by_table_name.merge(std::move(rhs.elements_by_table_name)); elements_in_order.insert(elements_in_order.end(), rhs.elements_in_order.begin(), rhs.elements_in_order.end()); sql_identifier_resolver->append(std::move(*rhs.sql_identifier_resolver)); } diff --git a/src/lib/statistics/cardinality_estimator.cpp b/src/lib/statistics/cardinality_estimator.cpp index f5d5d5c6df..8bc390c0c9 100644 --- a/src/lib/statistics/cardinality_estimator.cpp +++ b/src/lib/statistics/cardinality_estimator.cpp @@ -358,7 +358,9 @@ std::shared_ptr CardinalityEstimator::estimate_predicate_node( auto output_table_statistics = std::make_shared(std::move(output_column_statistics), row_count); return output_table_statistics; - } else if (logical_expression->logical_operator == LogicalOperator::And) { + } + + if (logical_expression->logical_operator == LogicalOperator::And) { // Estimate AND by splitting it up into two consecutive PredicateNodes const auto first_predicate_node = @@ -418,15 +420,15 @@ std::shared_ptr CardinalityEstimator::estimate_predicate_node( // That implies estimating a selectivity of 1 for such predicates if (!operator_scan_predicates) { return input_table_statistics; - } else { - auto output_table_statistics = input_table_statistics; + } - for (const auto& operator_scan_predicate : *operator_scan_predicates) { - output_table_statistics = estimate_operator_scan_predicate(output_table_statistics, operator_scan_predicate); - } + auto output_table_statistics = input_table_statistics; - return output_table_statistics; + for (const auto& operator_scan_predicate : *operator_scan_predicates) { + output_table_statistics = estimate_operator_scan_predicate(output_table_statistics, operator_scan_predicate); } + + return output_table_statistics; } std::shared_ptr CardinalityEstimator::estimate_join_node( @@ -547,9 +549,9 @@ std::shared_ptr CardinalityEstimator::estimate_limit_node( } return std::make_shared(std::move(column_statistics), clamped_row_count); - } else { - return input_table_statistics; } + + return input_table_statistics; } std::shared_ptr CardinalityEstimator::estimate_operator_scan_predicate( diff --git a/src/lib/statistics/cardinality_estimator.hpp b/src/lib/statistics/cardinality_estimator.hpp index e52f94a751..7afa70dfee 100644 --- a/src/lib/statistics/cardinality_estimator.hpp +++ b/src/lib/statistics/cardinality_estimator.hpp @@ -135,6 +135,7 @@ class CardinalityEstimator : public AbstractCardinalityEstimator { return builder.build(); } + /** @} */ /** diff --git a/src/lib/statistics/join_graph_statistics_cache.cpp b/src/lib/statistics/join_graph_statistics_cache.cpp index 41b5e20446..9c3e8d6930 100644 --- a/src/lib/statistics/join_graph_statistics_cache.cpp +++ b/src/lib/statistics/join_graph_statistics_cache.cpp @@ -42,19 +42,20 @@ std::optional JoinGraphStatisticsCache::bitma DebugAssert(vertex_iter->second < bitmask->size(), "Vertex index out of range"); bitmask->set(vertex_iter->second); return LQPVisitation::DoNotVisitInputs; + } - } else if (const auto join_node = std::dynamic_pointer_cast(node)) { + if (const auto join_node = std::dynamic_pointer_cast(node)) { if (join_node->join_mode == JoinMode::Inner) { for (const auto& join_predicate : join_node->join_predicates()) { const auto predicate_index_iter = _predicate_indices.find(join_predicate); if (predicate_index_iter == _predicate_indices.end()) { bitmask.reset(); return LQPVisitation::DoNotVisitInputs; - } else { - Assert(predicate_index_iter->second + _vertex_indices.size() < bitmask->size(), - "Predicate index out of range"); - bitmask->set(predicate_index_iter->second + _vertex_indices.size()); } + + Assert(predicate_index_iter->second + _vertex_indices.size() < bitmask->size(), + "Predicate index out of range"); + bitmask->set(predicate_index_iter->second + _vertex_indices.size()); } } else if (join_node->join_mode == JoinMode::Cross) { return LQPVisitation::VisitInputs; @@ -69,11 +70,10 @@ std::optional JoinGraphStatisticsCache::bitma if (predicate_index_iter == _predicate_indices.end()) { bitmask.reset(); return LQPVisitation::DoNotVisitInputs; - } else { - Assert(predicate_index_iter->second + _vertex_indices.size() < bitmask->size(), "Predicate index out of range"); - bitmask->set(predicate_index_iter->second + _vertex_indices.size()); } + Assert(predicate_index_iter->second + _vertex_indices.size() < bitmask->size(), "Predicate index out of range"); + bitmask->set(predicate_index_iter->second + _vertex_indices.size()); } else if (node->type == LQPNodeType::Sort) { // ignore node type as it doesn't change the cardinality } else { @@ -106,7 +106,8 @@ std::shared_ptr JoinGraphStatisticsCache::get( // of the result auto cached_column_ids = std::vector{requested_column_order.size()}; auto result_column_data_types = std::vector{requested_column_order.size()}; - for (auto column_id = ColumnID{0}; column_id < requested_column_order.size(); ++column_id) { + const auto requested_column_order_size = requested_column_order.size(); + for (auto column_id = ColumnID{0}; column_id < requested_column_order_size; ++column_id) { const auto cached_column_id_iter = cache_entry.column_expression_order.find(requested_column_order[column_id]); Assert(cached_column_id_iter != cache_entry.column_expression_order.end(), "Column not found in cached statistics"); const auto cached_column_id = cached_column_id_iter->second; @@ -115,10 +116,10 @@ std::shared_ptr JoinGraphStatisticsCache::get( } // Allocate the TableStatistics to be returned - auto output_column_statistics = std::vector>{requested_column_order.size()}; + auto output_column_statistics = std::vector>{requested_column_order_size}; // Bring AttributeStatistics into the requested order for each statistics slice - for (auto column_id = ColumnID{0}; column_id < requested_column_order.size(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < requested_column_order_size; ++column_id) { const auto cached_column_id = cached_column_ids[column_id]; const auto& cached_column_statistics = cached_table_statistics->column_statistics[cached_column_id]; output_column_statistics[column_id] = cached_column_statistics; @@ -136,7 +137,8 @@ void JoinGraphStatisticsCache::set(const Bitmask& bitmask, auto cache_entry = CacheEntry{}; cache_entry.table_statistics = table_statistics; - for (auto column_id = ColumnID{0}; column_id < column_order.size(); ++column_id) { + const auto column_order_count = column_order.size(); + for (auto column_id = ColumnID{0}; column_id < column_order_count; ++column_id) { cache_entry.column_expression_order.emplace(column_order[column_id], column_id); } diff --git a/src/lib/statistics/statistics_objects/abstract_histogram.cpp b/src/lib/statistics/statistics_objects/abstract_histogram.cpp index c59d1c9b94..e799495390 100644 --- a/src/lib/statistics/statistics_objects/abstract_histogram.cpp +++ b/src/lib/statistics/statistics_objects/abstract_histogram.cpp @@ -315,10 +315,10 @@ std::pair AbstractHistogram::estimate_cardinality if (bin_distinct_count == 0) { return {Cardinality{0.0f}, 0.0f}; - } else { - const auto cardinality = Cardinality{bin_height(bin_id) / bin_distinct_count}; - return {cardinality, std::min(bin_distinct_count, HistogramCountType{1.0f})}; } + + const auto cardinality = Cardinality{bin_height(bin_id) / bin_distinct_count}; + return {cardinality, std::min(bin_distinct_count, HistogramCountType{1.0f})}; } case PredicateCondition::NotEquals: diff --git a/src/lib/statistics/statistics_objects/equal_distinct_count_histogram.cpp b/src/lib/statistics/statistics_objects/equal_distinct_count_histogram.cpp index a258970bdf..fa32e9c9a1 100644 --- a/src/lib/statistics/statistics_objects/equal_distinct_count_histogram.cpp +++ b/src/lib/statistics/statistics_objects/equal_distinct_count_histogram.cpp @@ -67,7 +67,7 @@ std::vector> value_distribution_from_column(con std::vector>{value_distribution_map.begin(), value_distribution_map.end()}; value_distribution_map.clear(); // Maps can be large and sorting slow. Free space early. boost::sort::pdqsort(value_distribution.begin(), value_distribution.end(), - [&](const auto& l, const auto& r) { return l.first < r.first; }); + [&](const auto& lhs, const auto& rhs) { return lhs.first < rhs.first; }); return value_distribution; } @@ -143,7 +143,9 @@ std::shared_ptr> EqualDistinctCountHistogram:: bin_heights[bin_idx] = std::accumulate(value_distribution.cbegin() + min_value_idx, value_distribution.cbegin() + max_value_idx + 1, HistogramCountType{0}, - [](HistogramCountType a, const std::pair& b) { return a + b.second; }); + [](HistogramCountType bin_height, const std::pair& value_and_count) { + return bin_height + value_and_count.second; + }); min_value_idx = max_value_idx + 1; } @@ -177,10 +179,10 @@ BinID EqualDistinctCountHistogram::bin_count() const { template BinID EqualDistinctCountHistogram::_bin_for_value(const T& value) const { - const auto it = std::lower_bound(_bin_maxima.cbegin(), _bin_maxima.cend(), value); - const auto index = static_cast(std::distance(_bin_maxima.cbegin(), it)); + const auto iter = std::lower_bound(_bin_maxima.cbegin(), _bin_maxima.cend(), value); + const auto index = static_cast(std::distance(_bin_maxima.cbegin(), iter)); - if (it == _bin_maxima.cend() || value < bin_minimum(index) || value > bin_maximum(index)) { + if (iter == _bin_maxima.cend() || value < bin_minimum(index) || value > bin_maximum(index)) { return INVALID_BIN_ID; } diff --git a/src/lib/statistics/statistics_objects/generic_histogram.cpp b/src/lib/statistics/statistics_objects/generic_histogram.cpp index 85a1cd3ede..85b3d4bcec 100644 --- a/src/lib/statistics/statistics_objects/generic_histogram.cpp +++ b/src/lib/statistics/statistics_objects/generic_histogram.cpp @@ -61,10 +61,10 @@ BinID GenericHistogram::bin_count() const { template BinID GenericHistogram::_bin_for_value(const T& value) const { - const auto it = std::lower_bound(_bin_maxima.cbegin(), _bin_maxima.cend(), value); - const auto index = static_cast(std::distance(_bin_maxima.cbegin(), it)); + const auto iter = std::lower_bound(_bin_maxima.cbegin(), _bin_maxima.cend(), value); + const auto index = static_cast(std::distance(_bin_maxima.cbegin(), iter)); - if (it == _bin_maxima.cend() || value < bin_minimum(index) || value > bin_maximum(index)) { + if (iter == _bin_maxima.cend() || value < bin_minimum(index) || value > bin_maximum(index)) { return INVALID_BIN_ID; } @@ -73,13 +73,13 @@ BinID GenericHistogram::_bin_for_value(const T& value) const { template BinID GenericHistogram::_next_bin_for_value(const T& value) const { - const auto it = std::upper_bound(_bin_maxima.cbegin(), _bin_maxima.cend(), value); + const auto iter = std::upper_bound(_bin_maxima.cbegin(), _bin_maxima.cend(), value); - if (it == _bin_maxima.cend()) { + if (iter == _bin_maxima.cend()) { return INVALID_BIN_ID; } - return static_cast(std::distance(_bin_maxima.cbegin(), it)); + return static_cast(std::distance(_bin_maxima.cbegin(), iter)); } template diff --git a/src/lib/statistics/statistics_objects/min_max_filter.cpp b/src/lib/statistics/statistics_objects/min_max_filter.cpp index 9a326b67ba..576d44fc93 100644 --- a/src/lib/statistics/statistics_objects/min_max_filter.cpp +++ b/src/lib/statistics/statistics_objects/min_max_filter.cpp @@ -159,10 +159,12 @@ bool MinMaxFilter::does_not_contain(const PredicateCondition predicate_condit const auto value2 = boost::get(*variant_value2); return value >= max || value2 <= min; } - case PredicateCondition::Like: { // NOLINTNEXTLINE - clang-tidy doesn't like the else path of the if constexpr + // NOLINTBEGIN(bugprone-branch-clone) + // clang-tidy considers the following two cases to be identical. They are only identical for non-strings. + case PredicateCondition::Like: { // We use the ascii collation for min/max filters. This means that lower case letters are considered larger than - // upper case letters. This can lead to a situation, where the USA% (e.g., JOB query XXXXX) is not pruned - // whenever just a single value starts with a lower case letter. + // upper case letters. This can lead to a situation, where the USA% (e.g., Join Order Benchamrk query 15c) is not + // pruned whenever just a single value starts with a lower case letter. // Examples for the handling of Like predicate: // | test% | %test | test\x7F% | test | '' (empty string) // LikeMatcher::bounds() | {test, tesu} | nullopt | nullopt | {test, test\0} | {'', '\0'} @@ -175,13 +177,12 @@ bool MinMaxFilter::does_not_contain(const PredicateCondition predicate_condit } const auto [lower_bound, upper_bound] = *bounds; - return max < lower_bound || upper_bound <= min; } return false; } - case PredicateCondition::NotLike: { // NOLINTNEXTLINE - clang-tidy doesn't like the else path of the if constexpr + case PredicateCondition::NotLike: { // Examples for the handling of NotLike predicate: // | test% | %test | test\x7F% | test | '' (empty string) // LikeMatcher::bounds() | {test, tesu} | nullopt | nullopt | {test, test\0} | {'', '\0'} @@ -194,12 +195,12 @@ bool MinMaxFilter::does_not_contain(const PredicateCondition predicate_condit } const auto [lower_bound, upper_bound] = *bounds; - return max < upper_bound && lower_bound <= min; } return false; } + // NOLINTEND(bugprone-branch-clone) default: return false; } diff --git a/src/lib/statistics/statistics_objects/range_filter.cpp b/src/lib/statistics/statistics_objects/range_filter.cpp index b54dc13f67..294374986d 100644 --- a/src/lib/statistics/statistics_objects/range_filter.cpp +++ b/src/lib/statistics/statistics_objects/range_filter.cpp @@ -49,40 +49,42 @@ std::shared_ptr RangeFilter::sliced( return std::make_shared>(value, value); case PredicateCondition::LessThan: case PredicateCondition::LessThanEquals: { - auto end_it = std::lower_bound(ranges.cbegin(), ranges.cend(), value, - [](const auto& a, const auto& b) { return a.second < b; }); + auto end_iter = + std::lower_bound(ranges.cbegin(), ranges.cend(), value, + [](const auto& range, const auto& search_value) { return range.second < search_value; }); // Copy all the ranges before the value. - auto it = ranges.cbegin(); - for (; it != end_it; it++) { - sliced_ranges.emplace_back(*it); + auto iter = ranges.cbegin(); + for (; iter != end_iter; iter++) { + sliced_ranges.emplace_back(*iter); } - DebugAssert(it != ranges.cend(), "does_not_contain() should have caught that."); + DebugAssert(iter != ranges.cend(), "does_not_contain() should have caught that."); // If value is not in a gap, limit the last range's upper bound to value. - if (value >= it->first) { - sliced_ranges.emplace_back(std::pair{it->first, value}); + if (value >= iter->first) { + sliced_ranges.emplace_back(std::pair{iter->first, value}); } } break; case PredicateCondition::GreaterThan: case PredicateCondition::GreaterThanEquals: { - auto it = std::lower_bound(ranges.cbegin(), ranges.cend(), value, - [](const auto& a, const auto& b) { return a.second < b; }); + auto iter = + std::lower_bound(ranges.cbegin(), ranges.cend(), value, + [](const auto& range, const auto& search_value) { return range.second < search_value; }); - DebugAssert(it != ranges.cend(), "does_not_contain() should have caught that."); + DebugAssert(iter != ranges.cend(), "does_not_contain() should have caught that."); // If value is in a gap, use the next range, otherwise limit the next range's upper bound to value. - if (value <= it->first) { - sliced_ranges.emplace_back(*it); + if (value <= iter->first) { + sliced_ranges.emplace_back(*iter); } else { - sliced_ranges.emplace_back(std::pair{value, it->second}); + sliced_ranges.emplace_back(std::pair{value, iter->second}); } - it++; + iter++; // Copy all following ranges. - for (; it != ranges.cend(); it++) { - sliced_ranges.emplace_back(*it); + for (; iter != ranges.cend(); iter++) { + sliced_ranges.emplace_back(*iter); } } break; diff --git a/src/lib/storage/base_segment_encoder.hpp b/src/lib/storage/base_segment_encoder.hpp index 7a44794e1e..5997aa93f3 100644 --- a/src/lib/storage/base_segment_encoder.hpp +++ b/src/lib/storage/base_segment_encoder.hpp @@ -107,6 +107,7 @@ class SegmentEncoder : public BaseSegmentEncoder { _vector_compression_type = type; } + /**@}*/ public: @@ -143,6 +144,7 @@ class SegmentEncoder : public BaseSegmentEncoder { // For now, we allocate without a specific memory source. return _self()._on_encode(iterable, PolymorphicAllocator{}); } + /**@}*/ protected: diff --git a/src/lib/storage/chunk.cpp b/src/lib/storage/chunk.cpp index 69819b3be6..f270973ffa 100644 --- a/src/lib/storage/chunk.cpp +++ b/src/lib/storage/chunk.cpp @@ -162,7 +162,7 @@ bool Chunk::references_exactly_one_table() const { auto first_referenced_table = first_segment->referenced_table(); auto first_pos_list = first_segment->pos_list(); - for (ColumnID column_id{1}; column_id < column_count(); ++column_id) { + for (auto column_id = ColumnID{1}; column_id < column_count(); ++column_id) { const auto segment = std::dynamic_pointer_cast(get_segment(column_id)); if (!segment) { return false; @@ -245,6 +245,7 @@ void Chunk::set_pruning_statistics(const std::optional& _pruning_statistics = pruning_statistics; } + void Chunk::increase_invalid_row_count(const ChunkOffset count) const { _invalid_row_count += count; } @@ -294,7 +295,6 @@ void Chunk::set_individually_sorted_by(const std::vector& } std::optional Chunk::get_cleanup_commit_id() const { - // TODO(Martin): check with PR #2402 whether GCC still needs the `.load()` (some used in abstract_task.cpp twice). if (_cleanup_commit_id.load() == CommitID{0}) { // Cleanup-Commit-ID is not yet set return std::nullopt; diff --git a/src/lib/storage/chunk_encoder.cpp b/src/lib/storage/chunk_encoder.cpp index 77aebfca8e..c1b8210e77 100644 --- a/src/lib/storage/chunk_encoder.cpp +++ b/src/lib/storage/chunk_encoder.cpp @@ -150,7 +150,7 @@ void ChunkEncoder::encode_all_chunks(const std::shared_ptr
& table, const auto chunk = table->get_chunk(chunk_id); Assert(chunk, "Physically deleted chunk should not reach this point, see get_chunk / #1686."); - const auto chunk_encoding_spec = chunk_encoding_specs[chunk_id]; + const auto& chunk_encoding_spec = chunk_encoding_specs[chunk_id]; encode_chunk(chunk, column_types, chunk_encoding_spec); } } diff --git a/src/lib/storage/dictionary_segment.cpp b/src/lib/storage/dictionary_segment.cpp index 6686220714..9676cd6bd0 100644 --- a/src/lib/storage/dictionary_segment.cpp +++ b/src/lib/storage/dictionary_segment.cpp @@ -85,11 +85,11 @@ ValueID DictionarySegment::lower_bound(const AllTypeVariant& value) const { static_cast(std::ceil(std::log2(_dictionary->size()))); const auto typed_value = boost::get(value); - auto it = std::lower_bound(_dictionary->cbegin(), _dictionary->cend(), typed_value); - if (it == _dictionary->cend()) { + auto iter = std::lower_bound(_dictionary->cbegin(), _dictionary->cend(), typed_value); + if (iter == _dictionary->cend()) { return INVALID_VALUE_ID; } - return ValueID{static_cast(std::distance(_dictionary->cbegin(), it))}; + return ValueID{static_cast(std::distance(_dictionary->cbegin(), iter))}; } template @@ -99,11 +99,11 @@ ValueID DictionarySegment::upper_bound(const AllTypeVariant& value) const { static_cast(std::ceil(std::log2(_dictionary->size()))); const auto typed_value = boost::get(value); - auto it = std::upper_bound(_dictionary->cbegin(), _dictionary->cend(), typed_value); - if (it == _dictionary->cend()) { + auto iter = std::upper_bound(_dictionary->cbegin(), _dictionary->cend(), typed_value); + if (iter == _dictionary->cend()) { return INVALID_VALUE_ID; } - return ValueID{static_cast(std::distance(_dictionary->cbegin(), it))}; + return ValueID{static_cast(std::distance(_dictionary->cbegin(), iter))}; } template diff --git a/src/lib/storage/dictionary_segment/attribute_vector_iterable.hpp b/src/lib/storage/dictionary_segment/attribute_vector_iterable.hpp index 0b2da1f20d..1da61eceb2 100644 --- a/src/lib/storage/dictionary_segment/attribute_vector_iterable.hpp +++ b/src/lib/storage/dictionary_segment/attribute_vector_iterable.hpp @@ -60,6 +60,7 @@ class AttributeVectorIterable : public PointAccessibleSegmentIterable, SegmentPosition> { public: using ValueType = ValueID; + explicit Iterator(const ValueID null_value_id, CompressedVectorIterator&& attribute_it, ChunkOffset chunk_offset) : _null_value_id{null_value_id}, _attribute_it{std::move(attribute_it)}, _chunk_offset{chunk_offset} {} @@ -108,6 +109,7 @@ class AttributeVectorIterable : public PointAccessibleSegmentIterable, PosListIteratorType> { public: using ValueType = ValueID; + PointAccessIterator(const ValueID null_value_id, Decompressor&& attribute_decompressor, const PosListIteratorType&& position_filter_begin, PosListIteratorType&& position_filter_it) : AbstractPointAccessSegmentIterator, diff --git a/src/lib/storage/encoding_type.hpp b/src/lib/storage/encoding_type.hpp index 5d84f748f1..10c3a5b522 100644 --- a/src/lib/storage/encoding_type.hpp +++ b/src/lib/storage/encoding_type.hpp @@ -62,7 +62,9 @@ bool encoding_supports_data_type(EncodingType encoding_type, DataType data_type) struct SegmentEncodingSpec { constexpr SegmentEncodingSpec() : encoding_type{EncodingType::Dictionary} {} + explicit constexpr SegmentEncodingSpec(EncodingType init_encoding_type) : encoding_type{init_encoding_type} {} + constexpr SegmentEncodingSpec(EncodingType init_encoding_type, std::optional init_vector_compression_type) : encoding_type{init_encoding_type}, vector_compression_type{init_vector_compression_type} {} diff --git a/src/lib/storage/fixed_string_dictionary_segment/fixed_string.cpp b/src/lib/storage/fixed_string_dictionary_segment/fixed_string.cpp index 59fbfe7220..d0fbc8ad0b 100644 --- a/src/lib/storage/fixed_string_dictionary_segment/fixed_string.cpp +++ b/src/lib/storage/fixed_string_dictionary_segment/fixed_string.cpp @@ -51,11 +51,11 @@ size_t FixedString::maximum_length() const { } std::string FixedString::string() const { - return std::string(_mem, strnlen(_mem, _maximum_length)); + return {_mem, strnlen(_mem, _maximum_length)}; } std::string_view FixedString::string_view() const { - return std::string_view(_mem, strnlen(_mem, _maximum_length)); + return {_mem, strnlen(_mem, _maximum_length)}; } bool FixedString::operator<(const FixedString& other) const { @@ -64,6 +64,7 @@ bool FixedString::operator<(const FixedString& other) const { if (result == 0) { return size() < other.size(); } + return result < 0; } @@ -104,8 +105,8 @@ void FixedString::swap(FixedString& other) { std::swap_ranges(_mem, _mem + _maximum_length, other._mem); } -std::ostream& operator<<(std::ostream& os, const FixedString& obj) { - return os << obj.string(); +std::ostream& operator<<(std::ostream& stream, const FixedString& obj) { + return stream << obj.string(); } void swap(FixedString lhs, FixedString rhs) { diff --git a/src/lib/storage/fixed_string_dictionary_segment/fixed_string.hpp b/src/lib/storage/fixed_string_dictionary_segment/fixed_string.hpp index f3d069df7b..43fc8b99d9 100644 --- a/src/lib/storage/fixed_string_dictionary_segment/fixed_string.hpp +++ b/src/lib/storage/fixed_string_dictionary_segment/fixed_string.hpp @@ -68,7 +68,7 @@ class FixedString { friend bool operator==(const char* lhs, const FixedString& rhs); // Prints FixedString as string - friend std::ostream& operator<<(std::ostream& os, const FixedString& obj); + friend std::ostream& operator<<(std::ostream& stream, const FixedString& obj); // Support swappable concept needed for sorting values. See: http://en.cppreference.com/w/cpp/concept/Swappable friend void swap(FixedString lhs, FixedString rhs); diff --git a/src/lib/storage/fixed_string_dictionary_segment/fixed_string_vector.cpp b/src/lib/storage/fixed_string_dictionary_segment/fixed_string_vector.cpp index 03a08ac9e6..e458f270d8 100644 --- a/src/lib/storage/fixed_string_dictionary_segment/fixed_string_vector.cpp +++ b/src/lib/storage/fixed_string_dictionary_segment/fixed_string_vector.cpp @@ -28,30 +28,31 @@ void FixedStringVector::push_back(const pmr_string& string) { } FixedStringIterator FixedStringVector::begin() noexcept { - return FixedStringIterator(_string_length, _chars, 0); + return {_string_length, _chars, 0}; } FixedStringIterator FixedStringVector::end() noexcept { - return FixedStringIterator(_string_length, _chars, _string_length == 0 ? 0 : _chars.size()); + return {_string_length, _chars, _string_length == 0 ? 0 : _chars.size()}; } FixedStringIterator FixedStringVector::begin() const noexcept { - return FixedStringIterator(_string_length, _chars, 0); + return {_string_length, _chars, 0}; } FixedStringIterator FixedStringVector::end() const noexcept { - return FixedStringIterator(_string_length, _chars, _string_length == 0 ? 0 : _chars.size()); + return {_string_length, _chars, _string_length == 0 ? 0 : _chars.size()}; } FixedStringIterator FixedStringVector::cbegin() const noexcept { - return FixedStringIterator(_string_length, _chars, 0); + return {_string_length, _chars, 0}; } FixedStringIterator FixedStringVector::cend() const noexcept { - return FixedStringIterator(_string_length, _chars, _string_length == 0 ? 0 : _chars.size()); + return {_string_length, _chars, _string_length == 0 ? 0 : _chars.size()}; } using ReverseIterator = boost::reverse_iterator>; + ReverseIterator FixedStringVector::rbegin() noexcept { return ReverseIterator(end()); } @@ -66,7 +67,7 @@ FixedString FixedStringVector::operator[](const size_t pos) { } FixedString FixedStringVector::at(const size_t pos) { - return FixedString(&_chars.at(pos * _string_length), _string_length); + return {&_chars.at(pos * _string_length), _string_length}; } pmr_string FixedStringVector::get_string_at(const size_t pos) const { @@ -77,10 +78,10 @@ pmr_string FixedStringVector::get_string_at(const size_t pos) const { if (*(string_start + string_end) == '\0') { // The string is zero-padded - the pmr_string constructor takes care of finding the correct length - return pmr_string(string_start); - } else { - return pmr_string(string_start, _string_length); + return {string_start}; } + + return {string_start, _string_length}; } const char* FixedStringVector::data() const { @@ -121,8 +122,8 @@ PolymorphicAllocator FixedStringVector::get_allocator() { return _chars.get_allocator(); } -void FixedStringVector::reserve(const size_t n) { - _chars.reserve(n * _string_length); +void FixedStringVector::reserve(const size_t size) { + _chars.reserve(size * _string_length); } size_t FixedStringVector::data_size() const { diff --git a/src/lib/storage/fixed_string_dictionary_segment/fixed_string_vector.hpp b/src/lib/storage/fixed_string_dictionary_segment/fixed_string_vector.hpp index 1e794a5de8..96724b7c71 100644 --- a/src/lib/storage/fixed_string_dictionary_segment/fixed_string_vector.hpp +++ b/src/lib/storage/fixed_string_dictionary_segment/fixed_string_vector.hpp @@ -77,7 +77,7 @@ class FixedStringVector { size_t string_length() const; // Request the vector capacity to be at least enough to contain n elements - void reserve(const size_t n); + void reserve(const size_t size); // Remove elements from the vector void erase(const FixedStringIterator start, const FixedStringIterator end); diff --git a/src/lib/storage/frame_of_reference_segment.hpp b/src/lib/storage/frame_of_reference_segment.hpp index 05e2cdac6f..e52db4ddfb 100644 --- a/src/lib/storage/frame_of_reference_segment.hpp +++ b/src/lib/storage/frame_of_reference_segment.hpp @@ -19,26 +19,20 @@ class BaseCompressedVector; /** * @brief Segment implementing frame-of-reference encoding * - * Frame-of-Reference encoding divides the values of segment into - * fixed-size blocks. The values of each block are encoded - * as an offset from the block’s minimum value. These offsets, - * which can ideally be represented by fewer bits, are then - * compressed using vector compression (null suppression). - * FOR encoding on its own without vector compression does not - * add any benefit. + * Frame-of-Reference encoding divides the values of segment into fixed-size blocks. The values of each block are + * encoded as an offset from the block's minimum value. These offsets, which can ideally be represented by fewer bits, + * are then compressed using vector compression (null suppression). * - * Null values are stored in a separate vector. Note, for correct - * offset handling, the minimum of each frame is stored in the - * offset_values vector at each position that is NULL. + * FOR encoding on its own without vector compression does not add any benefit. * - * std::enable_if_t must be used here and cannot be replaced by a - * static_assert in order to prevent instantiation of - * FrameOfReferenceSegment with T other than int32_t. Otherwise, - * the compiler might instantiate FrameOfReferenceSegment with other - * types even if they are never actually needed. - * "If the function selected by overload resolution can be determined - * without instantiating a class template definition, it is unspecified - * whether that instantiation actually takes place." Draft Std. N4800 12.8.1.8 + * Null values are stored in a separate vector. Note, for correct offset handling, the minimum of each frame is stored + * in the offset_values vector at each position that is NULL. + * + * std::enable_if_t must be used here and cannot be replaced by a static_assert in order to prevent instantiation of + * FrameOfReferenceSegment with T other than int32_t. Otherwise, the compiler might instantiate + * FrameOfReferenceSegment with other types even if they are never actually needed. + * "If the function selected by overload resolution can be determined without instantiating a class template + * definition, it is unspecified whether that instantiation actually takes place." Draft Std. N4800 12.8.1.8 */ template , hana::type_c)>> diff --git a/src/lib/storage/index/adaptive_radix_tree/adaptive_radix_tree_index.cpp b/src/lib/storage/index/adaptive_radix_tree/adaptive_radix_tree_index.cpp index 81d8fcc522..0d0bc8de4f 100644 --- a/src/lib/storage/index/adaptive_radix_tree/adaptive_radix_tree_index.cpp +++ b/src/lib/storage/index/adaptive_radix_tree/adaptive_radix_tree_index.cpp @@ -62,11 +62,14 @@ AbstractIndex::Iterator AdaptiveRadixTreeIndex::_lower_bound(const std::vectorlower_bound(values[0]); if (value_id == INVALID_VALUE_ID) { return _chunk_offsets.end(); - } else if (_root) { // _root is nullptr if the index contains NULL positions only + } + + // _root is nullptr if the index contains NULL positions only + if (_root) { return _root->lower_bound(BinaryComparable(value_id), 0); - } else { - return _cend(); } + + return _cend(); } AbstractIndex::Iterator AdaptiveRadixTreeIndex::_upper_bound(const std::vector& values) const { @@ -77,11 +80,14 @@ AbstractIndex::Iterator AdaptiveRadixTreeIndex::_upper_bound(const std::vectorupper_bound(values[0]); if (value_id == INVALID_VALUE_ID) { return _chunk_offsets.end(); - } else if (_root) { // _root is nullptr if the index contains NULL positions only + } + + // _root is nullptr if the index contains NULL positions only + if (_root) { return _root->lower_bound(BinaryComparable(value_id), 0); - } else { - return _cend(); } + + return _cend(); } AbstractIndex::Iterator AdaptiveRadixTreeIndex::_cbegin() const { @@ -96,11 +102,11 @@ std::shared_ptr AdaptiveRadixTreeIndex::_bulk_insert( const std::vector>& values) { if (values.empty()) { return nullptr; - } else { - _chunk_offsets.reserve(values.size()); - auto begin = _chunk_offsets.cbegin(); - return _bulk_insert(values, static_cast(0u), begin); } + + _chunk_offsets.reserve(values.size()); + auto begin = _chunk_offsets.cbegin(); + return _bulk_insert(values, static_cast(0u), begin); } std::shared_ptr AdaptiveRadixTreeIndex::_bulk_insert( @@ -145,13 +151,17 @@ std::shared_ptr AdaptiveRadixTreeIndex::_bulk_insert( // finally create the appropriate ARTNode according to the size of the children if (children.size() <= 4) { return std::make_shared(children); - } else if (children.size() <= 16) { + } + + if (children.size() <= 16) { return std::make_shared(children); - } else if (children.size() <= 48) { + } + + if (children.size() <= 48) { return std::make_shared(children); - } else { - return std::make_shared(children); } + + return std::make_shared(children); } std::vector> AdaptiveRadixTreeIndex::_get_indexed_segments() const { @@ -164,7 +174,7 @@ size_t AdaptiveRadixTreeIndex::_memory_consumption() const { } AdaptiveRadixTreeIndex::BinaryComparable::BinaryComparable(ValueID value) : _parts(sizeof(value)) { - for (size_t byte_id = 1; byte_id <= _parts.size(); ++byte_id) { + for (auto byte_id = size_t{1}; byte_id <= _parts.size(); ++byte_id) { // grab the 8 least significant bits and put them at the front of the vector _parts[_parts.size() - byte_id] = static_cast(value) & 0xFFu; // rightshift 8 bits diff --git a/src/lib/storage/index/adaptive_radix_tree/adaptive_radix_tree_nodes.cpp b/src/lib/storage/index/adaptive_radix_tree/adaptive_radix_tree_nodes.cpp index fdbe31e403..7e19d8d22e 100644 --- a/src/lib/storage/index/adaptive_radix_tree/adaptive_radix_tree_nodes.cpp +++ b/src/lib/storage/index/adaptive_radix_tree/adaptive_radix_tree_nodes.cpp @@ -29,9 +29,10 @@ ARTNode4::ARTNode4(std::vector>>& ch [](const std::pair>& left, const std::pair>& right) { return left.first < right.first; }); _partial_keys.fill(INVALID_INDEX); - for (auto i = size_t{0}; i < children.size(); ++i) { - _partial_keys[i] = children[i].first; - _children[i] = children[i].second; + const auto child_count = children.size(); + for (auto index = size_t{0}; index < child_count; ++index) { + _partial_keys[index] = children[index].first; + _children[index] = children[index].second; } } @@ -61,8 +62,8 @@ ARTNode4::ARTNode4(std::vector>>& ch AbstractIndex::Iterator ARTNode4::_delegate_to_child(const AdaptiveRadixTreeIndex::BinaryComparable& key, size_t depth, const std::function& function) const { - auto partial_key = key[depth]; - for (uint8_t partial_key_id = 0; partial_key_id < 4; ++partial_key_id) { + const auto partial_key = key[depth]; + for (auto partial_key_id = uint8_t{0}; partial_key_id < 4; ++partial_key_id) { if (_partial_keys[partial_key_id] < partial_key) { continue; // key not found yet } @@ -81,13 +82,15 @@ AbstractIndex::Iterator ARTNode4::_delegate_to_child(const AdaptiveRadixTreeInde } AbstractIndex::Iterator ARTNode4::lower_bound(const AdaptiveRadixTreeIndex::BinaryComparable& key, size_t depth) const { - return _delegate_to_child( - key, depth, [&key, this](size_t i, size_t new_depth) { return _children[i]->lower_bound(key, new_depth); }); + return _delegate_to_child(key, depth, [&key, this](size_t index, size_t new_depth) { + return _children[index]->lower_bound(key, new_depth); + }); } AbstractIndex::Iterator ARTNode4::upper_bound(const AdaptiveRadixTreeIndex::BinaryComparable& key, size_t depth) const { - return _delegate_to_child( - key, depth, [&key, this](size_t i, size_t new_depth) { return _children[i]->upper_bound(key, new_depth); }); + return _delegate_to_child(key, depth, [&key, this](size_t index, size_t new_depth) { + return _children[index]->upper_bound(key, new_depth); + }); } AbstractIndex::Iterator ARTNode4::begin() const { @@ -95,9 +98,9 @@ AbstractIndex::Iterator ARTNode4::begin() const { } AbstractIndex::Iterator ARTNode4::end() const { - for (uint8_t i = 4; i > 0; --i) { - if (_children[i - 1]) { - return _children[i - 1]->end(); + for (auto index = uint32_t{4}; index > 0; --index) { + if (_children[index - 1]) { + return _children[index - 1]->end(); } } Fail("Empty _children array in ARTNode4 should never happen"); @@ -118,9 +121,10 @@ ARTNode16::ARTNode16(std::vector>>& [](const std::pair>& left, const std::pair>& right) { return left.first < right.first; }); _partial_keys.fill(INVALID_INDEX); - for (auto i = size_t{0}; i < children.size(); ++i) { - _partial_keys[i] = children[i].first; - _children[i] = children[i].second; + const auto child_count = children.size(); + for (auto index = uint32_t{0}; index < child_count; ++index) { + _partial_keys[index] = children[index].first; + _children[index] = children[index].second; } } @@ -200,10 +204,10 @@ AbstractIndex::Iterator ARTNode16::end() const { if (!_children[partial_key_pos]) { // there does not exist a child with partial_key 255u, we take the partial_key in front of it return _children[partial_key_pos - 1]->end(); - } else { - // there exists a child with partial_key 255u - return _children[partial_key_pos]->end(); } + + // there exists a child with partial_key 255u + return _children[partial_key_pos]->end(); } /** @@ -218,9 +222,10 @@ AbstractIndex::Iterator ARTNode16::end() const { ARTNode48::ARTNode48(const std::vector>>& children) { _index_to_child.fill(INVALID_INDEX); - for (auto i = size_t{0}; i < children.size(); ++i) { - _index_to_child[children[i].first] = static_cast(i); - _children[i] = children[i].second; + const auto child_count = children.size(); + for (auto index = uint8_t{0}; index < child_count; ++index) { + _index_to_child[children[index].first] = index; + _children[index] = children[index].second; } } @@ -257,15 +262,15 @@ ARTNode48::ARTNode48(const std::vector& function) const { - auto partial_key = key[depth]; + const auto partial_key = key[depth]; if (_index_to_child[partial_key] != INVALID_INDEX) { // case0 return function(partial_key, ++depth); } - for (uint16_t i = partial_key + 1; i < 256u; ++i) { - if (_index_to_child[i] != INVALID_INDEX) { + for (auto index = partial_key + 1; index < 256; ++index) { + if (_index_to_child[index] != INVALID_INDEX) { // case2 - return _children[_index_to_child[i]]->begin(); + return _children[_index_to_child[index]]->begin(); } } // case1 @@ -287,7 +292,7 @@ AbstractIndex::Iterator ARTNode48::upper_bound(const AdaptiveRadixTreeIndex::Bin } AbstractIndex::Iterator ARTNode48::begin() const { - for (auto index : _index_to_child) { + for (const auto index : _index_to_child) { if (index != INVALID_INDEX) { return _children[index]->begin(); } @@ -296,9 +301,10 @@ AbstractIndex::Iterator ARTNode48::begin() const { } AbstractIndex::Iterator ARTNode48::end() const { - for (uint8_t i = static_cast(_index_to_child.size()) - 1; i > 0; --i) { - if (_index_to_child[i] != INVALID_INDEX) { - return _children[_index_to_child[i]]->begin(); + const auto start_index = size_t{_index_to_child.size() - 1}; + for (auto index = start_index; index > 0; --index) { + if (_index_to_child[index] != INVALID_INDEX) { + return _children[_index_to_child[index]]->begin(); } } Fail("Empty _index_to_child array in ARTNode48 should never happen"); @@ -342,15 +348,15 @@ ARTNode256::ARTNode256(const std::vector& function) const { - auto partial_key = key[depth]; + const auto partial_key = key[depth]; if (_children[partial_key]) { // case0 return function(partial_key, ++depth); } - for (uint16_t i = partial_key + 1; i < 256u; ++i) { - if (_children[i]) { + for (auto index = partial_key + 1; index < 256; ++index) { + if (_children[index]) { // case2 - return _children[i]->begin(); + return _children[index]->begin(); } } // case1 @@ -381,9 +387,10 @@ AbstractIndex::Iterator ARTNode256::begin() const { } AbstractIndex::Iterator ARTNode256::end() const { - for (int16_t i = static_cast(_children.size()) - 1; i >= 0; --i) { - if (_children[i]) { - return _children[i]->begin(); + const auto child_count = _children.size(); + for (auto index = static_cast(child_count - 1); index >= 0; --index) { + if (_children[index]) { + return _children[index]->begin(); } } Fail("Empty _children array in ARTNode256 should never happen"); @@ -391,11 +398,13 @@ AbstractIndex::Iterator ARTNode256::end() const { Leaf::Leaf(AbstractIndex::Iterator& lower, AbstractIndex::Iterator& upper) : _begin(lower), _end(upper) {} -AbstractIndex::Iterator Leaf::lower_bound(const AdaptiveRadixTreeIndex::BinaryComparable& /*key*/, size_t) const { +AbstractIndex::Iterator Leaf::lower_bound(const AdaptiveRadixTreeIndex::BinaryComparable& /*key*/, + size_t /*depth*/) const { return _begin; } -AbstractIndex::Iterator Leaf::upper_bound(const AdaptiveRadixTreeIndex::BinaryComparable& /*key*/, size_t) const { +AbstractIndex::Iterator Leaf::upper_bound(const AdaptiveRadixTreeIndex::BinaryComparable& /*key*/, + size_t /*depth*/) const { return _end; } diff --git a/src/lib/storage/index/b_tree/b_tree_index_impl.cpp b/src/lib/storage/index/b_tree/b_tree_index_impl.cpp index 80ca482e3b..0ea7f0d046 100644 --- a/src/lib/storage/index/b_tree/b_tree_index_impl.cpp +++ b/src/lib/storage/index/b_tree/b_tree_index_impl.cpp @@ -40,9 +40,9 @@ BaseBTreeIndexImpl::Iterator BTreeIndexImpl::lower_bound(DataType valu auto result = _btree.lower_bound(value); if (result == _btree.end()) { return _chunk_offsets.end(); - } else { - return _chunk_offsets.begin() + result->second; } + + return _chunk_offsets.begin() + result->second; } template @@ -50,9 +50,9 @@ BaseBTreeIndexImpl::Iterator BTreeIndexImpl::upper_bound(DataType valu auto result = _btree.upper_bound(value); if (result == _btree.end()) { return _chunk_offsets.end(); - } else { - return _chunk_offsets.begin() + result->second; } + + return _chunk_offsets.begin() + result->second; } template @@ -83,7 +83,7 @@ void BTreeIndexImpl::_bulk_insert(const std::shared_ptr(row_count) + distinct_count) * sizeof(ChunkOffset) + + static_cast(distinct_count * value_bytes); } CompositeGroupKeyIndex::CompositeGroupKeyIndex( @@ -154,8 +155,8 @@ VariableLengthKey CompositeGroupKeyIndex::_create_composite_key(const std::vecto // fill empty space of key with zeros if less values than segments were provided auto empty_bits = std::accumulate( - _indexed_segments.cbegin() + values.size(), _indexed_segments.cend(), static_cast(0u), - [](auto value, auto segment) { + _indexed_segments.cbegin() + static_cast(values.size()), _indexed_segments.cend(), uint8_t{0}, + [](const auto& value, const auto& segment) { return value + byte_width_for_fixed_width_integer_type(*segment->compressed_vector_type()) * CHAR_BIT; }); result <<= empty_bits; @@ -193,7 +194,7 @@ std::vector> CompositeGroupKeyIndex::_get } size_t CompositeGroupKeyIndex::_memory_consumption() const { - size_t byte_count = _keys.size() * _keys.key_size(); + auto byte_count = static_cast(_keys.size() * _keys.key_size()); byte_count += _key_offsets.size() * sizeof(ChunkOffset); byte_count += _position_list.size() * sizeof(ChunkOffset); return byte_count; diff --git a/src/lib/storage/index/group_key/variable_length_key.cpp b/src/lib/storage/index/group_key/variable_length_key.cpp index 4500b56dbe..04d5b855cd 100644 --- a/src/lib/storage/index/group_key/variable_length_key.cpp +++ b/src/lib/storage/index/group_key/variable_length_key.cpp @@ -76,9 +76,9 @@ CompositeKeyLength VariableLengthKey::bytes_per_key() const { return _impl._size; } -std::ostream& operator<<(std::ostream& os, const VariableLengthKey& key) { - os << key._impl; - return os; +std::ostream& operator<<(std::ostream& stream, const VariableLengthKey& key) { + stream << key._impl; + return stream; } } // namespace hyrise diff --git a/src/lib/storage/index/group_key/variable_length_key.hpp b/src/lib/storage/index/group_key/variable_length_key.hpp index ba0736ba30..5eab404fe0 100644 --- a/src/lib/storage/index/group_key/variable_length_key.hpp +++ b/src/lib/storage/index/group_key/variable_length_key.hpp @@ -50,7 +50,7 @@ class VariableLengthKey { VariableLengthKey& shift_and_set(uint64_t value, uint8_t bits_to_set); - friend std::ostream& operator<<(std::ostream& os, const VariableLengthKey& key); + friend std::ostream& operator<<(std::ostream& stream, const VariableLengthKey& key); private: explicit VariableLengthKey(const VariableLengthKeyBase& other); diff --git a/src/lib/storage/index/group_key/variable_length_key_base.cpp b/src/lib/storage/index/group_key/variable_length_key_base.cpp index 747dabc1b6..b70a0e41e0 100644 --- a/src/lib/storage/index/group_key/variable_length_key_base.cpp +++ b/src/lib/storage/index/group_key/variable_length_key_base.cpp @@ -31,11 +31,11 @@ VariableLengthKeyBase& VariableLengthKeyBase::operator|=(uint64_t other) { static_assert(std::is_same_v, "Changes for new word type required."); const auto* const raw_other = reinterpret_cast(&other); auto operation_width = std::min(static_cast(sizeof(other)), _size); - for (CompositeKeyLength i = 0; i < operation_width; ++i) { + for (auto index = CompositeKeyLength{0}; index < operation_width; ++index) { if constexpr (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) { - _data[i] |= raw_other[i]; + _data[index] |= raw_other[index]; } else { - _data[_size - 1 - i] |= raw_other[8 - 1 - i]; + _data[_size - 1 - index] |= raw_other[8 - 1 - index]; } } return *this; @@ -50,35 +50,35 @@ VariableLengthKeyBase& VariableLengthKeyBase::operator<<=(CompositeKeyLength shi } else { if constexpr (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) { // perform shifting - for (int16_t i = _size - 1; i > static_cast(byte_shift) - 1; --i) { - const auto [value, borrow] = shift_left_with_borrow(_data[i - byte_shift], bit_shift); - _data[i] = value; - if (i + 1 < _size) { - _data[i + 1] |= borrow; + for (auto index = _size - 1; index > byte_shift - 1; --index) { + const auto [value, borrow] = shift_left_with_borrow(_data[index - byte_shift], bit_shift); + _data[index] = value; + if (index + 1 < _size) { + _data[index + 1] |= borrow; } } // fill now "empty" positions with zeros - std::fill(_data, _data + byte_shift, static_cast(0u)); + std::fill(_data, _data + byte_shift, VariableLengthKeyWord{0}); } else { // perform shifting - for (int16_t i = 0; i < _size - static_cast(byte_shift); ++i) { - const auto [value, borrow] = shift_left_with_borrow(_data[i + byte_shift], bit_shift); - _data[i] = value; - if (i > 0) { - _data[i - 1] |= borrow; + for (auto index = int16_t{0}; index < _size - static_cast(byte_shift); ++index) { + const auto [value, borrow] = shift_left_with_borrow(_data[index + byte_shift], bit_shift); + _data[index] = value; + if (index > 0) { + _data[index - 1] |= borrow; } } // fill now "empty" positions with zeros - std::fill(_data + _size - byte_shift, _data + _size, static_cast(0u)); + std::fill(_data + _size - byte_shift, _data + _size, VariableLengthKeyWord{0}); } } return *this; } VariableLengthKeyBase& VariableLengthKeyBase::shift_and_set(uint64_t value, uint8_t bits_to_set) { - uint64_t mask = 0xFFFFFFFFFFFFFFFF; + auto mask = uint64_t{0xFFFFFFFFFFFFFFFF}; // shifting is undefined if right operand is greater than or equal to the number of bits of left operand if (bits_to_set < sizeof(uint64_t) * CHAR_BIT) { mask = ~(mask << bits_to_set); @@ -107,11 +107,11 @@ bool operator<(const VariableLengthKeyBase& left, const VariableLengthKeyBase& r // compare right to left since most significant byte is on the right // memcmp can not be used since it performs lexical comparison // loop overflows after iteration with i == 0, so i becomes greater than left._size - for (CompositeKeyLength i = left._size - 1; i < left._size; --i) { - if (left._data[i] == right._data[i]) { + for (CompositeKeyLength index = left._size - 1; index < left._size; --index) { + if (left._data[index] == right._data[index]) { continue; } - return left._data[i] < right._data[i]; + return left._data[index] < right._data[index]; } } else { return std::memcmp(left._data, right._data, left._size) < 0; @@ -132,25 +132,27 @@ bool operator>=(const VariableLengthKeyBase& left, const VariableLengthKeyBase& return !(left < right); } -std::ostream& operator<<(std::ostream& os, const VariableLengthKeyBase& key) { - os << std::hex << std::setfill('0'); +std::ostream& operator<<(std::ostream& stream, const VariableLengthKeyBase& key) { + stream << std::hex << std::setfill('0'); const auto* const raw_data = reinterpret_cast(key._data); + if constexpr (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) { - for (CompositeKeyLength i = 1; i <= key._size; ++i) { - os << std::setw(2) << +raw_data[key._size - i]; - if (i != key._size) { - os << ' '; + for (auto key_id = CompositeKeyLength{1}; key_id <= key._size; ++key_id) { + stream << std::setw(2) << +raw_data[key._size - key_id]; + if (key_id != key._size) { + stream << ' '; } } } else { - for (CompositeKeyLength i = 0; i < key._size; ++i) { - os << std::setw(2) << +raw_data[i]; - if (i != key._size - 1) { - os << ' '; + for (auto key_id = CompositeKeyLength{0}; key_id < key._size; ++key_id) { + stream << std::setw(2) << +raw_data[key_id]; + if (key_id != key._size - 1) { + stream << ' '; } } } - os << std::dec << std::setw(0) << std::setfill(' '); - return os; + + stream << std::dec << std::setw(0) << std::setfill(' '); + return stream; } } // namespace hyrise diff --git a/src/lib/storage/index/group_key/variable_length_key_base.hpp b/src/lib/storage/index/group_key/variable_length_key_base.hpp index 323af164ce..936db42d4b 100644 --- a/src/lib/storage/index/group_key/variable_length_key_base.hpp +++ b/src/lib/storage/index/group_key/variable_length_key_base.hpp @@ -63,6 +63,6 @@ bool operator>=(const VariableLengthKeyBase& left, const VariableLengthKeyBase& /** * Prints the data as hex number. */ -std::ostream& operator<<(std::ostream& os, const VariableLengthKeyBase& key); +std::ostream& operator<<(std::ostream& stream, const VariableLengthKeyBase& key); } // namespace hyrise diff --git a/src/lib/storage/index/group_key/variable_length_key_proxy.cpp b/src/lib/storage/index/group_key/variable_length_key_proxy.cpp index 41f21ed726..8afeafee75 100644 --- a/src/lib/storage/index/group_key/variable_length_key_proxy.cpp +++ b/src/lib/storage/index/group_key/variable_length_key_proxy.cpp @@ -44,9 +44,9 @@ bool VariableLengthKeyConstProxy::operator<(const VariableLengthKey& other) cons return _impl < other._impl; } -std::ostream& operator<<(std::ostream& os, const VariableLengthKeyConstProxy& key) { - os << key._impl; - return os; +std::ostream& operator<<(std::ostream& ostream, const VariableLengthKeyConstProxy& key) { + ostream << key._impl; + return ostream; } // Mutable VariableLengthKeyProxy diff --git a/src/lib/storage/index/group_key/variable_length_key_proxy.hpp b/src/lib/storage/index/group_key/variable_length_key_proxy.hpp index f09a570722..195cf8bd5c 100644 --- a/src/lib/storage/index/group_key/variable_length_key_proxy.hpp +++ b/src/lib/storage/index/group_key/variable_length_key_proxy.hpp @@ -37,7 +37,7 @@ class VariableLengthKeyConstProxy { bool operator<(const VariableLengthKeyConstProxy& other) const; bool operator<(const VariableLengthKey& other) const; - friend std::ostream& operator<<(std::ostream& os, const VariableLengthKeyConstProxy& key); + friend std::ostream& operator<<(std::ostream& ostream, const VariableLengthKeyConstProxy& key); protected: explicit VariableLengthKeyConstProxy(VariableLengthKeyWord* data, CompositeKeyLength bytes_per_key); diff --git a/src/lib/storage/index/group_key/variable_length_key_store.cpp b/src/lib/storage/index/group_key/variable_length_key_store.cpp index 137a62b9eb..0f5288f2f9 100644 --- a/src/lib/storage/index/group_key/variable_length_key_store.cpp +++ b/src/lib/storage/index/group_key/variable_length_key_store.cpp @@ -7,11 +7,12 @@ namespace hyrise { -VariableLengthKeyStore::VariableLengthKeyStore(ChunkOffset size, CompositeKeyLength bytes_per_key) { +VariableLengthKeyStore::VariableLengthKeyStore(ChunkOffset size, CompositeKeyLength bytes_per_key) + : _bytes_per_key{bytes_per_key} { static const CompositeKeyLength alignment = 8u; - _bytes_per_key = bytes_per_key; _key_alignment = (bytes_per_key / alignment + (bytes_per_key % alignment == 0u ? 0u : 1u)) * alignment; - _data = std::vector(size * _key_alignment); + _data = std::vector( + static_cast::size_type>(size * _key_alignment)); } VariableLengthKeyProxy VariableLengthKeyStore::operator[](ChunkOffset position) { @@ -27,7 +28,7 @@ VariableLengthKeyConstProxy VariableLengthKeyStore::operator[](ChunkOffset posit } void VariableLengthKeyStore::resize(ChunkOffset size) { - _data.resize(size * _key_alignment); + _data.resize(size * static_cast(_key_alignment)); } void VariableLengthKeyStore::shrink_to_fit() { diff --git a/src/lib/storage/lz4_segment.cpp b/src/lib/storage/lz4_segment.cpp index 67135c83a3..7fa821329b 100644 --- a/src/lib/storage/lz4_segment.cpp +++ b/src/lib/storage/lz4_segment.cpp @@ -74,9 +74,9 @@ template std::unique_ptr LZ4Segment::string_offset_decompressor() const { if (_string_offsets) { return _string_offsets->create_base_decompressor(); - } else { - return nullptr; } + + return nullptr; } template @@ -136,10 +136,12 @@ std::vector LZ4Segment::decompress() const { const auto decompressed_size = (_lz4_blocks.size() - 1) * _block_size + _last_block_size; auto decompressed_data = std::vector(decompressed_size); + using DecompressedDataDifferenceType = + typename std::iterator_traits::difference_type; const auto num_blocks = _lz4_blocks.size(); - for (auto block_index = size_t{0u}; block_index < num_blocks; ++block_index) { + for (auto block_index = size_t{0}; block_index < num_blocks; ++block_index) { // This offset is needed to write directly into the decompressed data vector. const auto decompression_offset = block_index * _block_size; _decompress_block_to_bytes(block_index, decompressed_data, decompression_offset); @@ -157,15 +159,17 @@ std::vector LZ4Segment::decompress() const { auto decompressed_strings = std::vector(); for (auto offset_index = size_t{0u}; offset_index < offset_decompressor->size(); ++offset_index) { auto start_char_offset = offset_decompressor->get(offset_index); - size_t end_char_offset; + auto end_char_offset = size_t{0}; if (offset_index + 1 == offset_decompressor->size()) { end_char_offset = decompressed_size; } else { end_char_offset = offset_decompressor->get(offset_index + 1); } - const auto start_offset_it = decompressed_data.cbegin() + start_char_offset; - const auto end_offset_it = decompressed_data.cbegin() + end_char_offset; + const auto start_offset_it = + decompressed_data.cbegin() + static_cast(start_char_offset); + const auto end_offset_it = + decompressed_data.cbegin() + static_cast(end_char_offset); decompressed_strings.emplace_back(start_offset_it, end_offset_it); } @@ -291,12 +295,15 @@ template <> std::pair LZ4Segment::decompress(const ChunkOffset& chunk_offset, const std::optional cached_block_index, std::vector& cached_block) const { + using CachedBlockDifferenceType = + typename std::iterator_traits::iterator>::difference_type; + /** * If the input segment only contained empty strings, the original size is 0. The segment can't be decompressed, and * instead we can just return as many empty strings as the input contained. */ if (_lz4_blocks.empty()) { - return std::pair{pmr_string{""}, 0u}; + return std::pair{pmr_string{""}, size_t{0}}; } /** @@ -306,7 +313,7 @@ std::pair LZ4Segment::decompress(const ChunkOffs */ auto offset_decompressor = _string_offsets->create_base_decompressor(); auto start_offset = offset_decompressor->get(chunk_offset); - size_t end_offset; + auto end_offset = size_t{0}; if (chunk_offset + 1 == offset_decompressor->size()) { end_offset = (_lz4_blocks.size() - 1) * _block_size + _last_block_size; } else { @@ -333,88 +340,89 @@ std::pair LZ4Segment::decompress(const ChunkOffs // Extract the string from the block via the offsets. const auto block_start_offset = start_offset % _block_size; const auto block_end_offset = end_offset % _block_size; - const auto start_offset_it = cached_block.cbegin() + block_start_offset; - const auto end_offset_it = cached_block.cbegin() + block_end_offset; + const auto start_offset_it = cached_block.cbegin() + static_cast(block_start_offset); + const auto end_offset_it = cached_block.cbegin() + static_cast(block_end_offset); return std::pair{pmr_string{start_offset_it, end_offset_it}, start_block}; - } else { - /** - * Multiple blocks need to be decompressed. Iterate over all relevant blocks and append the result to this string - * stream. - */ - std::stringstream result_string; + } - // These are the character offsets that need to be read in every block. - size_t block_start_offset = start_offset % _block_size; - size_t block_end_offset = _block_size; + /** + * Multiple blocks need to be decompressed. Iterate over all relevant blocks and append the result to this string + * stream. + */ + auto result_stringstream = std::stringstream{}; - /** - * This is true if there is a block cached and it is one of the blocks that has to be accessed to decompress the - * current element. - * If it is true there are two cases: - * 1) The first block that has to be accesses is cached. This is trivial and afterwards the data can be overwritten. - * 2) The cached block is not the first but a later block. In that case, the cached block is copied. The original - * buffer is overwritten when decompressing the other blocks. When the cached block needs to be accessed, the copy - * is used. - */ - const auto use_caching = - cached_block_index && *cached_block_index >= start_block && *cached_block_index <= end_offset; + // These are the character offsets that need to be read in every block. + auto block_start_offset = start_offset % _block_size; + auto block_end_offset = _block_size; - /** - * If the cached block is not the first block, keep a copy so that the blocks can still be decompressed into the - * passed char array and the last decompressed block will be cached afterwards. - */ - auto cached_block_copy = std::vector{}; - if (use_caching && *cached_block_index != start_block) { - cached_block_copy = std::vector{cached_block}; + /** + * This is true if there is a block cached and it is one of the blocks that has to be accessed to decompress the + * current element. + * If it is true there are two cases: + * 1) The first block that has to be accesses is cached. This is trivial and afterwards the data can be overwritten. + * 2) The cached block is not the first but a later block. In that case, the cached block is copied. The original + * buffer is overwritten when decompressing the other blocks. When the cached block needs to be accessed, the copy + * is used. + */ + const auto use_caching = + cached_block_index && *cached_block_index >= start_block && *cached_block_index <= end_offset; + + /** + * If the cached block is not the first block, keep a copy so that the blocks can still be decompressed into the + * passed char array and the last decompressed block will be cached afterwards. + */ + auto cached_block_copy = std::vector{}; + if (use_caching && *cached_block_index != start_block) { + cached_block_copy = std::vector{cached_block}; + } + + /** + * Store the index of the last decompressed block. The blocks are decompressed into the cache buffer. If the cached + * block is the last block the string, it is copied and used. As a result, the cache contains the last decompressed + * block (i.e., the block before the cached block). + * In that case, this index equals end_block - 1. Otherwise, it will equal end_block. + */ + auto new_cached_block_index = size_t{0}; + + for (auto block_index = start_block; block_index <= end_block; ++block_index) { + // Only decompress the current block if it's not cached. + if (!(use_caching && block_index == *cached_block_index)) { + _decompress_block_to_bytes(block_index, cached_block); + new_cached_block_index = block_index; + } + + // Set the offset for the end of the string. + if (block_index == end_block) { + block_end_offset = end_offset % _block_size; } /** - * Store the index of the last decompressed block. The blocks are decompressed into the cache buffer. If the cached - * block is the last block the string, it is copied and used. As a result, the cache contains the last decompressed - * block (i.e., the block before the cached block). - * In that case, this index equals end_block - 1. Otherwise, it will equal end_block. + * Extract the string from the current block via the offsets and append it to the result string stream. + * If the cached block is not the start block, the data is retrieved from the copy. */ - auto new_cached_block_index = size_t{0u}; - - for (size_t block_index = start_block; block_index <= end_block; ++block_index) { - // Only decompress the current block if it's not cached. - if (!(use_caching && block_index == *cached_block_index)) { - _decompress_block_to_bytes(block_index, cached_block); - new_cached_block_index = block_index; - } - - // Set the offset for the end of the string. - if (block_index == end_block) { - block_end_offset = end_offset % _block_size; - } - - /** - * Extract the string from the current block via the offsets and append it to the result string stream. - * If the cached block is not the start block, the data is retrieved from the copy. - */ - pmr_string partial_result; - if (use_caching && block_index == *cached_block_index && block_index != start_block) { - const auto start_offset_it = cached_block_copy.cbegin() + block_start_offset; - const auto end_offset_it = cached_block_copy.cbegin() + block_end_offset; - partial_result = pmr_string{start_offset_it, end_offset_it}; - } else { - const auto start_offset_it = cached_block.cbegin() + block_start_offset; - const auto end_offset_it = cached_block.cbegin() + block_end_offset; - partial_result = pmr_string{start_offset_it, end_offset_it}; - } - result_string << partial_result; - - // After the first iteration, this is set to 0 since only the first block's start offset can't be equal to zero. - block_start_offset = 0u; + auto partial_result = pmr_string{}; + if (use_caching && block_index == *cached_block_index && block_index != start_block) { + const auto start_offset_it = + cached_block_copy.cbegin() + static_cast(block_start_offset); + const auto end_offset_it = cached_block_copy.cbegin() + static_cast(block_end_offset); + partial_result = pmr_string{start_offset_it, end_offset_it}; + } else { + const auto start_offset_it = cached_block.cbegin() + static_cast(block_start_offset); + const auto end_offset_it = cached_block.cbegin() + static_cast(block_end_offset); + partial_result = pmr_string{start_offset_it, end_offset_it}; } - return std::pair{pmr_string{result_string.str()}, new_cached_block_index}; + result_stringstream << partial_result; + + // After the first iteration, this is set to 0 since only the first block's start offset can't be equal to zero. + block_start_offset = 0; } + return std::pair{pmr_string{result_stringstream.str()}, new_cached_block_index}; } template T LZ4Segment::decompress(const ChunkOffset& chunk_offset) const { - auto decompressed_block = std::vector(_block_size); + auto decompressed_block = std::vector(_block_size, char{}); return decompress(chunk_offset, std::nullopt, decompressed_block).first; } diff --git a/src/lib/storage/lz4_segment.hpp b/src/lib/storage/lz4_segment.hpp index 1436a07637..9dcfe5dfe8 100644 --- a/src/lib/storage/lz4_segment.hpp +++ b/src/lib/storage/lz4_segment.hpp @@ -219,7 +219,8 @@ class LZ4Segment : public AbstractEncodedSegment { template <> std::vector LZ4Segment::decompress() const; template <> -std::pair LZ4Segment::decompress(const ChunkOffset&, const std::optional, +std::pair LZ4Segment::decompress(const ChunkOffset&, + const std::optional cached_block_index, std::vector&) const; template <> std::optional LZ4Segment::compressed_vector_type() const; diff --git a/src/lib/storage/pos_lists/abstract_pos_list.cpp b/src/lib/storage/pos_lists/abstract_pos_list.cpp index 490afbdca3..8e8579be05 100644 --- a/src/lib/storage/pos_lists/abstract_pos_list.cpp +++ b/src/lib/storage/pos_lists/abstract_pos_list.cpp @@ -3,11 +3,11 @@ namespace hyrise { AbstractPosList::PosListIterator<> AbstractPosList::begin() const { PerformanceWarning("Unresolved iterator created for AbstractPosList"); - return PosListIterator<>(this, ChunkOffset{0}); + return {this, ChunkOffset{0}}; } AbstractPosList::PosListIterator<> AbstractPosList::end() const { - return PosListIterator<>(this, static_cast(size())); + return {this, static_cast(size())}; } AbstractPosList::PosListIterator<> AbstractPosList::cbegin() const { diff --git a/src/lib/storage/pos_lists/entire_chunk_pos_list.cpp b/src/lib/storage/pos_lists/entire_chunk_pos_list.cpp index fe4b487b8a..8b57bf7e29 100644 --- a/src/lib/storage/pos_lists/entire_chunk_pos_list.cpp +++ b/src/lib/storage/pos_lists/entire_chunk_pos_list.cpp @@ -23,11 +23,11 @@ size_t EntireChunkPosList::memory_usage(const MemoryUsageCalculationMode /*mode* } AbstractPosList::PosListIterator EntireChunkPosList::begin() const { - return PosListIterator(this, ChunkOffset{0}); + return {this, ChunkOffset{0}}; } AbstractPosList::PosListIterator EntireChunkPosList::end() const { - return PosListIterator(this, static_cast(size())); + return {this, static_cast(size())}; } AbstractPosList::PosListIterator EntireChunkPosList::cbegin() const { diff --git a/src/lib/storage/pos_lists/row_id_pos_list.hpp b/src/lib/storage/pos_lists/row_id_pos_list.hpp index 66dd9da638..a4530ad42d 100644 --- a/src/lib/storage/pos_lists/row_id_pos_list.hpp +++ b/src/lib/storage/pos_lists/row_id_pos_list.hpp @@ -34,22 +34,31 @@ class RowIDPosList final : public AbstractPosList, private pmr_vector { using const_reverse_iterator = Vector::const_reverse_iterator; /* (1 ) */ RowIDPosList() noexcept(noexcept(allocator_type())) {} + /* (1 ) */ explicit RowIDPosList(const allocator_type& allocator) noexcept : Vector(allocator) {} + /* (2 ) */ RowIDPosList(size_type count, const RowID& value, const allocator_type& alloc = allocator_type()) : Vector(count, value, alloc) {} + /* (3 ) */ explicit RowIDPosList(size_type count, const allocator_type& alloc = allocator_type()) : Vector(count, alloc) {} + /* (4 ) */ template RowIDPosList(InputIt first, InputIt last, const allocator_type& alloc = allocator_type()) : Vector(std::move(first), std::move(last)) {} + /* (5 ) */ // RowIDPosList(const Vector& other) : Vector(other); - Oh no, you don't. /* (5 ) */ // RowIDPosList(const Vector& other, const allocator_type& alloc) : Vector(other, alloc); /* (6 ) */ RowIDPosList(RowIDPosList&& other) noexcept : Vector(std::move(other)), _references_single_chunk{other._references_single_chunk} {} + /* (6+) */ explicit RowIDPosList(Vector&& other) noexcept : Vector(std::move(other)) {} + /* (7 ) */ RowIDPosList(RowIDPosList&& other, const allocator_type& alloc) : Vector(std::move(other), alloc), _references_single_chunk{other._references_single_chunk} {} + /* (7+) */ RowIDPosList(Vector&& other, const allocator_type& alloc) : Vector(std::move(other), alloc) {} + /* (8 ) */ RowIDPosList(std::initializer_list init, const allocator_type& alloc = allocator_type()) : Vector(std::move(init), alloc) {} @@ -96,9 +105,11 @@ class RowIDPosList final : public AbstractPosList, private pmr_vector { using Vector::max_size; using Vector::reserve; using Vector::shrink_to_fit; + size_t size() const final { return Vector::size(); } + bool empty() const final { return Vector::empty(); } diff --git a/src/lib/storage/prepared_plan.cpp b/src/lib/storage/prepared_plan.cpp index cbfb0fcc2c..d5bc7c4bd4 100644 --- a/src/lib/storage/prepared_plan.cpp +++ b/src/lib/storage/prepared_plan.cpp @@ -27,7 +27,9 @@ void expression_bind_placeholders_impl( sub_expression = parameter_iter->second; return ExpressionVisitation::DoNotVisitArguments; - } else if (const auto subquery_expression = std::dynamic_pointer_cast(sub_expression)) { + } + + if (const auto subquery_expression = std::dynamic_pointer_cast(sub_expression)) { lqp_bind_placeholders_impl(subquery_expression->lqp, parameters, visited_nodes); } diff --git a/src/lib/storage/reference_segment/reference_segment_iterable.hpp b/src/lib/storage/reference_segment/reference_segment_iterable.hpp index 4e48c5c67e..c8b859322c 100644 --- a/src/lib/storage/reference_segment/reference_segment_iterable.hpp +++ b/src/lib/storage/reference_segment/reference_segment_iterable.hpp @@ -202,9 +202,8 @@ class ReferenceSegmentIterable : public SegmentIterable{std::move(*typed_value), false, pos_list_offset}; - } else { - return SegmentPosition{T{}, true, pos_list_offset}; } + return SegmentPosition{T{}, true, pos_list_offset}; } void _create_accessor(const ChunkID chunk_id) const { diff --git a/src/lib/storage/resolve_encoded_segment_type.hpp b/src/lib/storage/resolve_encoded_segment_type.hpp index eef490d6c9..9a6ea93bd8 100644 --- a/src/lib/storage/resolve_encoded_segment_type.hpp +++ b/src/lib/storage/resolve_encoded_segment_type.hpp @@ -35,6 +35,7 @@ constexpr auto encoded_segment_for_type = hana::make_map( template_c), hana::make_pair(enum_c, template_c), hana::make_pair(enum_c, template_c)); + // When adding something here, please also append all_segment_encoding_specs in the BaseTest class. /** diff --git a/src/lib/storage/run_length_segment/run_length_segment_iterable.hpp b/src/lib/storage/run_length_segment/run_length_segment_iterable.hpp index 1bd589e06c..49399dd0ec 100644 --- a/src/lib/storage/run_length_segment/run_length_segment_iterable.hpp +++ b/src/lib/storage/run_length_segment/run_length_segment_iterable.hpp @@ -86,6 +86,7 @@ class RunLengthSegmentIterable : public PointAccessibleSegmentIterable::const_iterator; + static EndPositionIterator search_end_positions_for_chunk_offset( const std::shared_ptr>& end_positions, const ChunkOffset old_chunk_offset, const ChunkOffset new_chunk_offset, const size_t previous_end_position_index, diff --git a/src/lib/storage/segment_access_counter.cpp b/src/lib/storage/segment_access_counter.cpp index 172229ea0c..bf5ae3467a 100644 --- a/src/lib/storage/segment_access_counter.cpp +++ b/src/lib/storage/segment_access_counter.cpp @@ -22,7 +22,8 @@ SegmentAccessCounter& SegmentAccessCounter::operator=(const SegmentAccessCounter } void SegmentAccessCounter::_set_counters(const SegmentAccessCounter& counter) { - for (auto counter_index = 0ul, size = _counters.size(); counter_index < size; ++counter_index) { + const auto counter_count = _counters.size(); + for (auto counter_index = size_t{0}; counter_index < counter_count; ++counter_index) { _counters[counter_index] = counter._counters[counter_index].load(); } } @@ -38,7 +39,7 @@ const SegmentAccessCounter::CounterType& SegmentAccessCounter::operator[](const std::string SegmentAccessCounter::to_string() const { std::string result = std::to_string(_counters[0]); result.reserve(static_cast(AccessType::Count) * 19); - for (auto access_type = 1u; access_type < static_cast(AccessType::Count); ++access_type) { + for (auto access_type = size_t{1}; access_type < static_cast(AccessType::Count); ++access_type) { result.append(","); result.append(std::to_string(_counters[access_type])); } @@ -86,12 +87,12 @@ SegmentAccessCounter::AccessPattern SegmentAccessCounter::_access_pattern(const }}; // clang-format on - const auto max_items_to_compare = std::min(positions.size(), 100ul); + const auto max_items_to_compare = std::min(positions.size(), size_t{100}); auto access_pattern = AccessPattern::Point; - for (auto i = 1ul; i < max_items_to_compare; ++i) { - const int64_t diff = - static_cast(positions[i].chunk_offset) - static_cast(positions[i - 1].chunk_offset); + for (auto item_index = size_t{1}; item_index < max_items_to_compare; ++item_index) { + const int64_t diff = static_cast(positions[item_index].chunk_offset) - + static_cast(positions[item_index - 1].chunk_offset); auto input = Input{}; if (diff == 0) { @@ -118,7 +119,8 @@ SegmentAccessCounter::AccessPattern SegmentAccessCounter::_access_pattern(const } bool SegmentAccessCounter::operator==(const SegmentAccessCounter& other) const { - for (auto counter_index = 0ul, size = _counters.size(); counter_index < size; ++counter_index) { + const auto counter_count = _counters.size(); + for (auto counter_index = size_t{0}; counter_index < counter_count; ++counter_index) { if (_counters[counter_index] != other._counters[counter_index]) { return false; } diff --git a/src/lib/storage/segment_accessor.cpp b/src/lib/storage/segment_accessor.cpp index c77a09df5b..024878aa79 100644 --- a/src/lib/storage/segment_accessor.cpp +++ b/src/lib/storage/segment_accessor.cpp @@ -45,5 +45,6 @@ std::unique_ptr> CreateSegmentAccessor::create( }); return accessor; } + EXPLICITLY_INSTANTIATE_DATA_TYPES(CreateSegmentAccessor); } // namespace hyrise::detail diff --git a/src/lib/storage/segment_encoding_utils.cpp b/src/lib/storage/segment_encoding_utils.cpp index b2796c2f74..59c7525d72 100644 --- a/src/lib/storage/segment_encoding_utils.cpp +++ b/src/lib/storage/segment_encoding_utils.cpp @@ -32,10 +32,10 @@ const auto encoder_for_type = std::map create_encoder(EncodingType encoding_type) { Assert(encoding_type != EncodingType::Unencoded, "Encoding type must not be Unencoded`."); - auto it = encoder_for_type.find(encoding_type); - Assert(it != encoder_for_type.cend(), "All encoding types must be in encoder_for_type."); + auto iter = encoder_for_type.find(encoding_type); + Assert(iter != encoder_for_type.cend(), "All encoding types must be in encoder_for_type."); - const auto& encoder = it->second; + const auto& encoder = iter->second; return encoder->create_new(); } diff --git a/src/lib/storage/segment_iterables/any_segment_iterator.hpp b/src/lib/storage/segment_iterables/any_segment_iterator.hpp index 73e6ed2dea..e3e32f5a42 100644 --- a/src/lib/storage/segment_iterables/any_segment_iterator.hpp +++ b/src/lib/storage/segment_iterables/any_segment_iterator.hpp @@ -121,10 +121,12 @@ class AnySegmentIterator : public AbstractSegmentIterator, template explicit AnySegmentIterator(const Iterator& iterator) : _wrapper{std::make_unique>(iterator)} {} + /**@}*/ public: AnySegmentIterator(const AnySegmentIterator& other) : _wrapper{other._wrapper->clone()} {} + AnySegmentIterator& operator=(const AnySegmentIterator& other) { if (this == &other) { return *this; diff --git a/src/lib/storage/table.cpp b/src/lib/storage/table.cpp index 3dde32e820..22a9b9f3f5 100644 --- a/src/lib/storage/table.cpp +++ b/src/lib/storage/table.cpp @@ -202,9 +202,9 @@ std::shared_ptr Table::get_chunk(ChunkID chunk_id) { if (_type == TableType::References) { // Not written concurrently, since reference tables are not modified anymore once they are written. return _chunks[chunk_id]; - } else { - return std::atomic_load(&_chunks[chunk_id]); } + + return std::atomic_load(&_chunks[chunk_id]); } std::shared_ptr Table::get_chunk(ChunkID chunk_id) const { @@ -212,9 +212,9 @@ std::shared_ptr Table::get_chunk(ChunkID chunk_id) const { if (_type == TableType::References) { // see comment in non-const function return _chunks[chunk_id]; - } else { - return std::atomic_load(&_chunks[chunk_id]); } + + return std::atomic_load(&_chunks[chunk_id]); } std::shared_ptr Table::last_chunk() const { @@ -222,9 +222,9 @@ std::shared_ptr Table::last_chunk() const { if (_type == TableType::References) { // Not written concurrently, since reference tables are not modified anymore once they are written. return _chunks.back(); - } else { - return std::atomic_load(&_chunks.back()); } + + return std::atomic_load(&_chunks.back()); } void Table::remove_chunk(ChunkID chunk_id) { @@ -285,14 +285,14 @@ std::vector Table::get_row(size_t row_idx) const { if (row_idx < chunk->size()) { auto row = std::vector(column_count()); - for (ColumnID column_id{0}; column_id < column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < column_count(); ++column_id) { row[column_id] = chunk->get_segment(column_id)->operator[](static_cast(row_idx)); } return row; - } else { - row_idx -= chunk->size(); } + + row_idx -= chunk->size(); } Fail("row_idx out of bounds"); diff --git a/src/lib/storage/vector_compression/base_compressed_vector.hpp b/src/lib/storage/vector_compression/base_compressed_vector.hpp index 1230825897..df846949d8 100644 --- a/src/lib/storage/vector_compression/base_compressed_vector.hpp +++ b/src/lib/storage/vector_compression/base_compressed_vector.hpp @@ -100,6 +100,7 @@ class CompressedVector : public BaseCompressedVector { auto cend() const { return end(); } + /**@}*/ public: diff --git a/src/lib/storage/vector_compression/bitpacking/bitpacking_decompressor.hpp b/src/lib/storage/vector_compression/bitpacking/bitpacking_decompressor.hpp index 8b73bba832..45093430a3 100644 --- a/src/lib/storage/vector_compression/bitpacking/bitpacking_decompressor.hpp +++ b/src/lib/storage/vector_compression/bitpacking/bitpacking_decompressor.hpp @@ -11,6 +11,7 @@ class BitPackingVector; class BitPackingDecompressor : public BaseVectorDecompressor { public: explicit BitPackingDecompressor(const pmr_compact_vector& data) : _data{data} {} + BitPackingDecompressor(const BitPackingDecompressor& other) = default; BitPackingDecompressor(BitPackingDecompressor&& other) = default; @@ -18,6 +19,7 @@ class BitPackingDecompressor : public BaseVectorDecompressor { DebugAssert(&_data == &other._data, "Cannot reassign BitPackingDecompressor"); return *this; } + BitPackingDecompressor& operator=(BitPackingDecompressor&& other) { DebugAssert(&_data == &other._data, "Cannot reassign BitPackingDecompressor"); return *this; diff --git a/src/lib/storage/vector_compression/bitpacking/bitpacking_vector.cpp b/src/lib/storage/vector_compression/bitpacking/bitpacking_vector.cpp index 77fca8484a..6daeaf0a25 100644 --- a/src/lib/storage/vector_compression/bitpacking/bitpacking_vector.cpp +++ b/src/lib/storage/vector_compression/bitpacking/bitpacking_vector.cpp @@ -14,6 +14,7 @@ const pmr_compact_vector& BitPackingVector::data() const { size_t BitPackingVector::on_size() const { return _data.size(); } + size_t BitPackingVector::on_data_size() const { return _data.bytes(); } diff --git a/src/lib/storage/vector_compression/fixed_width_integer/fixed_width_integer_compressor.cpp b/src/lib/storage/vector_compression/fixed_width_integer/fixed_width_integer_compressor.cpp index 92cc4d10ca..896433708e 100644 --- a/src/lib/storage/vector_compression/fixed_width_integer/fixed_width_integer_compressor.cpp +++ b/src/lib/storage/vector_compression/fixed_width_integer/fixed_width_integer_compressor.cpp @@ -14,19 +14,21 @@ std::unique_ptr FixedWidthIntegerCompressor::create_new() } uint32_t FixedWidthIntegerCompressor::_find_max_value(const pmr_vector& vector) { - const auto it = std::max_element(vector.cbegin(), vector.cend()); - return *it; + const auto iter = std::max_element(vector.cbegin(), vector.cend()); + return *iter; } std::unique_ptr FixedWidthIntegerCompressor::_compress_using_max_value( const PolymorphicAllocator& alloc, const pmr_vector& vector, const uint32_t max_value) { if (max_value <= std::numeric_limits::max()) { return _compress_using_uint_type(alloc, vector); - } else if (max_value <= std::numeric_limits::max()) { + } + + if (max_value <= std::numeric_limits::max()) { return _compress_using_uint_type(alloc, vector); - } else { - return _compress_using_uint_type(alloc, vector); } + + return _compress_using_uint_type(alloc, vector); } template diff --git a/src/lib/storage/vector_compression/fixed_width_integer/fixed_width_integer_decompressor.hpp b/src/lib/storage/vector_compression/fixed_width_integer/fixed_width_integer_decompressor.hpp index 6b94b36fee..aa3bbd5ca7 100644 --- a/src/lib/storage/vector_compression/fixed_width_integer/fixed_width_integer_decompressor.hpp +++ b/src/lib/storage/vector_compression/fixed_width_integer/fixed_width_integer_decompressor.hpp @@ -10,6 +10,7 @@ template class FixedWidthIntegerDecompressor : public BaseVectorDecompressor { public: explicit FixedWidthIntegerDecompressor(const pmr_vector& data) : _data{data} {} + FixedWidthIntegerDecompressor(const FixedWidthIntegerDecompressor&) = default; FixedWidthIntegerDecompressor(FixedWidthIntegerDecompressor&&) = default; @@ -17,6 +18,7 @@ class FixedWidthIntegerDecompressor : public BaseVectorDecompressor { DebugAssert(&_data == &other._data, "Cannot reassign FixedWidthIntegerDecompressor"); return *this; } + FixedWidthIntegerDecompressor& operator=(FixedWidthIntegerDecompressor&& other) { DebugAssert(&_data == &other._data, "Cannot reassign FixedWidthIntegerDecompressor"); return *this; diff --git a/src/lib/storage/vector_compression/vector_compression.cpp b/src/lib/storage/vector_compression/vector_compression.cpp index 7a445635f5..74ae6c830f 100644 --- a/src/lib/storage/vector_compression/vector_compression.cpp +++ b/src/lib/storage/vector_compression/vector_compression.cpp @@ -22,11 +22,11 @@ const auto vector_compressor_for_type = std::map()}}; std::unique_ptr create_compressor_by_type(VectorCompressionType type) { - auto it = vector_compressor_for_type.find(type); - Assert(it != vector_compressor_for_type.cend(), + auto iter = vector_compressor_for_type.find(type); + Assert(iter != vector_compressor_for_type.cend(), "All vector compression types must be in vector_compressor_for_type."); - const auto& compressor = it->second; + const auto& compressor = iter->second; return compressor->create_new(); } diff --git a/src/lib/strong_typedef.hpp b/src/lib/strong_typedef.hpp index 94ff07e37e..53009eeb34 100644 --- a/src/lib/strong_typedef.hpp +++ b/src/lib/strong_typedef.hpp @@ -51,7 +51,7 @@ \ namespace std { \ template <> \ - struct hash<::hyrise::D> : public unary_function<::hyrise::D, size_t> { \ + struct hash<::hyrise::D> { \ size_t operator()(const ::hyrise::D& x) const { \ return hash{}(x); \ } \ diff --git a/src/lib/types.cpp b/src/lib/types.cpp index f120db6133..b60414ee89 100644 --- a/src/lib/types.cpp +++ b/src/lib/types.cpp @@ -120,13 +120,17 @@ PredicateCondition conditions_to_between(const PredicateCondition lower, const P if (lower == PredicateCondition::GreaterThan) { if (upper == PredicateCondition::LessThan) { return PredicateCondition::BetweenExclusive; - } else if (upper == PredicateCondition::LessThanEquals) { + } + + if (upper == PredicateCondition::LessThanEquals) { return PredicateCondition::BetweenLowerExclusive; } } else if (lower == PredicateCondition::GreaterThanEquals) { if (upper == PredicateCondition::LessThan) { return PredicateCondition::BetweenUpperExclusive; - } else if (upper == PredicateCondition::LessThanEquals) { + } + + if (upper == PredicateCondition::LessThanEquals) { return PredicateCondition::BetweenInclusive; } } diff --git a/src/lib/types.hpp b/src/lib/types.hpp index f9f2207396..2e5595c4a2 100644 --- a/src/lib/types.hpp +++ b/src/lib/types.hpp @@ -10,23 +10,18 @@ #include #include -#include -#if BOOST_VERSION < 107400 // TODO(anyone): remove this block once Ubuntu ships boost 1.74 -#include "utils/boost_bimap_core_override.hpp" // NOLINT -#endif - #include #include #include #include +#include #include "strong_typedef.hpp" #include "utils/assert.hpp" /** - * We use STRONG_TYPEDEF to avoid things like adding chunk ids and value ids. - * Because implicit constructors are deleted, you cannot initialize a ChunkID - * like this + * We use STRONG_TYPEDEF to avoid things like adding chunk ids and value ids. Because implicit constructors are + * deleted, you cannot initialize a ChunkID like this: * ChunkID x = 3; * but need to use * auto x = ChunkID{3}; @@ -126,9 +121,9 @@ struct RowID { return std::tie(chunk_id, chunk_offset) == std::tie(other.chunk_id, other.chunk_offset); } - friend std::ostream& operator<<(std::ostream& o, const RowID& row_id) { - o << "RowID(" << row_id.chunk_id << "," << row_id.chunk_offset << ")"; - return o; + friend std::ostream& operator<<(std::ostream& stream, const RowID& row_id) { + stream << "RowID(" << row_id.chunk_id << "," << row_id.chunk_offset << ")"; + return stream; } }; @@ -153,7 +148,7 @@ constexpr NodeID CURRENT_NODE_ID{std::numeric_limits::max() - // Declaring one part of a RowID as invalid would suffice to represent NULL values. However, this way we add an extra // safety net which ensures that NULL values are handled correctly. E.g., getting a chunk with INVALID_CHUNK_ID // immediately crashes. -const RowID NULL_ROW_ID = RowID{INVALID_CHUNK_ID, INVALID_CHUNK_OFFSET}; // TODO(anyone): Couldn’t use constexpr here +constexpr RowID NULL_ROW_ID = RowID{INVALID_CHUNK_ID, INVALID_CHUNK_OFFSET}; constexpr ValueID INVALID_VALUE_ID{std::numeric_limits::max()}; diff --git a/src/lib/utils/abstract_plugin.cpp b/src/lib/utils/abstract_plugin.cpp index b7a8adb792..eff82018af 100644 --- a/src/lib/utils/abstract_plugin.cpp +++ b/src/lib/utils/abstract_plugin.cpp @@ -5,8 +5,7 @@ namespace hyrise { // We have to instantiate this function here because clang-12(+) does not instantiate it and llvm-cov throws a warning // (functions have mismatched data). See // https://stackoverflow.com/questions/57331600/llvm-cov-statistics-for-uninstantiated-functions -std::vector> AbstractPlugin::provided_user_executable_functions() - const { +std::vector> AbstractPlugin::provided_user_executable_functions() { return {}; } diff --git a/src/lib/utils/abstract_plugin.hpp b/src/lib/utils/abstract_plugin.hpp index 01804c0064..e7d854f0aa 100644 --- a/src/lib/utils/abstract_plugin.hpp +++ b/src/lib/utils/abstract_plugin.hpp @@ -36,7 +36,7 @@ class AbstractPlugin { // exec_user_function method. If you are writing a plugin and provide user-exectuable functions it // is YOUR responsibility to keep these function calls as short and efficient as possible, e.g., // by spinning up a thread inside the plugin to execute the actual functionality. - virtual std::vector> provided_user_executable_functions() const; + virtual std::vector> provided_user_executable_functions(); }; } // namespace hyrise diff --git a/src/lib/utils/assert.hpp b/src/lib/utils/assert.hpp index bb88886240..385ec02a63 100644 --- a/src/lib/utils/assert.hpp +++ b/src/lib/utils/assert.hpp @@ -12,10 +12,9 @@ /** * This file provides better assertions than the std cassert/assert.h - DebugAssert(condition, msg) and Fail(msg) can be - * used - * to both harden code by programming by contract and document the invariants enforced in messages. + * used to both harden code by programming by contract and document the invariants enforced in messages. * - * --> Use DebugAssert() whenever a certain invariant must hold, as in + * --> Use DebugAssert() whenever a certain invariant must hold, as in: * * int divide(int numerator, int denominator) { * DebugAssert(denominator == 0, "Divisions by zero are not allowed"); @@ -34,7 +33,7 @@ * } * * --> Use Assert() whenever an invariant should be checked even in release builds, either because testing it is - * very cheap or the invariant is considered very important + * very cheap or the invariant is considered very important. * * --> Use AssertInput() to check if the user input is correct. This provides a more specific error handling since an * invalid input might want to be caught. @@ -51,7 +50,7 @@ namespace detail { } } // namespace detail -#define Fail(msg) \ +#define Fail(msg) \ hyrise::detail::fail(hyrise::trim_source_file_path(__FILE__) + ":" BOOST_PP_STRINGIZE(__LINE__) " " + msg); \ static_assert(true, "End call of macro with a semicolon") diff --git a/src/lib/utils/check_table_equal.cpp b/src/lib/utils/check_table_equal.cpp index d3c0ec40d0..e2ee7f8271 100644 --- a/src/lib/utils/check_table_equal.cpp +++ b/src/lib/utils/check_table_equal.cpp @@ -47,7 +47,7 @@ std::string matrix_to_string(const Matrix& matrix, const std::vector(matrix[row_id][column_id]); coloring = ""; if (highlight && it->second == column_id) { @@ -92,9 +92,9 @@ bool almost_equals(T left_val, T right_val, FloatComparisonMode float_comparison static_assert(std::is_floating_point_v, "Values must be of floating point type."); if (float_comparison_mode == FloatComparisonMode::AbsoluteDifference) { return std::fabs(left_val - right_val) < EPSILON; - } else { - return std::fabs(left_val - right_val) < std::max(EPSILON, std::fabs(right_val * EPSILON)); } + + return std::fabs(left_val - right_val) < std::max(EPSILON, std::fabs(right_val * EPSILON)); } } // namespace @@ -204,7 +204,7 @@ std::optional check_table_equal(const std::shared_ptr& } bool all_null = true; - for (auto row_id = size_t{HEADER_SIZE}; row_id < expected_matrix.size(); row_id++) { + for (auto row_id = size_t{HEADER_SIZE}; row_id < expected_matrix.size(); ++row_id) { if (!variant_is_null(expected_matrix[row_id][column_id])) { all_null = false; break; @@ -275,8 +275,8 @@ std::optional check_table_equal(const std::shared_ptr& }; // Compare each cell, skipping header - for (auto row_id = size_t{HEADER_SIZE}; row_id < actual_matrix.size(); row_id++) { - for (auto column_id = ColumnID{0}; column_id < actual_matrix[row_id].size(); column_id++) { + for (auto row_id = size_t{HEADER_SIZE}; row_id < actual_matrix.size(); ++row_id) { + for (auto column_id = ColumnID{0}; column_id < actual_matrix[row_id].size(); ++column_id) { if (variant_is_null(actual_matrix[row_id][column_id]) || variant_is_null(expected_matrix[row_id][column_id])) { highlight_if( !(variant_is_null(actual_matrix[row_id][column_id]) && variant_is_null(expected_matrix[row_id][column_id])), diff --git a/src/lib/utils/date_time_utils.cpp b/src/lib/utils/date_time_utils.cpp index dc7f46b3be..1d4165125f 100644 --- a/src/lib/utils/date_time_utils.cpp +++ b/src/lib/utils/date_time_utils.cpp @@ -32,13 +32,13 @@ boost::gregorian::date date_interval(const boost::gregorian::date& start_date, i case DatetimeComponent::Year: { // We obtain an iterator that adds offset years when incremented. Thus, we have to actually increment and // dereference it. The same applies to the other cases. - return *(++boost::gregorian::year_iterator(start_date, offset)); + return *(++boost::gregorian::year_iterator{start_date, static_cast(offset)}); } case DatetimeComponent::Month: { - return *(++boost::gregorian::month_iterator(start_date, offset)); + return *(++boost::gregorian::month_iterator{start_date, static_cast(offset)}); } case DatetimeComponent::Day: { - return *(++boost::gregorian::day_iterator(start_date, offset)); + return *(++boost::gregorian::day_iterator{start_date, static_cast(offset)}); } default: Fail("Invalid time unit for date interval: " + std::string{magic_enum::enum_name(unit)}); diff --git a/src/lib/utils/format_duration.cpp b/src/lib/utils/format_duration.cpp index f413c59cff..bc7208242b 100644 --- a/src/lib/utils/format_duration.cpp +++ b/src/lib/utils/format_duration.cpp @@ -15,9 +15,9 @@ std::string format_duration(const std::chrono::nanoseconds& total_nanoseconds) { std::chrono::microseconds, std::chrono::nanoseconds>); const std::vector unit_strings = {" min", " s", " ms", " µs", " ns"}; - std::chrono::nanoseconds remaining_nanoseconds = total_nanoseconds; - std::vector floor_durations; - std::vector round_durations; + auto remaining_nanoseconds = total_nanoseconds; + auto floor_durations = std::vector{}; + auto round_durations = std::vector{}; boost::hana::for_each(TIME_UNIT_ORDER, [&](const auto duration_t) { using DurationType = typename decltype(duration_t)::type; auto floored_duration = std::chrono::floor(total_nanoseconds); @@ -26,8 +26,9 @@ std::string format_duration(const std::chrono::nanoseconds& total_nanoseconds) { remaining_nanoseconds -= floored_duration; }); - std::stringstream stream; - for (size_t unit_iterator{0}; unit_iterator < unit_strings.size(); ++unit_iterator) { + auto stream = std::stringstream{}; + const auto unit_string_count = unit_strings.size(); + for (auto unit_iterator = size_t{0}; unit_iterator < unit_string_count; ++unit_iterator) { const auto& floored_duration = floor_durations.at(unit_iterator); const auto is_last_element = unit_iterator == unit_strings.size() - 1; if (floored_duration > 0 || is_last_element) { diff --git a/src/lib/utils/lossless_predicate_cast.cpp b/src/lib/utils/lossless_predicate_cast.cpp index 05ec46766b..974146745a 100644 --- a/src/lib/utils/lossless_predicate_cast.cpp +++ b/src/lib/utils/lossless_predicate_cast.cpp @@ -16,11 +16,7 @@ std::optional next_float_towards(const double value, const double towards const auto casted_value = static_cast(value); - if (casted_value < value && towards < value) { - return casted_value; - } - - if (casted_value > value && towards > value) { + if ((casted_value < value && towards < value) || (casted_value > value && towards > value)) { return casted_value; } diff --git a/src/lib/utils/meta_table_manager.cpp b/src/lib/utils/meta_table_manager.cpp index 2d24a28027..d594eecaa7 100644 --- a/src/lib/utils/meta_table_manager.cpp +++ b/src/lib/utils/meta_table_manager.cpp @@ -39,7 +39,7 @@ MetaTableManager::MetaTableManager() { bool MetaTableManager::is_meta_table_name(const std::string& name) { const auto prefix_len = META_PREFIX.size(); - return name.size() > prefix_len && std::string_view{&name[0], prefix_len} == MetaTableManager::META_PREFIX; + return name.size() > prefix_len && std::string_view{name.data(), prefix_len} == MetaTableManager::META_PREFIX; } const std::vector& MetaTableManager::table_names() const { @@ -53,7 +53,7 @@ void MetaTableManager::add_table(const std::shared_ptr& table } bool MetaTableManager::has_table(const std::string& table_name) const { - return _meta_tables.count(_trim_table_name(table_name)); + return _meta_tables.contains(_trim_table_name(table_name)); } std::shared_ptr MetaTableManager::get_table(const std::string& table_name) const { @@ -98,7 +98,8 @@ void MetaTableManager::update(const std::string& table_name, const std::shared_p const auto& update_rows = update_values->get_rows(); Assert(selected_rows.size() == update_rows.size(), "Selected and updated values need to have the same size."); - for (size_t row = 0; row < selected_rows.size(); row++) { + const auto row_count = selected_rows.size(); + for (auto row = size_t{0}; row < row_count; ++row) { _meta_tables.at(table_name)->_update(selected_rows[row], update_rows[row]); } } diff --git a/src/lib/utils/meta_tables/meta_log_table.cpp b/src/lib/utils/meta_tables/meta_log_table.cpp index 0aa3ad6137..644ffbccd5 100644 --- a/src/lib/utils/meta_tables/meta_log_table.cpp +++ b/src/lib/utils/meta_tables/meta_log_table.cpp @@ -30,7 +30,9 @@ std::shared_ptr
MetaLogTable::_on_generate() const { // why-is-there-no-c11-threadsafe-alternative-to-stdlocaltime-and-stdgmtime std::ostringstream timestamp; auto time = std::chrono::system_clock::to_time_t(entry.timestamp); + struct tm buffer {}; + timestamp << std::put_time(localtime_r(&time, &buffer), "%F %T"); output_table->append( {timestamp_ns, pmr_string{timestamp.str()}, pmr_string{log_level_to_string.left.at(entry.log_level)}, diff --git a/src/lib/utils/meta_tables/meta_system_information_table.cpp b/src/lib/utils/meta_tables/meta_system_information_table.cpp index 025b4438f3..43706ed48b 100644 --- a/src/lib/utils/meta_tables/meta_system_information_table.cpp +++ b/src/lib/utils/meta_tables/meta_system_information_table.cpp @@ -74,6 +74,7 @@ size_t MetaSystemInformationTable::_cpu_count() { size_t MetaSystemInformationTable::_ram_size() { #ifdef __linux__ struct sysinfo memory_info {}; + const auto ret = sysinfo(&memory_info); Assert(ret == 0, "Failed to get sysinfo"); @@ -120,7 +121,7 @@ std::string MetaSystemInformationTable::_cpu_model() { const auto ret = sysctlbyname("machdep.cpu.brand_string", &buffer, &buffer_size, nullptr, 0); Assert(ret == 0, "Failed to call sysctl machdep.cpu.brand_string"); - return std::string(&buffer[0]); + return std::string{buffer.data()}; #endif Fail("Method not implemented for this platform"); diff --git a/src/lib/utils/meta_tables/meta_system_utilization_table.cpp b/src/lib/utils/meta_tables/meta_system_utilization_table.cpp index 90f696b166..431b1b2ae8 100644 --- a/src/lib/utils/meta_tables/meta_system_utilization_table.cpp +++ b/src/lib/utils/meta_tables/meta_system_utilization_table.cpp @@ -140,6 +140,7 @@ uint64_t MetaSystemUtilizationTable::_get_process_cpu_time() { // A clock that measures (user and system) CPU time consumed by (all of the threads in) the calling process. #ifdef __linux__ struct timespec time_spec {}; + const auto ret = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time_spec); Assert(ret == 0, "Failed in clock_gettime"); @@ -245,6 +246,7 @@ MetaSystemUtilizationTable::ProcessMemoryUsage MetaSystemUtilizationTable::_get_ #ifdef __APPLE__ struct task_basic_info info {}; + mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT; const auto ret = task_info(mach_task_self(), TASK_BASIC_INFO, reinterpret_cast(&info), &count); Assert(ret == KERN_SUCCESS, "Failed to get task_info"); diff --git a/src/lib/utils/meta_tables/segment_meta_data.cpp b/src/lib/utils/meta_tables/segment_meta_data.cpp index ddadad17b9..3619763061 100644 --- a/src/lib/utils/meta_tables/segment_meta_data.cpp +++ b/src/lib/utils/meta_tables/segment_meta_data.cpp @@ -11,28 +11,30 @@ namespace hyrise { void gather_segment_meta_data(const std::shared_ptr
& meta_table, const MemoryUsageCalculationMode mode) { for (const auto& [table_name, table] : Hyrise::get().storage_manager.tables()) { - for (auto chunk_id = ChunkID{0}; chunk_id < table->chunk_count(); ++chunk_id) { + const auto chunk_count = table->chunk_count(); + for (auto chunk_id = ChunkID{0}; chunk_id < chunk_count; ++chunk_id) { const auto& chunk = table->get_chunk(chunk_id); // Skip physically deleted chunks if (!chunk) { continue; } - for (auto column_id = ColumnID{0}; column_id < table->column_count(); ++column_id) { + const auto column_count = table->column_count(); + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { const auto& segment = chunk->get_segment(column_id); const auto data_type = pmr_string{data_type_to_string.left.at(table->column_data_type(column_id))}; const auto estimated_size = segment->memory_usage(mode); - AllTypeVariant encoding = NULL_VALUE; - AllTypeVariant vector_compression = NULL_VALUE; + auto encoding = NULL_VALUE; + auto vector_compression = NULL_VALUE; if (const auto& encoded_segment = std::dynamic_pointer_cast(segment)) { encoding = pmr_string{encoding_type_to_string.left.at(encoded_segment->encoding_type())}; if (encoded_segment->compressed_vector_type()) { - std::stringstream ss; - ss << *encoded_segment->compressed_vector_type(); - vector_compression = pmr_string{ss.str()}; + std::stringstream sstream; + sstream << *encoded_segment->compressed_vector_type(); + vector_compression = pmr_string{sstream.str()}; } } @@ -72,15 +74,17 @@ size_t get_distinct_value_count(const std::shared_ptr& segment) if (const auto dictionary_segment = std::dynamic_pointer_cast>(segment)) { distinct_value_count = dictionary_segment->dictionary()->size(); return; - } else if (const auto fs_dictionary_segment = - std::dynamic_pointer_cast>(segment)) { + } + + if (const auto fs_dictionary_segment = + std::dynamic_pointer_cast>(segment)) { distinct_value_count = fs_dictionary_segment->fixed_string_dictionary()->size(); return; } - std::unordered_set distinct_values; + auto distinct_values = std::unordered_set{}; auto iterable = create_any_segment_iterable(*segment); - iterable.with_iterators([&](auto it, auto end) { + iterable.with_iterators([&](auto it, const auto end) { for (; it != end; ++it) { const auto segment_item = *it; if (!segment_item.is_null()) { diff --git a/src/lib/utils/pausable_loop_thread.cpp b/src/lib/utils/pausable_loop_thread.cpp index 5e104a1d7c..e177fe90f6 100644 --- a/src/lib/utils/pausable_loop_thread.cpp +++ b/src/lib/utils/pausable_loop_thread.cpp @@ -14,21 +14,24 @@ PausableLoopThread::PausableLoopThread(std::chrono::milliseconds loop_sleep_time _loop_thread = std::thread([&, loop_func] { size_t counter = 0; while (!_shutdown_flag) { - std::unique_lock lk(_mutex); + auto lock = std::unique_lock{_mutex}; if (_loop_sleep_time > std::chrono::milliseconds(0)) { - _cv.wait_for(lk, _loop_sleep_time, [&] { return static_cast(_shutdown_flag); }); + _cv.wait_for(lock, _loop_sleep_time, [&] { return static_cast(_shutdown_flag); }); } + if (_shutdown_flag) { return; } + while (_pause_requested) { _is_paused = true; - _cv.wait(lk, [&] { return !_pause_requested || _shutdown_flag; }); + _cv.wait(lock, [&] { return !_pause_requested || _shutdown_flag; }); if (_shutdown_flag) { return; } - lk.unlock(); + lock.unlock(); } + _is_paused = false; loop_func(counter++); } diff --git a/src/lib/utils/performance_warning.hpp b/src/lib/utils/performance_warning.hpp index 843f069585..3972aa9a59 100644 --- a/src/lib/utils/performance_warning.hpp +++ b/src/lib/utils/performance_warning.hpp @@ -59,6 +59,7 @@ class PerformanceWarningDisabler { public: PerformanceWarningDisabler() : _previously_disabled(PerformanceWarningClass::disable()) {} + ~PerformanceWarningDisabler() { if (!_previously_disabled) { PerformanceWarningClass::enable(); diff --git a/src/lib/utils/plugin_manager.cpp b/src/lib/utils/plugin_manager.cpp index e9ce639f3b..7480259117 100644 --- a/src/lib/utils/plugin_manager.cpp +++ b/src/lib/utils/plugin_manager.cpp @@ -46,7 +46,12 @@ void PluginManager::load_plugin(const std::filesystem::path& path) { Assert(!_plugins.contains(plugin_name), "Loading plugin failed: A plugin with name " + plugin_name + " already exists."); + // Lock for dl* functions (see clang-tidy's "concurrency-mt-unsafe") + static auto dl_mutex = std::mutex{}; + auto lock = std::lock_guard{dl_mutex}; + PluginHandle plugin_handle = dlopen(path.c_str(), static_cast(RTLD_NOW) | static_cast(RTLD_LOCAL)); + // NOLINTNEXTLINE(concurrency-mt-unsafe) - dlerror is not thread-safe, but it's guarded by dl_mutex. Assert(plugin_handle, std::string{"Loading plugin failed: "} + dlerror()); // abstract_plugin.hpp defines a macro for exporting plugins which makes them instantiable by providing a diff --git a/src/lib/utils/settings_manager.cpp b/src/lib/utils/settings_manager.cpp index 75a163827a..16d76f7be1 100644 --- a/src/lib/utils/settings_manager.cpp +++ b/src/lib/utils/settings_manager.cpp @@ -3,21 +3,21 @@ namespace hyrise { bool SettingsManager::has_setting(const std::string& name) const { - return _settings.count(name); + return _settings.contains(name); } void SettingsManager::_add(std::shared_ptr setting) { - Assert(!_settings.count(setting->name), "A setting with that name already exists."); + Assert(!_settings.contains(setting->name), "A setting with that name already exists."); _settings[setting->name] = std::move(setting); } void SettingsManager::_remove(const std::string& name) { - Assert(_settings.count(name), "A setting with that name does not exist."); + Assert(_settings.contains(name), "A setting with that name does not exist."); _settings.erase(name); } std::shared_ptr SettingsManager::get_setting(const std::string& name) const { - Assert(_settings.count(name), "A setting with that name does not exist."); + Assert(_settings.contains(name), "A setting with that name does not exist."); return _settings.at(name); } diff --git a/src/lib/utils/singleton.hpp b/src/lib/utils/singleton.hpp index 389efac52d..efbacf38cc 100644 --- a/src/lib/utils/singleton.hpp +++ b/src/lib/utils/singleton.hpp @@ -23,6 +23,7 @@ class Singleton : public Noncopyable { // If you need to overwrite the constructor make sure to friend this Singleton class. Otherwise it cannot call // the protected constructor of a derived class. Singleton() {} + Singleton& operator=(Singleton&&) = default; }; diff --git a/src/lib/utils/sqlite_wrapper.cpp b/src/lib/utils/sqlite_wrapper.cpp index a284b62f7e..9bb1fadc8c 100644 --- a/src/lib/utils/sqlite_wrapper.cpp +++ b/src/lib/utils/sqlite_wrapper.cpp @@ -19,6 +19,7 @@ namespace { using namespace hyrise; // NOLINT + /* * Creates columns in given Hyrise table according to an sqlite intermediate statement (one result row). */ @@ -27,10 +28,10 @@ std::shared_ptr
create_hyrise_table_from_result(sqlite3_stmt* sqlite_stat std::vector column_types(column_count, ""); std::vector column_names(column_count, ""); - bool no_result = true; - int rc; - while ((rc = sqlite3_step(sqlite_statement)) == SQLITE_ROW) { - for (int column_id = 0; column_id < column_count; ++column_id) { + auto no_result = true; + auto return_code = int{}; + while ((return_code = sqlite3_step(sqlite_statement)) == SQLITE_ROW) { + for (auto column_id = int{0}; column_id < column_count; ++column_id) { if (no_result) { column_names[column_id] = sqlite3_column_name(sqlite_statement, column_id); } @@ -71,11 +72,11 @@ std::shared_ptr
create_hyrise_table_from_result(sqlite3_stmt* sqlite_stat // If this fails, this is likely because of a transaction conflict within sqlite. This means that the Hyrise // and the sqlite states have diverged. When using the SQLite wrapper, the caller must ensure that parallel // operations do not conflict. - Assert(rc == SQLITE_ROW || rc == SQLITE_DONE, "Unexpected sqlite state"); + Assert(return_code == SQLITE_ROW || return_code == SQLITE_DONE, "Unexpected sqlite state"); if (!no_result) { - TableColumnDefinitions column_definitions; - for (int column_id = 0; column_id < column_count; ++column_id) { + auto column_definitions = TableColumnDefinitions{}; + for (auto column_id = int{0}; column_id < column_count; ++column_id) { if (column_types[column_id].empty()) { // Hyrise does not have explicit NULL columns column_types[column_id] = "int"; @@ -96,9 +97,9 @@ std::shared_ptr
create_hyrise_table_from_result(sqlite3_stmt* sqlite_stat */ void copy_row_from_sqlite_to_hyrise(const std::shared_ptr
& table, sqlite3_stmt* sqlite_statement, int column_count) { - std::vector row; + auto row = std::vector{}; - for (int column_id = 0; column_id < column_count; ++column_id) { + for (auto column_id = int{0}; column_id < column_count; ++column_id) { switch (sqlite3_column_type(sqlite_statement, column_id)) { case SQLITE_INTEGER: { row.emplace_back(AllTypeVariant{sqlite3_column_int(sqlite_statement, column_id)}); @@ -184,11 +185,11 @@ std::shared_ptr
SQLiteWrapper::Connection::execute_query(const std::strin std::vector queries_before_select(queries.begin(), queries.end() - 1); std::string select_query = queries.back(); - int rc; + auto return_code = int{}; for (const auto& query : queries_before_select) { - rc = sqlite3_prepare_v2(db, query.c_str(), -1, &sqlite_statement, nullptr); + return_code = sqlite3_prepare_v2(db, query.c_str(), -1, &sqlite_statement, nullptr); - if (rc != SQLITE_OK) { + if (return_code != SQLITE_OK) { sqlite3_finalize(sqlite_statement); Fail("Failed to execute query \"" + query + "\": " + std::string(sqlite3_errmsg(db)) + "\n"); } @@ -196,9 +197,9 @@ std::shared_ptr
SQLiteWrapper::Connection::execute_query(const std::strin while (sqlite3_step(sqlite_statement) != SQLITE_DONE) {} } - rc = sqlite3_prepare_v2(db, select_query.c_str(), -1, &sqlite_statement, nullptr); + return_code = sqlite3_prepare_v2(db, select_query.c_str(), -1, &sqlite_statement, nullptr); - if (rc != SQLITE_OK) { + if (return_code != SQLITE_OK) { auto error_message = "Failed to execute query \"" + select_query + "\": " + std::string(sqlite3_errmsg(db)); sqlite3_finalize(sqlite_statement); Fail(error_message); @@ -216,11 +217,11 @@ std::shared_ptr
SQLiteWrapper::Connection::execute_query(const std::strin sqlite3_reset(sqlite_statement); - while ((rc = sqlite3_step(sqlite_statement)) == SQLITE_ROW) { + while ((return_code = sqlite3_step(sqlite_statement)) == SQLITE_ROW) { copy_row_from_sqlite_to_hyrise(result_table, sqlite_statement, sqlite3_column_count(sqlite_statement)); } - Assert(rc == SQLITE_DONE, "Unexpected sqlite state"); + Assert(return_code == SQLITE_DONE, "Unexpected sqlite state"); sqlite3_finalize(sqlite_statement); return result_table; @@ -228,9 +229,9 @@ std::shared_ptr
SQLiteWrapper::Connection::execute_query(const std::strin void SQLiteWrapper::Connection::raw_execute_query(const std::string& sql, const bool allow_failure) const { char* err_msg; - auto rc = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &err_msg); + auto return_code = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &err_msg); - if (rc != SQLITE_OK) { + if (return_code != SQLITE_OK) { auto msg = std::string(err_msg); sqlite3_free(err_msg); Fail("Failed to execute query (" + sql + "). SQL error: " + msg + "\n"); @@ -238,7 +239,7 @@ void SQLiteWrapper::Connection::raw_execute_query(const std::string& sql, const } void SQLiteWrapper::create_sqlite_table(const Table& table, const std::string& table_name) const { - std::vector column_types; + auto column_types = std::vector{}; for (const auto& column_definition : table.column_definitions()) { switch (column_definition.data_type) { @@ -262,12 +263,13 @@ void SQLiteWrapper::create_sqlite_table(const Table& table, const std::string& t // SQLite doesn't like an unescaped "ORDER" as a table name, thus we escape all table names. const auto escaped_table_name = std::string{"\""} + table_name + "\""; - std::stringstream create_table_query; + auto create_table_query = std::stringstream{}; create_table_query << "CREATE TABLE " << escaped_table_name << "("; - for (auto column_id = ColumnID{0}; column_id < table.column_definitions().size(); column_id++) { + const auto column_count = table.column_definitions().size(); + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { create_table_query << table.column_definitions()[column_id].name << " " << column_types[column_id]; - if (column_id + 1u < table.column_definitions().size()) { + if (column_id + 1u < column_count) { create_table_query << ", "; } } @@ -275,11 +277,11 @@ void SQLiteWrapper::create_sqlite_table(const Table& table, const std::string& t main_connection.raw_execute_query(create_table_query.str()); // Prepare `INSERT INTO VALUES (?, ?, ...)` statement - std::stringstream insert_into_stream; + auto insert_into_stream = std::stringstream{}; insert_into_stream << "INSERT INTO " << escaped_table_name << " VALUES ("; - for (auto column_id = ColumnID{0}; column_id < table.column_count(); column_id++) { + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { insert_into_stream << "?"; - if (static_cast(column_id + 1u) < table.column_count()) { + if (static_cast(column_id + 1u) < column_count) { insert_into_stream << ", "; } } @@ -301,8 +303,9 @@ void SQLiteWrapper::create_sqlite_table(const Table& table, const std::string& t continue; } - for (auto chunk_offset = ChunkOffset{0}; chunk_offset < chunk->size(); ++chunk_offset) { - for (auto column_id = ColumnID{0}; column_id < table.column_count(); column_id++) { + const auto chunk_size = chunk->size(); + for (auto chunk_offset = ChunkOffset{0}; chunk_offset < chunk_size; ++chunk_offset) { + for (auto column_id = ColumnID{0}; column_id < column_count; ++column_id) { const auto segment = chunk->get_segment(column_id); // SQLite's parameter indices are 1-based. const auto sqlite_column_id = static_cast(column_id) + 1; @@ -362,11 +365,11 @@ void SQLiteWrapper::create_sqlite_table(const Table& table, const std::string& t void SQLiteWrapper::reset_table_from_copy(const std::string& table_name_to_reset, const std::string& table_name_to_copy_from) const { - std::stringstream command_ss; - command_ss << "DROP TABLE IF EXISTS " << table_name_to_reset << ";"; - command_ss << "CREATE TABLE " << table_name_to_reset << " AS SELECT * FROM " << table_name_to_copy_from << ";"; + auto command_sstream = std::stringstream{}; + command_sstream << "DROP TABLE IF EXISTS " << table_name_to_reset << ";"; + command_sstream << "CREATE TABLE " << table_name_to_reset << " AS SELECT * FROM " << table_name_to_copy_from << ";"; - main_connection.raw_execute_query(command_ss.str()); + main_connection.raw_execute_query(command_sstream.str()); } } // namespace hyrise diff --git a/src/lib/utils/string_utils.cpp b/src/lib/utils/string_utils.cpp index 213c005ae4..ae118151e6 100644 --- a/src/lib/utils/string_utils.cpp +++ b/src/lib/utils/string_utils.cpp @@ -8,22 +8,22 @@ namespace hyrise { std::vector trim_and_split(const std::string& input) { - std::string converted = input; + auto converted = input; boost::algorithm::trim_all(converted); - std::vector arguments; + auto arguments = std::vector{}; boost::algorithm::split(arguments, converted, boost::is_space()); return arguments; } -std::vector split_string_by_delimiter(const std::string& str, char delimiter) { - std::vector internal; - std::stringstream ss(str); - std::string tok; +std::vector split_string_by_delimiter(const std::string& str, const char delimiter) { + auto internal = std::vector{}; + auto sstream = std::stringstream(str); + auto token = std::string{}; - while (std::getline(ss, tok, delimiter)) { - internal.push_back(tok); + while (std::getline(sstream, token, delimiter)) { + internal.push_back(token); } return internal; diff --git a/src/lib/utils/timer.cpp b/src/lib/utils/timer.cpp index 48c23494c5..384686835b 100644 --- a/src/lib/utils/timer.cpp +++ b/src/lib/utils/timer.cpp @@ -10,7 +10,7 @@ Timer::Timer() { std::chrono::nanoseconds Timer::lap() { const auto now = std::chrono::steady_clock::now(); - const auto lap_duration = std::chrono::nanoseconds(now - _begin); + const auto lap_duration = std::chrono::nanoseconds{now - _begin}; _begin = now; return lap_duration; } diff --git a/src/lib/visualization/join_graph_visualizer.cpp b/src/lib/visualization/join_graph_visualizer.cpp index e20467dc4b..da1155784a 100644 --- a/src/lib/visualization/join_graph_visualizer.cpp +++ b/src/lib/visualization/join_graph_visualizer.cpp @@ -10,7 +10,8 @@ namespace hyrise { void JoinGraphVisualizer::_build_graph(const std::vector& graphs) { for (const auto& graph : graphs) { - for (auto vertex_idx = size_t{0}; vertex_idx < graph.vertices.size(); ++vertex_idx) { + const auto vertex_count = graph.vertices.size(); + for (auto vertex_idx = size_t{0}; vertex_idx < vertex_count; ++vertex_idx) { const auto& vertex = graph.vertices[vertex_idx]; const auto predicates = graph.find_local_predicates(vertex_idx); @@ -68,7 +69,8 @@ void JoinGraphVisualizer::_build_graph(const std::vector& graphs) { // Render a diamond vertex that contains all the Predicates and connect all hyperedge vertices to that vertex. std::stringstream vertex_label_stream; - for (size_t predicate_idx{0}; predicate_idx < edge.predicates.size(); ++predicate_idx) { + const auto edge_predicate_count = edge.predicates.size(); + for (size_t predicate_idx{0}; predicate_idx < edge_predicate_count; ++predicate_idx) { const auto& predicate = edge.predicates[predicate_idx]; vertex_label_stream << predicate->as_column_name(); if (predicate_idx + 1 < edge.predicates.size()) { @@ -117,7 +119,8 @@ std::string JoinGraphVisualizer::_create_vertex_description(const std::shared_pt stream << "Tables: "; } - for (auto node_idx = size_t{0}; node_idx < stored_table_nodes.size(); ++node_idx) { + const auto stored_table_node_count = stored_table_nodes.size(); + for (auto node_idx = size_t{0}; node_idx < stored_table_node_count; ++node_idx) { stream << stored_table_nodes[node_idx]->table_name; if (node_idx + 1u < stored_table_nodes.size()) { stream << ", "; diff --git a/src/lib/visualization/lqp_visualizer.cpp b/src/lib/visualization/lqp_visualizer.cpp index b99daeac24..ca80a53b20 100644 --- a/src/lib/visualization/lqp_visualizer.cpp +++ b/src/lib/visualization/lqp_visualizer.cpp @@ -89,29 +89,29 @@ void LQPVisualizer::_build_subtree(const std::shared_ptr& node, } } -void LQPVisualizer::_build_dataflow(const std::shared_ptr& from, - const std::shared_ptr& to, const InputSide side) { +void LQPVisualizer::_build_dataflow(const std::shared_ptr& source_node, + const std::shared_ptr& target_node, const InputSide side) { float row_count = NAN; double pen_width = 1.0; auto row_percentage = 100.0f; try { - row_count = _cardinality_estimator.estimate_cardinality(from); + row_count = _cardinality_estimator.estimate_cardinality(source_node); pen_width = row_count; } catch (...) { // statistics don't exist for this edge } - if (from->left_input()) { + if (source_node->left_input()) { try { - float input_count = _cardinality_estimator.estimate_cardinality(from->left_input()); + float input_count = _cardinality_estimator.estimate_cardinality(source_node->left_input()); // Include right side in cardinality estimation unless it is a semi/anti join - const auto join_node = std::dynamic_pointer_cast(from); - if (from->right_input() && + const auto join_node = std::dynamic_pointer_cast(source_node); + if (source_node->right_input() && (!join_node || (join_node->join_mode != JoinMode::Semi && join_node->join_mode != JoinMode::AntiNullAsTrue && join_node->join_mode != JoinMode::AntiNullAsFalse))) { - input_count *= _cardinality_estimator.estimate_cardinality(from->right_input()); + input_count *= _cardinality_estimator.estimate_cardinality(source_node->right_input()); } row_percentage = 100 * row_count / input_count; } catch (...) { @@ -119,7 +119,7 @@ void LQPVisualizer::_build_dataflow(const std::shared_ptr& from } } - std::ostringstream label_stream; + auto label_stream = std::ostringstream{}; // Use a copy of the stream's default locale with thousands separators: Dynamically allocated raw pointers should // be avoided whenever possible. Unfortunately, std::locale stores pointers to the facets and does internal @@ -135,56 +135,63 @@ void LQPVisualizer::_build_dataflow(const std::shared_ptr& from label_stream << "no est."; } - std::stringstream tooltip_stream; + auto tooltip_stream = std::stringstream{}; // Edge Tooltip: Node Output Expressions tooltip_stream << "Output Expressions: \n"; - const auto& output_expressions = from->output_expressions(); - for (auto column_id = ColumnID{0}; column_id < output_expressions.size(); ++column_id) { + const auto& output_expressions = source_node->output_expressions(); + const auto output_expression_count = output_expressions.size(); + for (auto column_id = ColumnID{0}; column_id < output_expression_count; ++column_id) { tooltip_stream << " (" << column_id + 1 << ") "; tooltip_stream << output_expressions.at(column_id)->as_column_name(); - if (from->is_column_nullable(column_id)) { + if (source_node->is_column_nullable(column_id)) { tooltip_stream << " NULL"; } tooltip_stream << "\n"; } - if (!dynamic_pointer_cast(from)) { + if (!dynamic_pointer_cast(source_node)) { // Edge Tooltip: Unique Constraints - const auto& unique_constraints = from->unique_constraints(); + const auto& unique_constraints = source_node->unique_constraints(); tooltip_stream << "\n" << "Unique Constraints: \n"; if (unique_constraints->empty()) { tooltip_stream << " \n"; } - for (auto uc_idx = size_t{0}; uc_idx < unique_constraints->size(); ++uc_idx) { - tooltip_stream << " (" << uc_idx + 1 << ") "; - tooltip_stream << unique_constraints->at(uc_idx) << "\n"; + + const auto unique_constraint_count = unique_constraints->size(); + for (auto constraint_index = size_t{0}; constraint_index < unique_constraint_count; ++constraint_index) { + tooltip_stream << " (" << constraint_index + 1 << ") "; + tooltip_stream << unique_constraints->at(constraint_index) << "\n"; } // Edge Tooltip: Trivial FDs auto trivial_fds = std::vector(); if (!unique_constraints->empty()) { - trivial_fds = fds_from_unique_constraints(from, unique_constraints); + trivial_fds = fds_from_unique_constraints(source_node, unique_constraints); } tooltip_stream << "\n" << "Functional Dependencies (trivial): \n"; if (trivial_fds.empty()) { tooltip_stream << " \n"; } - for (auto fd_idx = size_t{0}; fd_idx < trivial_fds.size(); ++fd_idx) { + + const auto trivial_fd_count = trivial_fds.size(); + for (auto fd_idx = size_t{0}; fd_idx < trivial_fd_count; ++fd_idx) { tooltip_stream << " (" << fd_idx + 1 << ") "; tooltip_stream << trivial_fds.at(fd_idx) << "\n"; } // Edge Tooltip: Non-trivial FDs - const auto& fds = from->non_trivial_functional_dependencies(); + const auto& fds = source_node->non_trivial_functional_dependencies(); tooltip_stream << "\n" << "Functional Dependencies (non-trivial): \n"; if (fds.empty()) { tooltip_stream << " "; } - for (auto fd_idx = size_t{0}; fd_idx < fds.size(); ++fd_idx) { + + const auto fd_count = fds.size(); + for (auto fd_idx = size_t{0}; fd_idx < fd_count; ++fd_idx) { tooltip_stream << " (" << fd_idx + 1 << ") "; tooltip_stream << fds.at(fd_idx) << "\n"; } @@ -194,11 +201,11 @@ void LQPVisualizer::_build_dataflow(const std::shared_ptr& from info.label = label_stream.str(); info.label_tooltip = tooltip_stream.str(); info.pen_width = pen_width; - if (to->input_count() == 2) { + if (target_node->input_count() == 2) { info.arrowhead = side == InputSide::Left ? "lnormal" : "rnormal"; } - _add_edge(from, to, info); + _add_edge(source_node, target_node, info); } } // namespace hyrise diff --git a/src/lib/visualization/lqp_visualizer.hpp b/src/lib/visualization/lqp_visualizer.hpp index 6723150320..0ca9e90240 100644 --- a/src/lib/visualization/lqp_visualizer.hpp +++ b/src/lib/visualization/lqp_visualizer.hpp @@ -29,8 +29,8 @@ class LQPVisualizer : public AbstractVisualizer>& visualized_nodes, ExpressionUnorderedSet& visualized_sub_queries); - void _build_dataflow(const std::shared_ptr& from, const std::shared_ptr& to, - const InputSide side); + void _build_dataflow(const std::shared_ptr& source_node, + const std::shared_ptr& target_node, const InputSide side); CardinalityEstimator _cardinality_estimator; }; diff --git a/src/lib/visualization/pqp_visualizer.cpp b/src/lib/visualization/pqp_visualizer.cpp index b47cbd4b36..bc8cb4c05c 100644 --- a/src/lib/visualization/pqp_visualizer.cpp +++ b/src/lib/visualization/pqp_visualizer.cpp @@ -140,12 +140,12 @@ void PQPVisualizer::_visualize_subqueries(const std::shared_ptr& from, - const std::shared_ptr& to, const InputSide side) { +void PQPVisualizer::_build_dataflow(const std::shared_ptr& source_node, + const std::shared_ptr& target_node, const InputSide side) { VizEdgeInfo info = _default_edge; - const auto& performance_data = *from->performance_data; - if (from->executed() && performance_data.has_output) { + const auto& performance_data = *source_node->performance_data; + if (source_node->executed() && performance_data.has_output) { std::stringstream stream; // Use a copy of the stream's default locale with thousands separators: Dynamically allocated raw pointers should @@ -161,11 +161,11 @@ void PQPVisualizer::_build_dataflow(const std::shared_ptr(performance_data.output_row_count); - if (to->right_input() != nullptr) { + if (target_node->right_input() != nullptr) { info.arrowhead = side == InputSide::Left ? "lnormal" : "rnormal"; } - _add_edge(from, to, info); + _add_edge(source_node, target_node, info); } void PQPVisualizer::_add_operator(const std::shared_ptr& op) { diff --git a/src/lib/visualization/pqp_visualizer.hpp b/src/lib/visualization/pqp_visualizer.hpp index 14e2711346..132d983379 100644 --- a/src/lib/visualization/pqp_visualizer.hpp +++ b/src/lib/visualization/pqp_visualizer.hpp @@ -28,8 +28,8 @@ class PQPVisualizer : public AbstractVisualizer& expression, std::unordered_set>& visualized_ops); - void _build_dataflow(const std::shared_ptr& from, - const std::shared_ptr& to, const InputSide side); + void _build_dataflow(const std::shared_ptr& source_node, + const std::shared_ptr& target_node, const InputSide side); void _add_operator(const std::shared_ptr& op); diff --git a/src/lib/visualization/viz_record_layout.cpp b/src/lib/visualization/viz_record_layout.cpp index dede26d7b7..64354ac9e5 100644 --- a/src/lib/visualization/viz_record_layout.cpp +++ b/src/lib/visualization/viz_record_layout.cpp @@ -19,7 +19,8 @@ std::string VizRecordLayout::to_label_string() const { std::stringstream stream; stream << "{"; - for (size_t element_idx{0}; element_idx < content.size(); ++element_idx) { + const auto content_size = content.size(); + for (auto element_idx = size_t{0}; element_idx < content_size; ++element_idx) { const auto& element = content[element_idx]; if (element.type() == typeid(std::string)) { @@ -39,8 +40,8 @@ std::string VizRecordLayout::to_label_string() const { std::string VizRecordLayout::escape(const std::string& input) { std::ostringstream stream; - for (const auto& c : input) { - switch (c) { + for (const auto& character : input) { + switch (character) { case '<': case '>': case '{': @@ -53,7 +54,7 @@ std::string VizRecordLayout::escape(const std::string& input) { default: { } } - stream << c; + stream << character; } return stream.str(); diff --git a/src/plugins/mvcc_delete_plugin.cpp b/src/plugins/mvcc_delete_plugin.cpp index 77637eac79..6582a3037e 100644 --- a/src/plugins/mvcc_delete_plugin.cpp +++ b/src/plugins/mvcc_delete_plugin.cpp @@ -37,12 +37,12 @@ void MvccDeletePlugin::_logical_delete_loop() { const auto tables = Hyrise::get().storage_manager.tables(); // Check all tables - for (auto& [table_name, table] : tables) { + for (const auto& [table_name, table] : tables) { if (table->empty() || table->uses_mvcc() != UseMvcc::Yes) { continue; } - size_t saved_memory = 0; - size_t num_chunks = 0; + auto saved_memory = size_t{0}; + auto num_chunks = size_t{0}; // Check all chunks, except for the last one, which is currently used for insertions const auto max_chunk_id = static_cast(table->chunk_count() - 1); @@ -52,8 +52,8 @@ void MvccDeletePlugin::_logical_delete_loop() { const auto chunk_memory = chunk->memory_usage(MemoryUsageCalculationMode::Sampled); // Calculate metric 1 – Chunk invalidation level - const double invalidated_rows_ratio = static_cast(chunk->invalid_row_count()) / chunk->size(); - const bool criterion1 = (DELETE_THRESHOLD_PERCENTAGE_INVALIDATED_ROWS <= invalidated_rows_ratio); + const auto invalidated_rows_ratio = static_cast(chunk->invalid_row_count()) / chunk->size(); + const auto criterion1 = (DELETE_THRESHOLD_PERCENTAGE_INVALIDATED_ROWS <= invalidated_rows_ratio); if (!criterion1) { continue; @@ -69,7 +69,7 @@ void MvccDeletePlugin::_logical_delete_loop() { } } - const bool criterion2 = + const auto criterion2 = highest_end_commit_id + DELETE_THRESHOLD_LAST_COMMIT <= Hyrise::get().transaction_manager.last_commit_id(); if (!criterion2) { @@ -77,7 +77,7 @@ void MvccDeletePlugin::_logical_delete_loop() { } auto transaction_context = Hyrise::get().transaction_manager.new_transaction_context(AutoCommit::No); - const bool success = _try_logical_delete(table_name, chunk_id, transaction_context); + const auto success = _try_logical_delete(table_name, chunk_id, transaction_context); if (success) { DebugAssert(table->get_chunk(chunk_id)->get_cleanup_commit_id(), @@ -115,7 +115,7 @@ void MvccDeletePlugin::_physical_delete_loop() { if (chunk->get_cleanup_commit_id().has_value()) { // Check whether there are still active transactions that might use the chunk - bool conflicting_transactions = false; + auto conflicting_transactions = false; auto lowest_snapshot_commit_id = Hyrise::get().transaction_manager.get_lowest_active_snapshot_commit_id(); if (lowest_snapshot_commit_id.has_value()) { @@ -141,7 +141,7 @@ bool MvccDeletePlugin::_try_logical_delete(const std::string& table_name, const // Create temporary referencing table that contains the given chunk only // Include all ChunksIDs of current table except chunk_id for pruning in GetTable - std::vector excluded_chunk_ids(table->chunk_count() - 1); + auto excluded_chunk_ids = std::vector(table->chunk_count() - 1); std::iota(excluded_chunk_ids.begin(), excluded_chunk_ids.begin() + chunk_id, 0); std::iota(excluded_chunk_ids.begin() + chunk_id, excluded_chunk_ids.end(), chunk_id + 1); diff --git a/src/plugins/non_instantiable_plugin.cpp b/src/plugins/non_instantiable_plugin.cpp index fdbe17b786..1bf1184068 100644 --- a/src/plugins/non_instantiable_plugin.cpp +++ b/src/plugins/non_instantiable_plugin.cpp @@ -4,6 +4,7 @@ namespace hyrise { // This plugin does not export its instantiation so that we can test if this case is handled correctly. +// NOLINTNEXTLINE(fuchsia-multiple-inheritance) class TestNonInstantiablePlugin : public AbstractPlugin, public Singleton { public: std::string description() const final { diff --git a/src/plugins/second_test_plugin.cpp b/src/plugins/second_test_plugin.cpp index 6bc628699e..c4d9e53241 100644 --- a/src/plugins/second_test_plugin.cpp +++ b/src/plugins/second_test_plugin.cpp @@ -12,8 +12,8 @@ void SecondTestPlugin::start() {} void SecondTestPlugin::stop() {} -std::vector> SecondTestPlugin::provided_user_executable_functions() - const { +std::vector> +SecondTestPlugin::provided_user_executable_functions() { return {{"OurFreelyChoosableFunctionName", [&]() { this->a_user_executable_function(); }}}; } diff --git a/src/plugins/second_test_plugin.hpp b/src/plugins/second_test_plugin.hpp index e9b07bc614..e1f9053491 100644 --- a/src/plugins/second_test_plugin.hpp +++ b/src/plugins/second_test_plugin.hpp @@ -15,7 +15,7 @@ class SecondTestPlugin : public AbstractPlugin { void stop() final; - std::vector> provided_user_executable_functions() const final; + std::vector> provided_user_executable_functions() final; void a_user_executable_function() const; diff --git a/src/plugins/test_plugin.cpp b/src/plugins/test_plugin.cpp index cef8dfb8c4..fc6f07a3ac 100644 --- a/src/plugins/test_plugin.cpp +++ b/src/plugins/test_plugin.cpp @@ -20,21 +20,21 @@ void TestPlugin::stop() { Hyrise::get().storage_manager.drop_table("DummyTable"); } -std::vector> TestPlugin::provided_user_executable_functions() - const { +std::vector> TestPlugin::provided_user_executable_functions() { return {{"OurFreelyChoosableFunctionName", [&]() { this->a_user_executable_function(); }}, - {"SpecialFunction17", [&]() { this->another_user_executable_function(); }}}; + {"SpecialFunction17", [&]() { hyrise::TestPlugin::a_static_user_executable_function(); }}}; } -void TestPlugin::a_user_executable_function() const { +void TestPlugin::a_user_executable_function() { TableColumnDefinitions column_definitions; column_definitions.emplace_back("col_A", DataType::Int, false); auto table = std::make_shared
(column_definitions, TableType::Data); - storage_manager.add_table("TableOfTestPlugin", table); + storage_manager.add_table("TableOfTestPlugin_" + std::to_string(_added_tables_count), table); + ++_added_tables_count; } -void TestPlugin::another_user_executable_function() const { +void TestPlugin::a_static_user_executable_function() { std::cout << "This is never being called!" << std::endl; } diff --git a/src/plugins/test_plugin.hpp b/src/plugins/test_plugin.hpp index 13971a1e25..3687be6af6 100644 --- a/src/plugins/test_plugin.hpp +++ b/src/plugins/test_plugin.hpp @@ -15,13 +15,16 @@ class TestPlugin : public AbstractPlugin { void stop() final; - std::vector> provided_user_executable_functions() const final; + std::vector> provided_user_executable_functions() final; - void a_user_executable_function() const; + void a_user_executable_function(); - void another_user_executable_function() const; + static void a_static_user_executable_function(); StorageManager& storage_manager; + + private: + size_t _added_tables_count{0}; }; } // namespace hyrise diff --git a/src/test/benchmarklib/tpcds/tpcds_db_generator_test.cpp b/src/test/benchmarklib/tpcds/tpcds_db_generator_test.cpp index e447735ba3..62f9a60cc4 100644 --- a/src/test/benchmarklib/tpcds/tpcds_db_generator_test.cpp +++ b/src/test/benchmarklib/tpcds/tpcds_db_generator_test.cpp @@ -70,9 +70,9 @@ TEST_F(TPCDSTableGeneratorTest, TableContentsFirstRows) { TEST_F(TPCDSTableGeneratorTest, GenerateAndStoreRowCounts) { /** - * Check whether all TPC-DS tables are created by the TPCDSTableGenerator and added to the StorageManager. - * Then check whether the row count is correct for all tables. - */ + * Check whether all TPC-DS tables are created by the TPCDSTableGenerator and added to the StorageManager. + * Then check whether the row count is correct for all tables. + */ const auto expected_sizes = std::map{{"call_center", 6}, {"catalog_page", 11718}, diff --git a/src/test/lib/concurrency/stress_test.cpp b/src/test/lib/concurrency/stress_test.cpp index 8621fab9aa..fe6d8f23ac 100644 --- a/src/test/lib/concurrency/stress_test.cpp +++ b/src/test/lib/concurrency/stress_test.cpp @@ -58,11 +58,11 @@ TEST_F(StressTest, TestTransactionConflicts) { // - https://stackoverflow.com/questions/12508653/what-is-the-issue-with-stdasync // - Mastering the C++17 STL, pages 205f // TODO(anyone): Change this to proper threads+futures, or at least do not reuse this code. - const auto num_threads = 100u; + const auto num_threads = uint32_t{100}; std::vector> thread_futures; thread_futures.reserve(num_threads); - for (auto thread_num = 0u; thread_num < num_threads; ++thread_num) { + for (auto thread_num = uint32_t{0}; thread_num < num_threads; ++thread_num) { // We want a future to the thread running, so we can kill it after a future.wait(timeout) or the test would freeze thread_futures.emplace_back(std::async(std::launch::async, run)); } diff --git a/src/test/lib/concurrency/transaction_manager_test.cpp b/src/test/lib/concurrency/transaction_manager_test.cpp index 671292021c..136b0cff9b 100644 --- a/src/test/lib/concurrency/transaction_manager_test.cpp +++ b/src/test/lib/concurrency/transaction_manager_test.cpp @@ -19,6 +19,7 @@ class TransactionManagerTest : public BaseTest { static void register_transaction(CommitID snapshot_commit_id) { Hyrise::get().transaction_manager._register_transaction(snapshot_commit_id); } + static void deregister_transaction(CommitID snapshot_commit_id) { Hyrise::get().transaction_manager._deregister_transaction(snapshot_commit_id); } diff --git a/src/test/lib/expression/expression_evaluator_to_values_test.cpp b/src/test/lib/expression/expression_evaluator_to_values_test.cpp index 017e9dab14..c4958de35c 100644 --- a/src/test/lib/expression/expression_evaluator_to_values_test.cpp +++ b/src/test/lib/expression/expression_evaluator_to_values_test.cpp @@ -609,7 +609,7 @@ TEST_F(ExpressionEvaluatorToValuesTest, InSubqueryUncorrelatedWithPrecalculated) TEST_F(ExpressionEvaluatorToValuesTest, InSubqueryUncorrelatedWithBrokenPrecalculated) { // Make sure the expression evaluator complains if it has been given a list of preevaluated sub queries but one is // missing - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } diff --git a/src/test/lib/expression/expression_test.cpp b/src/test/lib/expression/expression_test.cpp index 6984db73aa..e688e99ebb 100644 --- a/src/test/lib/expression/expression_test.cpp +++ b/src/test/lib/expression/expression_test.cpp @@ -16,7 +16,7 @@ #include "utils/load_table.hpp" -using namespace std::string_literals; // NOLINT +using namespace std::string_literals; // NOLINT using namespace hyrise::expression_functional; // NOLINT namespace hyrise { diff --git a/src/test/lib/expression/lqp_subquery_expression_test.cpp b/src/test/lib/expression/lqp_subquery_expression_test.cpp index 2f6c0e9ed7..c223cf70d6 100644 --- a/src/test/lib/expression/lqp_subquery_expression_test.cpp +++ b/src/test/lib/expression/lqp_subquery_expression_test.cpp @@ -14,7 +14,7 @@ #include "logical_query_plan/stored_table_node.hpp" #include "utils/load_table.hpp" -using namespace std::string_literals; // NOLINT +using namespace std::string_literals; // NOLINT using namespace hyrise::expression_functional; // NOLINT namespace hyrise { diff --git a/src/test/lib/expression/pqp_subquery_expression_test.cpp b/src/test/lib/expression/pqp_subquery_expression_test.cpp index c02f375d73..cb68be68c3 100644 --- a/src/test/lib/expression/pqp_subquery_expression_test.cpp +++ b/src/test/lib/expression/pqp_subquery_expression_test.cpp @@ -15,7 +15,7 @@ #include "operators/union_positions.hpp" #include "utils/load_table.hpp" -using namespace std::string_literals; // NOLINT +using namespace std::string_literals; // NOLINT using namespace hyrise::expression_functional; // NOLINT namespace hyrise { diff --git a/src/test/lib/import_export/binary/binary_parser_test.cpp b/src/test/lib/import_export/binary/binary_parser_test.cpp index 9efae5d0cd..fb977de273 100644 --- a/src/test/lib/import_export/binary/binary_parser_test.cpp +++ b/src/test/lib/import_export/binary/binary_parser_test.cpp @@ -196,8 +196,7 @@ TEST_P(BinaryParserMultiEncodingTest, AllTypesAllNullValues) { column_definitions.emplace_back("e", DataType::Double, true); auto expected_table = std::make_shared
(column_definitions, TableType::Data); - auto null_values = {NULL_VALUE, NULL_VALUE, NULL_VALUE, NULL_VALUE, - NULL_VALUE}; + auto null_values = {NULL_VALUE, NULL_VALUE, NULL_VALUE, NULL_VALUE, NULL_VALUE}; expected_table->append(null_values); expected_table->append(null_values); diff --git a/src/test/lib/import_export/binary/binary_writer_test.cpp b/src/test/lib/import_export/binary/binary_writer_test.cpp index 429ccc0ffc..bd3097da61 100644 --- a/src/test/lib/import_export/binary/binary_writer_test.cpp +++ b/src/test/lib/import_export/binary/binary_writer_test.cpp @@ -508,8 +508,7 @@ TEST_P(BinaryWriterMultiEncodingTest, AllTypesAllNullValues) { column_definitions.emplace_back("e", DataType::Double, true); auto table = std::make_shared
(column_definitions, TableType::Data, ChunkOffset{100'000}); - auto null_values = {NULL_VALUE, NULL_VALUE, NULL_VALUE, NULL_VALUE, - NULL_VALUE}; + auto null_values = {NULL_VALUE, NULL_VALUE, NULL_VALUE, NULL_VALUE, NULL_VALUE}; table->append(null_values); table->append(null_values); diff --git a/src/test/lib/logical_query_plan/intersect_node_test.cpp b/src/test/lib/logical_query_plan/intersect_node_test.cpp index e8d33f419c..704e5bc297 100644 --- a/src/test/lib/logical_query_plan/intersect_node_test.cpp +++ b/src/test/lib/logical_query_plan/intersect_node_test.cpp @@ -31,6 +31,7 @@ class IntersectNodeTest : public BaseTest { std::shared_ptr _b; std::shared_ptr _c; }; + TEST_F(IntersectNodeTest, Description) { EXPECT_EQ(_intersect_node->description(), "[IntersectNode] Mode: Positions"); } diff --git a/src/test/lib/logical_query_plan/lqp_translator_test.cpp b/src/test/lib/logical_query_plan/lqp_translator_test.cpp index e6e1d1bd09..49184123ef 100644 --- a/src/test/lib/logical_query_plan/lqp_translator_test.cpp +++ b/src/test/lib/logical_query_plan/lqp_translator_test.cpp @@ -570,7 +570,7 @@ TEST_F(LQPTranslatorTest, PredicateNodeBinaryIndexScan) { } TEST_F(LQPTranslatorTest, PredicateNodeIndexScanFailsWhenNotApplicable) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } diff --git a/src/test/lib/memory/segments_using_allocators_test.cpp b/src/test/lib/memory/segments_using_allocators_test.cpp index a1397d139c..9a3d12993f 100644 --- a/src/test/lib/memory/segments_using_allocators_test.cpp +++ b/src/test/lib/memory/segments_using_allocators_test.cpp @@ -52,24 +52,23 @@ class SegmentsUsingAllocatorsTest : public BaseTestWithParam>(contains_null_values, ChunkOffset{0}); // original_segment contains the numbers from 0 to 99, then 100x100, then the numbers from 200 to 299. // This way, we can check if, e.g., run-length encoding properly handles the duplicate values - for (auto i = 0; i <= 99; ++i) { - original_segment->append(convert_value(i)); + for (auto value = int32_t{0}; value <= 99; ++value) { + original_segment->append(convert_value(value)); } if (contains_null_values) { - for (auto i = 0; i < 80; ++i) { + for (auto value = int32_t{0}; value < 80; ++value) { original_segment->append(convert_value(100)); } - - for (auto i = 0; i < 20; ++i) { + for (auto value = int32_t{0}; value < 20; ++value) { original_segment->append(NULL_VALUE); } } else { - for (auto i = 0; i < 100; ++i) { + for (auto value = int32_t{0}; value < 100; ++value) { original_segment->append(convert_value(100)); } } - for (auto i = 200; i <= 299; ++i) { - original_segment->append(convert_value(i)); + for (auto value = int32_t{200}; value <= 299; ++value) { + original_segment->append(convert_value(value)); } }); } diff --git a/src/test/lib/operators/delete_test.cpp b/src/test/lib/operators/delete_test.cpp index 1f7d4b83bc..1c4b344bde 100644 --- a/src/test/lib/operators/delete_test.cpp +++ b/src/test/lib/operators/delete_test.cpp @@ -304,7 +304,7 @@ TEST_F(OperatorsDeleteTest, UseTransactionContextAfterCommit) { } TEST_F(OperatorsDeleteTest, RunOnUnvalidatedTable) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } diff --git a/src/test/lib/operators/difference_test.cpp b/src/test/lib/operators/difference_test.cpp index 4cd088ac72..59f6ffe89d 100644 --- a/src/test/lib/operators/difference_test.cpp +++ b/src/test/lib/operators/difference_test.cpp @@ -65,9 +65,10 @@ TEST_F(OperatorsDifferenceTest, DifferneceOnReferenceTables) { } TEST_F(OperatorsDifferenceTest, ThrowWrongColumnNumberException) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } + auto table_wrapper_c = std::make_shared(load_table("resources/test_data/tbl/int.tbl", ChunkOffset{2})); table_wrapper_c->execute(); @@ -77,7 +78,7 @@ TEST_F(OperatorsDifferenceTest, ThrowWrongColumnNumberException) { } TEST_F(OperatorsDifferenceTest, ThrowWrongColumnOrderException) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } diff --git a/src/test/lib/operators/get_table_test.cpp b/src/test/lib/operators/get_table_test.cpp index 88159451dc..7091176832 100644 --- a/src/test/lib/operators/get_table_test.cpp +++ b/src/test/lib/operators/get_table_test.cpp @@ -69,8 +69,7 @@ TEST_F(OperatorsGetTableTest, Description) { EXPECT_EQ(get_table_a->description(DescriptionMode::MultiLine), "GetTable\n(int_int_float)\npruned:\n0/4 chunk(s)\n0/3 column(s)"); - auto get_table_b = - std::make_shared("int_int_float", std::vector{ChunkID{0}}, std::vector{ColumnID{1}}); + auto get_table_b = std::make_shared("int_int_float", std::vector{ChunkID{0}}, std::vector{ColumnID{1}}); EXPECT_EQ(get_table_b->description(DescriptionMode::SingleLine), "GetTable (int_int_float) pruned: 1/4 chunk(s), 1/3 column(s)"); EXPECT_EQ(get_table_b->description(DescriptionMode::MultiLine), @@ -107,8 +106,8 @@ TEST_F(OperatorsGetTableTest, PassThroughInvalidRowCount) { } TEST_F(OperatorsGetTableTest, PrunedChunks) { - auto get_table = std::make_shared("int_int_float", std::vector{ChunkID{0}, ChunkID{2}}, - std::vector{}); + auto get_table = + std::make_shared("int_int_float", std::vector{ChunkID{0}, ChunkID{2}}, std::vector{}); get_table->execute(); @@ -126,8 +125,7 @@ TEST_F(OperatorsGetTableTest, PrunedChunks) { } TEST_F(OperatorsGetTableTest, PrunedColumns) { - auto get_table = - std::make_shared("int_int_float", std::vector{}, std::vector{ColumnID{1}}); + auto get_table = std::make_shared("int_int_float", std::vector{}, std::vector{ColumnID{1}}); get_table->execute(); @@ -148,8 +146,8 @@ TEST_F(OperatorsGetTableTest, PrunedColumns) { } TEST_F(OperatorsGetTableTest, PrunedColumnsAndChunks) { - auto get_table = std::make_shared("int_int_float", std::vector{ChunkID{0}, ChunkID{2}}, - std::vector{ColumnID{0}}); + auto get_table = + std::make_shared("int_int_float", std::vector{ChunkID{0}, ChunkID{2}}, std::vector{ColumnID{0}}); get_table->execute(); @@ -256,8 +254,7 @@ TEST_F(OperatorsGetTableTest, PrunedChunksCombined) { EXPECT_FALSE(original_table->get_chunk(ChunkID{2})); // 2. --- Logical deletion of a chunk - auto get_table_2 = - std::make_shared("int_int_float", std::vector{ChunkID{0}}, std::vector{}); + auto get_table_2 = std::make_shared("int_int_float", std::vector{ChunkID{0}}, std::vector{}); auto context2 = std::make_shared(TransactionID{1}, CommitID{3}, AutoCommit::No); @@ -297,8 +294,7 @@ TEST_F(OperatorsGetTableTest, AdaptOrderByInformation) { // single column pruned { - auto get_table = - std::make_shared("int_int_float", std::vector{}, std::vector{ColumnID{1}}); + auto get_table = std::make_shared("int_int_float", std::vector{}, std::vector{ColumnID{1}}); get_table->execute(); const auto& get_table_output = get_table->get_output(); @@ -313,8 +309,8 @@ TEST_F(OperatorsGetTableTest, AdaptOrderByInformation) { // multiple columns pruned { - auto get_table = std::make_shared("int_int_float", std::vector{}, - std::vector{ColumnID{0}, ColumnID{1}}); + auto get_table = + std::make_shared("int_int_float", std::vector{}, std::vector{ColumnID{0}, ColumnID{1}}); get_table->execute(); const auto& get_table_output = get_table->get_output(); @@ -327,8 +323,7 @@ TEST_F(OperatorsGetTableTest, AdaptOrderByInformation) { // no columns pruned { - auto get_table = - std::make_shared("int_int_float", std::vector{}, std::vector{}); + auto get_table = std::make_shared("int_int_float", std::vector{}, std::vector{}); get_table->execute(); const auto& get_table_output = get_table->get_output(); @@ -341,8 +336,8 @@ TEST_F(OperatorsGetTableTest, AdaptOrderByInformation) { // pruning the columns on which chunks are sorted { - auto get_table = std::make_shared("int_int_float", std::vector{}, - std::vector{ColumnID{0}, ColumnID{2}}); + auto get_table = + std::make_shared("int_int_float", std::vector{}, std::vector{ColumnID{0}, ColumnID{2}}); get_table->execute(); const auto& get_table_output = get_table->get_output(); diff --git a/src/test/lib/operators/index_scan_test.cpp b/src/test/lib/operators/index_scan_test.cpp index 0b205e0102..147f311aa9 100644 --- a/src/test/lib/operators/index_scan_test.cpp +++ b/src/test/lib/operators/index_scan_test.cpp @@ -259,7 +259,7 @@ TYPED_TEST(OperatorsIndexScanTest, OperatorName) { const auto right_values = std::vector(this->_column_ids.size(), AllTypeVariant{0}); auto scan = std::make_shared(this->_int_int, this->_index_type, this->_column_ids, - PredicateCondition::GreaterThanEquals, right_values); + PredicateCondition::GreaterThanEquals, right_values); EXPECT_EQ(scan->name(), "IndexScan"); } @@ -268,7 +268,7 @@ TYPED_TEST(OperatorsIndexScanTest, InvalidIndexTypeThrows) { const auto right_values = std::vector(this->_column_ids.size(), AllTypeVariant{0}); auto scan = std::make_shared(this->_int_int, SegmentIndexType::Invalid, this->_column_ids, - PredicateCondition::GreaterThan, right_values); + PredicateCondition::GreaterThan, right_values); EXPECT_THROW(scan->execute(), std::logic_error); } diff --git a/src/test/lib/operators/join_hash/join_hash_steps_test.cpp b/src/test/lib/operators/join_hash/join_hash_steps_test.cpp index e425e166ea..d4f06db304 100644 --- a/src/test/lib/operators/join_hash/join_hash_steps_test.cpp +++ b/src/test/lib/operators/join_hash/join_hash_steps_test.cpp @@ -308,12 +308,12 @@ TEST_F(JoinHashStepsTest, BuildRespectsBloomFilter) { } TEST_F(JoinHashStepsTest, ThrowWhenNoNullValuesArePassed) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } - size_t radix_bit_count = 0; - std::vector> histograms; + auto radix_bit_count = size_t{0}; + auto histograms = std::vector>{}; BloomFilter bloom_filter; // Ignored in this test const auto materialized_without_null_handling = materialize_input( diff --git a/src/test/lib/operators/join_index_test.cpp b/src/test/lib/operators/join_index_test.cpp index bf21cad229..d3cc4c7f86 100644 --- a/src/test/lib/operators/join_index_test.cpp +++ b/src/test/lib/operators/join_index_test.cpp @@ -77,7 +77,7 @@ class OperatorsJoinIndexTest : public BaseTest { const auto chunk = table->get_chunk(chunk_id); std::vector columns{1}; - for (ColumnID column_id{0}; column_id < chunk->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < chunk->column_count(); ++column_id) { columns[0] = column_id; chunk->create_index(columns); } diff --git a/src/test/lib/operators/join_test_runner.cpp b/src/test/lib/operators/join_test_runner.cpp index 0dc49acab6..4c2221eca5 100644 --- a/src/test/lib/operators/join_test_runner.cpp +++ b/src/test/lib/operators/join_test_runner.cpp @@ -147,6 +147,7 @@ class JoinOperatorFactory : public BaseJoinOperatorFactory { } } }; + // Order of columns in the input tables const std::unordered_map data_type_order = { {DataType::Int, 0u}, {DataType::Float, 1u}, {DataType::Double, 2u}, {DataType::Long, 3u}, {DataType::String, 4u}, @@ -600,7 +601,7 @@ class JoinTestRunner : public BaseTestWithParam { */ for (auto chunk_id = indexed_chunk_range.first; chunk_id < indexed_chunk_range.second; ++chunk_id) { - for (ColumnID column_id{0}; column_id < data_table->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < data_table->column_count(); ++column_id) { if (encoding_type == EncodingType::Dictionary) { data_table->get_chunk(chunk_id)->create_index(std::vector{column_id}); } else { diff --git a/src/test/lib/operators/pqp_utils_test.cpp b/src/test/lib/operators/pqp_utils_test.cpp index 1f6ffe2ced..b889684cb3 100644 --- a/src/test/lib/operators/pqp_utils_test.cpp +++ b/src/test/lib/operators/pqp_utils_test.cpp @@ -13,6 +13,7 @@ class PQPUtilsTest : public BaseTest { void SetUp() override { node_a = std::make_shared("foo"); } + std::shared_ptr node_a; }; diff --git a/src/test/lib/operators/projection_test.cpp b/src/test/lib/operators/projection_test.cpp index 6385a312d6..899c315ce9 100644 --- a/src/test/lib/operators/projection_test.cpp +++ b/src/test/lib/operators/projection_test.cpp @@ -107,8 +107,7 @@ TEST_F(OperatorsProjectionTest, ForwardsDataTable) { } TEST_F(OperatorsProjectionTest, ForwardsDataTableAndExpression) { - const auto projection = - std::make_shared(table_wrapper_a, expression_vector(a_b, a_a, add_(a_b, a_a))); + const auto projection = std::make_shared(table_wrapper_a, expression_vector(a_b, a_a, add_(a_b, a_a))); projection->execute(); const auto input_chunk = table_wrapper_a->get_output()->get_chunk(ChunkID{0}); @@ -125,8 +124,7 @@ TEST_F(OperatorsProjectionTest, DoNotForwardEvaluatedColumns) { const auto table_scan = create_table_scan(table_wrapper_a, ColumnID{0}, PredicateCondition::LessThan, 100'000); table_scan->never_clear_output(); table_scan->execute(); - const auto projection = - std::make_shared(table_scan, expression_vector(a_b, a_a, add_(a_b, a_a))); + const auto projection = std::make_shared(table_scan, expression_vector(a_b, a_a, add_(a_b, a_a))); projection->execute(); const auto input_chunk = table_scan->get_output()->get_chunk(ChunkID{0}); @@ -192,8 +190,7 @@ TEST_F(OperatorsProjectionTest, ExpressionUnorderedSetCheck) { // a_a should not be forwarded as a_a2 references the same input columns and is evaluated. const auto a_a2 = PQPColumnExpression::from_table(*table_wrapper_a->get_output(), "a"); - const auto projection = - std::make_shared(table_scan, expression_vector(a_a, a_b, add_(a_a2, 17))); + const auto projection = std::make_shared(table_scan, expression_vector(a_a, a_b, add_(a_a2, 17))); projection->never_clear_output(); projection->execute(); diff --git a/src/test/lib/operators/sort_test.cpp b/src/test/lib/operators/sort_test.cpp index 311fe980d7..e41f6afa1e 100644 --- a/src/test/lib/operators/sort_test.cpp +++ b/src/test/lib/operators/sort_test.cpp @@ -158,6 +158,7 @@ INSTANTIATE_TEST_SUITE_P(Variations, SortTest, SortTestParam{{SortColumnDefinition{ColumnID{0}, SortMode::Ascending}}, true, true, Chunk::DEFAULT_SIZE, Sort::ForceMaterialization::Yes, "empty.tbl"} // NOLINT ), // NOLINT sort_test_formatter); + // clang-format on TEST_F(SortTest, JoinProducesReferences) { diff --git a/src/test/lib/operators/table_scan_sorted_segment_search_test.cpp b/src/test/lib/operators/table_scan_sorted_segment_search_test.cpp index ea3a77368c..d6ff065c06 100644 --- a/src/test/lib/operators/table_scan_sorted_segment_search_test.cpp +++ b/src/test/lib/operators/table_scan_sorted_segment_search_test.cpp @@ -113,6 +113,7 @@ INSTANTIATE_TEST_SUITE_P( ::testing::Values(SortMode::Ascending, SortMode::Descending), ::testing::Bool()), // nullable table_scan_sorted_segment_search_test_formatter); + // clang-format on TEST_P(OperatorsTableScanSortedSegmentSearchTest, ScanSortedSegment) { diff --git a/src/test/lib/operators/typed_operator_base_test.hpp b/src/test/lib/operators/typed_operator_base_test.hpp index 1c2f51b577..8e6e5de57c 100644 --- a/src/test/lib/operators/typed_operator_base_test.hpp +++ b/src/test/lib/operators/typed_operator_base_test.hpp @@ -36,6 +36,7 @@ static std::vector create_test_params() { if (!encoding_supports_data_type(encoding, data_type)) { continue; } + for (auto sorted_by_it = sort_mode_to_string.begin(); sorted_by_it != sort_mode_to_string.end(); ++sorted_by_it) { const auto& sort_mode = sorted_by_it->left; pairs.emplace_back(data_type, encoding, sort_mode, true); diff --git a/src/test/lib/operators/validate_test.cpp b/src/test/lib/operators/validate_test.cpp index ad7efd6444..4a5fa6c083 100644 --- a/src/test/lib/operators/validate_test.cpp +++ b/src/test/lib/operators/validate_test.cpp @@ -140,7 +140,7 @@ TEST_F(OperatorsValidateTest, ValidateAfterDelete) { } TEST_F(OperatorsValidateTest, ChunkEntirelyVisibleThrowsOnRefChunk) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } @@ -229,7 +229,7 @@ TEST_F(OperatorsValidateTest, ValidateReferenceSegmentWithMultipleChunks) { } Segments segments; - for (ColumnID column_id{0}; column_id < _test_table->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < _test_table->column_count(); ++column_id) { segments.emplace_back(std::make_shared(_test_table, column_id, pos_list)); } diff --git a/src/test/lib/optimizer/optimizer_test.cpp b/src/test/lib/optimizer/optimizer_test.cpp index 70b39430c5..02b7aa3f14 100644 --- a/src/test/lib/optimizer/optimizer_test.cpp +++ b/src/test/lib/optimizer/optimizer_test.cpp @@ -93,9 +93,10 @@ TEST_F(OptimizerTest, AssertsInPlanReferences) { } TEST_F(OptimizerTest, VerifiesResults) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } + // While the Asserts* tests checked the different features of validate_lqp, this test checks that a rule that breaks // an LQP throws an assertion. // clang-format off @@ -111,6 +112,7 @@ TEST_F(OptimizerTest, VerifiesResults) { public: explicit LQPBreakingRule(const std::shared_ptr& init_out_of_plan_expression) : out_of_plan_expression(init_out_of_plan_expression) {} + std::string name() const override { return "LQPBreakingRule"; } @@ -144,6 +146,7 @@ TEST_F(OptimizerTest, OptimizesSubqueries) { class MockRule : public AbstractRule { public: explicit MockRule(std::unordered_set>& init_nodes) : nodes(init_nodes) {} + std::string name() const override { return "MockRule"; } @@ -226,9 +229,11 @@ TEST_F(OptimizerTest, OptimizesSubqueriesExactlyOnce) { // to check whether SubqueryExpressions pointing to the same LQP before optimization still point to the same (though // deep_copy()ed) LQP afterwards size_t counter{0}; + class MockRule : public AbstractRule { public: explicit MockRule(size_t& init_counter) : counter(init_counter) {} + std::string name() const override { return "MockRule"; } diff --git a/src/test/lib/optimizer/strategy/in_expression_rewrite_rule_test.cpp b/src/test/lib/optimizer/strategy/in_expression_rewrite_rule_test.cpp index 3dcf4bfedc..89c04dc7be 100644 --- a/src/test/lib/optimizer/strategy/in_expression_rewrite_rule_test.cpp +++ b/src/test/lib/optimizer/strategy/in_expression_rewrite_rule_test.cpp @@ -40,8 +40,8 @@ class InExpressionRewriteRuleTest : public StrategyBaseTest { null_in_expression = in_(col_a, list_(1, NULL_VALUE)); auto hundred_elements = std::vector>{}; - for (auto i = 0; i < 100; ++i) { - hundred_elements.emplace_back(value_(i)); + for (auto index = 0; index < 100; ++index) { + hundred_elements.emplace_back(value_(index)); } hundred_element_in_expression = std::make_shared(PredicateCondition::In, col_a, std::make_shared(hundred_elements)); @@ -311,8 +311,8 @@ TEST_F(InExpressionRewriteRuleTest, AutoStrategy) { const auto column_definitions = TableColumnDefinitions{{"right_values", DataType::Int, false}}; auto table = std::make_shared
(column_definitions, TableType::Data); - for (auto i = 0; i < 100; ++i) { - table->append({i}); + for (auto index = int32_t{0}; index < 100; ++index) { + table->append({index}); } const auto static_table_node = StaticTableNode::make(table); const auto right_col = lqp_column_(static_table_node, ColumnID{0}); @@ -331,8 +331,8 @@ TEST_F(InExpressionRewriteRuleTest, AutoStrategy) { const auto column_definitions = TableColumnDefinitions{{"right_values", DataType::Int, false}}; auto table = std::make_shared
(column_definitions, TableType::Data); - for (auto i = 0; i < 100; ++i) { - table->append({i}); + for (auto index = int32_t{0}; index < 100; ++index) { + table->append({index}); } const auto static_table_node = StaticTableNode::make(table); const auto right_col = lqp_column_(static_table_node, ColumnID{0}); diff --git a/src/test/lib/optimizer/strategy/null_scan_removal_rule_test.cpp b/src/test/lib/optimizer/strategy/null_scan_removal_rule_test.cpp index 574898c61a..0f6d340964 100644 --- a/src/test/lib/optimizer/strategy/null_scan_removal_rule_test.cpp +++ b/src/test/lib/optimizer/strategy/null_scan_removal_rule_test.cpp @@ -27,6 +27,7 @@ class NullScanRemovalRuleTest : public StrategyBaseTest { nullable_table_node_column = lqp_column_(nullable_table_node, ColumnID{0}); table_node_column = lqp_column_(table_node, ColumnID{0}); } + std::shared_ptr mock_node; std::shared_ptr rule; std::shared_ptr mock_node_column, nullable_table_node_column, table_node_column; diff --git a/src/test/lib/server/postgres_protocol_handler_test.cpp b/src/test/lib/server/postgres_protocol_handler_test.cpp index 0cf5b84495..c73b8cc6a6 100644 --- a/src/test/lib/server/postgres_protocol_handler_test.cpp +++ b/src/test/lib/server/postgres_protocol_handler_test.cpp @@ -263,7 +263,7 @@ TEST_F(PostgresProtocolHandlerTest, ReadExecutePacket) { TEST_F(PostgresProtocolHandlerTest, SendErrorMessage) { const std::string error_description = "error"; - const auto error_message = ErrorMessage{{PostgresMessageType::HumanReadableError, error_description}}; + const auto error_message = ErrorMessages{{PostgresMessageType::HumanReadableError, error_description}}; _protocol_handler->send_error_message(error_message); const std::string file_content = _mocked_socket->read(); diff --git a/src/test/lib/server/query_handler_test.cpp b/src/test/lib/server/query_handler_test.cpp index b1824ebb29..abf20df06f 100644 --- a/src/test/lib/server/query_handler_test.cpp +++ b/src/test/lib/server/query_handler_test.cpp @@ -19,7 +19,7 @@ TEST_F(QueryHandlerTest, ExecutePipeline) { const auto [execution_information, transaction_context] = QueryHandler::execute_pipeline(query, SendExecutionInfo::Yes, nullptr); - EXPECT_TRUE(execution_information.error_message.empty()); + EXPECT_TRUE(execution_information.error_messages.empty()); EXPECT_EQ(execution_information.result_table->column_count(), 1); EXPECT_EQ(execution_information.result_table->row_count(), 1); EXPECT_PRED_FORMAT2(testing::IsSubstring, "Execution info:", execution_information.pipeline_metrics); diff --git a/src/test/lib/server/result_serializer_test.cpp b/src/test/lib/server/result_serializer_test.cpp index 7a7b67697f..64a20346f0 100644 --- a/src/test/lib/server/result_serializer_test.cpp +++ b/src/test/lib/server/result_serializer_test.cpp @@ -29,7 +29,7 @@ TEST_F(ResultSerializerTest, RowDescription) { EXPECT_EQ(NetworkConversionHelper::get_message_length(file_content.cbegin() + 1), file_content.size() - 1); EXPECT_EQ(NetworkConversionHelper::get_small_int(file_content.cbegin() + 5), _test_table->column_count()); - for (ColumnID column_id{0}; column_id < _test_table->column_count(); column_id++) { + for (auto column_id = ColumnID{0}; column_id < _test_table->column_count(); column_id++) { EXPECT_NE(file_content.find(_test_table->column_name(column_id)), std::string::npos); } } diff --git a/src/test/lib/server/transaction_handling_test.cpp b/src/test/lib/server/transaction_handling_test.cpp index 828ba7211a..9de11ff0b4 100644 --- a/src/test/lib/server/transaction_handling_test.cpp +++ b/src/test/lib/server/transaction_handling_test.cpp @@ -13,7 +13,7 @@ TEST_F(TransactionHandlingTest, CreateTableWithinTransaction) { QueryHandler::execute_pipeline(query, SendExecutionInfo::Yes, nullptr); // begin and commit transaction statements are executed successfully - EXPECT_TRUE(execution_information.error_message.empty()); + EXPECT_TRUE(execution_information.error_messages.empty()); EXPECT_EQ(execution_information.result_table, nullptr); EXPECT_EQ(execution_information.custom_command_complete_message.value(), "COMMIT"); EXPECT_EQ(Hyrise::get().storage_manager.get_table("users")->row_count(), 1); @@ -30,7 +30,7 @@ TEST_F(TransactionHandlingTest, RollbackTransaction) { // rollback transaction statement is executed successfully // in this case the second insert into the table gets rolled back - EXPECT_TRUE(execution_information.error_message.empty()); + EXPECT_TRUE(execution_information.error_messages.empty()); EXPECT_EQ(execution_information.result_table->row_count(), 2); } @@ -48,7 +48,7 @@ TEST_F(TransactionHandlingTest, TestTransactionContextInternals) { auto execution_information = execution_info_transaction_context_pair.first; // The transaction context should be in "auto-commit" mode - EXPECT_TRUE(execution_information.error_message.empty()); + EXPECT_TRUE(execution_information.error_messages.empty()); EXPECT_EQ(transaction_ctx, nullptr); transaction_ctx = execution_info_transaction_context_pair.second; @@ -65,7 +65,7 @@ TEST_F(TransactionHandlingTest, TestTransactionContextInternals) { // when the user begins a transaction, a new transaction context is created internally (not in "auto-commit" mode) // the transaction is therefore still active until the user either rolls back or commits EXPECT_EQ(transaction_ctx->phase(), TransactionPhase::Active); - EXPECT_TRUE(execution_information.error_message.empty()); + EXPECT_TRUE(execution_information.error_messages.empty()); EXPECT_EQ(transaction_ctx->is_auto_commit(), false); } @@ -79,7 +79,7 @@ TEST_F(TransactionHandlingTest, TestTransactionContextInternals) { // now that the user rolled back, // the transaction context is in the successful state of having been rolled back on purpose EXPECT_EQ(transaction_ctx->phase(), TransactionPhase::RolledBackByUser); - EXPECT_TRUE(execution_information.error_message.empty()); + EXPECT_TRUE(execution_information.error_messages.empty()); // internally the transaction context returned by the pipeline is nullptr // in order to force creating a new one in the next pipeline execution @@ -100,7 +100,7 @@ TEST_F(TransactionHandlingTest, TestTransactionSideEffects) { QueryHandler::execute_pipeline(query, SendExecutionInfo::Yes, transaction_ctx); auto execution_information = execution_info_transaction_context_pair.first; - EXPECT_TRUE(execution_information.error_message.empty()); + EXPECT_TRUE(execution_information.error_messages.empty()); transaction_ctx = execution_info_transaction_context_pair.second; } @@ -112,7 +112,7 @@ TEST_F(TransactionHandlingTest, TestTransactionSideEffects) { auto execution_info_transaction_context_pair = QueryHandler::execute_pipeline(query, SendExecutionInfo::Yes, transaction_ctx); auto execution_information = execution_info_transaction_context_pair.first; - EXPECT_TRUE(execution_information.error_message.empty()); + EXPECT_TRUE(execution_information.error_messages.empty()); transaction_ctx = execution_info_transaction_context_pair.second; } @@ -128,7 +128,7 @@ TEST_F(TransactionHandlingTest, TestTransactionSideEffects) { // the DELETE statement from user A has not been committed yet // that's why the change is not visible yet - EXPECT_TRUE(execution_information_2.error_message.empty()); + EXPECT_TRUE(execution_information_2.error_messages.empty()); EXPECT_EQ(execution_information_2.result_table->row_count(), 1); } @@ -139,7 +139,7 @@ TEST_F(TransactionHandlingTest, TestTransactionSideEffects) { auto execution_info_transaction_context_pair = QueryHandler::execute_pipeline(query, SendExecutionInfo::Yes, transaction_ctx); auto execution_information = execution_info_transaction_context_pair.first; - EXPECT_TRUE(execution_information.error_message.empty()); + EXPECT_TRUE(execution_information.error_messages.empty()); } { @@ -152,7 +152,7 @@ TEST_F(TransactionHandlingTest, TestTransactionSideEffects) { auto execution_information_2 = execution_info_transaction_context_pair_2.first; // now the changes of the DELETE statement are visible - EXPECT_TRUE(execution_information_2.error_message.empty()); + EXPECT_TRUE(execution_information_2.error_messages.empty()); EXPECT_EQ(execution_information_2.result_table->row_count(), 0); } } diff --git a/src/test/lib/sql/sql_identifier_resolver_test.cpp b/src/test/lib/sql/sql_identifier_resolver_test.cpp index 172d616eda..151709f5c4 100644 --- a/src/test/lib/sql/sql_identifier_resolver_test.cpp +++ b/src/test/lib/sql/sql_identifier_resolver_test.cpp @@ -9,7 +9,7 @@ #include "sql/sql_identifier_resolver.hpp" #include "sql/sql_identifier_resolver_proxy.hpp" -using namespace std::string_literals; // NOLINT +using namespace std::string_literals; // NOLINT using namespace hyrise::expression_functional; // NOLINT namespace hyrise { diff --git a/src/test/lib/sql/sql_pipeline_test.cpp b/src/test/lib/sql/sql_pipeline_test.cpp index f745667f7b..ffcc7ec953 100644 --- a/src/test/lib/sql/sql_pipeline_test.cpp +++ b/src/test/lib/sql/sql_pipeline_test.cpp @@ -120,7 +120,7 @@ TEST_F(SQLPipelineTest, SimpleCreationInvalid) { } TEST_F(SQLPipelineTest, ParseErrorDebugMessage) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } diff --git a/src/test/lib/statistics/statistics_objects/range_filter_test.cpp b/src/test/lib/statistics/statistics_objects/range_filter_test.cpp index d272adfdd1..9bad342cbf 100644 --- a/src/test/lib/statistics/statistics_objects/range_filter_test.cpp +++ b/src/test/lib/statistics/statistics_objects/range_filter_test.cpp @@ -57,7 +57,7 @@ TYPED_TEST(RangeFilterTest, ValueRangeTooLarge) { } TYPED_TEST(RangeFilterTest, ThrowOnUnsortedData) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } @@ -120,7 +120,7 @@ TYPED_TEST(RangeFilterTest, MultipleRanges) { EXPECT_FALSE(filter->does_not_contain(PredicateCondition::BetweenInclusive, third_gap_min, third_gap_max)); } // starting with 4 ranges, all tested gaps should be covered - for (auto range_count : {4, 5, 100, 1'000}) { + for (const auto range_count : {4, 5, 100, 1'000}) { { const auto filter = RangeFilter::build_filter(this->_values, range_count); EXPECT_TRUE(filter->does_not_contain(PredicateCondition::Equals, this->_value_in_gap)); @@ -133,7 +133,7 @@ TYPED_TEST(RangeFilterTest, MultipleRanges) { } } { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } diff --git a/src/test/lib/statistics/statistics_objects/string_histogram_domain_test.cpp b/src/test/lib/statistics/statistics_objects/string_histogram_domain_test.cpp index f2180638e1..c11ed0ab80 100644 --- a/src/test/lib/statistics/statistics_objects/string_histogram_domain_test.cpp +++ b/src/test/lib/statistics/statistics_objects/string_histogram_domain_test.cpp @@ -40,9 +40,10 @@ TEST_F(StringHistogramDomainTest, NextValue) { } TEST_F(StringHistogramDomainTest, NextValueThrowsOnInvalidInput) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } + // "A" is not in `domain_a` EXPECT_THROW(domain_a.next_value_clamped("A"), std::logic_error); } diff --git a/src/test/lib/storage/chunk_test.cpp b/src/test/lib/storage/chunk_test.cpp index e3619c520c..c32397af56 100644 --- a/src/test/lib/storage/chunk_test.cpp +++ b/src/test/lib/storage/chunk_test.cpp @@ -239,7 +239,7 @@ TEST_F(StorageChunkTest, SetSortedInformationVector) { } TEST_F(StorageChunkTest, SetSortedInformationAscendingWithNulls) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } @@ -255,7 +255,7 @@ TEST_F(StorageChunkTest, SetSortedInformationAscendingWithNulls) { } TEST_F(StorageChunkTest, SetSortedInformationDescendingWithNulls) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } @@ -273,7 +273,7 @@ TEST_F(StorageChunkTest, SetSortedInformationDescendingWithNulls) { } TEST_F(StorageChunkTest, SetSortedInformationUnsortedNULLs) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } @@ -291,7 +291,7 @@ TEST_F(StorageChunkTest, SetSortedInformationUnsortedNULLs) { } TEST_F(StorageChunkTest, SetSortedInformationNULLsLast) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } diff --git a/src/test/lib/storage/dictionary_segment_test.cpp b/src/test/lib/storage/dictionary_segment_test.cpp index 1ecad7cf85..6d39a0e082 100644 --- a/src/test/lib/storage/dictionary_segment_test.cpp +++ b/src/test/lib/storage/dictionary_segment_test.cpp @@ -36,8 +36,8 @@ INSTANTIATE_TEST_SUITE_P(VectorCompressionTypes, StorageDictionarySegmentTest, dictionary_segment_test_formatter); TEST_P(StorageDictionarySegmentTest, LowerUpperBound) { - for (int i = 0; i <= 10; i += 2) { - vs_int->append(i); + for (auto value = int32_t{0}; value <= 10; value += 2) { + vs_int->append(value); } auto segment = diff --git a/src/test/lib/storage/fixed_string_dictionary_segment/fixed_string_test.cpp b/src/test/lib/storage/fixed_string_dictionary_segment/fixed_string_test.cpp index 3cbddffd03..b3d88b5327 100644 --- a/src/test/lib/storage/fixed_string_dictionary_segment/fixed_string_test.cpp +++ b/src/test/lib/storage/fixed_string_dictionary_segment/fixed_string_test.cpp @@ -10,6 +10,7 @@ namespace hyrise { class FixedStringTest : public BaseTest { public: void SetUp() override {} + std::vector char_vector1 = {'f', 'o', 'o'}; std::vector char_vector2 = {'b', 'a', 'r', 'b', 'a', 'z'}; FixedString fixed_string1 = FixedString(&char_vector1[0], 3u); diff --git a/src/test/lib/storage/fixed_string_dictionary_segment/fixed_string_vector_test.cpp b/src/test/lib/storage/fixed_string_dictionary_segment/fixed_string_vector_test.cpp index e9d3302dcf..b1defc5637 100644 --- a/src/test/lib/storage/fixed_string_dictionary_segment/fixed_string_vector_test.cpp +++ b/src/test/lib/storage/fixed_string_dictionary_segment/fixed_string_vector_test.cpp @@ -12,6 +12,7 @@ class FixedStringVectorTest : public BaseTest { std::vector strings = {"foo", "barbaz", "str3"}; fixed_string_vector = std::make_shared(FixedStringVector(strings.begin(), strings.end(), 6u)); } + std::shared_ptr fixed_string_vector = nullptr; }; diff --git a/src/test/lib/storage/index/group_key/variable_length_key_store_test.cpp b/src/test/lib/storage/index/group_key/variable_length_key_store_test.cpp index cf41224146..7a35e13e16 100644 --- a/src/test/lib/storage/index/group_key/variable_length_key_store_test.cpp +++ b/src/test/lib/storage/index/group_key/variable_length_key_store_test.cpp @@ -186,9 +186,10 @@ TEST_F(VariableLengthKeyStoreTest, WriteAccessViaBracketsOperator) { } TEST_F(VariableLengthKeyStoreTest, WriteNonFittingKeys) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } + // _store is created with 4 bytes per entry auto short_key = VariableLengthKey(sizeof(uint16_t)); auto long_key = VariableLengthKey(sizeof(uint64_t)); diff --git a/src/test/lib/storage/index/multi_segment_index_test.cpp b/src/test/lib/storage/index/multi_segment_index_test.cpp index 713e74333c..7bc63a84de 100644 --- a/src/test/lib/storage/index/multi_segment_index_test.cpp +++ b/src/test/lib/storage/index/multi_segment_index_test.cpp @@ -164,9 +164,10 @@ TYPED_TEST(MultiSegmentIndexTest, RangeQueryOpenBegin) { } TYPED_TEST(MultiSegmentIndexTest, TooManyReferenceValues) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } + EXPECT_THROW(this->index_int_str->lower_bound({1, "baz", 3.0f}), std::logic_error); EXPECT_THROW(this->index_int_str->upper_bound({1, "baz", 3.0f}), std::logic_error); } diff --git a/src/test/lib/storage/index/single_segment_index_test.cpp b/src/test/lib/storage/index/single_segment_index_test.cpp index dd85ba44b4..76e7fbde0a 100644 --- a/src/test/lib/storage/index/single_segment_index_test.cpp +++ b/src/test/lib/storage/index/single_segment_index_test.cpp @@ -659,6 +659,7 @@ TYPED_TEST(SingleSegmentIndexTest, IndexOnNonDictionaryThrows) { if (!HYRISE_DEBUG || std::is_same_v) { GTEST_SKIP(); } + auto vs_int = std::make_shared>(); vs_int->append(4); diff --git a/src/test/lib/storage/reference_segment_test.cpp b/src/test/lib/storage/reference_segment_test.cpp index 15f35531b8..712930e960 100644 --- a/src/test/lib/storage/reference_segment_test.cpp +++ b/src/test/lib/storage/reference_segment_test.cpp @@ -36,8 +36,7 @@ class ReferenceSegmentTest : public BaseTest { TableColumnDefinitions column_definitions2; column_definitions2.emplace_back("a", DataType::Int, false); column_definitions2.emplace_back("b", DataType::Int, false); - _test_table_dict = - std::make_shared
(column_definitions2, TableType::Data, ChunkOffset{5}, UseMvcc::Yes); + _test_table_dict = std::make_shared
(column_definitions2, TableType::Data, ChunkOffset{5}, UseMvcc::Yes); for (auto index = int32_t{0}; index <= 24; index += 2) { _test_table_dict->append({index, 100 + index}); } diff --git a/src/test/lib/storage/table_test.cpp b/src/test/lib/storage/table_test.cpp index 9b91179da7..87ef9f9de2 100644 --- a/src/test/lib/storage/table_test.cpp +++ b/src/test/lib/storage/table_test.cpp @@ -180,7 +180,7 @@ TEST_F(StorageTableTest, EmplaceEmptyChunk) { } TEST_F(StorageTableTest, EmplaceEmptyChunkWhenEmptyExists) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } @@ -240,9 +240,10 @@ TEST_F(StorageTableTest, EmplaceChunkDoesNotReplaceIfNumberOfChunksGreaterOne) { } TEST_F(StorageTableTest, ChunkSizeZeroThrows) { - if (!HYRISE_DEBUG) { + if constexpr (!HYRISE_DEBUG) { GTEST_SKIP(); } + TableColumnDefinitions column_definitions{}; EXPECT_THROW(Table(column_definitions, TableType::Data, ChunkOffset{0}), std::logic_error); } diff --git a/src/test/lib/tasks/chunk_compression_task_test.cpp b/src/test/lib/tasks/chunk_compression_task_test.cpp index 6645dce32e..8b243d3655 100644 --- a/src/test/lib/tasks/chunk_compression_task_test.cpp +++ b/src/test/lib/tasks/chunk_compression_task_test.cpp @@ -36,10 +36,10 @@ TEST_F(ChunkCompressionTaskTest, CompressionPreservesTableContent) { EXPECT_TABLE_EQ_UNORDERED(table, table_dict); constexpr auto chunk_count = 4u; - for (ChunkID chunk_id{0}; chunk_id < chunk_count; ++chunk_id) { + for (auto chunk_id = ChunkID{0}; chunk_id < chunk_count; ++chunk_id) { const auto chunk = table_dict->get_chunk(chunk_id); - for (ColumnID column_id{0}; column_id < chunk->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < chunk->column_count(); ++column_id) { auto segment = chunk->get_segment(column_id); auto dict_segment = std::dynamic_pointer_cast(segment); @@ -61,9 +61,9 @@ TEST_F(ChunkCompressionTaskTest, DictionarySize) { auto dictionary_sizes = std::array, chunk_count>{{{3u, 3u}, {2u, 3u}}}; - for (ChunkID chunk_id{0}; chunk_id < chunk_count; ++chunk_id) { + for (auto chunk_id = ChunkID{0}; chunk_id < chunk_count; ++chunk_id) { const auto chunk = table_dict->get_chunk(chunk_id); - for (ColumnID column_id{0}; column_id < chunk->column_count(); ++column_id) { + for (auto column_id = ColumnID{0}; column_id < chunk->column_count(); ++column_id) { auto segment = chunk->get_segment(column_id); auto dict_segment = std::dynamic_pointer_cast(segment); @@ -96,9 +96,9 @@ TEST_F(ChunkCompressionTaskTest, CompressionWithAbortedInsert) { "table_insert", std::vector{ChunkID{0}, ChunkID{1}, ChunkID{2}, ChunkID{3}}); Hyrise::get().scheduler()->schedule_and_wait_for_tasks({compression}); - for (auto i = ChunkID{0}; i < table->chunk_count() - 1; ++i) { + for (auto chunk_id = ChunkID{0}; chunk_id < table->chunk_count() - 1; ++chunk_id) { auto dict_segment = - std::dynamic_pointer_cast(table->get_chunk(i)->get_segment(ColumnID{0})); + std::dynamic_pointer_cast(table->get_chunk(chunk_id)->get_segment(ColumnID{0})); ASSERT_NE(dict_segment, nullptr); } diff --git a/src/test/lib/utils/meta_tables/meta_exec_table_test.cpp b/src/test/lib/utils/meta_tables/meta_exec_table_test.cpp index 868da7c2d6..4ce2165b45 100644 --- a/src/test/lib/utils/meta_tables/meta_exec_table_test.cpp +++ b/src/test/lib/utils/meta_tables/meta_exec_table_test.cpp @@ -45,13 +45,16 @@ TEST_F(MetaExecTest, CallUserExecutableFunctions) { pm.load_plugin(build_dylib_path("libhyriseTestPlugin")); pm.load_plugin(build_dylib_path("libhyriseSecondTestPlugin")); - SQLPipelineBuilder{ + // Test plugin has state and cretes tables with an increasing id. + const auto exec_query = "INSERT INTO meta_exec (plugin_name, function_name) VALUES ('hyriseTestPlugin', " - "'OurFreelyChoosableFunctionName')"} - .create_pipeline() - .get_result_table(); + "'OurFreelyChoosableFunctionName')"; + SQLPipelineBuilder{exec_query}.create_pipeline().get_result_table(); // The test plugin creates the below table when the called function is executed - EXPECT_TRUE(sm.has_table("TableOfTestPlugin")); + EXPECT_TRUE(sm.has_table("TableOfTestPlugin_0")); + + SQLPipelineBuilder{exec_query}.create_pipeline().get_result_table(); + EXPECT_TRUE(sm.has_table("TableOfTestPlugin_1")); SQLPipelineBuilder{ "INSERT INTO meta_exec (plugin_name, function_name) VALUES ('hyriseSecondTestPlugin', " diff --git a/src/test/lib/utils/plugin_manager_test.cpp b/src/test/lib/utils/plugin_manager_test.cpp index b5a46fe6b3..ab83c1f9b1 100644 --- a/src/test/lib/utils/plugin_manager_test.cpp +++ b/src/test/lib/utils/plugin_manager_test.cpp @@ -104,7 +104,7 @@ TEST_F(PluginManagerTest, CallUserExecutableFunctions) { pm.exec_user_function("hyriseTestPlugin", "OurFreelyChoosableFunctionName"); // The test plugin creates the below table when the called function is executed - EXPECT_TRUE(sm.has_table("TableOfTestPlugin")); + EXPECT_TRUE(sm.has_table("TableOfTestPlugin_0")); // The PluginManager adds log messages when user executable functions are called EXPECT_EQ(lm.log_entries().size(), 1); diff --git a/src/test/plugins/mvcc_delete_plugin_test.cpp b/src/test/plugins/mvcc_delete_plugin_test.cpp index d15b65a520..40308fcb5d 100644 --- a/src/test/plugins/mvcc_delete_plugin_test.cpp +++ b/src/test/plugins/mvcc_delete_plugin_test.cpp @@ -61,14 +61,17 @@ class MvccDeletePluginTest : public BaseTest { transaction_context->commit(); } + static bool _try_logical_delete(const std::string& table_name, ChunkID chunk_id) { auto transaction_context = Hyrise::get().transaction_manager.new_transaction_context(AutoCommit::No); return MvccDeletePlugin::_try_logical_delete(table_name, chunk_id, transaction_context); } + static bool _try_logical_delete(const std::string& table_name, ChunkID chunk_id, std::shared_ptr transaction_context) { return MvccDeletePlugin::_try_logical_delete(table_name, chunk_id, transaction_context); } + static void _delete_chunk_physically(const std::string& table_name, ChunkID chunk_id) { MvccDeletePlugin::_delete_chunk_physically(Hyrise::get().storage_manager.get_table(table_name), chunk_id); } diff --git a/src/test/testing_assert.hpp b/src/test/testing_assert.hpp index 7994be8d6e..4f6e9910cc 100644 --- a/src/test/testing_assert.hpp +++ b/src/test/testing_assert.hpp @@ -52,13 +52,13 @@ bool contained_in_query_plan(const std::shared_ptr& node * Compare two tables with respect to OrderSensitivity, TypeCmpMode and FloatComparisonMode */ #define EXPECT_TABLE_EQ(hyrise_table, expected_table, order_sensitivity, type_cmp_mode, float_comparison_mode) \ - { \ - if (const auto table_difference_message = \ + { \ + if (const auto table_difference_message = \ check_table_equal(hyrise_table, expected_table, order_sensitivity, type_cmp_mode, float_comparison_mode, \ - IgnoreNullable::No)) { \ - FAIL() << *table_difference_message; \ - } \ - } \ + IgnoreNullable::No)) { \ + FAIL() << *table_difference_message; \ + } \ + } \ static_assert(true, "End call of macro with a semicolon") /** @@ -98,11 +98,12 @@ bool contained_in_query_plan(const std::shared_ptr& node EXPECT_SEGMENT_EQ(segment_to_test, expected_segment, OrderSensitivity::Yes, TypeCmpMode::Strict, \ FloatComparisonMode::AbsoluteDifference) -#define ASSERT_LQP_TIE(output, input_side, input) \ - { \ - if (!hyrise::check_lqp_tie(output, input_side, input)) \ - FAIL(); \ - } \ +#define ASSERT_LQP_TIE(output, input_side, input) \ + { \ + if (!hyrise::check_lqp_tie(output, input_side, input)) { \ + FAIL(); \ + } \ + } \ static_assert(true, "End call of macro with a semicolon") #define EXPECT_LQP_EQ(lhs, rhs) \ @@ -110,18 +111,17 @@ bool contained_in_query_plan(const std::shared_ptr& node Assert(lhs != rhs, "Comparing an LQP with itself is always true. Did you mean to take a deep copy?"); \ const auto mismatch = lqp_find_subplan_mismatch(lhs, rhs); \ if (mismatch) { \ - std::cout << "Differing subtrees" << std::endl; \ - std::cout << "-------------- Actual LQP --------------" << std::endl; \ + std::cout << "Differing subtrees\n"; \ + std::cout << "-------------- Actual LQP --------------\n"; \ if (mismatch->first) \ std::cout << *mismatch->first; \ else \ - std::cout << "NULL" << std::endl; \ - std::cout << std::endl; \ - std::cout << "------------- Expected LQP -------------" << std::endl; \ + std::cout << "NULL\n"; \ + std::cout << "\n------------- Expected LQP -------------\n"; \ if (mismatch->second) \ std::cout << *mismatch->second; \ else \ - std::cout << "NULL" << std::endl; \ + std::cout << "NULL\n"; \ std::cout << "-------------..............-------------" << std::endl; \ GTEST_FAIL(); \ } \ diff --git a/third_party/compact_vector b/third_party/compact_vector index 66d05265ae..0aab8c43ca 160000 --- a/third_party/compact_vector +++ b/third_party/compact_vector @@ -1 +1 @@ -Subproject commit 66d05265ae7f0e305fa7cc7d4e04aefc2c1d0afc +Subproject commit 0aab8c43ca9416897b6f84624c19471ba7d4fedb