You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-11-03 17:13:17 +03:00 
			
		
		
		
	This patch is the columnstore-part of the task. Columnstore wanted to have previous 32 depth, so this patch aims at keeping the compatibility.
		
			
				
	
	
		
			150 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include <string_view>
 | 
						|
#include <algorithm>
 | 
						|
using namespace std;
 | 
						|
 | 
						|
#include "functor_json.h"
 | 
						|
#include "functioncolumn.h"
 | 
						|
#include "constantcolumn.h"
 | 
						|
#include "rowgroup.h"
 | 
						|
using namespace execplan;
 | 
						|
using namespace rowgroup;
 | 
						|
 | 
						|
#include "dataconvert.h"
 | 
						|
 | 
						|
#include "jsonhelpers.h"
 | 
						|
using namespace funcexp::helpers;
 | 
						|
 | 
						|
namespace funcexp
 | 
						|
{
 | 
						|
CalpontSystemCatalog::ColType Func_json_contains_path::operationType(
 | 
						|
    FunctionParm& fp, [[maybe_unused]] CalpontSystemCatalog::ColType& resultType)
 | 
						|
{
 | 
						|
  return fp[0]->data()->resultType();
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * getBoolVal API definition
 | 
						|
 */
 | 
						|
bool Func_json_contains_path::getBoolVal(Row& row, FunctionParm& fp, bool& isNull,
 | 
						|
                                         [[maybe_unused]] CalpontSystemCatalog::ColType& type)
 | 
						|
{
 | 
						|
  const auto& js_ns = fp[0]->data()->getStrVal(row, isNull);
 | 
						|
  if (isNull)
 | 
						|
    return false;
 | 
						|
 | 
						|
  const std::string_view js = js_ns.unsafeStringRef();
 | 
						|
 | 
						|
#if MYSQL_VERSION_ID >= 100900
 | 
						|
  int arrayCounters[JSON_DEPTH_LIMIT];
 | 
						|
  bool hasNegPath = false;
 | 
						|
#endif
 | 
						|
  const int argSize = fp.size() - 2;
 | 
						|
 | 
						|
  if (!isModeParsed)
 | 
						|
  {
 | 
						|
    if (!isModeConst)
 | 
						|
      isModeConst = (dynamic_cast<ConstantColumn*>(fp[1]->data()) != nullptr);
 | 
						|
 | 
						|
    auto mode_ns = fp[1]->data()->getStrVal(row, isNull);
 | 
						|
    if (isNull)
 | 
						|
      return false;
 | 
						|
    std::string mode = mode_ns.unsafeStringRef();
 | 
						|
 | 
						|
    transform(mode.begin(), mode.end(), mode.begin(), ::tolower);
 | 
						|
    if (mode != "one" && mode != "all")
 | 
						|
    {
 | 
						|
      isNull = true;
 | 
						|
      return false;
 | 
						|
    }
 | 
						|
 | 
						|
    isModeOne = (mode == "one");
 | 
						|
    isModeParsed = isModeConst;
 | 
						|
  }
 | 
						|
 | 
						|
  if (paths.size() == 0)
 | 
						|
    hasFound.assign(argSize, false);
 | 
						|
 | 
						|
  for (size_t i = 2; i < fp.size(); i++)
 | 
						|
  {
 | 
						|
    JSONPath& path = paths[i - 2];
 | 
						|
 | 
						|
    if (!path.parsed)
 | 
						|
    {
 | 
						|
      if (parseJSPath(path, row, fp[i]))
 | 
						|
      {
 | 
						|
        isNull = true;
 | 
						|
        return false;
 | 
						|
      }
 | 
						|
#if MYSQL_VERSION_ID >= 100900
 | 
						|
      hasNegPath |= path.p.types_used & JSON_PATH_NEGATIVE_INDEX;
 | 
						|
#endif
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  json_get_path_start(&jsEg, getCharset(fp[0]), (const uchar*)js.data(), (const uchar*)js.data() + js.size(),
 | 
						|
                      &p);
 | 
						|
 | 
						|
  bool result = false;
 | 
						|
  int needFound = 0;
 | 
						|
 | 
						|
  if (!isModeOne)
 | 
						|
  {
 | 
						|
    hasFound.assign(argSize, false);
 | 
						|
    needFound = argSize;
 | 
						|
  }
 | 
						|
 | 
						|
  while (json_get_path_next(&jsEg, &p) == 0)
 | 
						|
  {
 | 
						|
#if MYSQL_VERSION_ID >= 100900
 | 
						|
#if MYSQL_VERSION_ID >= 120200
 | 
						|
    json_path_step_t *last_step= reinterpret_cast<json_path_step_t*>
 | 
						|
                                  (mem_root_dynamic_array_get_val(&p.steps,
 | 
						|
                                                                  p.last_step_idx));
 | 
						|
    if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY &&
 | 
						|
        json_skip_array_and_count(&jsEg, arrayCounters + (last_step - reinterpret_cast<json_path_step_t*>(p.steps.buffer))))
 | 
						|
#else
 | 
						|
    if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY &&
 | 
						|
        json_skip_array_and_count(&jsEg, arrayCounters + (p.last_step - p.steps)))
 | 
						|
    {
 | 
						|
      result = true;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
    for (int restSize = argSize, curr = 0; restSize > 0; restSize--, curr++)
 | 
						|
    {
 | 
						|
      JSONPath& path = paths[curr];
 | 
						|
#if MYSQL_VERSION_ID >= 100900
 | 
						|
      int cmp = cmpJSPath(&path.p, &p, jsEg.value_type, arrayCounters);
 | 
						|
#else
 | 
						|
      int cmp = cmpJSPath(&path.p, &p, jsEg.value_type);
 | 
						|
#endif
 | 
						|
      if (cmp >= 0)
 | 
						|
      {
 | 
						|
        if (isModeOne)
 | 
						|
        {
 | 
						|
          result = true;
 | 
						|
          break;
 | 
						|
        }
 | 
						|
        /* mode_all */
 | 
						|
        if (hasFound[restSize - 1])
 | 
						|
          continue; /* already found */
 | 
						|
        if (--needFound == 0)
 | 
						|
        {
 | 
						|
          result = true;
 | 
						|
          break;
 | 
						|
        }
 | 
						|
        hasFound[restSize - 1] = true;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (likely(jsEg.s.error == 0))
 | 
						|
    return result;
 | 
						|
 | 
						|
  isNull = true;
 | 
						|
  return false;
 | 
						|
}
 | 
						|
}  // namespace funcexp
 |