From 6ca798a3571022dc121da8aaaf00bc9546c0e697 Mon Sep 17 00:00:00 2001 From: proller Date: Fri, 4 Aug 2017 19:59:50 +0300 Subject: [PATCH] Fix infinite loop in dictGetHierarchy if id chain looped --- dbms/src/Dictionaries/CacheDictionary.cpp | 5 +++++ dbms/src/Functions/FunctionsExternalDictionaries.h | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/dbms/src/Dictionaries/CacheDictionary.cpp b/dbms/src/Dictionaries/CacheDictionary.cpp index c55284c3a8f..0eef171feaa 100644 --- a/dbms/src/Dictionaries/CacheDictionary.cpp +++ b/dbms/src/Dictionaries/CacheDictionary.cpp @@ -138,6 +138,11 @@ void CacheDictionary::isInImpl( out[out_idx] = 1; } /// Found intermediate parent, add this value to search at next loop iteration + else if (children[new_children_idx] == parents[parents_idx]) + { + // Loop detected + out[out_idx] = 0; + } else { children[new_children_idx] = parents[parents_idx]; diff --git a/dbms/src/Functions/FunctionsExternalDictionaries.h b/dbms/src/Functions/FunctionsExternalDictionaries.h index 89434353739..d2d5d8edd7e 100644 --- a/dbms/src/Functions/FunctionsExternalDictionaries.h +++ b/dbms/src/Functions/FunctionsExternalDictionaries.h @@ -1431,9 +1431,16 @@ private: if (0 == id) continue; + + auto & hierarchy = hierarchies[i]; + + //Checking for loop + if (std::find(std::begin(hierarchy), std::end(hierarchy), id) != std::end(hierarchy)) + continue; + all_zeroes = false; /// place id at it's corresponding place - hierarchies[i].push_back(id); + hierarchy.push_back(id); ++total_count; }